on master help sign in
Change parens style and how separated lists of items are printed

Goals: * Make the set of combinators clearer and smaller. * Solve a number of issues, such as those about parse failures related to patterns. * Solve the bug from #244. The idea is very simple, we stop doing this ( foo , bar ) and start doing this ( foo, bar ) * We switch to trailing commas which solves the indentation issues for patterns automatically. * The new general ‘sep’ combinator finally is clear enough, and all the old zoo of ‘velt’ and ‘velt'’ and ‘sepWith’, etc. which was confusing and overlapping goes away.

commit85d5f78b4b025792baeee945566bb6cb65a3f481 authormrkkrp <mark.karpov@tweag.io> dateTue 30 Jul 2019, 21:33 (7 years ago) parent180df38
99 files changed+635−633
data/examples/declaration/annotation/annotation-out.hs+1−1 data/examples/declaration/class/default-signatures-out.hs+3−3 data/examples/declaration/class/dependency-super-classes-out.hs+3−3 data/examples/declaration/class/functional-dependencies-out.hs+5−5 data/examples/declaration/class/poly-kinded-classes-out.hs+1−1 data/examples/declaration/class/single-parameters-out.hs+3−3 data/examples/declaration/class/super-classes-out.hs+4−4 data/examples/declaration/class/type-operators-out.hs+2−2 data/examples/declaration/data/deriving-strategies-out.hs+3−3 data/examples/declaration/data/gadt/multiple-declaration-out.hs+5−5 data/examples/declaration/data/gadt/record-out.hs+6−5 data/examples/declaration/data/gadt/record.hs+2−1 data/examples/declaration/data/multiline-names-out.hs+2−2 data/examples/declaration/data/record-out.hs+9−9 data/examples/declaration/default/default-out.hs+4−4 data/examples/declaration/instance/contexts-out.hs+24−21 data/examples/declaration/instance/data-family-instances-out.hs+7−7 data/examples/declaration/instance/overlappable-instances-out.hs+2−1 data/examples/declaration/instance/type-family-instances-out.hs+6−6 data/examples/declaration/rewrite-rule/type-signature-out.hs+1−1 data/examples/declaration/signature/complete/complete-out.hs+3−3 data/examples/declaration/signature/minimal/minimal-out.hs+4−4 data/examples/declaration/signature/specialize/specialize-instance-out.hs+1−1 data/examples/declaration/signature/specialize/specialize-out.hs+3−3 data/examples/declaration/signature/type/arguments-out.hs+1−1 data/examples/declaration/signature/type/context-multi-line-out.hs+4−4 data/examples/declaration/signature/type/long-multiline-applications-out.hs+1−1 data/examples/declaration/signature/type/multi-value-out.hs+3−3 data/examples/declaration/splice/typed-splice-out.hs+1−1 data/examples/declaration/splice/untyped-splice-out.hs+1−1 data/examples/declaration/value/function/arithmetic-sequences-out.hs+6−6 data/examples/declaration/value/function/arrow/expression-forms-out.hs+3−3 data/examples/declaration/value/function/arrow/proc-applications-out.hs+8−8 data/examples/declaration/value/function/arrow/proc-cases-out.hs+3−3 data/examples/declaration/value/function/arrow/proc-do-complex-out.hs+19−19 data/examples/declaration/value/function/arrow/proc-do-simple-out.hs+4−4 data/examples/declaration/value/function/arrow/proc-forms-out.hs+3−3 data/examples/declaration/value/function/arrow/proc-parentheses-out.hs+5−5 data/examples/declaration/value/function/arrow/recursive-procs-out.hs+3−3 data/examples/declaration/value/function/do-single-multi-out.hs+4 data/examples/declaration/value/function/do-single-multi.hs+2 data/examples/declaration/value/function/implicit-params-out.hs+3−3 data/examples/declaration/value/function/list-comprehensions-out.hs+14−14 data/examples/declaration/value/function/multiline-arguments-out.hs+1−1 data/examples/declaration/value/function/operator-sections-out.hs+2−2 data/examples/declaration/value/function/parallel-comprehensions-out.hs+29−29 data/examples/declaration/value/function/pattern/famous-cardano-pattern-out.hs+8 data/examples/declaration/value/function/pattern/famous-cardano-pattern.hs+7 data/examples/declaration/value/function/pattern/multiline-case-pattern-out.hs+15 data/examples/declaration/value/function/pattern/multiline-case-pattern.hs+12 data/examples/declaration/value/function/pattern/n-plus-k-pattern-out.hs+1−1 data/examples/declaration/value/function/pattern/record-patterns-out.hs+4−4 data/examples/declaration/value/function/pattern/splice-pattern-out.hs+2−2 data/examples/declaration/value/function/pattern/view-pattern-out.hs+1−1 data/examples/declaration/value/function/record-constructors-out.hs+3−3 data/examples/declaration/value/function/record-updaters-out.hs+3−3 data/examples/declaration/value/function/record-wildcards-out.hs+5−5 data/examples/declaration/value/function/static-pointers-out.hs+6−6 data/examples/declaration/value/function/transform-comprehensions-out.hs+30−30 data/examples/declaration/value/function/tuple-sections-out.hs+1−2 data/examples/declaration/value/function/tuples-out.hs+4−4 data/examples/declaration/value/function/unboxed-sums-out.hs+1−1 data/examples/declaration/value/function/unboxed-tuples-out.hs+4−4 data/examples/declaration/value/other/line-multi-line-out.hs+4−4 data/examples/declaration/warning/warning-multiline-out.hs+5−5 data/examples/import/explicit-imports-out.hs+11−11 data/examples/import/explicit-imports-with-comments-out.hs+4−4 data/examples/import/misc-out.hs+8−8 data/examples/import/nested-explicit-imports-out.hs+9−9 data/examples/module-header/double-dot-with-names-out.hs+4−4 data/examples/module-header/multiline-out.hs+4−4 data/examples/module-header/multiline-with-comments-out.hs+11−11 data/examples/module-header/multiline2-out.hs+4−4 data/examples/module-header/warning-pragma-list-multiline-out.hs+7−7 data/examples/module-header/warning-pragma-multiline-out.hs+4−4 data/printer/list0-multi.hs+4−4 data/printer/list1-multi.hs+5−5 data/printer/mhdr-multi.hs+5−5 data/printer/ssig-multi.hs+1−1 src/Ormolu/Printer/Combinators.hs+33−79 src/Ormolu/Printer/Meat/Common.hs+2−2 src/Ormolu/Printer/Meat/Declaration/Class.hs+7−11 src/Ormolu/Printer/Meat/Declaration/Data.hs+18−18 src/Ormolu/Printer/Meat/Declaration/Default.hs+2−2 src/Ormolu/Printer/Meat/Declaration/Foreign.hs+1−1 src/Ormolu/Printer/Meat/Declaration/Instance.hs+25−23 src/Ormolu/Printer/Meat/Declaration/RoleAnnotation.hs+1−1 src/Ormolu/Printer/Meat/Declaration/Rule.hs+9−10 src/Ormolu/Printer/Meat/Declaration/Signature.hs+13−11 src/Ormolu/Printer/Meat/Declaration/Type.hs+1−1 src/Ormolu/Printer/Meat/Declaration/TypeFamily.hs+3−8 src/Ormolu/Printer/Meat/Declaration/Value.hs+46−45 src/Ormolu/Printer/Meat/Declaration/Warning.hs+4−9 src/Ormolu/Printer/Meat/ImportExport.hs+5−5 src/Ormolu/Printer/Meat/Module.hs+6−8 src/Ormolu/Printer/Meat/Type.hs+17−15 src/Ormolu/Utils.hs+2 tests/Ormolu/Printer/CombinatorsSpec.hs+18−16 tests/Ormolu/PrinterSpec.hs+1
data/examples/declaration/annotation/annotation-out.hs+1−1
@@ -4,7 +4,7 @@
44 module
55 ( 5
66 :: Int
7− )
7+ )
88 #-}
99
1010{-# ANN foo "hey" #-}
data/examples/declaration/class/default-signatures-out.hs+3−3
@@ -20,9 +20,9 @@ class Bar a where
2020
2121 -- Pointless comment
2222 default bar
23− :: ( Read a
24− , Semigroup a
25− )
23+ :: ( Read a,
24+ Semigroup a
25+ )
2626 => a
2727 -> a
2828 -> a
data/examples/declaration/class/dependency-super-classes-out.hs+3−3
@@ -9,9 +9,9 @@ class (MonadReader r s, MonadWriter w m) => MonadState s m | m -> s where
99
1010-- | 'MonadParsec'
1111class
12− ( Stream s -- Token streams
13− , MonadPlus m -- Potential for failure
14− )
12+ ( Stream s, -- Token streams
13+ MonadPlus m -- Potential for failure
14+ )
1515 => MonadParsec e s m
1616 | m -> e s where
1717
data/examples/declaration/class/functional-dependencies-out.hs+5−5
@@ -10,10 +10,10 @@ class Bar a b | a -> b, b -> a where
1010-- | Something else.
1111class
1212 Baz a b c d
13− | a b -> c d -- Foo
14− , b c -> a d -- Bar
15− , a c -> b d -- Baz
16− , a c d -> b
17− , a b d -> a b c d where
13+ | a b -> c d, -- Foo
14+ b c -> a d, -- Bar
15+ a c -> b d, -- Baz
16+ a c d -> b,
17+ a b d -> a b c d where
1818
1919 baz :: a -> b
data/examples/declaration/class/poly-kinded-classes-out.hs+1−1
@@ -6,4 +6,4 @@ class
66 Bar
77 ( a -- Variable
88 :: * -- Star
9− )
9+ )
data/examples/declaration/class/single-parameters-out.hs+3−3
@@ -13,9 +13,9 @@ class Baz a where
1313
1414 -- | Baz
1515 baz
16− :: ( a
17− , a -- ^ First argument
18− )
16+ :: ( a,
17+ a -- ^ First argument
18+ )
1919 -> a -- ^ Second argument
2020 -> a -- ^ Return value
2121
data/examples/declaration/class/super-classes-out.hs+4−4
@@ -7,8 +7,8 @@ class
77 => Baz a
88
99class
10− ( Foo a -- Foo?
11− , Bar a -- Bar?
12− , Baz a -- Baz
13− )
10+ ( Foo a, -- Foo?
11+ Bar a, -- Bar?
12+ Baz a -- Baz
13+ )
1414 => BarBar a
data/examples/declaration/class/type-operators-out.hs+2−2
@@ -17,7 +17,7 @@ class
1717class
1818 ( f :.
1919 g
20− )
20+ )
2121 a
2222
2323class a `Pair` b
@@ -31,5 +31,5 @@ class (f `Product` g) a
3131class
3232 ( f `Sum`
3333 g
34− )
34+ )
3535 a
data/examples/declaration/data/deriving-strategies-out.hs+3−3
@@ -2,9 +2,9 @@
22newtype Foo = Foo Int
33 deriving stock (Eq, Show, Generic)
44 deriving anyclass
5− ( ToJSON
6− , FromJSON
7− )
5+ ( ToJSON,
6+ FromJSON
7+ )
88 deriving newtype (Num)
99 deriving (Monoid) via (Sum Int)
1010 deriving
data/examples/declaration/data/gadt/multiple-declaration-out.hs+5−5
@@ -2,14 +2,14 @@ data GADT0 a where
22 GADT01, GADT02 :: Int -> GADT0 a
33
44data GADT1 a where
5− GADT11
6− , GADT12
5+ GADT11,
6+ GADT12
77 :: Int
88 -> GADT1 a
99
1010data GADT2 a where
11− GADT21
12− , GADT21
13− , GADT22
11+ GADT21,
12+ GADT21,
13+ GADT22
1414 :: Int
1515 -> GADT2 a
data/examples/declaration/data/gadt/record-out.hs+6−5
@@ -2,10 +2,11 @@
22data Foo where
33 Foo :: {fooX :: Int} -> Foo
44 Bar
5− :: { fooY :: Int
6− , fooBar, fooBaz :: Bool
7− , fooFoo
8− , barBar
5+ :: { fooY :: Int,
6+ fooBar, fooBaz :: Bool,
7+ fooFoo,
8+ barBar,
9+ bazBaz
910 :: Int
10− }
11+ }
1112 -> Foo
data/examples/declaration/data/gadt/record.hs+2−1
@@ -5,5 +5,6 @@ data Foo where
55 Bar :: { fooY :: Int
66 , fooBar, fooBaz :: Bool
77 , fooFoo
8− , barBar :: Int
8+ , barBar
9+ , bazBaz :: Int
910 } -> Foo
data/examples/declaration/data/multiline-names-out.hs+2−2
@@ -11,7 +11,7 @@ data (f :* g) a = f a :* g a
1111data
1212 ( f :+
1313 g
14− )
14+ )
1515 a
1616 = L (f a)
1717 | R (g a)
@@ -23,7 +23,7 @@ data (f `Product` g) a = f a `Product` g a
2323data
2424 ( f `Sum`
2525 g
26− )
26+ )
2727 a
2828 = L' (f a)
2929 | R' (g a)
data/examples/declaration/data/record-out.hs+9−9
@@ -1,18 +1,18 @@
11-- | Something.
22data Foo
33 = Foo
4− { fooX :: Int -- ^ X
5− , fooY :: Int -- ^ Y
6− , fooBar, fooBaz :: NonEmpty (Identity Bool) -- ^ BarBaz
7− , fooGag
8− , fooGog
4+ { fooX :: Int, -- ^ X
5+ fooY :: Int, -- ^ Y
6+ fooBar, fooBaz :: NonEmpty (Identity Bool), -- ^ BarBaz
7+ fooGag,
8+ fooGog
99 :: NonEmpty
1010 ( Indentity
1111 Bool
12− )
12+ ),
1313 -- ^ GagGog
14− , fooFoo
15− , barBar
14+ fooFoo,
15+ barBar
1616 :: Int -- ^ Huh!
17− }
17+ }
1818 deriving (Eq, Show)
data/examples/declaration/default/default-out.hs+4−4
@@ -1,7 +1,7 @@
11default (Int, Foo, Bar)
22
33default
4− ( Int
5− , Foo
6− , Bar
7− )
4+ ( Int,
5+ Foo,
6+ Bar
7+ )
data/examples/declaration/instance/contexts-out.hs+24−21
@@ -3,38 +3,41 @@ instance Eq a => Eq [a] where
33 (==) _ _ = False
44
55instance
6− ( Ord a
7− , Ord b
8− )
9− => Ord (a, b) where
6+ ( Ord a,
7+ Ord b
8+ )
9+ => Ord (a, b)
10+ where
1011
1112 compare _ _ = GT
1213
1314instance
1415 (Show a, Show b)
1516 => Show
16− ( a
17− , b
18− ) where
17+ ( a,
18+ b
19+ )
20+ where
1921
2022 showsPrec _ _ = showString ""
2123
2224instance
23− ( Read a -- Foo
24− , Read b
25− , Read
26− ( c
27− , -- Bar
28− d
29− )
30− )
25+ ( Read a, -- Foo
26+ Read b,
27+ Read
28+ ( c,
29+ -- Bar
30+ d
31+ )
32+ )
3133 => Read
32− ( a
33− , -- Baz
34− b
35− , ( c -- Quux
36− , d
34+ ( a,
35+ -- Baz
36+ b,
37+ ( c, -- Quux
38+ d
39+ )
3740 )
38− ) where
41+ where
3942
4043 readsPrec = undefined
data/examples/declaration/instance/data-family-instances-out.hs+7−7
@@ -7,17 +7,17 @@ data instance
77 Foo
88 [Int]
99 = IntListFoo
10− ( Int
11− , Int
12− )
13− ( Double
14− , Double
15− )
10+ ( Int,
11+ Int
12+ )
13+ ( Double,
14+ Double
15+ )
1616
1717newtype instance Foo [Double]
1818 = DoubleListFoo
1919 { unDoubleListFoo :: Double
20− }
20+ }
2121
2222data instance Bar Double a
2323 = DoubleBar
data/examples/declaration/instance/overlappable-instances-out.hs+2−1
@@ -13,6 +13,7 @@ instance {-# OVERLAPS #-} Eq Double where
1313instance
1414 {-# INCOHERENT #-}
1515 Ord
16− Double where
16+ Double
17+ where
1718
1819 compare _ _ = GT
data/examples/declaration/instance/type-family-instances-out.hs+6−6
@@ -5,9 +5,9 @@ type instance Foo Int = Int
55type instance
66 Foo
77 [Int] =
8− ( Int
9− , Int
10− )
8+ ( Int,
9+ Int
10+ )
1111
1212type instance Bar Int [Int] Double = (Int, Double)
1313
@@ -16,6 +16,6 @@ type instance
1616 [Int]
1717 [Int]
1818 Double =
19− ( Int
20− , Double
21− )
19+ ( Int,
20+ Double
21+ )
data/examples/declaration/rewrite-rule/type-signature-out.hs+1−1
@@ -10,7 +10,7 @@
1010 :: forall b. (a -> b -> b)
1111 -> b
1212 -> b
13− ).
13+ ).
1414 foldr k z (build g) =
1515 g k z
1616 #-}
data/examples/declaration/signature/complete/complete-out.hs+3−3
@@ -3,8 +3,8 @@
33{-# COMPLETE A, B #-}
44
55{-# COMPLETE
6− A
7− , B
8− , C
6+ A,
7+ B,
8+ C
99 :: Foo
1010 #-}
data/examples/declaration/signature/minimal/minimal-out.hs+4−4
@@ -5,10 +5,10 @@ class Foo a where
55 {-# MINIMAL
66 a
77 | ( b, c, d
8− | e
9− , f
10− )
11− | g
8+ | e,
9+ f
10+ )
11+ | g
1212 #-}
1313
1414 (==) :: a -> a -> Bool
data/examples/declaration/signature/specialize/specialize-instance-out.hs+1−1
@@ -12,7 +12,7 @@ instance (Num r, V.Vector v r, Factored m r) => Num (VT v m r) where
1212
1313 {-# SPECIALIZE instance
1414 ( Factored m Int => Num (VT U.Vector m Int)
15− )
15+ )
1616 #-}
1717
1818 VT x + VT y = VT $ V.zipWith (+) x y
data/examples/declaration/signature/specialize/specialize-out.hs+3−3
@@ -11,14 +11,14 @@ baz :: Num a => a -> a
1111baz = id
1212{-# SPECIALIZE [~2] baz
1313 :: Int
14− -> Int
14+ -> Int
1515 #-}
1616
1717{-# SPECIALIZE fits13Bits :: Int -> Bool, Integer -> Bool #-}
1818{-# SPECIALIZE fits13Bits
1919 :: Int
20− -> Bool
21− , Integer -> Bool
20+ -> Bool,
21+ Integer -> Bool
2222 #-}
2323fits13Bits :: Integral a => a -> Bool
2424fits13Bits x = x >= -4096 && x < 4096
data/examples/declaration/signature/type/arguments-out.hs+1−1
@@ -10,6 +10,6 @@ functionName
1010 -> AnotherLongDataTypeName
1111 -> b
1212 -> c
13− )
13+ )
1414 -> (c -> d)
1515 -> (a, b, c, d)
data/examples/declaration/signature/type/context-multi-line-out.hs+4−4
@@ -1,8 +1,8 @@
11functionName
2− :: ( C1
3− , C2
4− , C3
5− )
2+ :: ( C1,
3+ C2,
4+ C3
5+ )
66 => a
77 -> b
88 -> c
data/examples/declaration/signature/type/long-multiline-applications-out.hs+1−1
@@ -10,6 +10,6 @@ functionName
1010 -> AnotherLongDataTypeName4
1111 -> b
1212 -> c
13− )
13+ )
1414 -> (c -> d)
1515 -> (a, b, c, d)
data/examples/declaration/signature/type/multi-value-out.hs+3−3
@@ -1,6 +1,6 @@
11foo, bar :: Int
22
3−foo
4− , bar
5− , baz
3+foo,
4+ bar,
5+ baz
66 :: Int
data/examples/declaration/splice/typed-splice-out.hs+1−1
@@ -2,6 +2,6 @@
22
33x =
44 $$( foo bar
5− )
5+ )
66
77x = $$foo
data/examples/declaration/splice/untyped-splice-out.hs+1−1
@@ -5,6 +5,6 @@ x = $(foo bar)
55x =
66 $( foo
77 bar
8− )
8+ )
99
1010x = $foo
data/examples/declaration/value/function/arithmetic-sequences-out.hs+6−6
@@ -4,14 +4,14 @@ foo' = [0 .. 5]
44
55bar x =
66 [ 0
7− .. x
8− ]
7+ .. x
8+ ]
99
1010baz x =
11− [ 1
12− , 3
13− .. x
14− ]
11+ [ 1,
12+ 3
13+ .. x
14+ ]
1515
1616barbaz x = [0, 1 ..]
1717
data/examples/declaration/value/function/arrow/expression-forms-out.hs+3−3
@@ -6,8 +6,8 @@ bar f g x y =
66 (| test
77 ( f -<
88 x
9− )
9+ )
1010 ( g -<
1111 y
12− )
13− |)
12+ )
13+ |)
data/examples/declaration/value/function/arrow/proc-applications-out.hs+8−8
@@ -4,15 +4,15 @@ foo x = proc a -> a -< x
44
55bar f x =
66 proc
7− ( y
8− , z
9− , w
10− )
7+ ( y,
8+ z,
9+ w
10+ )
1111 ->
1212 f -< -- The value
13− ( x -- Foo
14− , w -- Bar
15− , z -- Baz
16− )
13+ ( x, -- Foo
14+ w, -- Bar
15+ z -- Baz
16+ )
1717
1818baz x = proc a -> a -<< x
data/examples/declaration/value/function/arrow/proc-cases-out.hs+3−3
@@ -5,9 +5,9 @@ foo f = proc a -> case a of Left b -> f -< b
55bar f g h j =
66 proc a -> case a of
77 Left
8− ( (a, b)
9− , (c, d)
10− ) -> f (a <> c) -< b <> d
8+ ( (a, b),
9+ (c, d)
10+ ) -> f (a <> c) -< b <> d
1111 Right
1212 (Left a) ->
1313 h -< a
data/examples/declaration/value/function/arrow/proc-do-complex-out.hs+19−19
@@ -6,37 +6,37 @@ foo
66 h
77 ma =
88 proc
9− ( (a, b)
10− , (c, d)
11− , (e, f)
12− )
9+ ( (a, b),
10+ (c, d),
11+ (e, f)
12+ )
1313 -> do
1414 -- Begin do
1515 (x, y) <- -- GHC parser fails if layed out over multiple lines
1616 f -- Call into f
17− ( a
18− , c -- Tuple together arguments
19− )
20− ( b
21− , d
22− ) -<
23− ( b + 1 -- Funnel into arrow
24− , d * b
25− )
17+ ( a,
18+ c -- Tuple together arguments
19+ )
20+ ( b,
21+ d
22+ ) -<
23+ ( b + 1, -- Funnel into arrow
24+ d * b
25+ )
2626 if x `mod` y == 0 -- Basic condition
2727 then
2828 case e of -- Only left case is relevant
2929 Left
30− ( z
31− , w
32− ) -> \u -> -- Procs can have lambdas
30+ ( z,
31+ w
32+ ) -> \u -> -- Procs can have lambdas
3333 let v =
3434 u ^ -- Actually never used
3535 2
3636 in ( returnA -<
3737 -- Just do the calculation
3838 (x + y * z)
39− )
39+ )
4040 else
4141 do
4242 let u = x -- Let bindings bind expressions, not commands
@@ -47,8 +47,8 @@ foo
4747 n ->
4848 ( ( h . g -<
4949 y -- First actual use of y
50+ )
5051 )
51− )
5252 returnA -< ()
5353 -- Sometimes execute effects
5454 if i > 0
@@ -58,4 +58,4 @@ foo
5858 ( i +
5959 x *
6060 y -- Just do the calculation
61− )
61+ )
data/examples/declaration/value/function/arrow/proc-do-simple-out.hs+4−4
@@ -28,9 +28,9 @@ bazbaz f g h = proc (a, b, c) -> do
2828 h
2929 x
3030 y -<
31− ( a
32− , b
33− , c
34− )
31+ ( a,
32+ b,
33+ c
34+ )
3535 returnA -<
3636 (x, y, z)
data/examples/declaration/value/function/arrow/proc-forms-out.hs+3−3
@@ -13,13 +13,13 @@ foo2 f g h x =
1313 h g -<
1414 y x .
1515 y z
16− )
16+ )
1717 ( h g .
1818 h f -<
1919 y z .
2020 y x
21− )
22− |)
21+ )
22+ |)
2323
2424bar0 f g x y = proc _ -> f -< x &&& g -< y
2525
data/examples/declaration/value/function/arrow/proc-parentheses-out.hs+5−5
@@ -4,15 +4,15 @@ foo f = proc a -> (f -< a)
44
55bar f g = proc a ->
66 ( ( (f)
7− ( g
8− )
9− ) -<
7+ ( g
8+ )
9+ ) -<
1010 ( ( ( ( ( ( g
11− a
11+ a
12+ )
1213 )
1314 )
1415 )
1516 )
1617 )
1718 )
18− )
data/examples/declaration/value/function/arrow/recursive-procs-out.hs+3−3
@@ -6,9 +6,9 @@ foo f g = proc (x, y) -> do
66 g x -<
77 y
88 bar -<
9− ( a
10− , b
11− )
9+ ( a,
10+ b
11+ )
1212 rec p <-
1313 f
1414 p -<
data/examples/declaration/value/function/do-single-multi-out.hsnew file+4
@@ -0,0 +1,4 @@
1+foo = do
2+ ( bar
3+ baz
4+ )
data/examples/declaration/value/function/do-single-multi.hsnew file+2
@@ -0,0 +1,2 @@
1+foo = do (bar
2+ baz)
data/examples/declaration/value/function/implicit-params-out.hs+3−3
@@ -7,9 +7,9 @@ sort = sortBy ?cmp
77
88sort'
99 :: ( ?cmp
10− :: a -> a -> Bool
11− , ?foo :: Int
12− )
10+ :: a -> a -> Bool,
11+ ?foo :: Int
12+ )
1313 => [a]
1414 -> [a]
1515sort' = sort
data/examples/declaration/value/function/list-comprehensions-out.hs+14−14
@@ -5,21 +5,21 @@ bar x y = [(a, b) | a <- x, even a, b <- y, a != b]
55barbaz x y z w =
66 [ (a, b, c, d) -- Foo
77 | a <-
8− x -- Bar
9− , b <- y -- Baz
10− , any even [a, b]
11− , c <-
8+ x, -- Bar
9+ b <- y, -- Baz
10+ any even [a, b],
11+ c <-
1212 z *
1313 z ^
14− 2 -- Bar baz
15− , d <-
14+ 2, -- Bar baz
15+ d <-
1616 w +
17− w -- Baz bar
18− , all
17+ w, -- Baz bar
18+ all
1919 even
20− [ a
21− , b
22− , c
23− , d
24− ]
25− ]
20+ [ a,
21+ b,
22+ c,
23+ d
24+ ]
25+ ]
data/examples/declaration/value/function/multiline-arguments-out.hs+1−1
@@ -4,5 +4,5 @@ foo
44 ( Bar
55 x
66 y
7− )
7+ )
88 z = x
data/examples/declaration/value/function/operator-sections-out.hs+2−2
@@ -5,9 +5,9 @@ bar = (<> "hello")
55baz =
66 ( 1 * 2
77 +
8− )
8+ )
99 ( *
1010 3 ^ 5
11− )
11+ )
1212
1313quux = (,) <$> foo <$> bar
data/examples/declaration/value/function/parallel-comprehensions-out.hs+29−29
@@ -3,35 +3,35 @@ foo x y = [(a, b) | a <- x | b <- y]
33bar x y z w = [(a, b, c, d) | a <- x, b <- y, a `mod` b == 0 | c <- z | d <- w]
44
55baz x y z w =
6− [ ( a
7− , b
8− , c
9− , d
10− , e
11− , f
12− , g
13− , h
14− , i
15− , j
16− )
6+ [ ( a,
7+ b,
8+ c,
9+ d,
10+ e,
11+ f,
12+ g,
13+ h,
14+ i,
15+ j
16+ )
1717 | a <- -- Foo 1
18− x -- Foo 2
19− , b <- -- Bar 1
20− y -- Bar 2
21− , a `mod`
18+ x, -- Foo 2
19+ b <- -- Bar 1
20+ y, -- Bar 2
21+ a `mod`
2222 b == -- Value
2323 0
24− | c <- -- Baz 1
25− z * -- Baz 2
26− z -- Baz 3
27− | d <- w -- Other
28− | e <- x * x -- Foo bar
29− | f <- -- Foo baz 1
30− y + y -- Foo baz 2
31− | h <- z + z * w ^ 2 -- Bar foo
32− | i <- -- Bar bar 1
33− a + -- Bar bar 2
34− b -- Bar bar 3
35− , j <- -- Bar baz 1
36− a + b -- Bar baz 2
37− ]
24+ | c <- -- Baz 1
25+ z * -- Baz 2
26+ z -- Baz 3
27+ | d <- w -- Other
28+ | e <- x * x -- Foo bar
29+ | f <- -- Foo baz 1
30+ y + y -- Foo baz 2
31+ | h <- z + z * w ^ 2 -- Bar foo
32+ | i <- -- Bar bar 1
33+ a + -- Bar bar 2
34+ b, -- Bar bar 3
35+ j <- -- Bar baz 1
36+ a + b -- Bar baz 2
37+ ]
data/examples/declaration/value/function/pattern/famous-cardano-pattern-out.hsnew file+8
@@ -0,0 +1,8 @@
1+( getNodeSettingsR :<|>
2+ getNodeInfoR :<|>
3+ getNextUpdateR :<|>
4+ restartNodeR
5+ ) :<|>
6+ ( getUtxoR :<|>
7+ getConfirmedProposalsR
8+ ) = client nodeV1Api
data/examples/declaration/value/function/pattern/famous-cardano-pattern.hsnew file+7
@@ -0,0 +1,7 @@
1+( getNodeSettingsR
2+ :<|> getNodeInfoR
3+ :<|> getNextUpdateR
4+ :<|> restartNodeR
5+ ):<|>( getUtxoR
6+ :<|> getConfirmedProposalsR
7+ ) = client nodeV1Api
data/examples/declaration/value/function/pattern/multiline-case-pattern-out.hsnew file+15
@@ -0,0 +1,15 @@
1+readerBench doc name =
2+ runPure $ case (getReader name, getWriter name) of
3+ ( Right (TextReader r, rexts),
4+ Right (TextWriter w, wexts)
5+ ) -> undefined
6+
7+f xs = case xs of
8+ [ a,
9+ b
10+ ] -> a + b
11+
12+g xs = case xs of
13+ ( a :
14+ bs
15+ ) -> a + b
data/examples/declaration/value/function/pattern/multiline-case-pattern.hsnew file+12
@@ -0,0 +1,12 @@
1+readerBench doc name =
2+ runPure $ case (getReader name, getWriter name) of
3+ (Right (TextReader r, rexts),
4+ Right (TextWriter w, wexts)) -> undefined
5+
6+f xs = case xs of
7+ [ a,
8+ b ] -> a + b
9+
10+g xs = case xs of
11+ (a:
12+ bs) -> a + b
data/examples/declaration/value/function/pattern/n-plus-k-pattern-out.hs+1−1
@@ -7,4 +7,4 @@ multiline :: Int
77multiline
88 ( n
99 + 1
10− ) = n
10+ ) = n
data/examples/declaration/value/function/pattern/record-patterns-out.hs+4−4
@@ -13,7 +13,7 @@ baz Boom {boom = b, ..} = b
1313quux :: Boom -> Int
1414quux
1515 Boom
16− { boom = a
17− , foom = b
18− , ..
19− } = a + b
16+ { boom = a,
17+ foom = b,
18+ ..
19+ } = a + b
data/examples/declaration/value/function/pattern/splice-pattern-out.hs+2−2
@@ -7,7 +7,7 @@ singleLine = case () of
77multiline = case () of
88 $( x +
99 y
10− ) -> ()
10+ ) -> ()
1111 $( y
1212 "something"
13− ) -> ()
13+ ) -> ()
data/examples/declaration/value/function/pattern/view-pattern-out.hs+1−1
@@ -12,4 +12,4 @@ multiline
1212 Foo
1313 bar
1414 baz
15− ) = True
15+ ) = True
data/examples/declaration/value/function/record-constructors-out.hs+3−3
@@ -1,8 +1,8 @@
11foo = Foo {a = 3}
22
33bar = Bar
4− { abc = foo
5− , def = Foo {a = 10}
6− }
4+ { abc = foo,
5+ def = Foo {a = 10}
6+ }
77
88baz = Baz {}
data/examples/declaration/value/function/record-updaters-out.hs+3−3
@@ -2,8 +2,8 @@ foo x = x {a = 3}
22
33bar x =
44 x
5− { abc = foo
6− , def = Foo {a = 10}
7− }
5+ { abc = foo,
6+ def = Foo {a = 10}
7+ }
88
99baz x = x {}
data/examples/declaration/value/function/record-wildcards-out.hs+5−5
@@ -4,10 +4,10 @@
44foo x y = Foo {x, y}
55
66bar x y z = Bar
7− { x
8− , y
9− , z
10− , ..
11− }
7+ { x,
8+ y,
9+ z,
10+ ..
11+ }
1212
1313baz = Baz {..}
data/examples/declaration/value/function/static-pointers-out.hs+6−6
@@ -6,14 +6,14 @@ foo = static 5
66bar :: StaticPtr [Int]
77bar =
88 static
9− [ 1
10− , 2
11− , 3
12− ]
9+ [ 1,
10+ 2,
11+ 3
12+ ]
1313
1414baz :: StaticPtr Bool
1515baz =
1616 static
1717 ( fun 1
18− 2
19− )
18+ 2
19+ )
data/examples/declaration/value/function/transform-comprehensions-out.hs+30−30
@@ -3,56 +3,56 @@
33foo xs ys = [(x, y) | x <- xs, y <- ys, then reverse]
44
55foo' xs ys =
6− [ ( x
7− , y
8− )
9− | x <- xs
10− , y <- ys
11− , -- First comment
6+ [ ( x,
7+ y
8+ )
9+ | x <- xs,
10+ y <- ys,
11+ -- First comment
1212 then reverse -- Second comment
13− ]
13+ ]
1414
1515bar xs ys = [(x, y) | x <- xs, y <- ys, then sortWith by (x + y)]
1616
1717bar' xs ys =
18− [ ( x
19− , y
20− )
21− | x <- xs
22− , y <- ys
23− , -- First comment
18+ [ ( x,
19+ y
20+ )
21+ | x <- xs,
22+ y <- ys,
23+ -- First comment
2424 then sortWith
2525 by
2626 ( x +
2727 y -- Second comment
28− )
29− ]
28+ )
29+ ]
3030
3131baz xs ys = [(x, y) | x <- xs, y <- ys, then group using permutations]
3232
3333baz' xs ys =
34− [ ( x
35− , y
36− )
37− | x <- xs
38− , y <- ys
39− , -- First comment
34+ [ ( x,
35+ y
36+ )
37+ | x <- xs,
38+ y <- ys,
39+ -- First comment
4040 then group using permutations -- Second comment
41− ]
41+ ]
4242
4343quux xs ys = [(x, y) | x <- xs, y <- ys, then group by (x + y) using groupWith]
4444
4545quux' xs ys =
46− [ ( x
47− , y
48− )
49− | x <- xs
50− , y <- ys
51− , -- First comment
46+ [ ( x,
47+ y
48+ )
49+ | x <- xs,
50+ y <- ys,
51+ -- First comment
5252 then group by
5353 ( x +
5454 y
55− )
55+ )
5656 -- Second comment
5757 using groupWith -- Third comment
58− ]
58+ ]
data/examples/declaration/value/function/tuple-sections-out.hs+1−2
@@ -5,5 +5,4 @@ foo = (,2)
55bar = (,5,)
66
77baz =
8− ( ,,5,6,7,,,
9− )
8+ (,,5,6,7,,,)
data/examples/declaration/value/function/tuples-out.hs+4−4
@@ -1,7 +1,7 @@
11foo = (1, 2, 3)
22
33bar =
4− ( 1
5− , 2
6− , 3
7− )
4+ ( 1,
5+ 2,
6+ 3
7+ )
data/examples/declaration/value/function/unboxed-sums-out.hs+1−1
@@ -6,4 +6,4 @@ bar = (# | | 2 | #)
66
77baz =
88 (# | | | 10 | | | | |
9− #)
9+ #)
data/examples/declaration/value/function/unboxed-tuples-out.hs+4−4
@@ -3,7 +3,7 @@
33foo = (# 1, 2, 3 #)
44
55bar =
6− (# 1
7− , 2
8− , 3
9− #)
6+ (# 1,
7+ 2,
8+ 3
9+ #)
data/examples/declaration/value/other/line-multi-line-out.hs+4−4
@@ -1,6 +1,6 @@
11x :: [Int]
22x =
3− [ 1
4− , 2
5− , somethingSomething 3
6− ]
3+ [ 1,
4+ 2,
5+ somethingSomething 3
6+ ]
data/examples/declaration/warning/warning-multiline-out.hs+5−5
@@ -1,9 +1,9 @@
11{-# WARNING
2− test
3− , foo
4− [ "These are bad functions"
5− , "Really bad!"
6− ]
2+ test,
3+ foo
4+ [ "These are bad functions",
5+ "Really bad!"
6+ ]
77 #-}
88test :: IO ()
99test = pure ()
data/examples/import/explicit-imports-out.hs+11−11
@@ -1,12 +1,12 @@
11import qualified MegaModule as M
2− ( (<<<)
3− , (>>>)
4− , Either
5− , Maybe (Just, Nothing)
6− , MaybeT (..)
7− , Monad ((>>), (>>=), return)
8− , MonadBaseControl
9− , join
10− , liftIO
11− , void
12− )
2+ ( (<<<),
3+ (>>>),
4+ Either,
5+ Maybe (Just, Nothing),
6+ MaybeT (..),
7+ Monad ((>>), (>>=), return),
8+ MonadBaseControl,
9+ join,
10+ liftIO,
11+ void
12+ )
data/examples/import/explicit-imports-with-comments-out.hs+4−4
@@ -1,6 +1,6 @@
11import qualified MegaModule as M
22 ( -- (1)
3− (<<<) -- (2)
4− , (>>>)
5− , Either -- (3)
6− )
3+ (<<<), -- (2)
4+ (>>>),
5+ Either -- (3)
6+ )
data/examples/import/misc-out.hs+8−8
@@ -1,11 +1,11 @@
11import A hiding
2− ( foobarbazqux
3− , foobarbazqux
4− , foobarbazqux
5− , foobarbazqux
6− , foobarbazqux
7− , foobarbazqux
8− , foobarbazqux
9− )
2+ ( foobarbazqux,
3+ foobarbazqux,
4+ foobarbazqux,
5+ foobarbazqux,
6+ foobarbazqux,
7+ foobarbazqux,
8+ foobarbazqux
9+ )
1010import {-# SOURCE #-} safe qualified Module as M hiding (a, b, c, d, e, f)
1111import Name hiding ()
data/examples/import/nested-explicit-imports-out.hs+9−9
@@ -1,10 +1,10 @@
11import qualified MegaModule as M
2− ( (<<<)
3− , (>>>)
4− , Either
5− , Monad
6− ( (>>)
7− , (>>=)
8− , return
9− )
10− )
2+ ( (<<<),
3+ (>>>),
4+ Either,
5+ Monad
6+ ( (>>),
7+ (>>=),
8+ return
9+ )
10+ )
data/examples/module-header/double-dot-with-names-out.hs+4−4
@@ -1,10 +1,10 @@
11{-# LANGUAGE PatternSynonyms #-}
22
33module ExportSyntax
4− ( A (.., NoA)
5− , Q (F, ..)
6− , G (T, .., U)
7− )
4+ ( A (.., NoA),
5+ Q (F, ..),
6+ G (T, .., U)
7+ )
88where
99
1010data A = A | B
data/examples/module-header/multiline-out.hs+4−4
@@ -1,6 +1,6 @@
11module Foo
2− ( foo
3− , bar
4− , baz
5− )
2+ ( foo,
3+ bar,
4+ baz
5+ )
66where
data/examples/module-header/multiline-with-comments-out.hs+11−11
@@ -4,18 +4,18 @@
44-- | Header.
55module My.Module
66 ( -- * Something
7− foo
8− , bar
9− , -- * Another thing
10− (<?>)
11− , {- some other thing -} foo2 -- yet another
12− , foo3 -- third one
13− , baz
14− , bar2 -- a multiline comment
7+ foo,
8+ bar,
9+ -- * Another thing
10+ (<?>),
11+ {- some other thing -} foo2, -- yet another
12+ foo3, -- third one
13+ baz,
14+ bar2, -- a multiline comment
1515 -- the second line
16− , bar3
17− , module Foo.Bar.Baz
18− )
16+ bar3,
17+ module Foo.Bar.Baz
18+ )
1919where
2020
2121-- Wow
data/examples/module-header/multiline2-out.hs+4−4
@@ -1,6 +1,6 @@
11module Foo
2− ( foo
3− , bar
4− , baz
5− )
2+ ( foo,
3+ bar,
4+ baz
5+ )
66where
data/examples/module-header/warning-pragma-list-multiline-out.hs+7−7
@@ -1,11 +1,11 @@
11module Test
22 {-# DEPRECATED
3− [ "This module is deprecated."
4− , "Please use OtherModule instead."
5− ]
3+ [ "This module is deprecated.",
4+ "Please use OtherModule instead."
5+ ]
66 #-}
7− ( foo
8− , bar
9− , baz
10− )
7+ ( foo,
8+ bar,
9+ baz
10+ )
1111where
data/examples/module-header/warning-pragma-multiline-out.hs+4−4
@@ -1,8 +1,8 @@
11module Test {-# DEPRECATED "This module is unstable" #-}
2− ( foo
3− , bar
4− , baz
5− )
2+ ( foo,
3+ bar,
4+ baz
5+ )
66where
77
88import Blah
data/printer/list0-multi.hs+4−4
@@ -1,4 +1,4 @@
1−[ foo
2−, bar
3−, baz
4−]
1+[ foo,
2+ bar,
3+ baz
4+ ]
data/printer/list1-multi.hs+5−5
@@ -1,8 +1,8 @@
1−[ foo
2−, bar
3−, foo
1+[ foo,
2+ bar,
3+ foo
44 :: ( Int
55 -> Int
6− )
6+ )
77 -> Bool
8−]
8+ ]
data/printer/mhdr-multi.hs+5−5
@@ -1,7 +1,7 @@
11module MyModule
2− ( R
3− , runR
4− , txt
5− , blah
6− )
2+ ( R,
3+ runR,
4+ txt,
5+ blah
6+ )
77where
data/printer/ssig-multi.hs+1−1
@@ -1,5 +1,5 @@
11foo
22 :: ( Int
33 -> Int
4− )
4+ )
55 -> Bool
src/Ormolu/Printer/Combinators.hs+33−79
@@ -17,18 +17,13 @@ module Ormolu.Printer.Combinators
1717 , newline
1818 , inci
1919 , located
20− , locatedVia
2120 , located'
2221 , switchLayout
2322 , vlayout
2423 , breakpoint
2524 , breakpoint'
2625 -- ** Formatting lists
27− , velt
28− , velt'
29− , withSep
30− , spaceSep
31− , newlineSep
26+ , sep
3227 -- ** Wrapping
3328 , sitcc
3429 , line
@@ -85,18 +80,7 @@ located
8580 => Located a -- ^ Thing to enter
8681 -> (a -> R ()) -- ^ How to render inner value
8782 -> R ()
88−located loc@(L l _) = locatedVia (Just l) loc
89−
90−-- | A special version of 'located' that allows to control layout using an
91−-- externally provided span. 'Nothing' means that layout won't be changed.
92−
93−locatedVia
94− :: Data a
95− => Maybe SrcSpan -- ^ Span that controls layout selection
96− -> Located a -- ^ Thing to enter
97− -> (a -> R ()) -- ^ How to render inner value
98− -> R ()
99−locatedVia ml loc f = do
83+located loc f = do
10084 let withRealLocated (L l a) g =
10185 case l of
10286 UnhelpfulSpan _ -> return ()
@@ -109,9 +93,7 @@ locatedVia ml loc f = do
10993 if isModule (unLoc loc)
11094 then id
11195 else withEnclosingSpan orf
112− setEnclosingSpan $ case ml of
113− Nothing -> f (unLoc loc)
114− Just l' -> switchLayout l' (f (unLoc loc))
96+ setEnclosingSpan $ switchLayout [getLoc loc] (f (unLoc loc))
11597 withRealLocated loc spitFollowingComments
11698
11799-- | A version of 'located' with arguments flipped.
@@ -123,19 +105,28 @@ located'
123105 -> R ()
124106located' = flip located
125107
126−-- | Set layout according to given 'SrcSpan' for a given computation. Use
127−-- this only when you need to set layout based on e.g. combined span of
108+-- | Set layout according to combination of given 'SrcSpan's for a given.
109+-- Use this only when you need to set layout based on e.g. combined span of
128110-- several elements when there is no corresponding 'Located' wrapper
129111-- provided by GHC AST. It is relatively rare that this one is needed.
112+--
113+-- Given empty list this function will set layout to single line.
130114
131115switchLayout
132− :: SrcSpan -- ^ Span that controls layout
116+ :: [SrcSpan] -- ^ Span that controls layout
133117 -> R () -- ^ Computation to run with changed layout
134118 -> R ()
135−switchLayout spn = enterLayout
136− (if isOneLineSpan spn
137− then SingleLine
138− else MultiLine)
119+switchLayout spans' = enterLayout (spansLayout spans')
120+
121+-- | Which layout combined spans result in?
122+
123+spansLayout :: [SrcSpan] -> Layout
124+spansLayout = \case
125+ [] -> SingleLine
126+ (x:xs) ->
127+ if isOneLineSpan (foldr combineSrcSpans x xs)
128+ then SingleLine
129+ else MultiLine
139130
140131-- | Insert a space if enclosing layout is single-line, or newline if it's
141132-- multiline.
@@ -156,56 +147,14 @@ breakpoint' = vlayout (return ()) newline
156147----------------------------------------------------------------------------
157148-- Formatting lists
158149
159−-- | Element of variable layout. This means that the sub-components may be
160−-- rendered either on single line or each on its own line depending on
161−-- current layout.
162−--
163−-- This version does not make subsequent element (second and later) align
164−-- with the first automatically and does not insert spaces between elements
165−-- when layout is single line.
166−
167−velt :: [R ()] -> R ()
168−velt xs = sequence_ (intersperse breakpoint' (sitcc <$> xs))
169−
170−-- | Like 'velt', but all sub-elements start at the same indentation level
171−-- as first element, additionally spaces are inserted when layout is single
172−-- line.
173−
174−velt' :: [R ()] -> R ()
175−velt' xs = sitcc $ sequence_ (intersperse breakpoint (sitcc <$> xs))
150+-- | Render a collection of elements inserting a separator between them.
176151
177−-- | Put separator between renderings of items of a list.
178−
179−withSep
152+sep
180153 :: R () -- ^ Separator
181− -> (a -> R ()) -- ^ How to render list items
182− -> [a] -- ^ List to render
183− -> [R ()] -- ^ List of printing actions
184−withSep sep f = \case
185− [] -> []
186− (x:xs) ->
187− let g a = sep >> f a
188− in f x : fmap g xs
189−
190−-- | Render space-separated elements.
191−--
192−-- > spaceSep f = sequence_ . withSep space f
193−
194−spaceSep
195− :: (a -> R ()) -- ^ How to render list items
196− -> [a] -- ^ List to render
154+ -> (a -> R ()) -- ^ How to render an element
155+ -> [a] -- ^ Elements to render
197156 -> R ()
198−spaceSep f = sequence_ . withSep space f
199−
200−-- | Render newline-separated elements.
201−--
202−-- > newlineSep f = sequence_ . withSep newline f
203−
204−newlineSep
205− :: (a -> R ()) -- ^ How to render list items
206− -> [a] -- ^ List to render
207− -> R ()
208−newlineSep f = sequence_ . withSep newline f
157+sep s f xs = sequence_ (intersperse s (f <$> xs))
209158
210159----------------------------------------------------------------------------
211160-- Wrapping
@@ -259,6 +208,7 @@ bracketsPar :: R () -> R ()
259208bracketsPar m = sitcc $ do
260209 txt "[: "
261210 m
211+ vlayout (return ()) space
262212 txt " :]"
263213
264214-- | Surround given entity by parentheses @(@ and @)@.
@@ -275,7 +225,7 @@ parensHash :: R () -> R ()
275225parensHash m = sitcc $ do
276226 txt "(# "
277227 m
278− breakpoint
228+ vlayout space (newline >> txt " ")
279229 txt "#)"
280230
281231-- | Braces as used for pragmas: @{-#@ and @#-}@.
@@ -302,15 +252,19 @@ pragma pragmaText body = pragmaBraces $ do
302252-- current layout is multiline.
303253
304254ospaces :: R () -> R ()
305−ospaces m = vlayout m (txt " " >> m >> newline)
255+ospaces m = vlayout m $ do
256+ space
257+ m
258+ newline
259+ txt " "
306260
307261----------------------------------------------------------------------------
308262-- Literals
309263
310−-- | Print @,@ followed by a space.
264+-- | Print @,@.
311265
312266comma :: R ()
313−comma = txt ", "
267+comma = txt ","
314268
315269-- | Print single space.
316270
src/Ormolu/Printer/Meat/Common.hs+2−2
@@ -130,9 +130,9 @@ p_infixDefHelper isInfix inci' name args =
130130 inci' p1
131131 unless (null ps) . inci' $ do
132132 breakpoint
133− velt' ps
133+ sitcc (sep breakpoint sitcc ps)
134134 (_, ps) -> do
135135 name
136136 unless (null ps) $ do
137137 breakpoint
138− inci' (velt' args)
138+ inci' $ sitcc (sep breakpoint sitcc args)
src/Ormolu/Printer/Meat/Declaration/Class.hs+7−11
@@ -21,7 +21,6 @@ import Ormolu.Printer.Meat.Common
2121import Ormolu.Printer.Meat.Type
2222import Ormolu.Utils
2323import RdrName (RdrName (..))
24−import SrcLoc (Located, combineSrcSpans)
2524import {-# SOURCE #-} Ormolu.Printer.Meat.Declaration
2625
2726p_classDecl
@@ -37,13 +36,10 @@ p_classDecl
3736 -> R ()
3837p_classDecl ctx name tvars fixity fdeps csigs cdefs cats catdefs = do
3938 let HsQTvs {..} = tvars
40− variableSpans = foldr (combineSrcSpans . getLoc) noSrcSpan hsq_explicit
41− signatureSpans = getLoc name `combineSrcSpans` variableSpans
42− dependencySpans = foldr (combineSrcSpans . getLoc) noSrcSpan fdeps
43− combinedSpans =
44− getLoc ctx `combineSrcSpans`
45− signatureSpans `combineSrcSpans`
46− dependencySpans
39+ variableSpans = getLoc <$> hsq_explicit
40+ signatureSpans = getLoc name : variableSpans
41+ dependencySpans = getLoc <$> fdeps
42+ combinedSpans = getLoc ctx : (signatureSpans ++ dependencySpans)
4743 txt "class"
4844 switchLayout combinedSpans $ do
4945 breakpoint
@@ -86,13 +82,13 @@ p_classFundeps :: [Located (FunDep (Located RdrName))] -> R ()
8682p_classFundeps fdeps = unless (null fdeps) $ do
8783 breakpoint
8884 txt "| "
89− velt $ withSep comma (located' p_funDep) fdeps
85+ sitcc $ sep (comma >> breakpoint) (sitcc . located' p_funDep) fdeps
9086
9187p_funDep :: FunDep (Located RdrName) -> R ()
9288p_funDep (before, after) = do
93− spaceSep p_rdrName before
89+ sep space p_rdrName before
9490 txt " -> "
95− spaceSep p_rdrName after
91+ sep space p_rdrName after
9692
9793----------------------------------------------------------------------------
9894-- Helpers
src/Ormolu/Printer/Meat/Declaration/Data.hs+18−18
@@ -10,7 +10,6 @@ module Ormolu.Printer.Meat.Declaration.Data
1010where
1111
1212import Control.Monad
13−import Data.List.NonEmpty (NonEmpty (..))
1413import Data.Maybe (isJust)
1514import GHC
1615import Ormolu.Printer.Combinators
@@ -28,14 +27,13 @@ p_dataDecl
2827 -> HsDataDefn GhcPs -- ^ Data definition
2928 -> R ()
3029p_dataDecl style name tpats fixity HsDataDefn {..} = do
31− let combinedSpans = combineSrcSpans' (getLoc name :| (getLoc <$> tpats))
3230 txt $ case dd_ND of
3331 NewType -> "newtype"
3432 DataType -> "data"
3533 txt $ case style of
3634 Associated -> mempty
3735 Free -> " instance"
38− switchLayout combinedSpans $ do
36+ switchLayout (getLoc name : fmap getLoc tpats) $ do
3937 breakpoint
4038 inci $ p_infixDefHelper
4139 (isInfix fixity)
@@ -54,13 +52,13 @@ p_dataDecl style name tpats fixity HsDataDefn {..} = do
5452 then do
5553 txt " where"
5654 newline
57− inci $ newlineSep (sitcc . located' p_conDecl) dd_cons
58− else switchLayout (combineSrcSpans' (getLoc name :| (getLoc <$> dd_cons))) $
55+ inci . sitcc $ sep newline (sitcc . located' p_conDecl) dd_cons
56+ else switchLayout (getLoc name : (getLoc <$> dd_cons)) $
5957 inci $ do
6058 breakpoint
6159 txt "= "
62− let sep = vlayout (txt " | ") (txt "| ")
63− velt $ withSep sep (sitcc . located' p_conDecl) dd_cons
60+ let s = vlayout (txt " | ") (newline >> txt "| ")
61+ sep s (sitcc . located' p_conDecl) dd_cons
6462 newline
6563 inci . located dd_derivs $ \xs ->
6664 forM_ xs (line . located' p_hsDerivingClause)
@@ -73,11 +71,10 @@ p_conDecl = \case
7371 [] -> return ()
7472 (c:cs) -> do
7573 p_rdrName c
76− unless (null cs) $ do
77− breakpoint'
78− inci $ do
79− comma
80− velt $ withSep comma p_rdrName cs
74+ unless (null cs) . inci $ do
75+ comma
76+ breakpoint
77+ sitcc $ sep (comma >> breakpoint) p_rdrName cs
8178 breakpoint
8279 inci $ do
8380 txt ":: "
@@ -85,7 +82,7 @@ p_conDecl = \case
8582 forM_ con_mb_cxt p_lhsContext
8683 case con_args of
8784 PrefixCon xs -> do
88− velt' (located' p_hsType <$> xs)
85+ sep breakpoint (located' p_hsType) xs
8986 unless (null xs) $ do
9087 breakpoint
9188 txt "-> "
@@ -95,7 +92,7 @@ p_conDecl = \case
9592 breakpoint
9693 txt "-> "
9794 InfixCon _ _ -> notImplemented "InfixCon"
98− locatedVia Nothing con_res_ty p_hsType
95+ p_hsType (unLoc con_res_ty)
9996 ConDeclH98 {..} -> do
10097 p_forallBndrs con_ex_tvs
10198 forM_ con_mb_cxt p_lhsContext
@@ -103,7 +100,7 @@ p_conDecl = \case
103100 PrefixCon xs -> do
104101 p_rdrName con_name
105102 unless (null xs) breakpoint
106− inci $ velt' (located' p_hsType <$> xs)
103+ inci . sitcc $ sep breakpoint (sitcc . located' p_hsType) xs
107104 RecCon l -> do
108105 p_rdrName con_name
109106 breakpoint
@@ -124,7 +121,7 @@ p_forallBndrs = \case
124121 [] -> return ()
125122 bndrs -> do
126123 txt "forall "
127− spaceSep (located' p_hsTyVarBndr) bndrs
124+ sep space (located' p_hsTyVarBndr) bndrs
128125 txt ". "
129126
130127p_lhsContext
@@ -150,12 +147,15 @@ p_hsDerivingClause HsDerivingClause {..} = do
150147 txt "deriving"
151148 let derivingWhat = located deriv_clause_tys $ \case
152149 [] -> txt "()"
153− xs -> parens . velt $ withSep comma (located' p_hsType . hsib_body) xs
150+ xs -> parens . sitcc $ sep
151+ (comma >> breakpoint)
152+ (sitcc . located' p_hsType . hsib_body)
153+ xs
154154 case deriv_clause_strategy of
155155 Nothing -> do
156156 breakpoint
157157 inci derivingWhat
158− Just l -> locatedVia Nothing l $ \case
158+ Just (L _ a) -> case a of
159159 StockStrategy -> do
160160 txt " stock"
161161 breakpoint
src/Ormolu/Printer/Meat/Declaration/Default.hs+2−2
@@ -16,6 +16,6 @@ p_defaultDecl = \case
1616 DefaultDecl NoExt ts -> line $ do
1717 txt "default"
1818 breakpoint
19− inci . parens . velt $
20− withSep comma (located' p_hsType) ts
19+ inci . parens . sitcc $
20+ sep (comma >> breakpoint) (sitcc . located' p_hsType) ts
2121 XDefaultDecl {} -> notImplemented "XDefaultDecl"
src/Ormolu/Printer/Meat/Declaration/Foreign.hs+1−1
@@ -35,7 +35,7 @@ p_foreignTypeSig fd = do
3535 breakpoint
3636 -- Switch into the layout of the signature, to allow us to pull name and
3737 -- signature onto a single line.
38− inci . switchLayout (getLoc . hsib_body $ fd_sig_ty fd) $ do
38+ inci . switchLayout [getLoc . hsib_body $ fd_sig_ty fd] $ do
3939 p_rdrName (fd_name fd)
4040 p_typeAscription (HsWC NoExt (fd_sig_ty fd))
4141
src/Ormolu/Printer/Meat/Declaration/Instance.hs+25−23
@@ -41,7 +41,7 @@ p_standaloneDerivDecl DerivDecl {..} = do
4141 Nothing -> do
4242 space
4343 instTypes False
44− Just l -> locatedVia Nothing l $ \case
44+ Just (L _ a) -> case a of
4545 StockStrategy -> do
4646 txt " stock "
4747 instTypes False
@@ -72,29 +72,31 @@ p_clsInstDecl = \case
7272 inci $ do
7373 match_overlap_mode cid_overlap_mode breakpoint
7474 p_hsType x
75+ -- GHC's AST does not necessarily store each kind of element in source
76+ -- location order. This happens because different declarations are stored in
77+ -- different lists. Consequently, to get all the declarations in proper
78+ -- order, they need to be manually sorted.
79+ let sigs = (getLoc &&& fmap (SigD NoExt)) <$> cid_sigs
80+ vals = (getLoc &&& fmap (ValD NoExt)) <$> toList cid_binds
81+ tyFamInsts =
82+ ( getLoc &&& fmap (InstD NoExt . TyFamInstD NoExt)
83+ ) <$> cid_tyfam_insts
84+ dataFamInsts =
85+ ( getLoc &&& fmap (InstD NoExt . DataFamInstD NoExt)
86+ ) <$> cid_datafam_insts
87+ allDecls =
88+ snd <$>
89+ sortBy (comparing fst) (sigs <> vals <> tyFamInsts <> dataFamInsts)
90+ if null allDecls
91+ then newline
92+ else do
93+ switchLayout [getLoc hsib_body] breakpoint
94+ inci $ do
95+ txt "where"
96+ newline -- Ensure line is added after where clause.
97+ newline -- Add newline before first declaration.
98+ p_hsDecls Associated allDecls
7599 XHsImplicitBndrs NoExt -> notImplemented "XHsImplicitBndrs"
76− -- GHC's AST does not necessarily store each kind of element in source
77− -- location order. This happens because different declarations are stored in
78− -- different lists. Consequently, to get all the declarations in proper
79− -- order, they need to be manually sorted.
80− let sigs = (getLoc &&& fmap (SigD NoExt)) <$> cid_sigs
81− vals = (getLoc &&& fmap (ValD NoExt)) <$> toList cid_binds
82− tyFamInsts =
83− ( getLoc &&& fmap (InstD NoExt . TyFamInstD NoExt)
84− ) <$> cid_tyfam_insts
85− dataFamInsts =
86− ( getLoc &&& fmap (InstD NoExt . DataFamInstD NoExt)
87− ) <$> cid_datafam_insts
88− allDecls =
89− snd <$>
90− sortBy (comparing fst) (sigs <> vals <> tyFamInsts <> dataFamInsts)
91− if not (null allDecls)
92− then do
93− txt " where"
94− newline -- Ensure line is added after where clause.
95− newline -- Add newline before first declaration.
96− inci (p_hsDecls Associated allDecls)
97− else newline
98100 XClsInstDecl NoExt -> notImplemented "XClsInstDecl"
99101
100102p_tyFamInstDecl :: FamilyStyle -> TyFamInstDecl GhcPs -> R ()
src/Ormolu/Printer/Meat/Declaration/RoleAnnotation.hs+1−1
@@ -32,7 +32,7 @@ p_roleAnnot' l_name anns = line $ do
3232 breakpoint
3333 let
3434 p_role' = maybe (txt "_") p_role
35− inci $ velt' $ (located' p_role') <$> anns
35+ inci . sitcc $ sep breakpoint (sitcc . located' p_role') anns
3636
3737p_role :: Role -> R ()
3838p_role = \case
src/Ormolu/Printer/Meat/Declaration/Rule.hs+9−10
@@ -16,13 +16,12 @@ import Ormolu.Printer.Meat.Common
1616import Ormolu.Printer.Meat.Declaration.Signature
1717import Ormolu.Printer.Meat.Declaration.Value
1818import Ormolu.Utils
19−import qualified Data.List.NonEmpty as NE
2019import qualified Data.Text as T
2120
2221p_ruleDecls :: RuleDecls GhcPs -> R ()
2322p_ruleDecls = \case
24− HsRules NoExt _ xs -> line $ pragma "RULES" $
25− velt' $ (located' p_ruleDecl) <$> xs
23+ HsRules NoExt _ xs -> line . pragma "RULES" . sitcc $
24+ sep breakpoint (sitcc . located' p_ruleDecl) xs
2625 XRuleDecls NoExt -> notImplemented "XRuleDecls"
2726
2827p_ruleDecl :: RuleDecl GhcPs -> R ()
@@ -50,14 +49,14 @@ p_ruleName (_, name) = do
5049 txt "\""
5150
5251p_ruleBndrs :: [LRuleBndr GhcPs] -> R ()
52+p_ruleBndrs [] = return ()
5353p_ruleBndrs bndrs =
54− forM_ (NE.nonEmpty bndrs) $ \bndrs_ne ->
55− switchLayout (combineSrcSpans' (getLoc <$> bndrs_ne)) $ do
56− txt "forall"
57− breakpoint
58− inci $ do
59− velt' (located' p_ruleBndr <$> bndrs)
60− txt "."
54+ switchLayout (getLoc <$> bndrs) $ do
55+ txt "forall"
56+ breakpoint
57+ inci $ do
58+ sitcc $ sep breakpoint (sitcc . located' p_ruleBndr) bndrs
59+ txt "."
6160
6261p_ruleBndr :: RuleBndr GhcPs -> R ()
6362p_ruleBndr = \case
src/Ormolu/Printer/Meat/Declaration/Signature.hs+13−11
@@ -49,9 +49,9 @@ p_typeSig (n:ns) hswc = do
4949 if null ns
5050 then p_typeAscription hswc
5151 else inci $ do
52− vlayout (return ()) newline
5352 comma
54− velt (withSep comma p_rdrName ns)
53+ breakpoint
54+ sep (comma >> breakpoint) p_rdrName ns
5555 p_typeAscription hswc
5656
5757p_typeAscription
@@ -93,7 +93,7 @@ p_fixSig = \case
9393 space
9494 atom n
9595 space
96− sequence_ (withSep comma p_rdrName names)
96+ sitcc $ sep (comma >> breakpoint) p_rdrName names
9797 XFixitySig NoExt -> notImplemented "XFixitySig"
9898
9999p_inlineSig
@@ -125,7 +125,7 @@ p_specSig name ts InlinePragma {..} = pragmaBraces $ do
125125 breakpoint
126126 inci $ do
127127 txt ":: "
128− velt (withSep comma (located' p_hsType) (hsib_body <$> ts))
128+ sep (comma >> breakpoint) (located' p_hsType . hsib_body) ts
129129
130130p_activation :: Activation -> R ()
131131p_activation = \case
@@ -162,12 +162,14 @@ p_booleanFormula
162162 -> R ()
163163p_booleanFormula = \case
164164 Var name -> p_rdrName name
165− And xs -> velt $
166− withSep comma (located' p_booleanFormula) xs
167− Or xs -> velt $
168− withSep (vlayout space (return ()) >> txt "| ")
169− (located' p_booleanFormula)
170− xs
165+ And xs -> sitcc $ sep
166+ (comma >> breakpoint)
167+ (located' p_booleanFormula)
168+ xs
169+ Or xs -> sitcc $ sep
170+ (breakpoint >> txt "| ")
171+ (located' p_booleanFormula)
172+ xs
171173 Parens l -> located l (parens . p_booleanFormula)
172174
173175p_completeSig
@@ -177,7 +179,7 @@ p_completeSig
177179p_completeSig cs' mty =
178180 located cs' $ \cs ->
179181 pragma "COMPLETE" . inci $ do
180− velt (withSep comma p_rdrName cs)
182+ sitcc $ sep (comma >> breakpoint) p_rdrName cs
181183 forM_ mty $ \ty -> do
182184 breakpoint
183185 inci $ do
src/Ormolu/Printer/Meat/Declaration/Type.hs+1−1
@@ -26,6 +26,6 @@ p_synDecl name tvars t = line $ do
2626 p_rdrName name
2727 let HsQTvs {..} = tvars
2828 unless (null hsq_explicit) space
29− spaceSep (located' p_hsTyVarBndr) hsq_explicit
29+ sep space (located' p_hsTyVarBndr) hsq_explicit
3030 breakpoint
3131 inci (txt "= " >> located t p_hsType)
src/Ormolu/Printer/Meat/Declaration/TypeFamily.hs+3−8
@@ -12,7 +12,6 @@ where
1212
1313import BasicTypes (LexicalFixity (..))
1414import Control.Monad
15−import Data.List.NonEmpty (NonEmpty (..))
1615import Data.Maybe (isNothing, isJust)
1716import GHC
1817import Ormolu.Printer.Combinators
@@ -31,11 +30,9 @@ p_famDecl style FamilyDecl {..} = do
3130 Associated -> mempty
3231 Free -> " family"
3332 let HsQTvs {..} = fdTyVars
34− combinedSpans = combineSrcSpans' $
35− getLoc fdLName :| fmap getLoc hsq_explicit
3633 breakpoint
3734 inci $ do
38− switchLayout combinedSpans $ do
35+ switchLayout (getLoc fdLName : (getLoc <$> hsq_explicit)) $ do
3936 p_infixDefHelper
4037 (isInfix fdFixity)
4138 inci
@@ -82,14 +79,12 @@ p_injectivityAnn (InjectivityAnn a bs) = do
8279 p_rdrName a
8380 space
8481 txt "-> "
85− spaceSep p_rdrName bs
82+ sep space p_rdrName bs
8683
8784p_tyFamInstEqn :: TyFamInstEqn GhcPs -> R ()
8885p_tyFamInstEqn HsIB {..} = do
8986 let FamEqn {..} = hsib_body
90− combinedSpans = combineSrcSpans' $
91− getLoc feqn_tycon :| fmap getLoc feqn_pats
92− switchLayout combinedSpans $ p_infixDefHelper
87+ switchLayout (getLoc feqn_tycon : (getLoc <$> feqn_pats)) $ p_infixDefHelper
9388 (isInfix feqn_fixity)
9489 inci
9590 (p_rdrName feqn_tycon)
src/Ormolu/Printer/Meat/Declaration/Value.hs+46−45
@@ -85,9 +85,9 @@ p_matchGroup'
8585 -> MatchGroup GhcPs (Located body)
8686 -> R ()
8787p_matchGroup' placer pretty style MG {..} =
88− locatedVia Nothing mg_alts $
89− newlineSep (located' (\m@Match {..} ->
90− p_match' placer pretty style (isInfixMatch m) (matchStrictness m) m_pats m_grhss))
88+ sep newline (located' (\m@Match {..} ->
89+ p_match' placer pretty style (isInfixMatch m) (matchStrictness m) m_pats m_grhss))
90+ (unLoc mg_alts)
9191p_matchGroup' _ _ _ (XMatchGroup NoExt) = notImplemented "XMatchGroup"
9292
9393matchStrictness :: Match id body -> SrcStrictness
@@ -137,8 +137,8 @@ p_match' placer pretty style isInfix strictness m_pats m_grhss = do
137137 inci' = if isOneLineSpan combinedSpans
138138 then id
139139 else inci
140− switchLayout combinedSpans $ do
141− let stdCase = velt' (located' p_pat <$> m_pats)
140+ switchLayout [combinedSpans] $ do
141+ let stdCase = sep breakpoint (located' p_pat) m_pats
142142 case style of
143143 Function name ->
144144 p_infixDefHelper
@@ -201,12 +201,12 @@ p_match' placer pretty style isInfix strictness m_pats m_grhss = do
201201 if isCase style && hasGuards
202202 then RightArrow
203203 else EqualSign
204− newlineSep (located' (p_grhs' pretty groupStyle)) grhssGRHSs
204+ sep newline (located' (p_grhs' pretty groupStyle)) grhssGRHSs
205205 let whereLocation = combineSrcSpans patGrhssSpan $ getLoc grhssLocalBinds
206206 whereIsEmpty = GHC.isEmptyLocalBindsPR (unLoc grhssLocalBinds)
207207 unless (GHC.eqEmptyLocalBinds (unLoc grhssLocalBinds))
208208 . inciLocalBinds
209− . switchLayout whereLocation $ do
209+ . switchLayout [whereLocation] $ do
210210 if whereIsEmpty then newline else breakpoint
211211 txt "where"
212212 unless whereIsEmpty $ do
@@ -214,8 +214,8 @@ p_match' placer pretty style isInfix strictness m_pats m_grhss = do
214214 inci (located grhssLocalBinds p_hsLocalBinds)
215215 case style of
216216 Lambda -> placeHanging placement $
217− switchLayout patGrhssSpan p_body
218− _ -> switchLayout patGrhssSpan $
217+ switchLayout [patGrhssSpan] p_body
218+ _ -> switchLayout [patGrhssSpan] $
219219 placeHanging placement p_body
220220
221221p_grhs :: GroupStyle -> GRHS GhcPs (LHsExpr GhcPs) -> R ()
@@ -232,7 +232,7 @@ p_grhs' pretty style (GRHS NoExt guards body) =
232232 [] -> p_body
233233 xs -> do
234234 txt "| "
235− velt $ withSep comma (located' p_stmt) xs
235+ sitcc (sep (comma >> breakpoint) (sitcc . located' p_stmt) xs)
236236 space
237237 txt $ case style of
238238 EqualSign -> "="
@@ -298,7 +298,7 @@ p_hsCmd = \case
298298 HsCmdDo NoExt es -> do
299299 txt "do"
300300 newline
301− inci (located es (newlineSep (located' (sitcc . p_stmt' p_hsCmd))))
301+ inci (located es (sitcc . sep newline (located' (sitcc . p_stmt' p_hsCmd))))
302302 HsCmdWrap {} -> notImplemented "HsCmdWrap"
303303 XCmd {} -> notImplemented "XCmd"
304304
@@ -368,7 +368,7 @@ p_stmt' pretty = \case
368368 inci (p_hsExpr x)
369369 RecStmt {..} -> do
370370 txt "rec "
371− sitcc $ newlineSep (located' (p_stmt' pretty)) recS_stmts
371+ sitcc $ sep newline (located' (p_stmt' pretty)) recS_stmts
372372 XStmtLR {} -> notImplemented "XStmtLR"
373373
374374gatherStmt :: ExprLStmt GhcPs -> [[ExprLStmt GhcPs]]
@@ -393,7 +393,7 @@ p_hsLocalBinds = \case
393393 (Left <$> bagToList bag) ++ (Right <$> lsigs)
394394 p_item (Left x) = located x p_valDecl'
395395 p_item (Right x) = located x p_sigDecl'
396− newlineSep (sitcc . p_item) (sortOn ssStart items)
396+ sitcc $ sep newline (sitcc . p_item) (sortOn ssStart items)
397397 HsValBinds NoExt _ -> notImplemented "HsValBinds"
398398 HsIPBinds NoExt _ -> notImplemented "HsIPBinds"
399399 EmptyLocalBinds NoExt -> return ()
@@ -439,7 +439,7 @@ p_hsExpr = \case
439439 txt "\\case"
440440 newline
441441 inci (p_matchGroup LambdaCase mgroup)
442− HsApp NoExt f x -> do
442+ HsApp NoExt f x -> sitcc $ do
443443 located f p_hsExpr
444444 breakpoint
445445 inci (located x p_hsExpr)
@@ -479,9 +479,11 @@ p_hsExpr = \case
479479 case boxity of
480480 Boxed -> parens
481481 Unboxed -> parensHash
482− parens' $ if isSection
483− then sequence_ (withSep (txt ",") (located' p_hsTupArg) args)
484− else velt (withSep comma (located' p_hsTupArg) args)
482+ if isSection
483+ then switchLayout [] . parens' $
484+ sep comma (located' p_hsTupArg) args
485+ else switchLayout (getLoc <$> args) . parens' . sitcc $
486+ sep (comma >> breakpoint) (sitcc . located' p_hsTupArg) args
485487 ExplicitSum NoExt tag arity e -> do
486488 let before = tag - 1
487489 after = arity - before - 1
@@ -496,7 +498,7 @@ p_hsExpr = \case
496498 unless isFirst space
497499 located l p_hsExpr
498500 unless isLast space
499− parensHash $ sequence_ (withSep (txt "|") f (zip args [0..]))
501+ parensHash $ sep (txt "|") f (zip args [0..])
500502 HsCase NoExt e mgroup -> do
501503 txt "case "
502504 located e p_hsExpr
@@ -518,7 +520,7 @@ p_hsExpr = \case
518520 inci (p_hsExpr x)
519521 HsMultiIf NoExt guards -> do
520522 txt "if "
521− sitcc $ newlineSep (located' (p_grhs RightArrow)) guards
523+ sitcc $ sep newline (located' (p_grhs RightArrow)) guards
522524 HsLet NoExt localBinds e -> do
523525 txt "let "
524526 sitcc (located localBinds p_hsLocalBinds)
@@ -529,16 +531,14 @@ p_hsExpr = \case
529531 let doBody header = do
530532 txt header
531533 newline
532− inci $ located es (newlineSep (located' (sitcc . p_stmt)))
533− compBody = brackets $ located es $ \xs -> do
534− let p_parBody =
535− sequence_ .
536− intersperse breakpoint .
537− withSep (txt "| ") p_seqBody
538− p_seqBody =
539− sequence_ .
540− intersperse (vlayout (pure ()) newline) .
541− withSep comma (located' (sitcc . p_stmt))
534+ inci $ located es (sep newline (located' (sitcc . p_stmt)))
535+ compBody = brackets $ located es $ \xs -> do
536+ let p_parBody = sitcc . sep
537+ (breakpoint >> txt "| ")
538+ p_seqBody
539+ p_seqBody = sitcc . sep
540+ (comma >> breakpoint)
541+ (located' (sitcc . p_stmt))
542542 stmts = init xs
543543 yield = last xs
544544 lists = foldr (liftAppend . gatherStmt) [] stmts
@@ -557,7 +557,7 @@ p_hsExpr = \case
557557 ParStmtCtxt _ -> notImplemented "ParStmtCtxt"
558558 TransStmtCtxt _ -> notImplemented "TransStmtCtxt"
559559 ExplicitList _ _ xs ->
560− brackets $ velt (withSep comma (located' p_hsExpr) xs)
560+ brackets . sitcc $ sep (comma >> breakpoint) (sitcc . located' p_hsExpr) xs
561561 RecordCon {..} -> do
562562 located rcon_con_name atom
563563 breakpoint
@@ -567,11 +567,12 @@ p_hsExpr = \case
567567 case rec_dotdot of
568568 Just {} -> [txt ".."]
569569 Nothing -> []
570− inci $ braces $ velt (withSep comma id (fields <> dotdot))
570+ inci . braces . sitcc $ sep (comma >> breakpoint) sitcc (fields <> dotdot)
571571 RecordUpd {..} -> do
572572 located rupd_expr p_hsExpr
573573 breakpoint
574− inci $ braces $ velt (withSep comma (located' p_hsRecField) rupd_flds)
574+ inci . braces . sitcc $
575+ sep (comma >> breakpoint) (sitcc . located' p_hsRecField) rupd_flds
575576 ExprWithTySig affix x -> sitcc $ do
576577 located x p_hsExpr
577578 breakpoint
@@ -582,21 +583,21 @@ p_hsExpr = \case
582583 located hsib_body p_hsType
583584 ArithSeq NoExt _ x -> do
584585 case x of
585− From from -> brackets $ do
586+ From from -> brackets . sitcc $ do
586587 located from p_hsExpr
587588 breakpoint
588589 txt ".."
589− FromThen from next -> brackets $ do
590− velt (withSep comma (located' p_hsExpr) [from, next])
590+ FromThen from next -> brackets . sitcc $ do
591+ sitcc $ sep (comma >> breakpoint) (located' p_hsExpr) [from, next]
591592 breakpoint
592593 txt ".."
593− FromTo from to -> brackets $ do
594+ FromTo from to -> brackets . sitcc $ do
594595 located from p_hsExpr
595596 breakpoint
596597 txt ".. "
597598 located to p_hsExpr
598− FromThenTo from next to -> brackets $ do
599− velt (withSep comma (located' p_hsExpr) [from, next])
599+ FromThenTo from next to -> brackets . sitcc $ do
600+ sitcc $ sep (comma >> breakpoint) (located' p_hsExpr) [from, next]
600601 breakpoint
601602 txt ".. "
602603 located to p_hsExpr
@@ -680,9 +681,9 @@ p_patSynBind (XPatSynBind NoExt) = notImplemented "XPatSynBind"
680681p_patSynDetails :: HsPatSynDetails (Located RdrName) -> R ()
681682p_patSynDetails = \case
682683 PrefixCon xs ->
683− velt' (p_rdrName <$> xs)
684+ sitcc $ sep breakpoint p_rdrName xs
684685 RecCon xs ->
685− velt' (p_rdrName . recordPatSynPatVar <$> xs)
686+ sitcc $ sep breakpoint (p_rdrName . recordPatSynPatVar) xs
686687 InfixCon _ _ -> notImplemented "InfixCon"
687688
688689p_pat :: Pat GhcPs -> R ()
@@ -702,13 +703,13 @@ p_pat = \case
702703 txt "!"
703704 located pat p_pat
704705 ListPat NoExt pats -> do
705− brackets $ velt (withSep comma (located' p_pat) pats)
706+ brackets . sitcc $ sep (comma >> breakpoint) (located' p_pat) pats
706707 TuplePat NoExt pats boxing -> do
707708 let f =
708709 case boxing of
709710 Boxed -> parens
710711 Unboxed -> parensHash
711− f $ velt (withSep comma (located' p_pat) pats)
712+ f . sitcc $ sep (comma >> breakpoint) (sitcc . located' p_pat) pats
712713 SumPat NoExt pat _ _ -> do
713714 -- XXX I'm not sure about this one.
714715 located pat p_pat
@@ -718,14 +719,14 @@ p_pat = \case
718719 p_rdrName pat
719720 unless (null xs) $ do
720721 breakpoint
721− inci $ velt' (located' p_pat <$> xs)
722+ inci . sitcc $ sep breakpoint (sitcc . located' p_pat) xs
722723 RecCon (HsRecFields fields dotdot) -> do
723724 p_rdrName pat
724725 breakpoint
725726 let f = \case
726727 Nothing -> txt ".."
727728 Just x -> located x p_pat_hsRecField
728− inci . braces . velt . withSep comma f $ case dotdot of
729+ inci . braces . sitcc . sep (comma >> breakpoint) f $ case dotdot of
729730 Nothing -> Just <$> fields
730731 Just n -> (Just <$> take n fields) ++ [Nothing]
731732 InfixCon x y -> do
@@ -899,7 +900,7 @@ exprPlacement = \case
899900 RecordCon NoExt _ _ -> Hanging
900901 HsProc NoExt (L s _) _ ->
901902 -- Indentation breaks if pattern is longer than one line and left hanging.
902− -- Consequentally, once apply hanging when it is safe.
903+ -- Consequently, only apply hanging when it is safe.
903904 if isOneLineSpan s
904905 then Hanging
905906 else Normal
src/Ormolu/Printer/Meat/Declaration/Warning.hs+4−9
@@ -9,13 +9,11 @@ where
99
1010import BasicTypes
1111import Data.Foldable
12−import qualified Data.List.NonEmpty as NE
1312import Data.Text (Text)
1413import GHC
1514import Ormolu.Printer.Combinators
1615import Ormolu.Printer.Meat.Common
1716import Ormolu.Utils
18−import SrcLoc (combineSrcSpans)
1917
2018p_warnDecls :: WarnDecls GhcPs -> R ()
2119p_warnDecls (Warnings NoExt _ warnings) =
@@ -30,16 +28,16 @@ p_warnDecl XWarnDecl {} = notImplemented "XWarnDecl"
3028p_moduleWarning :: WarningTxt -> R ()
3129p_moduleWarning wtxt = do
3230 let (pragmaText, lits) = warningText wtxt
33− switchLayout (listSpan lits) $ do
31+ switchLayout (getLoc <$> lits) $ do
3432 breakpoint
3533 inci $ pragma pragmaText (inci $ p_lits lits)
3634
3735p_topLevelWarning :: [Located RdrName] -> WarningTxt -> R ()
3836p_topLevelWarning fnames wtxt = do
3937 let (pragmaText, lits) = warningText wtxt
40− switchLayout (combineSrcSpans (listSpan fnames) (listSpan lits)) $ do
38+ switchLayout (fmap getLoc fnames ++ fmap getLoc lits) $ do
4139 pragma pragmaText . inci $ do
42− velt (withSep comma p_rdrName fnames)
40+ sitcc $ sep (comma >> breakpoint) p_rdrName fnames
4341 breakpoint
4442 p_lits lits
4543
@@ -48,10 +46,7 @@ warningText = \case
4846 WarningTxt _ lits -> ("WARNING", lits)
4947 DeprecatedTxt _ lits -> ("DEPRECATED", lits)
5048
51−listSpan :: [Located a] -> SrcSpan
52−listSpan xs = combineSrcSpans' (getLoc <$> NE.fromList xs)
53−
5449p_lits :: [Located StringLiteral] -> R ()
5550p_lits = \case
5651 [l] -> atom l
57− ls -> brackets . velt $ withSep comma atom ls
52+ ls -> brackets . sitcc $ sep (comma >> breakpoint) atom ls
src/Ormolu/Printer/Meat/ImportExport.hs+5−5
@@ -23,7 +23,7 @@ p_hsmodExports [] = do
2323 breakpoint'
2424 txt ")"
2525p_hsmodExports xs =
26− parens . velt $ withSep comma (sitcc . located' p_lie) xs
26+ parens . sitcc $ sep (comma >> breakpoint) (sitcc . located' p_lie) xs
2727
2828p_hsmodImport :: ImportDecl GhcPs -> R ()
2929p_hsmodImport ImportDecl {..} = line $ do
@@ -52,10 +52,10 @@ p_hsmodImport ImportDecl {..} = line $ do
5252 txt " hiding"
5353 case ideclHiding of
5454 Nothing -> return ()
55− Just (_, l) -> do
55+ Just (_, (L _ a)) -> do
5656 breakpoint
57− inci . locatedVia Nothing l $
58− parens . velt . withSep comma (located' p_lie)
57+ inci . parens . sitcc $
58+ sep (comma >> breakpoint) (sitcc . located' p_lie) a
5959p_hsmodImport (XImportDecl NoExt) = notImplemented "XImportDecl"
6060
6161p_lie :: IE GhcPs -> R ()
@@ -72,7 +72,7 @@ p_lie = \case
7272 inci $ do
7373 let names :: [R ()]
7474 names = located' p_ieWrappedName <$> xs
75− parens . velt . withSep comma id $
75+ parens . sitcc . sep (comma >> breakpoint) sitcc $
7676 case w of
7777 NoIEWildcard -> names
7878 IEWildcard n ->
src/Ormolu/Printer/Meat/Module.hs+6−8
@@ -20,18 +20,16 @@ import Ormolu.Printer.Meat.Declaration
2020import Ormolu.Printer.Meat.Declaration.Warning
2121import Ormolu.Printer.Meat.ImportExport
2222import Ormolu.Printer.Meat.LanguagePragma
23−import SrcLoc (combineSrcSpans)
2423
2524p_hsModule :: Set String -> ParsedSource -> R ()
26−p_hsModule exts loc@(L moduleSpan hsModule) = do
25+p_hsModule exts (L moduleSpan HsModule {..}) = do
2726 -- NOTE If span of exports in multiline, the whole thing is multiline.
2827 -- This is especially important because span of module itself always seems
2928 -- to have length zero, so it's not reliable for layout selection.
30− let spn =
31− case hsmodExports hsModule of
32− Nothing -> moduleSpan
33− Just (L exportsSpan _) -> combineSrcSpans moduleSpan exportsSpan
34− locatedVia (Just spn) loc $ \HsModule {..} -> do
29+ let spans' = case hsmodExports of
30+ Nothing -> [moduleSpan]
31+ Just (L exportsSpan _) -> moduleSpan : [exportsSpan]
32+ switchLayout spans' $ do
3533 let hasLangPragmas = not (null exts)
3634 hasModuleHeader = isJust hsmodName
3735 hasImports = not (null hsmodImports)
@@ -49,7 +47,7 @@ p_hsModule exts loc@(L moduleSpan hsModule) = do
4947 Nothing -> return ()
5048 Just hsmodExports' -> do
5149 breakpoint
52− inci (locatedVia Nothing hsmodExports' p_hsmodExports)
50+ inci (p_hsmodExports (unLoc hsmodExports'))
5351 breakpoint
5452 txt "where"
5553 when (hasImports || hasDecls) newline
src/Ormolu/Printer/Meat/Type.hs+17−15
@@ -22,16 +22,16 @@ p_hsType :: HsType GhcPs -> R ()
2222p_hsType = \case
2323 HsForAllTy NoExt bndrs t -> do
2424 txt "forall "
25− spaceSep (located' p_hsTyVarBndr) bndrs
25+ sep space (located' p_hsTyVarBndr) bndrs
2626 txt ". "
27− locatedVia Nothing t p_hsType
27+ p_hsType (unLoc t)
2828 HsQualTy NoExt qs t -> do
2929 located qs p_hsContext
3030 breakpoint
3131 txt "=> "
3232 case unLoc t of
33− HsQualTy {} -> locatedVia Nothing t p_hsType
34− HsFunTy {} -> locatedVia Nothing t p_hsType
33+ HsQualTy {} -> p_hsType (unLoc t)
34+ HsFunTy {} -> p_hsType (unLoc t)
3535 _ -> located t p_hsType
3636 HsTyVar NoExt p n -> do
3737 case p of
@@ -60,9 +60,11 @@ p_hsType = \case
6060 HsBoxedTuple -> parens
6161 HsConstraintTuple -> parens
6262 HsBoxedOrConstraintTuple -> parens
63− in parens' . velt $ withSep comma (located' p_hsType) xs
63+ in parens' . sitcc $
64+ sep (comma >> breakpoint) (sitcc . located' p_hsType) xs
6465 HsSumTy NoExt xs ->
65− parensHash . velt $ withSep (txt "| ") (located' p_hsType) xs
66+ parensHash . sitcc $
67+ sep (txt "| " >> breakpoint') (sitcc . located' p_hsType) xs
6668 HsOpTy NoExt x op y -> do
6769 located x p_hsType
6870 breakpoint
@@ -115,10 +117,10 @@ p_hsType = \case
115117 case xs of
116118 ((L _ (HsTyVar _ Promoted _)):_) -> space
117119 _ -> return ()
118− velt $ withSep comma (located' p_hsType) xs
120+ sitcc $ sep (comma >> breakpoint) (sitcc . located' p_hsType) xs
119121 HsExplicitTupleTy NoExt xs -> do
120122 txt "'"
121− parens . velt $ withSep comma (located' p_hsType) xs
123+ parens $ sep (comma >> breakpoint) (located' p_hsType) xs
122124 HsTyLit NoExt t -> atom t
123125 HsWildCardTy NoExt -> txt "_"
124126 XHsType (NHsCoreTy t) -> atom t
@@ -127,7 +129,8 @@ p_hsContext :: HsContext GhcPs -> R ()
127129p_hsContext = \case
128130 [] -> txt "()"
129131 [x] -> located x p_hsType
130− xs -> parens . velt $ withSep comma (located' p_hsType) xs
132+ xs -> parens . sitcc $
133+ sep (comma >> breakpoint) (sitcc . located' p_hsType) xs
131134
132135p_hsTyVarBndr :: HsTyVarBndr GhcPs -> R ()
133136p_hsTyVarBndr = \case
@@ -142,23 +145,22 @@ p_hsTyVarBndr = \case
142145 XTyVarBndr NoExt -> notImplemented "XTyVarBndr"
143146
144147p_conDeclFields :: [LConDeclField GhcPs] -> R ()
145−p_conDeclFields =
146− braces . velt . withSep comma (sitcc . located' p_conDeclField)
148+p_conDeclFields xs = braces . sitcc $
149+ sep (comma >> breakpoint) (sitcc . located' p_conDeclField) xs
147150
148151p_conDeclField :: ConDeclField GhcPs -> R ()
149152p_conDeclField ConDeclField {..} = do
150− sitcc . velt $ withSep
151− comma
153+ sitcc $ sep (comma >> breakpoint)
152154 (located' (p_rdrName . rdrNameFieldOcc))
153155 cd_fld_names
154156 breakpoint
155157 sitcc . inci $ do
156158 txt ":: "
157− locatedVia Nothing cd_fld_type p_hsType
159+ p_hsType (unLoc cd_fld_type)
158160p_conDeclField (XConDeclField NoExt) = notImplemented "XConDeclField"
159161
160162----------------------------------------------------------------------------
161−-- Convertion functions
163+-- Conversion functions
162164
163165tyVarsToTypes :: LHsQTyVars GhcPs -> [LHsType GhcPs]
164166tyVarsToTypes = \case
src/Ormolu/Utils.hs+2
@@ -1,5 +1,7 @@
11-- | Random utilities used by the code.
22
3+{-# LANGUAGE LambdaCase #-}
4+
35module Ormolu.Utils
46 ( combineSrcSpans'
57 , isModule
tests/Ormolu/Printer/CombinatorsSpec.hs+18−16
@@ -47,27 +47,27 @@ rSimpleSig :: R ()
4747rSimpleSig = line rFn
4848
4949rList0 :: R ()
50−rList0 = line . brackets $
51− velt
50+rList0 = line . brackets . sitcc $
51+ sep (comma >> breakpoint) id
5252 [ txt "foo"
53− , comma >> txt "bar"
54− , comma >> txt "baz"
53+ , txt "bar"
54+ , txt "baz"
5555 ]
5656
5757rList1 :: R ()
58−rList1 = line . brackets $
59− velt
58+rList1 = line . brackets . sitcc $
59+ sep (comma >> breakpoint) id
6060 [ txt "foo"
61− , comma >> txt "bar"
62− , comma >> rFn
61+ , txt "bar"
62+ , rFn
6363 ]
6464
6565rFn :: R ()
66−rFn = velt'
66+rFn = sitcc $ sep breakpoint sitcc
6767 [ txt "foo"
68− , inci $ velt'
68+ , inci . sitcc $ sep breakpoint sitcc
6969 [ do txt ":: "
70− parens $ velt'
70+ parens . sitcc $ sep breakpoint sitcc
7171 [ txt "Int"
7272 , txt "-> " >> txt "Int"
7373 ]
@@ -80,11 +80,11 @@ rModuleHeader = do
8080 line $ do
8181 txt "module "
8282 txt "MyModule"
83− line . inci . parens . velt $
83+ line . inci . parens . sitcc . sep (comma >> breakpoint) sitcc $
8484 [ txt "R"
85− , comma >> txt "runR"
86− , comma >> txt "txt"
87− , comma >> txt "blah"
85+ , txt "runR"
86+ , txt "txt"
87+ , txt "blah"
8888 ]
8989 line (txt "where")
9090
@@ -96,8 +96,10 @@ rModuleHeader = do
9696
9797shouldRender :: R () -> FilePath -> Expectation
9898shouldRender m path = do
99+ let rendered = runR False m mempty mempty emptyAnns
100+ -- T.writeFile path rendered
99101 expected <- T.readFile path
100− runR False m mempty mempty emptyAnns `shouldBe` expected
102+ rendered `shouldBe` expected
101103
102104-- | Render using single-line layout.
103105
tests/Ormolu/PrinterSpec.hs+1
@@ -32,6 +32,7 @@ checkExample srcPath' = it (fromRelFile srcPath' ++ " works") $ do
3232 formatted0 <- ormoluFile defaultConfig (fromRelFile srcPath)
3333 -- 3. Check the output against expected output. Thus all tests should
3434 -- include two files: input and expected output.
35+ -- T.writeFile (fromRelFile expectedOutputPath) formatted0
3536 expected <- (liftIO . T.readFile . fromRelFile) expectedOutputPath
3637 shouldMatch False formatted0 expected
3738 -- 4. Check that running the formatter on the output produces the same