Next: , Previous: , Up: Top   [Index]


6 Indentation

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

In Haskell, code indentation has semantic meaning as it defines the block structure4.

As GNU Emacs’ default indentation function (i.e. indent-relative) is not designed for use with Haskell’s layout rule, Haskell mode includes three different indentation minor modes with different trade-offs:

haskell-simple-indent-mode

A very simple indentation scheme; In this scheme, TAB will now move the cursor to the next indent point in the previous non-blank line. An indent point is a non-whitespace character following whitespace.

haskell-indent-mode

Intelligent semi-automatic indentation for Haskell’s layout rule. The basic idea is to have TAB cycle through possibilities indentation points based on some clever heuristics.

The rationale and the implementation principles are described in more detail in the article Dynamic tabbing for automatic indentation with the layout rule published in the Journal of Functional Programming 8.5 (1998).

haskell-indentation-mode

Improved variation of haskell-indent-mode indentation mode. Rebinds RET and DEL, so that indentations can be set and deleted as if they were real tabs.

To enable one of these three mutually exclusive indentation schemes, you just need call one (and only one!) of the *-mode commands while in the buffer you want the indentation scheme to be activated for.

The recommended way is to add one of *-mode commands to haskell-mode-hook. This can be done either by using M-x customize-variable RET haskell-mode-hook which provides a convenient user interface or by adding one of the following three lines to your .emacs file:

(add-hook 'haskell-mode-hook 'haskell-simple-indent-mode)
(add-hook 'haskell-mode-hook 'haskell-indent-mode)
(add-hook 'haskell-mode-hook 'haskell-indentation-mode)

6.1 Interactive Block Indentation

By inserting the key bindings for C-, and C-. (these bindings are convenient on keyboard layouts where , and . are adjacent keys) as shown below you can interactively de/indent either the following nested block or, if a region is active while in Transient Mark Mode (see (emacs)Disabled Transient Mark), de/indent the active region.

By using a numeric prefix argument (see (elisp)Prefix Command Arguments) you can modify the shift-amount; for instance, C-u C-, increases indentation by 4 characters at once.

(eval-after-load "haskell-mode"
  '(progn
     (define-key haskell-mode-map (kbd "C-,") 'haskell-move-nested-left)
     (define-key haskell-mode-map (kbd "C-.") 'haskell-move-nested-right)))

6.2 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).


Footnotes

(4)

Haskell also supports braces and semicolons notation for conveying the block structure. However, most Haskell programs written by humans use indentation for block structuring.


Next: , Previous: , Up: Top   [Index]