hindent: Extensible Haskell pretty printer

[ bsd3, development, library, program ] [ Propose Tags ]

Extensible Haskell pretty printer. Both a library and an executable. See the GitHub page for usage / explanation: https://github.com/mihaimaruseac/hindent

[Skip to Readme]


Maintainer's Corner

Package maintainers

For package maintainers and hackage trustees


  • No Candidates
Versions [RSS] 0.0, 1.0, 2.0, 2.1, 2.2, 2.3, 2.4, 3.0, 3.1, 3.2, 3.3, 3.4, 3.5, 3.6, 3.7, 3.8, 3.9, 3.9.1, 4.0, 4.1.0, 4.1.1, 4.2.0, 4.2.1, 4.2.2, 4.2.3, 4.2.4, 4.3.0, 4.3.1, 4.3.2, 4.3.3, 4.3.4, 4.3.5, 4.3.6, 4.3.7, 4.3.8, 4.3.9, 4.3.10, 4.3.11, 4.3.12, 4.4.0, 4.4.1, 4.4.2, 4.5.0, 4.5.1, 4.5.2, 4.5.3, 4.5.4, 4.5.5, 4.5.6, 4.5.7, 4.6.0, 4.6.1, 4.6.2, 4.6.3, 4.6.4, 5.0.0, 5.0.1, 5.1.0, 5.1.1, 5.2.0, 5.2.1, 5.2.2, 5.2.3, 5.2.4,, 5.2.5, 5.2.6, 5.2.7, 5.3.0, 5.3.1, 5.3.2, 5.3.3, 5.3.4, 6.0.0, 6.1.0, 6.1.1 (info)
Change log CHANGELOG.md
Dependencies base (>=4.7 && <5), bytestring, Cabal, containers, deepseq, directory, exceptions, filepath, ghc-lib-parser (>=9.2 && <9.9), ghc-lib-parser-ex, hindent, monad-loops, mtl, optparse-applicative, path, path-io, regex-tdfa, split, syb, transformers, unicode-show, utf8-string, yaml [details]
License BSD-3-Clause
Copyright 2014 Chris Done, 2015 Andrew Gibiansky, 2021 Mihai Maruseac
Author Mihai Maruseac, Chris Done, Andrew Gibiansky, Tobias Pflug, Pierre Radermecker
Maintainer Mihai Maruseac
Category Development
Home page https://github.com/mihaimaruseac/hindent
Bug tracker https://github.com/mihaimaruseac/hindent/issues
Source repo head: git clone https://github.com/mihaimaruseac/hindent
Uploaded by MihaiMaruseac at 2023-11-12T15:45:09Z
Distributions Debian:5.3.1, LTSHaskell:6.1.1, NixOS:6.1.1, Stackage:6.1.1
Reverse Dependencies 4 direct, 0 indirect [details]
Executables hindent
Downloads 64479 total (209 in the last 30 days)
Rating 2.25 (votes: 2) [estimated by Bayesian average]
Your Rating
  • λ
  • λ
  • λ
Status Docs uploaded by user
Build status unknown [no reports yet]

Readme for hindent-6.1.1

[back to package description]

hindent Hackage Haskell Cabal Haskell Stack OpenSSF Scorecard

Haskell pretty printer



$ stack install hindent


$ hindent --help
hindent - Reformat Haskell source code

Usage: hindent [--version | [--line-length ARG]
                 [--indent-size ARG | --tab-size ARG] [--no-force-newline]
                 [--sort-imports | --no-sort-imports] [--style STYLE]
                 [-X GHCEXT] [--validate] [FILENAMES]]

Available options:
  --version                Print the version
  --line-length ARG        Desired length of lines (default: 80)
  --indent-size ARG        Indentation size in spaces (default: 2)
  --tab-size ARG           Same as --indent-size, for compatibility
  --no-force-newline       Don't force a trailing newline
  --sort-imports           Sort imports in groups
  --no-sort-imports        Don't sort imports
  --style STYLE            Style to print with (historical, now ignored)
  -X GHCEXT                Language extension
  --validate               Check if files are formatted without changing them
  -h,--help                Show this help text

hindent is used in a pipeline style

$ cat path/to/sourcefile.hs | hindent

The default indentation size is 2 spaces. Configure indentation size with --indent-size:

$ echo 'example = case x of Just p -> foo bar' | hindent --indent-size 2; echo
example =
  case x of
    Just p -> foo bar
$ echo 'example = case x of Just p -> foo bar' | hindent --indent-size 4; echo
example =
    case x of
        Just p -> foo bar


Create a .hindent.yaml file in your project directory or in your ~/ home directory. The following fields are accepted and are the default:

indent-size: 2
line-length: 80
force-trailing-newline: true
sort-imports: true
line-breaks: []
extensions: []

By default, hindent preserves the newline or lack of newline in your input. With force-trailing-newline, it will make sure there is always a trailing newline.

hindent can be forced to insert a newline before specific operators and tokens with line-breaks. This is especially useful when utilizing libraries like servant which use long type aliases.

Using extensions, hindent can be made aware of valid syntactic compiler extensions that would normally be considered invalid syntax.

It is also possible to specify which extensions HIndent runs with in your .hindent.yaml:

  - MagicHash
  - RecursiveDo


In elisp/hindent.el there is hindent-mode, which provides keybindings to reindent parts of the buffer:

  • M-q reformats the current declaration. When inside a comment, it fills the current paragraph instead, like the standard M-q.
  • C-M-\ reformats the current region.

To enable it, add the following to your init file:

(add-to-list 'load-path "/path/to/hindent/elisp")
(require 'hindent)
(add-hook 'haskell-mode-hook #'hindent-mode)


The 'formatprg' option lets you use an external program (like hindent) to format your text. Put the following line into ~/.vim/ftplugin/haskell.vim to set this option for Haskell files:

setlocal formatprg=hindent

Then you can format with hindent using gq. Read :help gq and help 'formatprg' for more details.

Note that unlike in emacs you have to take care of selecting a sensible buffer region as input to hindent yourself. If that is too much trouble you can try vim-textobj-haskell which provides a text object for top level bindings.

In order to format an entire source file execute:


Alternatively you could use the vim-hindent plugin which runs hindent automatically when a Haskell file is saved.

IntelliJ / other JetBrains IDEs

  1. Install the "HaskForce" Haskell plugin (this is so we get the language type recognized in the file watcher)
  2. Install the "File Watchers" plugin under "Browse Repositories"
  3. Add a File Watcher with
    1. File type: Haskell Language
    2. Program: /path/to/hindent
    3. Arguments: $FilePath$
    4. Immediate file synchronization: off
    5. Show console: Error

Now whenever you save a file, hindent should autoformat it.