    {-# LANGUAGE LambdaCase #-}
    {-# LANGUAGE OverloadedLabels #-}
    {-# LANGUAGE OverloadedStrings #-}
    {-# LANGUAGE PatternSynonyms #-}
    {-# LANGUAGE RecordWildCards #-}

    -- | Rendering of import and export lists.
    module Ormolu.Printer.Meat.ImportExport
      ( p_hsmodExports,
        p_hsmodImport,
      )
    where

    import Control.Monad
    import Data.Choice (pattern Without)
    import Data.Foldable (for_, traverse_)
    import Data.List (inits)
    import Data.Text qualified as T
    import GHC.Hs
    import GHC.LanguageExtensions.Type
    import GHC.Types.PkgQual
    import GHC.Types.SrcLoc
    import Ormolu.Config
    import Ormolu.Printer.Combinators
    import Ormolu.Printer.Meat.Common
    import Ormolu.Printer.Meat.Declaration.Warning
    import Ormolu.Utils (RelativePos (..), attachRelativePos)

    p_hsmodExports :: [LIE GhcPs] -> R ()
    p_hsmodExports :: [LIE GhcPs] -> R ()
    p_hsmodExports [LIE GhcPs]
    xs =
      Bool -> R () -> R ()
    parens' Bool
    False (R () -> R ()) -> R () -> R ()
    forall a b. (a -> b) -> a -> b
    $ do
        layout <- R Layout
    getLayout
        sep
          breakpoint
          (\(Bool
    isAllPrevDoc, RelativePos
    p, GenLocated SrcSpanAnnA (IE GhcPs)
    l) -> R () -> R ()
    sitcc (GenLocated SrcSpanAnnA (IE GhcPs) -> (IE GhcPs -> R ()) -> R ()
    forall l a. HasLoc l => GenLocated l a -> (a -> R ()) -> R ()
    located (GenLocated SrcSpanAnnA (IE GhcPs)
    -> GenLocated SrcSpanAnnA (IE GhcPs)
    forall {l}.
    (Semigroup l, HasAnnotation l) =>
    GenLocated l (IE GhcPs) -> GenLocated l (IE GhcPs)
    addDocSrcSpan GenLocated SrcSpanAnnA (IE GhcPs)
    l) (Layout -> Bool -> RelativePos -> IE GhcPs -> R ()
    p_lie Layout
    layout Bool
    isAllPrevDoc RelativePos
    p)))
          (withAllPrevDoc $ attachRelativePos xs)
      where
        -- In order to correctly set the layout when a doc comment is present.
        addDocSrcSpan :: GenLocated l (IE GhcPs) -> GenLocated l (IE GhcPs)
    addDocSrcSpan lie :: GenLocated l (IE GhcPs)
    lie@(L l
    l IE GhcPs
    ie) = case IE GhcPs -> Maybe (ExportDoc GhcPs)
    ieExportDoc IE GhcPs
    ie of
          Maybe (ExportDoc GhcPs)
    Nothing -> GenLocated l (IE GhcPs)
    lie
          Just (L SrcSpan
    l' HsDoc GhcPs
    _) -> l -> IE GhcPs -> GenLocated l (IE GhcPs)
    forall l e. l -> e -> GenLocated l e
    L (l
    l l -> l -> l
    forall a. Semigroup a => a -> a -> a
    <> SrcSpan -> l
    forall e. HasAnnotation e => SrcSpan -> e
    noAnnSrcSpan SrcSpan
    l') IE GhcPs
    ie

    p_hsmodImport :: ImportDecl GhcPs -> R ()
    p_hsmodImport :: ImportDecl GhcPs -> R ()
    p_hsmodImport ImportDecl {Bool
    Maybe (ImportListInterpretation, XRec GhcPs [LIE GhcPs])
    Maybe (XRec GhcPs ModuleName)
    ImportDeclPkgQual GhcPs
    XCImportDecl GhcPs
    XRec GhcPs ModuleName
    IsBootInterface
    ImportDeclQualifiedStyle
    ideclExt :: XCImportDecl GhcPs
    ideclName :: XRec GhcPs ModuleName
    ideclPkgQual :: ImportDeclPkgQual GhcPs
    ideclSource :: IsBootInterface
    ideclSafe :: Bool
    ideclQualified :: ImportDeclQualifiedStyle
    ideclAs :: Maybe (XRec GhcPs ModuleName)
    ideclImportList :: Maybe (ImportListInterpretation, XRec GhcPs [LIE GhcPs])
    ideclImportList :: forall pass.
    ImportDecl pass
    -> Maybe (ImportListInterpretation, XRec pass [LIE pass])
    ideclAs :: forall pass. ImportDecl pass -> Maybe (XRec pass ModuleName)
    ideclQualified :: forall pass. ImportDecl pass -> ImportDeclQualifiedStyle
    ideclSafe :: forall pass. ImportDecl pass -> Bool
    ideclSource :: forall pass. ImportDecl pass -> IsBootInterface
    ideclPkgQual :: forall pass. ImportDecl pass -> ImportDeclPkgQual pass
    ideclName :: forall pass. ImportDecl pass -> XRec pass ModuleName
    ideclExt :: forall pass. ImportDecl pass -> XCImportDecl pass
    ..} = do
      useQualifiedPost <- Extension -> R Bool
    isExtensionEnabled Extension
    ImportQualifiedPost
      txt "import"
      space
      when (ideclSource == IsBoot) (txt "{-# SOURCE #-}")
      space
      when ideclSafe (txt "safe")
      space
      when
        (isImportDeclQualified ideclQualified && not useQualifiedPost)
        (txt "qualified")
      space
      case ideclPkgQual of
        ImportDeclPkgQual GhcPs
    RawPkgQual
    NoRawPkgQual -> () -> R ()
    forall a. a -> R a
    forall (m :: * -> *) a. Monad m => a -> m a
    return ()
        RawPkgQual StringLiteral
    slit -> StringLiteral -> R ()
    forall a. Outputable a => a -> R ()
    atom StringLiteral
    slit
      space
      inci $ do
        located ideclName atom
        when
          (isImportDeclQualified ideclQualified && useQualifiedPost)
          (space >> txt "qualified")
        case ideclAs of
          Maybe (XRec GhcPs ModuleName)
    Nothing -> () -> R ()
    forall a. a -> R a
    forall (m :: * -> *) a. Monad m => a -> m a
    return ()
          Just XRec GhcPs ModuleName
    l -> do
            R ()
    space
            Text -> R ()
    txt Text
    "as"
            R ()
    space
            GenLocated SrcSpanAnnA ModuleName -> (ModuleName -> R ()) -> R ()
    forall l a. HasLoc l => GenLocated l a -> (a -> R ()) -> R ()
    located XRec GhcPs ModuleName
    GenLocated SrcSpanAnnA ModuleName
    l ModuleName -> R ()
    forall a. Outputable a => a -> R ()
    atom
        space
        case ideclImportList of
          Maybe (ImportListInterpretation, XRec GhcPs [LIE GhcPs])
    Nothing -> () -> R ()
    forall a. a -> R a
    forall (m :: * -> *) a. Monad m => a -> m a
    return ()
          Just (ImportListInterpretation
    hiding, L SrcSpanAnnLI
    _ [GenLocated SrcSpanAnnA (IE GhcPs)]
    xs) -> do
            case ImportListInterpretation
    hiding of
              ImportListInterpretation
    Exactly -> () -> R ()
    forall a. a -> R a
    forall (f :: * -> *) a. Applicative f => a -> f a
    pure ()
              ImportListInterpretation
    EverythingBut -> Text -> R ()
    txt Text
    "hiding"
            R ()
    breakIfNotDiffFriendly
            Bool -> R () -> R ()
    parens' Bool
    True (R () -> R ()) -> R () -> R ()
    forall a b. (a -> b) -> a -> b
    $ do
              layout <- R Layout
    getLayout
              sep
                breakpoint
                (\(RelativePos
    p, GenLocated SrcSpanAnnA (IE GhcPs)
    l) -> R () -> R ()
    sitcc (GenLocated SrcSpanAnnA (IE GhcPs) -> (IE GhcPs -> R ()) -> R ()
    forall l a. HasLoc l => GenLocated l a -> (a -> R ()) -> R ()
    located GenLocated SrcSpanAnnA (IE GhcPs)
    l (Layout -> Bool -> RelativePos -> IE GhcPs -> R ()
    p_lie Layout
    layout Bool
    False RelativePos
    p)))
                (attachRelativePos xs)
        newline

    p_lie :: Layout -> Bool -> RelativePos -> IE GhcPs -> R ()
    p_lie :: Layout -> Bool -> RelativePos -> IE GhcPs -> R ()
    p_lie Layout
    encLayout Bool
    isAllPrevDoc RelativePos
    relativePos = \case
      IEVar XIEVar GhcPs
    mwarn LIEWrappedName GhcPs
    l1 Maybe (ExportDoc GhcPs)
    exportDoc -> do
        Maybe (GenLocated SrcSpanAnnP (WarningTxt GhcPs))
    -> (GenLocated SrcSpanAnnP (WarningTxt GhcPs) -> R ()) -> R ()
    forall (t :: * -> *) (f :: * -> *) a b.
    (Foldable t, Applicative f) =>
    t a -> (a -> f b) -> f ()
    for_ Maybe (GenLocated SrcSpanAnnP (WarningTxt GhcPs))
    XIEVar GhcPs
    mwarn ((GenLocated SrcSpanAnnP (WarningTxt GhcPs) -> R ()) -> R ())
    -> (GenLocated SrcSpanAnnP (WarningTxt GhcPs) -> R ()) -> R ()
    forall a b. (a -> b) -> a -> b
    $ \GenLocated SrcSpanAnnP (WarningTxt GhcPs)
    warnTxt -> do
          GenLocated SrcSpanAnnP (WarningTxt GhcPs)
    -> (WarningTxt GhcPs -> R ()) -> R ()
    forall l a. HasLoc l => GenLocated l a -> (a -> R ()) -> R ()
    located GenLocated SrcSpanAnnP (WarningTxt GhcPs)
    warnTxt WarningTxt GhcPs -> R ()
    p_warningTxt
          R ()
    breakpoint
        R () -> R ()
    withComma (R () -> R ()) -> R () -> R ()
    forall a b. (a -> b) -> a -> b
    $
          GenLocated SrcSpanAnnA (IEWrappedName GhcPs)
    -> (IEWrappedName GhcPs -> R ()) -> R ()
    forall l a. HasLoc l => GenLocated l a -> (a -> R ()) -> R ()
    located LIEWrappedName GhcPs
    GenLocated SrcSpanAnnA (IEWrappedName GhcPs)
    l1 IEWrappedName GhcPs -> R ()
    p_ieWrappedName
        Maybe (ExportDoc GhcPs) -> R ()
    p_exportDoc Maybe (ExportDoc GhcPs)
    exportDoc
      IEThingAbs XIEThingAbs GhcPs
    _ LIEWrappedName GhcPs
    l1 Maybe (ExportDoc GhcPs)
    exportDoc -> do
        R () -> R ()
    withComma (R () -> R ()) -> R () -> R ()
    forall a b. (a -> b) -> a -> b
    $
          GenLocated SrcSpanAnnA (IEWrappedName GhcPs)
    -> (IEWrappedName GhcPs -> R ()) -> R ()
    forall l a. HasLoc l => GenLocated l a -> (a -> R ()) -> R ()
    located LIEWrappedName GhcPs
    GenLocated SrcSpanAnnA (IEWrappedName GhcPs)
    l1 IEWrappedName GhcPs -> R ()
    p_ieWrappedName
        Maybe (ExportDoc GhcPs) -> R ()
    p_exportDoc Maybe (ExportDoc GhcPs)
    exportDoc
      IEThingAll XIEThingAll GhcPs
    _ LIEWrappedName GhcPs
    l1 Maybe (ExportDoc GhcPs)
    exportDoc -> do
        R () -> R ()
    withComma (R () -> R ()) -> R () -> R ()
    forall a b. (a -> b) -> a -> b
    $ do
          GenLocated SrcSpanAnnA (IEWrappedName GhcPs)
    -> (IEWrappedName GhcPs -> R ()) -> R ()
    forall l a. HasLoc l => GenLocated l a -> (a -> R ()) -> R ()
    located LIEWrappedName GhcPs
    GenLocated SrcSpanAnnA (IEWrappedName GhcPs)
    l1 IEWrappedName GhcPs -> R ()
    p_ieWrappedName
          R ()
    space
          Text -> R ()
    txt Text
    "(..)"
        Maybe (ExportDoc GhcPs) -> R ()
    p_exportDoc Maybe (ExportDoc GhcPs)
    exportDoc
      IEThingWith XIEThingWith GhcPs
    _ LIEWrappedName GhcPs
    l1 IEWildcard
    w [LIEWrappedName GhcPs]
    xs Maybe (ExportDoc GhcPs)
    exportDoc -> R () -> R ()
    sitcc (R () -> R ()) -> R () -> R ()
    forall a b. (a -> b) -> a -> b
    $ do
        R () -> R ()
    withComma (R () -> R ()) -> R () -> R ()
    forall a b. (a -> b) -> a -> b
    $ do
          GenLocated SrcSpanAnnA (IEWrappedName GhcPs)
    -> (IEWrappedName GhcPs -> R ()) -> R ()
    forall l a. HasLoc l => GenLocated l a -> (a -> R ()) -> R ()
    located LIEWrappedName GhcPs
    GenLocated SrcSpanAnnA (IEWrappedName GhcPs)
    l1 IEWrappedName GhcPs -> R ()
    p_ieWrappedName
          R ()
    breakIfNotDiffFriendly
          R () -> R ()
    inci (R () -> R ()) -> R () -> R ()
    forall a b. (a -> b) -> a -> b
    $ do
            let names :: [R ()]
                names :: [R ()]
    names = (IEWrappedName GhcPs -> R ())
    -> GenLocated SrcSpanAnnA (IEWrappedName GhcPs) -> R ()
    forall l a. HasLoc l => (a -> R ()) -> GenLocated l a -> R ()
    located' IEWrappedName GhcPs -> R ()
    p_ieWrappedName (GenLocated SrcSpanAnnA (IEWrappedName GhcPs) -> R ())
    -> [GenLocated SrcSpanAnnA (IEWrappedName GhcPs)] -> [R ()]
    forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
    <$> [LIEWrappedName GhcPs]
    [GenLocated SrcSpanAnnA (IEWrappedName GhcPs)]
    xs
            Bool -> R () -> R ()
    parens' Bool
    False (R () -> R ()) -> ([R ()] -> R ()) -> [R ()] -> R ()
    forall b c a. (b -> c) -> (a -> b) -> a -> c
    . R () -> (R () -> R ()) -> [R ()] -> R ()
    forall a. R () -> (a -> R ()) -> [a] -> R ()
    sep R ()
    commaDelImportExport R () -> R ()
    sitcc ([R ()] -> R ()) -> [R ()] -> R ()
    forall a b. (a -> b) -> a -> b
    $
              case IEWildcard
    w of
                IEWildcard
    NoIEWildcard -> [R ()]
    names
                IEWildcard Int
    n ->
                  let ([R ()]
    before, [R ()]
    after) = Int -> [R ()] -> ([R ()], [R ()])
    forall a. Int -> [a] -> ([a], [a])
    splitAt Int
    n [R ()]
    names
                   in [R ()]
    before [R ()] -> [R ()] -> [R ()]
    forall a. [a] -> [a] -> [a]
    ++ [Text -> R ()
    txt Text
    ".."] [R ()] -> [R ()] -> [R ()]
    forall a. [a] -> [a] -> [a]
    ++ [R ()]
    after
        Maybe (ExportDoc GhcPs) -> R ()
    p_exportDoc Maybe (ExportDoc GhcPs)
    exportDoc
      IEModuleContents XIEModuleContents GhcPs
    _ XRec GhcPs ModuleName
    l1 ->
        R () -> R ()
    withComma (R () -> R ()) -> R () -> R ()
    forall a b. (a -> b) -> a -> b
    $
          GenLocated SrcSpanAnnA ModuleName -> (ModuleName -> R ()) -> R ()
    forall l a. HasLoc l => GenLocated l a -> (a -> R ()) -> R ()
    located XRec GhcPs ModuleName
    GenLocated SrcSpanAnnA ModuleName
    l1 ModuleName -> R ()
    p_hsmodName
      IEGroup XIEGroup GhcPs
    NoExtField
    NoExtField Int
    n ExportDoc GhcPs
    str -> do
        case RelativePos
    relativePos of
          RelativePos
    SinglePos -> () -> R ()
    forall a. a -> R a
    forall (m :: * -> *) a. Monad m => a -> m a
    return ()
          RelativePos
    FirstPos -> () -> R ()
    forall a. a -> R a
    forall (m :: * -> *) a. Monad m => a -> m a
    return ()
          RelativePos
    MiddlePos -> R ()
    newline
          RelativePos
    LastPos -> R ()
    newline
        R () -> R ()
    indentDoc (R () -> R ()) -> R () -> R ()
    forall a b. (a -> b) -> a -> b
    $ HaddockStyle -> Choice "endNewline" -> ExportDoc GhcPs -> R ()
    p_hsDoc (Int -> HaddockStyle
    Asterisk Int
    n) (Label "endNewline" -> Choice "endNewline"
    forall (a :: Symbol). Label a -> Choice a
    Without Label "endNewline"
    #endNewline) ExportDoc GhcPs
    str
      IEDoc XIEDoc GhcPs
    NoExtField
    NoExtField ExportDoc GhcPs
    str ->
        R () -> R ()
    indentDoc (R () -> R ()) -> R () -> R ()
    forall a b. (a -> b) -> a -> b
    $
          HaddockStyle -> Choice "endNewline" -> ExportDoc GhcPs -> R ()
    p_hsDoc HaddockStyle
    Pipe (Label "endNewline" -> Choice "endNewline"
    forall (a :: Symbol). Label a -> Choice a
    Without Label "endNewline"
    #endNewline) ExportDoc GhcPs
    str
      IEDocNamed XIEDocNamed GhcPs
    NoExtField
    NoExtField String
    str -> R () -> R ()
    indentDoc (R () -> R ()) -> R () -> R ()
    forall a b. (a -> b) -> a -> b
    $ Text -> R ()
    txt (Text -> R ()) -> Text -> R ()
    forall a b. (a -> b) -> a -> b
    $ Text
    "-- $" Text -> Text -> Text
    forall a. Semigroup a => a -> a -> a
    <> String -> Text
    T.pack String
    str
      where
        -- Add a comma to a import-export list element
        withComma :: R () -> R ()
    withComma R ()
    m =
          case Layout
    encLayout of
            Layout
    SingleLine ->
              case RelativePos
    relativePos of
                RelativePos
    SinglePos -> R () -> R ()
    forall (f :: * -> *) a. Functor f => f a -> f ()
    void R ()
    m
                RelativePos
    FirstPos -> R ()
    m R () -> R () -> R ()
    forall a b. R a -> R b -> R b
    forall (m :: * -> *) a b. Monad m => m a -> m b -> m b
    >> R ()
    comma
                RelativePos
    MiddlePos -> R ()
    m R () -> R () -> R ()
    forall a b. R a -> R b -> R b
    forall (m :: * -> *) a b. Monad m => m a -> m b -> m b
    >> R ()
    comma
                RelativePos
    LastPos -> R () -> R ()
    forall (f :: * -> *) a. Functor f => f a -> f ()
    void R ()
    m
            Layout
    MultiLine -> do
              commaStyle <- R CommaStyle
    getCommaStyle
              case commaStyle of
                CommaStyle
    Leading ->
                  case RelativePos
    relativePos of
                    RelativePos
    FirstPos -> R ()
    m
                    RelativePos
    _ | Bool
    isAllPrevDoc -> Int -> R () -> R ()
    inciBy Int
    2 R ()
    m
                    RelativePos
    SinglePos -> R ()
    m
                    RelativePos
    _ -> R ()
    comma R () -> R () -> R ()
    forall a b. R a -> R b -> R b
    forall (m :: * -> *) a b. Monad m => m a -> m b -> m b
    >> R ()
    space R () -> R () -> R ()
    forall a b. R a -> R b -> R b
    forall (m :: * -> *) a b. Monad m => m a -> m b -> m b
    >> R ()
    m
                CommaStyle
    Trailing -> R ()
    m R () -> R () -> R ()
    forall a b. R a -> R b -> R b
    forall (m :: * -> *) a b. Monad m => m a -> m b -> m b
    >> R ()
    comma

        -- This is used to support `@since` annotations for (re)exported items. It
        -- /must/ use caret style comments, see
        -- https://gitlab.haskell.org/ghc/ghc/-/merge_requests/12098 and
        -- https://github.com/haskell/haddock/issues/1629#issuecomment-1931354411.
        p_exportDoc :: Maybe (ExportDoc GhcPs) -> R ()
        p_exportDoc :: Maybe (ExportDoc GhcPs) -> R ()
    p_exportDoc = (ExportDoc GhcPs -> R ()) -> Maybe (ExportDoc GhcPs) -> R ()
    forall (t :: * -> *) (f :: * -> *) a b.
    (Foldable t, Applicative f) =>
    (a -> f b) -> t a -> f ()
    traverse_ ((ExportDoc GhcPs -> R ()) -> Maybe (ExportDoc GhcPs) -> R ())
    -> (ExportDoc GhcPs -> R ()) -> Maybe (ExportDoc GhcPs) -> R ()
    forall a b. (a -> b) -> a -> b
    $ \ExportDoc GhcPs
    exportDoc -> do
          R ()
    breakpoint
          HaddockStyle -> Choice "endNewline" -> ExportDoc GhcPs -> R ()
    p_hsDoc HaddockStyle
    Caret (Label "endNewline" -> Choice "endNewline"
    forall (a :: Symbol). Label a -> Choice a
    Without Label "endNewline"
    #endNewline) ExportDoc GhcPs
    exportDoc

        indentDoc :: R () -> R ()
    indentDoc R ()
    m = do
          commaStyle <- R CommaStyle
    getCommaStyle
          case commaStyle of
            CommaStyle
    Trailing -> R ()
    m
            CommaStyle
    Leading ->
              case RelativePos
    relativePos of
                RelativePos
    SinglePos -> R ()
    m
                RelativePos
    FirstPos -> R ()
    m
                RelativePos
    _ -> Int -> R () -> R ()
    inciBy Int
    2 R ()
    m

    ieExportDoc :: IE GhcPs -> Maybe (ExportDoc GhcPs)
    ieExportDoc :: IE GhcPs -> Maybe (ExportDoc GhcPs)
    ieExportDoc = \case
      IEVar XIEVar GhcPs
    _ LIEWrappedName GhcPs
    _ Maybe (ExportDoc GhcPs)
    doc -> Maybe (ExportDoc GhcPs)
    doc
      IEThingAbs XIEThingAbs GhcPs
    _ LIEWrappedName GhcPs
    _ Maybe (ExportDoc GhcPs)
    doc -> Maybe (ExportDoc GhcPs)
    doc
      IEThingAll XIEThingAll GhcPs
    _ LIEWrappedName GhcPs
    _ Maybe (ExportDoc GhcPs)
    doc -> Maybe (ExportDoc GhcPs)
    doc
      IEThingWith XIEThingWith GhcPs
    _ LIEWrappedName GhcPs
    _ IEWildcard
    _ [LIEWrappedName GhcPs]
    _ Maybe (ExportDoc GhcPs)
    doc -> Maybe (ExportDoc GhcPs)
    doc
      IEModuleContents {} -> Maybe (ExportDoc GhcPs)
    forall a. Maybe a
    Nothing
      IEGroup {} -> Maybe (ExportDoc GhcPs)
    forall a. Maybe a
    Nothing
      IEDoc {} -> Maybe (ExportDoc GhcPs)
    forall a. Maybe a
    Nothing
      IEDocNamed {} -> Maybe (ExportDoc GhcPs)
    forall a. Maybe a
    Nothing

    ----------------------------------------------------------------------------

    -- | Annotate each element with a Bool indicating if all preceding elements are
    -- documentation elements.
    withAllPrevDoc :: [(RelativePos, LIE GhcPs)] -> [(Bool, RelativePos, LIE GhcPs)]
    withAllPrevDoc :: [(RelativePos, LIE GhcPs)] -> [(Bool, RelativePos, LIE GhcPs)]
    withAllPrevDoc [(RelativePos, LIE GhcPs)]
    xs = ([(RelativePos, GenLocated SrcSpanAnnA (IE GhcPs))]
     -> (RelativePos, GenLocated SrcSpanAnnA (IE GhcPs))
     -> (Bool, RelativePos, GenLocated SrcSpanAnnA (IE GhcPs)))
    -> [[(RelativePos, GenLocated SrcSpanAnnA (IE GhcPs))]]
    -> [(RelativePos, GenLocated SrcSpanAnnA (IE GhcPs))]
    -> [(Bool, RelativePos, GenLocated SrcSpanAnnA (IE GhcPs))]
    forall a b c. (a -> b -> c) -> [a] -> [b] -> [c]
    zipWith [(RelativePos, GenLocated SrcSpanAnnA (IE GhcPs))]
    -> (RelativePos, GenLocated SrcSpanAnnA (IE GhcPs))
    -> (Bool, RelativePos, GenLocated SrcSpanAnnA (IE GhcPs))
    forall {t :: * -> *} {a} {l} {pass} {b} {c}.
    Foldable t =>
    t (a, GenLocated l (IE pass)) -> (b, c) -> (Bool, b, c)
    go ([(RelativePos, GenLocated SrcSpanAnnA (IE GhcPs))]
    -> [[(RelativePos, GenLocated SrcSpanAnnA (IE GhcPs))]]
    forall a. [a] -> [[a]]
    inits [(RelativePos, LIE GhcPs)]
    [(RelativePos, GenLocated SrcSpanAnnA (IE GhcPs))]
    xs) [(RelativePos, LIE GhcPs)]
    [(RelativePos, GenLocated SrcSpanAnnA (IE GhcPs))]
    xs
      where
        go :: t (a, GenLocated l (IE pass)) -> (b, c) -> (Bool, b, c)
    go t (a, GenLocated l (IE pass))
    prevElems (b
    p, c
    l) = (((a, GenLocated l (IE pass)) -> Bool)
    -> t (a, GenLocated l (IE pass)) -> Bool
    forall (t :: * -> *) a. Foldable t => (a -> Bool) -> t a -> Bool
    all (GenLocated l (IE pass) -> Bool
    forall {l} {pass}. GenLocated l (IE pass) -> Bool
    isDoc (GenLocated l (IE pass) -> Bool)
    -> ((a, GenLocated l (IE pass)) -> GenLocated l (IE pass))
    -> (a, GenLocated l (IE pass))
    -> Bool
    forall b c a. (b -> c) -> (a -> b) -> a -> c
    . (a, GenLocated l (IE pass)) -> GenLocated l (IE pass)
    forall a b. (a, b) -> b
    snd) t (a, GenLocated l (IE pass))
    prevElems, b
    p, c
    l)

        isDoc :: GenLocated l (IE pass) -> Bool
    isDoc = \case
          L l
    _ IEDoc {} -> Bool
    True
          L l
    _ IEGroup {} -> Bool
    True
          L l
    _ IEDocNamed {} -> Bool
    True
          GenLocated l (IE pass)
    _ -> Bool
    False

    -- | Surround given entity by parentheses @(@ and @)@.
    parens' :: Bool -> R () -> R ()
    parens' :: Bool -> R () -> R ()
    parens' Bool
    topLevelImport R ()
    m =
      (forall (f :: * -> *). PrinterOpts f -> f ImportExportStyle)
    -> R ImportExportStyle
    forall a. (forall (f :: * -> *). PrinterOpts f -> f a) -> R a
    getPrinterOpt PrinterOpts f -> f ImportExportStyle
    forall (f :: * -> *). PrinterOpts f -> f ImportExportStyle
    poImportExportStyle R ImportExportStyle -> (ImportExportStyle -> R ()) -> R ()
    forall a b. R a -> (a -> R b) -> R b
    forall (m :: * -> *) a b. Monad m => m a -> (a -> m b) -> m b
    >>= \case
        ImportExportStyle
    ImportExportDiffFriendly -> do
          Text -> R ()
    txt Text
    "("
          R ()
    breakpoint'
          R () -> R ()
    sitcc R ()
    body
          R () -> R () -> R ()
    forall a. R a -> R a -> R a
    vlayout (Text -> R ()
    txt Text
    ")") (Rational -> R () -> R ()
    inciByFrac (-Rational
    1) R ()
    trailingParen)
        ImportExportStyle
    _ -> R () -> R ()
    sitcc (R () -> R ()) -> R () -> R ()
    forall a b. (a -> b) -> a -> b
    $ do
          Text -> R ()
    txt Text
    "("
          R ()
    body
          Text -> R ()
    txt Text
    ")"
      where
        body :: R ()
    body = R () -> R () -> R ()
    forall a. R a -> R a -> R a
    vlayout R ()
    singleLine R ()
    multiLine
        singleLine :: R ()
    singleLine = R ()
    m
        multiLine :: R ()
    multiLine = do
          commaStyle <- R CommaStyle
    getCommaStyle
          case commaStyle of
            -- On leading commas, list elements are inline with the enclosing parentheses
            CommaStyle
    Leading -> do
              R ()
    space
              R ()
    m
              R ()
    newline
            -- On trailing commas, list elements are indented
            CommaStyle
    Trailing -> do
              R ()
    space
              R () -> R ()
    sitcc R ()
    m
              R ()
    newline
        trailingParen :: R ()
    trailingParen = if Bool
    topLevelImport then Text -> R ()
    txt Text
    " )" else Text -> R ()
    txt Text
    ")"

    getCommaStyle :: R CommaStyle
    getCommaStyle :: R CommaStyle
    getCommaStyle =
      (forall (f :: * -> *). PrinterOpts f -> f ImportExportStyle)
    -> R ImportExportStyle
    forall a. (forall (f :: * -> *). PrinterOpts f -> f a) -> R a
    getPrinterOpt PrinterOpts f -> f ImportExportStyle
    forall (f :: * -> *). PrinterOpts f -> f ImportExportStyle
    poImportExportStyle R ImportExportStyle
    -> (ImportExportStyle -> R CommaStyle) -> R CommaStyle
    forall a b. R a -> (a -> R b) -> R b
    forall (m :: * -> *) a b. Monad m => m a -> (a -> m b) -> m b
    >>= \case
        ImportExportStyle
    ImportExportLeading -> CommaStyle -> R CommaStyle
    forall a. a -> R a
    forall (f :: * -> *) a. Applicative f => a -> f a
    pure CommaStyle
    Leading
        ImportExportStyle
    ImportExportTrailing -> CommaStyle -> R CommaStyle
    forall a. a -> R a
    forall (f :: * -> *) a. Applicative f => a -> f a
    pure CommaStyle
    Trailing
        ImportExportStyle
    ImportExportDiffFriendly -> CommaStyle -> R CommaStyle
    forall a. a -> R a
    forall (f :: * -> *) a. Applicative f => a -> f a
    pure CommaStyle
    Trailing

    breakIfNotDiffFriendly :: R ()
    breakIfNotDiffFriendly :: R ()
    breakIfNotDiffFriendly =
      (forall (f :: * -> *). PrinterOpts f -> f ImportExportStyle)
    -> R ImportExportStyle
    forall a. (forall (f :: * -> *). PrinterOpts f -> f a) -> R a
    getPrinterOpt PrinterOpts f -> f ImportExportStyle
    forall (f :: * -> *). PrinterOpts f -> f ImportExportStyle
    poImportExportStyle R ImportExportStyle -> (ImportExportStyle -> R ()) -> R ()
    forall a b. R a -> (a -> R b) -> R b
    forall (m :: * -> *) a b. Monad m => m a -> (a -> m b) -> m b
    >>= \case
        ImportExportStyle
    ImportExportDiffFriendly -> R ()
    space
        ImportExportStyle
    _ -> R ()
    breakpoint