summaryrefslogtreecommitdiffhomepage
path: root/README.markdown
blob: 02ca63537857c2c2366ad9e1c8f0e96f6eef441c (plain)
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
## 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/jaspervdj/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
```

## 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/jaspervdj/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