on master help sign in
.buildkite/pipeline.yml+2−2
since splitsnapshots
unifiedsplit
@@ -3,9 +3,9 @@ steps:
3 command: |
3 command: |
4 nix-build --keep-going --no-out-link --argstr ormoluCompiler ghc865
4 nix-build --keep-going --no-out-link --argstr ormoluCompiler ghc865
5 timeout: 100
5 timeout: 100
6− - label: Build and test with GHC 8.8.3
6+ - label: Build and test with GHC 8.8.4
7 command: |
7 command: |
8− nix-build --keep-going --no-out-link --argstr ormoluCompiler ghc883
8+ nix-build --keep-going --no-out-link --argstr ormoluCompiler ghc884
9 timeout: 100
9 timeout: 100
10 - label: Build and test with GHC 8.10.1
10 - label: Build and test with GHC 8.10.1
11 command: |
11 command: |
.github/workflows/binaries.ymlnew file+39
@@ -0,0 +1,39 @@
1+name: Build binaries
2+on:
3+ release:
4+ types: [published]
5+jobs:
6+ build:
7+ strategy:
8+ fail-fast: false
9+ matrix:
10+ os: [ubuntu-latest, macOS-latest, windows-latest]
11+ runs-on: ${{ matrix.os }}
12+ steps:
13+ - uses: actions/checkout@v2
14+ - uses: actions/setup-haskell@v1
15+ if: runner.os != 'Linux'
16+ with:
17+ ghc-version: '8.10.1'
18+ cabal-version: '3.2'
19+ - name: Build Linux binary
20+ if: runner.os == 'Linux'
21+ run: |
22+ docker run \
23+ -v $(pwd):/mnt -w /mnt \
24+ utdemir/ghc-musl:v14-ghc8101 \
25+ bash .github/workflows/build.sh
26+ - name: Build ${{ runner.os }} binary
27+ if: runner.os != 'Linux'
28+ shell: bash
29+ run: |
30+ cabal build exe:ormolu
31+ cp $(find dist-newstyle \( -name ormolu -o -name ormolu.exe \) -type f) ormolu
32+ - uses: actions/upload-release-asset@v1
33+ env:
34+ GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
35+ with:
36+ upload_url: ${{ github.event.release.upload_url }}
37+ asset_path: ormolu
38+ asset_name: ormolu-${{ runner.os }}
39+ asset_content_type: application/octet-stream
.github/workflows/build.shnew file+7
@@ -0,0 +1,7 @@
1+set -e
2+
3+cabal update
4+cabal build exe:ormolu --enable-executable-static --ghc-options="-split-sections"
5+
6+cp $(find dist-newstyle -name ormolu -type f) .
7+strip -s ormolu
CHANGELOG.md+23−6
@@ -1,6 +1,26 @@
1## Unreleased
1## Unreleased
2
2
3−* Duplicate imports in a single import list are now eliminated.
3+* Ormolu no longer overwrites already formatted files. [PR
4+ 649](https://github.com/tweag/ormolu/pull/649).
5+
6+## Ormolu 0.1.2.0
7+
8+* Fixed the bug when comments in different styles got glued together after
9+ formatting. [Issue 589](https://github.com/tweag/ormolu/issues/589).
10+
11+* Added `-i` as a shortcut for `--mode inplace`. [Issue
12+ 467](https://github.com/tweag/ormolu/issues/467).
13+
14+* Improved grouping of top-level declarations. [Issue
15+ 466](https://github.com/tweag/ormolu/issues/466).
16+
17+## Ormolu 0.1.1.0
18+
19+* Imports in a import lists are now normalized: duplicate imports are
20+ combined/eliminated intelligently.
21+
22+* Import declarations that can be merged are now automatically merged.
23+ [Issue 414](https://github.com/tweag/ormolu/issues/414).
4
24
5* The magic comments for disabling and enabling Ormolu now can encompass any
25* The magic comments for disabling and enabling Ormolu now can encompass any
6 fragment of code provided that the remaining code after exclusion of the
26 fragment of code provided that the remaining code after exclusion of the
@@ -22,16 +42,13 @@
22* Blank lines between definitions in `let` and `while` bindings are now
42* Blank lines between definitions in `let` and `while` bindings are now
23 preserved. [Issue 554](https://github.com/tweag/ormolu/issues/554).
43 preserved. [Issue 554](https://github.com/tweag/ormolu/issues/554).
24
44
25−* Fixed the bug when type applications glued to TH splices that followed
45+* Fixed the bug when type applications stuck to the `$` of TH splices that
26− them. [Issue 613](https://github.com/tweag/ormolu/issues/613).
46+ followed them. [Issue 613](https://github.com/tweag/ormolu/issues/613).
27
47
28* Improved region formatting so that indented fragments—such as definitions
48* Improved region formatting so that indented fragments—such as definitions
29 inside of `where` clauses—can be formatted. [Issue
49 inside of `where` clauses—can be formatted. [Issue
30 572](https://github.com/tweag/ormolu/issues/572).
50 572](https://github.com/tweag/ormolu/issues/572).
31
51
32−* Fixed the bug in the de-duplicating algorithm for import lists. [Issue
33− 620](https://github.com/tweag/ormolu/issues/620).
34−
35* Fixed the bug related to the de-association of pragma comments. [Issue
52* Fixed the bug related to the de-association of pragma comments. [Issue
36 619](https://github.com/tweag/ormolu/issues/619).
53 619](https://github.com/tweag/ormolu/issues/619).
37
54
README.md+21−11
@@ -22,7 +22,7 @@ the following goals in mind:
22* That formatting style aims to result in minimal diffs while still
22* That formatting style aims to result in minimal diffs while still
23 remaining very close to “conventional” Haskell formatting people use.
23 remaining very close to “conventional” Haskell formatting people use.
24* Choose a style compatible with modern dialects of Haskell. As new Haskell
24* Choose a style compatible with modern dialects of Haskell. As new Haskell
25− extensions enter broad use, we may change the style to accomodate them.
25+ extensions enter broad use, we may change the style to accommodate them.
26* Idempotence: formatting already formatted code doesn't change it.
26* Idempotence: formatting already formatted code doesn't change it.
27* Be well-tested and robust to the point that it can be used in large
27* Be well-tested and robust to the point that it can be used in large
28 projects without exposing unfortunate, disappointing bugs here and there.
28 projects without exposing unfortunate, disappointing bugs here and there.
@@ -45,11 +45,12 @@ Alternatively, `stack` could be used with a `stack.yaml` file as follows.
45
45
46```console
46```console
47$ cat stack.yaml
47$ cat stack.yaml
48−resolver: lts-14.3
48+resolver: lts-16.0
49packages:
49packages:
50- '.'
50- '.'
51
51
52−$ stack build
52+$ stack build # to build
53+$ stack install # to install
53```
54```
54
55
55To use Ormolu directly from GitHub with Nix, this snippet may come in handy:
56To use Ormolu directly from GitHub with Nix, this snippet may come in handy:
@@ -129,14 +130,6 @@ independent top-level definitions.
129 criterion than just being valid Haskell modules.
130 criterion than just being valid Haskell modules.
130* Various minor idempotence issues, most of them are related to comments.
131* Various minor idempotence issues, most of them are related to comments.
131
132
132−## Editor integration
133−
134−We know of the following editor integrations:
135−
136−* [Emacs][emacs-package]
137−* [VS Code][vs-code-plugin]
138−* vim: [neoformat][neoformat], [vim-ormolu][vim-ormolu]
139−
140## Running on Hackage
133## Running on Hackage
141
134
142It's possible to try Ormolu on arbitrary packages from Hackage. For that
135It's possible to try Ormolu on arbitrary packages from Hackage. For that
@@ -151,6 +144,22 @@ also contain formatted `.hs` files for inspection and original inputs with
151`.hs-original` extension (those are with CPP dropped, exactly what is fed
144`.hs-original` extension (those are with CPP dropped, exactly what is fed
152into Ormolu).
145into Ormolu).
153
146
147+## Editor integration
148+
149+We know of the following editor integrations:
150+
151+* [Emacs][emacs-package]
152+* [VS Code][vs-code-plugin]
153+* vim: [neoformat][neoformat], [vim-ormolu][vim-ormolu]
154+
155+## Arch Linux
156+
157+To install Ormolu on Arch Linux, one can use [the package on AUR][aur]:
158+
159+```console
160+yay -S ormolu
161+```
162+
154## Contributing
163## Contributing
155
164
156See [CONTRIBUTING.md][contributing].
165See [CONTRIBUTING.md][contributing].
@@ -169,3 +178,4 @@ Copyright © 2018–present Tweag I/O
169[vs-code-plugin]: https://marketplace.visualstudio.com/items?itemName=sjurmillidahl.ormolu-vscode
178[vs-code-plugin]: https://marketplace.visualstudio.com/items?itemName=sjurmillidahl.ormolu-vscode
170[vim-ormolu]: https://github.com/sdiehl/vim-ormolu
179[vim-ormolu]: https://github.com/sdiehl/vim-ormolu
171[neoformat]: https://github.com/sbdchd/neoformat
180[neoformat]: https://github.com/sbdchd/neoformat
181+[aur]: https://aur.archlinux.org/packages/ormolu
app/Main.hs+23−13
@@ -8,6 +8,7 @@ module Main (main) where
8
8
9import Control.Exception (SomeException, displayException, try)
9import Control.Exception (SomeException, displayException, try)
10import Control.Monad
10import Control.Monad
11+import Data.Bool (bool)
11import Data.Either (lefts)
12import Data.Either (lefts)
12import Data.List (intercalate, sort)
13import Data.List (intercalate, sort)
13import qualified Data.Text.IO as TIO
14import qualified Data.Text.IO as TIO
@@ -60,15 +61,19 @@ formatOne mode config = \case
60 -- 101 is different from all the other exit codes we already use.
61 -- 101 is different from all the other exit codes we already use.
61 exitWith (ExitFailure 101)
62 exitWith (ExitFailure 101)
62 Just inputFile -> do
63 Just inputFile -> do
64+ originalInput <- TIO.readFile inputFile
63− r <- ormoluFile config inputFile
65+ formattedInput <- ormoluFile config inputFile
64 case mode of
66 case mode of
65 Stdout ->
67 Stdout ->
66− TIO.putStr r
68+ TIO.putStr formattedInput
67− InPlace ->
69+ InPlace -> do
70+ -- Only write when the contents have changed, in order to avoid
71+ -- updating the modified timestamp if the file was already correctly
72+ -- formatted.
73+ when (formattedInput /= originalInput) $
68− TIO.writeFile inputFile r
74+ TIO.writeFile inputFile formattedInput
69 Check -> do
75 Check -> do
70− r' <- TIO.readFile inputFile
76+ when (formattedInput /= originalInput) $
71− when (r /= r') $
72 -- 100 is different to all the other exit code that are emitted
77 -- 100 is different to all the other exit code that are emitted
73 -- either from an 'OrmoluException' or from 'error' and
78 -- either from an 'OrmoluException' or from 'error' and
74 -- 'notImplemented'.
79 -- 'notImplemented'.
@@ -134,13 +139,18 @@ optsParserInfo =
134optsParser :: Parser Opts
139optsParser :: Parser Opts
135optsParser =
140optsParser =
136 Opts
141 Opts
142+ <$> ( (fmap (bool Stdout InPlace) . switch . mconcat)
143+ [ short 'i',
144+ help "A shortcut for --mode inplace"
145+ ]
137− <$> (option parseMode . mconcat)
146+ <|> (option parseMode . mconcat)
138− [ long "mode",
147+ [ long "mode",
139− short 'm',
148+ short 'm',
140− metavar "MODE",
149+ metavar "MODE",
141− value Stdout,
150+ value Stdout,
142− help "Mode of operation: 'stdout' (default), 'inplace', or 'check'"
151+ help "Mode of operation: 'stdout' (default), 'inplace', or 'check'"
143− ]
152+ ]
153+ )
144 <*> configParser
154 <*> configParser
145 <*> (many . strArgument . mconcat)
155 <*> (many . strArgument . mconcat)
146 [ metavar "FILE",
156 [ metavar "FILE",
data/examples/declaration/signature/type/infix-promoted-type-constructor-out.hs−1
@@ -1,3 +1,2 @@
1fun1 :: Def ('[Ref s (Stored Uint32), IBool] 'T.:-> IBool)
1fun1 :: Def ('[Ref s (Stored Uint32), IBool] 'T.:-> IBool)
2−
3fun2 :: Def ('[Ref s (Stored Uint32), IBool] ':-> IBool)
2fun2 :: Def ('[Ref s (Stored Uint32), IBool] ':-> IBool)
data/examples/declaration/signature/type/unrelated-out.hsnew file+4
@@ -0,0 +1,4 @@
1+clientFunc1 :: SomeType1
2+clientFunc2 :: SomeType2
3+clientFunc3 :: SomeType3
4+clientFunc1 :<|> clientFunc2 :<|> clientFunc3 = hoistClient foo bar baz
data/examples/declaration/signature/type/unrelated.hsnew file+4
@@ -0,0 +1,4 @@
1+clientFunc1 :: SomeType1
2+clientFunc2 :: SomeType2
3+clientFunc3 :: SomeType3
4+clientFunc1 :<|> clientFunc2 :<|> clientFunc3 = hoistClient foo bar baz
data/examples/declaration/value/function/implicit-params-out.hs+1
@@ -1,6 +1,7 @@
1{-# LANGUAGE ImplicitParams #-}
1{-# LANGUAGE ImplicitParams #-}
2
2
3sortBy :: (a -> a -> Bool) -> [a] -> [a]
3sortBy :: (a -> a -> Bool) -> [a] -> [a]
4+sortBy = undefined
4
5
5sort :: (?cmp :: a -> a -> Bool) => [a] -> [a]
6sort :: (?cmp :: a -> a -> Bool) => [a] -> [a]
6sort = sortBy ?cmp
7sort = sortBy ?cmp
data/examples/declaration/value/function/implicit-params.hs+2
@@ -1,6 +1,8 @@
1{-# LANGUAGE ImplicitParams #-}
1{-# LANGUAGE ImplicitParams #-}
2sortBy :: (a -> a -> Bool) -> [a] -> [a]
2sortBy :: (a -> a -> Bool) -> [a] -> [a]
3
3
4+sortBy = undefined
5+
4sort :: (?cmp :: a -> a -> Bool) => [a] -> [a]
6sort :: (?cmp :: a -> a -> Bool) => [a] -> [a]
5sort = sortBy ?cmp
7sort = sortBy ?cmp
6
8
data/examples/import/deduplication-bug-out.hs+4
@@ -1,2 +1,6 @@
1import Foo1 (Bar1 (..), Baz1)
1import Foo1 (Bar1 (..), Baz1)
2import Foo2 (Bar2 (..), Baz2)
2import Foo2 (Bar2 (..), Baz2)
3+import Foo3 (Bar3 (x1, x2, x3))
4+import Foo4 (Bar4 (x1, x2))
5+import Foo5 (Bar5 (x1))
6+import Foo6 (Bar6 (..))
data/examples/import/deduplication-bug.hs+4
@@ -1,2 +1,6 @@
1import Foo1 (Bar1, Baz1, Bar1(..))
1import Foo1 (Bar1, Baz1, Bar1(..))
2import Foo2 (Bar2(..), Baz2, Bar2)
2import Foo2 (Bar2(..), Baz2, Bar2)
3+import Foo3 (Bar3(x1,x3), Bar3(x1, x2))
4+import Foo4 (Bar4(x1), Bar4(x2))
5+import Foo5 (Bar5, Bar5(x1))
6+import Foo6 (Bar6(x1), Bar6(..))
data/examples/import/merging-0-out.hsnew file+3
@@ -0,0 +1,3 @@
1+import Foo
2+import Foo (bar, foo)
3+import Foo as F
data/examples/import/merging-0.hsnew file+4
@@ -0,0 +1,4 @@
1+import Foo
2+import Foo (foo)
3+import Foo (bar)
4+import Foo as F
data/examples/import/merging-1-out.hsnew file+2
@@ -0,0 +1,2 @@
1+import "bar" Foo (bar)
2+import "foo" Foo (baz, foo)
data/examples/import/merging-1.hsnew file+3
@@ -0,0 +1,3 @@
1+import "foo" Foo (foo)
2+import "bar" Foo (bar)
3+import "foo" Foo (baz)
data/examples/import/merging-2-out.hsnew file+2
@@ -0,0 +1,2 @@
1+import Foo hiding (bar4, foo2)
2+import qualified Foo (bar3, foo1)
data/examples/import/merging-2.hsnew file+4
@@ -0,0 +1,4 @@
1+import qualified Foo (foo1)
2+import Foo hiding (foo2)
3+import qualified Foo (bar3)
4+import Foo hiding (bar4)
data/examples/import/qualified-post-out.hs+1−1
@@ -1,5 +1,5 @@
1{-# LANGUAGE ImportQualifiedPost #-}
1{-# LANGUAGE ImportQualifiedPost #-}
2
2
3−import Data.Text qualified as T
4import Data.Text qualified (a, b, c)
3import Data.Text qualified (a, b, c)
5import Data.Text qualified hiding (a, b, c)
4import Data.Text qualified hiding (a, b, c)
5+import Data.Text qualified as T
data/examples/import/qualified-prelude-out.hs+1−1
@@ -1,4 +1,4 @@
1module P where
1module P where
2
2
3−import qualified Prelude
4import Prelude hiding (id, (.))
3import Prelude hiding (id, (.))
4+import qualified Prelude
data/examples/import/simple-out.hs+2−5
@@ -1,8 +1,5 @@
1import Data.Text
1import Data.Text
2−import Data.Text
3−import qualified Data.Text as T
4−import qualified Data.Text (a, b, c)
5−import Data.Text (a, b, c)
6−import Data.Text hiding (a, b, c)
7import Data.Text (a, b, c)
2import Data.Text (a, b, c)
8import Data.Text hiding (a, b, c)
3import Data.Text hiding (a, b, c)
4+import qualified Data.Text (a, b, c)
5+import qualified Data.Text as T
data/examples/other/argument-comment-out.hs−1
@@ -9,7 +9,6 @@ foo ::
9 -- | Foo
9 -- | Foo
10 Int ->
10 Int ->
11 Int
11 Int
12−
13foo ::
12foo ::
14 Foo a =>
13 Foo a =>
15 -- | Foo
14 -- | Foo
data/examples/other/comment-glued-together-out.hsnew file+7
@@ -0,0 +1,7 @@
1+module Main (main) where
2+
3+-- | Foo.
4+
5+-- Bar
6+main :: IO ()
7+main = return ()
data/examples/other/comment-glued-together.hsnew file+6
@@ -0,0 +1,6 @@
1+module Main (main) where
2+
3+{- | Foo. -}
4+-- Bar
5+main :: IO ()
6+main = return ()
data/examples/other/cpp/separation-2b-out.hs−1
@@ -1,5 +1,4 @@
1ffff, ffffffff :: Natural
1ffff, ffffffff :: Natural
2−
3#ifdef HASKELL_ZIP_DEV_MODE
2#ifdef HASKELL_ZIP_DEV_MODE
4ffff = 200
3ffff = 200
5ffffffff = 5000
4ffffffff = 5000
default.nix+7−10
@@ -1,5 +1,6 @@
1−{ pkgs ? (import ./nix/nixpkgs)
1+{ pkgs ? (import ./nix/nixpkgs { inherit system; })
2+, system ? builtins.currentSystem
2−, ormoluCompiler ? "ghc883" # the shell doesn't work with ghc8101 yet
3+, ormoluCompiler ? "ghc884" # the shell doesn't work with ghc8101 yet
3}:
4}:
4
5
5let
6let
@@ -16,12 +17,6 @@ let
16 };
17 };
17 ormoluOverlay = self: super: {
18 ormoluOverlay = self: super: {
18 "ormolu" = super.callCabal2nixWithOptions "ormolu" source "-fdev" { };
19 "ormolu" = super.callCabal2nixWithOptions "ormolu" source "-fdev" { };
19− "ghc-lib-parser" = pkgs.haskell.lib.dontHaddock
20− (super.callHackageDirect {
21− pkg = "ghc-lib-parser";
22− ver = "8.10.1.20200412";
23− sha256 = "sha256-EjMzp8xRT3xVFKDI1fAfopkylGB0hv35Av2+uZeETRU=";
24− } {});
25 };
20 };
26 ormolize = import ./nix/ormolize {
21 ormolize = import ./nix/ormolize {
27 inherit pkgs;
22 inherit pkgs;
@@ -33,14 +28,16 @@ let
33 "distributed-process"
28 "distributed-process"
34 "esqueleto"
29 "esqueleto"
35 "fay"
30 "fay"
31+ "hlint"
36 "idris"
32 "idris"
37 "intero"
33 "intero"
38 "leksah"
34 "leksah"
39− "lens"
40 "pandoc"
35 "pandoc"
41 "pipes"
36 "pipes"
37+ "postgrest"
42 "purescript"
38 "purescript"
43− ];
39+ "tensorflow"
40+ ] ++ (if ormoluCompiler == "ghc8101" then [] else ["lens"]);
44 ormolizedPackages = doCheck:
41 ormolizedPackages = doCheck:
45 pkgs.lib.mapAttrs (name: p: ormolize {
42 pkgs.lib.mapAttrs (name: p: ormolize {
46 package = p;
43 package = p;
expected-failures/Agda.txt+1−1
@@ -1,5 +1,5 @@
1Formatting is not idempotent:
1Formatting is not idempotent:
2− dist/build/Agda/Syntax/Parser/Lexer.hs<rendered>:1597:17
2+ dist/build/Agda/Syntax/Parser/Lexer.hs<rendered>:1602:17
3 before: " = (check_ac"
3 before: " = (check_ac"
4 after: " =\n "
4 after: " =\n "
5Please, consider reporting the bug.
5Please, consider reporting the bug.
expected-failures/esqueleto.txt+1−1
@@ -3,5 +3,5 @@ The GHC parser (in Haddock mode) failed:
3 lexical error in string/character literal at character 's'
3 lexical error in string/character literal at character 's'
4
4
5The GHC parser (in Haddock mode) failed:
5The GHC parser (in Haddock mode) failed:
6− test/PostgreSQL/Test.hs:510:9-41
6+ test/PostgreSQL/Test.hs:562:9-41
7 parse error on input `-- | Check the result is not null'
7 parse error on input `-- | Check the result is not null'
expected-failures/hlint.txtnew file+11
@@ -0,0 +1,11 @@
1+Formatting is not idempotent:
2+ src/Extension.hs<rendered>:19:22
3+ before: "DoRec , -} Recursive"
4+ after: "DoRec , -}\n "
5+Please, consider reporting the bug.
6+
7+Formatting is not idempotent:
8+ src/Hint/Bracket.hs<rendered>:249:50
9+ before: "\" x y [r]) {ideaSpan"
10+ after: "\" x y [r])\n "
11+Please, consider reporting the bug.
expected-failures/idris.txt−4
@@ -2,10 +2,6 @@ The GHC parser (in Haddock mode) failed:
2 src/Idris/Parser.hs:1052:1
2 src/Idris/Parser.hs:1052:1
3 parse error on input `@'
3 parse error on input `@'
4
4
5−AST of input and AST of formatted code differ.
6− at src/Idris/Parser/Data.hs:281:1-29
7−Please, consider reporting the bug.
8−
9The GHC parser (in Haddock mode) failed:
5The GHC parser (in Haddock mode) failed:
10 src/Idris/Parser/Expr.hs:75:1
6 src/Idris/Parser/Expr.hs:75:1
11 parse error on input `@'
7 parse error on input `@'
expected-failures/intero.txt+1−1
@@ -1,5 +1,5 @@
1Formatting is not idempotent:
1Formatting is not idempotent:
2− src/InteractiveUI.hs<rendered>:3757:33
2+ src/InteractiveUI.hs<rendered>:3748:33
3 before: "text \"Try\" <+> doWha"
3 before: "text \"Try\" <+> doWha"
4 after: "text \"Try\"\n "
4 after: "text \"Try\"\n "
5Please, consider reporting the bug.
5Please, consider reporting the bug.
expected-failures/leksah.txt+1−1
@@ -1,5 +1,5 @@
1Formatting is not idempotent:
1Formatting is not idempotent:
2− src/IDE/Pane/Modules.hs<rendered>:1189:7
2+ src/IDE/Pane/Modules.hs<rendered>:1184:7
3 before: "cr\n -- show"
3 before: "cr\n -- show"
4 after: "cr\n in -- show"
4 after: "cr\n in -- show"
5Please, consider reporting the bug.
5Please, consider reporting the bug.
expected-failures/pandoc.txt+1−1
@@ -3,7 +3,7 @@ The GHC parser (in Haddock mode) failed:
3 parse error on input `import'
3 parse error on input `import'
4
4
5Formatting is not idempotent:
5Formatting is not idempotent:
6− src/Text/Pandoc/Readers/Vimwiki.hs<rendered>:615:19
6+ src/Text/Pandoc/Readers/Vimwiki.hs<rendered>:613:19
7 before: ".softbreak <$ endlin"
7 before: ".softbreak <$ endlin"
8 after: ".softbreak\n <$ en"
8 after: ".softbreak\n <$ en"
9Please, consider reporting the bug.
9Please, consider reporting the bug.
expected-failures/postgrest.txtnew file+5
@@ -0,0 +1,5 @@
1+Formatting is not idempotent:
2+ src/PostgREST/DbRequestBuilder.hs<rendered>:149:24
3+ before: " || -- clients"
4+ after: " || ( origin ="
5+Please, consider reporting the bug.
expected-failures/purescript.txt+2−2
@@ -1,10 +1,10 @@
1The GHC parser (in Haddock mode) failed:
1The GHC parser (in Haddock mode) failed:
2− src/Language/PureScript/AST/Declarations.hs:478:1-17
2+ src/Language/PureScript/AST/Declarations.hs:479:1-17
3 Invalid type signature: pattern ValueDecl :: ...
3 Invalid type signature: pattern ValueDecl :: ...
4Perhaps you meant to use PatternSynonyms?
4Perhaps you meant to use PatternSynonyms?
5
5
6The GHC parser (in Haddock mode) failed:
6The GHC parser (in Haddock mode) failed:
7− src/Language/PureScript/AST/SourcePos.hs:101:1-22
7+ src/Language/PureScript/AST/SourcePos.hs:99:1-22
8 Invalid type signature: pattern NullSourceSpan :: ...
8 Invalid type signature: pattern NullSourceSpan :: ...
9Perhaps you meant to use PatternSynonyms?
9Perhaps you meant to use PatternSynonyms?
10
10
expected-failures/tensorflow.txtnew file+7
@@ -0,0 +1,7 @@
1+The GHC parser (in Haddock mode) failed:
2+ tensorflow-mnist/app/Main.hs:50:13-14
3+ parse error on input `->'
4+
5+The GHC parser (in Haddock mode) failed:
6+ tensorflow-ops/tests/RegressionTest.hs:3:1-6
7+ parse error on input `import'
nix/nixpkgs/default.nix+7−3
@@ -1,9 +1,13 @@
1+{ system ? builtins.currentSystem }:
1let
2let
2− rev = "807ca93fadd5197c2260490de0c76e500562dc05";
3+ rev = "32b46dd897ab2143a609988a04d87452f0bbef59";
3− sha256 = "10yq8bnls77fh3pk5chkkb1sv5lbdgyk1rr2v9xn71rr1k2x563p";
4+ sha256 = "1gzfrpjnr1bz9zljsyg3a4zrhk8r927sz761mrgcg56dwinkhpjk";
4 nixpkgs = builtins.fetchTarball {
5 nixpkgs = builtins.fetchTarball {
5 url = "https://github.com/NixOS/nixpkgs/archive/${rev}.tar.gz";
6 url = "https://github.com/NixOS/nixpkgs/archive/${rev}.tar.gz";
6 inherit sha256;
7 inherit sha256;
7 };
8 };
9+ pkgs = import nixpkgs {
10+ inherit system;
8− pkgs = import nixpkgs { config.allowUnfree = true; };
11+ config.allowUnfree = true;
12+ };
9in pkgs
13in pkgs
ormolu.cabal+4−4
@@ -1,10 +1,10 @@
1cabal-version: 1.18
1cabal-version: 1.18
2name: ormolu
2name: ormolu
3−version: 0.1.0.0
3+version: 0.1.2.0
4license: BSD3
4license: BSD3
5license-file: LICENSE.md
5license-file: LICENSE.md
6maintainer: Mark Karpov <mark.karpov@tweag.io>
6maintainer: Mark Karpov <mark.karpov@tweag.io>
7−tested-with: ghc ==8.6.5 ghc ==8.8.3 ghc ==8.10.1
7+tested-with: ghc ==8.6.5 ghc ==8.8.4 ghc ==8.10.1
8homepage: https://github.com/tweag/ormolu
8homepage: https://github.com/tweag/ormolu
9bug-reports: https://github.com/tweag/ormolu/issues
9bug-reports: https://github.com/tweag/ormolu/issues
10synopsis: A formatter for Haskell source code
10synopsis: A formatter for Haskell source code
@@ -119,7 +119,7 @@ library
119 base >=4.12 && <5.0,
119 base >=4.12 && <5.0,
120 bytestring >=0.2 && <0.11,
120 bytestring >=0.2 && <0.11,
121 containers >=0.5 && <0.7,
121 containers >=0.5 && <0.7,
122− dlist >=0.8 && <0.9,
122+ dlist >=0.8 && <2.0,
123 exceptions >=0.6 && <0.11,
123 exceptions >=0.6 && <0.11,
124 ghc-lib-parser >=8.10 && <8.11,
124 ghc-lib-parser >=8.10 && <8.11,
125 mtl >=2.0 && <3.0,
125 mtl >=2.0 && <3.0,
@@ -144,7 +144,7 @@ executable ormolu
144 base >=4.12 && <5.0,
144 base >=4.12 && <5.0,
145 ghc-lib-parser >=8.10 && <8.11,
145 ghc-lib-parser >=8.10 && <8.11,
146 gitrev >=1.3 && <1.4,
146 gitrev >=1.3 && <1.4,
147− optparse-applicative >=0.14 && <0.16,
147+ optparse-applicative >=0.14 && <0.17,
148 ormolu -any,
148 ormolu -any,
149 text >=0.2 && <1.3
149 text >=0.2 && <1.3
150
150
shell.nix+3−1
@@ -1,3 +1,5 @@
1−{ pkgs ? (import ./nix/nixpkgs) }:
1+{ pkgs ? (import ./nix/nixpkgs { inherit system; })
2+, system ? builtins.currentSystem
3+}:
2
4
3(import ./default.nix { inherit pkgs; }).dev.ormoluShell
5(import ./default.nix { inherit pkgs; }).dev.ormoluShell
src/Ormolu/Diff.hs+3−3
@@ -14,7 +14,7 @@ import Data.Text (Text)
14import qualified Data.Text as T
14import qualified Data.Text as T
15import qualified FastString as GHC
15import qualified FastString as GHC
16import GHC
16import GHC
17−import Ormolu.Imports (sortImports)
17+import Ormolu.Imports (normalizeImports)
18import Ormolu.Parser.CommentStream
18import Ormolu.Parser.CommentStream
19import Ormolu.Parser.Result
19import Ormolu.Parser.Result
20import Ormolu.Utils
20import Ormolu.Utils
@@ -47,8 +47,8 @@ diffParseResult
47 } =
47 } =
48 matchIgnoringSrcSpans cstream0 cstream1
48 matchIgnoringSrcSpans cstream0 cstream1
49 <> matchIgnoringSrcSpans
49 <> matchIgnoringSrcSpans
50− hs0 {hsmodImports = sortImports (hsmodImports hs0)}
50+ hs0 {hsmodImports = normalizeImports (hsmodImports hs0)}
51− hs1 {hsmodImports = sortImports (hsmodImports hs1)}
51+ hs1 {hsmodImports = normalizeImports (hsmodImports hs1)}
52
52
53-- | Compare two values for equality disregarding differences in 'SrcSpan's
53-- | Compare two values for equality disregarding differences in 'SrcSpan's
54-- and the ordering of import lists.
54-- and the ordering of import lists.
src/Ormolu/Imports.hs+139−55
@@ -4,92 +4,176 @@
4
4
5-- | Manipulations on import lists.
5-- | Manipulations on import lists.
6module Ormolu.Imports
6module Ormolu.Imports
7− ( sortImports,
7+ ( normalizeImports,
8 )
8 )
9where
9where
10
10
11import Data.Bifunctor
11import Data.Bifunctor
12import Data.Char (isAlphaNum)
12import Data.Char (isAlphaNum)
13import Data.Function (on)
13import Data.Function (on)
14−import Data.Generics (gcompare)
15−import Data.List (nubBy, sortBy)
14+import Data.List (foldl', nubBy, sortBy, sortOn)
15+import Data.Map.Strict (Map)
16+import qualified Data.Map.Strict as M
17+import FastString (FastString)
16import GHC hiding (GhcPs, IE)
18import GHC hiding (GhcPs, IE)
17import GHC.Hs.Extension
19import GHC.Hs.Extension
18import GHC.Hs.ImpExp (IE (..))
20import GHC.Hs.ImpExp (IE (..))
19import Ormolu.Utils (notImplemented, showOutputable)
21import Ormolu.Utils (notImplemented, showOutputable)
20
22
21−-- | Sort imports by module name. This also sorts explicit import lists for
23+-- | Sort and normalize imports.
22−-- each declaration.
23−sortImports :: [LImportDecl GhcPs] -> [LImportDecl GhcPs]
24+normalizeImports :: [LImportDecl GhcPs] -> [LImportDecl GhcPs]
24−sortImports = sortBy compareIdecl . fmap (fmap sortImportLists)
25+normalizeImports =
26+ fmap snd
27+ . M.toAscList
28+ . M.fromListWith combineImports
29+ . fmap (\x -> (importId x, g x))
25 where
30 where
26− sortImportLists :: ImportDecl GhcPs -> ImportDecl GhcPs
27− sortImportLists = \case
28− ImportDecl {..} ->
31+ g (L l ImportDecl {..}) =
32+ L
33+ l
29 ImportDecl
34 ImportDecl
30− { ideclHiding = second (fmap sortLies) <$> ideclHiding,
35+ { ideclHiding = second (fmap normalizeLies) <$> ideclHiding,
31 ..
36 ..
32 }
37 }
33− XImportDecl x -> noExtCon x
38+ g _ = notImplemented "XImportDecl"
34
39
35−-- | Compare two @'LImportDecl' 'GhcPs'@ things.
40+-- | Combine two import declarations. It should be assumed that 'ImportId's
41+-- are equal.
42+combineImports ::
36−compareIdecl :: LImportDecl GhcPs -> LImportDecl GhcPs -> Ordering
43+ LImportDecl GhcPs ->
37−compareIdecl (L _ m0) (L _ m1) =
44+ LImportDecl GhcPs ->
38− case (isPrelude n0, isPrelude n1) of
45+ LImportDecl GhcPs
39− (False, False) -> n0 `compare` n1
46+combineImports (L lx ImportDecl {..}) (L _ y) =
40− (True, False) -> GT
47+ L
41− (False, True) -> LT
48+ lx
42− (True, True) -> m0 `gcompare` m1
49+ ImportDecl
43− where
50+ { ideclHiding = case (ideclHiding, GHC.ideclHiding y) of
44− n0 = unLoc (ideclName m0)
51+ (Just (hiding, L l' xs), Just (_, L _ ys)) ->
45− n1 = unLoc (ideclName m1)
52+ Just (hiding, (L l' (normalizeLies (xs ++ ys))))
46− isPrelude = (== "Prelude") . moduleNameString
53+ _ -> Nothing,
54+ ..
55+ }
56+combineImports _ _ = notImplemented "XImportDecl"
47
57
48−-- | Sort located import or export, dropping duplicates.
58+-- | Import id, a collection of all things that justify having a separate
49−sortLies :: [LIE GhcPs] -> [LIE GhcPs]
59+-- import entry. This is used for merging of imports. If two imports have
50−sortLies =
60+-- the same 'ImportId' they can be merged.
51− nubBy (\x y -> compareLIE x y == EQ)
61+data ImportId = ImportId
52− . sortBy compareLIEAll
62+ { importIsPrelude :: Bool,
53− . fmap (fmap sortThings)
63+ importIdName :: ModuleName,
64+ importPkgQual :: Maybe FastString,
65+ importSource :: Bool,
66+ importSafe :: Bool,
67+ importQualified :: Bool,
68+ importImplicit :: Bool,
69+ importAs :: Maybe ModuleName,
70+ importHiding :: Maybe Bool
71+ }
72+ deriving (Eq, Ord)
54
73
55−-- | Sort imports\/exports inside of 'IEThingWith'.
74+-- | Obtain an 'ImportId' for a given import.
56−sortThings :: IE GhcPs -> IE GhcPs
75+importId :: LImportDecl GhcPs -> ImportId
57−sortThings = \case
76+importId (L _ ImportDecl {..}) =
58− IEThingWith NoExtField x w xs fl ->
77+ ImportId
59− IEThingWith NoExtField x w (sortBy (compareIewn `on` unLoc) xs) fl
78+ { importIsPrelude = isPrelude,
60− other -> other
79+ importIdName = moduleName,
80+ importPkgQual = sl_fs <$> ideclPkgQual,
81+ importSource = ideclSource,
82+ importSafe = ideclSafe,
83+ importQualified = case ideclQualified of
84+ QualifiedPre -> True
85+ QualifiedPost -> True
86+ NotQualified -> False,
87+ importImplicit = ideclImplicit,
88+ importAs = unLoc <$> ideclAs,
89+ importHiding = fst <$> ideclHiding
90+ }
91+ where
92+ isPrelude = moduleNameString moduleName == "Prelude"
93+ moduleName = unLoc ideclName
94+importId _ = notImplemented "XImportDecl"
61
95
62−-- | Compare a pair of located imports or exports taking into account
96+-- | Normalize a collection of import\/export items.
63−-- wildcards.
64−compareLIEAll :: LIE GhcPs -> LIE GhcPs -> Ordering
97+normalizeLies :: [LIE GhcPs] -> [LIE GhcPs]
65−compareLIEAll = f `on` getIewn . unLoc
98+normalizeLies = sortOn (getIewn . unLoc) . M.elems . foldl' combine M.empty
66 where
99 where
67− f (x, xall) (y, yall) =
100+ combine ::
68− case x `compareIewn` y of
101+ Map IEWrappedNameOrd (LIE GhcPs) ->
69− EQ -> xall `compare` yall
102+ LIE GhcPs ->
70− ordering -> ordering
103+ Map IEWrappedNameOrd (LIE GhcPs)
104+ combine m (L new_l new) =
105+ let wname = getIewn new
106+ normalizeWNames =
107+ nubBy (\x y -> compareLIewn x y == EQ) . sortBy compareLIewn
108+ alter = \case
109+ Nothing -> Just . L new_l $
110+ case new of
111+ IEThingWith NoExtField n wildcard g flbl ->
112+ IEThingWith NoExtField n wildcard (normalizeWNames g) flbl
113+ other -> other
114+ Just old ->
115+ let f = \case
116+ IEVar NoExtField n -> IEVar NoExtField n
117+ IEThingAbs NoExtField _ -> new
118+ IEThingAll NoExtField n -> IEThingAll NoExtField n
119+ IEThingWith NoExtField n wildcard g flbl ->
120+ case new of
121+ IEVar NoExtField _ ->
122+ error "Ormolu.Imports broken presupposition"
123+ IEThingAbs NoExtField _ ->
124+ IEThingWith NoExtField n wildcard g flbl
125+ IEThingAll NoExtField n' ->
126+ IEThingAll NoExtField n'
127+ IEThingWith NoExtField n' wildcard' g' flbl' ->
128+ let combinedWildcard =
129+ case (wildcard, wildcard') of
130+ (IEWildcard _, _) -> IEWildcard 0
131+ (_, IEWildcard _) -> IEWildcard 0
132+ _ -> NoIEWildcard
133+ in IEThingWith
134+ NoExtField
135+ n'
136+ combinedWildcard
137+ (normalizeWNames (g <> g'))
138+ flbl'
139+ IEModuleContents NoExtField _ -> notImplemented "IEModuleContents"
140+ IEGroup NoExtField _ _ -> notImplemented "IEGroup"
141+ IEDoc NoExtField _ -> notImplemented "IEDoc"
142+ IEDocNamed NoExtField _ -> notImplemented "IEDocNamed"
143+ XIE x -> noExtCon x
144+ IEModuleContents NoExtField _ -> notImplemented "IEModuleContents"
145+ IEGroup NoExtField _ _ -> notImplemented "IEGroup"
146+ IEDoc NoExtField _ -> notImplemented "IEDoc"
147+ IEDocNamed NoExtField _ -> notImplemented "IEDocNamed"
148+ XIE x -> noExtCon x
149+ in Just (f <$> old)
150+ in M.alter alter wname m
71
151
72−-- | The same as 'compareLIEAll'.
152+-- | A wrapper for @'IEWrappedName' 'RdrName'@ that allows us to define an
73−compareLIE :: LIE GhcPs -> LIE GhcPs -> Ordering
153+-- 'Ord' instance for it.
74−compareLIE = compareIewn `on` fst . getIewn . unLoc
154+newtype IEWrappedNameOrd = IEWrappedNameOrd (IEWrappedName RdrName)
155+ deriving (Eq)
75
156
76−-- | Indication whether or not a wildcard is used by an import item.
157+instance Ord IEWrappedNameOrd where
77−data IEWild = All | NoWild
158+ compare (IEWrappedNameOrd x) (IEWrappedNameOrd y) = compareIewn x y
78− deriving (Eq, Ord)
79
159
80-- | Project @'IEWrappedName' 'RdrName'@ from @'IE' 'GhcPs'@.
160-- | Project @'IEWrappedName' 'RdrName'@ from @'IE' 'GhcPs'@.
81−getIewn :: IE GhcPs -> (IEWrappedName RdrName, IEWild)
161+getIewn :: IE GhcPs -> IEWrappedNameOrd
82getIewn = \case
162getIewn = \case
83− IEVar NoExtField x -> (unLoc x, NoWild)
163+ IEVar NoExtField x -> IEWrappedNameOrd (unLoc x)
84− IEThingAbs NoExtField x -> (unLoc x, NoWild)
164+ IEThingAbs NoExtField x -> IEWrappedNameOrd (unLoc x)
85− IEThingAll NoExtField x -> (unLoc x, All)
165+ IEThingAll NoExtField x -> IEWrappedNameOrd (unLoc x)
86− IEThingWith NoExtField x _ _ _ -> (unLoc x, NoWild)
166+ IEThingWith NoExtField x _ _ _ -> IEWrappedNameOrd (unLoc x)
87 IEModuleContents NoExtField _ -> notImplemented "IEModuleContents"
167 IEModuleContents NoExtField _ -> notImplemented "IEModuleContents"
88 IEGroup NoExtField _ _ -> notImplemented "IEGroup"
168 IEGroup NoExtField _ _ -> notImplemented "IEGroup"
89 IEDoc NoExtField _ -> notImplemented "IEDoc"
169 IEDoc NoExtField _ -> notImplemented "IEDoc"
90 IEDocNamed NoExtField _ -> notImplemented "IEDocNamed"
170 IEDocNamed NoExtField _ -> notImplemented "IEDocNamed"
91 XIE x -> noExtCon x
171 XIE x -> noExtCon x
92
172
173+-- | Like 'compareIewn' for located wrapped names.
174+compareLIewn :: LIEWrappedName RdrName -> LIEWrappedName RdrName -> Ordering
175+compareLIewn = compareIewn `on` unLoc
176+
93-- | Compare two @'IEWrapppedName' 'RdrName'@ things.
177-- | Compare two @'IEWrapppedName' 'RdrName'@ things.
94compareIewn :: IEWrappedName RdrName -> IEWrappedName RdrName -> Ordering
178compareIewn :: IEWrappedName RdrName -> IEWrappedName RdrName -> Ordering
95compareIewn (IEName x) (IEName y) = unLoc x `compareRdrName` unLoc y
179compareIewn (IEName x) (IEName y) = unLoc x `compareRdrName` unLoc y
src/Ormolu/Printer/Comments.hs+2−2
@@ -154,6 +154,7 @@ needsNewlineBefore ::
154 -- | Last printed comment span
154 -- | Last printed comment span
155 Maybe SpanMark ->
155 Maybe SpanMark ->
156 Bool
156 Bool
157+needsNewlineBefore _ (Just (HaddockSpan _ _)) = True
157needsNewlineBefore l mlastMark =
158needsNewlineBefore l mlastMark =
158 case spanMarkSpan <$> mlastMark of
159 case spanMarkSpan <$> mlastMark of
159 Nothing -> False
160 Nothing -> False
@@ -238,8 +239,7 @@ commentFollowsElt ref mnSpn meSpn mlastMark (L l comment) =
238 -- lexemes in front of it and goes right after the previous comment.
239 -- lexemes in front of it and goes right after the previous comment.
239 not (hasAtomsBefore comment)
240 not (hasAtomsBefore comment)
240 && ( case mlastMark of
241 && ( case mlastMark of
241− Just (HaddockSpan _ spn) ->
242+ Just (HaddockSpan _ _) -> False
242− srcSpanEndLine spn + 1 == srcSpanStartLine l
243 Just (CommentSpan spn) ->
243 Just (CommentSpan spn) ->
244 srcSpanEndLine spn + 1 == srcSpanStartLine l
244 srcSpanEndLine spn + 1 == srcSpanStartLine l
245 _ -> False
245 _ -> False
src/Ormolu/Printer/Meat/Declaration.hs+14−4
@@ -85,9 +85,6 @@ isDocumented = any (isHaddock . unLoc)
85 isHaddock _ = False
85 isHaddock _ = False
86
86
87-- | Group relevant declarations together.
87-- | Group relevant declarations together.
88−--
89−-- Add a declaration to a group iff it is relevant to either the first or
90−-- the preceding declaration in the group.
91groupDecls :: [LHsDecl GhcPs] -> [NonEmpty (LHsDecl GhcPs)]
88groupDecls :: [LHsDecl GhcPs] -> [NonEmpty (LHsDecl GhcPs)]
92groupDecls [] = []
89groupDecls [] = []
93groupDecls (l@(L _ DocNext) : xs) =
90groupDecls (l@(L _ DocNext) : xs) =
@@ -100,7 +97,8 @@ groupDecls (header : xs) =
100 let (grp, rest) = flip span (zip (header : xs) xs) $ \(previous, current) ->
97 let (grp, rest) = flip span (zip (header : xs) xs) $ \(previous, current) ->
101 let relevantToHdr = groupedDecls header current
98 let relevantToHdr = groupedDecls header current
102 relevantToPrev = groupedDecls previous current
99 relevantToPrev = groupedDecls previous current
100+ isDeclSeries = declSeries previous current
103− in relevantToHdr || relevantToPrev
101+ in isDeclSeries || relevantToHdr || relevantToPrev
104 in (header :| map snd grp) : groupDecls (map snd rest)
102 in (header :| map snd grp) : groupDecls (map snd rest)
105
103
106p_hsDecl :: FamilyStyle -> HsDecl GhcPs -> R ()
104p_hsDecl :: FamilyStyle -> HsDecl GhcPs -> R ()
@@ -197,6 +195,18 @@ groupedDecls (L l_x x') (L l_y y') =
197 (_, DocPrev) -> True
195 (_, DocPrev) -> True
198 _ -> False
196 _ -> False
199
197
198+-- | Detect declaration series that should not have blanks between them.
199+declSeries ::
200+ LHsDecl GhcPs ->
201+ LHsDecl GhcPs ->
202+ Bool
203+declSeries (L _ x) (L _ y) =
204+ case (x, y) of
205+ ( SigD NoExtField (TypeSig NoExtField _ _),
206+ SigD NoExtField (TypeSig NoExtField _ _)
207+ ) -> True
208+ _ -> False
209+
200intersects :: Ord a => [a] -> [a] -> Bool
210intersects :: Ord a => [a] -> [a] -> Bool
201intersects a b = go (sort a) (sort b)
211intersects a b = go (sort a) (sort b)
202 where
212 where
src/Ormolu/Printer/Meat/Declaration.hs-boot−1
@@ -9,5 +9,4 @@ import Ormolu.Printer.Combinators
9import Ormolu.Printer.Meat.Common
9import Ormolu.Printer.Meat.Common
10
10
11p_hsDecls :: FamilyStyle -> [LHsDecl GhcPs] -> R ()
11p_hsDecls :: FamilyStyle -> [LHsDecl GhcPs] -> R ()
12−
13p_hsDeclsRespectGrouping :: FamilyStyle -> [LHsDecl GhcPs] -> R ()
12p_hsDeclsRespectGrouping :: FamilyStyle -> [LHsDecl GhcPs] -> R ()
src/Ormolu/Printer/Meat/Declaration/Value.hs-boot−4
@@ -11,11 +11,7 @@ import GHC
11import Ormolu.Printer.Combinators
11import Ormolu.Printer.Combinators
12
12
13p_valDecl :: HsBindLR GhcPs GhcPs -> R ()
13p_valDecl :: HsBindLR GhcPs GhcPs -> R ()
14−
15p_pat :: Pat GhcPs -> R ()
14p_pat :: Pat GhcPs -> R ()
16−
17p_hsExpr :: HsExpr GhcPs -> R ()
15p_hsExpr :: HsExpr GhcPs -> R ()
18−
19p_hsSplice :: HsSplice GhcPs -> R ()
16p_hsSplice :: HsSplice GhcPs -> R ()
20−
21p_stringLit :: String -> R ()
17p_stringLit :: String -> R ()
src/Ormolu/Printer/Meat/Module.hs+2−2
@@ -11,7 +11,7 @@ where
11import Control.Monad
11import Control.Monad
12import qualified Data.Text as T
12import qualified Data.Text as T
13import GHC
13import GHC
14−import Ormolu.Imports
14+import Ormolu.Imports (normalizeImports)
15import Ormolu.Parser.CommentStream
15import Ormolu.Parser.CommentStream
16import Ormolu.Parser.Pragma
16import Ormolu.Parser.Pragma
17import Ormolu.Parser.Shebang
17import Ormolu.Parser.Shebang
@@ -69,7 +69,7 @@ p_hsModule mstackHeader shebangs pragmas qualifiedPost HsModule {..} = do
69 txt "where"
69 txt "where"
70 newline
70 newline
71 newline
71 newline
72− forM_ (sortImports hsmodImports) (located' (p_hsmodImport qualifiedPost))
72+ forM_ (normalizeImports hsmodImports) (located' (p_hsmodImport qualifiedPost))
73 newline
73 newline
74 switchLayout (getLoc <$> hsmodDecls) $ do
74 switchLayout (getLoc <$> hsmodDecls) $ do
75 p_hsDecls Free hsmodDecls
75 p_hsDecls Free hsmodDecls
src/Ormolu/Processing/Preprocess.hs+1−2
@@ -11,8 +11,7 @@ where
11import Control.Monad
11import Control.Monad
12import Data.Char (isSpace)
12import Data.Char (isSpace)
13import qualified Data.List as L
13import qualified Data.List as L
14−import Data.Maybe (isJust)
14+import Data.Maybe (isJust, maybeToList)
15−import Data.Maybe (maybeToList)
16import FastString
15import FastString
17import Ormolu.Config (RegionDeltas (..))
16import Ormolu.Config (RegionDeltas (..))
18import Ormolu.Parser.Shebang (isShebang)
17import Ormolu.Parser.Shebang (isShebang)
src/Ormolu/Utils.hs+1−1
@@ -22,8 +22,8 @@ where
22
22
23import Data.Char (isSpace)
23import Data.Char (isSpace)
24import Data.List (dropWhileEnd)
24import Data.List (dropWhileEnd)
25−import qualified Data.List.NonEmpty as NE
26import Data.List.NonEmpty (NonEmpty (..))
25import Data.List.NonEmpty (NonEmpty (..))
26+import qualified Data.List.NonEmpty as NE
27import Data.Maybe (fromMaybe)
27import Data.Maybe (fromMaybe)
28import Data.Text (Text)
28import Data.Text (Text)
29import qualified Data.Text as T
29import qualified Data.Text as T