BSD-3-Clause licensed by Mihai Maruseac, Chris Done, Andrew Gibiansky, Tobias Pflug, Pierre Radermecker
Maintained by Mihai Maruseac
This version can be pinned in stack with:hindent-6.2.0@sha256:2712035e7af8c61ad29dcf1ff2522c6c19313be821bb58bb199ffac53461f694,8741

Module documentation for 6.2.0

hindent Hackage Haskell Cabal Haskell Stack OpenSSF Scorecard

Haskell pretty printer

Examples

Install

$ stack install hindent

Usage

$ 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

Customization

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: [
    "GHC2021",
    "ListTuplePuns",
]

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:

extensions:
  - MagicHash
  - RecursiveDo

Emacs

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)

Vim

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:

:%!hindent

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.

Changes

Changelog

Unreleased

Added

Changed

Fixed

Removed

[6.2.0] - 2024-09-07

Added

  • Support for GHC 9.8 (#775) and GHC 9.10(#904).
  • Support for ImportPostQualified (#875).
  • HIndent now formats multiple files in parallel (#914).

Changed

  • The formatting style of import declarations with constructors (#829).
  • HIndent no longer inserts an empty line after a standalone kind signature (#873).
  • Bumped Stack LTS to 22.26 (#918).
  • HIndent re-assumes the default extensions are enabled (#904).

Fixed

  • Wrong default HIndent configuration in README.md (#750).
  • Fix the bug of panicking when the given source code has CPP lines and space-prefixed lines (#780).
  • Fix not pretty-printing multiple signatures in a SPECIALISE (#784).
  • Fix the bug of not pretty-printing multiple module-level warning messages (#822)
  • Fix the bug of wrongly converting a newtype instance to a data one (#839)
  • Fix the bug of not pretty-printing multiple functional dependencies in a typeclass (#843)
  • Fix the bug of not pretty-printing data declarations with records and typeclass constraints (#849)
  • Fix the bug of not pretty-printing unboxed tuples (#868)

Removed

  • Support for GHC 8.10 ([#950])

6.1.0 - 2023-05-17

Added

  • Support for GHC 9.6 (#699)
  • The hindent function for easy use within a project (#709).

Changed

  • reformat now takes a list of Extensions instead of a Maybe value containing the list (#712).
  • reformat and testAst now return a ParseError on error (#715).
  • reformat now returns the formatted code as a ByteString instead of a Builder. (#720).
  • HIndent now assumes no extensions are enabled by default (#728).
  • All modules except for HIndent are now private, and the minimum necessary definitions are exposed from the module (#729).
  • HIndent now prints all do expressions in a unified style (#739).
  • HIndent now formats operators based on their fixities (#741, #742).

Fixed

  • Fixed module names being removed from uses of qualified do (#696).
  • Misplaced haddocks for class declarations (#706).
  • Misplaced comments in do expressions (#707).
  • Misplaced comments in case expressions (#708).
  • The bug of extensions specified via pragmas not enabling implied ones (#727).
  • Language extensions enabled via pragmas were not effective across CPP boundaries (#731).

Removed

  • HIndent.LanguageExtension.defaultExtensions (#728)
  • HIndent.LanguageExtension.allExtensions (#728)

6.0.0 - 2023-02-20

Added

  • The getConfig function is exported.

Changed

  • Switched the parser from haskell-src-exts to ghc-lib-parser. This switch causes changes in the formatting results in some cases.
  • Changed how to format a data type with a record constructor to follow the Johan Tibell’s Haskell Style Guide. (#662).
  • A newline is no longer inserted after a pattern signature (#663).
  • A type with many type applications are now broken into multiple lines. (#664).
  • A long type-level list is broken into multiple lines. (#665).
  • Spaces around typed expression brackets are removed (#666).
  • HIndent no longer breaks short class constraints in function signautres into multiple lines (#669).

Fixed

  • Fixed the wrong formatting of data family instances inside class instances (#667).
  • Fixed the bug of removing the space before the enclosing parenthesis of a record syntax in a signature in a GADT declaration (#670).
  • Fixed the bug of inserting unnecessary empty lines if a file contains only comments (#672).

Removed

  • Test functions except testAst.
  • Atom support (#671).

5.3.4 - 2022-07-07

This version is accidentally pushlished, and is the same as 5.3.3.

5.3.3 - 2022-07-07

Added

  • Support for GHC 9.2.2.
  • Test CI with GitHub Actions (WIP).

Fixed

5.3.2 - 2022-02-02

Fixed

  • MonadFix issues to support newer GHC versions.

5.3.1 - 2019-06-28

Fixed

  • Comment relocations in where clauses of top-level function declarations.

5.3.0 - 2019-04-29

Added

  • Allow batch processing of multiple files.
  • You can now specify default extensions in the configuration file.

Fixed

  • Handle multiple deriving clauses in the DerivingStrategies scenario.
  • Ignore non-files in findCabalFiles.
  • Prevent HIndent from trying to open non-files when searching for .cabal files.
  • Fix the bad output for [p|Foo|] pattern quasi-quotes.
  • Fix pretty-printing of '(:).
  • Fix parsing C preprocessor line continuations.
  • Add parentheses around symbols (:|) when required.
  • Support $p pattern splices.
  • Fix formatting of associated type families.
  • Fix formatting of non-dependent record constructors.

5.2.7 - 2019-03-16

Fixed

  • A bug in the -X option

5.2.6 - 2019-03-16

Changed

5.2.5 - 2018-01-04

Added

  • Support getting extensions from a .cabal file

Changed

  • Improved the indentation with record constructions and updates
  • Updated haskell-src-exts dependency to version >= 1.20.0

Fixed

  • Fix the let ... in bug
  • Fix formatting top-level lambda expressions in TemplateHaskell slices

5.2.4 - 2017-10-20

Added

  • Improved pretty-printing unboxed tuples.
  • Support the --validate option for checking the format without reformatting
  • Support parsing #include, #error, and #warning directives.
  • Support reading LANGUAGE pragmas and parse the declared extensions from sources.
  • Support the EmptyCases extension
  • Optimize pretty-printing for many functional dependencies.

Changed

  • The TypeApplications extension is now disabled-by-default due to the @ symbol

Fixed

  • Fixed pretty-printing imports
  • Fixed pretty-printing string literals for DataKinds
  • Fixed many issues related to infix operators including TH name quotes, INLINE/NOINLINE pragmas, infix type operators, and infix constructors.
  • Fix extra linebreaks after short identifiers.

5.2.3 - 2017-05-07

Added

  • HIndent now reports where a parse happened.
  • Added --line-breaks parameter to support custom line breaks.
  • Added the RecStmt support

Changed

  • Explicit import lists are now sorted.
  • Improved pretty-printing long type signatures.
  • Improved pretty-printing GADT records.
  • Improved pretty-printing data declaration records.
  • The RecursiveDo and DoRec extensions are now disabled-by-default.

Fixed

  • Fixed pretty-printing for infix data constructors.
  • Fixed pretty-printing of quasi-quoter names.
  • Fixed pretty-printing of complicated type aliases.
  • Fixed pretty-printing of complicated type signatures.

5.2.2 - 2017-01-16

Changed

  • HIndent now leaves do, lambda (\x->), and lambda-case (\case->) on the previous line of $.

Fixed

  • Fixed pretty-printing of parallel list comprehensions.
  • Miscellaneous fixes.

5.2.1 - 2016-09-01

Changed

  • The --tab-size option is renamed to --indent-size.
  • The PatternSynonyms extension is now disabled by default.
  • HIndent now puts a newline before the closing bracket on a list.

Fixed

  • Fixed handling of paragraph overhang when using large constraints.
  • Fixed pretty-printing of multi-line comments.
  • Fixed bug resulting in adding a spurious space for comments at the end of a file.
  • Fixed bug which results in adding a trailing white space on <-

5.2.0 - 2016-08-30

Added

  • Support the .hindent.yaml file to specify alternative tab width and max column numbers.
  • Implement the tab-size support in Emacs Lisp.

Changed

  • The default number of spaces for a tab is changed to 2.

5.1.1 - 2016-08-29

Added

  • Add shebang support (Fixes #208).
  • Output the filename for parse errors (Fixes #179).
  • Added a document of the -X option (Fixes #212).

Changed

  • HIndent now preserves spaces between groups of imports (Fixes #200).
  • HIndent now preserves the last newline if the input ends with one (Fixes #211).
  • HIndent now puts the last parenthesis of an export list on a new line (Fixes #227).

Fixed

  • Fixed pretty-printing explicit foralls in instances (Fixes #218).

5.1.0 - 2016-08-25

Added

  • Add --tab-size parameter to control indentation spaces.

Changed

  • Rewrote comment association for more reliability.

Fixed

  • Some miscellaneous bugs.

5.0.1 - 2016-08-20

Added

  • Made HIndent compatible with GHC 7.8 through GHC 8.0
  • Added test suites and benchmarks in TESTS.md and BENCHMARKS.md

Changed

5.0.0 - 2016-08-11

Removed

  • Support for styles

4.6.4 - 2016-07-15

Changed

  • The formatted file is now created by coping/deleting a file instead of renaming.

4.6.3 - 2016-04-18

Added

  • Accept a filename to reformat.

Fixed

  • Fixed the whole module printer.

4.5.4 - 2015-06-22

Added

  • Improvements to Tibell style.
  • 6x speed up on rendering operators.

4.4.5 - 2015-11-10

Fixed

  • Fixed a bug in infix patterns.

4.4.2 - 2015-04-05

Added

  • Support for CPP.

Fixed

  • Bunch of Gibiansky style bugs.
  • Tibell style bugs.

4.3.8 - 2015-02-06

Fixed

  • A bug in printing operators in statements.