From 004dee73e0802211e6f75c82b147aed0105d3e76 Mon Sep 17 00:00:00 2001 From: Bryan Richter Date: Sun, 22 Apr 2018 15:54:19 -0400 Subject: [PATCH 1/5] Add test for IndentPolicyMultiple --- .../40-indent-policy-multiple.blt | 33 +++++++++++++++++++ 1 file changed, 33 insertions(+) create mode 100644 src-literatetests/40-indent-policy-multiple.blt diff --git a/src-literatetests/40-indent-policy-multiple.blt b/src-literatetests/40-indent-policy-multiple.blt new file mode 100644 index 0000000..42b19ca --- /dev/null +++ b/src-literatetests/40-indent-policy-multiple.blt @@ -0,0 +1,33 @@ +############################################################################### +############################################################################### +############################################################################### +#group indent-policy-multiple +############################################################################### +############################################################################### +############################################################################### + +#test long +-- brittany { lconfig_indentAmount: 4, lconfig_indentPolicy: IndentPolicyMultiple } +-- brittany { lconfig_columnAlignMode: { tag: ColumnAlignModeDisabled }} +func = + mweroiuxlskdfjlksjdflkjsdfljksldkjflkjsdflkj + + mweroiuxlskdfjlksjdflkjsdfljksldkjflkjsdflkj + +#test let +-- brittany { lconfig_indentAmount: 4, lconfig_indentPolicy: IndentPolicyMultiple } +-- brittany { lconfig_columnAlignMode: { tag: ColumnAlignModeDisabled }} +foo = do + let + aaaaaaaaaaaaaaaaaaaaaaaaaaaaaa = + aaaaaaaaaaaaaaaaaaaaaaaaaaaaaa + aaaaaaaaaaaaaaaaaaaaaaaaaaaaaa + foo + +#test nested do-block +-- brittany { lconfig_indentAmount: 4, lconfig_indentPolicy: IndentPolicyMultiple } +-- brittany { lconfig_columnAlignMode: { tag: ColumnAlignModeDisabled }} +foo = asdyf8asdf + "ajsdfas" + [ asjdf asyhf $ do + aaaaaaaaaaaaaaaaaaaaaaaaaaaaaa + aaaaaaaaaaaaaaaaaaaaaaaaaaaaaa + ] From 9ab17cc899718714fb387a475afde5a11041ea69 Mon Sep 17 00:00:00 2001 From: Bryan Richter Date: Sun, 22 Apr 2018 15:24:40 +0200 Subject: [PATCH 2/5] Implement IndentPolicyMultiple --- .../Brittany/Internal/Layouters/Decl.hs | 2 +- .../Brittany/Internal/Layouters/Expr.hs | 42 +++++++++++-------- .../Brittany/Internal/Layouters/Import.hs | 2 +- .../Brittany/Internal/Layouters/Stmt.hs | 30 +++++++------ .../Brittany/Internal/Transformations/Alt.hs | 10 ++++- 5 files changed, 49 insertions(+), 37 deletions(-) diff --git a/src/Language/Haskell/Brittany/Internal/Layouters/Decl.hs b/src/Language/Haskell/Brittany/Internal/Layouters/Decl.hs index d4e8bce..19a6f48 100644 --- a/src/Language/Haskell/Brittany/Internal/Layouters/Decl.hs +++ b/src/Language/Haskell/Brittany/Internal/Layouters/Decl.hs @@ -436,7 +436,7 @@ layoutPatternBindFinal alignmentToken binderDoc mPatDoc clauseDocs mWhereDocs ha -- multiple clauses added in-paragraph, each in a single line -- example: foo | bar = baz -- | lll = asd - addAlternativeCond (indentPolicy /= IndentPolicyLeft) + addAlternativeCond (indentPolicy == IndentPolicyFree) $ docLines $ [ docSeq [ appSep $ docForceSingleline $ return patDoc diff --git a/src/Language/Haskell/Brittany/Internal/Layouters/Expr.hs b/src/Language/Haskell/Brittany/Internal/Layouters/Expr.hs index 93a06ac..a9deffc 100644 --- a/src/Language/Haskell/Brittany/Internal/Layouters/Expr.hs +++ b/src/Language/Haskell/Brittany/Internal/Layouters/Expr.hs @@ -422,7 +422,8 @@ layoutExpr lexpr@(L _ expr) = do let maySpecialIndent = case indentPolicy of IndentPolicyLeft -> BrIndentRegular - _ -> BrIndentSpecial 3 + IndentPolicyMultiple -> BrIndentRegular + IndentPolicyFree -> BrIndentSpecial 3 -- TODO: some of the alternatives (especially last and last-but-one) -- overlap. runFilteredAlternative $ do @@ -541,7 +542,10 @@ layoutExpr lexpr@(L _ expr) = do let ifIndentLeftElse :: a -> a -> a ifIndentLeftElse x y = - if indentPolicy == IndentPolicyLeft then x else y + case indentPolicy of + IndentPolicyLeft -> x + IndentPolicyMultiple -> x + IndentPolicyFree -> y -- this `docSetBaseAndIndent` might seem out of place (especially the -- Indent part; setBase is necessary due to the use of docLines below), -- but is here due to ghc-exactprint's DP handling of "let" in @@ -596,18 +600,21 @@ layoutExpr lexpr@(L _ expr) = do -- c = d -- in -- fooooooooooooooooooo + let noHangingBinds = + [ docAddBaseY BrIndentRegular + $ docPar + (docLit $ Text.pack "let") + (docSetBaseAndIndent $ docLines bindDocs) + , docSeq + [ docLit $ Text.pack "in " + , docAddBaseY BrIndentRegular expDoc1 + ] + ] addAlternativeCond (indentPolicy == IndentPolicyLeft) - $ docLines - [ docAddBaseY BrIndentRegular - $ docPar - (docLit $ Text.pack "let") - (docSetBaseAndIndent $ docLines bindDocs) - , docSeq - [ docLit $ Text.pack "in " - , docAddBaseY BrIndentRegular expDoc1 - ] - ] - addAlternativeCond (indentPolicy /= IndentPolicyLeft) + $ docLines noHangingBinds + addAlternativeCond (indentPolicy == IndentPolicyMultiple) + $ docLines noHangingBinds + addAlternativeCond (indentPolicy == IndentPolicyFree) $ docLines [ docSeq [ appSep $ docLit $ Text.pack "let" @@ -877,7 +884,7 @@ layoutExpr lexpr@(L _ expr) = do -- container { fieldA = blub -- , fieldB = blub -- } - addAlternativeCond (indentPolicy /= IndentPolicyLeft) + addAlternativeCond (indentPolicy == IndentPolicyFree) $ docSeq [ docNodeAnnKW lexpr Nothing $ appSep rExprDoc , docSetBaseY $ docLines $ let @@ -918,9 +925,10 @@ layoutExpr lexpr@(L _ expr) = do $ docPar (docNodeAnnKW lexpr Nothing rExprDoc) (docNonBottomSpacing $ docLines $ let - expressionWrapper = if indentPolicy == IndentPolicyLeft - then docForceParSpacing - else docSetBaseY + expressionWrapper = case indentPolicy of + IndentPolicyLeft -> docForceParSpacing + IndentPolicyMultiple -> docForceParSpacing + IndentPolicyFree -> docSetBaseY line1 = docCols ColRecUpdate [ appSep $ docLit $ Text.pack "{" , docWrapNodePrior rF1f $ appSep $ docLit rF1n diff --git a/src/Language/Haskell/Brittany/Internal/Layouters/Import.hs b/src/Language/Haskell/Brittany/Internal/Layouters/Import.hs index 3f56dcd..aa4380f 100644 --- a/src/Language/Haskell/Brittany/Internal/Layouters/Import.hs +++ b/src/Language/Haskell/Brittany/Internal/Layouters/Import.hs @@ -48,7 +48,7 @@ layoutImport limportD@(L _ importD) = docWrapNode limportD $ case importD of importAsCol <- mAsk <&> _conf_layout .> _lconfig_importAsColumn .> confUnpack indentPolicy <- mAsk <&> _conf_layout .> _lconfig_indentPolicy .> confUnpack let - compact = indentPolicy == IndentPolicyLeft + compact = indentPolicy /= IndentPolicyFree modNameT = Text.pack $ moduleNameString modName pkgNameT = Text.pack . prepPkg . sl_st <$> pkg masT = Text.pack . moduleNameString . prepModName <$> mas diff --git a/src/Language/Haskell/Brittany/Internal/Layouters/Stmt.hs b/src/Language/Haskell/Brittany/Internal/Layouters/Stmt.hs index 70daf6c..33b700e 100644 --- a/src/Language/Haskell/Brittany/Internal/Layouters/Stmt.hs +++ b/src/Language/Haskell/Brittany/Internal/Layouters/Stmt.hs @@ -58,11 +58,11 @@ layoutStmt lstmt@(L _ stmt) = do docCols ColDoLet [ appSep $ docLit $ Text.pack "let" - , ( if indentPolicy == IndentPolicyLeft - then docForceSingleline - else docSetBaseAndIndent - ) - $ return bindDoc + , let f = case indentPolicy of + IndentPolicyFree -> docSetBaseAndIndent + IndentPolicyLeft -> docForceSingleline + IndentPolicyMultiple -> docForceSingleline + in f $ return bindDoc ] , -- let -- bind = expr @@ -74,8 +74,8 @@ layoutStmt lstmt@(L _ stmt) = do -- let aaa = expra -- bbb = exprb -- ccc = exprc - addAlternativeCond (indentPolicy /= IndentPolicyLeft) - $ docSeq + -- TODO: Allow this for IndentPolicyMultiple when indentAmount = 4 + addAlternativeCond (indentPolicy == IndentPolicyFree) $ docSeq [ appSep $ docLit $ Text.pack "let" , docSetBaseAndIndent $ docLines $ return <$> bindDocs ] @@ -83,16 +83,14 @@ layoutStmt lstmt@(L _ stmt) = do -- aaa = expra -- bbb = exprb -- ccc = exprc - addAlternative $ - docAddBaseY BrIndentRegular $ docPar - (docLit $ Text.pack "let") - (docSetBaseAndIndent $ docLines $ return <$> bindDocs) + addAlternative $ docAddBaseY BrIndentRegular $ docPar + (docLit $ Text.pack "let") + (docSetBaseAndIndent $ docLines $ return <$> bindDocs) RecStmt stmts _ _ _ _ _ _ _ _ _ -> runFilteredAlternative $ do -- rec stmt1 -- stmt2 -- stmt3 - addAlternativeCond (indentPolicy /= IndentPolicyLeft) - $ docSeq + addAlternativeCond (indentPolicy == IndentPolicyFree) $ docSeq [ docLit (Text.pack "rec") , docSeparator , docSetBaseAndIndent $ docLines $ layoutStmt <$> stmts @@ -101,9 +99,9 @@ layoutStmt lstmt@(L _ stmt) = do -- stmt1 -- stmt2 -- stmt3 - addAlternative - $ docAddBaseY BrIndentRegular - $ docPar (docLit (Text.pack "rec")) (docLines $ layoutStmt <$> stmts) + addAlternative $ docAddBaseY BrIndentRegular $ docPar + (docLit (Text.pack "rec")) + (docLines $ layoutStmt <$> stmts) BodyStmt expr _ _ _ -> do expDoc <- docSharedWrapper layoutExpr expr docAddBaseY BrIndentRegular $ expDoc diff --git a/src/Language/Haskell/Brittany/Internal/Transformations/Alt.hs b/src/Language/Haskell/Brittany/Internal/Transformations/Alt.hs index f7ed523..5b833fd 100644 --- a/src/Language/Haskell/Brittany/Internal/Transformations/Alt.hs +++ b/src/Language/Haskell/Brittany/Internal/Transformations/Alt.hs @@ -142,17 +142,23 @@ transformAlts = BDFAddBaseY indent bd -> do acp <- mGet indAmount <- mAsk <&> _conf_layout .> _lconfig_indentAmount .> confUnpack + indPolicy <- mAsk <&> _conf_layout .> _lconfig_indentPolicy .> confUnpack let indAdd = case indent of BrIndentNone -> 0 BrIndentRegular -> indAmount BrIndentSpecial i -> i - mSet $ acp { _acp_indentPrep = max (_acp_indentPrep acp) indAdd } + let indAdd' = + if indPolicy == IndentPolicyMultiple + then + max 0 (indAdd - ((_acp_indent acp + indAdd) `mod` indAmount)) + else indAdd + mSet $ acp { _acp_indentPrep = max (_acp_indentPrep acp) indAdd' } r <- rec bd acp' <- mGet mSet $ acp' { _acp_indent = _acp_indent acp } return $ case indent of BrIndentNone -> r - BrIndentRegular -> reWrap $ BDFAddBaseY (BrIndentSpecial indAdd) r + BrIndentRegular -> reWrap $ BDFAddBaseY (BrIndentSpecial indAdd') r BrIndentSpecial i -> reWrap $ BDFAddBaseY (BrIndentSpecial i) r BDFBaseYPushCur bd -> do acp <- mGet From e91bb6aec979d26ceca93c7827cbceff444fa582 Mon Sep 17 00:00:00 2001 From: Lennart Spitzner Date: Tue, 1 May 2018 23:19:44 +0200 Subject: [PATCH 3/5] Clean up IndentPolicyMultiple --- .../40-indent-policy-multiple.blt | 3 -- .../Brittany/Internal/Layouters/Expr.hs | 42 +++++++++---------- 2 files changed, 20 insertions(+), 25 deletions(-) diff --git a/src-literatetests/40-indent-policy-multiple.blt b/src-literatetests/40-indent-policy-multiple.blt index 42b19ca..80288bd 100644 --- a/src-literatetests/40-indent-policy-multiple.blt +++ b/src-literatetests/40-indent-policy-multiple.blt @@ -8,14 +8,12 @@ #test long -- brittany { lconfig_indentAmount: 4, lconfig_indentPolicy: IndentPolicyMultiple } --- brittany { lconfig_columnAlignMode: { tag: ColumnAlignModeDisabled }} func = mweroiuxlskdfjlksjdflkjsdfljksldkjflkjsdflkj + mweroiuxlskdfjlksjdflkjsdfljksldkjflkjsdflkj #test let -- brittany { lconfig_indentAmount: 4, lconfig_indentPolicy: IndentPolicyMultiple } --- brittany { lconfig_columnAlignMode: { tag: ColumnAlignModeDisabled }} foo = do let aaaaaaaaaaaaaaaaaaaaaaaaaaaaaa = @@ -24,7 +22,6 @@ foo = do #test nested do-block -- brittany { lconfig_indentAmount: 4, lconfig_indentPolicy: IndentPolicyMultiple } --- brittany { lconfig_columnAlignMode: { tag: ColumnAlignModeDisabled }} foo = asdyf8asdf "ajsdfas" [ asjdf asyhf $ do diff --git a/src/Language/Haskell/Brittany/Internal/Layouters/Expr.hs b/src/Language/Haskell/Brittany/Internal/Layouters/Expr.hs index a9deffc..6e32798 100644 --- a/src/Language/Haskell/Brittany/Internal/Layouters/Expr.hs +++ b/src/Language/Haskell/Brittany/Internal/Layouters/Expr.hs @@ -540,12 +540,12 @@ layoutExpr lexpr@(L _ expr) = do mBindDocs <- mapM (fmap (fmap return) . docWrapNodeRest lexpr . return) =<< layoutLocalBinds binds let - ifIndentLeftElse :: a -> a -> a - ifIndentLeftElse x y = + ifIndentFreeElse :: a -> a -> a + ifIndentFreeElse x y = case indentPolicy of - IndentPolicyLeft -> x - IndentPolicyMultiple -> x - IndentPolicyFree -> y + IndentPolicyLeft -> y + IndentPolicyMultiple -> y + IndentPolicyFree -> x -- this `docSetBaseAndIndent` might seem out of place (especially the -- Indent part; setBase is necessary due to the use of docLines below), -- but is here due to ghc-exactprint's DP handling of "let" in @@ -566,7 +566,7 @@ layoutExpr lexpr@(L _ expr) = do [ docAlt [ docSeq [ appSep $ docLit $ Text.pack "let" - , ifIndentLeftElse docForceSingleline docSetBaseAndIndent + , ifIndentFreeElse docSetBaseAndIndent docForceSingleline $ bindDoc ] , docAddBaseY BrIndentRegular @@ -576,8 +576,8 @@ layoutExpr lexpr@(L _ expr) = do ] , docAlt [ docSeq - [ appSep $ docLit $ Text.pack $ ifIndentLeftElse "in" "in " - , ifIndentLeftElse docForceSingleline docSetBaseAndIndent expDoc1 + [ appSep $ docLit $ Text.pack $ ifIndentFreeElse "in " "in" + , ifIndentFreeElse docSetBaseAndIndent docForceSingleline expDoc1 ] , docAddBaseY BrIndentRegular $ docPar @@ -610,21 +610,19 @@ layoutExpr lexpr@(L _ expr) = do , docAddBaseY BrIndentRegular expDoc1 ] ] - addAlternativeCond (indentPolicy == IndentPolicyLeft) - $ docLines noHangingBinds - addAlternativeCond (indentPolicy == IndentPolicyMultiple) - $ docLines noHangingBinds - addAlternativeCond (indentPolicy == IndentPolicyFree) - $ docLines - [ docSeq - [ appSep $ docLit $ Text.pack "let" - , docSetBaseAndIndent $ docLines bindDocs + addAlternative $ case indentPolicy of + IndentPolicyLeft -> docLines noHangingBinds + IndentPolicyMultiple -> docLines noHangingBinds + IndentPolicyFree -> docLines + [ docSeq + [ appSep $ docLit $ Text.pack "let" + , docSetBaseAndIndent $ docLines bindDocs + ] + , docSeq + [ appSep $ docLit $ Text.pack "in " + , docSetBaseY expDoc1 + ] ] - , docSeq - [ appSep $ docLit $ Text.pack "in " - , docSetBaseY expDoc1 - ] - ] addAlternative $ docLines [ docAddBaseY BrIndentRegular From dd53948a23a2809630a754bf09c91de2ad051669 Mon Sep 17 00:00:00 2001 From: Lennart Spitzner Date: Tue, 1 May 2018 23:20:11 +0200 Subject: [PATCH 4/5] Fix IndentPolicyMultiple for indentAmount>4 --- .../40-indent-policy-multiple.blt | 18 ++++++-- .../Brittany/Internal/Transformations/Alt.hs | 44 +++++++++++-------- 2 files changed, 41 insertions(+), 21 deletions(-) diff --git a/src-literatetests/40-indent-policy-multiple.blt b/src-literatetests/40-indent-policy-multiple.blt index 80288bd..b75c726 100644 --- a/src-literatetests/40-indent-policy-multiple.blt +++ b/src-literatetests/40-indent-policy-multiple.blt @@ -12,14 +12,26 @@ func = mweroiuxlskdfjlksjdflkjsdfljksldkjflkjsdflkj + mweroiuxlskdfjlksjdflkjsdfljksldkjflkjsdflkj -#test let +#test let indAmount=4 -- brittany { lconfig_indentAmount: 4, lconfig_indentPolicy: IndentPolicyMultiple } foo = do - let - aaaaaaaaaaaaaaaaaaaaaaaaaaaaaa = + let aaaaaaaaaaaaaaaaaaaaaaaaaaaaaa = aaaaaaaaaaaaaaaaaaaaaaaaaaaaaa + aaaaaaaaaaaaaaaaaaaaaaaaaaaaaa foo +#test let indAmount=8 +-- brittany { lconfig_indentAmount: 8, lconfig_indentPolicy: IndentPolicyMultiple } +foo = do + let aaaaaaaaaaaaaaaaaaaaaaaaaaaaaa = + aaaaaaaaaaaaaaaaaaaaaaaaaaaaaa + aaaaaaaaaaaaaaaaaaaaaaaaaaaaaa + foo +foo = do + let aaaaaaaaaaaaaaaaaaaaaaaaaaaaaa = + aaaaaaaaaaaaaaaaaaaaaaaaaaaaaa + + aaaaaaaaaaaaaaaaaaaaaaaaaaaaaa + + aaaaaaaaaaaaaaaaaaaaaaaaaaaaaa + foo + #test nested do-block -- brittany { lconfig_indentAmount: 4, lconfig_indentPolicy: IndentPolicyMultiple } foo = asdyf8asdf diff --git a/src/Language/Haskell/Brittany/Internal/Transformations/Alt.hs b/src/Language/Haskell/Brittany/Internal/Transformations/Alt.hs index 5b833fd..7361ce6 100644 --- a/src/Language/Haskell/Brittany/Internal/Transformations/Alt.hs +++ b/src/Language/Haskell/Brittany/Internal/Transformations/Alt.hs @@ -141,24 +141,14 @@ transformAlts = BDFSeparator -> processSpacingSimple bdX $> bdX BDFAddBaseY indent bd -> do acp <- mGet - indAmount <- mAsk <&> _conf_layout .> _lconfig_indentAmount .> confUnpack - indPolicy <- mAsk <&> _conf_layout .> _lconfig_indentPolicy .> confUnpack - let indAdd = case indent of - BrIndentNone -> 0 - BrIndentRegular -> indAmount - BrIndentSpecial i -> i - let indAdd' = - if indPolicy == IndentPolicyMultiple - then - max 0 (indAdd - ((_acp_indent acp + indAdd) `mod` indAmount)) - else indAdd - mSet $ acp { _acp_indentPrep = max (_acp_indentPrep acp) indAdd' } + indAdd <- fixIndentationForMultiple acp indent + mSet $ acp { _acp_indentPrep = max (_acp_indentPrep acp) indAdd } r <- rec bd acp' <- mGet mSet $ acp' { _acp_indent = _acp_indent acp } return $ case indent of BrIndentNone -> r - BrIndentRegular -> reWrap $ BDFAddBaseY (BrIndentSpecial indAdd') r + BrIndentRegular -> reWrap $ BDFAddBaseY (BrIndentSpecial indAdd) r BrIndentSpecial i -> reWrap $ BDFAddBaseY (BrIndentSpecial i) r BDFBaseYPushCur bd -> do acp <- mGet @@ -321,11 +311,7 @@ transformAlts = return $ reWrap $ BDFLines (l':lr') BDFEnsureIndent indent bd -> do acp <- mGet - indAmount <- mAsk <&> _conf_layout .> _lconfig_indentAmount .> confUnpack - let indAdd = case indent of - BrIndentNone -> 0 - BrIndentRegular -> indAmount - BrIndentSpecial i -> i + indAdd <- fixIndentationForMultiple acp indent mSet $ acp { _acp_indentPrep = 0 -- TODO: i am not sure this is valid, in general. @@ -863,3 +849,25 @@ getSpacings limit bridoc = preFilterLimit <$> rec bridoc VerticalSpacingParSome i -> VerticalSpacingParSome $ x1 `max` i VerticalSpacingParNone -> VerticalSpacingParSome $ x1 VerticalSpacingParAlways i -> VerticalSpacingParAlways $ x1 `max` i + +fixIndentationForMultiple + :: (MonadMultiReader (CConfig Identity) m) => AltCurPos -> BrIndent -> m Int +fixIndentationForMultiple acp indent = do + indAmount <- mAsk <&> _conf_layout .> _lconfig_indentAmount .> confUnpack + let indAddRaw = case indent of + BrIndentNone -> 0 + BrIndentRegular -> indAmount + BrIndentSpecial i -> i + -- for IndentPolicyMultiple, we restrict the amount of added + -- indentation in such a manner that we end up on a multiple of the + -- base indentation. + indPolicy <- mAsk <&> _conf_layout .> _lconfig_indentPolicy .> confUnpack + pure $ if indPolicy == IndentPolicyMultiple + then + let indAddMultiple1 = + indAddRaw - ((_acp_indent acp + indAddRaw) `mod` indAmount) + indAddMultiple2 = if indAddMultiple1 <= 0 + then indAddMultiple1 + indAmount + else indAddMultiple1 + in indAddMultiple2 + else indAddRaw From 4973298f309f8d88f431f789b3bb421acc936bc6 Mon Sep 17 00:00:00 2001 From: Lennart Spitzner Date: Tue, 1 May 2018 23:21:31 +0200 Subject: [PATCH 5/5] Support same-line let decl when indentAmount>=4 --- .../Brittany/Internal/Layouters/Stmt.hs | 89 +++++++++++-------- 1 file changed, 50 insertions(+), 39 deletions(-) diff --git a/src/Language/Haskell/Brittany/Internal/Layouters/Stmt.hs b/src/Language/Haskell/Brittany/Internal/Layouters/Stmt.hs index 33b700e..7a9b922 100644 --- a/src/Language/Haskell/Brittany/Internal/Layouters/Stmt.hs +++ b/src/Language/Haskell/Brittany/Internal/Layouters/Stmt.hs @@ -13,7 +13,10 @@ import Language.Haskell.Brittany.Internal.Types import Language.Haskell.Brittany.Internal.LayouterBasics import Language.Haskell.Brittany.Internal.Config.Types -import GHC ( runGhc, GenLocated(L), moduleNameString ) +import GHC ( runGhc + , GenLocated(L) + , moduleNameString + ) import HsSyn import Name import qualified FastString @@ -28,6 +31,8 @@ import {-# SOURCE #-} Language.Haskell.Brittany.Internal.Layouters.Expr layoutStmt :: ToBriDoc' (StmtLR GhcPs GhcPs (LHsExpr GhcPs)) layoutStmt lstmt@(L _ stmt) = do indentPolicy <- mAsk <&> _conf_layout .> _lconfig_indentPolicy .> confUnpack + indentAmount :: Int <- + mAsk <&> _conf_layout .> _lconfig_indentAmount .> confUnpack docWrapNode lstmt $ case stmt of LastStmt body False _ -> do layoutExpr body @@ -47,45 +52,51 @@ layoutStmt lstmt@(L _ stmt) = do $ docPar (docLit $ Text.pack "<-") (expDoc) ] ] - LetStmt binds -> layoutLocalBinds binds >>= \case - Nothing -> docLit $ Text.pack "let" -- i just tested - -- it, and it is - -- indeed allowed. - -- heh. - Just [] -> docLit $ Text.pack "let" -- this probably never happens - Just [bindDoc] -> docAlt - [ -- let bind = expr - docCols - ColDoLet - [ appSep $ docLit $ Text.pack "let" - , let f = case indentPolicy of - IndentPolicyFree -> docSetBaseAndIndent - IndentPolicyLeft -> docForceSingleline - IndentPolicyMultiple -> docForceSingleline - in f $ return bindDoc + LetStmt binds -> do + let isFree = indentPolicy == IndentPolicyFree + let indentFourPlus = indentAmount >= 4 + layoutLocalBinds binds >>= \case + Nothing -> docLit $ Text.pack "let" + -- i just tested the above, and it is indeed allowed. heh. + Just [] -> docLit $ Text.pack "let" -- this probably never happens + Just [bindDoc] -> docAlt + [ -- let bind = expr + docCols + ColDoLet + [ appSep $ docLit $ Text.pack "let" + , let + f = case indentPolicy of + IndentPolicyFree -> docSetBaseAndIndent + IndentPolicyLeft -> docForceSingleline + IndentPolicyMultiple | indentFourPlus -> docSetBaseAndIndent + | otherwise -> docForceSingleline + in f $ return bindDoc + ] + , -- let + -- bind = expr + docAddBaseY BrIndentRegular $ docPar + (docLit $ Text.pack "let") + (docSetBaseAndIndent $ return bindDoc) ] - , -- let - -- bind = expr - docAddBaseY BrIndentRegular $ docPar - (docLit $ Text.pack "let") - (docSetBaseAndIndent $ return bindDoc) - ] - Just bindDocs -> runFilteredAlternative $ do - -- let aaa = expra - -- bbb = exprb - -- ccc = exprc - -- TODO: Allow this for IndentPolicyMultiple when indentAmount = 4 - addAlternativeCond (indentPolicy == IndentPolicyFree) $ docSeq - [ appSep $ docLit $ Text.pack "let" - , docSetBaseAndIndent $ docLines $ return <$> bindDocs - ] - -- let - -- aaa = expra - -- bbb = exprb - -- ccc = exprc - addAlternative $ docAddBaseY BrIndentRegular $ docPar - (docLit $ Text.pack "let") - (docSetBaseAndIndent $ docLines $ return <$> bindDocs) + Just bindDocs -> runFilteredAlternative $ do + -- let aaa = expra + -- bbb = exprb + -- ccc = exprc + addAlternativeCond (isFree || indentFourPlus) $ docSeq + [ appSep $ docLit $ Text.pack "let" + , let f = if indentFourPlus + then docEnsureIndent BrIndentRegular + else docSetBaseAndIndent + in f $ docLines $ return <$> bindDocs + ] + -- let + -- aaa = expra + -- bbb = exprb + -- ccc = exprc + addAlternativeCond (not indentFourPlus) + $ docAddBaseY BrIndentRegular + $ docPar (docLit $ Text.pack "let") + (docSetBaseAndIndent $ docLines $ return <$> bindDocs) RecStmt stmts _ _ _ _ _ _ _ _ _ -> runFilteredAlternative $ do -- rec stmt1 -- stmt2