diff --git a/src/Language/Haskell/Brittany/Internal/Layouters/IE.hs b/src/Language/Haskell/Brittany/Internal/Layouters/IE.hs index 3daf877..926f642 100644 --- a/src/Language/Haskell/Brittany/Internal/Layouters/IE.hs +++ b/src/Language/Haskell/Brittany/Internal/Layouters/IE.hs @@ -71,12 +71,15 @@ layoutIE lie@(L _ ie) = docWrapNode lie $ case ie of -- left to the caller since that is context sensitive layoutAnnAndSepLLIEs :: (Located [LIE RdrName]) -> ToBriDocM [ToBriDocM BriDocNumbered] layoutAnnAndSepLLIEs llies@(L _ lies) = do - let makeIENode ie = docSeq [docCommaSep, ie] - layoutAnnAndSepLLIEs' ies = case ies of - [] -> [] - [ie] -> [docWrapNode llies $ ie] - (ie:ies') -> ie:map makeIENode (List.init ies') - ++ [makeIENode $ docWrapNode llies $ List.last ies'] + let + makeIENode ie = docSeq [docCommaSep, ie] + layoutAnnAndSepLLIEs' ies = case splitFirstLast ies of + FirstLastEmpty -> [] + FirstLastSingleton ie -> [docWrapNodeRest llies $ ie] + FirstLast ie1 ieMs ieN -> + [ie1] + ++ map makeIENode ieMs + ++ [makeIENode $ docWrapNodeRest llies $ ieN] layoutAnnAndSepLLIEs' <$> mapM (docSharedWrapper layoutIE) lies -- Builds a complete layout for the given located diff --git a/src/Language/Haskell/Brittany/Internal/Layouters/Import.hs b/src/Language/Haskell/Brittany/Internal/Layouters/Import.hs index cc4172f..7aac868 100644 --- a/src/Language/Haskell/Brittany/Internal/Layouters/Import.hs +++ b/src/Language/Haskell/Brittany/Internal/Layouters/Import.hs @@ -46,13 +46,16 @@ layoutImport :: ToBriDoc ImportDecl layoutImport limportD@(L _ importD) = docWrapNode limportD $ case importD of ImportDecl _ (L _ modName) pkg src safe q False as mllies -> do importCol <- mAsk <&> _conf_layout .> _lconfig_importColumn .> confUnpack + -- NB we don't need to worry about sharing in the below code + -- (docSharedWrapper etc.) because we do not use any docAlt nodes; all + -- "decisions" are made statically. let - modNameT = Text.pack $ moduleNameString modName - pkgNameT = Text.pack . prepPkg . sl_st <$> pkg - asT = Text.pack . moduleNameString . prepModName <$> as - hiding = case mllies of + modNameT = Text.pack $ moduleNameString modName + pkgNameT = Text.pack . prepPkg . sl_st <$> pkg + asT = Text.pack . moduleNameString . prepModName <$> as + hiding = case mllies of Just (h, _) -> h - Nothing -> False + Nothing -> False minQLength = length "import qualified " qLengthReal = let qualifiedPart = if q then length "qualified " else 0 @@ -76,37 +79,31 @@ layoutImport limportD@(L _ importD) = docWrapNode limportD $ case importD of docEnsureIndent (BrIndentSpecial qLength) $ appSep $ docLit modNameT hidDoc = if hiding then appSep $ docLit $ Text.pack "hiding" else docEmpty - importHead = docSeq [importQualifiers, modNameD] - bindingsH = docParenLSep - bindingsT = [docSeq [docSeparator, docParenR]] - bindingsD = case mllies of - Nothing -> docSeq [docEmpty] + importHead = docSeq [importQualifiers, modNameD] + bindingsD = case mllies of + Nothing -> docSeq [docEmpty] Just (_, llies) -> do - ieDs <- layoutAnnAndSepLLIEs llies + ieDs <- layoutAnnAndSepLLIEs llies hasComments <- hasAnyCommentsBelow llies - case ieDs of + docWrapNodeRest llies $ case ieDs of -- ..[hiding].( ) - [] -> do - if hasComments - then - docWrapNodeRest llies $ docPar (docSeq [hidDoc, bindingsH, docWrapNode llies docEmpty]) $ docLines - bindingsT - else - docWrapNodeRest llies $ docSeq $ hidDoc : bindingsH : bindingsT + [] -> if hasComments + then docPar + (docSeq [hidDoc, docParenLSep, docWrapNode llies docEmpty]) + docParenR + else docSeq [hidDoc, docParenLSep, docSeparator, docParenR] -- ..[hiding].( b ) - [ieD] -> do - if hasComments - then - docWrapNodeRest llies $ docPar (docSeq [hidDoc, bindingsH, ieD ]) $ docLines $ - bindingsT - else - docWrapNodeRest llies $ docSeq $ hidDoc : bindingsH : ieD : bindingsT + [ieD] -> if hasComments + then docPar (docSeq [hidDoc, docParenLSep, ieD]) docParenR + else docSeq [hidDoc, docParenLSep, ieD, docSeparator, docParenR] -- ..[hiding].( b -- , b' -- ) - (ieD:ieDs') -> do - docWrapNodeRest llies $ docPar (docSeq [hidDoc, docSetBaseY $ docSeq [bindingsH, ieD]]) - $ docLines $ ieDs' ++ bindingsT + (ieD:ieDs') -> + docPar (docSeq [hidDoc, docSetBaseY $ docSeq [docParenLSep, ieD]]) + $ docLines + $ ieDs' + ++ [docParenR] bindingLine = docEnsureIndent (BrIndentSpecial (importCol - bindingCost)) bindingsD case asT of diff --git a/src/Language/Haskell/Brittany/Internal/Layouters/Module.hs b/src/Language/Haskell/Brittany/Internal/Layouters/Module.hs index 509b24a..c0f569b 100644 --- a/src/Language/Haskell/Brittany/Internal/Layouters/Module.hs +++ b/src/Language/Haskell/Brittany/Internal/Layouters/Module.hs @@ -30,11 +30,12 @@ layoutModule lmod@(L _ mod') = do HsModule Nothing _ imports _ _ _ -> docLines $ map layoutImport imports HsModule (Just n) les imports _ _ _ -> do let tn = Text.pack $ moduleNameString $ unLoc n - (hasComments, es) <- case les of - Nothing -> return (False, docEmpty) + (hasComments, exportsDoc) <- case les of + Nothing -> return (False, docEmpty) Just llies -> do hasComments <- hasAnyCommentsBelow llies - return (hasComments, layoutLLIEs llies) + exportsDoc <- docSharedWrapper layoutLLIEs llies + return (hasComments, exportsDoc) docLines $ docSeq [ docWrapNode lmod $ docEmpty @@ -44,7 +45,7 @@ layoutModule lmod@(L _ mod') = do ( [ docSeq [ appSep $ docLit $ Text.pack "module" , appSep $ docLit tn - , appSep $ docForceSingleline es + , appSep $ docForceSingleline exportsDoc , docLit $ Text.pack "where" ] | not hasComments @@ -54,7 +55,7 @@ layoutModule lmod@(L _ mod') = do ( docSeq [appSep $ docLit $ Text.pack "module", docLit tn] ) - (docForceMultiline es) + (docForceMultiline exportsDoc) , docLit $ Text.pack "where" ] ]