586 lines
26 KiB
Org Mode
586 lines
26 KiB
Org Mode
#+TITLE: Haskell layer
|
|
|
|
#+TAGS: general|layer|programming|pure
|
|
|
|
[[file:img/haskell.png]]
|
|
|
|
* Table of Contents :TOC_5_gh:noexport:
|
|
- [[#description][Description]]
|
|
- [[#features][Features:]]
|
|
- [[#install][Install]]
|
|
- [[#layer][Layer]]
|
|
- [[#dependencies][Dependencies]]
|
|
- [[#setup-path][Setup PATH]]
|
|
- [[#choosing-a-backend][Choosing a backend]]
|
|
- [[#company-ghci][=company-ghci=]]
|
|
- [[#intero][=intero=]]
|
|
- [[#dante][=dante=]]
|
|
- [[#ghc-mod][=ghc-mod=]]
|
|
- [[#lsp][=lsp=]]
|
|
- [[#optional-extras][Optional extras]]
|
|
- [[#structured-haskell-mode][structured-haskell-mode]]
|
|
- [[#hindent][hindent]]
|
|
- [[#key-bindings][Key bindings]]
|
|
- [[#documentation][Documentation]]
|
|
- [[#debug][Debug]]
|
|
- [[#debug-buffer][Debug Buffer]]
|
|
- [[#repl][REPL]]
|
|
- [[#intero-repl][Intero REPL]]
|
|
- [[#cabal-commands][Cabal commands]]
|
|
- [[#cabal-files][Cabal files]]
|
|
- [[#refactor][Refactor]]
|
|
- [[#ghc-mod-1][Ghc-mod]]
|
|
- [[#insert-template][Insert template]]
|
|
- [[#intero-1][Intero]]
|
|
- [[#syntax-checking][Syntax checking]]
|
|
- [[#flycheck][Flycheck]]
|
|
- [[#hlint][HLint]]
|
|
- [[#ghc-mod-2][ghc-mod]]
|
|
- [[#interactive-haskell-mode][Interactive haskell-mode]]
|
|
- [[#flymake][Flymake]]
|
|
- [[#troubleshooting][Troubleshooting]]
|
|
- [[#faq][FAQ]]
|
|
- [[#the-repl-doesnt-work][The REPL doesn't work]]
|
|
- [[#the-repl-is-stuck][The REPL is stuck]]
|
|
- [[#i-am-using-stack-and-ghc-mod-but-ghc-mod-doesnt-work][I am using =stack= and =ghc-mod=, but =ghc-mod= doesn't work]]
|
|
- [[#ghc-mod-doesnt-work][=ghc-mod= doesn't work]]
|
|
- [[#indentation-doesnt-reset-when-pressing-return-after-an-empty-line][Indentation doesn't reset when pressing return after an empty line]]
|
|
- [[#flycheck-displays-hlint-warnings-but-not-errors][Flycheck displays HLint warnings but not errors]]
|
|
- [[#i-can-see-highlighted-errors-but-they-dont-appear-in-the-error-list][I can see highlighted errors but they don't appear in the error list]]
|
|
- [[#flycheck-doesnt-work][Flycheck doesn't work]]
|
|
- [[#flycheck-doesnt-work-with-stack][Flycheck doesn't work with =stack=]]
|
|
- [[#the-stack-build-directory-is-wrong][The =stack= build directory is wrong]]
|
|
- [[#the-project-root-directory-is-not-set-properly][The Project root directory is not set properly]]
|
|
- [[#haskell-mode-commands-dont-work][haskell-mode commands don't work]]
|
|
- [[#ghc-mod-and-haskell-mode-commands-overlap-how-do-i-know-which-command-belongs-to-what][=ghc-mod= and =haskell-mode= commands overlap. How do I know which command belongs to what?]]
|
|
- [[#some-commands-start-with-ghc--and-some-with-haskell--what-does-that-mean][Some commands start with =ghc-= and some with =haskell-=. What does that mean?]]
|
|
- [[#why-doesnt-the-hlint-flycheck-checker-work-when-the-intero-backend-is-enabled][Why doesn't the HLint Flycheck checker work when the Intero backend is enabled?]]
|
|
|
|
* Description
|
|
This layer adds support for the [[https://www.haskell.org/][Haskell]] language.
|
|
|
|
** Features:
|
|
- syntax highlighting for [[https://github.com/haskell/haskell-mode][haskell source]], [[https://github.com/haskell/haskell-mode][cabal files]], [[https://github.com/bgamari/cmm-mode][C-- source]],
|
|
- auto-completion with one of the selected backends (=intero=, =dante=, =ghci= or
|
|
=ghc-mod=).
|
|
|
|
*This layer is under construction, it needs your contributions and bug reports.*
|
|
|
|
* Install
|
|
** Layer
|
|
To use this configuration layer, add it to your =~/.spacemacs=. You will need to
|
|
add =haskell= to the existing =dotspacemacs-configuration-layers= list in this
|
|
file.
|
|
|
|
** Dependencies
|
|
This layer requires some [[https://www.haskell.org/cabal/][cabal]] packages:
|
|
- =apply-refact= (required by =hlint-refactor=)
|
|
- =hlint= (required by =hlint-refactor=)
|
|
- =stylish-haskell= (optional for =haskell-mode=)
|
|
- =hasktags= (optional)
|
|
- =hoogle= (optional for =haskell-mode= and =helm-hoogle=)
|
|
- =ghc-mod= (optional for completion)
|
|
- =intero= (optional for completion)
|
|
- =hie= (optional for completion)
|
|
|
|
To install them, use the following command (or the =stack= equivalent):
|
|
|
|
#+BEGIN_SRC sh
|
|
$ cabal install apply-refact hlint stylish-haskell hasktags hoogle
|
|
#+END_SRC
|
|
|
|
** Setup PATH
|
|
First of all, make sure that your =$PATH= contains the installation path for
|
|
Haskell tools like =ghc=, =ghci= etc. It depends on how you have installed
|
|
=ghc=, but you can always check it by running =which ghc= in your terminal.
|
|
=Stack= users should only add the installation path of =stack= itself. Usually
|
|
it's =~/.local/bin=.
|
|
|
|
Then make sure that your =$PATH= contains the installation path for the =cabal=
|
|
packages. If you are using =cabal= it should be =~/.cabal/bin= or
|
|
=~/Library/Haskell/bin= (for 'Haskell for Mac' users). If you are using =stack=
|
|
then it should be =~/.local/bin=.
|
|
|
|
For information about setting up =$PATH=, check out the corresponding section in
|
|
the FAQ (~SPC h SPC $PATH RET~).
|
|
|
|
** Choosing a backend
|
|
To choose a default backend set the layer variable =haskell-completion-backend=:
|
|
|
|
#+BEGIN_SRC elisp
|
|
(haskell :variables haskell-completion-backend 'ghci)
|
|
#+END_SRC
|
|
|
|
Note that in order to enable completion, you'll have to enable the
|
|
=auto-completion= layer as well.
|
|
|
|
Alternatively the =lsp= backend will be automatically chosen if the layer =lsp=
|
|
is used and you did not specify any value for =haskell-completion-backend=.
|
|
|
|
Backend can be chosen on a per project basis using directory local variables
|
|
(files named =.dir-locals.el= at the root of a project), an example to use the
|
|
=lsp= backend:
|
|
|
|
#+BEGIN_SRC elisp
|
|
;;; Directory Local Variables
|
|
;;; For more information see (info "(emacs) Directory Variables")
|
|
|
|
((haskell-mode (haskell-completion-backend . lsp)))
|
|
#+END_SRC
|
|
|
|
*Note:* you can easily add a directory local variable with ~SPC f v d~.
|
|
|
|
Supported values for =haskell-completion-backend= arer =intero=, =dante=,
|
|
=ghci=, =ghc-mod=, and =lsp=. =ghci= (=company-ghci=) is used by default unless
|
|
the layer =lsp= is used. =ghci= is the default backend because it doesn't
|
|
require any dependencies, and it works with both =stack= and pure =cabal=
|
|
projects.
|
|
|
|
#+BEGIN_SRC emacs-lisp
|
|
(setq-default dotspacemacs-configuration-layers
|
|
'(auto-completion
|
|
(haskell :variables haskell-completion-backend 'intero)))
|
|
#+END_SRC
|
|
|
|
*** =company-ghci=
|
|
[[https://github.com/juiko/company-ghci][company-ghci]] communicates directly with =ghci=, in order to provide completion.
|
|
To use it, you have to call =haskell-process-load-or-reload= (=SPC s b=).
|
|
|
|
*** =intero=
|
|
=Intero= only works for =stack= users. You can install the =intero= executable
|
|
manually, by calling =stack install intero=, but this step is optional as
|
|
=Intero= installs itself.
|
|
|
|
*** =dante=
|
|
=dante= works for =cabal=, =nix=, =sytx=, and =stack= users.
|
|
=dante= requires Emacs 25.
|
|
|
|
*** =ghc-mod=
|
|
[[http://www.mew.org/~kazu/proj/ghc-mod/][ghc-mod]] enhances =haskell-mode=, with for example code completion, templates,
|
|
case-splitting and much more. In order to use it, you need to install the
|
|
executable with =cabal install ghc-mod= (or the =stack= equivalent).
|
|
|
|
=Stack= users also should make sure that =dist/setup-config= doesn't exist in
|
|
the project root. As it will confuse =ghc-mod=. For more troubleshooting,
|
|
checkout this [[https://github.com/DanielG/ghc-mod/wiki#user-content-known-issues-related-to-stack][document]].
|
|
|
|
Also note that =ghc-mod= only works with the =GHC= version that was used to
|
|
build =ghc-mod=. You can check which version was used by calling
|
|
=ghc-mod --version=.
|
|
|
|
*** =lsp=
|
|
=lsp= requires an appropriate installation of =hie= to provide the Haskell language server.
|
|
=hie= is built on =ghc-mod=, so many of the same considerations apply.
|
|
|
|
Enabling the =lsp= backend requires the =lsp= layer to be enabled, and provides access to
|
|
all the additional =lsp-mode= key bindings. As such it is more of a full backend than just
|
|
a completion backend.
|
|
|
|
** Optional extras
|
|
The Haskell layer supports some extra features, which can be enabled through the
|
|
layer variables.
|
|
|
|
*** structured-haskell-mode
|
|
Currently there is no support for [[https://github.com/chrisdone/structured-haskell-mode][structured-haskell-mode]], since it doesn't play
|
|
very well with non-emacs editing styles ([[https://github.com/chrisdone/structured-haskell-mode/issues/81][structured-haskell-mode/#81]]). Emacs
|
|
editing style users can easily enable it by adding =structured-haskell-mode= to
|
|
the list of =dotspacemacs-additional-packages= in your =.spacemacs= file. For
|
|
more installation instructions, please refer to the official documentation at
|
|
the [[https://github.com/chrisdone/structured-haskell-mode#features][structured-haskell-mode]] page. In case you are a non-emacs editing style user
|
|
and still want to use =structured-haskell-mode= - use it at your own risk.
|
|
|
|
Any contributions that will help to solve issues with =structured-haskell-mode=
|
|
are warmly welcome!
|
|
|
|
*** hindent
|
|
[[https://github.com/commercialhaskell/hindent][hindent]] is an extensible Haskell pretty printer, which lets you reformat your
|
|
code. You need to install the executable with =cabal install hindent= or
|
|
=stack install hindent=.
|
|
|
|
To enable it you have to toggle the variable =haskell-enable-hindent=.
|
|
|
|
See examples [[https://github.com/commercialhaskell/hindent/blob/master/TESTS.md][here]].
|
|
|
|
#+BEGIN_SRC emacs-lisp
|
|
(setq-default dotspacemacs-configuration-layers
|
|
'((haskell :variables haskell-enable-hindent t)))
|
|
#+END_SRC
|
|
|
|
* Key bindings
|
|
All Haskell specific bindings are prefixed with the major-mode leader ~SPC m~.
|
|
|
|
Top-level commands are prefixed by ~SPC m~:
|
|
|
|
| Key binding | Description |
|
|
|-------------+---------------------------------------------------------------------|
|
|
| ~SPC m g g~ | go to definition or tag |
|
|
| ~SPC m g i~ | cycle the Haskell import lines or return to point (with prefix arg) |
|
|
| ~SPC m F~ | format buffer using haskell-stylish |
|
|
| ~SPC m f~ | format declaration using hindent (if enabled) |
|
|
|
|
** Documentation
|
|
Documentation commands are prefixed by ~SPC m h~
|
|
|
|
| Key binding | Description |
|
|
|-------------+----------------------------------------------------------------------------|
|
|
| ~SPC m h d~ | find or generate Haddock documentation for the identifier under the cursor |
|
|
| ~SPC m h f~ | do a helm-hoogle lookup |
|
|
| ~SPC m h h~ | do a Hoogle lookup |
|
|
| ~SPC m h H~ | do a local Hoogle lookup |
|
|
| ~SPC m h i~ | gets information for the identifier under the cursor |
|
|
| ~SPC m h t~ | gets the type of the identifier under the cursor |
|
|
| ~SPC m h y~ | do a Hayoo lookup |
|
|
|
|
** Debug
|
|
Debug commands are prefixed by ~SPC m d~:
|
|
|
|
| Key binding | Description |
|
|
|-------------+--------------------------------------------|
|
|
| ~SPC m d a~ | abandon current process |
|
|
| ~SPC m d b~ | insert breakpoint at function |
|
|
| ~SPC m d B~ | delete breakpoint |
|
|
| ~SPC m d c~ | continue current process |
|
|
| ~SPC m d d~ | start debug process, needs to be run first |
|
|
| ~SPC m d n~ | next breakpoint |
|
|
| ~SPC m d N~ | previous breakpoint |
|
|
| ~SPC m d p~ | previous breakpoint |
|
|
| ~SPC m d r~ | refresh process buffer |
|
|
| ~SPC m d s~ | step into the next function |
|
|
| ~SPC m d t~ | trace the expression |
|
|
|
|
** Debug Buffer
|
|
|
|
| Key binding | Description |
|
|
|-------------+---------------------------------------------|
|
|
| ~RET~ | select object at the point |
|
|
| ~a~ | abandon current computation |
|
|
| ~b~ | break on function |
|
|
| ~c~ | continue the current computation |
|
|
| ~d~ | delete object at the point |
|
|
| ~i~ | step into the next function |
|
|
| ~r~ | refresh the debugger buffer |
|
|
| ~s~ | go to next step to inspect bindings |
|
|
| ~S~ | go to previous step to inspect the bindings |
|
|
| ~t~ | trace the expression |
|
|
|
|
** REPL
|
|
REPL commands are prefixed by ~SPC m s~:
|
|
|
|
| Key binding | Description |
|
|
|-------------+-------------------------------------------------|
|
|
| ~SPC m s b~ | load or reload the current buffer into the REPL |
|
|
| ~SPC m s c~ | clear the REPL |
|
|
| ~SPC m s s~ | show and switch to the REPL |
|
|
| ~SPC m s S~ | show the REPL without switching to it |
|
|
|
|
** Intero REPL
|
|
Intero REPL commands are prefixed by ~SPC m i~:
|
|
|
|
| Key binding | Description |
|
|
|-------------+---------------------------------------------------------------|
|
|
| ~SPC m i c~ | change directory in the backend process |
|
|
| ~SPC m i d~ | reload the module =DevelMain= and then run =DevelMain.update= |
|
|
| ~SPC m i k~ | stop the current worker process and kill its associated |
|
|
| ~SPC m i l~ | list hidden process buffers created by =intero= |
|
|
| ~SPC m i r~ | restart the process with the same configuration as before |
|
|
| ~SPC m i t~ | set the targets to use for stack =ghci= |
|
|
|
|
** Cabal commands
|
|
Cabal commands are prefixed by ~SPC m c~:
|
|
|
|
| Key binding | Description |
|
|
|-------------+------------------------------------------------------------|
|
|
| ~SPC m c a~ | cabal actions |
|
|
| ~SPC m c b~ | build the current cabal project, i.e. invoke =cabal build= |
|
|
| ~SPC m c c~ | compile the current project, i.e. invoke =ghc= |
|
|
| ~SPC m c v~ | visit the cabal file |
|
|
|
|
** Cabal files
|
|
These commands are available in a cabal file.
|
|
|
|
| Key binding | Description |
|
|
|-------------+---------------------------------------------|
|
|
| ~SPC m d~ | add a dependency to the project |
|
|
| ~SPC m b~ | go to benchmark section |
|
|
| ~SPC m e~ | go to executable section |
|
|
| ~SPC m t~ | go to test-suite section |
|
|
| ~SPC m m~ | go to exposed modules |
|
|
| ~SPC m l~ | go to library section |
|
|
| ~SPC m n~ | go to next subsection |
|
|
| ~SPC m p~ | go to previous subsection |
|
|
| ~SPC m s c~ | clear the REPL |
|
|
| ~SPC m s s~ | show the REPL without switching to it |
|
|
| ~SPC m s S~ | show and switch to the REPL |
|
|
| ~SPC m N~ | go to next section |
|
|
| ~SPC m P~ | go to previous section |
|
|
| ~SPC m f~ | find or create source-file under the cursor |
|
|
|
|
** Refactor
|
|
Refactor commands are prefixed by ~SPC m r~:
|
|
|
|
| Key binding | Description |
|
|
|-------------+---------------------------------------------------|
|
|
| ~SPC m r b~ | apply all HLint suggestions in the current buffer |
|
|
| ~SPC m r i~ | reformat imports from anywhere in the buffer |
|
|
| ~SPC m r r~ | apply the HLint suggestion under the cursor |
|
|
| ~SPC m r s~ | list all Intero suggestions |
|
|
|
|
Only some of the HLint suggestions can be applied.
|
|
|
|
To apply the Intero suggestions, press `C-c C-c` when the window is open.
|
|
|
|
Both the HLint and Intero suggestions appear in the same window.
|
|
|
|
** Ghc-mod
|
|
These commands are only available when ghc-mod is enabled.
|
|
|
|
For more info, see
|
|
[[http://www.mew.org/~kazu/proj/ghc-mod/en/emacs.html]]
|
|
|
|
ghc-mod commands are prefixed by ~SPC m m~:
|
|
|
|
| Key binding | Description |
|
|
|-------------+-------------------------------------------|
|
|
| ~SPC t~ | insert template |
|
|
| ~SPC m m u~ | insert template with holes |
|
|
| ~SPC m m a~ | select one of possible cases (=ghc-auto=) |
|
|
| ~SPC m m f~ | replace a hole (=ghc-refine=) |
|
|
| ~SPC m m e~ | expand template haskell |
|
|
| ~SPC m m n~ | go to next type hole |
|
|
| ~SPC m m p~ | go to previous type hole |
|
|
| ~SPC m m >~ | make indent deeper |
|
|
| ~SPC m m <~ | make indent shallower |
|
|
|
|
*** Insert template
|
|
~SPC m m t~ inserts a template. What this means is that in the beginning of a
|
|
buffer, =module Foo where= is inserted. On a function without signature, the
|
|
inferred type is inserted. On a symbol =foo= without definition, =foo =
|
|
undefined= is inserted or a proper module is imported. ~SPC m m u~ inserts a
|
|
hole in this case. On a variable, the case is split. When checking with hlint,
|
|
the original code is replaced with hlint's suggestion if possible.
|
|
|
|
** Intero
|
|
This command is only available when intero is enabled.
|
|
|
|
This top-level command is prefixed by ~SPC m~:
|
|
|
|
| Key binding | Description |
|
|
|-------------+------------------------|
|
|
| ~SPC m g b~ | return from definition |
|
|
|
|
* Syntax checking
|
|
At the moment there are four components, which can check the syntax and indicate
|
|
errors and warnings in the code. Those components are:
|
|
- flycheck
|
|
- hlint (via flycheck)
|
|
- ghc-mod
|
|
- haskell-mode interactive
|
|
|
|
Since all of these components can be active at the same time, it can be tricky to
|
|
know which component is displaying which message, especially when they disagree,
|
|
or if one isn't working. Only flycheck errors (ghc and hlint) are displayed in
|
|
the error list and can be navigated between, using the standard Spacemacs key
|
|
bindings (under ~SPC e~) even though errors from other modes might highlight the
|
|
actual buffer.
|
|
|
|
** Flycheck
|
|
This is the standard Spacemacs way of syntax checking, and it's also the most
|
|
elaborate. You need to install the syntax-checking layer first. Please read the
|
|
layer's [[https://github.com/syl20bnr/spacemacs/tree/develop/layers/+checkers/syntax-checking][documentation]] on how to interact with flycheck.
|
|
|
|
Flycheck has different Haskell checkers: =haskell-ghc=, =haskell-stack-ghc= and
|
|
=haskell-hlint=. Normally it can detect the best one to use automatically, but
|
|
if it doesn't work, then you can change it with ~SPC e s~.
|
|
|
|
** HLint
|
|
HLint is a linter for Haskell. It doesn't detect errors (as long as it can parse
|
|
the file) but bad coding style and code smell. The HLint checker is called
|
|
*after* the flycheck GHC checker.
|
|
|
|
** ghc-mod
|
|
Ghc-mod, when enabled, also does syntax checking. It doesn't highlight errors,
|
|
but instead displays an exclamation point in the fringe. You can navigate
|
|
between errors using =ghc-goto-next-error= (~M-n~) and =ghc-goto-prev-error=
|
|
(~M-p~).
|
|
|
|
** Interactive haskell-mode
|
|
Finally, interactive haskell-mode (~SPC m s b~) also displays errors. These
|
|
errors can be navigated to, from the interactive buffer (by clicking on the
|
|
error) or using =haskell-goto-next-error= (~M-n~) and =haskell-goto-prev-error=
|
|
(~M-p~).
|
|
|
|
** Flymake
|
|
An alternative to syntax checking is to build your projects with
|
|
=flymake-compile=. It doesn't highlight errors in the buffer, but it's more
|
|
reliable. The error navigation is similar to interactive haskell-mode.
|
|
|
|
** Troubleshooting
|
|
Flycheck and ghc-mod can fail silently for miscellaneous reasons. See the [[#faq][FAQ]]
|
|
for troubleshooting.
|
|
|
|
* FAQ
|
|
** The REPL doesn't work
|
|
Usually =haskell-mode= is great at figuring out which interactive process to
|
|
bring up. But if you are experiencing problems with it, then you can help
|
|
=haskell-mode= by setting =haskell-process-type= as in following code:
|
|
|
|
#+BEGIN_SRC emacs-lisp
|
|
(setq-default dotspacemacs-configuration-layers
|
|
'((haskell :variables haskell-process-type 'stack-ghci)))
|
|
#+END_SRC
|
|
|
|
Available options are:
|
|
- ghci
|
|
- cabal-repl
|
|
- cabal-new-repl
|
|
- cabal-dev
|
|
- cabal-ghci
|
|
- stack-ghci
|
|
|
|
** The REPL is stuck
|
|
Make sure that there's a space between the REPL's =λ>= prompt and the cursor.
|
|
When there is no space, then the REPL will behave as if it's stuck. Usually,
|
|
when you enter normal state, the cursor moves backwards by one character, so there
|
|
is no required space when you switch to insert mode. There is a possible
|
|
workaround - just add the following snippet to your =dotspacemacs/user-config=
|
|
function:
|
|
|
|
#+BEGIN_SRC emacs-lisp
|
|
(when (configuration-layer/package-used-p 'haskell)
|
|
(add-hook 'haskell-interactive-mode-hook
|
|
(lambda ()
|
|
(setq-local evil-move-cursor-back nil))))
|
|
#+END_SRC
|
|
|
|
It makes the cursor stay in the right place in the REPL buffer when you enter
|
|
normal state. Which in most cases helps you to avoid the problem with 'stuck'
|
|
REPL.
|
|
|
|
Also, some users might want to start the REPL in insert mode. This is done by
|
|
placing the following snippet in your =dotspacemacs/user-config= function:
|
|
|
|
#+BEGIN_SRC emacs-lisp
|
|
(when (configuration-layer/package-used-p 'haskell)
|
|
(defadvice haskell-interactive-switch (after spacemacs/haskell-interactive-switch-advice activate)
|
|
(when (eq dotspacemacs-editing-style 'vim)
|
|
(call-interactively 'evil-insert))))
|
|
#+END_SRC
|
|
|
|
** I am using =stack= and =ghc-mod=, but =ghc-mod= doesn't work
|
|
Make sure that a =dist= directory doesn't exist in your project root. If it
|
|
exists, just remove it and try again.
|
|
|
|
** =ghc-mod= doesn't work
|
|
First of all - make sure that the version of =ghc= matches the version of =ghc=
|
|
that was used to build =ghc-mod=. To get the latter, call =ghc-mod --version= in
|
|
the terminal. If they don't match then you'll have to rebuild =ghc-mod=.
|
|
|
|
=Stack= provides the ability to use different =ghc= versions across different
|
|
projects. If you're using this feature, then you'll have to rebuild =ghc-mod=
|
|
quite often. If you only use =ghc-mod= for completion, and don't want to rebuild
|
|
=ghc-mod= every time you switch projects, then you'd better disable =ghc-mod=
|
|
support, so that =company-ghci= will be used for completion.
|
|
|
|
The second thing to do if it's still not working - is to call =ghc-mod debug= in
|
|
the root of the project that you're currently working on. Make sure that it
|
|
doesn't show any errors. If there are errors that you can't solve - then it's
|
|
better to report them [[https://github.com/DanielG/ghc-mod][upstream]].
|
|
|
|
** Indentation doesn't reset when pressing return after an empty line
|
|
This is the intended behavior in =haskell-indentation-mode=. If you want to
|
|
reset the indentation when pressing return after an empty line, add the
|
|
following snippet into your =dotspacemacs/user-config= function.
|
|
|
|
#+BEGIN_SRC emacs-lisp
|
|
(defun haskell-indentation-advice ()
|
|
(when (and (< 1 (line-number-at-pos))
|
|
(save-excursion
|
|
(forward-line -1)
|
|
(string= "" (s-trim (buffer-substring (line-beginning-position) (line-end-position))))))
|
|
(delete-region (line-beginning-position) (point))))
|
|
|
|
(advice-add 'haskell-indentation-newline-and-indent
|
|
:after 'haskell-indentation-advice)
|
|
#+END_SRC
|
|
|
|
** Flycheck displays HLint warnings but not errors
|
|
The HLint checker is called *after* the normal flycheck checker, even if the
|
|
checker fails. Check the [[#flycheck-doesnt-work][Flycheck doesn't work]] section.
|
|
|
|
** I can see highlighted errors but they don't appear in the error list
|
|
The error list is only set by flycheck. You are probably seeing errors
|
|
highlighted by either ghc-mode or haskell-mode. Check the [[#flycheck-doesnt-work][Flycheck doesn't work]]
|
|
section.
|
|
|
|
** Flycheck doesn't work
|
|
You can use the =flycheck-compile= command to check what's wrong with flycheck.
|
|
This will show you the exact command line that's used, and its output.
|
|
|
|
If you are using =stack=, check the [[#flycheck-doesnt-work-with-stack][Flycheck doesn't work with =stack=]] section.
|
|
|
|
** Flycheck doesn't work with =stack=
|
|
First check that flycheck uses the correct checker, and all the paths are
|
|
properly configured using =flycheck-verify-setup= (~SPC e v~). You can force the
|
|
checker with =flycheck-select-checker= (~SPC e s~) to ensure that it uses
|
|
=haskell-stack-ghc=. If it still doesn't work, then it could be one of the
|
|
following problems:
|
|
- The =stack= build directory is wrong
|
|
- The project root is not set properly
|
|
|
|
*** The =stack= build directory is wrong
|
|
The path to the build directory, which contains some generated files, is
|
|
normally under =.stack-work/install/<os>/Cabal-<version>/build=.
|
|
|
|
However the version of the cabal library that's used by =stack= to generate the
|
|
directory name is not the version of the cabal library that's installed by
|
|
=stack= but rather the version of cabal that's associated to the GHC version.
|
|
This error can happen after upgrading cabal or cabal-install. To check if this
|
|
is the problem, compare the path name of the build path that's used by flycheck
|
|
using =flycheck-compile= and compare it to the actual path in the =.stack-work=
|
|
directory. If they are different, then you'll need to reinstall ghc using the
|
|
command =stack setup --upgrade-cabal=.
|
|
|
|
*** The Project root directory is not set properly
|
|
Flycheck launches the GHC command, not from the project root directory, but from
|
|
the directory of the file that's being checked. This is normally not a problem,
|
|
as all the paths are set properly, however it could be a problem if some
|
|
template Haskell functions use relative paths (e.g. in Yesod scaffolded
|
|
projects).
|
|
|
|
Until it's fixed in flycheck, the workaround is to wrap the =stack= command in
|
|
order to run all subcommands from the project's root directory. You can do so
|
|
with the following script:
|
|
|
|
#+BEGIN_SRC bash
|
|
#!/bin/bash
|
|
cd `stack --project-root`
|
|
stack $*
|
|
#+END_SRC
|
|
|
|
Make sure you set =flycheck-haskell-stack-ghc-executable= to this script.
|
|
|
|
** haskell-mode commands don't work
|
|
Some (most) of the haskell-mode commands only work when haskell-mode is in
|
|
interactive mode, i.e. has an interactive session associated with it. Load it
|
|
using ~SPC m s b~.
|
|
|
|
** =ghc-mod= and =haskell-mode= commands overlap. How do I know which command belongs to what?
|
|
ghc-mod commands are prefixed with =ghc-=, haskell-mode ones are prefixed with
|
|
=haskell-=.
|
|
|
|
** Some commands start with =ghc-= and some with =haskell-=. What does that mean?
|
|
Commands starting with =ghc-= are ghc-mod commands. Commands starting with
|
|
=haskell-= are haskell-mode commands.
|
|
|
|
** Why doesn't the HLint Flycheck checker work when the Intero backend is enabled?
|
|
By default, only the Intrero checker will be enabled if you manually set the
|
|
Intero backend as described in [[#choosing-a-backend][Choosing a backend]].
|
|
|
|
To also enable the HLint checker, use =flycheck-add-next-checker= to set the
|
|
HLint checker after the Intero checker.
|
|
|
|
#+BEGIN_SRC emacs-lisp
|
|
(defun dotspacemacs/user-init ()
|
|
(with-eval-after-load 'intero
|
|
(flycheck-add-next-checker 'intero '(warning . haskell-hlint))))
|
|
#+END_SRC
|