This repository has been archived on 2024-10-22. You can view files and clone it, but cannot push or open issues or pull requests.
spacemacs/layers/+lang/haskell
2015-10-10 23:54:58 -04:00
..
img Use + instead of ! for layer categories 2015-09-11 00:13:51 -04:00
config.el Use + instead of ! for layer categories 2015-09-11 00:13:51 -04:00
packages.el Add variables to opt-in to flycheck/flyspell 2015-10-10 23:18:46 -04:00
README.org update tips for 'stuck' haskell repl 2015-10-10 23:54:58 -04:00

Haskell contribution layer for Spacemacs

/TakeV/spacemacs/media/commit/2b87b3d8ea1c607e568725793709588a946f5723/layers/+lang/haskell/img/haskell.png

Description

This layer adds support for the Haskell language.

Features:

This layer is in construction, it needs your contributions and bug reports.

Install

Layer

To use this contribution add it to your ~/.spacemacs

  (setq-default dotspacemacs-configuration-layers '(haskell))

Dependencies

This layer requires some cabal packages:

  • hlint
  • stylish-haskell
  • hasktags

You can install them using cabal or stack. Cabal users should use following command:

  $ cabal install stylish-haskell hlint hasktags

Stack users should use following command:

  $ stack install stylish-haskell hlint hasktags

Setup PATH

First of all make sure that your $PATH contains installation path for Haskell tools like ghc, ghci etc. It depends on how you have installed ghc. But you can always check it by calling $ which ghc in your terminal. Stack users should add only installation path of stack itself, usually it's ~/.local/bin.

Then make sure that your $PATH contains installation path for cabal packages. If you are using cabal it should be ~/.cabal/bin or /Users/<username>/Library/Haskell/bin (for 'Haskell for Mac' users). If you are using stack then it should be ~/.local/bin.

If you are using bash, sh or zsh, you could update your $PATH by using following command:

  $ export PATH=~/.local/bin:$PATH

If you are using fish, you could update your $PATH by using following command:

  $ set -x PATH ~/.local/bin $PATH

After you setup your $PATH, emacs should automatically pick it's value (after restart).

Alternatively, you can add path to the Emacs exec-path variable in the dotspacemacs/user-config function of your .spacemacs file:

  (add-to-list 'exec-path "~/.cabal/bin/")

Or for stack users:

  (add-to-list 'exec-path "~/.local/bin/")

OS X

Note that emacs.app for OS X does not pick up $PATH from ~/.bashrc or ~/.zshrc when launched from outside a terminal.

Optional extras

The Haskell layer supports some extra features that can be enabled through layer variables.

ghc-mod support

ghc-mod enhances haskell-mode with for example templates, case-splitting and much more. In order to use it you need to install the executable with

  $ cabal install ghc-mod

Stack users should use following command:

  $ stack install ghc-mod --resolver nightly-2015-10-07

and set the layer variable:

  (setq-default dotspacemacs-configuration-layers
    '((haskell :variables haskell-enable-ghc-mod-support t)))

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 document.

GHCi-ng support

ghci-ng adds some nice features to haskell-mode, and is supported in Spacemacs by a layer variable:

Follow the instructions to install ghci-ng (remember to add :set +c in ~/.ghci, next set the layer variable:

  (setq-default dotspacemacs-configuration-layers
    '((haskell :variables haskell-enable-ghci-ng-support t)))

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
SPC m h t gets the type of the identifier under the cursor or for the active region
SPC m g g go to definition
SPC m u finds uses of identifier

structured-haskell-mode

structured-haskell-mode, or shm, replaces default haskell-mode auto-indentation and adds some nice functionalities.

To Install shm with cabal run following command:

  $ cabal install structured-haskell-mode

Stack users should use following command:

  $ stack install structured-haskell-mode

To enable shm set the layer variable:

  (setq-default dotspacemacs-configuration-layers
    '((haskell :variables haskell-enable-shm-support t)))

After shm has been enabled, some of the evil normal state bindings are overridden:

Key Binding Description
D shm/kill-line
R shm/raise
P shm/yank
( shm/forward-node
) shm/backward-node

For a nice visualization of these functions, please refer to the github page for structured-haskell-mode.

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:

  • fundamental
  • johan-tibell
  • chris-done
  • gibiansky

See examples here

  (setq-default dotspacemacs-configuration-layers
    '((haskell :variables haskell-enable-hindent-style "johan-tibell")))

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 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 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 d start debug process, needs to be run first
SPC m d b insert breakpoint at function
SPC m d n next breakpoint
SPC m d N previous breakpoint
SPC m d B delete breakpoint
SPC m d c continue current process
SPC m d a abandon current process
SPC m d r refresh process buffer

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 the REPL
SPC m s S show and switch to 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

This 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 libary section
SPC m n go to next subsection
SPC m p go to previous subsection
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

FAQ

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:

  (setq-default dotspacemacs-configuration-layers
    '((haskell :variables haskell-process-type 'stack-ghci)))

Available options are:

  • ghci
  • cabal-repl
  • cabal-dev
  • cabal-ghci
  • stack-ghci

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 required space when you switch to insert mode. There is possible workaround - just add following snippet to your dotspacemacs/user-config function:

  (when (configuration-layer/layer-usedp 'haskell)
    (add-hook 'haskell-interactive-mode-hook
              (lambda ()
                (setq-local evil-move-cursor-back nil))))

It will make cursor stay at 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 REPL in insert mode. For this to happen you could place following snippet in your dotspacemacs/user-config function:

(when (configuration-layer/layer-usedp 'haskell)
    (defadvice haskell-interactive-switch (after spacemacs/haskell-interactive-switch-advice activate)
      (when (eq dotspacemacs-editing-style 'vim)
        (call-interactively 'evil-insert))))

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.