1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241
|
## stylish-haskell
## Introduction
A simple Haskell code prettifier. The goal is not to format all of the code in
a file, since I find those kind of tools often "get in the way". However,
manually cleaning up import statements etc. gets tedious very quickly.
This tool tries to help where necessary without getting in the way.
## Features
- Aligns and sorts `import` statements
- Groups and wraps `{-# LANGUAGE #-}` pragmas, can remove (some) redundant
pragmas
- Removes trailing whitespace
- Aligns branches in `case` and fields in records
- Converts line endings (customizable)
- Replaces tabs by four spaces (turned off by default)
- Replaces some ASCII sequences by their Unicode equivalents (turned off by
default)
- Format data constructors and fields in records.
Feature requests are welcome! Use the [issue tracker] for that.
[issue tracker]: https://github.com/haskell/stylish-haskell/issues
## Example
Turns:
```haskell
{-# LANGUAGE ViewPatterns, TemplateHaskell #-}
{-# LANGUAGE GeneralizedNewtypeDeriving,
ViewPatterns,
ScopedTypeVariables #-}
module Bad where
import Control.Applicative ((<$>))
import System.Directory (doesFileExist)
import qualified Data.Map as M
import Data.Map ((!), keys, Map)
data Point = Point { pointX, pointY :: Double , pointName :: String} deriving (Show)
```
into:
```haskell
{-# LANGUAGE GeneralizedNewtypeDeriving #-}
{-# LANGUAGE ScopedTypeVariables #-}
{-# LANGUAGE TemplateHaskell #-}
module Bad where
import Control.Applicative ((<$>))
import System.Directory (doesFileExist)
import Data.Map (Map, keys, (!))
import qualified Data.Map as M
data Point = Point
{ pointX, pointY :: Double
, pointName :: String
} deriving (Show)
```
## Configuration
The tool is customizable to some extent. It tries to find a config file in the
following order:
1. A file passed to the tool using the `-c/--config` argument
2. `.stylish-haskell.yaml` in the current directory (useful for per-directory
settings)
3. `.stylish-haskell.yaml` in the nearest ancestor directory (useful for
per-project settings)
4. `stylish-haskell/config.yaml` in the platform’s configuration directory
(on Windows, it is %APPDATA%, elsewhere it defaults to `~/.config` and
can be overridden by the `XDG_CONFIG_HOME` environment variable;
useful for user-wide settings)
5. `.stylish-haskell.yaml` in your home directory (useful for user-wide
settings)
6. The default settings.
Use `stylish-haskell --defaults > .stylish-haskell.yaml` to dump a
well-documented default configuration to a file, this way you can get started
quickly.
## Record formatting
Basically, stylish-haskell supports 4 different styles of records, controlled by `records`
in the config file.
Here's an example of all four styles:
```haskell
-- equals: "indent 2", "first_field": "indent 2"
data Foo a
= Foo
{ a :: Int
, a2 :: String
-- ^ some haddock
}
| Bar
{ b :: a
}
deriving (Eq, Show)
deriving (ToJSON) via Bar Foo
-- equals: "same_line", "first_field": "indent 2"
data Foo a = Foo
{ a :: Int
, a2 :: String
-- ^ some haddock
}
| Bar
{ b :: a
}
deriving (Eq, Show)
deriving (ToJSON) via Bar Foo
-- equals: "same_line", "first_field": "same_line"
data Foo a = Foo { a :: Int
, a2 :: String
-- ^ some haddock
}
| Bar { b :: a
}
deriving (Eq, Show)
deriving (ToJSON) via Bar Foo
-- equals: "indent 2", first_field: "same_line"
data Foo a
= Foo { a :: Int
, a2 :: String
-- ^ some haddock
}
| Bar { b :: a
}
deriving (Eq, Show)
deriving (ToJSON) via Bar Foo
```
## Editor integration
### Haskell Language Server
[Haskell Language Server(HLS)][HLS] includes a [plugin][HLS stylish-haskell Plugin]
for stylish-haskell. By changing the formatting provider option
(`haskell.formattingProvider`) to `stylish-haskell` as described in
[HLS options][HLS option], any editors that support [Language Server Protocol][LSP]
can use stylish-haskell for formatting.
[HLS]: https://github.com/haskell/haskell-language-server
[HLS option]: https://haskell-language-server.readthedocs.io/en/latest/configuration.html#language-specific-server-options
[HLS stylish-haskell Plugin]: https://github.com/haskell/haskell-language-server/blob/master/plugins/hls-stylish-haskell-plugin/src/Ide/Plugin/StylishHaskell.hs
[LSP]: https://microsoft.github.io/language-server-protocol/
### VIM integration
Since it works as a filter it is pretty easy to integrate this with VIM.
You can call
:%!stylish-haskell
and add a keybinding for it.
Or you can define `formatprg`
:set formatprg=stylish-haskell
and then use `gq`.
Alternatively, [vim-autoformat] supports stylish-haskell. To have it
automatically reformat the files on save, add to your vimrc:
```vim
autocmd BufWrite *.hs :Autoformat
" Don't automatically indent on save, since vim's autoindent for haskell is buggy
autocmd FileType haskell let b:autoformat_autoindent=0
```
There are also plugins that run stylish-haskell automatically when you save a
Haskell file:
- [vim-stylish-haskell]
- [vim-stylishask]
[vim-stylish-haskell]: https://github.com/nbouscal/vim-stylish-haskell
[vim-stylishask]: https://github.com/alx741/vim-stylishask
### Emacs integration
[haskell-mode] for Emacs supports `stylish-haskell`. For configuration,
see [the “Using external formatters” section][haskell-mode/format] of the
haskell-mode manual.
[haskell-mode]: https://github.com/haskell/haskell-mode
[haskell-mode/format]: http://haskell.github.io/haskell-mode/manual/latest/Autoformating.html
### Atom integration
[ide-haskell] for Atom supports `stylish-haskell`.
[atom-beautify] for Atom supports Haskell using `stylish-haskell`.
[ide-haskell]: https://atom.io/packages/ide-haskell
[atom-beautify]: Https://atom.io/packages/atom-beautify
### Visual Studio Code integration
[stylish-haskell-vscode] for VSCode supports `stylish-haskell`.
[stylish-haskell-vscode]: https://github.com/vigoo/stylish-haskell-vscode
## Using with Continuous Integration
You can quickly grab the latest binary and run `stylish-haskell` like so:
curl -sL https://raw.github.com/haskell/stylish-haskell/master/scripts/latest.sh | sh -s .
Where the `.` can be replaced with the arguments you pass to `stylish-haskell`.
## Credits
Written and maintained by Jasper Van der Jeugt.
Contributors:
- Chris Done
- Hiromi Ishii
- Leonid Onokhov
- Michael Snoyman
- Mikhail Glushenkov
- Beatrice Vergani
- Paweł Szulc
- Łukasz Gołębiewski
- Felix Mulder
|