Skip to content

Commit 0e2ebd1

Browse files
authored
Fix some issues with record field padding
See #318 and #319
1 parent 1bc2b2c commit 0e2ebd1

File tree

4 files changed

+198
-102
lines changed

4 files changed

+198
-102
lines changed

lib/Language/Haskell/Stylish/Printer.hs

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -44,6 +44,7 @@ module Language.Haskell.Stylish.Printer
4444
, space
4545
, spaces
4646
, suffix
47+
, pad
4748

4849
-- ** Advanced combinators
4950
, withColumns
@@ -323,6 +324,13 @@ prefix pa pb = pa >> pb
323324
suffix :: P a -> P b -> P a
324325
suffix pa pb = pb >> pa
325326

327+
-- | Indent to a given number of spaces. If the current line already exceeds
328+
-- that number in length, nothing happens.
329+
pad :: Int -> P ()
330+
pad n = do
331+
len <- length <$> getCurrentLine
332+
spaces $ n - len
333+
326334
-- | Gets comment on supplied 'line' and removes it from the state
327335
removeLineComment :: Int -> P (Maybe AnnotationComment)
328336
removeLineComment line =

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

Lines changed: 55 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,12 @@
1-
{-# LANGUAGE BlockArguments #-}
1+
{-# LANGUAGE BlockArguments #-}
22
{-# LANGUAGE DoAndIfThenElse #-}
3-
{-# LANGUAGE LambdaCase #-}
4-
{-# LANGUAGE NamedFieldPuns #-}
3+
{-# LANGUAGE LambdaCase #-}
4+
{-# LANGUAGE NamedFieldPuns #-}
55
{-# LANGUAGE RecordWildCards #-}
66
module Language.Haskell.Stylish.Step.Data
77
( Config(..)
8+
, defaultConfig
9+
810
, Indent(..)
911
, MaxColumns(..)
1012
, step
@@ -22,19 +24,24 @@ import Data.Maybe (listToMaybe)
2224

2325
--------------------------------------------------------------------------------
2426
import ApiAnnotation (AnnotationComment)
25-
import BasicTypes (LexicalFixity(..))
26-
import GHC.Hs.Decls (HsDecl(..), HsDataDefn(..))
27-
import GHC.Hs.Decls (TyClDecl(..), NewOrData(..))
28-
import GHC.Hs.Decls (HsDerivingClause(..), DerivStrategy(..))
29-
import GHC.Hs.Decls (ConDecl(..))
30-
import GHC.Hs.Extension (GhcPs, NoExtField(..), noExtCon)
31-
import GHC.Hs.Types (ConDeclField(..), HsContext)
32-
import GHC.Hs.Types (HsType(..), ForallVisFlag(..))
33-
import GHC.Hs.Types (LHsQTyVars(..), HsTyVarBndr(..))
34-
import GHC.Hs.Types (HsConDetails(..), HsImplicitBndrs(..))
27+
import BasicTypes (LexicalFixity (..))
28+
import GHC.Hs.Decls (ConDecl (..),
29+
DerivStrategy (..),
30+
HsDataDefn (..), HsDecl (..),
31+
HsDerivingClause (..),
32+
NewOrData (..),
33+
TyClDecl (..))
34+
import GHC.Hs.Extension (GhcPs, NoExtField (..),
35+
noExtCon)
36+
import GHC.Hs.Types (ConDeclField (..),
37+
ForallVisFlag (..),
38+
HsConDetails (..), HsContext,
39+
HsImplicitBndrs (..),
40+
HsTyVarBndr (..),
41+
HsType (..), LHsQTyVars (..))
3542
import RdrName (RdrName)
36-
import SrcLoc (Located, RealLocated)
37-
import SrcLoc (GenLocated(..))
43+
import SrcLoc (GenLocated (..), Located,
44+
RealLocated)
3845

3946
--------------------------------------------------------------------------------
4047
import Language.Haskell.Stylish.Block
@@ -76,6 +83,21 @@ data Config = Config
7683
, cMaxColumns :: !MaxColumns
7784
} deriving (Show)
7885

86+
-- | TODO: pass in MaxColumns?
87+
defaultConfig :: Config
88+
defaultConfig = Config
89+
{ cEquals = Indent 4
90+
, cFirstField = Indent 4
91+
, cFieldComment = 2
92+
, cDeriving = 4
93+
, cBreakEnums = True
94+
, cBreakSingleConstructors = False
95+
, cVia = Indent 4
96+
, cSortDeriving = True
97+
, cMaxColumns = NoMaxColumns
98+
, cCurriedContext = False
99+
}
100+
79101
step :: Config -> Step
80102
step cfg = makeStep "Data" \ls m -> applyChanges (changes m) ls
81103
where
@@ -190,19 +212,19 @@ formatDataDecl cfg@Config{..} m ldecl@(L declPos decl) =
190212
data DataDecl = MkDataDecl
191213
{ dataDeclName :: Located RdrName
192214
, dataTypeVars :: LHsQTyVars GhcPs
193-
, dataDefn :: HsDataDefn GhcPs
194-
, dataFixity :: LexicalFixity
215+
, dataDefn :: HsDataDefn GhcPs
216+
, dataFixity :: LexicalFixity
195217
}
196218

197219
putDeriving :: Config -> Located (HsDerivingClause GhcPs) -> P ()
198220
putDeriving Config{..} (L pos clause) = do
199221
putText "deriving"
200222

201223
forM_ (deriv_clause_strategy clause) \case
202-
L _ StockStrategy -> space >> putText "stock"
224+
L _ StockStrategy -> space >> putText "stock"
203225
L _ AnyclassStrategy -> space >> putText "anyclass"
204-
L _ NewtypeStrategy -> space >> putText "newtype"
205-
L _ (ViaStrategy _) -> pure ()
226+
L _ NewtypeStrategy -> space >> putText "newtype"
227+
L _ (ViaStrategy _) -> pure ()
206228

207229
putCond
208230
withinColumns
@@ -224,13 +246,13 @@ putDeriving Config{..} (L pos clause) = do
224246

225247
where
226248
getType = \case
227-
HsIB _ tp -> tp
249+
HsIB _ tp -> tp
228250
XHsImplicitBndrs x -> noExtCon x
229251

230252
withinColumns PrinterState{currentLine} =
231253
case cMaxColumns of
232254
MaxColumns maxCols -> length currentLine <= maxCols
233-
NoMaxColumns -> True
255+
NoMaxColumns -> True
234256

235257
oneLinePrint = do
236258
space
@@ -361,8 +383,10 @@ putConstructor cfg consIndent (L _ cons) = case cons of
361383
sep space (fmap putOutputable xs)
362384
RecCon (L recPos (L posFirst firstArg : args)) -> do
363385
putRdrName con_name
364-
skipToBrace >> putText "{"
386+
skipToBrace
365387
bracePos <- getCurrentLineLength
388+
putText "{"
389+
let fieldPos = bracePos + 2
366390
space
367391

368392
-- Unless everything's configured to be on the same line, put pending
@@ -371,7 +395,7 @@ putConstructor cfg consIndent (L _ cons) = case cons of
371395
removeCommentTo posFirst >>= mapM_ \c -> putComment c >> sepDecl bracePos
372396

373397
-- Put first decl field
374-
putConDeclField cfg firstArg
398+
pad fieldPos >> putConDeclField cfg firstArg
375399
unless (cFirstField cfg == SameLine) (putEolComment posFirst)
376400

377401
-- Put tail decl fields
@@ -395,19 +419,21 @@ putConstructor cfg consIndent (L _ cons) = case cons of
395419
skipToBrace >> putText "}"
396420

397421
where
422+
-- Jump to the first brace of the first record of the first constructor.
398423
skipToBrace = case (cEquals cfg, cFirstField cfg) of
399424
(_, Indent y) | not (cBreakSingleConstructors cfg) -> newline >> spaces y
400425
(SameLine, SameLine) -> space
401426
(Indent x, Indent y) -> newline >> spaces (x + y + 2)
402427
(SameLine, Indent y) -> newline >> spaces (consIndent + y)
403428
(Indent _, SameLine) -> space
404429

430+
-- Jump to the next declaration.
405431
sepDecl bracePos = newline >> spaces case (cEquals cfg, cFirstField cfg) of
406432
(_, Indent y) | not (cBreakSingleConstructors cfg) -> y
407-
(SameLine, SameLine) -> bracePos - 1 -- back one from brace pos to place comma
433+
(SameLine, SameLine) -> bracePos
408434
(Indent x, Indent y) -> x + y + 2
409-
(SameLine, Indent y) -> bracePos - 1 + y - 2
410-
(Indent x, SameLine) -> bracePos - 1 + x - 2
435+
(SameLine, Indent y) -> bracePos + y - 2
436+
(Indent x, SameLine) -> bracePos + x - 2
411437

412438
putNewtypeConstructor :: Config -> Located (ConDecl GhcPs) -> P ()
413439
putNewtypeConstructor cfg (L _ cons) = case cons of
@@ -493,7 +519,7 @@ isGADT = any isGADTCons . dd_cons . dataDefn
493519
where
494520
isGADTCons = \case
495521
L _ (ConDeclGADT {}) -> True
496-
_ -> False
522+
_ -> False
497523

498524
isNewtype :: DataDecl -> Bool
499525
isNewtype = (== NewType) . dd_ND . dataDefn
@@ -507,7 +533,7 @@ isEnum = all isUnary . dd_cons . dataDefn
507533
isUnary = \case
508534
L _ (ConDeclH98 {..}) -> case con_args of
509535
PrefixCon [] -> True
510-
_ -> False
536+
_ -> False
511537
_ -> False
512538

513539
hasConstructors :: DataDecl -> Bool

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

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -182,9 +182,7 @@ printExportList conf (L srcLoc exports) = do
182182
-- > xxxxyyfoo
183183
-- > xxxx) where
184184
doIndent = spaces (indent conf)
185-
doHang = do
186-
len <- length <$> getCurrentLine
187-
spaces $ indent conf + 2 - len
185+
doHang = pad (indent conf + 2)
188186

189187
doSort = if sort conf then NonEmpty.sortBy compareLIE else id
190188

0 commit comments

Comments
 (0)