on master help sign in
Preserve blank lines in ‘let’ and ‘where’ bindings
commita877785709e8e43b69ee68306d94c2ecf90af4af authorMark Karpov <markkarpov92@gmail.com> dateFri 12 Jun 2020, 14:02 (6 years ago) parent033bb16
9 files changed+56−24
CHANGELOG.md+3 data/examples/declaration/value/function/blank-lines-let-out.hs+6 data/examples/declaration/value/function/blank-lines-let.hs+9 data/examples/declaration/value/function/blank-lines-where-out.hs+6 data/examples/declaration/value/function/blank-lines-where.hs+7 expected-failures/Agda.txt+1−1 expected-failures/intero.txt+1−1 expected-failures/leksah.txt+1−1 src/Ormolu/Printer/Meat/Declaration/Value.hs+22−21
CHANGELOG.md+3
@@ -19,6 +19,9 @@
1919* Fixed rendering of function arguments in multiline layout. [Issue
2020 609](https://github.com/tweag/ormolu/issues/609).
2121
22+* Blank lines between definitions in `let` and `while` bindings are now
23+ preserved. [Issue 554](https://github.com/tweag/ormolu/issues/554).
24+
2225## Ormolu 0.1.0.0
2326
2427* Fixed rendering of type signatures concerning several identifiers. [Issue
data/examples/declaration/value/function/blank-lines-let-out.hsnew file+6
@@ -0,0 +1,6 @@
1+foo =
2+ let x = 10
3+
4+ y = 11
5+ z = 12
6+ in x + y + z
data/examples/declaration/value/function/blank-lines-let.hsnew file+9
@@ -0,0 +1,9 @@
1+foo =
2+ let
3+
4+ x = 10
5+
6+ y = 11
7+ z = 12
8+
9+ in x + y + z
data/examples/declaration/value/function/blank-lines-where-out.hsnew file+6
@@ -0,0 +1,6 @@
1+foo = x + y + z
2+ where
3+ x = 10
4+
5+ y = 11
6+ z = 12
data/examples/declaration/value/function/blank-lines-where.hsnew file+7
@@ -0,0 +1,7 @@
1+foo = x + y + z
2+ where
3+
4+ x = 10
5+
6+ y = 11
7+ z = 12
expected-failures/Agda.txt+1−1
@@ -5,7 +5,7 @@ Formatting is not idempotent:
55Please, consider reporting the bug.
66
77Formatting is not idempotent:
8− src/full/Agda/Syntax/Translation/InternalToAbstract.hs<rendered>:750:4
8+ src/full/Agda/Syntax/Translation/InternalToAbstract.hs<rendered>:769:4
99 before: " nes\n\n "
1010 after: " nes\n\n -- Andreas"
1111Please, consider reporting the bug.
expected-failures/intero.txt+1−1
@@ -1,5 +1,5 @@
11Formatting is not idempotent:
2− src/InteractiveUI.hs<rendered>:3710:33
2+ src/InteractiveUI.hs<rendered>:3757:33
33 before: "text \"Try\" <+> doWha"
44 after: "text \"Try\"\n "
55Please, consider reporting the bug.
expected-failures/leksah.txt+1−1
@@ -1,5 +1,5 @@
11Formatting is not idempotent:
2− src/IDE/Pane/Modules.hs<rendered>:1187:7
2+ src/IDE/Pane/Modules.hs<rendered>:1189:7
33 before: "cr\n -- show"
44 after: "cr\n in -- show"
55Please, consider reporting the bug.
src/Ormolu/Printer/Meat/Declaration/Value.hs+22−21
@@ -353,7 +353,14 @@ p_hsCmdTop = \case
353353 HsCmdTop NoExtField cmd -> located cmd p_hsCmd
354354 XCmdTop x -> noExtCon x
355355
356−withSpacing :: Data a => (a -> R ()) -> Located a -> R ()
356+-- | Render an expression preserving blank lines between such consecutive
357+-- expressions found in the original source code.
358+withSpacing ::
359+ -- | Rendering function
360+ (a -> R ()) ->
361+ -- | Entity to render
362+ Located a ->
363+ R ()
357364withSpacing f l = located l $ \x -> do
358365 case getLoc l of
359366 UnhelpfulSpan _ -> f x
@@ -464,30 +471,24 @@ gatherStmtBlock (XParStmtBlock x) = noExtCon x
464471p_hsLocalBinds :: HsLocalBindsLR GhcPs GhcPs -> R ()
465472p_hsLocalBinds = \case
466473 HsValBinds NoExtField (ValBinds NoExtField bag lsigs) -> do
467− let ssStart =
468− either
469− (srcSpanStart . getLoc)
470− (srcSpanStart . getLoc)
471− items =
472− (Left <$> bagToList bag) ++ (Right <$> lsigs)
473− p_item (Left x) = located x p_valDecl
474− p_item (Right x) = located x p_sigDecl
475474 -- When in a single-line layout, there is a chance that the inner
476475 -- elements will also contain semicolons and they will confuse the
477476 -- parser. so we request braces around every element except the last.
478477 br <- layoutToBraces <$> getLayout
479− sitcc $
480− sepSemi
481− ( \(p, i) ->
482− ( case p of
483− SinglePos -> id
484− FirstPos -> br
485− MiddlePos -> br
486− LastPos -> id
487− )
488− (p_item i)
489− )
490− (attachRelativePos $ sortOn ssStart items)
478+ let items =
479+ let injectLeft (L l x) = L l (Left x)
480+ injectRight (L l x) = L l (Right x)
481+ in (injectLeft <$> bagToList bag) ++ (injectRight <$> lsigs)
482+ positionToBracing = \case
483+ SinglePos -> id
484+ FirstPos -> br
485+ MiddlePos -> br
486+ LastPos -> id
487+ p_item' (p, item) =
488+ positionToBracing p $
489+ withSpacing (either p_valDecl p_sigDecl) item
490+ binds = sortOn (srcSpanStart . getLoc) items
491+ sitcc $ sepSemi p_item' (attachRelativePos binds)
491492 HsValBinds NoExtField _ -> notImplemented "HsValBinds"
492493 HsIPBinds NoExtField (IPBinds NoExtField xs) ->
493494 -- Second argument of IPBind is always Left before type-checking.