From bcdd05848569c5381eeebf43558b31b1d8007758 Mon Sep 17 00:00:00 2001 From: Lennart Spitzner <hexagoxel@hexagoxel.de> Date: Tue, 19 Dec 2017 15:28:52 +0100 Subject: [PATCH 01/34] Update README.md for stackage lts release --- README.md | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/README.md b/README.md index 3196b27..c7bd461 100644 --- a/README.md +++ b/README.md @@ -52,7 +52,7 @@ log the size of the input, but _not_ the full requests.) # Other usage notes - Supports GHC versions `8.0.*` and `8.2.*`. -- as of November'17, `brittany` is available on stackage nightly. +- included in stackage with lts>=10.0 (or nightlies dating to >=2017-11-15) - config (file) documentation is lacking. - some config values can not be configured via commandline yet. - uses/creates user config file in `~/.config/brittany/config.yaml`; @@ -84,11 +84,11 @@ log the size of the input, but _not_ the full requests.) - via `stack` using a sufficiently recent stackage snapshot (dated to >= 2017-11-15) ~~~~.sh - stack install brittany # --resolver=nightly-2017-11-15 + stack install brittany # --resolver lts-10.0 ~~~~ - (alternatively, should nightlies be unreliable, or you want to use ghc-8.0 or something, then - cloning the repo and doing `stack install` will use an lts resolver.) + (earlier ltss did not include `brittany` yet, but the repo should contain a + `stack.yaml` that works with ghc-8.0.) - on ArchLinux via [the britanny AUR package](https://aur.archlinux.org/packages/brittany/) using `aura`: From f920f4714d976cef33b3557fc098e152879f9991 Mon Sep 17 00:00:00 2001 From: Lennart Spitzner <hexagoxel@hexagoxel.de> Date: Thu, 21 Dec 2017 21:45:29 +0100 Subject: [PATCH 02/34] Fix maximum on empty list, fixes #88 --- src/Language/Haskell/Brittany/Internal/Backend.hs | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/src/Language/Haskell/Brittany/Internal/Backend.hs b/src/Language/Haskell/Brittany/Internal/Backend.hs index 44264d4..c121eaf 100644 --- a/src/Language/Haskell/Brittany/Internal/Backend.hs +++ b/src/Language/Haskell/Brittany/Internal/Backend.hs @@ -352,7 +352,11 @@ alignColsLines bridocs = do -- colInfos `forM_` \colInfo -> do -- maxZipper xs [] = xs -- maxZipper (x:xr) (y:yr) = max x y : maxZipper xr yr colAggregation :: [Int] -> Int - colAggregation xs = maximum [ x | x <- xs, x < minimum xs + alignMax ] + colAggregation [] = 0 -- this probably cannot happen the way we call + -- this function, because _cbs_map only ever + -- contains nonempty Seqs. + colAggregation xs = maximum [ x | x <- xs, x <= minimum xs + alignMax' ] + where alignMax' = max 0 alignMax processedMap :: ColMap2 processedMap = From 0f3ee76944d041c5c36bff828f5e1553d4e198cd Mon Sep 17 00:00:00 2001 From: Lennart Spitzner <hexagoxel@hexagoxel.de> Date: Wed, 27 Dec 2017 23:26:18 +0100 Subject: [PATCH 03/34] Fix shebang handling with stdin input Fixes #92 probably should update upstream (ghc-exactprint) --- brittany.cabal | 2 +- .../Brittany/Internal/ExactPrintUtils.hs | 51 +++++++++++++++++-- .../Haskell/Brittany/Internal/PreludeUtils.hs | 3 ++ 3 files changed, 51 insertions(+), 5 deletions(-) diff --git a/brittany.cabal b/brittany.cabal index bfba1dc..42277ad 100644 --- a/brittany.cabal +++ b/brittany.cabal @@ -82,7 +82,7 @@ library { { base >=4.9 && <4.11 , ghc >=8.0.1 && <8.3 , ghc-paths >=0.1.0.9 && <0.2 - , ghc-exactprint >=0.5.3.0 && <0.6 + , ghc-exactprint >=0.5.3.0 && <0.5.6 , transformers >=0.5.2.0 && <0.6 , containers >=0.5.7.1 && <0.6 , mtl >=2.2.1 && <2.3 diff --git a/src/Language/Haskell/Brittany/Internal/ExactPrintUtils.hs b/src/Language/Haskell/Brittany/Internal/ExactPrintUtils.hs index d0f481c..7494d9e 100644 --- a/src/Language/Haskell/Brittany/Internal/ExactPrintUtils.hs +++ b/src/Language/Haskell/Brittany/Internal/ExactPrintUtils.hs @@ -24,11 +24,17 @@ import qualified DynFlags as GHC import qualified GHC as GHC hiding (parseModule) import qualified Parser as GHC import qualified SrcLoc as GHC +import qualified FastString as GHC +import qualified GHC as GHC hiding (parseModule) +import qualified Lexer as GHC +import qualified StringBuffer as GHC +import qualified Outputable as GHC import RdrName ( RdrName(..) ) import HsSyn import SrcLoc ( SrcSpan, Located ) import RdrName ( RdrName(..) ) + import qualified Language.Haskell.GHC.ExactPrint as ExactPrint import qualified Language.Haskell.GHC.ExactPrint.Annotate as ExactPrint import qualified Language.Haskell.GHC.ExactPrint.Types as ExactPrint @@ -106,10 +112,47 @@ parseModuleFromString args fp dynCheck str = $ ExceptT.throwE $ "when parsing ghc flags: encountered warnings: " ++ show (warnings <&> \(L _ s) -> s) - x <- ExceptT.ExceptT $ liftIO $ dynCheck dflags1 - either (\(span, err) -> ExceptT.throwE $ show span ++ ": " ++ err) - (\(a, m) -> pure (a, m, x)) - $ ExactPrint.parseWith dflags1 fp GHC.parseModule str + dynCheckRes <- ExceptT.ExceptT $ liftIO $ dynCheck dflags1 + let res = parseModulePure dflags1 fp str + case res of + Left (span, err) -> ExceptT.throwE $ show span ++ ": " ++ err + Right (a , m ) -> pure (a, m, dynCheckRes) + +----------- + +-- this function should move to ghc-exactprint. btw, we can deprecate/remove +-- the `parseModuleFromString` function that I added initially to +-- ghc-exactprint. +parseModulePure + :: GHC.DynFlags + -> System.IO.FilePath + -> String + -> Either (SrcSpan, String) (ExactPrint.Anns, GHC.ParsedSource) +parseModulePure dflags fileName str = + let (str1, lp) = ExactPrint.stripLinePragmas str + res = case runParser GHC.parseModule dflags fileName str1 of + GHC.PFailed ss m -> Left (ss, GHC.showSDoc dflags m) + GHC.POk x pmod -> Right $ (mkApiAnns x, lp, dflags, pmod) + in ExactPrint.postParseTransform res ExactPrint.normalLayout + +-- copied from exactprint until exactprint exposes a proper interface. +runParser + :: GHC.P a + -> GHC.DynFlags + -> System.IO.FilePath + -> String + -> GHC.ParseResult a +runParser parser flags filename str = GHC.unP parser parseState + where + location = GHC.mkRealSrcLoc (GHC.mkFastString filename) 1 1 + buffer = GHC.stringToStringBuffer str + parseState = GHC.mkPState flags buffer location +mkApiAnns :: GHC.PState -> GHC.ApiAnns +mkApiAnns pstate = + ( Map.fromListWith (++) . GHC.annotations $ pstate + , Map.fromList + ((GHC.noSrcSpan, GHC.comment_q pstate) : GHC.annotations_comments pstate) + ) ----------- diff --git a/src/Language/Haskell/Brittany/Internal/PreludeUtils.hs b/src/Language/Haskell/Brittany/Internal/PreludeUtils.hs index d34690c..88f2894 100644 --- a/src/Language/Haskell/Brittany/Internal/PreludeUtils.hs +++ b/src/Language/Haskell/Brittany/Internal/PreludeUtils.hs @@ -46,6 +46,9 @@ traceFunctionWith name s1 s2 f x = putStrErrLn :: String -> IO () putStrErrLn s = hPutStrLn stderr s +putStrErr :: String -> IO () +putStrErr s = hPutStr stderr s + printErr :: Show a => a -> IO () printErr = putStrErrLn . show From 292bd3d216f679613c33b8a0d568af95c9f01f75 Mon Sep 17 00:00:00 2001 From: Tuncer Ayaz <tuncer.ayaz@gmail.com> Date: Sat, 23 Dec 2017 00:12:51 +0000 Subject: [PATCH 04/34] stack.yaml: update to lts-10.0 --- stack.yaml | 9 +-------- 1 file changed, 1 insertion(+), 8 deletions(-) diff --git a/stack.yaml b/stack.yaml index 539cd6d..74e27d2 100644 --- a/stack.yaml +++ b/stack.yaml @@ -1,11 +1,4 @@ -resolver: lts-9.0 - -extra-deps: - - monad-memo-0.4.1 - - czipwith-1.0.0.0 - - butcher-1.2.0.0 - - data-tree-print-0.1.0.0 - - deque-0.2 +resolver: lts-10.0 packages: - . From 8137035ac2e6144200bec6903489904350fa5a44 Mon Sep 17 00:00:00 2001 From: Tuncer Ayaz <tuncer.ayaz@gmail.com> Date: Sat, 23 Dec 2017 01:59:49 +0000 Subject: [PATCH 05/34] Resurrect old stack.yaml for lts-9.0 ci job --- .travis.yml | 2 +- stack-lts-9.0.yaml | 11 +++++++++++ 2 files changed, 12 insertions(+), 1 deletion(-) create mode 100644 stack-lts-9.0.yaml diff --git a/.travis.yml b/.travis.yml index e1c64bf..6577274 100644 --- a/.travis.yml +++ b/.travis.yml @@ -115,7 +115,7 @@ matrix: #- env: BUILD=stack ARGS="--resolver lts-7" # compiler: ": #stack 8.0.1" # addons: {apt: {packages: [libgmp-dev]}} - - env: BUILD=stack ARGS="--resolver lts-8" + - env: BUILD=stack ARGS="--stack-yaml stack-lts-9.0.yaml" compiler: ": #stack 8.0.2" addons: {apt: {packages: [libgmp-dev]}} diff --git a/stack-lts-9.0.yaml b/stack-lts-9.0.yaml new file mode 100644 index 0000000..539cd6d --- /dev/null +++ b/stack-lts-9.0.yaml @@ -0,0 +1,11 @@ +resolver: lts-9.0 + +extra-deps: + - monad-memo-0.4.1 + - czipwith-1.0.0.0 + - butcher-1.2.0.0 + - data-tree-print-0.1.0.0 + - deque-0.2 + +packages: + - . From ac9d505334204de5e0833c045b83c29868ccc2c5 Mon Sep 17 00:00:00 2001 From: Lennart Spitzner <hexagoxel@hexagoxel.de> Date: Thu, 28 Dec 2017 17:30:26 +0100 Subject: [PATCH 06/34] Rename the ghc-8.0.2 stack yaml --- .travis.yml | 2 +- stack-lts-9.0.yaml => stack-8.0.2.yaml | 0 2 files changed, 1 insertion(+), 1 deletion(-) rename stack-lts-9.0.yaml => stack-8.0.2.yaml (100%) diff --git a/.travis.yml b/.travis.yml index 6577274..50a0a71 100644 --- a/.travis.yml +++ b/.travis.yml @@ -115,7 +115,7 @@ matrix: #- env: BUILD=stack ARGS="--resolver lts-7" # compiler: ": #stack 8.0.1" # addons: {apt: {packages: [libgmp-dev]}} - - env: BUILD=stack ARGS="--stack-yaml stack-lts-9.0.yaml" + - env: BUILD=stack ARGS="--stack-yaml stack-8.0.2.yaml" compiler: ": #stack 8.0.2" addons: {apt: {packages: [libgmp-dev]}} diff --git a/stack-lts-9.0.yaml b/stack-8.0.2.yaml similarity index 100% rename from stack-lts-9.0.yaml rename to stack-8.0.2.yaml From 43abab2dd2c87c7e9547e2e2b43270dde0da178e Mon Sep 17 00:00:00 2001 From: Lennart Spitzner <hexagoxel@hexagoxel.de> Date: Thu, 28 Dec 2017 20:46:03 +0100 Subject: [PATCH 07/34] Remove space after opening parenthesis (fixes #87) --- src-literatetests/15-regressions.blt | 2 +- src-literatetests/tests-context-free.blt | 4 ++-- src/Language/Haskell/Brittany/Internal/Layouters/Expr.hs | 2 +- 3 files changed, 4 insertions(+), 4 deletions(-) diff --git a/src-literatetests/15-regressions.blt b/src-literatetests/15-regressions.blt index c2290ba..0fbc830 100644 --- a/src-literatetests/15-regressions.blt +++ b/src-literatetests/15-regressions.blt @@ -219,7 +219,7 @@ showPackageDetailedInfo pkginfo = , entry "Versions installed" installedVersions - ( altText + (altText null (if hasLib pkginfo then "[ Not installed ]" else "[ Unknown ]") ) diff --git a/src-literatetests/tests-context-free.blt b/src-literatetests/tests-context-free.blt index 7700adb..0918e60 100644 --- a/src-literatetests/tests-context-free.blt +++ b/src-literatetests/tests-context-free.blt @@ -714,7 +714,7 @@ func #test some indentation thingy func = - ( lkjadljasldjalskdjaldjalsdjkalsdjlaksdjlasjdlajsaldskj + (lkjadljasldjalskdjaldjalsdjkalsdjlaksdjlasjdlajsaldskj $ abc $ def $ ghi @@ -840,7 +840,7 @@ showPackageDetailedInfo pkginfo = , entry "Versions installed" installedVersions - ( altText + (altText null (if hasLib pkginfo then "[ Not installed ]" else "[ Unknown ]") ) diff --git a/src/Language/Haskell/Brittany/Internal/Layouters/Expr.hs b/src/Language/Haskell/Brittany/Internal/Layouters/Expr.hs index 2eb1863..1462c56 100644 --- a/src/Language/Haskell/Brittany/Internal/Layouters/Expr.hs +++ b/src/Language/Haskell/Brittany/Internal/Layouters/Expr.hs @@ -327,7 +327,7 @@ layoutExpr lexpr@(L _ expr) = do ] , docSetBaseY $ docLines [ docCols ColOpPrefix - [ docParenLSep + [ docLit $ Text.pack "(" , docAddBaseY (BrIndentSpecial 2) innerExpDoc ] , docLit $ Text.pack ")" From 37e355fea57133302f0fc4b27cc358b5b3745466 Mon Sep 17 00:00:00 2001 From: Lennart Spitzner <hexagoxel@hexagoxel.de> Date: Thu, 28 Dec 2017 21:38:31 +0100 Subject: [PATCH 08/34] Support hanging type signature config option --- src-literatetests/Main.hs | 1 + src-unittests/TestUtils.hs | 1 + .../Haskell/Brittany/Internal/Config.hs | 2 + .../Haskell/Brittany/Internal/Config/Types.hs | 11 +++++ .../Brittany/Internal/Layouters/Decl.hs | 48 ++++++++++++------- 5 files changed, 47 insertions(+), 16 deletions(-) diff --git a/src-literatetests/Main.hs b/src-literatetests/Main.hs index 938aca6..5567e68 100644 --- a/src-literatetests/Main.hs +++ b/src-literatetests/Main.hs @@ -173,6 +173,7 @@ defaultTestConfig = Config , _lconfig_columnAlignMode = coerce (ColumnAlignModeMajority 0.7) , _lconfig_alignmentLimit = coerce (30 :: Int) , _lconfig_alignmentBreakOnMultiline = coerce True + , _lconfig_hangingTypeSignature = coerce False } , _conf_errorHandling = (_conf_errorHandling staticDefaultConfig) { _econf_omit_output_valid_check = coerce True diff --git a/src-unittests/TestUtils.hs b/src-unittests/TestUtils.hs index 30eac3e..1ee5203 100644 --- a/src-unittests/TestUtils.hs +++ b/src-unittests/TestUtils.hs @@ -55,6 +55,7 @@ defaultTestConfig = Config , _lconfig_columnAlignMode = coerce (ColumnAlignModeMajority 0.7) , _lconfig_alignmentLimit = coerce (30 :: Int) , _lconfig_alignmentBreakOnMultiline = coerce True + , _lconfig_hangingTypeSignature = coerce False } , _conf_errorHandling = (_conf_errorHandling staticDefaultConfig) { _econf_ExactPrintFallback = coerce ExactPrintFallbackModeNever diff --git a/src/Language/Haskell/Brittany/Internal/Config.hs b/src/Language/Haskell/Brittany/Internal/Config.hs index baaca1f..f225545 100644 --- a/src/Language/Haskell/Brittany/Internal/Config.hs +++ b/src/Language/Haskell/Brittany/Internal/Config.hs @@ -63,6 +63,7 @@ staticDefaultConfig = Config , _lconfig_columnAlignMode = coerce (ColumnAlignModeMajority 0.7) , _lconfig_alignmentLimit = coerce (30 :: Int) , _lconfig_alignmentBreakOnMultiline = coerce True + , _lconfig_hangingTypeSignature = coerce False } , _conf_errorHandling = ErrorHandlingConfig { _econf_produceOutputOnErrors = coerce False @@ -156,6 +157,7 @@ configParser = do , _lconfig_columnAlignMode = mempty , _lconfig_alignmentLimit = mempty , _lconfig_alignmentBreakOnMultiline = mempty + , _lconfig_hangingTypeSignature = mempty } , _conf_errorHandling = ErrorHandlingConfig { _econf_produceOutputOnErrors = wrapLast $ falseToNothing outputOnErrors diff --git a/src/Language/Haskell/Brittany/Internal/Config/Types.hs b/src/Language/Haskell/Brittany/Internal/Config/Types.hs index d726d8a..f2530b0 100644 --- a/src/Language/Haskell/Brittany/Internal/Config/Types.hs +++ b/src/Language/Haskell/Brittany/Internal/Config/Types.hs @@ -73,6 +73,17 @@ data CLayoutConfig f = LayoutConfig -- short <- some more stuff -- that requires two lines -- loooooooong <- stuff + , _lconfig_hangingTypeSignature :: f (Last Bool) + -- Do not put "::" in a new line, and use hanging indentation for the + -- signature, i.e.: + -- func :: SomeLongStuff + -- -> SomeLongStuff + -- instead of the usual + -- func + -- :: SomeLongStuff + -- -> SomeLongStuff + -- As usual for hanging indentation, the result will be + -- context-sensitive (in the function name). } deriving (Generic) diff --git a/src/Language/Haskell/Brittany/Internal/Layouters/Decl.hs b/src/Language/Haskell/Brittany/Internal/Layouters/Decl.hs index 30e26c2..8724291 100644 --- a/src/Language/Haskell/Brittany/Internal/Layouters/Decl.hs +++ b/src/Language/Haskell/Brittany/Internal/Layouters/Decl.hs @@ -52,23 +52,39 @@ layoutSig lsig@(L _loc sig) = case sig of let nameStr = Text.intercalate (Text.pack ", ") $ nameStrs typeDoc <- docSharedWrapper layoutType typ hasComments <- hasAnyCommentsBelow lsig - docAlt - $ [ docSeq - [ appSep $ docWrapNodeRest lsig $ docLit nameStr - , appSep $ docLit $ Text.pack "::" - , docForceSingleline typeDoc - ] - | not hasComments - ] - ++ [ docAddBaseY BrIndentRegular $ docPar - (docWrapNodeRest lsig $ docLit nameStr) - ( docCols - ColTyOpPrefix - [ docLit $ Text.pack ":: " - , docAddBaseY (BrIndentSpecial 3) $ typeDoc + shouldBeHanging <- mAsk + <&> _conf_layout + .> _lconfig_hangingTypeSignature + .> confUnpack + if shouldBeHanging + then docSeq + [ appSep $ docWrapNodeRest lsig $ docLit nameStr + , docSetBaseY $ docLines + [ docCols + ColTyOpPrefix + [ docLit $ Text.pack ":: " + , docAddBaseY (BrIndentSpecial 3) $ typeDoc + ] + ] + ] + else + docAlt + $ [ docSeq + [ appSep $ docWrapNodeRest lsig $ docLit nameStr + , appSep $ docLit $ Text.pack "::" + , docForceSingleline typeDoc + ] + | not hasComments + ] + ++ [ docAddBaseY BrIndentRegular $ docPar + (docWrapNodeRest lsig $ docLit nameStr) + ( docCols + ColTyOpPrefix + [ docLit $ Text.pack ":: " + , docAddBaseY (BrIndentSpecial 3) $ typeDoc + ] + ) ] - ) - ] InlineSig name (InlinePragma _ spec _arity phaseAct conlike) -> docWrapNode lsig $ do nameStr <- lrdrNameToTextAnn name From f1b49b082fec2e4ca1c2dc4de7773546daf13763 Mon Sep 17 00:00:00 2001 From: Evan Rutledge Borden <evan@evan-borden.com> Date: Sun, 31 Dec 2017 00:04:53 -0500 Subject: [PATCH 09/34] Format let and in on a single line if they fit The following is wasteful of vertical space: ``` _ = let longIdentifierForShortValue = 1 in longIdentifierForShortValue + longIdentifierForShortValue ``` We should format it on two lines if possible. ``` _ = let longIdentifierForShortValue = 1 in longIdentifierForShortValue + longIdentifierForShortValue ``` This commit also allows for a mix of variations: ``` _ = let longIdentifierForShortValue = 1 in longIdentifierForShortValue + longIdentifierForShortValue _ = let longIdentifierForShortValue = 1 in longIdentifierForShortValue + longIdentifierForShortValue ``` --- src-literatetests/tests-context-free.blt | 5 ++ .../Brittany/Internal/Layouters/Expr.hs | 54 +++++++++---------- 2 files changed, 32 insertions(+), 27 deletions(-) diff --git a/src-literatetests/tests-context-free.blt b/src-literatetests/tests-context-free.blt index 0918e60..e8303cd 100644 --- a/src-literatetests/tests-context-free.blt +++ b/src-literatetests/tests-context-free.blt @@ -510,6 +510,11 @@ func = (abc, def) func = (lakjsdlajsdljasdlkjasldjasldjasldjalsdjlaskjd , lakjsdlajsdljasdlkjasldjasldjasldjalsdjlaskjd) +#test let in on single line +foo = + let longIdentifierForShortValue = 1 + in longIdentifierForShortValue + longIdentifierForShortValue + ############################################################################### diff --git a/src/Language/Haskell/Brittany/Internal/Layouters/Expr.hs b/src/Language/Haskell/Brittany/Internal/Layouters/Expr.hs index 1462c56..6e6929f 100644 --- a/src/Language/Haskell/Brittany/Internal/Layouters/Expr.hs +++ b/src/Language/Haskell/Brittany/Internal/Layouters/Expr.hs @@ -531,6 +531,9 @@ layoutExpr lexpr@(L _ expr) = do HsLet binds exp1 -> do expDoc1 <- docSharedWrapper layoutExpr exp1 mBindDocs <- layoutLocalBinds binds + let + whenIndentLeftOr x y = + if indentPolicy == IndentPolicyLeft then x else y -- this `docSetIndentLevel` might seem out of place, but is here due to -- ghc-exactprint's DP handling of "let" in particular. -- Just pushing another indentation level is a straightforward approach @@ -538,39 +541,36 @@ layoutExpr lexpr@(L _ expr) = do -- if "let" is moved horizontally as part of the transformation, as the -- comments before the first let item are moved horizontally with it. docSetIndentLevel $ case mBindDocs of - Just [bindDoc] -> docAltFilter - [ ( True - , docSeq + Just [bindDoc] -> docAlt + [ docSeq [ appSep $ docLit $ Text.pack "let" , appSep $ docForceSingleline $ return bindDoc , appSep $ docLit $ Text.pack "in" , docForceSingleline $ expDoc1 ] - ) - , ( indentPolicy /= IndentPolicyLeft - , docLines - [ docSeq - [ appSep $ docLit $ Text.pack "let" - , docSetBaseAndIndent $ return bindDoc - ] - , docSeq - [ appSep $ docLit $ Text.pack "in " - , docSetBaseY $ expDoc1 - ] + , docLines + [ docAlt + [ docSeq + [ appSep $ docLit $ Text.pack "let" + , whenIndentLeftOr docForceSingleline docSetBaseAndIndent + $ return bindDoc + ] + , docAddBaseY BrIndentRegular + $ docPar + (appSep $ docLit $ Text.pack "let") + (docSetBaseAndIndent $ return bindDoc) + ] + , docAlt + [ docSeq + [ whenIndentLeftOr id appSep $ docLit $ Text.pack "in " + , whenIndentLeftOr docForceSingleline docSetBaseAndIndent expDoc1 + ] + , docAddBaseY BrIndentRegular + $ docPar + (appSep $ docLit $ Text.pack "in") + (docSetBaseY $ expDoc1) + ] ] - ) - , ( True - , docLines - [ docAddBaseY BrIndentRegular - $ docPar - (appSep $ docLit $ Text.pack "let") - (docSetBaseAndIndent $ return bindDoc) - , docAddBaseY BrIndentRegular - $ docPar - (appSep $ docLit $ Text.pack "in") - (docSetBaseY $ expDoc1) - ] - ) ] Just bindDocs@(_:_) -> docAltFilter --either From cab12975851076e568c839471ce46830a3948dfc Mon Sep 17 00:00:00 2001 From: Evan Rutledge Borden <evan@evan-borden.com> Date: Sun, 31 Dec 2017 00:11:10 -0500 Subject: [PATCH 10/34] Change function name to if/else --- src/Language/Haskell/Brittany/Internal/Layouters/Expr.hs | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/Language/Haskell/Brittany/Internal/Layouters/Expr.hs b/src/Language/Haskell/Brittany/Internal/Layouters/Expr.hs index 6e6929f..fcf69b4 100644 --- a/src/Language/Haskell/Brittany/Internal/Layouters/Expr.hs +++ b/src/Language/Haskell/Brittany/Internal/Layouters/Expr.hs @@ -532,7 +532,7 @@ layoutExpr lexpr@(L _ expr) = do expDoc1 <- docSharedWrapper layoutExpr exp1 mBindDocs <- layoutLocalBinds binds let - whenIndentLeftOr x y = + ifIndentLeftElse x y = if indentPolicy == IndentPolicyLeft then x else y -- this `docSetIndentLevel` might seem out of place, but is here due to -- ghc-exactprint's DP handling of "let" in particular. @@ -552,7 +552,7 @@ layoutExpr lexpr@(L _ expr) = do [ docAlt [ docSeq [ appSep $ docLit $ Text.pack "let" - , whenIndentLeftOr docForceSingleline docSetBaseAndIndent + , ifIndentLeftElse docForceSingleline docSetBaseAndIndent $ return bindDoc ] , docAddBaseY BrIndentRegular @@ -562,8 +562,8 @@ layoutExpr lexpr@(L _ expr) = do ] , docAlt [ docSeq - [ whenIndentLeftOr id appSep $ docLit $ Text.pack "in " - , whenIndentLeftOr docForceSingleline docSetBaseAndIndent expDoc1 + [ ifIndentLeftElse id appSep $ docLit $ Text.pack "in " + , ifIndentLeftElse docForceSingleline docSetBaseAndIndent expDoc1 ] , docAddBaseY BrIndentRegular $ docPar From 8fe9ba1f43b753c2522a37aece27e4bd9c523502 Mon Sep 17 00:00:00 2001 From: Lennart Spitzner <hexagoxel@hexagoxel.de> Date: Sat, 13 Jan 2018 18:02:00 +0100 Subject: [PATCH 11/34] Update readme: Add editor integration paragraph --- README.md | 13 +++++++++++++ 1 file changed, 13 insertions(+) diff --git a/README.md b/README.md index c7bd461..ba6fe36 100644 --- a/README.md +++ b/README.md @@ -96,6 +96,19 @@ log the size of the input, but _not_ the full requests.) aura -A brittany ~~~~ +# Editor Integration + +#### Sublime text + [In this gist](https://gist.github.com/lspitzner/097c33177248a65e7657f0c6d0d12075) + I have described a haskell setup that includes a shortcut to run brittany formatting. +#### VSCode + [This extension](https://marketplace.visualstudio.com/items?itemName=MaxGabriel.brittany) + connects commandline `brittany` to VSCode formatting API. Thanks to Max Garbriel. +#### Via HIE + [haskell-ide-engine](https://github.com/haskell/haskell-ide-engine) + includes a `brittany` plugin that directly uses the brittany library. + Relevant for any editors that properly support the language-server-protocol. + # Usage - Default mode of operation: Transform a single module, from `stdin` to `stdout`. From 37bc36f10a8924552bb666104bc92f07fc58732a Mon Sep 17 00:00:00 2001 From: Lennart Spitzner <hexagoxel@hexagoxel.de> Date: Sat, 13 Jan 2018 18:05:21 +0100 Subject: [PATCH 12/34] Update README.md --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index ba6fe36..3850fbd 100644 --- a/README.md +++ b/README.md @@ -103,7 +103,7 @@ log the size of the input, but _not_ the full requests.) I have described a haskell setup that includes a shortcut to run brittany formatting. #### VSCode [This extension](https://marketplace.visualstudio.com/items?itemName=MaxGabriel.brittany) - connects commandline `brittany` to VSCode formatting API. Thanks to Max Garbriel. + connects commandline `brittany` to VSCode formatting API. Thanks to @MaxGarbriel. #### Via HIE [haskell-ide-engine](https://github.com/haskell/haskell-ide-engine) includes a `brittany` plugin that directly uses the brittany library. From e788ac9afdc7210aecf1e24d698859cf785458b5 Mon Sep 17 00:00:00 2001 From: Lennart Spitzner <hexagoxel@hexagoxel.de> Date: Sat, 13 Jan 2018 18:31:39 +0100 Subject: [PATCH 13/34] Minor fixup in Main.hs for next butcher release --- src-brittany/Main.hs | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/src-brittany/Main.hs b/src-brittany/Main.hs index 046c830..56aa928 100644 --- a/src-brittany/Main.hs +++ b/src-brittany/Main.hs @@ -140,16 +140,16 @@ mainCmdParser helpDesc = do "" ["write-mode"] "(display|inplace)" - Flag - { _flag_help = Just $ PP.vcat + ( flagHelp + ( PP.vcat [ PP.text "display: output for any input(s) goes to stdout" , PP.text "inplace: override respective input file (without backup!)" ] - , _flag_default = Just Display - } + ) + <> flagDefault Display + ) inputParams <- addParamNoFlagStrings "PATH" (paramHelpStr "paths to input haskell source files") reorderStop - desc <- peekCmdDesc addCmdImpl $ void $ do when printLicense $ do print licenseDoc @@ -161,7 +161,7 @@ mainCmdParser helpDesc = do putStrLn $ "There is NO WARRANTY, to the extent permitted by law." System.Exit.exitSuccess when printHelp $ do - liftIO $ print $ ppHelpShallow desc + liftIO $ print $ ppHelpShallow helpDesc System.Exit.exitSuccess let inputPaths = if null inputParams then [Nothing] else map Just inputParams From 399e2f4f43a4fad1ddf68da6f065d0d16ea08991 Mon Sep 17 00:00:00 2001 From: Lennart Spitzner <hexagoxel@hexagoxel.de> Date: Sat, 13 Jan 2018 18:41:51 +0100 Subject: [PATCH 14/34] Minor cleanups --- src/Language/Haskell/Brittany/Internal/Layouters/Expr.hs | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/src/Language/Haskell/Brittany/Internal/Layouters/Expr.hs b/src/Language/Haskell/Brittany/Internal/Layouters/Expr.hs index fcf69b4..8d90148 100644 --- a/src/Language/Haskell/Brittany/Internal/Layouters/Expr.hs +++ b/src/Language/Haskell/Brittany/Internal/Layouters/Expr.hs @@ -532,6 +532,7 @@ layoutExpr lexpr@(L _ expr) = do expDoc1 <- docSharedWrapper layoutExpr exp1 mBindDocs <- layoutLocalBinds binds let + ifIndentLeftElse :: a -> a -> a ifIndentLeftElse x y = if indentPolicy == IndentPolicyLeft then x else y -- this `docSetIndentLevel` might seem out of place, but is here due to @@ -557,17 +558,17 @@ layoutExpr lexpr@(L _ expr) = do ] , docAddBaseY BrIndentRegular $ docPar - (appSep $ docLit $ Text.pack "let") + (docLit $ Text.pack "let") (docSetBaseAndIndent $ return bindDoc) ] , docAlt [ docSeq - [ ifIndentLeftElse id appSep $ docLit $ Text.pack "in " + [ appSep $ docLit $ Text.pack $ ifIndentLeftElse "in" "in " , ifIndentLeftElse docForceSingleline docSetBaseAndIndent expDoc1 ] , docAddBaseY BrIndentRegular $ docPar - (appSep $ docLit $ Text.pack "in") + (docLit $ Text.pack "in") (docSetBaseY $ expDoc1) ] ] From b46f9dd23b29f71a34896a6e52d0f3ce855414eb Mon Sep 17 00:00:00 2001 From: Erik Schnetter <schnetter@gmail.com> Date: Mon, 15 Jan 2018 18:11:50 -0500 Subject: [PATCH 15/34] Correct wording of warning message "certain" -> "some" --- src-brittany/Main.hs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src-brittany/Main.hs b/src-brittany/Main.hs index 56aa928..bcb8a3f 100644 --- a/src-brittany/Main.hs +++ b/src-brittany/Main.hs @@ -281,7 +281,7 @@ coreIO putErrorLnIO config suppressOutput inputPathM outputPathM = ExceptT.runEx putErrorLn $ "Error: detected unprocessed comments." ++ " The transformation output will most likely" - ++ " not contain certain of the comments" + ++ " not contain some of the comments" ++ " present in the input haskell source file." putErrorLn $ "Affected are the following comments:" unused `forM_` \case From d086140120dc1398d8149723979c1e347bdc7130 Mon Sep 17 00:00:00 2001 From: Jake Zimmerman <zimmerman.jake@gmail.com> Date: Wed, 24 Jan 2018 15:19:04 -0800 Subject: [PATCH 16/34] Add Vim / Neovim plugin I saw that you started an editor integration section, and thought that it might benefit from a Vim / Neovim section \o/ Thanks for this program by the way! --- README.md | 3 +++ 1 file changed, 3 insertions(+) diff --git a/README.md b/README.md index 3850fbd..cc264e4 100644 --- a/README.md +++ b/README.md @@ -108,6 +108,9 @@ log the size of the input, but _not_ the full requests.) [haskell-ide-engine](https://github.com/haskell/haskell-ide-engine) includes a `brittany` plugin that directly uses the brittany library. Relevant for any editors that properly support the language-server-protocol. +#### Neovim / Vim 8 + The [Neoformat](https://github.com/sbdchd/neoformat) plugin comes with support for + brittany built in. # Usage From 18b3cfaf88d44ba6d2e1bfc27a3d43eb8381314b Mon Sep 17 00:00:00 2001 From: Evan Rutledge Borden <evan@evan-borden.com> Date: Mon, 15 Jan 2018 16:02:14 -0500 Subject: [PATCH 17/34] Fix infix constructor pattern matching for normal constructors Brittany was previously only support symbol based infix constructors. It is common in some libraries (for example Esqueleto) to pattern match on normal constructors as infix. Brittany was failing in this case by not wrapping the constructor name in back ticks/spaces. Backticks and spaces have been added in the case where the constructor contains any alpha characters. --- src-literatetests/10-tests.blt | 3 +++ src/Language/Haskell/Brittany/Internal/Layouters/Pattern.hs | 5 ++++- 2 files changed, 7 insertions(+), 1 deletion(-) diff --git a/src-literatetests/10-tests.blt b/src-literatetests/10-tests.blt index a3d8591..6659847 100644 --- a/src-literatetests/10-tests.blt +++ b/src-literatetests/10-tests.blt @@ -355,6 +355,9 @@ func (x:xr) = x #pending func (x:+:xr) = x +#test normal infix constructor +func (x `Foo` xr) = x + ############################################################################### ############################################################################### diff --git a/src/Language/Haskell/Brittany/Internal/Layouters/Pattern.hs b/src/Language/Haskell/Brittany/Internal/Layouters/Pattern.hs index ebdd91d..2f881a0 100644 --- a/src/Language/Haskell/Brittany/Internal/Layouters/Pattern.hs +++ b/src/Language/Haskell/Brittany/Internal/Layouters/Pattern.hs @@ -13,6 +13,7 @@ where import Language.Haskell.Brittany.Internal.Types import Language.Haskell.Brittany.Internal.LayouterBasics +import Data.Char (isAlpha) import RdrName ( RdrName(..) ) import GHC ( Located, runGhc, GenLocated(L), moduleNameString ) import HsSyn @@ -80,7 +81,9 @@ layoutPat lpat@(L _ pat) = docWrapNode lpat $ case pat of let nameDoc = lrdrNameToText lname leftDoc <- colsWrapPat =<< layoutPat left rightDoc <- colsWrapPat =<< layoutPat right - middle <- docLit nameDoc + middle <- docLit $ if Text.any isAlpha nameDoc + then Text.pack " `" <> nameDoc <> Text.pack "` " + else nameDoc return $ Seq.empty Seq.|> leftDoc Seq.|> middle Seq.|> rightDoc ConPatIn lname (RecCon (HsRecFields [] Nothing)) -> do -- Abc{} -> expr From 019d47bf7e7a4c4d7cca18b41f9319c6f518ff6e Mon Sep 17 00:00:00 2001 From: Evan Rutledge Borden <evan@evan-borden.com> Date: Mon, 15 Jan 2018 19:11:25 -0500 Subject: [PATCH 18/34] Change infix patterns to include spaces This commit changes infix patterns to utilize `lrdrNameToTextAnn`. This function allows the logic to avoid introspecting on the constructor name. Additionally this adds spaces to all infix operator pattern matches. Previously infix symbols did not include spaces: ``` foo (x:xs) = _ ``` Now they include a space ``` foo (x : xs) = _ ``` --- src-literatetests/10-tests.blt | 4 ++-- src-literatetests/15-regressions.blt | 4 ++-- src-literatetests/tests-context-free.blt | 6 +++--- .../Haskell/Brittany/Internal/Layouters/Pattern.hs | 8 +++----- 4 files changed, 10 insertions(+), 12 deletions(-) diff --git a/src-literatetests/10-tests.blt b/src-literatetests/10-tests.blt index 6659847..af873df 100644 --- a/src-literatetests/10-tests.blt +++ b/src-literatetests/10-tests.blt @@ -349,11 +349,11 @@ func reallyreallyreallyreallyreallyreallyreallyreallyreallyreallylongvariable func (A a) = a #test list constructor -func (x:xr) = x +func (x : xr) = x #test some other constructor symbol #pending -func (x:+:xr) = x +func (x :+: xr) = x #test normal infix constructor func (x `Foo` xr) = x diff --git a/src-literatetests/15-regressions.blt b/src-literatetests/15-regressions.blt index 0fbc830..5c31ab6 100644 --- a/src-literatetests/15-regressions.blt +++ b/src-literatetests/15-regressions.blt @@ -123,8 +123,8 @@ func = do #test list comprehension comment placement func = [ (thing, take 10 alts) --TODO: select best ones - | (thing, _got, alts@(_:_)) <- nosuchFooThing - , gast <- award + | (thing, _got, alts@(_ : _)) <- nosuchFooThing + , gast <- award ] #test if-then-else comment placement diff --git a/src-literatetests/tests-context-free.blt b/src-literatetests/tests-context-free.blt index e8303cd..0d3d8cf 100644 --- a/src-literatetests/tests-context-free.blt +++ b/src-literatetests/tests-context-free.blt @@ -366,11 +366,11 @@ func reallyreallyreallyreallyreallyreallyreallyreallyreallyreallylongvariable func (A a) = a #test list constructor -func (x:xr) = x +func (x : xr) = x #test some other constructor symbol #pending -func (x:+:xr) = x +func (x :+: xr) = x ############################################################################### @@ -748,7 +748,7 @@ func = do #test list comprehension comment placement func = [ (thing, take 10 alts) --TODO: select best ones - | (thing, _got, alts@(_:_)) <- nosuchFooThing + | (thing, _got, alts@(_ : _)) <- nosuchFooThing , gast <- award ] diff --git a/src/Language/Haskell/Brittany/Internal/Layouters/Pattern.hs b/src/Language/Haskell/Brittany/Internal/Layouters/Pattern.hs index 2f881a0..317fbe2 100644 --- a/src/Language/Haskell/Brittany/Internal/Layouters/Pattern.hs +++ b/src/Language/Haskell/Brittany/Internal/Layouters/Pattern.hs @@ -78,12 +78,10 @@ layoutPat lpat@(L _ pat) = docWrapNode lpat $ case pat of return $ x1 Seq.<| xR ConPatIn lname (InfixCon left right) -> do -- a :< b -> expr - let nameDoc = lrdrNameToText lname - leftDoc <- colsWrapPat =<< layoutPat left + let nameDoc = lrdrNameToTextAnn lname + leftDoc <- appSep . colsWrapPat =<< layoutPat left rightDoc <- colsWrapPat =<< layoutPat right - middle <- docLit $ if Text.any isAlpha nameDoc - then Text.pack " `" <> nameDoc <> Text.pack "` " - else nameDoc + middle <- appSep . docLit =<< nameDoc return $ Seq.empty Seq.|> leftDoc Seq.|> middle Seq.|> rightDoc ConPatIn lname (RecCon (HsRecFields [] Nothing)) -> do -- Abc{} -> expr From eb8f0de6c3b04505f2350137ce41308c25149c54 Mon Sep 17 00:00:00 2001 From: Evan Rutledge Borden <evan@evan-borden.com> Date: Mon, 15 Jan 2018 19:15:51 -0500 Subject: [PATCH 19/34] Remove redundant import. --- src/Language/Haskell/Brittany/Internal/Layouters/Pattern.hs | 1 - 1 file changed, 1 deletion(-) diff --git a/src/Language/Haskell/Brittany/Internal/Layouters/Pattern.hs b/src/Language/Haskell/Brittany/Internal/Layouters/Pattern.hs index 317fbe2..c04790d 100644 --- a/src/Language/Haskell/Brittany/Internal/Layouters/Pattern.hs +++ b/src/Language/Haskell/Brittany/Internal/Layouters/Pattern.hs @@ -13,7 +13,6 @@ where import Language.Haskell.Brittany.Internal.Types import Language.Haskell.Brittany.Internal.LayouterBasics -import Data.Char (isAlpha) import RdrName ( RdrName(..) ) import GHC ( Located, runGhc, GenLocated(L), moduleNameString ) import HsSyn From 077b93db016123ba58aed9568fef05bfeb0dd7f8 Mon Sep 17 00:00:00 2001 From: Lennart Spitzner <hexagoxel@hexagoxel.de> Date: Fri, 9 Feb 2018 16:50:57 +0100 Subject: [PATCH 20/34] Minor refactor --- src/Language/Haskell/Brittany/Internal/Layouters/Pattern.hs | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/Language/Haskell/Brittany/Internal/Layouters/Pattern.hs b/src/Language/Haskell/Brittany/Internal/Layouters/Pattern.hs index c04790d..51bb03a 100644 --- a/src/Language/Haskell/Brittany/Internal/Layouters/Pattern.hs +++ b/src/Language/Haskell/Brittany/Internal/Layouters/Pattern.hs @@ -77,10 +77,10 @@ layoutPat lpat@(L _ pat) = docWrapNode lpat $ case pat of return $ x1 Seq.<| xR ConPatIn lname (InfixCon left right) -> do -- a :< b -> expr - let nameDoc = lrdrNameToTextAnn lname - leftDoc <- appSep . colsWrapPat =<< layoutPat left + nameDoc <- lrdrNameToTextAnn lname + leftDoc <- appSep . colsWrapPat =<< layoutPat left rightDoc <- colsWrapPat =<< layoutPat right - middle <- appSep . docLit =<< nameDoc + middle <- appSep $ docLit nameDoc return $ Seq.empty Seq.|> leftDoc Seq.|> middle Seq.|> rightDoc ConPatIn lname (RecCon (HsRecFields [] Nothing)) -> do -- Abc{} -> expr From 8430b74b1ad77835f755a821bd32635879bc13f5 Mon Sep 17 00:00:00 2001 From: Lennart Spitzner <hexagoxel@hexagoxel.de> Date: Tue, 13 Feb 2018 20:05:48 +0100 Subject: [PATCH 21/34] Switch to butcher-1.3, Improve help layout, fixes #103 --- brittany.cabal | 2 +- src-brittany/Main.hs | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/brittany.cabal b/brittany.cabal index 42277ad..ae71fde 100644 --- a/brittany.cabal +++ b/brittany.cabal @@ -94,7 +94,7 @@ library { , pretty >=1.1.3.3 && <1.2 , bytestring >=0.10.8.1 && <0.11 , directory >=1.2.6.2 && <1.4 - , butcher >=1.2 && <1.3 + , butcher >=1.3 && <1.4 , yaml >=0.8.18 && <0.9 , aeson >=1.0.1.0 && <1.3 , extra >=1.4.10 && <1.7 diff --git a/src-brittany/Main.hs b/src-brittany/Main.hs index bcb8a3f..cc721d2 100644 --- a/src-brittany/Main.hs +++ b/src-brittany/Main.hs @@ -161,7 +161,7 @@ mainCmdParser helpDesc = do putStrLn $ "There is NO WARRANTY, to the extent permitted by law." System.Exit.exitSuccess when printHelp $ do - liftIO $ print $ ppHelpShallow helpDesc + liftIO $ putStrLn $ PP.renderStyle PP.style { PP.ribbonsPerLine = 1.0 } $ ppHelpShallow helpDesc System.Exit.exitSuccess let inputPaths = if null inputParams then [Nothing] else map Just inputParams From d749c0da2715f0d0678644ab95429a8715827a50 Mon Sep 17 00:00:00 2001 From: Lennart Spitzner <hexagoxel@hexagoxel.de> Date: Tue, 13 Feb 2018 20:06:31 +0100 Subject: [PATCH 22/34] Prevent crash if ~/.config does not exist (fixes #115) --- src-brittany/Main.hs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src-brittany/Main.hs b/src-brittany/Main.hs index cc721d2..324a7a3 100644 --- a/src-brittany/Main.hs +++ b/src-brittany/Main.hs @@ -346,7 +346,7 @@ readConfigs cmdlineConfig configPaths = do userConfigXdg <- readConfig userConfigPathXdg let userConfig = userConfigSimple <|> userConfigXdg when (Data.Maybe.isNothing userConfig) $ do - liftIO $ Directory.createDirectoryIfMissing False userBritPathXdg + liftIO $ Directory.createDirectoryIfMissing True userBritPathXdg writeDefaultConfig userConfigPathXdg -- rightmost has highest priority pure $ [userConfig, localConfig] From 779a23c380d1ff3bc68642d91a367903d05aa6bd Mon Sep 17 00:00:00 2001 From: Lennart Spitzner <hexagoxel@hexagoxel.de> Date: Tue, 13 Feb 2018 20:32:19 +0100 Subject: [PATCH 23/34] Update README.md: Conf file discovery description --- README.md | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/README.md b/README.md index cc264e4..8366d6b 100644 --- a/README.md +++ b/README.md @@ -56,7 +56,8 @@ log the size of the input, but _not_ the full requests.) - config (file) documentation is lacking. - some config values can not be configured via commandline yet. - uses/creates user config file in `~/.config/brittany/config.yaml`; - also reads `brittany.yaml` in current dir if present. + also reads (the first) `brittany.yaml` found in current or parent + directories. # Installation From 91de1ca08cc7e95c072a85fd98d11926ba4c0689 Mon Sep 17 00:00:00 2001 From: Lennart Spitzner <hexagoxel@hexagoxel.de> Date: Tue, 13 Feb 2018 23:48:00 +0100 Subject: [PATCH 24/34] Fix bang deletion on ghc-8.2, Add testcase (fixes #116) --- src-literatetests/15-regressions.blt | 6 ++++ .../Brittany/Internal/Layouters/Decl.hs | 31 ++++++++++++++++--- 2 files changed, 33 insertions(+), 4 deletions(-) diff --git a/src-literatetests/15-regressions.blt b/src-literatetests/15-regressions.blt index 5c31ab6..dda42a0 100644 --- a/src-literatetests/15-regressions.blt +++ b/src-literatetests/15-regressions.blt @@ -513,3 +513,9 @@ cs0 = 0 : [ c / Interval n | c <- cs | n <- [1..] ] #test issue 70 {-# LANGUAGE TemplateHaskell #-} deriveFromJSON (unPrefix "assignPost") ''AssignmentPost + +#test issue 116 +{-# LANGUAGE BangPatterns #-} +func = do + let !forced = some + pure () diff --git a/src/Language/Haskell/Brittany/Internal/Layouters/Decl.hs b/src/Language/Haskell/Brittany/Internal/Layouters/Decl.hs index 8724291..c6ff4e0 100644 --- a/src/Language/Haskell/Brittany/Internal/Layouters/Decl.hs +++ b/src/Language/Haskell/Brittany/Internal/Layouters/Decl.hs @@ -192,16 +192,17 @@ layoutPatternBind -> BriDocNumbered -> LMatch RdrName (LHsExpr RdrName) -> ToBriDocM BriDocNumbered -layoutPatternBind mIdStr binderDoc lmatch@(L _ match@(Match _ pats _ (GRHSs grhss whereBinds))) = do +layoutPatternBind mIdStr binderDoc lmatch@(L _ match@(Match fixityOrCtx pats _ (GRHSs grhss whereBinds))) = do patDocs <- pats `forM` \p -> fmap return $ colsWrapPat =<< layoutPat p let isInfix = isInfixMatch match - patDoc <- docWrapNodePrior lmatch $ case (mIdStr, patDocs) of - (Just idStr, p1:pr) | isInfix -> docCols + let mIdStr' = fixPatternBindIdentifier fixityOrCtx <$> mIdStr + patDoc <- docWrapNodePrior lmatch $ case (mIdStr', patDocs) of + (Just idStr, p1 : pr) | isInfix -> docCols ColPatternsFuncInfix ( [appSep $ docForceSingleline p1, appSep $ docLit idStr] ++ (spacifyDocs $ docForceSingleline <$> pr) ) - (Just idStr, [] ) -> docLit idStr + (Just idStr, []) -> docLit idStr (Just idStr, ps) -> docCols ColPatternsFuncPrefix $ appSep (docLit $ idStr) @@ -220,6 +221,28 @@ layoutPatternBind mIdStr binderDoc lmatch@(L _ match@(Match _ pats _ (GRHSs grhs mWhereDocs hasComments +#if MIN_VERSION_ghc(8,2,0) /* ghc-8.2 */ +fixPatternBindIdentifier + :: HsMatchContext (NameOrRdrName RdrName) -> Text -> Text +fixPatternBindIdentifier ctx idStr = case ctx of + (FunRhs _ _ SrcLazy ) -> Text.cons '~' idStr + (FunRhs _ _ SrcStrict ) -> Text.cons '!' idStr + (FunRhs _ _ NoSrcStrict) -> idStr + (StmtCtxt ctx1 ) -> fixPatternBindIdentifier' ctx1 + _ -> idStr + where + -- I have really no idea if this path ever occurs, but better safe than + -- risking another "drop bangpatterns" bugs. + fixPatternBindIdentifier' = \case + (PatGuard ctx1) -> fixPatternBindIdentifier ctx1 idStr + (ParStmtCtxt ctx1) -> fixPatternBindIdentifier' ctx1 + (TransStmtCtxt ctx1) -> fixPatternBindIdentifier' ctx1 + _ -> idStr +#else /* ghc-8.0 */ +fixPatternBindIdentifier :: MatchFixity RdrName -> Text -> Text +fixPatternBindIdentifier _ x = x +#endif + layoutPatternBindFinal :: Maybe Text -> BriDocNumbered From 55b1c71bf3da03eab9a722d7143871fe079c4f9d Mon Sep 17 00:00:00 2001 From: Lennart Spitzner <hexagoxel@hexagoxel.de> Date: Wed, 14 Feb 2018 01:00:01 +0100 Subject: [PATCH 25/34] Fix a layouting mistake that went unnoticed so far --- src-literatetests/15-regressions.blt | 6 ++++++ src/Language/Haskell/Brittany/Internal/Layouters/Decl.hs | 7 +++++-- 2 files changed, 11 insertions(+), 2 deletions(-) diff --git a/src-literatetests/15-regressions.blt b/src-literatetests/15-regressions.blt index dda42a0..7654285 100644 --- a/src-literatetests/15-regressions.blt +++ b/src-literatetests/15-regressions.blt @@ -519,3 +519,9 @@ deriveFromJSON (unPrefix "assignPost") ''AssignmentPost func = do let !forced = some pure () + +#test let-in-hanging +spanKey p q = case minViewWithKey q of + Just ((k, _), q') | p k -> + let (kas, q'') = spanKey p q' in ((k, a) : kas, q'') + _ -> ([], q) diff --git a/src/Language/Haskell/Brittany/Internal/Layouters/Decl.hs b/src/Language/Haskell/Brittany/Internal/Layouters/Decl.hs index c6ff4e0..9681453 100644 --- a/src/Language/Haskell/Brittany/Internal/Layouters/Decl.hs +++ b/src/Language/Haskell/Brittany/Internal/Layouters/Decl.hs @@ -300,10 +300,13 @@ layoutPatternBindFinal alignmentToken binderDoc mPatDoc clauseDocs mWhereDocs ha ] let singleLineGuardsDoc guards = appSep $ case guards of [] -> docEmpty - [g] -> docSeq [appSep $ docLit $ Text.pack "|", return g] + [g] -> docSeq + [appSep $ docLit $ Text.pack "|", docForceSingleline $ return g] gs -> docSeq $ [appSep $ docLit $ Text.pack "|"] - ++ List.intersperse docCommaSep (return <$> gs) + ++ (List.intersperse docCommaSep + (docForceSingleline . return <$> gs) + ) indentPolicy <- mAsk <&> _conf_layout From 81928ea59715508d6d2b931bbed82f205fa9ac7d Mon Sep 17 00:00:00 2001 From: Lennart Spitzner <hexagoxel@hexagoxel.de> Date: Wed, 14 Feb 2018 01:14:24 +0100 Subject: [PATCH 26/34] Switch to ghc-exactprint-0.5.6.0, Remove code duplication --- brittany.cabal | 2 +- .../Brittany/Internal/ExactPrintUtils.hs | 39 +------------------ 2 files changed, 2 insertions(+), 39 deletions(-) diff --git a/brittany.cabal b/brittany.cabal index ae71fde..d0059f1 100644 --- a/brittany.cabal +++ b/brittany.cabal @@ -82,7 +82,7 @@ library { { base >=4.9 && <4.11 , ghc >=8.0.1 && <8.3 , ghc-paths >=0.1.0.9 && <0.2 - , ghc-exactprint >=0.5.3.0 && <0.5.6 + , ghc-exactprint >=0.5.6.0 && <0.5.7 , transformers >=0.5.2.0 && <0.6 , containers >=0.5.7.1 && <0.6 , mtl >=2.2.1 && <2.3 diff --git a/src/Language/Haskell/Brittany/Internal/ExactPrintUtils.hs b/src/Language/Haskell/Brittany/Internal/ExactPrintUtils.hs index 7494d9e..749804c 100644 --- a/src/Language/Haskell/Brittany/Internal/ExactPrintUtils.hs +++ b/src/Language/Haskell/Brittany/Internal/ExactPrintUtils.hs @@ -113,48 +113,11 @@ parseModuleFromString args fp dynCheck str = $ "when parsing ghc flags: encountered warnings: " ++ show (warnings <&> \(L _ s) -> s) dynCheckRes <- ExceptT.ExceptT $ liftIO $ dynCheck dflags1 - let res = parseModulePure dflags1 fp str + let res = ExactPrint.parseModuleFromStringInternal dflags1 fp str case res of Left (span, err) -> ExceptT.throwE $ show span ++ ": " ++ err Right (a , m ) -> pure (a, m, dynCheckRes) ------------ - --- this function should move to ghc-exactprint. btw, we can deprecate/remove --- the `parseModuleFromString` function that I added initially to --- ghc-exactprint. -parseModulePure - :: GHC.DynFlags - -> System.IO.FilePath - -> String - -> Either (SrcSpan, String) (ExactPrint.Anns, GHC.ParsedSource) -parseModulePure dflags fileName str = - let (str1, lp) = ExactPrint.stripLinePragmas str - res = case runParser GHC.parseModule dflags fileName str1 of - GHC.PFailed ss m -> Left (ss, GHC.showSDoc dflags m) - GHC.POk x pmod -> Right $ (mkApiAnns x, lp, dflags, pmod) - in ExactPrint.postParseTransform res ExactPrint.normalLayout - --- copied from exactprint until exactprint exposes a proper interface. -runParser - :: GHC.P a - -> GHC.DynFlags - -> System.IO.FilePath - -> String - -> GHC.ParseResult a -runParser parser flags filename str = GHC.unP parser parseState - where - location = GHC.mkRealSrcLoc (GHC.mkFastString filename) 1 1 - buffer = GHC.stringToStringBuffer str - parseState = GHC.mkPState flags buffer location -mkApiAnns :: GHC.PState -> GHC.ApiAnns -mkApiAnns pstate = - ( Map.fromListWith (++) . GHC.annotations $ pstate - , Map.fromList - ((GHC.noSrcSpan, GHC.comment_q pstate) : GHC.annotations_comments pstate) - ) - ------------ commentAnnFixTransformGlob :: SYB.Data ast => ast -> ExactPrint.Transform () commentAnnFixTransformGlob ast = do From c28ec4cfdfe33e222a76053bb49dbee87c476382 Mon Sep 17 00:00:00 2001 From: Lennart Spitzner <hexagoxel@hexagoxel.de> Date: Wed, 14 Feb 2018 14:42:26 +0100 Subject: [PATCH 27/34] Bump butcher version in stack-8.0.2.yaml --- stack-8.0.2.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/stack-8.0.2.yaml b/stack-8.0.2.yaml index 539cd6d..51c6004 100644 --- a/stack-8.0.2.yaml +++ b/stack-8.0.2.yaml @@ -3,7 +3,7 @@ resolver: lts-9.0 extra-deps: - monad-memo-0.4.1 - czipwith-1.0.0.0 - - butcher-1.2.0.0 + - butcher-1.3.0.0 - data-tree-print-0.1.0.0 - deque-0.2 From c28636adca522713ceebf51854162dd11f548828 Mon Sep 17 00:00:00 2001 From: Lennart Spitzner <hexagoxel@hexagoxel.de> Date: Wed, 14 Feb 2018 15:20:22 +0100 Subject: [PATCH 28/34] Add ghc-exactprint-0.5.6.0 to extra-deps in stack.yaml --- stack-8.0.2.yaml | 1 + 1 file changed, 1 insertion(+) diff --git a/stack-8.0.2.yaml b/stack-8.0.2.yaml index 51c6004..ca6ad6a 100644 --- a/stack-8.0.2.yaml +++ b/stack-8.0.2.yaml @@ -6,6 +6,7 @@ extra-deps: - butcher-1.3.0.0 - data-tree-print-0.1.0.0 - deque-0.2 + - ghc-exactprint-0.5.6.0 packages: - . From f17d9f8bf6f71358d3b9aa287150a923de38b1c5 Mon Sep 17 00:00:00 2001 From: Maximilian Tagher <feedback.tagher@gmail.com> Date: Wed, 14 Feb 2018 06:54:39 -0800 Subject: [PATCH 29/34] Fix spelling of my name --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 8366d6b..2f55f03 100644 --- a/README.md +++ b/README.md @@ -104,7 +104,7 @@ log the size of the input, but _not_ the full requests.) I have described a haskell setup that includes a shortcut to run brittany formatting. #### VSCode [This extension](https://marketplace.visualstudio.com/items?itemName=MaxGabriel.brittany) - connects commandline `brittany` to VSCode formatting API. Thanks to @MaxGarbriel. + connects commandline `brittany` to VSCode formatting API. Thanks to @MaxGabriel. #### Via HIE [haskell-ide-engine](https://github.com/haskell/haskell-ide-engine) includes a `brittany` plugin that directly uses the brittany library. From 4b53072ccdfa348d107044c624afaf4a1e973544 Mon Sep 17 00:00:00 2001 From: Lennart Spitzner <hexagoxel@hexagoxel.de> Date: Wed, 14 Feb 2018 17:18:15 +0100 Subject: [PATCH 30/34] Correct some commandline help output --- src-brittany/Main.hs | 9 +++++---- src/Language/Haskell/Brittany/Internal/Config.hs | 6 +++--- 2 files changed, 8 insertions(+), 7 deletions(-) diff --git a/src-brittany/Main.hs b/src-brittany/Main.hs index 324a7a3..f986ad9 100644 --- a/src-brittany/Main.hs +++ b/src-brittany/Main.hs @@ -82,9 +82,10 @@ helpDoc = PP.vcat $ List.intersperse ] , parDocW [ "This program is written carefully and contains safeguards to ensure" - , "the transformation does not change semantics (or the syntax tree at all)" - , "and that no comments are removed." - , "Nonetheless, this is a young project, and there will always be bugs." + , "the output is syntactically valid and that no comments are removed." + , "Nonetheless, this is a young project, and there will always be bugs," + , "and ensuring that the transformation never changes semantics of the" + , "transformed source is currently not possible." , "Please do check the output and do not let brittany override your large" , "codebase without having backups." ] @@ -148,7 +149,7 @@ mainCmdParser helpDesc = do ) <> flagDefault Display ) - inputParams <- addParamNoFlagStrings "PATH" (paramHelpStr "paths to input haskell source files") + inputParams <- addParamNoFlagStrings "PATH" (paramHelpStr "paths to input/inout haskell source files") reorderStop addCmdImpl $ void $ do when printLicense $ do diff --git a/src/Language/Haskell/Brittany/Internal/Config.hs b/src/Language/Haskell/Brittany/Internal/Config.hs index f225545..ad991b5 100644 --- a/src/Language/Haskell/Brittany/Internal/Config.hs +++ b/src/Language/Haskell/Brittany/Internal/Config.hs @@ -105,7 +105,7 @@ configParser = do cols <- addFlagReadParams "" ["columns"] "AMOUNT" (flagHelpStr "target max columns (80 is an old default for this)") importCol <- addFlagReadParams "" ["import-col"] "N" (flagHelpStr "column to align import lists at") - dumpConfig <- addSimpleBoolFlag "" ["dump-config"] (flagHelp $ parDoc "dump the programs full config (commandline + file + defaults)") + dumpConfig <- addSimpleBoolFlag "" ["dump-config"] (flagHelp $ parDoc "dump the programs full config (merged commandline + file + defaults)") dumpAnnotations <- addSimpleBoolFlag "" ["dump-annotations"] (flagHelp $ parDoc "dump the full annotations returned by ghc-exactprint") dumpUnknownAST <- addSimpleBoolFlag "" ["dump-ast-unknown"] (flagHelp $ parDoc "dump the ast for any nodes not transformed, but copied as-is by brittany") dumpCompleteAST <- addSimpleBoolFlag "" ["dump-ast-full"] (flagHelp $ parDoc "dump the full ast") @@ -119,9 +119,9 @@ configParser = do dumpBriDocIndent <- addSimpleBoolFlag "" ["dump-bridoc-indent"] (flagHelp $ parDoc "dump the partially transformed bridoc: after transformation: indent") dumpBriDocFinal <- addSimpleBoolFlag "" ["dump-bridoc-final"] (flagHelp $ parDoc "dump the post-transformation bridoc") - outputOnErrors <- addSimpleBoolFlag "" ["output-on-errors"] (flagHelp $ parDoc "even when there are errors, produce output (or try to to the degree possible") + outputOnErrors <- addSimpleBoolFlag "" ["output-on-errors"] (flagHelp $ parDoc "even when there are errors, produce output (or try to to the degree possible)") wError <- addSimpleBoolFlag "" ["werror"] (flagHelp $ parDoc "treat warnings as errors") - omitValidCheck <- addSimpleBoolFlag "" ["omit-output-check"] (flagHelp $ parDoc "omit checking if the output is syntactically valid; for dev on brittany") + omitValidCheck <- addSimpleBoolFlag "" ["omit-output-check"] (flagHelp $ parDoc "omit checking if the output is syntactically valid (debugging)") roundtripOnly <- addSimpleBoolFlag "" ["exactprint-only"] (flagHelp $ parDoc "do not reformat, but exclusively use exactprint to roundtrip (debugging)") From bac69ba54f3988f4f2999366a038c973bedb8a11 Mon Sep 17 00:00:00 2001 From: Lennart Spitzner <hexagoxel@hexagoxel.de> Date: Wed, 14 Feb 2018 17:18:22 +0100 Subject: [PATCH 31/34] Bump to 0.9.0.1, Add changelog --- ChangeLog.md | 16 ++++++++++++++++ brittany.cabal | 2 +- 2 files changed, 17 insertions(+), 1 deletion(-) diff --git a/ChangeLog.md b/ChangeLog.md index 05a7ea2..1b23e1e 100644 --- a/ChangeLog.md +++ b/ChangeLog.md @@ -1,5 +1,21 @@ # Revision history for brittany +## 0.9.0.1 -- February 2018 + +* Support `TupleSections` (thanks to Matthew Piziak) +* Bugfixes: + - Fix Shebang handling with stdin input (#92) + - Fix bug that effectively deleted strict/lazy matches (BangPatterns) (#116) + - Fix infix operator whitespace bug (#101, #114) + - Fix help command output and its layouting (#103) + - Fix crash when config dir does not exist yet (#115) +* Layouting changes: + - no space after opening non-tuple parenthesis even for multi-line case + - use spaces around infix operators (applies to sections and in pattern + matches) + - Let-in is layouted more flexibly in fewer lines, if possible + (thanks to Evan Borden) + ## 0.9.0.0 -- December 2017 * Change default global config path (use XDG spec) diff --git a/brittany.cabal b/brittany.cabal index d0059f1..b6ecf52 100644 --- a/brittany.cabal +++ b/brittany.cabal @@ -1,5 +1,5 @@ name: brittany -version: 0.9.0.0 +version: 0.9.0.1 synopsis: Haskell source code formatter description: { See <https://github.com/lspitzner/brittany/blob/master/README.md the README>. From c124336738b922b0269d4e44e1c1095ada9ec8e9 Mon Sep 17 00:00:00 2001 From: Lennart Spitzner <hexagoxel@hexagoxel.de> Date: Mon, 19 Feb 2018 17:17:39 +0100 Subject: [PATCH 32/34] Fix NOINLINE pragma layouting --- src-literatetests/10-tests.blt | 4 ++++ src/Language/Haskell/Brittany/Internal/Layouters/Decl.hs | 3 ++- 2 files changed, 6 insertions(+), 1 deletion(-) diff --git a/src-literatetests/10-tests.blt b/src-literatetests/10-tests.blt index af873df..3f7ec68 100644 --- a/src-literatetests/10-tests.blt +++ b/src-literatetests/10-tests.blt @@ -287,6 +287,10 @@ func = f {-# INLINE CONLIKE [1] f #-} f = id +#test noinline pragma 1 +{-# NOINLINE func #-} +func :: Int + #test inline pragma 4 #pending this does not work with the compiler version we currently use yet (i think). should work with ghc-8.0.2. func = f diff --git a/src/Language/Haskell/Brittany/Internal/Layouters/Decl.hs b/src/Language/Haskell/Brittany/Internal/Layouters/Decl.hs index 9681453..400d422 100644 --- a/src/Language/Haskell/Brittany/Internal/Layouters/Decl.hs +++ b/src/Language/Haskell/Brittany/Internal/Layouters/Decl.hs @@ -94,7 +94,8 @@ layoutSig lsig@(L _loc sig) = case sig of NoInline -> "NOINLINE " EmptyInlineSpec -> "" -- i have no idea if this is correct. let phaseStr = case phaseAct of - NeverActive -> "[] " + NeverActive -> "" -- not [] - for NOINLINE NeverActive is + -- in fact the default AlwaysActive -> "" ActiveBefore _ i -> "[~" ++ show i ++ "] " ActiveAfter _ i -> "[" ++ show i ++ "] " From 19e31fdaf2bed40e25f9c9b29907441279f53fbe Mon Sep 17 00:00:00 2001 From: Lennart Spitzner <hexagoxel@hexagoxel.de> Date: Mon, 19 Feb 2018 21:33:43 +0100 Subject: [PATCH 33/34] Improve layouting of RecordUpd, Fix minor issue for HsLet --- src-literatetests/15-regressions.blt | 5 +- .../Brittany/Internal/Layouters/Expr.hs | 55 ++++++++++++++----- 2 files changed, 42 insertions(+), 18 deletions(-) diff --git a/src-literatetests/15-regressions.blt b/src-literatetests/15-regressions.blt index 7654285..5e4f52c 100644 --- a/src-literatetests/15-regressions.blt +++ b/src-literatetests/15-regressions.blt @@ -367,9 +367,8 @@ runBrittany tabSize text = do let config' = staticDefaultConfig config = config' - { _conf_layout = (_conf_layout config') { _lconfig_indentAmount = coerce - tabSize - } + { _conf_layout = + (_conf_layout config') { _lconfig_indentAmount = coerce tabSize } , _conf_forward = forwardOptionsSyntaxExtsEnabled } parsePrintModule config text diff --git a/src/Language/Haskell/Brittany/Internal/Layouters/Expr.hs b/src/Language/Haskell/Brittany/Internal/Layouters/Expr.hs index 8d90148..807aad8 100644 --- a/src/Language/Haskell/Brittany/Internal/Layouters/Expr.hs +++ b/src/Language/Haskell/Brittany/Internal/Layouters/Expr.hs @@ -535,13 +535,15 @@ layoutExpr lexpr@(L _ expr) = do ifIndentLeftElse :: a -> a -> a ifIndentLeftElse x y = if indentPolicy == IndentPolicyLeft then x else y - -- this `docSetIndentLevel` might seem out of place, but is here due to - -- ghc-exactprint's DP handling of "let" in particular. + -- 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 + -- particular. -- Just pushing another indentation level is a straightforward approach -- to making brittany idempotent, even though the result is non-optimal -- if "let" is moved horizontally as part of the transformation, as the -- comments before the first let item are moved horizontally with it. - docSetIndentLevel $ case mBindDocs of + docSetBaseAndIndent $ case mBindDocs of Just [bindDoc] -> docAlt [ docSeq [ appSep $ docLit $ Text.pack "let" @@ -733,6 +735,8 @@ layoutExpr lexpr@(L _ expr) = do , docLit $ Text.pack "}" ] RecordCon lname _ _ (HsRecFields fs@(_:_) Nothing) -> do + -- TODO: the layouter for RecordUpd is slightly more clever. Should + -- probably copy the approach from there. let nameDoc = docWrapNode lname $ docLit $ lrdrNameToText lname ((fd1l, fd1n, fd1e):fdr) <- fs `forM` \fieldl@(L _ (HsRecField (L _ (FieldOcc lnameF _)) fExpr pun)) -> do fExpDoc <- if pun @@ -852,7 +856,7 @@ layoutExpr lexpr@(L _ expr) = do Unambiguous n _ -> (lfield, lrdrNameToText n, rFExpDoc) Ambiguous n _ -> (lfield, lrdrNameToText n, rFExpDoc) docAltFilter - -- singleline + -- container { fieldA = blub, fieldB = blub } [ ( True , docSeq [ docNodeAnnKW lexpr Nothing $ appSep $ docForceSingleline rExprDoc @@ -870,7 +874,10 @@ layoutExpr lexpr@(L _ expr) = do , docLit $ Text.pack "}" ] ) - -- wild-indentation block + -- hanging single-line fields + -- container { fieldA = blub + -- , fieldB = blub + -- } , ( indentPolicy /= IndentPolicyLeft , docSeq [ docNodeAnnKW lexpr Nothing $ appSep rExprDoc @@ -881,7 +888,7 @@ layoutExpr lexpr@(L _ expr) = do , case rF1e of Just x -> docWrapNodeRest rF1f $ docSeq [ appSep $ docLit $ Text.pack "=" - , docForceSingleline $ x + , docForceSingleline x ] Nothing -> docEmpty ] @@ -901,36 +908,54 @@ layoutExpr lexpr@(L _ expr) = do in [line1] ++ lineR ++ [lineN] ] ) - -- strict indentation block + -- non-hanging with expressions placed to the right of the names + -- container + -- { fieldA = blub + -- , fieldB = potentially + -- multiline + -- } , ( True , docSetParSpacing $ docAddBaseY BrIndentRegular $ docPar (docNodeAnnKW lexpr Nothing $ rExprDoc) (docNonBottomSpacing $ docLines $ let + expressionWrapper = if indentPolicy == IndentPolicyLeft + then docForceParSpacing + else docSetBaseY line1 = docCols ColRecUpdate [ appSep $ docLit $ Text.pack "{" , docWrapNodePrior rF1f $ appSep $ docLit $ rF1n , docWrapNodeRest rF1f $ case rF1e of - Just x -> docSeq [ appSep $ docLit $ Text.pack "=" - , docAddBaseY BrIndentRegular $ x - ] + Just x -> docAlt + [ docSeq [ appSep $ docLit $ Text.pack "=" + , expressionWrapper x + ] + , docAddBaseY BrIndentRegular + $ docPar (docLit $ Text.pack "=") x + ] Nothing -> docEmpty ] - lineR = rFr <&> \(lfield, fText, fDoc) -> docWrapNode lfield $ docCols ColRecUpdate + lineR = rFr <&> \(lfield, fText, fDoc) -> docWrapNode lfield + $ docCols ColRecUpdate [ docCommaSep , appSep $ docLit $ fText , case fDoc of - Just x -> docSeq [ appSep $ docLit $ Text.pack "=" - , docAddBaseY BrIndentRegular x - ] + Just x -> docAlt + [ docSeq [ appSep $ docLit $ Text.pack "=" + , expressionWrapper x + ] + , docAddBaseY BrIndentRegular + $ docPar (docLit $ Text.pack "=") x + ] Nothing -> docEmpty ] lineN = docSeq [ docNodeAnnKW lexpr (Just AnnOpenC) docEmpty , docLit $ Text.pack "}" ] - in [line1] ++ lineR ++ [lineN]) + in [line1] ++ lineR ++ [lineN] + ) ) ] #if MIN_VERSION_ghc(8,2,0) /* ghc-8.2 */ From e4dea8783901d44fe5236ef080814fa76250b2e4 Mon Sep 17 00:00:00 2001 From: Lennart Spitzner <hexagoxel@hexagoxel.de> Date: Sun, 4 Mar 2018 19:11:10 +0100 Subject: [PATCH 34/34] Switch to using branches master/release instead of dev/master --- README.md | 2 -- 1 file changed, 2 deletions(-) diff --git a/README.md b/README.md index 2f55f03..42e7fa5 100644 --- a/README.md +++ b/README.md @@ -160,8 +160,6 @@ a good amount of high-level documentation at [the documentation index](doc/implementation/index.md) -Note that most development happens on the `dev` branch of this repository! - # License Copyright (C) 2016-2017 Lennart Spitzner