@@ -2,7 +2,9 @@
2{-# LANGUAGE OverloadedStrings #-}
2{-# LANGUAGE OverloadedStrings #-}
3{-# LANGUAGE RecordWildCards #-}
3{-# LANGUAGE RecordWildCards #-}
5−-- | Printing combinators.
5+-- | Printing combinators. The definitions here are presented in such an
6+-- order so you can just go through the Haddocks and by the end of the file
7+-- you should have a pretty good idea how to program rendering logic.
7module Ormolu.Printer.Combinators
9module Ormolu.Printer.Combinators
8 ( -- * The 'R' monad
10 ( -- * The 'R' monad
@@ -56,19 +58,24 @@ import qualified Data.Text as T
58-- | Output a fixed 'Text' fragment. The argument may not contain any line
60-- | Output a fixed 'Text' fragment. The argument may not contain any line
59−-- breaks or tab characters.
61+-- breaks or tab characters. 'txt' is used to output all sorts of “fixed”
62+-- bits of syntax like keywords and pipes @|@ in functional dependencies.
61txt :: Text -> R ()
64txt :: Text -> R ()
62txt t = ensureIndent >> spit t
65txt t = ensureIndent >> spit t
64−-- | Output 'Outputable' fragment of AST.
67+-- | Output 'Outputable' fragment of AST. This can be used to output numeric
68+-- literals and similar. Everything that doesn't have inner structure but
69+-- does have an 'Outputable' instance.
66atom :: Outputable a => a -> R ()
71atom :: Outputable a => a -> R ()
67atom = txt . T.pack . showSDocUnsafe . ppr
72atom = txt . T.pack . showSDocUnsafe . ppr
69-- | Enter a 'Located' entity. This combinator handles outputting comments
74-- | Enter a 'Located' entity. This combinator handles outputting comments
70−-- that may be associated with the primitive and sets corresponding layout
71−-- for the inner computation.
75+-- and sets layout (single-line vs multi-line) for the inner computation.
76+-- Roughly, the rule for using 'located' is that every time there is a
77+-- 'Located' wrapper, it should be “discharged” with a corresponding
78+-- 'located' invocation.
@@ -118,7 +125,7 @@ located' = flip located
118-- | Set layout according to given 'SrcSpan' for a given computation. Use
125-- | Set layout according to given 'SrcSpan' for a given computation. Use
119-- this only when you need to set layout based on e.g. combined span of
126-- this only when you need to set layout based on e.g. combined span of
120-- several elements when there is no corresponding 'Located' wrapper
127-- several elements when there is no corresponding 'Located' wrapper
121−-- provided by GHC AST.
128+-- provided by GHC AST. It is relatively rare that this one is needed.
123switchLayout
130switchLayout
124 :: SrcSpan -- ^ Span that controls layout
131 :: SrcSpan -- ^ Span that controls layout
@@ -131,6 +138,8 @@ switchLayout spn = enterLayout
132-- | Insert a space if enclosing layout is single-line, or newline if it's
139-- | Insert a space if enclosing layout is single-line, or newline if it's
133-- multiline.
140-- multiline.
142+-- > breakpoint = vlayout space newline
135breakpoint :: R ()
144breakpoint :: R ()
136breakpoint = vlayout space newline
145breakpoint = vlayout space newline
@@ -174,6 +183,8 @@ withSep sep f = \case
174 in f x : fmap g xs
183 in f x : fmap g xs
176-- | Render space-separated elements.
185-- | Render space-separated elements.
187+-- > spaceSep f = sequence_ . withSep space f
179 :: (a -> R ()) -- ^ How to render list items
190 :: (a -> R ()) -- ^ How to render list items
@@ -182,6 +193,8 @@ spaceSep
182spaceSep f = sequence_ . withSep space f
193spaceSep f = sequence_ . withSep space f
184-- | Render newline-separated elements.
195-- | Render newline-separated elements.
197+-- > newlineSep f = sequence_ . withSep newline f
186newlineSep
199newlineSep
187 :: (a -> R ()) -- ^ How to render list items
200 :: (a -> R ()) -- ^ How to render list items
@@ -193,6 +206,10 @@ newlineSep f = sequence_ . withSep newline f
193-- Wrapping
206-- Wrapping
195-- | Finish given entity by a 'newline'.
208-- | Finish given entity by a 'newline'.
197line :: R () -> R ()
214line :: R () -> R ()
198line m = do
215line m = do