{"id":15010935,"url":"https://github.com/ennocramer/floskell","last_synced_at":"2025-04-04T08:07:03.380Z","repository":{"id":31721025,"uuid":"94985227","full_name":"ennocramer/floskell","owner":"ennocramer","description":"Floskell is a flexible Haskell source code pretty printer.","archived":false,"fork":false,"pushed_at":"2024-07-13T14:56:24.000Z","size":2207,"stargazers_count":181,"open_issues_count":18,"forks_count":24,"subscribers_count":3,"default_branch":"master","last_synced_at":"2025-03-28T07:04:47.787Z","etag":null,"topics":["code-formatter","haskell","pretty-printer"],"latest_commit_sha":null,"homepage":"","language":"Haskell","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"bsd-3-clause","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/ennocramer.png","metadata":{"files":{"readme":"README.md","changelog":"CHANGELOG.md","contributing":null,"funding":null,"license":"LICENSE.md","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2017-06-21T09:08:39.000Z","updated_at":"2024-12-20T02:56:02.000Z","dependencies_parsed_at":"2024-07-13T16:15:02.841Z","dependency_job_id":null,"html_url":"https://github.com/ennocramer/floskell","commit_stats":{"total_commits":757,"total_committers":43,"mean_commits":17.6046511627907,"dds":0.595772787318362,"last_synced_commit":"94e77be6d4391de6962914f94ce5c86ecce87d96"},"previous_names":[],"tags_count":68,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/ennocramer%2Ffloskell","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/ennocramer%2Ffloskell/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/ennocramer%2Ffloskell/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/ennocramer%2Ffloskell/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/ennocramer","download_url":"https://codeload.github.com/ennocramer/floskell/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":247142032,"owners_count":20890651,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["code-formatter","haskell","pretty-printer"],"created_at":"2024-09-24T19:37:38.882Z","updated_at":"2025-04-04T08:07:03.358Z","avatar_url":"https://github.com/ennocramer.png","language":"Haskell","readme":"# Floskell\n\n[![Hackage][hackage-image]][hackage-url]\n[![Build Status][ci-image]][ci-url]\n[![License][license-image]][license-url]\n\nFloskell is a flexible Haskell source code pretty printer.\n\n[Documentation](https://github.com/ennocramer/floskell/blob/master/README.md)\n\n[Examples](https://github.com/ennocramer/floskell/blob/master/styles)\n\nFloskell started as a fork of version 4 of [Chris Done's\nhindent](https://github.com/commercialhaskell/hindent).  The\nformatting styles present in hindent 4 have been preserved in spirit,\nbut generally will not produce exactly the same output.\n\n\n## Installation\n\n    git clone https://github.com/ennocramer/floskell\n    cd floskell\n    stack install\n\n\n## Usage\n\nFloskell can be used to reformat Haskell source files in place\n\n    floskell path/to/sourcefile.hs\n\nor as a pipeline processor\n\n    cat path/to/sourcefile.hs | floskell \u003e outfile.hs\n\nOne of the predefined formatting styles can be selected with the\n`--style` option\n\n    floskell --style cramer path/to/sourcefile.hs\n\nOr the style can be read from a configuration file\n\n    floskell --config path/to/config.json path/to/sourcefile.hs\n\nIf neither style nor configuration file is given on the command line,\nFloskell will try to find a configuration file in the current working\ndirectory or any of its parent directories, or fall back to the users\nglobal configuration file.\n\n\n## Formatting Process\n\nA style in Floskell is a set of formatting possibilities for different\nlanguage constructs.  Floskell formats Haskell code according to a\ngiven style by finding the combination of allowed formatting choices\nthat result in the best overall layout.\n\n### Penalty\n\nThe overall layout of the generated output is judged by a penalty\nfunction.  This function takes into account the number of lines\ngenerated, whether lines are longer than a defined limit, and the\nindentation of each line.\n\nIn general, Floskell will try to generate\n\n* the smallest number of lines,\n\n* the least amount of indentation, and\n\n* the least amount of overflow.\n\n### Layout\n\nA number of language constructs can be formatted in different ways.\nFloskell generally defines two layout choices for these constructs,\n`flex` and `vertical`, and three modes to apply these choices, `flex`,\n`vertical`, and `try-oneline`.\n\nThe layout choice `flex` generally tries to fit as much on each line\nas possible, but allows linebreaks in a number of places, while the\n`vertical` layout choice forces linebreaks in various places.\n\nThe `flex` and `vertical` layout modes simply select the respective\nlayout choice, while `try-oneline` will first try `flex`, but replace\nthe choice with `vertical` if the `flex` layout would more than one\nline or an overfull line.\n\nAn example:\n\n```haskell\n-- flex layout for con-decls\ndata Enum = One | Two | Three\n\n-- vertical layout for con-decls\ndata Enum = One\n          | Two\n          | Three\n```\n\n### Indentation\n\nA number of language constructs can apply indentation to sub-elements.\nFloskell provides two different indentation choices, `aligned` and\n`indented`, and three modes to apply these choices, `align`,\n`indent-by n`, and `align-or-indent-by n`.\n\n`align` will start the sub-element on the same line and raise the\nindentation to align following lines, while `indent-by n` will start\nthe sub-element on the following line with the indentation raised by\n`n`.\n\n`align-or-indent-by n` will allow either choice and select the\nformatting with the least penalty.\n\nAn example:\n\n```haskell\n-- align for do\nfoo = do x \u003c- xs\n         y \u003c- ys\n         return (x, y)\n\n-- indent-by 4 for do\nfoo = do\n    x \u003c- xs\n    y \u003c- ys\n    return (x, y)\n```\n\n### Tabstop Alignment\n\nSome language constructs allow for tabstop alignment.  Alignment is\noptional and subject to configurable limits, regarding the amount of\nadded whitespace.\n\nAn example:\n\n```haskell\n-- let without alignment\nlet foo = bar\n    quux = quuz\nin foo quux\n\n-- let with alignment\nlet foo    = bar\n    quuuux = quuz\nin foo quuuux\n```\n\n### Whitespace\n\nFloskell allows the customization of whitespace around infix\noperators, as well as inside parentheses and other enclosing\npunctuation characters.\n\nThe presence of whitespace or linebreaks is as `before`, meaning\nbefore the operator/enclosed item, `after`, meaning after the\noperator/enclosed item, or `both`, meaning both before and after the\noperator/enclosed item.\n\nWhitespace configuration can depend on the context where an operator\nor enclosing punctuation is used.  The context can be one of\n`declaration`, `type`, `pattern`, `expression`, or `other`.\n\nAn example:\n\n```haskell\n-- tuple with space after/before parentheses and after comma\ntuple = ( 1, 2 )\n-- tuple without any spaces\ntuple = (1,2)\n```\n\n### Preprocessor Directives (CPP)\n\nFloskell, in general, supports Haskell source with conditional\ncompilation directives using the `CPP` language extensions.  However,\ndue to the way this support is implemented, some care must be taken to\nnot confuse the Haskell source parser.\n\nFloskell treats conditional compilation directives as if they were\nsimply comments.  As a consequence, the input must still be valid\nHaskell when all preprocessor lines are removed.  This is relevant\nwhen using `#if`/`#else`/`#endif` sequences, as Floskell will see both\nthe if- and else-block in sequence.  For example, the following cannot\nbe processed with Floskell, as the first declaration of `prettyPrint`\nends with an incomplete `do` block:\n\n```haskell\n#if MIN_VERSION_haskell_src_exts(1,21,0)\n    prettyPrint (GadtDecl _ name _ _ mfielddecls ty) = do\n#else\n    prettyPrint (GadtDecl _ name mfielddecls ty) = do\n#endif\n        pretty name\n        operator Declaration \"::\"\n        mayM_ mfielddecls $ \\decls -\u003e do\n            prettyRecordFields len Declaration decls\n            operator Type \"-\u003e\"\n        pretty ty\n```\n\nInstead, some of the contents of the `do` block have to be duplicated,\nso that the contents of the `#if` are valid Haskell on their own.\n\n```haskell\n#if MIN_VERSION_haskell_src_exts(1,21,0)\n    prettyPrint (GadtDecl _ name _ _ mfielddecls ty) = do\n        pretty name\n        operator Declaration \"::\"\n        mayM_ mfielddecls $ \\decls -\u003e do\n            prettyRecordFields len Declaration decls\n            operator Type \"-\u003e\"\n        pretty ty\n#else\n    prettyPrint (GadtDecl _ name mfielddecls ty) = do\n        pretty name\n        operator Declaration \"::\"\n        mayM_ mfielddecls $ \\decls -\u003e do\n            prettyRecordFields len Declaration decls\n            operator Type \"-\u003e\"\n        pretty ty\n#endif\n```\n\n### Manual Formatting and Hiding Code\n\nFloskell can be told to not change the formatting of a section of code\nby enclosing the section with `floskell-disable` and `floskell-enable`\ncomments. The comments must be on a line of their own and can use the\n`--` and `{- -}` syntax.\n\nAs Floskell will simply copy anything between these comments to the\noutput and not attempt to parse the contents, this mechanism can also\nbe used to hide constructs from Floskell that the parser does not\nsupport.\n\n\n## Customization\n\nFloskell's behaviour and the style of its output can be modified with\na configuration file.\n\nSee the documentation on the [Configuration Format](CONFIGURATION.md)\nfor a detailed description of the contents of the configuration file.\n\n### Initial Configuration\n\nThe `--print-config` command line option can be used to create an\ninitial configuration file.\n\n    floskell --style cramer --print-config \u003e ~/.floskell.json\n\nThis command will create a configuration file with all fields and the\nentire definition of the selected style in the `formatting` block.\n\n### Configuration File Location\n\n* If a style is given on the command line, but no explicit\n  configuration file, the style will be used as-is and no\n  configuration file will be loaded.\n\n* If both a style and an explicit configuration file are given on the\n  command line, the explicit configuration file will be loaded and the\n  style parameter will replace any style setting in the configuration\n  file.\n\n* If neither style nor explicit configuration file are given on the\n  command line, Floskell will try to find an applicable configuration\n  file.  Floskell will look for\n\n  * a file called `floskell.json` in the current working directory and\n    all its parent directories,\n\n  * a file called `config.json` in `~/.floskell`, `~/config/floskell`,\n    or `%APPDATA%/floskell`, and lastly\n\n  * a file called `.floskell.json` in `~` or `~/.config`.\n\n  Only the first file found will be loaded.\n\n\n## Editor Integration\n\n### Emacs\n\nIn\n[contrib/floskell.el](https://github.com/ennocramer/floskell/blob/master/contrib/floskell.el)\nthere is `floskell-mode`, which provides keybindings to reindent parts\nof the buffer:\n\n- `M-q` reformats the current declaration.  When inside a comment, it\n  fills the current paragraph instead, like the standard `M-q`.\n- `C-M-\\` reformats the current region.\n\nTo enable it, add the following to your init file:\n\n```lisp\n(add-to-list 'load-path \"/path/to/floskell/contrib\")\n(require 'floskell)\n(add-hook 'haskell-mode-hook #'floskell-mode)\n```\n\nBy default, Floskell uses the style called `base`.  If you want to use\nanother, run `M-x customize-variable floskell-style` or create a\nFloskell configuration file in your home directory. If you want to\nconfigure per-project, add a configuration file in the project root or\nmake a file called `.dir-locals.el` in the project root directory like\nthis:\n\n``` lisp\n((nil . ((floskell-style . \"johan-tibell\"))))\n```\n\n### Vim\n\nThe `'formatprg'` option lets you use an external program (like\nfloskell) to format your text. Put the following line into\n~/.vim/ftplugin/haskell.vim to set this option for Haskell files:\n\n    setlocal formatprg=floskell\\ --style\\ chris-done\n\nThen you can format with floskell using `gq`. Read `:help gq` and `help\n'formatprg'` for more details.\n\nNote that unlike in emacs you have to take care of selecting a\nsensible buffer region as input to floskell yourself. If that is too\nmuch trouble you can try\n[vim-textobj-haskell](https://github.com/gilligan/vim-textobj-haskell)\nwhich provides a text object for top level bindings.\n\n### Atom\n\nBasic support is provided through\n[contrib/floskell.coffee](https://github.com/ennocramer/floskell/blob/master/contrib/floskell.coffee),\nwhich adds floskell to atom menu with each available style, and\n`Default` which will use the appropriate configuration file. Mode\nshould be installed as package into `.atom\\packages\\${PACKAGE_NAME}`,\nhere is simple example of atom\n[package](https://github.com/Heather/atom-hindent).\n\n\u003c!-- Markdown link \u0026 img dfn's --\u003e\n[hackage-image]: https://img.shields.io/hackage/v/floskell.svg?style=flat\n[hackage-url]: https://hackage.haskell.org/package/floskell\n[ci-image]: https://github.com/ennocramer/floskell/workflows/CI%20Pipeline/badge.svg\n[ci-url]: https://github.com/ennocramer/floskell/actions?query=workflow%3A%22CI+Pipeline%22\n[license-image]: https://img.shields.io/badge/license-BSD--3--Clause-blue?style=flat-square\n[license-url]: https://github.com/ennocramer/floskell/blob/master/LICENSE.md\n","funding_links":[],"categories":[],"sub_categories":[],"project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fennocramer%2Ffloskell","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fennocramer%2Ffloskell","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fennocramer%2Ffloskell/lists"}