# Haskell contribution layer for Spacemacs ![logo](img/haskell.png) **Table of Contents** - [Haskell contribution layer for Spacemacs](#haskell-contribution-layer-for-spacemacs) - [Description](#description) - [Install](#install) - [Layer](#layer) - [Cabal packages](#cabal-packages) - [OS X](#os-x) - [Optional extras](#optional-extras) - [GHCi-ng support](#ghci-ng-support) - [structured-haskell-mode](#structured-haskell-mode) - [hindent](#hindent) - [Key bindings](#key-bindings) - [-](#-) - [Debug](#debug) - [REPL](#repl) - [Cabal commands](#cabal-commands) - [Cabal files](#cabal-files) ## Description This layer adds support for the [Haskell][] language. Features: - auto-completion with [company-ghc][], - auto-indentation with [hi2][]. **This layer is in construction, it needs your contributions and bug reports.** ## Install ### Layer To use this contribution add it to your `~/.spacemacs` ```elisp (setq-default dotspacemacs-configuration-layers '(haskell)) ``` ### Cabal packages This layer requires some [cabal][] packages: - `ghc-mod` - `hlint` - `stylish-haskell` To install them, use the following command: ```sh cabal install stylish-haskell hlint ghc-mod ``` Then you have to add this path to your system `$PATH` (preferred): Note that on **Linux** distributions the installed binaries should be in `~/.cabal/bin` and on **OS X** the binaries are installed in `/Users//Library/Haskell/bin`. ```sh export PATH=~/.cabal/bin/:$PATH ``` _or_ to the Emacs `exec-path` variable in the `dotspacemacs/init` function of your `.spacemacs` file: ```elisp (add-to-list 'exec-path "~/.cabal/bin/") ``` **Note:** it is important to add the path in the `dotspacemacs/init` function, so that the path is added before any layers is loaded. ### 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. #### 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: ```elisp (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 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 hi2 (and any other Haskell-indentation modes) and adds some nice functionality. To enable shm, run `cabal install structured-haskell-mode` and set the layer variable: ```elisp (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`. To enable it you have to set the variable `haskell-enable-hindent-support` to a supported style. The available styles are: - fundamental - johan-tibell - chris-done - andrew-gibiansky See examples [here][hindent-examples] ```elisp (setq-default dotspacemacs-configuration-layers '((haskell :variables haskell-enable-hindent-support "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 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 [Haskell]: https://www.haskell.org/ [cabal]: https://www.haskell.org/cabal/ [company-ghc]: https://github.com/iquiw/company-ghc [hi2]: https://github.com/nilcons/hi2 [ghci-ng]: https://github.com/chrisdone/ghci-ng [structured-haskell-mode]: https://github.com/chrisdone/structured-haskell-mode [hindent]: https://github.com/chrisdone/hindent [hindent-examples]: https://github.com/chrisdone/hindent#example