fourmolu-0.15.0.0: A formatter for Haskell source code

Safe Haskell | None
Language | GHC2021

Ormolu.Printer.Internal

Contents

- The `R` monad
- Internal functions
- Helpers for braces
- Special helpers for comment placement
- Stateful markers
- Extensions

Description

In most cases import Ormolu.Printer.Combinators instead, these functions are the low-level building blocks and should not be used on their own. The `R` monad is re-exported from Ormolu.Printer.Combinators as well.

Synopsis

- data R a
- runR :: R () -> SpanStream -> CommentStream -> PrinterOptsTotal -> SourceType -> EnumSet Extension -> ModuleFixityMap -> Bool -> Text
- txt :: Text -> R ()
- interferingTxt :: Text -> R ()
- atom :: Outputable a => a -> R ()
- space :: R ()
- newline :: R ()
- declNewline :: R ()
- askSourceType :: R SourceType
- askModuleFixityMap :: R ModuleFixityMap
- askDebug :: R Bool
- inci :: R () -> R ()
- inciBy :: Int -> R () -> R ()
- inciByFrac :: Rational -> R () -> R ()
- sitcc :: R () -> R ()
- sitccIfTrailing :: R () -> R ()
- data Layout
  - = SingleLine
  - | MultiLine
- enterLayout :: Layout -> R () -> R ()
- vlayout :: R a -> R a -> R a
- getLayout :: R Layout
- getPrinterOpt :: (forall (f :: Type -> Type). PrinterOpts f -> f a) -> R a
- useBraces :: R () -> R ()
- dontUseBraces :: R () -> R ()
- canUseBraces :: R Bool
- data CommentPosition
  - = OnTheSameLine
  - | OnNextLine
- registerPendingCommentLine :: CommentPosition -> Text -> R ()
- trimSpanStream :: RealSrcSpan -> R ()
- nextEltSpan :: R (Maybe RealSrcSpan)
- popComment :: (LComment -> Bool) -> R (Maybe LComment)
- getEnclosingSpan :: R (Maybe RealSrcSpan)
- getEnclosingSpanWhere :: (RealSrcSpan -> Bool) -> R (Maybe RealSrcSpan)
- withEnclosingSpan :: RealSrcSpan -> R () -> R ()
- thisLineSpans :: R [RealSrcSpan]
- data SpanMark
  - = HaddockSpan HaddockStyle RealSrcSpan
  - | CommentSpan RealSrcSpan
  - | StatementSpan RealSrcSpan
- spanMarkSpan :: SpanMark -> RealSrcSpan
- data HaddockStyle
  - = Pipe
  - | Caret
  - | Asterisk Int
  - | Named String
- setSpanMark :: SpanMark -> R ()
- getSpanMark :: R (Maybe SpanMark)
- isExtensionEnabled :: Extension -> R Bool

# The `R` monad

data R a #

The `R` monad hosts combinators that allow us to describe how to render AST.

#### Instances

Instances details

Applicative R # |
Instance details Defined in Ormolu.Printer.Internal Methods pure :: a -> R a # (<*>) :: R (a -> b) -> R a -> R b # liftA2 :: (a -> b -> c) -> R a -> R b -> R c # (*>) :: R a -> R b -> R b # (<*) :: R a -> R b -> R a #
Functor R # |
Instance details Defined in Ormolu.Printer.Internal Methods fmap :: (a -> b) -> R a -> R b # (<$) :: a -> R b -> R a #
Monad R # |
Instance details Defined in Ormolu.Printer.Internal Methods (>>=) :: R a -> (a -> R b) -> R b # (>>) :: R a -> R b -> R b # return :: a -> R a #

runR #

Arguments

:: R () | Monad to run
-> SpanStream | Span stream
-> CommentStream | Comment stream
-> PrinterOptsTotal |
-> SourceType | Whether the source is a signature or a regular module
-> EnumSet Extension | Enabled extensions
-> ModuleFixityMap | Module fixity map
-> Bool | Resulting rendition
-> Text |

Run `R` monad.

# Internal functions

txt #

Arguments

:: Text | `Text` to output
-> R () |

Output a fixed `Text` fragment. The argument may not contain any line breaks. `txt` is used to output all sorts of “fixed” bits of syntax like keywords and pipes `|` in functional dependencies.

To separate various bits of syntax with white space use `space` instead of ``txt` " "`. To output `Outputable` Haskell entities like numbers use `atom`.

interferingTxt #

Arguments

:: Text | `Text` to output
-> R () |

Similar to `txt` but the text inserted this way is assumed to break the “link” between the preceding atom and its pending comments.

atom :: Outputable a => a -> R () #

Output `Outputable` fragment of AST. This can be used to output numeric literals and similar. Everything that doesn't have inner structure but does have an `Outputable` instance.

space :: R () #

This primitive does not necessarily output a space. It just ensures that the next thing that will be printed on the same line will be separated by a single space from the previous output. Using this combinator twice results in at most one space.

In practice this design prevents trailing white space and makes it hard to output more than one delimiting space in a row, which is what we usually want.

newline :: R () #

Output a newline. First time `newline` is used after some non-`newline` output it gets inserted immediately. Second use of `newline` does not output anything but makes sure that the next non-white space output will be prefixed by a newline. Using `newline` more than twice in a row has no effect. Also, using `newline` at the very beginning has no effect, this is to avoid leading whitespace.

Similarly to `space`, this design prevents trailing newlines and makes it hard to output more than one blank newline in a row.

declNewline :: R () #

askSourceType :: R SourceType #

Return the source type.

askModuleFixityMap :: R ModuleFixityMap #

Retrieve the module fixity map.

askDebug :: R Bool #

Retrieve whether we should print out certain debug information while printing.

inci :: R () -> R () #

Increase indentation level by one indentation step for the inner computation. `inci` should be used when a part of code must be more indented relative to the parts outside of `inci` in order for the output to be valid Haskell. When layout is single-line there is no obvious effect, but with multi-line layout correct indentation levels matter.

inciBy :: Int -> R () -> R () #

Like `inci`, but indents by exactly the given number of steps.

inciByFrac :: Rational -> R () -> R () #

Like `inci`, but indents by the given fraction of a full step.

sitcc :: R () -> R () #

Set indentation level for the inner computation equal to current column. This makes sure that the entire inner block is uniformly "shifted" to the right.

sitccIfTrailing :: R () -> R () #

When using trailing commas, same as `sitcc`; when using leading commas, runs the input action unmodified.

data Layout #

`Layout` options.

Constructors

SingleLine | Put everything on single line
MultiLine | Use multiple lines

#### Instances

Instances details

Show Layout # |
Instance details Defined in Ormolu.Printer.Internal Methods showsPrec :: Int -> Layout -> ShowS # show :: Layout -> String # showList :: [Layout] -> ShowS #
Eq Layout # |
Instance details Defined in Ormolu.Printer.Internal Methods (==) :: Layout -> Layout -> Bool # (/=) :: Layout -> Layout -> Bool #

enterLayout :: Layout -> R () -> R () #

Set `Layout` for internal computation.

vlayout #

Arguments

:: R a | Single line
-> R a | Multi line
-> R a |

Do one or another thing depending on current `Layout`.

getLayout :: R Layout #

Get current `Layout`.

getPrinterOpt :: (forall (f :: Type -> Type). PrinterOpts f -> f a) -> R a #

Get a particular `PrinterOpts` field from the environment.

# Helpers for braces

useBraces :: R () -> R () #

Make the inner computation use braces around single-line layouts.

dontUseBraces :: R () -> R () #

Make the inner computation omit braces around single-line layouts.

canUseBraces :: R Bool #

Return `True` if we can use braces in this context.

# Special helpers for comment placement

data CommentPosition #

Modes for rendering of pending comments.

Constructors

OnTheSameLine | Put the comment on the same line
OnNextLine | Put the comment on next line

#### Instances

Instances details

Show CommentPosition # |
Instance details Defined in Ormolu.Printer.Internal Methods showsPrec :: Int -> CommentPosition -> ShowS # show :: CommentPosition -> String # showList :: [CommentPosition] -> ShowS #
Eq CommentPosition # |
Instance details Defined in Ormolu.Printer.Internal Methods (==) :: CommentPosition -> CommentPosition -> Bool # (/=) :: CommentPosition -> CommentPosition -> Bool #

registerPendingCommentLine #

Arguments

:: CommentPosition | Comment position
-> Text | `Text` to output
-> R () |

Register a comment line for outputting. It will be inserted right before next newline. When the comment goes after something else on the same line, a space will be inserted between preceding text and the comment when necessary.

trimSpanStream #

Arguments

:: RealSrcSpan | Reference span
-> R () |

Drop elements that begin before or at the same place as given `SrcSpan`.

nextEltSpan :: R (Maybe RealSrcSpan) #

Get location of next element in AST.

popComment :: (LComment -> Bool) -> R (Maybe LComment) #

Pop a `Comment` from the `CommentStream` if given predicate is satisfied and there are comments in the stream.

getEnclosingSpan :: R (Maybe RealSrcSpan) #

Get the immediately enclosing `RealSrcSpan`.

getEnclosingSpanWhere #

Arguments

:: (RealSrcSpan -> Bool) | Predicate to use
-> R (Maybe RealSrcSpan) |

Get the first enclosing `RealSrcSpan` that satisfies given predicate.

withEnclosingSpan :: RealSrcSpan -> R () -> R () #

Set `RealSrcSpan` of enclosing span for the given computation.

thisLineSpans :: R [RealSrcSpan] #

Get spans on this line so far.

# Stateful markers

data SpanMark #

An auxiliary marker for keeping track of last output element.

Constructors

HaddockSpan HaddockStyle RealSrcSpan | Haddock comment
CommentSpan RealSrcSpan | Non-haddock comment
StatementSpan RealSrcSpan | A statement in a do-block and such span

spanMarkSpan :: SpanMark -> RealSrcSpan #

Project `RealSrcSpan` from `SpanMark`.

data HaddockStyle #

Haddock string style.

Constructors

Pipe |
    -- |
Caret |
    -- ^
Asterisk Int |
    -- *
Named String |
    -- $

setSpanMark #

Arguments

:: SpanMark | Span mark to set
-> R () |

Set span of last output comment.

getSpanMark :: R (Maybe SpanMark) #

Get span of last output comment.

# Extensions

isExtensionEnabled :: Extension -> R Bool #