diff --git a/layers/+lang/haskell/README.org b/layers/+lang/haskell/README.org index c93b14a3e..b2a11e781 100644 --- a/layers/+lang/haskell/README.org +++ b/layers/+lang/haskell/README.org @@ -24,28 +24,28 @@ - [[Cabal commands][Cabal commands]] - [[Cabal files][Cabal files]] - [[Ghc-mod][Ghc-mod]] - - [[insert template][insert template]] + - [[Insert template][Insert template]] - [[Syntax checking][Syntax checking]] - [[Flycheck ][Flycheck ]] - [[HLint][HLint]] - [[ghc-mod][ghc-mod]] - - [[Haskell-mode interactive][Haskell-mode interactive]] + - [[Interactive haskell-mode][Interactive haskell-mode]] - [[Flymake][Flymake]] - - [[Troubles shooting][Troubles shooting]] + - [[Troublesshooting][Troublesshooting]] - [[FAQ][FAQ]] - - [[REPL doesn't work][REPL doesn't work]] - - [[REPL is stuck][REPL is stuck]] + - [[The REPL doesn't work][The REPL doesn't work]] + - [[The REPL is stuck][The REPL is stuck]] - [[I am using =stack= and =ghc-mod=, but =ghc-mod= doesn't work][I am using =stack= and =ghc-mod=, but =ghc-mod= doesn't work]] - - [[Indentation doesn't reset when pressing return after empty line][Indentation doesn't reset when pressing return after empty line]] + - [[Indentation doesn't 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 don't appear in the errors list][I can see highlighted errors but they don't appear in the errors list]] + - [[I can see highlighted errors but they don't appear in the error list][I can see highlighted errors but they don't appear in the error list]] - [[Flycheck doesn't work][Flycheck doesn't work]] - [[Flycheck doesn't work with =stack=][Flycheck doesn't work with =stack=]] - - [[stack build directory is wrong][stack build directory is wrong]] - - [[Project root directory not set properly][Project root directory not set properly]] + - [[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 don't work ][haskell-mode commands don't work ]] - - [[=ghc-mod= and =haskell-mode= commands overlaps. How do I know which command belongs to what ?][=ghc-mod= and =haskell-mode= commands overlaps. 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 ?]] + - [[=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?]] * Description This layer adds support for the [[https://www.haskell.org/][Haskell]] language. @@ -108,9 +108,8 @@ the project root. As it will confuse =ghc-mod=. For more troubleshooting, checkout this [[https://github.com/kazu-yamamoto/ghc-mod/wiki#known-issues-related-to-stack][document]]. *** Stack users - -Time to time =ghc-mod= is not available via latest Stackage LTS version. So if -you have problems with calling =stack install ghc-mod=, try to use =stack +From time to time =ghc-mod= is not available via latest Stackage LTS version. So +if you have problems with calling =stack install ghc-mod=, try to use =stack install ghc-mod --resolver lts-3.1= (the last known LTS version that had =ghc-mod=). But even if it doesn't work, don't panic, it's easy to install it from sources. @@ -143,23 +142,23 @@ $ rm -rf ghc-mod #+END_SRC ** Optional extras -The Haskell layer supports some extra features that can be enabled through -layer variables. +The Haskell layer supports some extra features that can be enabled through layer +variables. *** GHCi-ng support -[[https://github.com/chrisdone/ghci-ng][ghci-ng]] adds some nice features to =haskell-mode=, and is supported in -Spacemacs by a layer variable: +[[https://github.com/chrisdone/ghci-ng][ghci-ng]] adds some nice features to =haskell-mode=, and is supported in Spacemacs +by a layer variable: -Follow the instructions to install [[https://github.com/chrisdone/ghci-ng][ghci-ng]] (remember to add =:set +c= -in =~/.ghci=), next set the layer variable: +Follow the instructions to install [[https://github.com/chrisdone/ghci-ng][ghci-ng]] (remember to add =:set +c= in +=~/.ghci=), next set the layer variable: #+BEGIN_SRC emacs-lisp (setq-default dotspacemacs-configuration-layers '((haskell :variables haskell-enable-ghci-ng-support t))) #+END_SRC -Once ghci-ng is enabled, two of the old keybindings are overriden with -improved versions from ghci-ng, and a new keybinding available: +Once ghci-ng is enabled, two of the old keybindings are overriden with improved +versions from ghci-ng, and a new keybinding available: | Key Binding | Description | |-------------+---------------------------------------------------------------------------| @@ -168,7 +167,6 @@ improved versions from ghci-ng, and a new keybinding available: | ~SPC m u~ | finds uses of identifier | **** Stack users - =Stack= and =ghci-ng= doesn't play well with each other, so the general advice is to avoid mixing them. But, if you want mix them anyway, you'll need to set =haskell-process-type= explicitly: @@ -186,8 +184,7 @@ if you have =stack.yaml= file in the root of your project, =stack-ghci= will be used as process type. **** ghc-mod users - -If you want to use ~SPC m h t~ from =ghc-mod= instead of =ghci-ng= - then you +If you want to use ~SPC m h t~ from =ghc-mod= instead of =ghci-ng=, then you need to add following line in your =dotspacemacs/user-config=: #+BEGIN_SRC emacs-lisp @@ -199,8 +196,8 @@ This might be useful, because =ghc-mod= doesn't require active REPL in order to get type of symbol. *** structured-haskell-mode -[[https://github.com/chrisdone/structured-haskell-mode][structured-haskell-mode]], or shm, replaces default haskell-mode -auto-indentation and adds some nice functionalities. +[[https://github.com/chrisdone/structured-haskell-mode][structured-haskell-mode]], or shm, replaces default haskell-mode auto-indentation +and adds some nice functionalities. To install =shm= run =cabal install structured-haskell-mode= (or =stack= equivalent). @@ -226,22 +223,22 @@ For a nice visualization of these functions, please refer to the github page for [[https://github.com/chrisdone/structured-haskell-mode#features][structured-haskell-mode]]. *Warning* structured-haskell-mode doesn't play very well with =evil= -([[https://github.com/chrisdone/structured-haskell-mode/issues/81][structured-haskell-mode/#81]]). So it's better to be used with =emacs= edit -style. +([[https://github.com/chrisdone/structured-haskell-mode/issues/81][structured-haskell-mode/#81]]). So it's recommended only to be used with the +=emacs= editing style. *** hindent [[https://github.com/chrisdone/hindent][hindent]] is an extensible Haskell pretty printer, which let's you reformat your code. You need to install the executable with =cabal install hindent= or =stack install hindent= -To enable it you have to set the variable =haskell-enable-hindent-style= -to a supported style. The available styles are: +To enable it you have to set the variable =haskell-enable-hindent-style= to a +supported style. The available styles are: - fundamental - johan-tibell - chris-done - gibiansky -See examples [[https://github.com/chrisdone/hindent#example][here]] +See examples [[https://github.com/chrisdone/hindent#example][here]]. #+BEGIN_SRC emacs-lisp (setq-default dotspacemacs-configuration-layers @@ -349,59 +346,66 @@ ghc-mod commands are prefixed by ~SPC m m~: | ~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 the function without signature, 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, original code -is replaced with hlint's suggestion if possible. +*** 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, +original code is replaced with hlint's suggestion if possible. * Syntax checking -At the moment there are 4 components which can check the syntax and indicates somehow error and warnings in the code. -Those components are : +At the moment there are four components which can check the syntax and indicates +somehow error and warnings in the code. Those components are - - - flycheck - - hlint (via flycheck) - - ghc-mod - - haskell-mode interactive +- flycheck +- hlint (via flycheck) +- ghc-mod +- haskell-mode interactive -As all those components can be active at the same time, it can be tricky to know which component is display which message, -especially when they disagree or one is not working. Only flycheck errors (ghc and hlint) are displayed in the error list and -can be navigated using the standard spacemacs key bindings even though errors from other mode might highlight error in the buffer. +As all 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 +one is not working. Only flycheck errors (ghc and hlint) are displayed in the +error list and can be navigated 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 to do syntax checking and the most elaborate. flyckeck displays errors, warning, info, including symbols on the left or right side of the buffer -and tooltips if possible. -Errors are also available in the error window (~SPC e l~) and you can navigate between errors using ~SPC e n~ and ~SPC e p~. -Flycheck can be toggle on/off with ~SPC t s~. -Flycheck has different haskell checker : haskell-ghc, haskell-stackghc and haskell-hlint. -It normally detect automatically the good one, but if it doesn't work, you can change it using =flycheck-select-checker= (~SPC e s~). +This is the standard spacemacs way to do syntax checking and the most elaborate. +You need the syntax-checking layer to enable this. Please the documentation for +that layer on how to interact with flycheck. + +Flycheck has different Haskell checkers: =haskell-ghc=, =haskell-stackghc= and +=haskell-hlint=. Normally it can automatically detect the best one to use, but +if it doesn't work, you can change it using ~SPC e s~. ** HLint -HLint is a linter for Haskell. It doesn't detect error (as long as it can parse the file) but detect bad coding style and code smell. -HLint checker is called *after* the flycheck ghc checker. +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, does also syntax checking. It doesn't highlight errors but instead displays a ! in the left band. -You can navigate between errors using =ghc-goto-next-error= (~M-n)~ and =ghc-goto-prev-error= (~M-p~). - -** Haskell-mode interactive -Finally, haskell-mode when in interactive (~SPC m s b~) also displays errors. -haskell-mode errors can be navigated from the interactive buffer (by clicking on the error) or using -=haskell-goto-next-error= (~M-n~) and =haskell-goto-prev-error= (~M-p~) (same binding as 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 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 project using =flymake-compile=. It doesn't highlight the error on the buffer but is more reliable. -Error navigation is similar to haskell-mode interactive. -** Troubles shooting -Flycheck and ghc-mod can fails silently for miscellaneous reasons. See the [[FAQ]] for trouble shootings. +An alternative to syntax checking is to build your project using +=flymake-compile=. It doesn't highlight error in the buffer but is more +reliable. The error navigation is similar to interactive haskell-mode. + +** Troublesshooting +Flycheck and ghc-mod can fail silently for miscellaneous reasons. See the [[FAQ]] +for troubleshooting. + * FAQ -** REPL doesn't work +** 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 you can help =haskell-mode= by setting =haskell-process-type= as in following code: @@ -419,7 +423,7 @@ Available options are: - cabal-ghci - stack-ghci -** REPL is stuck +** The REPL is stuck Make sure that when you are typing anything in REPL there is a space between what you type and =λ>=. When there is no space - REPL will behave as it's stuck. Usually, when you enter normal state, cursor is moved back, so there is no @@ -450,9 +454,11 @@ could place following snippet in your =dotspacemacs/user-config= function: ** I am using =stack= and =ghc-mod=, but =ghc-mod= doesn't work Make sure that =dist= directory doesn't exist in your project root. So if it exists, just remove it and try again. -** Indentation doesn't reset when pressing return after empty line -This is intended behavior in =haskell-indentation-mode=. If you want to reset indentation when pressing return after empty line, add following snippet into your =dotspacemacs/user-config= function. +** 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 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 () @@ -465,45 +471,54 @@ This is intended behavior in =haskell-indentation-mode=. If you want to reset in (advice-add 'haskell-indentation-newline-and-indent :after 'haskell-indentation-advice) #+END_SRC + ** Flycheck displays HLInt warnings but not errors -HLint checker is called *after* normal flycheck checker even if the checkers fails. Check the [[Flycheck doesn't work]] section. -** I can see highlighted errors but they don't appear in the errors list -The errors list is only set by flycheck. You are probably seeing highlightings coming from either ghc-mode or haskell-mode. -Check the [[Flycheck doesn't work]] section. +The HLint checker is called *after* normal flycheck checker even if the checker +fails. Check the [[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 doesn't work]] +section. + ** Flycheck doesn't work -You can check what is wrong with flycheck with the =flycheck-compile= command. +You can check what is wrong with flycheck with the =flycheck-compile= command. This will show you the exact command line used and its output. If you are using stack, check the [[Flycheck doesn't work with =stack=]] section. ** Flycheck doesn't work with =stack= -First check flycheck use the correct checker and all the path are properly configured using =flycheck-verify-setup= (~SPC e v~). -You can force the checker by using =flycheck-select-checker= (~SPC e s~) to =haskell-stack-ghc=. -If it still doesn't work, it could be one of the following problems : +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 it uses +=haskell-stack-ghc=. If it still doesn't work, it could be one of the following +problems: -- stack build directory is wrong. -- project root not set properly +- 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 containing some generated files is normally +under =.stack-work/install//Cabal-/build=. -*** stack build directory is wrong -The path to the build directory containing some generated files is normally under +However, the version of the cabal library used by stack to generate the +directory name is not the version of the cabal library installed by stack, but +the version of cabal 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 used by flycheck using =flycheck-compile= and +compare it to to the actual path in the =.stack-work= directory. If they are +different you need to reinstall ghc using the command =stack setup +--upgrade-cabal=. -=.stack-work/install//Cabal-