Next: Introduction [Index]
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.
w3m
flyspell-prog-mode
Next: Installation, Previous: Haskell Mode, Up: Haskell Mode [Index]
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
).
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.
Next: Editing Haskell Code, Previous: Introduction, Up: Haskell Mode [Index]
Haskell Mode is distributed as a package in MELPA repository. To use MELPA as Emacs package archive do the following:
package-archives
using
M-x customize-option RET package-archives
Archive name: melpa-stable URL or directory name: http://stable.melpa.org/packages/
M-x package-refresh-contents
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.
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: Syntax highlighting, Previous: Installation, Up: Haskell Mode [Index]
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:
official file extension for Haskell files. Haskell Mode out of the box supports most of GHC extensions.
official file extension for Literate Haskell files. Both Bird and Latex styles are supported.
Haskell interfaces to C code used by hsc2hs pre-processor.
Haskell source with CPP pragmas used with cpphs pre-processor.
Haskell FFI bindings to C libraries used with c2hs pre-processor.
Haskell Mode offers many productivity tools described in following chapters in this manual.
There are a few functions for managing 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.
To generally format (sort, align) your imports, you can run
M-x haskell-mode-format-imports
Or C-c C-,.
To just sort imports, jump to an import section and run
M-x haskell-sort-imports
To just align imports, jump to an import section and run
M-x haskell-align-imports
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
.
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).
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.
Next: Completion support, Previous: Editing Haskell Code, Up: Haskell Mode [Index]
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
.
Syntax highlighting facilities parse strings and string escape sequences and are able to highlight unrecognized constructs.
Haskell Mode shows keywords, identifiers, operators, constructors and types in different colors.
There is also support to use mode-specific syntax highlighing for quasiquotes.
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:
haskell-keyword-face
: for keywords
haskell-type-face
: for type names and type class names
haskell-constructor-face
: for constructors
haskell-definition-face
: function and operator name at the definition place
haskell-operator-face
: operators
haskell-pragma-face
: GHC pragmas
haskell-literate-comment-face
: literate comments
haskell-quasi-quote-face
: quasi quotes unless using mode specific highlighting
haskell-c2hs-hook-pair-face
: c2hs hooks
haskell-c2hs-hook-name-face
: c2hs hook names
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.
Next: Unicode support, Previous: Syntax highlighting, Up: Haskell Mode [Index]
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.
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.
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: Indentation, Previous: Completion support, Up: Haskell Mode [Index]
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:
Sequence | Unicode | Sequence | Unicode | Sequence | Unicode | Sequence | Unicode |
---|---|---|---|---|---|---|---|
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 | ∈ |
notElem | ∉ | member | ∈ | notMember | ∉ | union | ∪ |
intersection | ∩ | isSubsetOf | ⊆ | isProperSubsetOf | ⊂ | <<< | ⋘ |
>>> | ⋙ | <| | ⊲ | |> | ⊳ | >< | ⋈ |
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.
Next: Other ways to indent code, Previous: Unicode support, Up: Haskell Mode [Index]
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:
haskell-indentation-mode
(default).
This is a semi-intelligent indentation mode doing a decent job at recognizing Haskell syntactical constructs. It is based on a recursive descent Haskell parser. TAB selects the next potential indentation position, S-TAB selects the previous one. If a block is selected you can use TAB to indent the block more and S-TAB to indent the block less.
When electric-indent-mode
is enabled or the variable
haskell-indentation-electric-flag
is non-nil, the insertion of
some characters (by default , ; ) } ])
may trigger auto reindentation under appropriate conditions. See the
documentation of haskell-indentation-common-electric-command
for
more details.
haskell-indent-mode
(optional).
This is a semi-intelligent indentation mode doing a decent job at recognizing Haskell syntactical constructs. It is based on a decision table. Sadly it is no longer developed and does not recognize newer Haskell syntax. TAB cycles through all available indentation positions.
To use haskell-indent-mode
, add this to your ~/.emacs
file:
(add-hook 'haskell-mode-hook 'turn-on-haskell-indent)
Note that turn-on-haskell-indent
will disable
haskell-indentation-mode
.
For general information about indentation support in GNU Emacs, see (emacs)Indentation.
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
).
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:
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
.
Next: Using external formatters, Previous: Indentation, Up: Haskell Mode [Index]
Some projects require indenting code with tabs and forbid indenting it with spaces. For hacking on such projects, check out haskell-tab-indent-mode.
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.
Next: Module templates, Previous: Other ways to indent code, Up: Haskell Mode [Index]
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
.
Next: Declaration scannning, Previous: Using external formatters, Up: Haskell Mode [Index]
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: Compilation, Previous: Module templates, Up: Haskell Mode [Index]
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:
Move to beginning of current or preceding declaration
(beginning-of-defun
).
Move to end of current or following declaration (end-of-defun
).
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))
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.
Next: Interactive Haskell, Previous: Declaration scannning, Up: Haskell Mode [Index]
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
.
cabal
, then cabal
is run, using the
command defined by haskell-compile-cabal-build-command
.
haskell-compile
looks for a .cabal file in the current directory
or its closet ancestor.
haskell-compiler-type
is the symbol stack
, then stack
is run, using the command haskell-compile-stack-build-command
, and
looking for the closest stack.yaml file.
haskell-compiler-type
is the symbol ghc
, then ghc
is
run, using the command haskell-compile-command
.
haskell-compiler-type
is the symbol auto
(the default),
then emacs tries to choose which build tool to use by looking for the closest
stack.yaml or .cabal file. (This is similar to the way
haskell-interactive-mode
uses the variable
haskell-process-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.
Key binding | Function |
---|---|
TAB | compilation-next-error |
RET | compile-goto-error |
C-o | compilation-display-error |
SPC | scroll-up-command |
- | negative-argument |
0 .. 9 | digit-argument |
< | beginning-of-buffer |
> | end-of-buffer |
? | describe-mode |
g | recompile |
h | describe-mode |
q | quit-window |
DEL | scroll-down-command |
S-SPC | scroll-down-command |
<backtab> | compilation-previous-error |
<follow-link> | mouse-face |
<mouse-2> | compile-goto-error |
<remap> | Prefix Command |
M-n | compilation-next-error |
M-p | compilation-previous-error |
M-{ | compilation-previous-file |
M-} | compilation-next-file |
C-c C-c | compile-goto-error |
C-c C-f | next-error-follow-minor-mode |
C-c C-k | kill-compilation |
Next: Editing Cabal files, Previous: Compilation, Up: Haskell Mode [Index]
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.
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
.
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.
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:
ghci
, haskell-process-path-ghci
and
haskell-process-args-ghci
will be used.
cabal-repl
or cabal-new-repl
,
haskell-process-path-cabal
and
haskell-process-args-cabal-repl
are used.
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.
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)
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))
This gives the basic ways to start a session. In a Haskell buffer:
(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)
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)
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:
Please, check the documentation for haskell-process-type
to see how
the real type is guessed, when it’s set to auto
.
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.
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.
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.
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.
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-..
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)
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
.
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.
To start a session run the following steps:
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.
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.
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
.
To see a list of all sessions you have open with some simple statistics about memory usage, etc. run
M-x haskell-menu
For example:
foo 14648 08:21:42 214MB /path/to/fpco/foo/ /path/to/fpco/foo/ ghci bar 29119 00:22:03 130MB /path/to/bar/ /path/to/bar/ ghci mu 22575 08:48:20 73MB /path/to/fpco/mu/ /path/to/fpco/mu/ ghci
There are a bunch of ways to compile Haskell modules. This page covers a few of them.
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.
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.
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.
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.
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
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.
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.
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.
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.
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/ λ>
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
If you don’t know where the REPL buffer is, you can always bring it with:
M-x haskell-interactive-bring
Or C-`.
To evaluate expressions, simply type one out and hit ‘RET‘.
λ> 123 123
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
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))
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.
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.
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
.
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.
To cancel a running REPL command, run C-c C-c.
Run C-c C-k to clear the REPL.
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))
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.
There a few ways GHCi lets you query information about your code.
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.
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.
To print the info of the identifier at point, run the following command:
M-x haskell-process-do-info
or C-c C-i.
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.
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.
There’s some integration with Cabal in Haskell Interactive Mode. Once you’ve started a session, the features below are available.
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.
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.
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.
There is limited support for debugging in GHCi. Haskell Interactive Mode provides an interface for interacting with this.
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.
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
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
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"
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.
Next: Browsing Haddocks using w3m
, Previous: Interactive Haskell, Up: Haskell Mode [Index]
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
Next: Using with flyspell-prog-mode
, Previous: Editing Cabal files, Up: Haskell Mode [Index]
w3m
An experimental feature is use of the w3m browser to browse Haddock docs inside Emacs.
Most Linux distributions will have a package for the binary:
$ sudo apt-get install w3m
Now grab w3m.el
from:
package-install
RET w3m
RET
Confirm installation by trying M-x w3m-browse-url
RET
haskell.org
RET.
If this works, you’re good to go.
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)))
It’s not enabled by default in haskell-mode at present, so you need to import it manually:
(require 'w3m-haddock)
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.
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.
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.
Next: Aligning code, Previous: Browsing Haddocks using w3m
, Up: Haskell Mode [Index]
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.
Documentation for flyspell-prog-mode
can be found in
See (emacs)Spelling. Here we point to a couple of useful
keybindings:
ispell-word
).
To enable spell checking of strings and comments add this line to your
~/.emacs
file:
(add-hook 'haskell-mode-hook 'flyspell-prog-mode)
Next: Using rectangular region commands, Previous: Using with flyspell-prog-mode
, Up: Haskell Mode [Index]
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))))
Next: Using GHCi REPL within Emacs, Previous: Aligning code, Up: Haskell Mode [Index]
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.
It will shift any text within the rectangle to the right side. Also see:
It will replace any text within the rectangle with the given string on all the lines in the region. If comment-region didn’t already exist, you could use this instead, for example.
It will delete the contents of the rectangle and move anything on the right over.
It will prompt you for a register number so it can save it for later.
This will insert the contents of the given register, overwriting whatever happens to be within the target rectangle. (So make room)
Delete rectangle and save contents for:
This will insert the contents of the last killed rectangle.
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.
Next: Collapsing Haskell code, Previous: Using rectangular region commands, Up: Haskell Mode [Index]
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
:
invokes comint-send-input. Sends the input to the GHCi process, evaluates the line and returns the output.
deletes the forward character
invokes comint-previous-input. Cycle backwards through input history, saving input.
invokes comint-next-input. Cycle forwards through input history.
invokes comint-interrupt-subjob. Sends KeyboardInterrupt signal.
invokes comint-quit-subjob. Sends KeyboardInterrupt signal.
invokes comint-stop-subjob. Kills the GHCi process.
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.
invokes comint-next-matching-input-from-input. Searches forwards through input history for match for current input.
invokes comint-dynamic-list-input-ring. Displays a list of recent inputs entered into the current buffer.
invokes comint-clear-buffer. Clears the buffer (Only with Emacs 25.X and above)
invokes comint-next-prompt. Goes to the start of the previous REPL prompt.
invokes comint-previous-prompt. Goes to the start of the next REPL prompt.
invokes comint-delete-output. Clears the output of the most recently evaluated expression.
invokes comint-show-maximum-output. Moves the point to the end of the buffer.
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.)
invokes backward-kill-word. Kills backward, the word at point
invokes comint-write-output. Write output from interpreter since last input to FILENAME. Any prompt at the end of the output is not written.
Interpreter (defcustom) | Default Value | Possible Values |
---|---|---|
haskell-process-type | 'auto | 'stack-ghci, 'cabal-repl, 'ghci, 'auto |
inferior-haskell-hook | nil | - |
haskell-process-path-ghci | ghci | - |
haskell-process-args-ghci | -ferror-spans | - |
haskell-process-path-cabal | cabal | - |
haskell-process-args-cabal-repl | --ghc-option=-ferror-spans | - |
haskell-process-path-stack | stack | - |
haskell-process-args-stack-ghci | --ghci-options=-ferror-spans --no-build --no-load | - |
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
Next: Getting Help and Reporting Bugs, Previous: Using GHCi REPL within Emacs, Up: Haskell Mode [Index]
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:
is bound to haskell-hide-toggle
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)…
Next: Concept index, Previous: Collapsing Haskell code, Up: Haskell Mode [Index]
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.
Next: Function index, Previous: Getting Help and Reporting Bugs, Up: Haskell Mode [Index]
Jump to: | B C H I L O R S T U |
---|
Jump to: | B C H I L O R S T U |
---|
Next: Variable index, Previous: Concept index, Up: Haskell Mode [Index]
Jump to: | H |
---|
Jump to: | H |
---|
Previous: Function index, Up: Haskell Mode [Index]
Jump to: | H |
---|
Jump to: | H |
---|