Persistent GHC powered background server for FAST Haskell development tools
hdevtools is a backend for text editor plugins, to allow for things such as
syntax and type checking of Haskell code, and retrieving type information, all
directly from within your text editor.
The advantage that
hdevtools has over competitors, is that it runs silently
in a persistent background process, and therefore is able to keeps all of your
Haskell modules and dependent libraries loaded in memory. This way, when you
change only a single source file, only it needs to be reloaded and rechecked,
instead of having to reload everything.
hdevtools very fast for checking syntax and type errors (runs just
as fast as the
:reload command in GHCi).
In fact, syntax and type checking is so fast, that you can safely enable auto checking on every save. Even for huge projects, checking is nearly instant.
Once you start using
hdevtools and you get used to having your errors shown
to you instantly (without having to switch back and forth between GHCi and your
editor), and shown directly on your code, in your editor (without having to
wait forever for GHC to run) you will wonder how you ever lived without it.
In addition to checking Haskell source code for errors,
hdevtools has tools
for getting info about identifiers, and getting type information for snippets
Text Editor Integration
hdevtools is designed to be integrated into text editors. The list of current
editor plugins that supply this integration is below.
$ stack install hdevtools
hdevtools automatically discovers compiler and libraries installed
Alternatively one can install from Hackage via cabal install:
$ cabal install hdevtools
Then you should install one or more of the following editor plugins:
Vim - Syntastic
Syntastic is a popular syntax checking plugin for Vim, and is the
recommended Vim integration of
hdevtools syntax and type checking. Recent
versions of Syntastic(since Sep. 2012) have builtin support for
hdevtools (as above) and Syntastic, and it will
automatically check your Haskell files.
Vim - vim-hdevtools
In addition to Syntastic, it is recommended that you also use
vim-hdevtools for additional functionality.
vim-hdevtools offers integration with the rest of the
including retrieving info about the identifier under the cursor, and getting
the type of the code under the cursor. Refer to its documentation for more
Emacs - flycheck
Atom - linter
There are two packages for the Atom editor:
- linter-hdevtools quickly finds and underlines type errors in Haskell files,
- hover-tooltips-hdevtools displays the types of identifiers under the mouse.
Sublime - SublimeLinter
Manual Editor Integration for any Editor
Most editors allow you to run a
make command, and will then parse the output
for errors and show line numbers, allowing you to jump between errors.
hdevtools check command is suitable for such usage.
For example, in Vim something like this will work:
:let &makeprg='hdevtools check %'
(Vim will replace the
% character with the name of the current file). Then
you can run
And Vim will invoke
hdevtools to check the current file for errors, and then
show a list of them and allow jumping to them.
See the "Command Line Usage" section below for more information.
Command Line Usage
Note: When using one of the above editor plugins, you don't really need to know this.
Available Commands and Help
For the list of commands available, run:
$ hdevtools --help
To get help for a specific command, run:
$ hdevtools [COMMAND] --help
$ hdevtools check --help
hdevtools background process
The first time
hdevtools runs a command, it will spawn a background process
that will remain running forever. You can check the status of this background
process by running:
$ hdevtools --status
You can shutdown the background process by running:
$ hdevtools --stop-server
Communication with the background process is done through a unix socket file.
The default name is
.hdevtools.sock, in the current directory. This allows
you to use
hdevtools with multiple projects simultaneously, without the
background processes getting in the way of each other.
You can use a different socket file name with the
--socket option, which
should be used for each invocation of
hdevtools. Remember that when telling
hdevtools to check a Haskell file, paths are relative to the path of the
background process, not your current directory. This can cause problems, and
therefore it is recommended that you leave the socket file as the default, and
hdevtools from the same directory.
You can specify the path to a target file with the
--path option. This is
useful for integration with IDEs that submit a copy of the original source
file (in a temporary directory) to
hdevtools making it impossible to extract
.cabal information for the file's project. In such cases, you can run as:
$ hdevtools check -p /path/to/file.hs /tmp/file.hs
hdevtools will use the given path to obtain the
Specifying GHC Options
For most non-trivial projects, you will need to tell
additional GHC options that your project requires.
hdevtools commands accept a
-g flag for this purpose.
- Your project source code is in the directory
- You want to use the GHC option
- You want to hide the package
transformersto prevent conflicts
hdevtools with something like this:
$ hdevtools check -g -isrc -g -Wall -g -hide-package -g transformers Foo.hs
Notice that a
-g flag is inserted before each GHC option. Don't try to string
multiple GHC options together after a single
This won't work:
$ hdevtools check -g '-hide-package transformers' Foo.hs
In general, you will need to pass to
hdevtools the same GHC options that you
would pass to GHCi.
For projects with custom build systems, you can prevent
detecting a global
stack.yaml configuration with the argument
Specifying GHC Options in Vim
The Vim plugins allow setting GHC options in the
variable. For example, for the above project, put the following in your
let g:hdevtools_options = '-g -isrc -g -Wall -g -hide-package -g transformers'
Specifying GHC Options with
.hdevtoolsrc file is present, then
parse arguments from the
.hdevtoolsrc file after arguments from the command
For example, for the above project, the
.hdevtoolsrc file would contain:
-g -isrc -g -Wall -g -hide-package -g transformers
.hdevtoolsrc file will be searched for in the target path and all parents
of the target path, or, if the
hdevtools command has no target, in
all parents of
0.1.6.0 - 2017-08-21
- Added handling of source errors: GHC
SourceErrorand other exceptions are now correctly sent to the frontend process. This enables
hdevtoolsto correctly report haskell syntax errors and improves visibility of exceptions leading the backend process to die.
.hdevtoolsrcfile for project-specific configuration.
- Use of
stackcan be turned off with
0.1.5.0 - 2016-12-23
- (Re-)added template haskell support when required. Can be turned off using
- Fixed system installed GHC libdir paths using stack.
0.1.4.1 - 2016-09-04
Do not try to execute
stackcommands if not available.
0.1.4.0 - 2016-08-08
Determine GHC libdir and binaries using stack.
0.1.3.2 - 2016-06-09
Added GHC 8.0.x support
0.1.3.1 - 2016-05-13
- Added support for new Cabal versions
- Do not generate code, fixing inline-c modules typechecking
0.1.3.0 - 2016-02-29
Improved performance in stack projects: The stack configuration is updated only when the passed path implies a different
stack.yaml. Performance improved substantially from roughly ~1s to ~0.3s.
0.1.2.2 - 2016-01-11
- Added type checking support for tests and benchmarks in stack projects.