ghcid 0.7.2 → 0.7.3
raw patch · 4 files changed
+41/−12 lines, 4 filesPVP ok
version bump matches the API change (PVP)
API changes (from Hackage documentation)
Files
- CHANGES.txt +2/−0
- README.md +29/−10
- ghcid.cabal +1/−1
- src/Ghcid.hs +9/−1
CHANGES.txt view
@@ -1,5 +1,7 @@ Changelog for ghcid (* = breaking change) +0.7.3, released 2019-04-15+ #236, add hlint support, pass --lint 0.7.2, released 2019-03-12 #225, allow watching directories for new files #226, fix the polling behaviour
README.md view
@@ -1,4 +1,4 @@-# ghcid [](https://hackage.haskell.org/package/ghcid) [](https://www.stackage.org/package/ghcid) [](https://travis-ci.org/ndmitchell/ghcid) [](https://ci.appveyor.com/project/ndmitchell/ghcid)+# ghcid [](https://hackage.haskell.org/package/ghcid) [](https://www.stackage.org/package/ghcid) [](https://travis-ci.org/ndmitchell/ghcid) [](https://ci.appveyor.com/project/ndmitchell/ghcid) Either "GHCi as a daemon" or "GHC + a bit of an IDE". To a first approximation, it opens `ghci` and runs `:reload` whenever your source code changes, formatting the output to fit a fixed height console. Unlike other Haskell development tools, `ghcid` is intended to be _incredibly simple_. In particular, it doesn't integrate with any editors, doesn't depend on GHC the library and doesn't start web servers. @@ -45,14 +45,33 @@ * There is an article on [auto-reloading threepenny-gui apps during development](https://binarin.ru/post/auto-reload-threepenny-gui/). * There are a list of [general tips for using Ghcid](http://www.parsonsmatt.org/2018/05/19/ghcid_for_the_win.html). +In general, to use `ghcid`, you first need to get `ghci` working well for you. In particular, craft a command line or `.ghci` file such that when you start `ghci` it has loaded all the files you care about (check `:show modules`). If you want to use `--test` check that whatever expression you want to use works in that `ghci` session. Getting `ghci` started properly is one of the hardest things of using `ghcid`, and while `ghcid` has a lot of defaults for common cases, it doesn't always work out of the box.+ ### FAQ -* _This isn't as good as full IDE._ I've gone for simplicity over features. It's a point in the design space, but not necessarily the best point in the design space for you. For "real" IDEs see [the Haskell wiki](http://www.haskell.org/haskellwiki/IDEs).-* _If I delete a file and put it back it gets stuck._ Yes, that's a [bug in GHCi](https://ghc.haskell.org/trac/ghc/ticket/9648). If you see GHCi getting confused just kill `ghcid` and start it again.-* _I want to run my tests when files change._ You can pass any `ghci` expression with the `--test` flag, e.g. `--test=:main`, which will be run whenever the code is warning free (or pass `--warnings` for when the code is merely error free).-* _I want to run arbitrary commands when arbitrary files change._ This project reloads `ghci` when files loaded by `ghci` change. If you want a more general mechanism something like [Steel Overseer](https://github.com/schell/steeloverseer) or [Watchman](https://facebook.github.io/watchman/) will probably work better.-* _I want syntax highlighting in the error messages._ One option is to use Neovim or Emacs and run the terminal in a buffer whose file type is set to Haskell. Another option is to pipe `ghcid` through [source-highlight](https://www.gnu.org/software/src-highlite/) (`ghcid | source-highlight -s haskell -f esc`).-* _I'm not seeing pattern matching warnings._ Ghcid automatically appends `-fno-code` to the command line, which makes the reload cycle about twice as fast. Unfortunately GHC 8.0 and 8.2 suffer from [bug 10600](https://ghc.haskell.org/trac/ghc/ticket/10600) which means `-fno-code` also disables pattern matching warnings. On these versions, either accept no pattern match warnings or use `-c` to specify a command line to start `ghci` that doesn't include `-fno-code`. From GHC 8.4 this problem no longer exists.-* _I get "During interactive linking, GHCi couldn't find the following symbol"._ This problem is a manifestation of [GHC bug 8025](https://ghc.haskell.org/trac/ghc/ticket/8025), which is fixed in GHC 8.4 and above. Ghcid automatically appends `-fno-code` to the command line, but for older GHC's you can supress that with `--test "return ()"` (to add a fake test) or `-c "ghci ..."` to manually specify the command to run.-* _I only see source-spans or error messages on errors/warnings after the first load._ Due to limitations in `ghci`, these flags are only set _after_ the first load. If you want them to apply from the start, pass them on the command line to `ghci` with something like `-c "ghci -ferror-spans -fdiagnostics-color=always".-* _I want to match on the file/line/column to get jump-to-error functionality in my editor._ You will variously see `file:line:col:message`, `file:line:col1-col2:msg` and `file:(line1,col1)-(line2,col2):message`, as these are the formats GHC uses. To match all of them you can use a regular expression such as `^(\\S*?):(?|(\\d+):(\\d+)(?:-\\d+)?|\\((\\d+),(\\d+)\\)-\\(\\d+,\\d+\\)):([^\n]*)`.+#### This isn't as good as full IDE+I've gone for simplicity over features. It's a point in the design space, but not necessarily the best point in the design space for you. For "real" IDEs see [the Haskell wiki](http://www.haskell.org/haskellwiki/IDEs).++#### If I delete a file and put it back it gets stuck.+Yes, that's a [bug in GHCi](https://ghc.haskell.org/trac/ghc/ticket/9648). If you see GHCi getting confused just kill `ghcid` and start it again.++#### I want to run my tests when files change.+You can pass any `ghci` expression with the `--test` flag, e.g. `--test=:main`, which will be run whenever the code is warning free (or pass `--warnings` for when the code is merely error free).++#### I want to run arbitrary commands when arbitrary files change.+This project reloads `ghci` when files loaded by `ghci` change. If you want a more general mechanism something like [Steel Overseer](https://github.com/schell/steeloverseer) or [Watchman](https://facebook.github.io/watchman/) will probably work better.++#### I want syntax highlighting in the error messages.+One option is to use Neovim or Emacs and run the terminal in a buffer whose file type is set to Haskell. Another option is to pipe `ghcid` through [source-highlight](https://www.gnu.org/software/src-highlite/) (`ghcid | source-highlight -s haskell -f esc`).++#### I'm not seeing pattern matching warnings.+Ghcid automatically appends `-fno-code` to the command line, which makes the reload cycle about twice as fast. Unfortunately GHC 8.0 and 8.2 suffer from [bug 10600](https://ghc.haskell.org/trac/ghc/ticket/10600) which means `-fno-code` also disables pattern matching warnings. On these versions, either accept no pattern match warnings or use `-c` to specify a command line to start `ghci` that doesn't include `-fno-code`. From GHC 8.4 this problem no longer exists.++#### I get "During interactive linking, GHCi couldn't find the following symbol"+This problem is a manifestation of [GHC bug 8025](https://ghc.haskell.org/trac/ghc/ticket/8025), which is fixed in GHC 8.4 and above. Ghcid automatically appends `-fno-code` to the command line, but for older GHC's you can supress that with `--test "return ()"` (to add a fake test) or `-c "ghci ..."` to manually specify the command to run.++#### I only see source-spans or error messages on errors/warnings after the first load.+Due to limitations in `ghci`, these flags are only set _after_ the first load. If you want them to apply from the start, pass them on the command line to `ghci` with something like `-c "ghci -ferror-spans -fdiagnostics-color=always"`.++#### I want to match on the file/line/column to get jump-to-error functionality in my editor.+You will variously see `file:line:col:message`, `file:line:col1-col2:msg` and `file:(line1,col1)-(line2,col2):message`, as these are the formats GHC uses. To match all of them you can use a regular expression such as `^(\\S*?):(?|(\\d+):(\\d+)(?:-\\d+)?|\\((\\d+),(\\d+)\\)-\\(\\d+,\\d+\\)):([^\n]*)`.
ghcid.cabal view
@@ -1,7 +1,7 @@ cabal-version: >= 1.18 build-type: Simple name: ghcid-version: 0.7.2+version: 0.7.3 license: BSD3 license-file: LICENSE category: Development
src/Ghcid.hs view
@@ -22,6 +22,7 @@ import System.Time.Extra import System.Exit import System.FilePath+import System.Process import System.Info import System.IO.Extra @@ -43,6 +44,7 @@ ,test :: [String] ,run :: [String] ,warnings :: Bool+ ,lint :: Maybe String ,no_status :: Bool ,height :: Maybe Int ,width :: Maybe Int@@ -75,6 +77,7 @@ ,test = [] &= name "T" &= typ "EXPR" &= help "Command to run after successful loading" ,run = [] &= name "r" &= typ "EXPR" &= opt "main" &= help "Command to run after successful loading (defaults to main)" ,warnings = False &= name "W" &= help "Allow tests to run even with warnings"+ ,lint = Nothing &= typ "COMMAND" &= name "lint" &= opt "hlint" &= help "Linter to run if there are no errors. Defaults to hlint." ,no_status = False &= name "S" &= help "Suppress status messages" ,height = Nothing &= help "Number of lines to use (defaults to console height)" ,width = Nothing &= name "w" &= help "Number of columns to use (defaults to console width)"@@ -281,8 +284,9 @@ let (countErrors, countWarnings) = both sum $ unzip [if loadSeverity == Error then (1,0) else (0,1) | m@Message{..} <- messages, loadMessage /= []]+ let hasErrors = countErrors /= 0 || (countWarnings /= 0 && not warnings) test <- return $- if null test || countErrors /= 0 || (countWarnings /= 0 && not warnings) then Nothing+ if null test || hasErrors then Nothing else Just $ intercalate "\n" test unless no_title $ setWindowIcon $@@ -326,6 +330,10 @@ else do updateTitle "(test done)" whenNormal $ outStrLn "\n...done"+ whenJust lint $ \lintcmd ->+ unless hasErrors $ do+ (exitcode, stdout, stderr) <- readProcessWithExitCode lintcmd loaded ""+ unless (exitcode == ExitSuccess) $ outStrLn (stdout ++ stderr) reason <- nextWait $ restart ++ reload ++ loaded whenLoud $ outStrLn $ "%RELOADING: " ++ unwords reason