# floskell: A flexible Haskell source code pretty printer

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

A flexible Haskell source code pretty printer.

See the Github page for usage/explanation: https://github.com/ennocramer/floskell

Versions [RSS] [faq] 0.9.0, 0.10.0, 0.10.1, 0.10.2, 0.10.3, 0.10.4, 0.10.5, 0.10.6 CHANGELOG.md aeson (>=0.11.3.0 && <1.5), aeson-pretty (>=0.8.2 && <0.9), attoparsec (>=0.13.1.0 && <0.14), base (>=4.9 && <4.15), bytestring (>=0.10.8.1 && <0.11), containers (>=0.5.7.1 && <0.7), data-default (>=0.7.1.1 && <0.8), directory (>=1.2.6.2 && <1.4), filepath (>=1.4.1.0 && <1.5), floskell, ghc-prim (>=0.5.0.0 && <0.7), haskell-src-exts (>=1.19 && <1.23), monad-dijkstra (>=0.1.1 && <0.2), mtl (>=2.2.1 && <2.3), optparse-applicative (>=0.12.1.0 && <0.16), text (>=1.2.2.2 && <1.3), transformers (>=0.5.2.0 && <0.6), unordered-containers (>=0.2.8.0 && <0.3), utf8-string (>=1.0.1.1 && <1.1) [details] BSD-3-Clause 2014 Chris Done, 2015 Andrew Gibiansky, 2016-2019 Enno Cramer Chris Done, Andrew Gibiansky, Tobias Pflug, Pierre Radermecker, Enno Cramer ecramer@memfrob.de Revision 1 made by ecramer at 2020-05-16T08:10:47Z Development https://www.github.com/ennocramer/floskell https://github.com/ennocramer/floskell/issues head: git clone https://github.com/ennocramer/floskell by ecramer at 2019-11-11T19:53:38Z Arch:0.10.5, NixOS:0.10.5 floskell 9581 total (432 in the last 30 days) 2.0 (votes: 1) [estimated by Bayesian average] λ λ λ Docs available Last success reported on 2019-11-11

Note: This package has metadata revisions in the cabal description newer than included in the tarball. To unpack the package including the revisions, use 'cabal get'.

#### Maintainer's Corner

For package maintainers and hackage trustees

Candidates

[back to package description]

# Floskell

Floskell is a flexible Haskell source code pretty printer.

Documentation

Examples

Floskell started as a fork of version 4 of Chris Done's hindent. The formatting styles present in hindent 4 have been preserved in spirit, but generally will not produce exactly the same output.

## Installation

$git clone https://github.com/ennocramer/floskell$ cd floskell
$stack install  ## Usage Floskell can be used to reformat Haskell source files in place $ floskell path/to/sourcefile.hs


or as a pipeline processor

$cat path/to/sourcefile.hs | floskell > outfile.hs  One of the predefined formatting styles can be selected with the --style option $ floskell --style cramer path/to/sourcefile.hs


Or the style can be read from a configuration file

floskell --config path/to/config.json path/to/sourcefile.hs  If neither style nor configuration file is given on the command line, Floskell will try to find a configuration file in the current working directory or any of its parent directories, or fall back to the users global configuration file. ## Formatting Process A style in Floskell is a set of formatting possibilities for different language constructs. Floskell formats Haskell code according to a given style by finding the combination of allowed formatting choices that result in the best overall layout. ### Penalty The overall layout of the generated output is judged by a penalty function. This function takes into account the number of lines generated, whether lines are longer than a defined limit, and the indentation of each line. In general, Floskell will try to generate • the smallest number of lines, • the least amount of indentation, and • the least amount of overflow. ### Layout A number of language constructs can be formatted in different ways. Floskell generally defines two layout choices for these constructs, flex and vertical, and three modes to apply these choices, flex, vertical, and try-oneline. The layout choice flex generally tries to fit as much on each line as possible, but allows linebreaks in a number of places, while the vertical layout choice forces linebreaks in various places. The flex and vertical layout modes simply select the respective layout choice, while try-oneline will first try flex, but replace the choice with vertical if the flex layout would more than one line or an overfull line. An example: -- flex layout for con-decls data Enum = One | Two | Three -- vertical layout for con-decls data Enum = One | Two | Three  ### Indentation A number of language constructs can apply indentation to sub-elements. Floskell provides two different indentation choices, aligned and indented, and three modes to apply these choices, align, indent-by n, and align-or-indent-by n. align will start the sub-element on the same line and raise the indentation to align following lines, while indent-by n will start the sub-element on the following line with the indentation raised by n. align-or-indent-by n will allow either choice and select the formatting with the least penalty. An example: -- align for do foo = do x <- xs y <- ys return (x, y) -- indent-by 4 for do foo = do x <- xs y <- ys return (x, y)  ### Tabstop Alignment Some language constructs allow for tabstop alignment. Alignment is optional and subject to configurable limits, regarding the amount of added whitespace. An example: -- let without alignment let foo = bar quux = quuz in foo quux -- let with alignment let foo = bar quuuux = quuz in foo quuuux  ### Whitespace Floskell allows the customization of whitespace around infix operators, as well as inside parentheses and other enclosing punctuation characters. The presence of whitespace or linebreaks is as before, meaning before the operator/enclosed item, after, meaning after the operator/enclosed item, or both, meaning both before and after the operator/enclosed item. Whitespace configuration can depend on the context where an operator or enclosing punctuation is used. The context can be one of declaration, type, pattern, expression, or other. An example: -- tuple with space after/before parentheses and after comma tuple = ( 1, 2 ) -- tuple without any spaces tuple = (1,2)  ### Preprocessor Directives (CPP) Floskell, in general, supports Haskell source with conditional compilation directives using the CPP language extensions. However, due to the way this support is implemented, some care must be taken to not confuse the Haskell source parser. Floskell treats conditional compilation directives as if they were simply comments. As a consequence, the input must still be valid Haskell when all preprocessor lines are removed. This is relevant when using #if/#else/#endif sequences, as Floskell will see both the if- and else-block in sequence. For example, the following cannot be processed with Floskell, as the first declaration of prettyPrint ends with an incomplete do block: #if MIN_VERSION_haskell_src_exts(1,21,0) prettyPrint (GadtDecl _ name _ _ mfielddecls ty) = do #else prettyPrint (GadtDecl _ name mfielddecls ty) = do #endif pretty name operator Declaration "::" mayM_ mfielddecls \decls -> do
prettyRecordFields len Declaration decls
operator Type "->"
pretty ty


Instead, some of the contents of the do block have to be duplicated, so that the contents of the #if are valid Haskell on their own.

#if MIN_VERSION_haskell_src_exts(1,21,0)
prettyPrint (GadtDecl _ name _ _ mfielddecls ty) = do
pretty name
operator Declaration "::"
mayM_ mfielddecls $\decls -> do prettyRecordFields len Declaration decls operator Type "->" pretty ty #else prettyPrint (GadtDecl _ name mfielddecls ty) = do pretty name operator Declaration "::" mayM_ mfielddecls$ \decls -> do
prettyRecordFields len Declaration decls
operator Type "->"
pretty ty
#endif


## Customization

Floskell's behaviour and the style of its output can be modified with a configuration file.

See the documentation on the Configuration Format for a detailed description of the contents of the configuration file.

### Initial Configuration

The --print-config command line option can be used to create an initial configuration file.