ghcid
GHCi based bare bones IDE
https://github.com/ndmitchell/ghcid#readme
LTS Haskell 22.39: | 0.8.9 |
Stackage Nightly 2024-10-31: | 0.8.9 |
Latest on Hackage: | 0.8.9 |
ghcid-0.8.9@sha256:5065e3f0e84f1913c4c1b93e7117cdb1bd73f7310b4069df7c8ba12a9bd8e751,3543
Module documentation for 0.8.9
- Language
- Language.Haskell
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 provide access to the ghci
it starts, doesn’t depend on GHC the library and doesn’t start web servers.
Acknowledgements: This project incorporates significant work from JPMoresmau, who is listed as a co-author.
Using it
Run stack install ghcid
or cabal update && cabal install ghcid
to install it as normal. Then run ghcid "--command=ghci Main.hs"
. The command
is how you start your project in ghci
. If you omit --command
then it will default to stack ghci
if you have the stack.yaml
file and .stack-work
directory, default to ghci
if you have a .ghci
file in the current directory, and otherwise default to cabal repl
.
Personally, I always create a .ghci
file at the root of all my projects, which usually reads something like:
:set -fwarn-unused-binds -fwarn-unused-imports
:set -isrc
:load Main
After that, resize your console and make it so you can see it while working in your editor. On Windows you may wish to pass --topmost
so the console will sit on top of all other windows. On Linux, you probably want to use your window manager to make it topmost or use a tiling window manager.
What you get
On every save you’ll see a list of the errors and warnings in your project. It uses ghci
under the hood, so even relatively large projects should update their status pretty quickly. As an example:
Main.hs:23:10:
Not in scope: `verbosit'
Perhaps you meant `verbosity' (imported from System.Console.CmdArgs)
Util.hs:18:1: Warning: Defined but not used: `foo'
Or, if everything is good, you see:
All good
Please report any bugs you find.
Editor integration
There are a few plugins that integrate Ghcid into editors, notably:
Usage tips
- If you have a
.ghcid
file in the current folder, or a parent folder, the contents of that file will be used as command line arguments. For example, if you always want to pass--command=custom-ghci
then putting that in a.ghcid
file will free you from writing it each time. - There is an article on auto-reloading threepenny-gui apps during development.
- There are a list of general tips for using Ghcid.
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.
Evaluation
Using the ghci
session that ghcid
manages you can also evaluate expressions:
-
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). -
If you pass the
--allow-eval
flag then comments in the source files such as-- $> expr
will runexpr
after loading - see this blog post for more details. Multiline comments are also supported with the following syntax:{- $> expr1 expr2 ... exprN <$ -}
Expressions that read from standard input are likely to hang, given that Ghcid already uses the standard input to interact with Ghci.
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. Other points in the design space include:
- ghcide - a real IDE in your editor.
- reflex-ghci - like Ghcid but with more terminal UI features.
- reflex-ghcide - a full IDE in the terminal.
If I delete a file and put it back it gets stuck.
Yes, that’s a bug in GHCi. If you see GHCi getting confused just kill ghcid
and start it again.
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, consider:
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 (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 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, 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 colors 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]*)
.
What if the error message is too big for my console?
You can let ghcid
print more with --no-height-limit
. The first error message might end up outside of the console view, so you can use --reverse-errors
to flip the order of the errors and warnings. Further error messages are just a scroll away. Finally if you’re going to be scrolling, you can achieve a cleaner experience with the --clear
flag, which clears the console on reload.
I use Alex (.x
) and Happy (.y
) files, how can I check them?
Ghcid only notices when the .hs
files change. To make it respond to other files you can pass the .x
and .y
files to --restart
, e.g. --restart=myparser.y
. As long as you set the initial command to something that runs Happy/Alex (e.g. cabal repl
) then when those files change everything will restart, causing the initial command to be rerun.
How do I run pass command arguments with –test?
ghcid ... --test Main.main --setup ":set args myargs"
Why do I get “addWatch: resource exhausted (No space left on device)” or “openFile: resource exhausted (Too many open files)” on my Mac?
The Mac has a fairly low limit on the number of file handles available. You can increase it with: sudo sysctl -w fs.inotify.max_user_watches=262144; sudo sysctl -p
Changes
0.8.9, released 2023-07-02
#375, fix crash when modules are renamed or deleted in GHC 9.6
#378, write output of the linter into output files
Support newer Win32 libraries
0.8.8, released 2022-09-17
#365, support fsnotify 0.4
#348, improve the no files loaded message
#321, print Ghcide has stopped to the output file.
0.8.7, released 2020-06-06
#319, allow eval multiline commands
0.8.6, released 2020-04-13
#314, report GHC panics as error messages
0.8.5, released 2020-03-19
#311, allow --target with Stack
0.8.4, released 2020-03-15
#309, use cabal repl --repl-options to avoid errors
0.8.3, released 2020-03-10
#306, fix --target to work on exe: targets
0.8.2, released 2020-03-08
#302, --target option for specifying targets for cabal repl
#300, restart on file changes detected by --restart=dir/
0.8.1, released 2020-01-09
#293, passing --allow-eval should disable -fno-code by default
#291, try and be more robust to mucking with the console
0.8, released 2019-12-04
* Add an extra field to GhciError
#288, include the last line of stderr in shutdown messages
0.7.7, released 2019-11-24
#287, only lint reloaded files
0.7.6, released 2019-10-13
#283, support Clashi
#278, allow --lint to take a shell command rather than just an executable
#275, fix error reporting with non .hs/.lhs filenames in LINE pragmas
0.7.5, released 2019-07-04
#263, fix not resizing on terminal resize
#262, add --test-message flag
#253, try and keep the cursor visible after Ctrl-C
#248, add --allow-eval flag to evaluate code snippets
#245, link with -rtsopts to be able to use RTS flags
0.7.4, released 2019-04-17
#237, ability to cope better with large error messages
#237, add --clear, --no-height-limit, --reverse-errors
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
#224, print out overly long files without line breaks
#202, make --verbose print out version, arch, os
0.7.1, released 2018-09-07
#190, load benchmarks as well as tests when using stack
#171, support GHCJSi
#163, allow --run, like --test but defaults to main
#161, if a file disappears, reload as soon as it returns
#162, always disable :set +t (which writes out types)
0.7, released 2018-04-18
#153, show errors/warnings to freshly edited files first
#153, set -j
#154, improve Ctrl-C behaviour and process termination during startup
Require extra-1.6.6
Add --setup actions to send to ghci stdin on startup
#152, make --output for a file ending .json produce JSON output
Make module cycles generate well-formed Load messages
* Add loadFilePosEnd to Load
If a command exits unexpectedly return a failing exit code
#120, use absolute paths everywhere, in case ghci does a cd
Add showPaths function to exercise ":show paths"
#127, use Loaded GHCi configuration message to add .ghci restart
#141, restart if .ghcid changes
#151, make "All good" green
#109, support OverloadedStrings and RebindableSyntax together
Remove support for GHC 7.6
#87, enable HSPEC colors if possible (POSIX only)
#147, move some :set flags to the command line if possible
#148, enable -ferror-spans by default
* #144, allow ANSI escape codes in loadMessage
#144, use color GHC messages where possible
#139, add --color=never to not show Bold output
#142, add startGhciProcess which takes CreateProcess
#146, add --max-messages=N to limit to N messages
0.6.10, released 2018-02-06
#96, make it work even if -fdiagnostics-color is active
#130, pass -fno-it to reduce memory leaks
#132, work even if -fhide-source-paths is set
Add isLoading function to test the constructor
0.6.9, released 2018-01-26
#121, add a --poll flag to use polling instead of notifiers
Require time-1.5 or above
#124, add timestamp to "All good" message
After the test completes write a message
0.6.8, released 2017-11-10
#110, work even if -v0 is passed to ghci
Read additional arguments from .ghcid file if present
0.6.7, released 2017-09-17
#104, add --ignore-loaded flag for use with -fobject-code
#103, deal with new GHC error formatting
0.6.6, released 2016-11-11
#89, exit sooner when the child process exits unexpectedly
Add Eq instance for Ghci
#88, add a --project flag
Rename --notitle flag to --no-title
0.6.5, released 2016-08-10
#82, properly deal with warning messages including spans
#78, support boot files better
Better support for dealing with GHC 8.0 call stack messages
#79, support multiple --test flags
#71, improve multi-project stack support
#74, make sure Cygwin terminals flush output properly
If the test exits then exit ghcid
0.6.4, released 2016-05-13
#69, fix up for stack project with file arguments
0.6.3, released 2016-05-11
#68, add --no-status to avoid printing the reloading message
0.6.2, released 2016-04-25
#63, detect test failures and update the titlebar/icon
#66, add --warnings to run tests even in there are warnings
#62, find stack.yaml in the parent directory
Make --verbose echo all things sent to stdin
#57, support wrappers that access stdin first (e.g. stack)
#67, make --reload/--restart recurse through directories
#61, deal with drive letters in files (for stack on Windows)
#58, improve the --help message
0.6.1, released 2016-04-06
Add --reload to add files that reload, but do not restart
#56, allow --restart to take directories
0.6, released 2016-04-06
#38, implement loading with stack
Add process, quit and execStream to the API
#29, add interrupt function
Add Data instances for the types
Make stopGhci more effective, now kills the underlying process
* Make startGhci take a function to write the buffer to
0.5.1, released 2016-03-02
#17, deal with recursive modules errors properly
#50, use -fno-code when not running tests (about twice as fast)
#44, abbreviate the redundant module import error
#45, add an extra space before the ... message
#42, always show the first error in full
#43, work even if people use break-on-exception flags
#42, make the first error a minimum of 5 lines
0.5, released 2015-06-20
* Add an extra boolean argument to startGhci
Add the number of modules loaded after All good
Print out messages until the prompt comes up
#23, add arguments and change what commands get invoked
#35, change the titlebar icon on Windows
0.4.2, released 2015-06-11
Fix a GHC 7.6 warning
0.4.1, released 2015-06-11
#37, add a --notitle flag
Require extra-1.2
0.4, released 2015-06-07
#33, make Ctrl-C more robust
#31, add an outputfile feature
#32, make newer warnings first (save a file, view its warnings)
#28, fix issues on VIM file saves
#29, support running a quick test on each save
Add a --directory flag to change directory first
#26, use fs-notify to avoid excessive wakeups
#25, detect console size just before using it
0.3.6, released 2015-03-09
#24, don't error out if error/putStrLn are not imported
0.3.5, released 2015-02-25
#19, put errors in bold
#9, display interesting information in the title bar
#7, reload if the .ghci or .cabal file changes
Use nubOrd
Require extra-1.1
0.3.4, released 2014-12-24
#21, if you aren't waiting for any files, exit
0.3.3, released 2014-12-21
#21, if the root file is missing, report an error
#20, avoid an O(n^2) nub
0.3.2, released 2014-11-06
#18, reformat excessively long lines, add a --width flag
0.3.1, released 2014-10-28
Ensure if there are lots of warnings, the first error gets shown
0.3, released 2014-10-24
#11, ignore certain GHCi-only warnings
#13, fix version printing
#8, display Loading... when starting
Require the extra library
#14, figure out the terminal height automatically
0.2, released 2014-10-06
#6, rewrite as a library
Remove duplicate error messages from cabal repl
0.1.3, released 2014-09-29
#2, handle files that get deleted while loaded
#3, flesh out the test suite
#4, give a polite error if ghci does not start
#5, add --topmost flag to make the window topmost
Add a very simple test suite
Default to cabal repl if there is no .ghci file
#1, if there is an IOError just :reload
Say why you are reloading
0.1.1, released 2014-09-27
Support arguments to --command
0.1, released 2014-09-27
Initial version