summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorNeilMitchell <>2019-04-15 13:55:00 (GMT)
committerhdiff <hdiff@hdiff.luite.com>2019-04-15 13:55:00 (GMT)
commitb7c51ed4b6ad2f8f195b1acbc86c3f97b3739d70 (patch)
treea7009ecd22a1c286c4a48b29ff645261a6e0dbff
parenteb0065c599896e08a26cf1da71ec71627c10c2eb (diff)
version 0.7.30.7.3
-rw-r--r--CHANGES.txt2
-rw-r--r--README.md39
-rw-r--r--ghcid.cabal2
-rw-r--r--src/Ghcid.hs10
4 files changed, 41 insertions, 12 deletions
diff --git a/CHANGES.txt b/CHANGES.txt
index 789ab6a..250a806 100644
--- a/CHANGES.txt
+++ b/CHANGES.txt
@@ -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
diff --git a/README.md b/README.md
index efd5efe..96c79ea 100644
--- a/README.md
+++ b/README.md
@@ -1,4 +1,4 @@
-# ghcid [![Hackage version](https://img.shields.io/hackage/v/ghcid.svg?label=Hackage)](https://hackage.haskell.org/package/ghcid) [![Stackage version](https://www.stackage.org/package/ghcid/badge/nightly?label=Stackage)](https://www.stackage.org/package/ghcid) [![Linux Build Status](https://img.shields.io/travis/ndmitchell/ghcid/master.svg?label=Linux%20build)](https://travis-ci.org/ndmitchell/ghcid) [![Windows Build Status](https://img.shields.io/appveyor/ci/ndmitchell/ghcid/master.svg?label=Windows%20build)](https://ci.appveyor.com/project/ndmitchell/ghcid)
+# ghcid [![Hackage version](https://img.shields.io/hackage/v/ghcid.svg?label=Hackage)](https://hackage.haskell.org/package/ghcid) [![Stackage version](https://www.stackage.org/package/ghcid/badge/nightly?label=Stackage)](https://www.stackage.org/package/ghcid) [![Linux build status](https://img.shields.io/travis/ndmitchell/ghcid/master.svg?label=Linux%20build)](https://travis-ci.org/ndmitchell/ghcid) [![Windows build status](https://img.shields.io/appveyor/ci/ndmitchell/ghcid/master.svg?label=Windows%20build)](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 are a few plugins that integrate Ghcid into editors, notably:
* 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]*)`.
diff --git a/ghcid.cabal b/ghcid.cabal
index 96dc841..37d1697 100644
--- a/ghcid.cabal
+++ b/ghcid.cabal
@@ -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
diff --git a/src/Ghcid.hs b/src/Ghcid.hs
index 20e6f34..f12addb 100644
--- a/src/Ghcid.hs
+++ b/src/Ghcid.hs
@@ -22,6 +22,7 @@ import System.Directory.Extra
import System.Time.Extra
import System.Exit
import System.FilePath
+import System.Process
import System.Info
import System.IO.Extra
@@ -43,6 +44,7 @@ data Options = Options
,test :: [String]
,run :: [String]
,warnings :: Bool
+ ,lint :: Maybe String
,no_status :: Bool
,height :: Maybe Int
,width :: Maybe Int
@@ -75,6 +77,7 @@ options = cmdArgsMode $ Options
,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 @@ runGhcid session waiter termSize termOutput opts@Options{..} = do
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 @@ runGhcid session waiter termSize termOutput opts@Options{..} = do
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