diff --git a/src-literatetests/Main.hs b/src-literatetests/Main.hs index ef70e44..435e328 100644 --- a/src-literatetests/Main.hs +++ b/src-literatetests/Main.hs @@ -179,6 +179,7 @@ defaultTestConfig = Config , _lconfig_reformatModulePreamble = coerce True , _lconfig_allowSingleLineExportList = coerce True , _lconfig_allowHangingQuasiQuotes = coerce True + , _lconfig_experimentalSemicolonNewlines = 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 bf7a1a3..d9555cc 100644 --- a/src-unittests/TestUtils.hs +++ b/src-unittests/TestUtils.hs @@ -60,6 +60,7 @@ defaultTestConfig = Config , _lconfig_reformatModulePreamble = coerce True , _lconfig_allowSingleLineExportList = coerce True , _lconfig_allowHangingQuasiQuotes = coerce True + , _lconfig_experimentalSemicolonNewlines = coerce False } , _conf_errorHandling = (_conf_errorHandling staticDefaultConfig) { _econf_ExactPrintFallback = coerce ExactPrintFallbackModeNever diff --git a/src/Language/Haskell/Brittany/Internal/Backend.hs b/src/Language/Haskell/Brittany/Internal/Backend.hs index e4872f2..8fd7c5d 100644 --- a/src/Language/Haskell/Brittany/Internal/Backend.hs +++ b/src/Language/Haskell/Brittany/Internal/Backend.hs @@ -225,26 +225,34 @@ layoutBriDocM = \case -- mModify $ \s -> s { _lstate_curYOrAddNewline = Right 0 } BDAnnotationRest annKey bd -> do layoutBriDocM bd - mComments <- do + annMay <- do state <- mGet - let m = _lstate_comments state - let mComments = nonEmpty =<< extractAllComments <$> Map.lookup annKey m - mSet $ state - { _lstate_comments = Map.adjust - ( \ann -> ann { ExactPrint.annFollowingComments = [] - , ExactPrint.annPriorComments = [] - , ExactPrint.annsDP = - flip filter (ExactPrint.annsDP ann) $ \case - (ExactPrint.Types.AnnComment{}, _) -> False - _ -> True - } - ) - annKey - m - } - return mComments + let m = _lstate_comments state + pure $ Map.lookup annKey m + let mComments = nonEmpty =<< extractAllComments <$> annMay + let semiCount = length [ () + | Just ann <- [ annMay ] + , (ExactPrint.Types.AnnSemiSep, _) <- ExactPrint.Types.annsDP ann + ] + shouldAddSemicolonNewlines <- mAsk <&> + _conf_layout .> _lconfig_experimentalSemicolonNewlines .> confUnpack + mModify $ \state -> state + { _lstate_comments = Map.adjust + ( \ann -> ann { ExactPrint.annFollowingComments = [] + , ExactPrint.annPriorComments = [] + , ExactPrint.annsDP = + flip filter (ExactPrint.annsDP ann) $ \case + (ExactPrint.Types.AnnComment{}, _) -> False + _ -> True + } + ) + annKey + (_lstate_comments state) + } case mComments of - Nothing -> pure () + Nothing -> do + when shouldAddSemicolonNewlines $ do + [1..semiCount] `forM_` \_ -> layoutWriteNewline Just comments -> do comments `forM_` \(ExactPrint.Types.Comment comment _ _, ExactPrint.Types.DP (y, x)) -> when (not $ comment == "(" || comment == ")") $ do diff --git a/src/Language/Haskell/Brittany/Internal/Config.hs b/src/Language/Haskell/Brittany/Internal/Config.hs index 89d125e..5d220fd 100644 --- a/src/Language/Haskell/Brittany/Internal/Config.hs +++ b/src/Language/Haskell/Brittany/Internal/Config.hs @@ -76,6 +76,7 @@ staticDefaultConfig = Config , _lconfig_reformatModulePreamble = coerce True , _lconfig_allowSingleLineExportList = coerce False , _lconfig_allowHangingQuasiQuotes = coerce True + , _lconfig_experimentalSemicolonNewlines = coerce False } , _conf_errorHandling = ErrorHandlingConfig { _econf_produceOutputOnErrors = coerce False @@ -179,6 +180,7 @@ cmdlineConfigParser = do , _lconfig_reformatModulePreamble = mempty , _lconfig_allowSingleLineExportList = mempty , _lconfig_allowHangingQuasiQuotes = mempty + , _lconfig_experimentalSemicolonNewlines = 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 a415a08..29711c5 100644 --- a/src/Language/Haskell/Brittany/Internal/Config/Types.hs +++ b/src/Language/Haskell/Brittany/Internal/Config/Types.hs @@ -127,6 +127,21 @@ data CLayoutConfig f = LayoutConfig -- > let body = [json| -- > hello -- > |] + , _lconfig_experimentalSemicolonNewlines :: f (Last Bool) + -- enables an experimental feature to turn semicolons in brace notation + -- into newlines when using layout: + -- + -- > do { a ;; b } + -- + -- turns into + -- > do + -- > a + -- > + -- > b + -- + -- The implementation for this is a bit hacky and not tested; it might + -- break output syntax or not work properly for every kind of brace. So + -- far I have considered `do` and `case-of`. } deriving (Generic)