5 次代码提交 7fef067df7 ... 82aa7b570e

作者 SHA1 备注 提交日期
  Peter Harpending 82aa7b570e Fix bug-reports url. 9 年之前
  Peter Harpending 394a7b4d2c Add a new function that uses conduit. 9 年之前
  Peter Harpending f14ac173d5 Depend on conduit. 9 年之前
  Peter Harpending 45ac9c642b Moving to GitHub. 9 年之前
  Peter Harpending 2dfcc1666d Version bump. 9 年之前
共有 2 个文件被更改,包括 133 次插入29 次删除
  1. 12 6
      editor-open.cabal
  2. 121 23
      src/Text/Editor.hs

+ 12 - 6
editor-open.cabal

@@ -1,5 +1,5 @@
 name:                editor-open
-version:             0.2.0.0
+version:             0.3.0.0
 synopsis:            Open the user's $EDITOR for text input.
 description:
   You know when you run @git commit@, and an editor pops open so you can enter a
@@ -7,7 +7,7 @@ description:
   .
   This library isn't very portable. It relies on the @$EDITOR@ environment
   variable. The concept only exists on *nix systems.
-homepage:            https://notabug.org/pharpend/editor-open
+homepage:            https://github.com/pharpend/editor-open
 license:             Apache-2.0
 license-file:        LICENSE
 author:              Peter Harpending
@@ -16,7 +16,7 @@ copyright:           Copyright 2015 Peter Harpending
 category:            Text
 build-type:          Simple
 cabal-version:       >=1.10
-bug-reports:         https://notabug.org/pharpend/editor-open/issues/new
+bug-reports:         https://github.com/pharpend/editor-open/issues/new
 extra-source-files:  
   README.md
 data-files:
@@ -32,11 +32,17 @@ library
     LambdaCase
     MultiWayIf
     OverloadedStrings
+    RankNTypes
   build-depends:
      base ==4.8.*
    , bytestring
+   , conduit >=1.2.3 && <1.3
+   , conduit-extra
+   , directory
    , process >=1.2
+   , resourcet
    , temporary
+   , transformers
    , unix
   exposed-modules:     
     Text.Editor
@@ -54,9 +60,9 @@ executable editor-open-test_yaml_file
 
 source-repository head 
   type: git
-  location: https://notabug.org/pharpend/editor-open.git
+  location: https://github.com/pharpend/editor-open.git
 
 source-repository this
   type: git
-  location: https://notabug.org/pharpend/editor-open.git
-  tag: 0.2.0.0
+  location: https://github.com/pharpend/editor-open.git
+  tag: 0.3.0.0

+ 121 - 23
src/Text/Editor.hs

@@ -27,96 +27,52 @@
 
 module Text.Editor where
 
+import           Control.Monad.Trans.Resource
+import           Control.Monad.IO.Class
 import qualified Data.ByteString as B
 import           Data.ByteString (ByteString)
 import           Data.ByteString.Char8 (unpack)
+import           Data.Conduit
+import           Data.Conduit.Binary
+import           Data.Conduit.Process
 import           Data.Monoid
+import           System.Directory (getTemporaryDirectory, removeFile)
+import           System.Exit (ExitCode)
 import           System.IO
 import           System.IO.Temp
 import           System.Process
 import           System.Posix
 
-
-wrapStr :: ByteString -> String
-wrapStr = unpack
-
-runUserEditorDWIM :: Template       -- ^Template for the file name
-                  -> ByteString     -- ^Initial contents
-                  -> IO ByteString  -- ^Resulting ByteString
-runUserEditorDWIM templ initialContents = userEditorDefault _default_editor >>= \theEditor ->
-                                            runSpecificEditor theEditor templ initialContents
-
-runUserEditorDWIMFile :: Template       -- ^Template for the file name
-                      -> FilePath       -- ^File containing initial contents
-                      -> IO ByteString  -- ^Resulting ByteString
-runUserEditorDWIMFile templ fp = B.readFile fp >>=  runUserEditorDWIM templ
-
-runUserEditor :: IO ByteString
-runUserEditor = userEditorDefault _default_editor >>= \theEditor ->
-                  runSpecificEditor theEditor plainTemplate mempty
-
-runUserEditorWithTemplate :: Template       -- ^Template for the file name
-                          -> IO ByteString  -- ^Resulting ByteString
-runUserEditorWithTemplate templ = userEditorDefault _default_editor >>= \theEditor ->
-                                    runSpecificEditor theEditor templ mempty
+-- |This is the function you should use.
+-- 
+-- 'bracketConduit' takes a 'Producer', to produce the contents of the
+-- original file, and a 'Consumer' to consume them, and returns the
+-- result of the consumer, along with the exit code from the editor.
+-- 
+-- If you don't know how to use conduits, see the
+-- <http://www.stackage.org/package/conduit documentation> for the
+-- conduit package.
+-- 
+-- If you really don't want to use conduits, you can use the strict I/O
+-- functions at the bottom of the module. Be warned that those functions
+-- are not very performant.
+bracketConduit :: Template
+               -> Producer (ResourceT IO) ByteString
+               -> Consumer ByteString (ResourceT IO) b
+               -> ResourceT IO (ExitCode,b)
+bracketConduit template producer consumer =
+  do userEditor_ <-
+       liftIO (userEditorDefault _default_editor)
+     systemTempDirectory <- liftIO getTemporaryDirectory
+     (filePath,handle) <-
+       liftIO (openBinaryTempFile systemTempDirectory template)
+     connect producer (sinkHandle handle)
+     liftIO (hClose handle)
+     result <-
+       sourceProcessWithConsumer (proc userEditor_ [filePath])
+                                 consumer
+     liftIO (removeFile filePath)
+     return result
 
 -- == File-type extensions ==
 -- 
@@ -273,3 +229,87 @@ _editor = "EDITOR"
 -- @
 _ftempl :: String
 _ftempl = "tmp"
+
+-- == Bad functions =
+-- 
+-- These are memory hogs, but exist for backwards compatibility
+
+-- |If you don't want to use ByteString, use this function.
+-- 
+-- >>> :t runUserEditorDWIM plainTemplate mempty
+-- ByteString
+-- >>> :t wrapStr <$> runUserEditorDWIM plainTemplate mempty
+-- String
+wrapStr :: ByteString -> String
+wrapStr = unpack
+
+-- |This is most likely the function you want to use. It takes a file
+-- type template as an argument, along with what you want displayed
+-- when the user opens the editor. It then runs the editor, and
+-- returns the version of the text that the user modified.
+-- 
+-- @
+-- runUserEditorDWIM templ initialContents = userEditorDefault _default_editor >>= \theEditor ->
+--                                             runSpecificEditor theEditor templ initialContents
+-- @
+-- 
+-- 
+-- Examples:
+-- 
+-- >>> :set -XOverloadedStrings
+-- >>> runUserEditorDWIM jsonTemplate "{\n\n}\n"
+-- 
+-- This will open up the user's @$EDITOR@ configured to edit JSON, and
+-- with the initial text:
+--  
+-- @
+-- {
+-- }
+-- @
+-- 
+-- There are a bunch of templates. See the "File-type extensions"
+-- section. It's also trivially easy to make your own templates. Say
+-- you want one for, I dunno, Python:
+-- 
+-- @
+-- pythonTemplate = mkTemplate "py"
+-- @
+-- 
+-- The argument to 'mkTemplate' should be the file extension you
+-- want. In that case, I used @"py"@, because Python's file extension
+-- is @.py@.
+runUserEditorDWIM :: Template       -- ^Template for the file name
+                  -> ByteString     -- ^Initial contents
+                  -> IO ByteString  -- ^Resulting ByteString
+runUserEditorDWIM templ initialContents = userEditorDefault _default_editor >>= \theEditor ->
+                                            runSpecificEditor theEditor templ initialContents
+
+-- |This is the same as above, it just takes a file as an argument
+-- instead of the ByteString
+-- 
+-- @
+-- runUserEditorDWIMFile templ fp = B.readFile fp >>=  runUserEditorDWIM templ
+-- @
+runUserEditorDWIMFile :: Template       -- ^Template for the file name
+                      -> FilePath       -- ^File containing initial contents
+                      -> IO ByteString  -- ^Resulting ByteString
+runUserEditorDWIMFile templ fp = B.readFile fp >>=  runUserEditorDWIM templ
+
+-- |This is likely the simplest function here. It opens up the user's editor,
+-- and fetches a ByteString from it
+-- 
+-- @
+-- runUserEditor = userEditorDefault _default_editor >>= \theEditor ->
+--                   runSpecificEditor theEditor plainTemplate mempty
+-- @
+runUserEditor :: IO ByteString
+runUserEditor = userEditorDefault _default_editor >>= \theEditor ->
+                  runSpecificEditor theEditor plainTemplate mempty
+
+-- |This is probably the second-simplest function.
+-- 
+-- 
+runUserEditorWithTemplate :: Template       -- ^Template for the file name
+                          -> IO ByteString  -- ^Resulting ByteString
+runUserEditorWithTemplate templ = userEditorDefault _default_editor >>= \theEditor ->
+                                    runSpecificEditor theEditor templ mempty