Skip to content

Commit 8447f67

Browse files
authored
Support alignment of cases with a single guard
1 parent b9c1141 commit 8447f67

File tree

2 files changed

+48
-11
lines changed

2 files changed

+48
-11
lines changed

lib/Language/Haskell/Stylish/Step/SimpleAlign.hs

Lines changed: 30 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@ module Language.Haskell.Stylish.Step.SimpleAlign
88

99
--------------------------------------------------------------------------------
1010
import Data.Data (Data)
11+
import Data.List (foldl')
1112
import Data.Maybe (maybeToList)
1213
import qualified Language.Haskell.Exts as H
1314

@@ -42,14 +43,30 @@ cases modu = [alts | H.Case _ _ alts <- everything modu]
4243

4344

4445
--------------------------------------------------------------------------------
45-
altToAlignable :: H.Alt l -> Maybe (Alignable l)
46-
altToAlignable (H.Alt _ _ _ (Just _)) = Nothing
47-
altToAlignable (H.Alt ann pat rhs Nothing) = Just $ Alignable
48-
{ aContainer = ann
49-
, aLeft = H.ann pat
50-
, aRight = H.ann rhs
51-
, aRightLead = length "-> "
52-
}
46+
-- | For this to work well, we require a way to merge annotations. This merge
47+
-- operation should follow the semigroup laws.
48+
altToAlignable :: (l -> l -> l) -> H.Alt l -> Maybe (Alignable l)
49+
altToAlignable _ (H.Alt _ _ _ (Just _)) = Nothing
50+
altToAlignable _ (H.Alt ann pat rhs@(H.UnGuardedRhs _ _) Nothing) = Just $
51+
Alignable
52+
{ aContainer = ann
53+
, aLeft = H.ann pat
54+
, aRight = H.ann rhs
55+
, aRightLead = length "-> "
56+
}
57+
altToAlignable
58+
merge
59+
(H.Alt ann pat (H.GuardedRhss _ [H.GuardedRhs _ guards rhs]) Nothing) =
60+
-- We currently only support the case where an alternative has a single
61+
-- guarded RHS. If there are more, we would need to return multiple
62+
-- `Alignable`s from this function, which would be a significant change.
63+
Just $ Alignable
64+
{ aContainer = ann
65+
, aLeft = foldl' merge (H.ann pat) (map H.ann guards)
66+
, aRight = H.ann rhs
67+
, aRightLead = length "-> "
68+
}
69+
altToAlignable _ _ = Nothing
5370

5471

5572
--------------------------------------------------------------------------------
@@ -101,9 +118,11 @@ step maxColumns config = makeStep "Cases" $ \ls (module', _) ->
101118
, change_ <- align maxColumns aligns
102119
]
103120

104-
configured = concat $
105-
[changes cases altToAlignable | cCases config] ++
106-
[changes tlpats matchToAlignable | cTopLevelPatterns config] ++
121+
configured = concat $
122+
[ changes cases (altToAlignable H.mergeSrcSpan)
123+
| cCases config
124+
] ++
125+
[changes tlpats matchToAlignable | cTopLevelPatterns config] ++
107126
[changes records fieldDeclToAlignable | cRecords config]
108127

109128
in applyChanges configured ls

tests/Language/Haskell/Stylish/Step/SimpleAlign/Tests.hs

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,7 @@ tests = testGroup "Language.Haskell.Stylish.Step.SimpleAlign.Tests"
2525
, testCase "case 05" case05
2626
, testCase "case 06" case06
2727
, testCase "case 07" case07
28+
, testCase "case 08" case08
2829
]
2930

3031

@@ -148,3 +149,20 @@ case07 =
148149
, " , barqux :: Int"
149150
, " }"
150151
]
152+
153+
154+
--------------------------------------------------------------------------------
155+
case08 :: Assertion
156+
case08 = expected @=? testStep (step 80 defaultConfig) input
157+
where
158+
input = unlines
159+
[ "canDrink mbAge = case mbAge of"
160+
, " Just age | age > 18 -> True"
161+
, " _ -> False"
162+
]
163+
164+
expected = unlines
165+
[ "canDrink mbAge = case mbAge of"
166+
, " Just age | age > 18 -> True"
167+
, " _ -> False"
168+
]

0 commit comments

Comments
 (0)