on master help sign in
Deal with non-zero indentation in region formatting

Improved region formatting so that indented fragments can also be processed correctly.

commit35f4fb39326ab7d4847c5c8940f4d4185f3d3d24 authorMark Karpov <markkarpov92@gmail.com> dateTue 16 Jun 2020, 11:40 (6 years ago) parentc982ba9
13 files changed+94−17
CHANGELOG.md+4 default.nix+10−6 region-tests/expected-result-17-18.hs+17 region-tests/expected-result-6-7.hs+6−1 region-tests/expected-result-6-8.hs+6−1 region-tests/expected-result-9-13.hs → region-tests/expected-result-9-12.hs+6−1 region-tests/expected-result-all.hs+6 region-tests/src.hs+6−1 src/Ormolu/Parser.hs+5−3 src/Ormolu/Parser/Result.hs+3−1 src/Ormolu/Printer.hs+1−1 src/Ormolu/Processing/Postprocess.hs+10−2 src/Ormolu/Utils.hs+14
CHANGELOG.md+4
@@ -25,6 +25,10 @@
2525* Fixed the bug when type applications glued to TH splices that followed
2626 them. [Issue 613](https://github.com/tweag/ormolu/issues/613).
2727
28+* Improved region formatting so that indented fragments—such as definitions
29+ inside of `where` clauses—can be formatted. [Issue
30+ 572](https://github.com/tweag/ormolu/issues/572).
31+
2832## Ormolu 0.1.0.0
2933
3034* Fixed rendering of type signatures concerning several identifiers. [Issue
default.nix+10−6
@@ -132,17 +132,19 @@ in {
132132 cp src.hs result-all-implicit.hs
133133 ormolu --check-idempotence --mode inplace result-all-implicit.hs
134134 cp src.hs result-all-explicit.hs
135− ormolu --check-idempotence --mode inplace --start-line 1 --end-line 13 result-all-explicit.hs
135+ ormolu --check-idempotence --mode inplace --start-line 1 --end-line 18 result-all-explicit.hs
136136 cp src.hs result-only-start.hs
137137 ormolu --check-idempotence --mode inplace --start-line 1 result-only-start.hs
138138 cp src.hs result-only-end.hs
139− ormolu --check-idempotence --mode inplace --end-line 13 result-only-end.hs
139+ ormolu --check-idempotence --mode inplace --end-line 18 result-only-end.hs
140140 cp src.hs result-6-7.hs
141141 ormolu --check-idempotence --mode inplace --start-line 6 --end-line 7 result-6-7.hs
142142 cp src.hs result-6-8.hs
143143 ormolu --check-idempotence --mode inplace --start-line 6 --end-line 8 result-6-8.hs
144− cp src.hs result-9-13.hs
145− ormolu --check-idempotence --mode inplace --start-line 9 --end-line 13 result-9-13.hs
144+ cp src.hs result-9-12.hs
145+ ormolu --check-idempotence --mode inplace --start-line 9 --end-line 12 result-9-12.hs
146+ cp src.hs result-17-18.hs
147+ ormolu --check-idempotence --mode inplace --start-line 17 --end-line 18 result-17-18.hs
146148 '';
147149 checkPhase = ''
148150 echo result-all-implicit.hs
@@ -157,8 +159,10 @@ in {
157159 diff --color=always expected-result-6-7.hs result-6-7.hs
158160 echo result-6-8.hs
159161 diff --color=always expected-result-6-8.hs result-6-8.hs
160− echo result-9-13.hs
161− diff --color=always expected-result-9-13.hs result-9-13.hs
162+ echo result-9-12.hs
163+ diff --color=always expected-result-9-12.hs result-9-12.hs
164+ echo result-17-18.hs
165+ diff --color=always expected-result-17-18.hs result-17-18.hs
162166 '';
163167 installPhase = ''
164168 mkdir "$out"
region-tests/expected-result-17-18.hsnew file+17
@@ -0,0 +1,17 @@
1+{-# LANGUAGE LambdaCase #-}
2+
3+module Foo (
4+ foo, bar, baz) where
5+
6+foo :: Int
7+foo = 5
8+
9+bar :: Int -> Int
10+bar = \case
11+ 0 -> foo
12+ x -> x - foo
13+
14+baz :: Int -> Int
15+baz = gege
16+ where
17+ gege = 1 + 2
region-tests/expected-result-6-7.hs+6−1
@@ -1,7 +1,7 @@
11{-# LANGUAGE LambdaCase #-}
22
33module Foo (
4− foo, bar) where
4+ foo, bar, baz) where
55
66foo :: Int
77foo = 5
@@ -10,3 +10,8 @@ bar :: Int -> Int
1010bar = \case
1111 0 -> foo
1212 x -> x - foo
13+
14+baz :: Int -> Int
15+baz = gege
16+ where
17+ gege = 1 + 2
region-tests/expected-result-6-8.hs+6−1
@@ -1,7 +1,7 @@
11{-# LANGUAGE LambdaCase #-}
22
33module Foo (
4− foo, bar) where
4+ foo, bar, baz) where
55
66foo :: Int
77foo = 5
@@ -9,3 +9,8 @@ bar :: Int -> Int
99bar = \case
1010 0 -> foo
1111 x -> x - foo
12+
13+baz :: Int -> Int
14+baz = gege
15+ where
16+ gege = 1 + 2
region-tests/expected-result-9-13.hs → region-tests/expected-result-9-12.hsrenamed+6−1
@@ -1,7 +1,7 @@
11{-# LANGUAGE LambdaCase #-}
22
33module Foo (
4− foo, bar) where
4+ foo, bar, baz) where
55
66foo :: Int
77foo = 5
@@ -10,3 +10,8 @@ bar :: Int -> Int
1010bar = \case
1111 0 -> foo
1212 x -> x - foo
13+
14+baz :: Int -> Int
15+baz = gege
16+ where
17+ gege = 1 + 2
region-tests/expected-result-all.hs+6
@@ -3,6 +3,7 @@
33module Foo
44 ( foo,
55 bar,
6+ baz,
67 )
78where
89
@@ -13,3 +14,8 @@ bar :: Int -> Int
1314bar = \case
1415 0 -> foo
1516 x -> x - foo
17+
18+baz :: Int -> Int
19+baz = gege
20+ where
21+ gege = 1 + 2
region-tests/src.hs+6−1
@@ -1,7 +1,7 @@
11{-# LANGUAGE LambdaCase #-}
22
33module Foo (
4− foo, bar) where
4+ foo, bar, baz) where
55
66foo :: Int
77foo = 5
@@ -10,3 +10,8 @@ bar :: Int -> Int
1010bar = \case
1111 0 -> foo
1212 x -> x - foo
13+
14+baz :: Int -> Int
15+baz = gege
16+ where
17+ gege = 1 + 2
src/Ormolu/Parser.hs+5−3
@@ -32,7 +32,7 @@ import Ormolu.Parser.Anns
3232import Ormolu.Parser.CommentStream
3333import Ormolu.Parser.Result
3434import Ormolu.Processing.Preprocess (preprocess)
35−import Ormolu.Utils (incSpanLine)
35+import Ormolu.Utils (incSpanLine, removeIndentation)
3636import qualified Panic as GHC
3737import qualified Parser as GHC
3838import qualified StringBuffer as GHC
@@ -51,8 +51,9 @@ parseModule ::
5151 Either (SrcSpan, String) ParseResult
5252 )
5353parseModule Config {..} path rawInput = liftIO $ do
54− let (literalPrefix, input, literalSuffix, extraComments) =
54+ let (literalPrefix, indentedInput, literalSuffix, extraComments) =
5555 preprocess path rawInput cfgRegion
56+ (input, indent) = removeIndentation indentedInput
5657 -- It's important that 'setDefaultExts' is done before
5758 -- 'parsePragmasIntoDynFlags', because otherwise we might enable an
5859 -- extension that was explicitly disabled in the file.
@@ -110,7 +111,8 @@ parseModule Config {..} path rawInput = liftIO $ do
110111 prImportQualifiedPost =
111112 GHC.xopt ImportQualifiedPost dynFlags,
112113 prLiteralPrefix = T.pack literalPrefix,
113− prLiteralSuffix = T.pack literalSuffix
114+ prLiteralSuffix = T.pack literalSuffix,
115+ prIndent = indent
114116 }
115117 return (warnings, r)
116118
src/Ormolu/Parser/Result.hs+3−1
@@ -35,7 +35,9 @@ data ParseResult = ParseResult
3535 -- | Literal prefix
3636 prLiteralPrefix :: Text,
3737 -- | Literal suffix
38− prLiteralSuffix :: Text
38+ prLiteralSuffix :: Text,
39+ -- | Indentation level, can be non-zero in case of region formatting
40+ prIndent :: Int
3941 }
4042
4143-- | Pretty-print a 'ParseResult'.
src/Ormolu/Printer.hs+1−1
@@ -23,7 +23,7 @@ printModule ParseResult {..} =
2323 prLiteralPrefix <> region <> prLiteralSuffix
2424 where
2525 region =
26− postprocess $
26+ postprocess prIndent $
2727 runR
2828 ( p_hsModule
2929 prStackHeader
src/Ormolu/Processing/Postprocess.hs+10−2
@@ -1,3 +1,4 @@
1+{-# LANGUAGE OverloadedStrings #-}
12{-# LANGUAGE ViewPatterns #-}
23
34-- | Postprocessing for the results of printing.
@@ -12,12 +13,19 @@ import Ormolu.Processing.Common
1213import qualified Ormolu.Processing.Cpp as Cpp
1314
1415-- | Postprocess output of the formatter.
15−postprocess :: Text -> Text
16−postprocess =
16+postprocess ::
17+ -- | Desired indentation level
18+ Int ->
19+ -- | Input to process
20+ Text ->
21+ Text
22+postprocess indent =
1723 T.unlines
24+ . fmap indentLine
1825 . fmap Cpp.unmaskLine
1926 . filter (not . magicComment)
2027 . T.lines
2128 where
2229 magicComment (T.stripStart -> x) =
2330 x == startDisabling || x == endDisabling
31+ indentLine x = T.replicate indent " " <> x
src/Ormolu/Utils.hs+14
@@ -1,5 +1,6 @@
11{-# LANGUAGE LambdaCase #-}
22{-# LANGUAGE OverloadedStrings #-}
3+{-# LANGUAGE ViewPatterns #-}
34
45-- | Random utilities used by the code.
56module Ormolu.Utils
@@ -15,9 +16,11 @@ module Ormolu.Utils
1516 separatedByBlank,
1617 separatedByBlankNE,
1718 onTheSameLine,
19+ removeIndentation,
1820 )
1921where
2022
23+import Data.Char (isSpace)
2124import Data.List (dropWhileEnd)
2225import qualified Data.List.NonEmpty as NE
2326import Data.List.NonEmpty (NonEmpty (..))
@@ -139,3 +142,14 @@ separatedByBlankNE loc a b = separatedByBlank loc (NE.last a) (NE.head b)
139142onTheSameLine :: SrcSpan -> SrcSpan -> Bool
140143onTheSameLine a b =
141144 isOneLineSpan (mkSrcSpan (srcSpanEnd a) (srcSpanStart b))
145+
146+-- | Remove indentation from a given 'String'. Return the input with
147+-- indentation removed and the detected indentation level.
148+removeIndentation :: String -> (String, Int)
149+removeIndentation (lines -> xs) = (unlines (drop n <$> xs), n)
150+ where
151+ n = minimum (getIndent <$> xs)
152+ getIndent y =
153+ if all isSpace y
154+ then 0
155+ else length (takeWhile isSpace y)