Haskell Mode 17.5

Next:   [Index]

Haskell Mode

Haskell Mode is an Haskell development Environment for GNU Emacs version 25.1 or later. It provides syntax-based indentation, font locking, editing cabal files, and supports running an inferior Haskell interpreter (e.g. GHCi).

This manual is for Haskell mode, version 17.5

Copyright © 2013-2017 Haskell Mode contributors.

Permission is granted to copy, distribute and/or modify this document under the terms of the GNU Free Documentation License, Version 1.3 or any later version published by the Free Software Foundation; with no Invariant Sections, no Front-Cover Texts and no Back-Cover Texts.


Next: , Previous: , Up: Haskell Mode   [Index]

1 Introduction

Haskell Mode is a major mode providing a convenient environment for editing Haskell programs.

Some of its major features are:

The name Haskell Mode refers to the whole collection of modules in this package. There is specifically a file haskell-mode.el which defines a major mode called haskell-mode. Generally, in this documentation they will be distinguished by normal font and title case (Haskell Mode) and code font (haskell-mode).

1.1 History

haskell-mode has a long history. It goes all the way back to 1992. Since then, it has received many contributions in many forms. Some design choices that remain in haskell-mode today are historical. Some modules are outdated or no longer used, or are used by a few people.

Historically there hasn’t been a single individual or set of individuals directing the package’s architecture for a long period of time, rather, patches and new modules were accepted in liberally and we are left with a box full of interesting toys that may or may not work.

As of 2016 Haskell Mode is coordinated using Github at https://github.com/haskell/haskell-mode.


2 Installation

Haskell Mode is distributed as a package in MELPA repository. To use MELPA as Emacs package archive do the following:

  1. Customize package-archives using
    M-x customize-option RET package-archives
    
  2. Use INS to add new archive, use:
    Archive name:          melpa-stable
    URL or directory name: http://stable.melpa.org/packages/
    
  3. Fetch new packages using:
    M-x package-refresh-contents
    
  4. Install Haskell Mode using:
    M-x package-install RET haskell-mode RET
    

Voila! haskell-mode is installed! You should be able to edit Haskell source code in color now.

The above steps should result in the following snippet in your .emacs:

(require 'package)
(custom-set-variables
 ;; custom-set-variables was added by Custom.
 ;; If you edit it by hand, you could mess it up, so be careful.
 ;; Your init file should contain only one such instance.
 ;; If there is more than one, they won't work right.
 '(package-archives
   (quote
    (("gnu" . "http://elpa.gnu.org/packages/")
     ("melpa-stable" . "http://stable.melpa.org/packages/")))))

Haskell Mode is available from melpa-stable (releases) and melpa (git snapshots).

Other means of obtaining haskell-mode include el-get, Emacs Prelude and Debian package.

2.1 Customizing

Most of Haskell Mode’s settings are configurable via customizable variables (see (emacs)Easy Customization, for details). You can use M-x customize-group RET haskell to browse the haskell customization sub-tree.

One of the important setting you should customize is the haskell-mode-hook variable (see (emacs)Hooks) which gets run right after the haskell-mode major mode is initialized for a buffer. You can customize haskell-mode-hook by

M-x customize-variable RET haskell-mode-hook

There you can enable or disable a couple of predefined options or add any function to the list.


Next: , Previous: , Up: Haskell Mode   [Index]

3 Editing Haskell Code

Haskell Mode as one of its components provides a major mode for editing Haskell source code called haskell-mode, which gave the name to the whole project. There is a derived mode provided called haskell-literate-mode that support Literate Haskell source code both in Bird and in Latex forms.

Haskell Mode supports files with the following extensions:

.hs

official file extension for Haskell files. Haskell Mode out of the box supports most of GHC extensions.

.lhs

official file extension for Literate Haskell files. Both Bird and Latex styles are supported.

.hsc

Haskell interfaces to C code used by hsc2hs pre-processor.

.cpphs

Haskell source with CPP pragmas used with cpphs pre-processor.

.c2hs

Haskell FFI bindings to C libraries used with c2hs pre-processor.

Haskell Mode offers many productivity tools described in following chapters in this manual.

3.1 Managing imports

There are a few functions for managing imports.

3.1.1 Jump to imports

To jump to your import list, run

M-x haskell-navigate-imports

It’s nicer to have a keybinding to do this, for example:

(define-key haskell-mode-map (kbd "<f8>") 'haskell-navigate-imports)

You can hit it repeatedly to jump between groups of imports. It will cycle.

3.1.2 Format imports

To generally format (sort, align) your imports, you can run

M-x haskell-mode-format-imports

Or C-c C-,.

3.1.3 Sort imports

To just sort imports, jump to an import section and run

M-x haskell-sort-imports

3.1.4 Align imports

To just align imports, jump to an import section and run

M-x haskell-align-imports

3.1.5 stylish-haskell

As an alternative to the elisp functions described above, haskell-mode can use the program stylish-haskell to format imports. You can set this behavior by typing: M-x customize-variable RET haskell-stylish-on-save. You can install stylish-haskell by running stack install stylish-haskell, or if you have not installed stack, cabal install stylish-haskell.

3.2 Haskell Tags

haskell-mode can generate tags when saving source files. To generate tags haskell-mode uses external program — Hasktags (wiki-article). To turn on tags generatation customize or set to t haskell-tags-on-save variable. Also, you may find useful to revert tags tables automatically, this can be done by customizing tags-revert-without-query variable (either globally or for Haskell buffers only).

3.3 Profiling and Debugging support

When profiling code with GHC, it is often useful to add cost centres by hand. These allow finer-grained information about program behavior. haskell-mode provides the function haskell-mode-toggle-scc-at-point to make this more convenient. It will remove an SCC annotation at point if one is present, or add one if point is over whitespace. By default it is bound to C-c C-s.


4 Syntax highlighting

haskell-mode supports syntax highlighting via Emacs’ Font Lock minor mode which should be enabled by default in current Emacsen. See (emacs)Font Lock, for more information on how to control font-lock-mode.

anim/font-lock

Syntax highlighting facilities parse strings and string escape sequences and are able to highlight unrecognized constructs.

anim/string-escape-highlight

Haskell Mode shows keywords, identifiers, operators, constructors and types in different colors.

anim/font-lock-types

There is also support to use mode-specific syntax highlighing for quasiquotes.

anim/font-lock-quasi-quotes

At this point quasi quotes for HTML, XML, shell scripts, Hamlet templates and SQL are supported out of the box. Customize haskell-font-lock-quasi-quote-modes to make sure your quoters are supported.

The following customization variables are responsible for faces applied:

All the above are available for customization.

GHC quasi quote syntax is ambiguous with list comprehension therefore syntax highlighting might get confused with situations like these:

result = [html| html <- htmlList]
result = [html| <html><body>...</body></html> |]

Please use spaces around a list comprehension variable to make this unambiguous. Any of the following will work:

result = [ html| html <- htmlList]
result = [html | html <- htmlList]

GHC’s ambiguity is an accident of the past but it is unlikely to be fixed due to backward compatibility baggage.


5 Completion support

haskell-mode can complete symbols, pragma directives, language extensions, and language keywords out-of-box. haskell-mode completes identifiers (symbols) using tags (see “Tags”), however you can get more precise completions with haskell-interactive-mode. In interactive mode completion candidates are produced by querying GHCi REPL.

anim/company-mode-language-pragma

If haskell-interactive-mode is enabled and working Haskell mode provides completions for import statements taking into account currently loaded and available packages. Also it completes symbols querying REPL with :complete command, hence completion candidate list also includes symbols from imported modules.

anim/company-mode-import-statement

Unfortunately, it is not possible to provide candidates for identifiers defined locally in let and where blocks even in interactive mode. But if you’re using company-mode you can override company-backends variable for Haskell buffers to combine completion candidates from completion-at-point function (company-capf backend) and dynamic abbrevs. company-mode provides special backend for dabbrev code completions, namely company-dabbrev-code. To combine completions from different backends you can create grouped backends, it is very easy — a grouped backend is just a list of backends, for example:

(add-hook 'haskell-mode-hook
          (lambda ()
            (set (make-local-variable 'company-backends)
                 (append '((company-capf company-dabbrev-code))
                         company-backends))))

If you use a GHCi version prior to 8.0.1 you might want to set haskell-completions-complete-operators to nil, if you experience major slowdown while trying to complete after an Haskell operator (See GHC-Bug 10576).


Next: , Previous: , Up: Haskell Mode   [Index]

6 Unicode support

See the Haskell Wiki’s entry on Unicode Symbols for general information about Unicode support in Haskell.

As Emacs supports editing files containing Unicode out of the box, so does Haskell Mode. As an add-on, Haskell Mode includes the haskell-unicode input method which allows you to easily type a number of Unicode symbols that are useful when writing Haskell code; See (emacs)Input Methods, for more details.

To automatically enable the haskell-unicode input method in haskell-mode buffers use M-x customize-variable RET haskell-mode-hook or put the following code in your .emacs file:

(add-hook 'haskell-mode-hook 'turn-on-haskell-unicode-input-method)

To temporarily enable this input method for a single buffer you can use M-x turn-on-haskell-unicode-input-method.

When the haskell-unicode input method is active, you can simply type ‘->’ and it is immediately replaced with ‘’. Use C-\ to toggle the input method. To see a table of all key sequences use M-x describe-input-method RET haskell-unicode. A sequence like ‘<=’ is ambiguous and can mean either ‘’ or ‘’. Typing it presents you with a choice. Type 1 or 2 to select an option or keep typing to use the default option.

Currently defined sequences are listed in the following table:

SequenceUnicodeSequenceUnicodeSequenceUnicodeSequenceUnicode
alphaαAlphaΑbetaβBetaΒ
gammaγGammaΓdeltaδDeltaΔ
epsilonεEpsilonΕzetaζZetaΖ
etaηEtaΗthetaθThetaΘ
iotaιIotaΙkappaκKappaΚ
lambdaλLambdaΛlamdaλLamdaΛ
muμMuΜnuνNuΝ
xiξXiΞomicronοOmicronΟ
piπPiΠrhoρRhoΡ
sigmaσSigmaΣtauτTauΤ
upsilonυUpsilonΥphiφPhiΦ
chiχChiΧpsiψPsiΨ
omegaωOmegaΩdigammaϝDigammaϜ
sanϻSanϺqoppaϙQoppaϘ
sampiϡSampiϠstigmaϛStigmaϚ
hetaͱHetaͰshoϸShoϷ
|A|𝔸|B|𝔹|C||D|𝔻
|E|𝔼|F|𝔽|G|𝔾|H|
|I|𝕀|J|𝕁|K|𝕂|L|𝕃
|M|𝕄|N||O|𝕆|P|
|Q||R||S|𝕊|T|𝕋
|U|𝕌|V|𝕍|W|𝕎|X|𝕏
|Y|𝕐|Z||gamma||Gamma|
|pi||Pi|::forall
exists-><-=>
~><~&&||
==/=≢, ≠<=>=
/</>*elem
notElemmembernotMemberunion
intersectionisSubsetOfisProperSubsetOf<<<
>>><||>><
mappend.undefined:=
=:=def=?...
_0_1_2_3
_4_5_6_7
_8_9^0^1¹
^2²^3³^4^5
^6^7^8^9

If you don’t like the highlighting of partially matching tokens you can turn it off by setting input-method-highlight-flag to nil via M-x customize-variable.


7 Indentation

In Haskell, code indentation has semantic meaning as it defines the block structure. Haskell also supports braces and semicolons notation for conveying the block structure. However, most Haskell programs written by humans use indentation for block structuring.

Haskell Mode ships with two indentation modes:

For general information about indentation support in GNU Emacs, see (emacs)Indentation.

7.1 Rectangle Commands

GNU Emacs provides so-called rectangle commands which operate on rectangular areas of text, which are particularly useful for languages with a layout rule such as Haskell. See (emacs)Rectangles, to learn more about rectangle commands.

Moreover, CUA mode (see (emacs)CUA Bindings) provides enhanced rectangle support with visible rectangle highlighting. When CUA mode is active, you can initiate a rectangle selection by C-RET and extend it simply by movement commands. You don’t have to enable full CUA mode to benefit from these enhanced rectangle commands; you can activate CUA selection mode (without redefining C-x,C-c,C-v, and C-z) by calling M-x cua-selection-mode (or adding (cua-selection-mode nil) to your haskell-mode-hook).

7.2 Region indent is a no-op

There is a indent-region function that supposedly could be used to indent code region without changing its semantics. Sadly it does not work that way because usual use case for indent-region is:

  1. Alter first line of code in region.
  2. Call indent-region to fix indentation for remaining lines.

Note that between 1 and 2 program is already semantically broken and knowing how to indent it preserving semantic from before step 1 would require time travel.

To stay on the safe side indent-region-function is bound to a no-op in haskell-mode.


8 Other ways to indent code

8.1 Indentation with tabs, not spaces

Some projects require indenting code with tabs and forbid indenting it with spaces. For hacking on such projects, check out haskell-tab-indent-mode.

8.2 Structured indentation

Another alternative is to install structured-haskell-mode. which indents code by parsing the code with a full Haskell parser and deciding where to indent based on that.


9 Using external formatters

You can enable stylish-haskell by installing it:

$ cabal install stylish-haskell

And by enabling it with a customization

(custom-set-variables
 '(haskell-stylish-on-save t))

Now when you run save-buffer (or C-x C-s) the module will be automatically formatted.

Alternatively, you can run the function directly on demand with M-x haskell-mode-stylish-buffer.


10 Module templates

To enable auto-insertion of module templates, enable:

(add-hook 'haskell-mode-hook 'haskell-auto-insert-module-template)

When you open a file called Foo.hs, it will auto-insert

-- |

module Foo where

And put your cursor in the comment section.


Next: , Previous: , Up: Haskell Mode   [Index]

11 Declaration scannning

haskell-decl-scan-mode is a minor mode which performs declaration scanning and provides M-x imenu support (see (emacs)Imenu for more information).

For non-literate and TeX-style literate scripts, the common convention that top-level declarations start at the first column is assumed. For Bird-style literate scripts, the common convention that top-level declarations start at the third column, ie. after ‘> ’, is assumed.

When haskell-decl-scan-mode is active, the standard Emacs top-level definition movement commands (see (emacs)Moving by Defuns) are enabled to operate on Haskell declarations:

C-M-a

Move to beginning of current or preceding declaration (beginning-of-defun).

C-M-e

Move to end of current or following declaration (end-of-defun).

C-M-h

Select whole current or following declaration (mark-defun).

Moreover, if enabled via the option haskell-decl-scan-add-to-menubar, a menu item “Declarations” is added to the menu bar listing the scanned declarations and allowing to jump to declarations in the source buffer.

It’s recommended to have font lock mode enabled (see (emacs)Font Lock) as haskell-decl-scan-mode ignores text highlighted with font-lock-comment-face.

As usual, in order to activate haskell-decl-scan-mode automatically for Haskell buffers, add haskell-decl-scan-mode to haskell-mode-hook:

(add-hook 'haskell-mode-hook 'haskell-decl-scan-mode)

haskell-decl-scan-mode enables the use of features that build upon imenu support such as Speedbar Frames (see (emacs)Speedbar) or the global “Which Function” minor mode (see (emacs)Which Function).

In order to enable which-function-mode for Haskell buffers you need to add the following to your Emacs initialization:

(eval-after-load "which-func"
  '(add-to-list 'which-func-modes 'haskell-mode))

11.1 Speedbar

Haskell-mode comes with declaration scanning support. This means that if you enable Haskell support for speedbar:

(speedbar-add-supported-extension ".hs")

And open speedbar with

M-x speedbar

It gives a listing of each module and under each module:

    Imports
    Instances
    Data types
    Classes
    Bindings

You will get a bar that looks like this:

~/Projects/ace/src/ACE/
0:<+> Types
0:[+] Combinators.hs
0:[-] Datalog.hs
1:   {-} Classes
2:      > ToTerm
1:   {-} Imports
2:      > ACE.Types.Syntax
2:      > Database.Datalog
1:   {-} Instances
2:    {+} ToTerm A
2:    {+} ToTerm Co to ToTerm Gen
2:    {+} ToTerm Intransitive to ToTerm N
2:    {+} ToTerm P
2:    {+} ToTerm Quotation to ToTerm Un
2:    {+} ToTerm V
0:[-] Html.hs
1:   {+} Imports
1:   {+} Instances
1:     > mtoMarkup
1:     > toMarkupm
1:     > wrap
0:[-] Parsers.hs
1:   {+} Imports
1:   {-} Datatypes
2:      > ACEParser
0:[+] Pretty.hs
0:[+] Tokenizer.hs

The hierarchy is expandable/collapsible and each entry will jump to the line in the right file when clicked/selected.


12 Compilation

Haskell mode comes equipped with a specialized Compilation mode tailored to GHC’s compiler messages with optional support for Cabal projects. See (emacs)Compilation Mode, for more information about the basic commands provided by the Compilation mode which are available in the Haskell compilation sub-mode as well. The additional features provided compared to Emacs’ basic Compilation mode are:

In order to use it, invoke the haskell-compile command instead of compile as you would for the ordinary Compilation mode. It’s recommended to bind haskell-compile to a convenient key binding. For instance, you can add the following to your Emacs initialization to bind haskell-compile to C-c C-c.

(eval-after-load "haskell-mode"
    '(define-key haskell-mode-map (kbd "C-c C-c") 'haskell-compile))

(eval-after-load "haskell-cabal"
    '(define-key haskell-cabal-mode-map (kbd "C-c C-c") 'haskell-compile))

The following description assumes that haskell-compile has been bound to C-c C-c.

When invoked, haskell-compile decides what build tool to run by consulting the value of haskell-compiler-type.

Moreover, when a negative prefix argument is supplied (e.g. C-- C-c C-c), the alternative build command is used, that is, haskell-compile-cabal-build-command-alt or haskell-compile-stack-build-command-alt. By default, the alternative build commands force a full rebuild. (Note this does not affect haskell-compile-command.)

As usual you can change any of these variables using M-x customize-variable.

You can also inspect and modify the compile command to be invoked temporarily by invoking haskell-compile with a prefix argument (e.g. C-u C-c C-c). If later-on you want to recompile using the same customized compile command, invoke recompile (bound to g) inside the ‘*haskell-compilation*’ buffer.

12.1 Keybindings

Key bindingFunction
TABcompilation-next-error
RETcompile-goto-error
C-ocompilation-display-error
SPCscroll-up-command
-negative-argument
0 .. 9digit-argument
<beginning-of-buffer
>end-of-buffer
?describe-mode
grecompile
hdescribe-mode
qquit-window
DELscroll-down-command
S-SPCscroll-down-command
<backtab>compilation-previous-error
<follow-link>mouse-face
<mouse-2>compile-goto-error
<remap>Prefix Command
M-ncompilation-next-error
M-pcompilation-previous-error
M-{compilation-previous-file
M-}compilation-next-file
C-c C-ccompile-goto-error
C-c C-fnext-error-follow-minor-mode
C-c C-kkill-compilation

Next: , Previous: , Up: Haskell Mode   [Index]

13 Interactive Haskell

REPL (read–eval–print loop) is provided both via Comint (inferior-haskell-mode) and an adhoc way called haskell-interactive-mode. The Comint based inferior-haskell-mode is just the REPL, it comes with the standard key bindings(like ielm or eshell).

haskell-interactive-mode comes with a different set of features:

With haskell-interactive-mode, each Haskell source buffer is associated with at most one GHCi session, so when you call haskell-process-load-file for a Haskell source buffer which has no session associated yet, you’re asked which GHCi session to create or associate with.

13.1 Goto Error

In a Haskell source buffer associated with a GHCi session, errors that prevent the file from loading are highlighted with haskell-error-face. You can move between these error lines with with the commands haskell-goto-next-error, haskell-goto-prev-error and haskell-goto-first-error, which you might like to bind to convenient keys in interactive-haskell-mode-map.

13.2 Using GHCi 8+ or GHCi-ng

If you use either of the above, then you can use these functions:

(define-key interactive-haskell-mode-map (kbd "M-.") 'haskell-mode-goto-loc)
(define-key interactive-haskell-mode-map (kbd "C-c C-t") 'haskell-mode-show-type-at)

You have to load the module before it works, after that it will remember for the current GHCi session.

13.3 Customizing

What kind of Haskell REPL haskell-interactive-mode will start up depends on the value of haskell-process-type. This can be one of the symbols auto, ghci, stack-ghci, cabal-repl, or cabal-new-repl.

(cabal-new-repl is allowed but obsolete, like the cabal command new-build that it selected. Emacs actually runs the equivalent cabal command build.)

If it’s auto, the directory contents and available programs will be used to make a best guess at the process type. The actual process type will then determine which variables haskell-interactive-mode will access to determine the program to start and its arguments:

  • If it’s ghci, haskell-process-path-ghci and haskell-process-args-ghci will be used.
  • If it’s cabal-repl or cabal-new-repl, haskell-process-path-cabal and haskell-process-args-cabal-repl are used.
  • If it’s stack-ghci, haskell-process-path-stack and haskell-process-args-stack-ghci will be used.

With each of these pairs, the the haskell-process-path-... variable needs to be a string specifying the program path, or a list of strings where the first element is the program path and the rest are initial arguments. The haskell-process-args-... is a list of strings specifying (further) command-line arguments.

13.4 Haskell Interactive Mode Setup

The most straight-forward way to get setup with Interactive Mode is to bind the right keybindings and set some customizations. This page contains a good base setup.

To enable the minor mode which activates keybindings associated with interactive mode, use:

(require 'haskell-interactive-mode)
(require 'haskell-process)
(add-hook 'haskell-mode-hook 'interactive-haskell-mode)

13.4.1 Customizations

This enables some handy and benign features.

(custom-set-variables
  '(haskell-process-suggest-remove-import-lines t)
  '(haskell-process-auto-import-loaded-modules t)
  '(haskell-process-log t))

13.4.2 Haskell-mode bindings

This gives the basic ways to start a session. In a Haskell buffer:

  • Run C-` to make a REPL open, this will create a session, start GHCi, and open the REPL.
  • Or: run C-c C-l to load the file. This will first try to start a session as the previous command does.
  • Or: run any command which requires a running session. It will always prompt to create one if there isn’t one already for the current project.
(define-key haskell-mode-map (kbd "C-c C-l") 'haskell-process-load-or-reload)
(define-key haskell-mode-map (kbd "C-`") 'haskell-interactive-bring)
(define-key haskell-mode-map (kbd "C-c C-t") 'haskell-process-do-type)
(define-key haskell-mode-map (kbd "C-c C-i") 'haskell-process-do-info)
(define-key haskell-mode-map (kbd "C-c C-c") 'haskell-process-cabal-build)
(define-key haskell-mode-map (kbd "C-c C-k") 'haskell-interactive-mode-clear)
(define-key haskell-mode-map (kbd "C-c c") 'haskell-process-cabal)

13.4.3 Cabal-mode bindings

The below commands pretty much match the ones above, but are handy to have in cabal-mode, too:

(define-key haskell-cabal-mode-map (kbd "C-`") 'haskell-interactive-bring)
(define-key haskell-cabal-mode-map (kbd "C-c C-k") 'haskell-interactive-mode-clear)
(define-key haskell-cabal-mode-map (kbd "C-c C-c") 'haskell-process-cabal-build)
(define-key haskell-cabal-mode-map (kbd "C-c c") 'haskell-process-cabal)

13.4.4 GHCi process type

By default haskell-process-type is set to auto. It is smart enough to pick the right type based on your project structure and installed tools, but in case something goes funky or you want to explicitly set the process type and ignore the inferred type, you can customize this setting by running M-x customize-variable RET haskell-process-type RET, or by setting the code:

(custom-set-variables
  '(haskell-process-type 'cabal-repl))

Here is a list of available process types:

  • ghci
  • cabal-repl
  • cabal-new-repl
  • stack-ghci

Please, check the documentation for haskell-process-type to see how the real type is guessed, when it’s set to auto.

13.4.5 Troubleshooting

Launching your GHCi process can fail when you’re first getting setup, depending on the type you choose. If it does fail to launch, switch to the buffer *haskell-process-log* and see what’s up. The buffer contains a log of incoming/outgoing messages to the GHCi process.

13.5 Haskell Interactive Mode Tags Using GHCi

You can bind the following to use GHCi to find definitions of things:

(define-key haskell-mode-map (kbd "M-.") 'haskell-mode-jump-to-def)

The one problem with this approach is that if your code doesn’t compile, GHCi doesn’t give any location info. So you need to make sure your code compiles and the modules you want to jump to are loaded byte-compiled.

Note: I think that when you restart GHCi you lose location information, even if you have the .o and .hi files lying around. I’m not sure. But sometimes :i foo will give foo is defined in Bar rather than foo is defined in /foo/Bar.hs:123:23.

Alternatively, you can use tags generation, which doesn’t require a valid compile.

13.5.1 Tags Setup

Make sure to install hasktags.

    $ cabal install hasktags

Then add the customization variable to enable tags generation on save:

(custom-set-variables
  '(haskell-tags-on-save t))

And make sure hasktags is in your $PATH which Emacs can see.

13.5.2 Generating tags

Now, every time you run save-buffer (C-x C-s), there is a hook that will run and generate Emacs See (emacs)Tags, for the whole project directory. The resulting file will be called TAGS.

WARNING: You should be careful that your project root isn’t your home directory or something, otherwise it will traverse all the way down and take an impossibly long time.

13.5.3 Jumping to tags

Bind the following keybinding:

(define-key haskell-mode-map (kbd "M-.") 'haskell-mode-tag-find)

To jump to the location of the top-level identifier at point, run M-x haskell-mode-tag-find or M-..

13.5.4 Hybrid: GHCi and fallback to tags

To use GHCi first and then if that fails to fallback to tags for jumping, use:

(define-key haskell-mode-map (kbd "M-.") 'haskell-mode-jump-to-def-or-tag)

13.5.5 Troubleshooting tags

Sometimes a TAGS file is deleted (by you or some other process). Emacs will complain that it doesn’t exist anymore. To resolve this simply do M-x tags-reset-tags-tables.

13.6 Sessions

All commands in Haskell Interactive Mode work within a session. Consider it like a “project” or a “solution” in popular IDEs. It tracks the root of your project and an associated process and REPL.

13.6.1 Start a session

To start a session run the following steps:

  • Open some Cabal or Haskell file.
  • Run C-` to make a REPL open, this will create a session, start GHCi, and open the REPL.
  • Or: run C-c C-l to load the file. This will first try to start a session as the previous command does.
  • Or: run any command which requires a running session. It will always prompt to create one if there isn’t one already for the current project.

It will prompt for a Cabal directory and a current directory. It figures out where the cabal directory is and defaults for the current directory, so you should be able to just hit RET twice.

13.6.2 Switch a session

Sometimes a particular file is used in two different sessions/projects. You can run

    M-x haskell-session-change

If it prompts you to make a new session, tell it no (that’s a bug). It will ask you to choose from a list of sessions.

13.6.3 Killing a session

To kill a session you can run

    M-x haskell-session-kill

Alternatively, you can switch to the REPL and just kill the buffer normally with C-x k RET. It will prompt

    Kill the whole session (y or n)?

You can choose y to kill the session itself, or n to just kill the REPL buffer. You can bring it back with M-x haskell-interactive-bring.

If you would like to be prompted to kill the associated buffers, you can add projectile-kill-buffers to haskell-kill-session-hook.

13.7 Compiling

There are a bunch of ways to compile Haskell modules. This page covers a few of them.

13.7.1 Load into GHCi

To compile and load a Haskell module into GHCi, run the following

    M-x haskell-process-load

Or C-c C-l. You’ll see any compile errors in the REPL window.

13.7.2 Build the Cabal project

To compile the whole Cabal project, run the following

    M-x haskell-process-cabal-build

Or C-c C-c. You’ll see any compile errors in the REPL window.

13.7.3 Reloading modules

To reload the current module, even when you’re in other modules, you can run C-u M-x haskell-process-load-or-reload or C-u C-c C-l. It will now reload that module whenever you run C-c C-l in the future from whatever module you’re in. To disable this mode, just run C-u C-c C-l again.

13.7.4 Jumping to compile errors

You can use the standard compile error navigation function C-x ` — jump to the next error.

Or you can move your cursor to an error in the REPL and hit RET to jump to it.

13.7.5 Auto-removing imports

If the customization variable haskell-process-suggest-remove-import-lines is enabled.

(custom-set-variables
  '(haskell-process-suggest-remove-import-lines t))

Building and loading modules which output warnings like,

    Warning: The import of `Control.Monad' is redundant
      except perhaps to import instances from `Control.Monad'
    To import instances alone, use: import Control.Monad()

will prompt the user with

> The import line `Control.Monad' is redundant. Remove? (y, n, c: comment out)

If you answer

  • y: it will delete the import, but leave the empty line remaining (this avoids messing with line positions in subsequent error messages).
  • n: it will leave the import.
  • c: it will comment out the import (this is handy for when you just want to temporarily hide an import).

13.7.6 Auto-adding of modules to import

Enable the customization variable haskell-process-suggest-hoogle-imports.

(custom-set-variables
  '(haskell-process-suggest-hoogle-imports t))

Whenever GHC says something is not in scope, it will hoogle that symbol. If there are results, it will prompt to add one of the modules from Hoogle’s results.

You need to make sure you’ve generated your Hoogle database properly.

13.7.7 Auto-adding of extensions

It you use an extension which is not enabled, GHC will often inform you. For example, if you write:

newtype X a = X (IO a)
  deriving (Monad)

Then you’ll see a message like:

    x.hs:13:13: Can't make a derived instance of `Monad X': …
          `Monad' is not a derivable class
          Try -XGeneralizedNewtypeDeriving for GHC's newtype-deriving extension
        In the newtype declaration for `X'

This -XFoo pattern will be picked up and you will be prompted:

> Add `{-# LANGUAGE GeneralizedNewtypeDeriving #-}` to the top of the
> file? (y or n)

If you answer ‘y‘, it will temporarily jump to the buffer and it to the top of the file.

13.7.8 Orphan instances

If GHC complains about orphan instances, you usually are doing it intentionally, so it prompts to add -fno-warn-orphans to the top of the file with an OPTIONS pragma.

13.7.9 Auto-adding of dependencies

When doing a build, you will sometimes get a message from GHC like:

    src/ACE/Tokenizer.hs:11:18: Could not find module `Data.Attoparsec.Text' …
        It is a member of the hidden package `attoparsec-0.11.1.0'.

This message contains all the necessary information to add this to your .cabal file, so you will be prompted to add it to your .cabal file:

    Add `attoparsec' to ace.cabal? (y or n)  y

If you hit y, it will prompt with this:

    attoparsec >= 0.11.1.0

Which you can edit (e.g. do some PVP decision or remove constraints entirely), and then it will open up your .cabal file and go through each section:

    Add to library? (y or n)  y

This will add it to the top of the build-depends field in your library section. If you have any executables, it will go through each of those, prompting, too.

Now you can rebuild with C-c C-c again.

13.8 Haskell Interactive Mode REPL

When GHCi has been launched, it works on a read-eval-print basis. So you will be presented with the prompt:

    The lambdas must flow.
    Changed directory: /path/to/your/project/
    λ>

13.8.1 Changing REPL target

With haskell-session-change-target you can change the target for REPL session.

After REPL session started, in haskell-interactive-mode buffer invoke the haskell-session-change-target and select from available targets for

- Testing

- Benchmark

- Executable

- Library

Answer “yes” to restart the session and run your tests, benchmarks, executables.

TODO/WRITEME

13.8.2 Bringing the REPL

If you don’t know where the REPL buffer is, you can always bring it with:

    M-x haskell-interactive-bring

Or C-`.

13.8.3 Evaluating expressions

To evaluate expressions, simply type one out and hit ‘RET‘.

    λ> 123
    123

13.8.4 Evaluating multiline expressions

GHCi features two ways to evaluate multiline expressions. You can use :set +m to enable multiline input for all expressions, or you can wrap your expression in :{ and :} (they have to be on their own lines).

The prompt will change to indicate that you’re inputting a multiline expression:

λ> :{
λ| let a = 10
λ|     b = 20
λ|     c = 30
λ| :}

You can also simulate multiline mode by having your input contain newline characters. You can input a literal newline character with C-q C-j, or you can use:

    M-x haskell-interactive-mode-newline-indent

which is bound to C-j. This command indents after the newline. You can simulate the above example like so:

λ> let a = 10
       b = 20
       c = 30

13.8.5 Type of expressions

You can use normal :type which is part of GHCi to get the type of something:

    λ> :t id
    id :: a -> a

But you can also just write out the value directly,

    λ> id
    id :: a -> a

and because there’s no Show instance for (a -> a). This would normally yield a compile error:

    No instance for (Show (a0 -> a0))
      arising from a use of `print'
    Possible fix: add an instance declaration for (Show (a0 -> a0))
    In a stmt of an interactive GHCi command: print it

It will run :type id in the background and print out the result. The same is true for ambiguous things:

    λ> :t read "a"
    read "a" :: Read a => a

Because this would normally be an ambiguous constraint:

    Ambiguous type variable `a0' in the constraint:
      (Read a0) arising from a use of `read'
    Probable fix: add a type signature that fixes these type variable(s)
    In the expression: read \"a\"
    In an equation for `it': it = read \"a\"

Which is less useful than just printing the type out.

You can disable this behaviour by disabling the customization option:

(custom-set-variables
  '(haskell-interactive-types-for-show-ambiguous nil))

13.8.6 Printing mode

You can choose between printing modes used for the results of evaluating expressions. To do that, configure the variable haskell-interactive-mode-eval-mode. Example:

(setq haskell-interactive-mode-eval-mode 'haskell-mode)

A handy function you can use is:

(defun haskell-interactive-toggle-print-mode ()
  (interactive)
  (setq haskell-interactive-mode-eval-mode
        (intern
         (ido-completing-read "Eval result mode: "
                              '("fundamental-mode"
                                "haskell-mode"
                                "espresso-mode"
                                "ghc-core-mode"
                                "org-mode")))))

(Add whichever modes you want to use.)

And then run

    M-x haskell-interactive-toggle-print-mode

Or C-c C-v:

(define-key haskell-interactive-mode-map (kbd "C-c C-v")
            'haskell-interactive-toggle-print-mode)

There you can choose ‘haskell-mode‘, for example, to pretty print the output as Haskell.

13.8.7 SVG images rendering

If you are working on SVG images, you can instruct Emacs to render the image as the output of an image producing command at the REPL.

The following example uses the diamgrams library with the default SVG backend to produce a circle:

    {-# LANGUAGE OverloadedStrings #-}

    import Diagrams.Prelude
    import Diagrams.Backend.SVG

    myCircle :: Diagram B
    myCircle = circle 1 # lc purple # fc yellow

    circle = renderDia SVG (SVGOptions (mkWidth 250) Nothing "" [] True) myCircle

After enabling SVG rendering with M-x haskell-svg-toggle-render-images, if you load the above code and type circle at the REPL, you will see the rendered circle instead of the XML representation of the image.

For this feature to work, it is required that the variable haskell-interactive-mode-eval-mode be set to a value different from nil, see printing mode.

This feature can be enabled by default by setting the customization variable haskell-svg-render-images to a non-nil value.

13.8.8 Presentations

If you have the present package installed, you can use the following syntax to print anything which is an instance of Data:

    λ> :present 123
    123

It will print data structures lazily:

    λ> :present [1..]
    [1
    ,[Integer]]

It shows types when there is an unevaluated field in a constructor. You can click the [Integer] or press RET on it to expand further:

    λ> :present [1..]
    [1
    ,2
    ,[Integer]]

Etc. Remember: this only works for instances of Data.Data.Data.

13.8.9 History

A history is maintained for the duration of the REPL buffer. To go up and down in the history, run M-p for previous and M-n for next.

13.8.10 Cancelling commands

To cancel a running REPL command, run C-c C-c.

13.8.11 Clear the REPL

Run C-c C-k to clear the REPL.

13.8.12 Trick: Put Interactive REPL in Separate Frame

The following create-haskell-interactive-frame is a quick hack to move the repl to a separate frame, for those that want a more predictable layout of windows in Emacs.

(defun create-unfocused-frame ()
  (let*
    ((prv (window-frame))
     (created (make-frame)))
    (select-frame-set-input-focus prv) created))

(defun create-haskell-interactive-frame ()
  (interactive)
  (haskell-interactive-bring)
  (create-unfocused-frame)
  (delete-window))

13.8.13 Troubleshooting

If the REPL ever goes funny, you can clear the command queue via:

    M-x haskell-process-clear

Alternatively, you can just restart the process:

    M-x haskell-process-restart

You can also switch to the buffer *haskell-process-log*, which can be enabled and disabled with the customization variable ‘haskell-process-log‘, to see what the cause of your troubles are.

If the process fails and nothing unusual is in the process log, the following command can dump the haskell-process state:

    M-: (haskell-process)

The output can be copied from the *Messages* buffer.

13.9 Haskell Interactive Mode Querying

There a few ways GHCi lets you query information about your code.

13.9.1 Get identifier type

To print the type of the top-level identifier at point in the REPL and in the message buffer, run the following command:

    M-x haskell-process-do-type

or C-c C-t.

13.9.2 Insert identifier’s type as type signature

To print the type of the top-level identifier at point, run the following command:

    C-u M-x haskell-process-do-type

or C-u C-c C-t.

13.9.3 Get identifier info

To print the info of the identifier at point, run the following command:

    M-x haskell-process-do-info

or C-c C-i.

13.9.4 Presentation mode

When using C-c C-i or C-c C-t it will open a buffer in haskell-presentation-mode. You can hit q to close the buffer.

But you can also continue to use C-c C-i inside the buffer to drill further down data types and classes.

E.g. if you go to Ord in your code buffer and C-c C-i, it will popup a buffer containing

class Eq a => Ord a where
  compare :: a -> a -> Ordering
  (<) :: a -> a -> Bool
  (>=) :: a -> a -> Bool
  (>) :: a -> a -> Bool
  (<=) :: a -> a -> Bool
  max :: a -> a -> a
  min :: a -> a -> a
  	-- Defined in `GHC.Classes'

And all the instances of that class. But then you can also move your cursor to Ordering and hit C-c C-i again to get another popup:

data Ordering = LT | EQ | GT 	-- Defined in `GHC.Types'
instance Bounded Ordering -- Defined in `GHC.Enum'
instance Enum Ordering -- Defined in `GHC.Enum'
instance Eq Ordering -- Defined in `GHC.Classes'
instance Ord Ordering -- Defined in `GHC.Classes'
instance Read Ordering -- Defined in `GHC.Read'
instance Show Ordering -- Defined in `GHC.Show'

And so on. It’s a very good way of exploring a new codebase.

13.9.5 Browse import’s module

To print all exported identifiers of the module imported by the import line at point, run the following command:

    M-x haskell-process-do-info

or C-c C-i. It will print all exports by running :browse The.Module in the GHCi process.

13.10 Haskell Interactive Mode Cabal integration

There’s some integration with Cabal in Haskell Interactive Mode. Once you’ve started a session, the features below are available.

13.10.1 Cabal building

The most common Cabal action is building, so that has a specific command:

    M-x haskell-process-cabal-build

Or C-c C-c. When building, it will hide unnecessary output.

For example, to build the ‘ace‘ package, the output is simply:

    Compiling: ACE.Types.Tokens
    Compiling: ACE.Combinators
    Compiling: ACE.Tokenizer
    Compiling: ACE.Parsers
    Compiling: ACE.Pretty
    Compiling: ACE
    Complete: cabal build (0 compiler messages)

Whereas the complete output is normally:

    Building ace-0.5...
    Preprocessing library ace-0.5...
    [4 of 9] Compiling ACE.Types.Tokens ( src/ACE/Types/Tokens.hs, dist/build/ACE/Types/Tokens.o )
    [5 of 9] Compiling ACE.Combinators  ( src/ACE/Combinators.hs, dist/build/ACE/Combinators.o ) [ACE.Types.Tokens changed]
    [6 of 9] Compiling ACE.Tokenizer    ( src/ACE/Tokenizer.hs, dist/build/ACE/Tokenizer.o ) [ACE.Types.Tokens changed]
    [7 of 9] Compiling ACE.Parsers      ( src/ACE/Parsers.hs, dist/build/ACE/Parsers.o )
    [8 of 9] Compiling ACE.Pretty       ( src/ACE/Pretty.hs, dist/build/ACE/Pretty.o )
    [9 of 9] Compiling ACE              ( src/ACE.hs, dist/build/ACE.o ) [ACE.Tokenizer changed]
    In-place registering ace-0.5...

Which is considerably more verbose but rarely useful or interesting.

13.10.2 Arbitrary cabal commands

To run an arbitrary Cabal command:

    C-u M-x haskell-process-cabal

Or run C-u C-c c.

It will prompt for an input, so you can write configure -fdev, for example.

13.10.3 Completing cabal commands

To run some common Cabal commands, just run:

    M-x haskell-process-cabal

Or C-c c. This is commonly used to do install, haddock, configure, etc.

13.11 Haskell Interactive Mode Debugger

There is limited support for debugging in GHCi. Haskell Interactive Mode provides an interface for interacting with this.

13.11.1 Opening the debug buffer

To open the debug buffer run the following command from any buffer associated with a session:

    M-x haskell-debug

It will open a buffer that looks like this:

    Debugging haskell

    You have to load a module to start debugging.

    g - refresh

    Modules

    No loaded modules.

13.11.2 Loading modules

To debug anything you need to load something into GHCi. Switch to a normal file, for example:

main = do putStrLn "Hello!"
          putStrLn "World"

and load it into GHCi (C-c C-l). Now when you hit g (to refresh) in the debugging buffer, you’ll see something like:


    Debugging haskell

    b - breakpoint, g - refresh

    Context

    Not debugging right now.

    Breakpoints

    No active breakpoints.

    Modules

    Main - hello.hs

13.11.3 Setting a breakpoint

To set a breakpoint hit b in the debugger buffer. It will prompt for a name. Enter main and hit RET.

Now the buffer will look like this:

    Debugging haskell

    s - step into an expression, b - breakpoint
    d - delete breakpoint, g - refresh

    Context

    Not debugging right now.

    Breakpoints

    0 - Main (1:8)

    Modules

    Main - hello.hs

13.11.4 Start stepping

Hit s to step through an expression: it will prompt for an expression to evaluate and step through. Enter main and hit RET. Now the buffer will look like this:

    Debugging haskell

    s - step into an expression, b - breakpoint
    d - delete breakpoint, a - abandon context, c - continue
    p - previous step, n - next step
    g - refresh

    Context

    main - hello.hs (stopped)

    do putStrLn "Hello!"
       putStrLn "World"

    _result :: IO () = _

       1 do putStrLn "Hello!" putStrLn "World"

    Breakpoints

    0 - Main (1:8)

    Modules

    Main - hello.hs

What we see here is the current expression being evaluated:

do putStrLn "Hello!"
   putStrLn "World"

And we see the type of it:

_result :: IO () = _

And we see a backtrace of steps so far:

1 do putStrLn "Hello!" putStrLn "World"

13.11.5 Continue stepping

To continue stepping, just hit s again. Now the context will change to:

main - hello.hs (stopped)

putStrLn "Hello!"

_result :: IO () = _

   1 do putStrLn "Hello!" putStrLn "World"

Hitting s once more, we see the context change to:

putStrLn "World"

_result :: IO () = _

   2 putStrLn "Hello!"
   1 do putStrLn "Hello!" putStrLn "World"

Finally hitting s again will say "Computation finished". Hitting s a final time will change the display back to:

    Debugging haskell

    s - step into an expression, b - breakpoint
    d - delete breakpoint, g - refresh

    Context

    Finished debugging.

       2 putStrLn "Hello!"
       1 do putStrLn "Hello!" putStrLn "World"

    Breakpoints

    1 - Main (1:8)

    Modules

    Main - hello.hs

And you’re done debugging.


14 Editing Cabal files

haskell-cabal-mode is a major mode for editing Cabal package description files and is automatically associated with files having a .cabal extension.

For quickly locating and jumping to the nearest .cabal file from a Haskell source buffer, you can use M-x haskell-cabal-visit-file; with a prefix argument (i.e. C-u) find-file-other-window is used to visit the .cabal file. haskell-cabal-visit-file is bound to the key sequence C-c v c.

TODO/WRITEME


15 Browsing Haddocks using w3m

An experimental feature is use of the w3m browser to browse Haddock docs inside Emacs.

15.1 Get w3m

Most Linux distributions will have a package for the binary:

$ sudo apt-get install w3m

Now grab w3m.el from:

Confirm installation by trying M-x w3m-browse-url RET haskell.org RET.

If this works, you’re good to go.

15.2 Configure w3m

Now that you have w3m, you probably want to configure it to be more of a passive viewer than a full-fledged browser. For example:

(setq w3m-mode-map (make-sparse-keymap))

(define-key w3m-mode-map (kbd "RET") 'w3m-view-this-url)
(define-key w3m-mode-map (kbd "q") 'bury-buffer)
(define-key w3m-mode-map (kbd "<mouse-1>") 'w3m-maybe-url)
(define-key w3m-mode-map [f5] 'w3m-reload-this-page)
(define-key w3m-mode-map (kbd "C-c C-d") 'haskell-w3m-open-haddock)
(define-key w3m-mode-map (kbd "M-<left>") 'w3m-view-previous-page)
(define-key w3m-mode-map (kbd "M-<right>") 'w3m-view-next-page)
(define-key w3m-mode-map (kbd "M-.") 'w3m-haddock-find-tag)

(defun w3m-maybe-url ()
  (interactive)
  (if (or (equal '(w3m-anchor) (get-text-property (point) 'face))
          (equal '(w3m-arrived-anchor) (get-text-property (point) 'face)))
      (w3m-view-this-url)))

15.3 Import w3m-haddock

It’s not enabled by default in haskell-mode at present, so you need to import it manually:

(require 'w3m-haddock)

15.4 Add a hook for w3m

In order to make haddock pages a little more palatable (and add syntax highlighting to source view), you can add this hook:

(add-hook 'w3m-display-hook 'w3m-haddock-display)

It’s a little rough around the edges, but it’s a start.

15.5 Configure your package locations

By default, the package locations is set to:

(defcustom haskell-w3m-haddock-dirs
  '("~/.cabal/share/doc/"))

If you are using an hsenv or a custom package directory, you should configure this variable with M-x customize-variable or by writing the custom-set-variables code for it.

15.6 Finally

You did all that! Now you’re ready to bind a useful key:

(define-key haskell-mode-map (kbd "C-c C-d") 'haskell-w3m-open-haddock)

Now when you press C-c C-d it will prompt for a package to browse to.

This feature will be improved gradually as time goes on.


16 Using with flyspell-prog-mode

Strings and comments can be checked for spelling mistakes. There is a standard Emacs mode for this purpose, flyspell-prog-mode, that can be enabled in Haskell buffers. Spelling errors are underlined using squiggly red lines.

anim/flyspell-prog-mode

Documentation for flyspell-prog-mode can be found in See (emacs)Spelling. Here we point to a couple of useful keybindings:

To enable spell checking of strings and comments add this line to your ~/.emacs file:

(add-hook 'haskell-mode-hook 'flyspell-prog-mode)


17 Aligning code

Select a region you want to align text within, M-x align-regexp, and type a regexp representing the alignment delimiter.

For example, I often line up my Haddock comments:

f :: a -- ^ does a
  -> Foo b -- ^ and b
  -> c -- ^ to c

Select the region, and let the regexp be ‘--’:

f :: a     -- ^ does a
  -> Foo b -- ^ and b
  -> c     -- ^ to c

Of course, this works for just about anything. Personally, I’ve globally bound it to C-x a r:

(global-set-key (kbd "C-x a r") 'align-regexp)

Note that you can also just use the rules below for telling the aligner about Haskell. Once you evaluate this, you can just use M-x align, which I like to bind to M-[.

(add-to-list 'align-rules-list
             '(haskell-types
               (regexp . "\\(\\s-+\\)\\(::\\|∷\\)\\s-+")
               (modes quote (haskell-mode haskell-literate-mode))))
(add-to-list 'align-rules-list
             '(haskell-assignment
               (regexp . "\\(\\s-+\\)=\\s-+")
               (modes quote (haskell-mode haskell-literate-mode))))
(add-to-list 'align-rules-list
             '(haskell-arrows
               (regexp . "\\(\\s-+\\)\\(->\\|→\\)\\s-+")
               (modes quote (haskell-mode haskell-literate-mode))))
(add-to-list 'align-rules-list
             '(haskell-left-arrows
               (regexp . "\\(\\s-+\\)\\(<-\\|←\\)\\s-+")
               (modes quote (haskell-mode haskell-literate-mode))))

18 Using rectangular region commands

Emacs has a set of commands which operate on the region as if it were rectangular. This turns out to be extremely useful when dealing with whitespace sensitive languages.

As with all Emacs modifier combos, you can type C-x r C-h to find out what keys are bound beginning with the C-x r prefix.


19 Using GHCi REPL within Emacs

To start the REPL you can run the following:

This repl works with Comint. So you will feel at home if you are already using M-x Shell or M-x ielm.

Inf-Haskell is a Major mode for running GHCi, with comint.

Important key bindings in Inf-haskell:

RET

invokes comint-send-input. Sends the input to the GHCi process, evaluates the line and returns the output.

C-d or <delete>

deletes the forward character

<C-up> or M-p

invokes comint-previous-input. Cycle backwards through input history, saving input.

<C-down> or M-n

invokes comint-next-input. Cycle forwards through input history.

C-c C-c

invokes comint-interrupt-subjob. Sends KeyboardInterrupt signal.

C-c C-\

invokes comint-quit-subjob. Sends KeyboardInterrupt signal.

C-c C-z

invokes comint-stop-subjob. Kills the GHCi process.

C-c M-r

invokes comint-previous-matching-input-from-input. If you are familiar with C-r in bash. This is the same as that. Searches backwards through input history for match for current input.

C-c M-s

invokes comint-next-matching-input-from-input. Searches forwards through input history for match for current input.

C-c C-l

invokes comint-dynamic-list-input-ring. Displays a list of recent inputs entered into the current buffer.

C-c M-o

invokes comint-clear-buffer. Clears the buffer (Only with Emacs 25.X and above)

C-c C-n

invokes comint-next-prompt. Goes to the start of the previous REPL prompt.

C-c C-p

invokes comint-previous-prompt. Goes to the start of the next REPL prompt.

C-c C-o

invokes comint-delete-output. Clears the output of the most recently evaluated expression.

C-c C-e

invokes comint-show-maximum-output. Moves the point to the end of the buffer.

C-c C-u

invokes comint-kill-input. Kills backward, the line at point. (Use this when you have typed in an expression into the prompt but you dont want to evaluate it.)

C-c C-w

invokes backward-kill-word. Kills backward, the word at point

C-c C-s

invokes comint-write-output. Write output from interpreter since last input to FILENAME. Any prompt at the end of the output is not written.

19.1 Relevant defcustoms:

Interpreter (defcustom)Default ValuePossible Values
haskell-process-type'auto'stack-ghci, 'cabal-repl, 'ghci, 'auto
inferior-haskell-hooknil-
haskell-process-path-ghcighci-
haskell-process-args-ghci-ferror-spans-
haskell-process-path-cabalcabal-
haskell-process-args-cabal-repl--ghc-option=-ferror-spans-
haskell-process-path-stackstack-
haskell-process-args-stack-ghci--ghci-options=-ferror-spans --no-build --no-load-

19.2 More on haskell-process-type

The Haskell interpreter used by Inf-Haskell is auto-detected by default, but is customizable with defcustom haskell-process-type. The values recognized by it are (default is ’auto):

  • 'stack-ghci
  • 'cabal-repl
  • 'ghci
  • 'auto

if the haskell-process-type is 'auto, the directories are searched for cabal.sandbox.config or stack.yaml or *.cabal file. If the file is present, then appropriate process is started.

When cabal.project or cabal.sandbox.config is found, haskell-process-type is 'cabal-repl. Similarly, when stack.yaml is found haskell-process-type is 'stack-ghci. Similarly, when xyz.cabal is found haskell-process-type is 'cabal-repl. When nothing is found haskell-process-type is 'ghci. When more than one file such as cabal.sandbox.config and stack.yaml are found the following preference is followed: cabal.project > stack.yaml > *.cabal


20 Collapsing Haskell code

This is hs-minor-mode for haskell-mode. This module uses hideshow module.

To activate this minor mode (haskell-collapse-mode)

This minor mode works with indentation.

In a quick glance:

C-c  C-c

is bound to haskell-hide-toggle

C-c  C-M-c
C-c  C-M-h
C-c  C-M-s

are all bound to haskell-hide-toggle-all

How to use M-x haskell-hide-toggle?

Place your point on the code block that you want to collapse and hit the keybinding. Now the code collapses and you can see the first line of the block and elipsis.

Take this example code (example usage of M-x haskell-hide-toggle): when you place the cursor here, like this (notice the thick block in the first line):

f█x | rem i 3 == 0 = if i == 0 && (k /= 0) then (c k) else (h j) | otherwise = 0 where i = sum x j = g x (div i 3) 0 0 [] k = zeroes x 0

or

f x | rem i 3 == 0 = if i == 0 && (k /= 0) then (c k) else (h j) █ | otherwise = 0 where i = sum x j = g x (div i 3) 0 0 [] k = zeroes x 0

then when you collapse it becomes something like this:

f█x…

It works in terms of (indentation) blocks.

One more example:

f x | rem i 3 == 0 = if i == 0 && (k /= 0) then (c k) else (h j) | otherwise = 0 w█ere i = sum x j = g x (div i 3) 0 0 [] k = zeroes x 0

or

f x | rem i 3 == 0 = if i == 0 && (k /= 0) then (c k) else (h j) | otherwise = 0 where i = sum x j = g x (div i 3) 0 0 [] █ k = zeroes x 0

this, will result in something like:

f x | rem i 3 == 0 = if i == 0 && (k /= 0) then (c k) else (h j) | otherwise = 0 where i = sum █…

The other functionality M-x haskell-hide-toggle-all also works only for indentation and it collapses all toplevel functions.

So a file that looks like this:

main = interact $ show.f. map read .words
f (x:xs) = dp x xs

dp money a | money < 0 || null a = [1..1000]
dp 0 a = []
dp money a @ (coin:coins)
  | (length i) <= length j = i
  | otherwise = j
  where i = (coin:(dp (money-coin) a))
        j = (dp money coins)

will turn into this:

main = interact $ show.f. map read .words
f (x:xs) = dp x xs

dp money a | money < 0 || null a = [1..1000]
dp 0 a = []
dp money a @ (coin:coins)…

21 Getting Help and Reporting Bugs

Work on Haskell Mode is organized with Github haskell-mode project. To understand how the project is run please read the information in the project wiki pages.

To report any issues please use the Github’s issue mechanism available from Haskell Mode’s GitHub Home.

For a quick question visit #haskell-emacs channel on IRC irc.freenode.net.

There is also a (now defunct) Haskellmode-emacs mailing list, also available on Gmane via the gmane.comp.lang.haskell.emacs newsgroup.

We welcome code and non-code contributions so that we can all enjoy coding Haskell even more.


Concept index

Jump to:   B   C   H   I   L   O   R   S   T   U  
Index Entry  Section

B
benchmarking: Interactive Haskell

C
CUA mode: Indentation
customizing: Installation
customizing: Interactive Haskell

H
haskell-mode: Editing Haskell Code

I
Images, rendering SVG images: Interactive Haskell
indentation: Indentation

L
layout rule: Indentation

O
off-side rule: Indentation

R
rectangle: Indentation
Rendering SVG images: Interactive Haskell

S
SVG images, rendering: Interactive Haskell

T
testing: Interactive Haskell

U
Unicode: Unicode support

Jump to:   B   C   H   I   L   O   R   S   T   U  

Next: , Previous: , Up: Haskell Mode   [Index]

Function index

Jump to:   H  
Index Entry  Section

H
haskell-cabal-mode: Editing Cabal files
haskell-cabal-visit-file: Editing Cabal files
haskell-compile: Compilation
haskell-decl-scan-mode: Declaration scanning
haskell-mode: Editing Haskell Code
haskell-session-change-target: Interactive Haskell
haskell-svg-toggle-render-images: Interactive Haskell

Jump to:   H  

Previous: , Up: Haskell Mode   [Index]

Variable index

Jump to:   H  
Index Entry  Section

H
haskell-c2hs-hook-name-face: Syntax highlighting
haskell-c2hs-hook-pair-face: Syntax highlighting
haskell-cabal-mode-hook: Editing Cabal files
haskell-compile-cabal-build-alt-command: Compilation
haskell-compile-cabal-build-command: Compilation
haskell-compile-command: Compilation
haskell-compile-stack-build-alt-command: Compilation
haskell-compile-stack-build-command: Compilation
haskell-compiler-type: Compilation
haskell-constructor-face: Syntax highlighting
haskell-decl-scan-mode-hook: Declaration scanning
haskell-definition-face: Syntax highlighting
haskell-interactive-mode-hook: Interactive Haskell
haskell-keyword-face: Syntax highlighting
haskell-literate-comment-face: Syntax highlighting
haskell-mode-hook: Installation
haskell-operator-face: Syntax highlighting
haskell-pragma-face: Syntax highlighting
haskell-process-args-cabal-repl: Interactive Haskell
haskell-process-args-ghci: Interactive Haskell
haskell-process-args-stack-ghci: Interactive Haskell
haskell-process-path-cabal: Interactive Haskell
haskell-process-path-ghci: Interactive Haskell
haskell-process-path-stack: Interactive Haskell
haskell-process-type: Interactive Haskell
haskell-quasi-quote-face: Syntax highlighting
haskell-svg-render-images: Interactive Haskell
haskell-type-face: Syntax highlighting

Jump to:   H