2fec4a49be
Using the correct target for the Haskell session is required when working on a project with more than one target defined in the Cabal file.
482 lines
23 KiB
Org Mode
482 lines
23 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:]]
|
|
- [[#quick-start-and-how-to-use-this-readme][Quick start (and how to use this README)]]
|
|
- [[#install][Install]]
|
|
- [[#layer][Layer]]
|
|
- [[#dependencies][Dependencies]]
|
|
- [[#setup-path][Setup PATH]]
|
|
- [[#configuration][Configuration]]
|
|
- [[#choosing-a-backend][Choosing a backend]]
|
|
- [[#dante][=dante=]]
|
|
- [[#lsp][=lsp=]]
|
|
- [[#hie][=hie=]]
|
|
- [[#hls][=hls=]]
|
|
- [[#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]]
|
|
- [[#cabal-commands][Cabal commands]]
|
|
- [[#cabal-files][Cabal files]]
|
|
- [[#refactor][Refactor]]
|
|
- [[#syntax-checking][Syntax checking]]
|
|
- [[#flycheck][Flycheck]]
|
|
- [[#hlint][HLint]]
|
|
- [[#faq][FAQ]]
|
|
- [[#dante-reports-missinghidden-imports-for-test-files][Dante reports missing/hidden imports for test files]]
|
|
- [[#the-repl-doesnt-work][The REPL doesn't work]]
|
|
- [[#the-repl-is-stuck][The REPL is stuck]]
|
|
- [[#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]]
|
|
- [[#hlint-fails-with-parse-error][HLint fails with parse error]]
|
|
- [[#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]]
|
|
|
|
* 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 and syntax-checking with one of the selected backends (=dante= or =lsp=).
|
|
|
|
* Quick start (and how to use this README)
|
|
- Follow instructions in *Install* section to correctly install the layer.
|
|
- Ensure that you have =auto-completion= and =syntax-checking= layers enabled.
|
|
- Set backend to =dante= (check *Configuration* section for details). =dante= is default already, but if =lsp= layer is enabled, you will have to set it explicitly.
|
|
- You are ready to go! Open any Haskell project and enjoy syntax-checking, auto-completion and more.
|
|
|
|
After that, check the rest of the README to:
|
|
- Learn about more powerful (but more complicated to set up) backend: =lsp= with =hie= / =hls=: Check *Configuration* -> *lsp*.
|
|
- Learn about all the functionalities and key bindings: Check *Key bindings* and *Configuration* -> *Optional extras*.
|
|
- Learn about the details of how syntax-checking works and how it can be tweaked: Check *Syntax checking*.
|
|
- Find solutions to common problems in FAQ: Check *FAQ*.
|
|
|
|
* 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=)
|
|
|
|
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 more information about setting up =$PATH=, check out the corresponding section in
|
|
the FAQ (~SPC h SPC $PATH RET~).
|
|
|
|
* Configuration
|
|
** Choosing a backend
|
|
Language backend is the core component of a language layer - it has the responsibility of compiling/parsing the actual code and reporting errors, warnings, suggesting fixes, auto-completions and more.
|
|
|
|
To get the most out of the language backend, you will want to ensure that you have =auto-completion= and =syntax-checking= layers enabled.
|
|
|
|
Then, to choose a haskell backend, set the haskell layer variable =haskell-completion-backend=:
|
|
|
|
#+BEGIN_SRC emacs-lisp
|
|
(haskell :variables haskell-completion-backend 'dante)
|
|
#+END_SRC
|
|
|
|
Supported values for =haskell-completion-backend= are =dante= and =lsp=.
|
|
|
|
If you don't specify any value for =haskell-completion-backend=,
|
|
=dante= will be used as default backend, unless the layer =lsp= is enabled,
|
|
in which case =lsp= is used as default 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 of =.dir-locals.el= 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~.
|
|
|
|
There are two backends available: =dante= and =lsp=.
|
|
|
|
=dante= is lightweight, requires no setup and works out of the box in most cases, which is why it is also a default backend.
|
|
|
|
=lsp= (=hie= or =hls=) is a more ambitious, heavy-weight, cutting-edge backend that is however still somewhat rough on the edges and requires some additional setup.
|
|
|
|
*** =dante=
|
|
[[https://github.com/jyp/dante][Dante]] is a lightweight backend which delegates most of its work directly to GHCi.
|
|
|
|
It brings features like syntax checking, auto completion, hlint suggestions, automatic error fixing, info at point, definition and use sites.
|
|
|
|
=dante= works for =cabal=, =nix=, =sytx=, and =stack= users and requires no additional setup.
|
|
|
|
*** =lsp=
|
|
[[https://microsoft.github.io/language-server-protocol][Language Server Protocol]] is a standard for implementing language backends.
|
|
|
|
In Haskell layer, you can use a backend that implements Language Server Protocol for Haskell by specifying =lsp= as backend
|
|
and then installing concrete backend implementation, of which there are two available at the moment: =hie= and =hls=.
|
|
|
|
Enabling the =lsp= backend requires the =lsp= layer to be enabled, and provides access to
|
|
all the additional =lsp-mode= key bindings.
|
|
|
|
**** =hie=
|
|
[[https://github.com/haskell/haskell-ide-engine][Haskell Ide Engine]] (=hie=) aims to be the universal interface to a growing number of Haskell tools,
|
|
providing a fully-featured Language Server Protocol server for editors and IDEs that require Haskell-specific functionality.
|
|
|
|
This is where most of the Haskell community effort is (was - check =hls=) being focused regarding building Haskell IDE / language backend.
|
|
|
|
=hie= is best installed by building it locally as it requires that the same GHC version has been used to
|
|
compile your code as has been used for =hie=.
|
|
|
|
To install it please refer to the official installation instructions [[https://github.com/haskell/haskell-ide-engine#installation][here]].
|
|
|
|
NOTE: =hie= is being superseded by =hls=, which is still in early development though.
|
|
|
|
**** =hls=
|
|
[[https://github.com/haskell/haskell-language-server][Haskell Language Server]] (=hls=) is integration point for ghcide and =hie=. One IDE to rule them all.
|
|
|
|
=hls= is meant to supersede =hie= and is therefore the cutting-edge and most ambitious implementation of Haskell language backend.
|
|
However, it is still in early stages of development.
|
|
|
|
Check their docs for installation details and how to use it with emacs/spacemacs.
|
|
|
|
** 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 |
|
|
|
|
** 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 |
|
|
| ~SPC m s t~ | change the target for the REPL |
|
|
| ~C-j~ | switch to next history item |
|
|
| ~C-k~ | switch to previous history item |
|
|
| ~C-l~ | clear the REPL |
|
|
|
|
** 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 |
|
|
|
|
Only some of the HLint suggestions can be applied.
|
|
|
|
* Syntax checking
|
|
There are multiple components that can indicate
|
|
errors and warnings in the code. Those components are:
|
|
- dante (via flycheck)
|
|
- hlint (via flycheck)
|
|
- lsp (via lsp-ui)
|
|
|
|
Since some 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 (from ghci 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, which will bring flycheck. 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-dante=, =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
|
|
[[https://github.com/ndmitchell/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.
|
|
|
|
HLint can be configured per project via .hlint.yaml (check Hlint docs for more details).
|
|
|
|
* FAQ
|
|
** Dante reports missing/hidden imports for test files
|
|
The cause might be that Dante is not loading appropriate packages for the test suite target, instead it is loading packages for the library.
|
|
|
|
Solution is to create =.dir-local.el= in the directory where the test suite (usually =test/= or =tests/=) is and to put the line =((haskell-mode . ((dante-target . "--test"))))= into it.
|
|
This tells Dante to use test suite target when working with test files.
|
|
|
|
** 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/layer-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/layer-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
|
|
|
|
** 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.
|
|
|
|
** HLint fails with parse error
|
|
If HLint is not correctly configured (e.g. does not load some extensions that you are using in your project) it might fail while parsing the file.
|
|
|
|
Check [[https://github.com/ndmitchell/hlint][HLint]] docs for more details.
|
|
|
|
** 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 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 path --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~.
|