twitch 0.1.7.1 → 0.1.7.2
raw patch · 6 files changed
+99/−47 lines, 6 filesdep +semigroupsPVP: minor bump suggested
API additions: PVP suggests at least a minor version bump
Dependencies added: semigroups
API changes (from Hackage documentation)
+ Twitch: [debounceAmount] :: Options -> Double
+ Twitch: [debounce] :: Options -> DebounceType
+ Twitch: [logFile] :: Options -> Maybe FilePath
+ Twitch: [log] :: Options -> LoggerType
+ Twitch: [pollInterval] :: Options -> Int
+ Twitch: [recurseThroughDirectories] :: Options -> Bool
+ Twitch: [root] :: Options -> Maybe FilePath
+ Twitch: [usePolling] :: Options -> Bool
Files
- README.md +22/−1
- src/Twitch.hs +55/−36
- src/Twitch/Internal.hs +5/−1
- src/Twitch/InternalRule.hs +4/−3
- src/Twitch/Main.hs +8/−5
- twitch.cabal +5/−1
README.md view
@@ -45,7 +45,26 @@ handleHaskellFiles = "src/**/*.hs" |+ addToCabalFile |% reloadFile |- removeFromCabalFile ``` -The glob above is also more complicated and incorporates a recursive wildcard. For+Here is another complex example, using the named `addModify` and `delete` callbacks+to the same function, which build a pdf and a Word document using pandoc, and+refreshes a mupdf window.++```haskell+buildPDFandWordandRefreshWindow _ = do+ pdfLatexCode <- system "pdflatex --interaction errorstopmode -file-line-error -halt-on-error document.tex"+ (pandocCode,pandocOut,pandocErr) <- readProcessWithExitCode "pandoc" [ "--from=latex" , "--to=docx" , "document.tex" , "-o" , "document.docx" ] ""+ (xwininfoCode,xwininfoOut,xwininfoErr) <- readProcessWithExitCode "xwininfo" ["-root", "-int", "-all"] ""+ let windowId = head . words . head . filter (isInfixOf "document") $ lines xwininfoOut+ (xDoToolCode,xDoToolOut,xDoToolErr) <- readProcessWithExitCode "xdotool" ["key", "--window", windowId, "r"] ""+ return ()++main :: IO ()+main = defaultMain $ do+ addModify buildPDFandWordandRefreshWindow "src/**/*.tex"+ delete buildPDFandWordandRefreshWindow "src/**/*.tex"+```++The globs in the above two examples are also more complicated and incorporate recursive wildcards. For complete documentation on the glob syntax, consult the [Glob](https://hackage.haskell.org/package/Glob-0.7.5/docs/System-FilePath-Glob.html#v:compile) library's documentation.@@ -67,3 +86,5 @@ "*.md" |> [s|pandoc -t html -o$directory$basename-test.html $path|] "*.html" |> [s|osascript refreshSafari.AppleScript|] ```++For an alternative command line interface take a look at [twitch-cli](https://github.com/grafted-in/twitch-cli)
src/Twitch.hs view
@@ -1,64 +1,83 @@--- | Twitch is a monadic DSL and library for file watching. --- It conveniently utilizes 'do' notation in the style of --- <https://hackage.haskell.org/package/shake Shake> and +-- | Twitch is a monadic DSL and library for file watching.+-- It conveniently utilizes 'do' notation in the style of+-- <https://hackage.haskell.org/package/shake Shake> and -- <https://hackage.haskell.org/package/clay clay> to expose the functionality of the--- <http://hackage.haskell.org/package/fsnotify fsnotify> cross-platform file system +-- <http://hackage.haskell.org/package/fsnotify fsnotify> cross-platform file system -- watcher.--- +-- -- Here is an example that converts Markdown files to HTML and reloads Safari -- whenever the input files change.--- +-- -- > {-# LANGUAGE OverloadedStrings #-}--- > import Twitch +-- > import Twitch -- > import Filesystem.Path.CurrentOS--- > +-- > -- > main = defaultMain $ do--- > "*.md" |> \filePath -> system $ "pandoc -t html " ++ encodeString filePath +-- > "*.md" |> \filePath -> system $ "pandoc -t html " ++ encodeString filePath -- > "*.html" |> \_ -> system $ "osascript refreshSafari.AppleScript"--- --- Rules are specified in the 'Dep' (for Dependency) monad. The library takes advantage +--+-- Rules are specified in the 'Dep' (for Dependency) monad. The library takes advantage -- of the OverloadedStrings extension to create a 'Dep' value from a glob pattern.--- +-- -- After creating a 'Dep' value using a glob, event callbacks are added using prefix -- or infix API.--- --- There are three types of events: \'add\', \'modify\' and \'delete\'. In many cases, --- the \'add\' and \'modify\' responses are the same, so an \'add and modify\' API +--+-- There are three types of events: \'add\', \'modify\' and \'delete\'. In many cases,+-- the \'add\' and \'modify\' responses are the same, so an \'add and modify\' API -- is provided--- --- In the example above, an \'add and modify\' callback was added to both the \"*.md\" --- and \"*.html\" globs using the '|>' operator. --- +--+-- In the example above, an \'add and modify\' callback was added to both the \"*.md\"+-- and \"*.html\" globs using the '|>' operator.+-- -- Although this is the common case, differing callbacks can be added with '|+' (or 'add')--- and '|%' (or 'modify') functions. Finally, delete callbacks are added with +-- and '|%' (or 'modify') functions. Finally, delete callbacks are added with -- '|-' (of 'delete').--- +-- -- Here is a more complex usage example, handling all three events separately.--- --- > handleHaskellFiles :: Dep +--+-- > handleHaskellFiles :: Dep -- > handleHaskellFiles = "src/**/*.hs" |+ addToCabalFile |% reloadFile |- removeFromCabalFile--- --- The glob above is also more complicated and incorporates a recursive wildcard. For--- complete documentation on the glob syntax, consult the --- <https://hackage.haskell.org/package/Glob-0.7.5/docs/System-FilePath-Glob.html#v:compile Glob>+--+-- Here is another complex example, using the named `addModify` and `delete` callbacks+-- to the same function, which build a pdf and a Word document using pandoc, and+-- refreshes a mupdf window.+--+-- ```haskell+-- buildPDFandWordandRefreshWindow _ = do+-- pdfLatexCode <- system "pdflatex --interaction errorstopmode -file-line-error -halt-on-error document.tex"+-- (pandocCode,pandocOut,pandocErr) <- readProcessWithExitCode "pandoc" [ "--from=latex" , "--to=docx" , "document.tex" , "-o" , "document.docx" ] ""+-- (xwininfoCode,xwininfoOut,xwininfoErr) <- readProcessWithExitCode "xwininfo" ["-root", "-int", "-all"] ""+-- let windowId = head . words . head . filter (isInfixOf "document") $ lines xwininfoOut+-- (xDoToolCode,xDoToolOut,xDoToolErr) <- readProcessWithExitCode "xdotool" ["key", "--window", windowId, "r"] ""+-- return ()+--+-- main :: IO ()+-- main = defaultMain $ do+-- addModify buildPDFandWordandRefreshWindow "src/**/*.tex"+-- delete buildPDFandWordandRefreshWindow "src/**/*.tex"+-- ```+--+-- The globs in the above two examples are also more complicated and incorporate recursive wildcards. For+-- complete documentation on the glob syntax, consult the+-- [Glob](https://hackage.haskell.org/package/Glob-0.7.5/docs/System-FilePath-Glob.html#v:compile) -- library's documentation.--- +-- -- Since a command pattern is calling system commands with a file path, a useful addition--- to twitch is the <https://hackage.haskell.org/package/file-command-qq-0.1.0.4 file-command-qq> quasiquoter. +-- to twitch is the <https://hackage.haskell.org/package/file-command-qq-0.1.0.4 file-command-qq> quasiquoter. ----- Here is a slightly more complicated version the example from earlier, using the +-- Here is a slightly more complicated version the example from earlier, using the -- FileCommand quasiquoter.--- +-- -- > {-# LANGUAGE OverloadedStrings #-} -- > {-# LANGUAGE QuasiQuotes #-}--- > import Twitch +-- > import Twitch -- > import FileCommand -- > -- > main = defaultMain $ do -- > "*.md" |> [s|pandoc -t html -o$directory$basename-test.html $path|] -- > "*.html" |> [s|osascript refreshSafari.AppleScript|]--- -module Twitch +--+module Twitch ( Dep , defaultMain -- * Infix API@@ -66,7 +85,7 @@ , (|%) , (|-) , (|>)- , (|#) + , (|#) -- * Prefix API , add , modify@@ -105,7 +124,7 @@ import Twitch.InternalRule ( Config(..), Issue(..), InternalRule ) import Twitch.Main ( DebounceType(..),- Options(Options, debounce, debounceAmount, root,+ Options(Options, debounce, debounceAmount, root, log, logFile, pollInterval, recurseThroughDirectories, usePolling), LoggerType(..), defaultMain,
src/Twitch/Internal.hs view
@@ -11,6 +11,7 @@ import Data.String ( IsString(..) ) import Control.Applicative -- satisfy GHC < 7.10 import Data.Monoid -- satisfy GHC < 7.10+import Data.Semigroup as S -- satisfy GHC < 8.0 import Prelude hiding (FilePath) -- | A polymorphic 'Dep'. Exported for completeness, ignore. @@ -20,9 +21,12 @@ , Monad ) +instance S.Semigroup (DepM a) where+ x <> y = x >> y+ instance Monoid a => Monoid (DepM a) where mempty = return mempty- mappend x y = x >> y+ mappend = (<>) -- | This is the key type of the package, it is where rules are accumulated. type Dep = DepM ()
src/Twitch/InternalRule.hs view
@@ -98,9 +98,10 @@ -- | Run the Rule action associated with the an event fireRule :: Event -> InternalRule -> IO () fireRule event rule = case event of- Added file tyme -> modify rule file tyme- Modified file tyme -> add rule file tyme- Removed file tyme -> delete rule file tyme+ Added file tyme _ -> modify rule file tyme+ Modified file tyme _ -> add rule file tyme+ Removed file tyme _ -> delete rule file tyme+ Unknown _ _ _ -> pure () -- | Test to see if the rule should fire and fire it testAndFireRule :: Config -> Event -> InternalRule -> IO ()
src/Twitch/Main.hs view
@@ -2,6 +2,8 @@ {-# LANGUAGE OverloadedStrings #-} module Twitch.Main where import Control.Applicative -- satisfy GHC < 7.10+import Control.Concurrent ( threadDelay )+import Control.Exception ( finally ) import Data.Monoid import Options.Applicative ( Parser@@ -45,7 +47,7 @@ , isRelative , isValid )-import Control.Monad ( liftM )+import Control.Monad ( forever, liftM ) -- Moved here to suppress redundant import warnings for GHC > 7.10 import Prelude hiding (log, FilePath) -- parse the command line@@ -263,8 +265,9 @@ defaultMainWithOptions options dep = do (root, config, mhandle) <- optionsToConfig options manager <- runWithConfig root config dep- putStrLn "Type anything to quit"- _ <- getLine- for_ mhandle hClose- FS.stopManager manager+ putStrLn "Type Ctrl+C to quit"+ forever (threadDelay maxBound)+ `finally` do+ for_ mhandle hClose+ FS.stopManager manager
twitch.cabal view
@@ -2,7 +2,7 @@ -- documentation, see http://haskell.org/cabal/users-guide/ name: twitch-version: 0.1.7.1+version: 0.1.7.2 synopsis: A high level file watcher DSL description: Twitch is a monadic DSL and library for file watching.@@ -67,6 +67,10 @@ , data-default , fsnotify , optparse-applicative++ if !impl(ghc >= 8.0)+ build-depends: semigroups+ hs-source-dirs: src default-language: Haskell2010 ghc-options: -Wall