{-| Pretty printing functions.
-}
module Agda.Syntax.Common.Pretty
    ( module Agda.Syntax.Common.Pretty
    , module Text.PrettyPrint.Annotated
    -- This re-export can be removed once <GHC-8.4 is dropped.
    , module Data.Semigroup
    ) where

import Prelude hiding (null)

import qualified Data.Foldable as Fold
import qualified Data.IntSet as IntSet
import qualified Data.IntMap as IntMap
import qualified Data.Text as T
import qualified Data.Map as Map
import qualified Data.Set as Set
import Data.IntSet (IntSet)
import Data.IntMap (IntMap)
import Data.Word (Word64)
import Data.Text (Text)
import Data.Int (Int32)
import Data.Map (Map)
import Data.Set (Set)

import qualified Text.PrettyPrint.Annotated as P
import Text.PrettyPrint.Annotated hiding
  ( Doc, TextDetails(Str), empty, (<>), sep, fsep, hsep, hcat, vcat, punctuate

  , parens, brackets, braces, quotes, doubleQuotes

  , semi, comma, colon, space, equals, lparen, rparen, lbrack, rbrack
  , lbrace, rbrace
  )

import Data.Semigroup ((<>))

import Agda.Utils.Float
import Agda.Utils.List1 (List1)
import qualified Agda.Utils.List1 as List1
import qualified Agda.Utils.Maybe.Strict as Strict
import Agda.Utils.Null
import Agda.Utils.Size

import Agda.Syntax.Common.Aspect
import Agda.Syntax.Position
import Agda.Utils.Impossible
import Agda.Utils.FileName


-- * Pretty class

-- | The type of documents. We use documents annotated by 'Aspects' to
-- record syntactic highlighting information that is generated during
-- pretty-printing.
type Doc = P.Doc Aspects

-- | While 'Show' is for rendering data in Haskell syntax,
--   'Pretty' is for displaying data to the world, i.e., the
--   user and the environment.
--
--   Atomic data has no inner document structure, so just
--   implement 'pretty' as @pretty a = text $ ... a ...@.

class Pretty a where
  pretty      :: a -> Doc
  prettyPrec  :: Int -> a -> Doc
  prettyList  :: [a] -> Doc

  pretty      = forall a. Pretty a => Int -> a -> Doc Aspects
prettyPrec Int
0
  prettyPrec  = forall a b. a -> b -> a
const forall a. Pretty a => a -> Doc Aspects
pretty
  prettyList  = Doc Aspects -> Doc Aspects
brackets forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall a. Pretty a => [a] -> Doc Aspects
prettyList_

-- | Use instead of 'show' when printing to world.

prettyShow :: Pretty a => a -> String
prettyShow :: forall a. Pretty a => a -> String
prettyShow = forall a. Doc a -> String
render forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall a. Pretty a => a -> Doc Aspects
pretty

-- * Pretty instances

instance Pretty Bool    where pretty :: Bool -> Doc Aspects
pretty = forall a. String -> Doc a
text forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall a. Show a => a -> String
show
instance Pretty Int     where pretty :: Int -> Doc Aspects
pretty = forall a. String -> Doc a
text forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall a. Show a => a -> String
show
instance Pretty Int32   where pretty :: Int32 -> Doc Aspects
pretty = forall a. String -> Doc a
text forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall a. Show a => a -> String
show
instance Pretty Integer where pretty :: Integer -> Doc Aspects
pretty = forall a. String -> Doc a
text forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall a. Show a => a -> String
show
instance Pretty Word64  where pretty :: Word64 -> Doc Aspects
pretty = forall a. String -> Doc a
text forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall a. Show a => a -> String
show
instance Pretty Double  where pretty :: Double -> Doc Aspects
pretty = forall a. String -> Doc a
text forall b c a. (b -> c) -> (a -> b) -> a -> c
. Double -> String
toStringWithoutDotZero
instance Pretty Text    where pretty :: Text -> Doc Aspects
pretty = forall a. String -> Doc a
text forall b c a. (b -> c) -> (a -> b) -> a -> c
. Text -> String
T.unpack

instance Pretty Char where
  pretty :: Char -> Doc Aspects
pretty Char
c = forall a. String -> Doc a
text [Char
c]
  prettyList :: String -> Doc Aspects
prettyList = forall a. String -> Doc a
text


-- The equational constraint forces GHC to pick this instance and unify
-- the type variable, instead of deferring selection to when the type of
-- annotations is solved.
instance a ~ Aspects => Pretty (P.Doc a) where
  pretty :: Doc a -> Doc Aspects
pretty = forall a. a -> a
id

instance Pretty () where
  pretty :: () -> Doc Aspects
pretty ()
_ = forall a. Doc a
P.empty

instance Pretty a => Pretty (Maybe a) where
  prettyPrec :: Int -> Maybe a -> Doc Aspects
prettyPrec Int
p Maybe a
Nothing  = Doc Aspects
"(nothing)"
  prettyPrec Int
p (Just a
x) = forall a. Pretty a => Int -> a -> Doc Aspects
prettyPrec Int
p a
x

instance Pretty a => Pretty [a] where
  pretty :: [a] -> Doc Aspects
pretty = forall a. Pretty a => [a] -> Doc Aspects
prettyList

instance Pretty a => Pretty (List1 a) where
  pretty :: List1 a -> Doc Aspects
pretty = forall a. Pretty a => [a] -> Doc Aspects
prettyList forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall l. IsList l => l -> [Item l]
List1.toList

instance Pretty IntSet where
  pretty :: IntSet -> Doc Aspects
pretty = forall a. Pretty a => [a] -> Doc Aspects
prettySet forall b c a. (b -> c) -> (a -> b) -> a -> c
. IntSet -> [Int]
IntSet.toList

instance Pretty a => Pretty (Set a) where
  pretty :: Set a -> Doc Aspects
pretty = forall a. Pretty a => [a] -> Doc Aspects
prettySet forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall a. Set a -> [a]
Set.toList

instance Pretty a => Pretty (IntMap a) where
  pretty :: IntMap a -> Doc Aspects
pretty = forall k v. (Pretty k, Pretty v) => [(k, v)] -> Doc Aspects
prettyMap forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall a. IntMap a -> [(Int, a)]
IntMap.toList

instance (Pretty k, Pretty v) => Pretty (Map k v) where
  pretty :: Map k v -> Doc Aspects
pretty = forall k v. (Pretty k, Pretty v) => [(k, v)] -> Doc Aspects
prettyMap forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall k a. Map k a -> [(k, a)]
Map.toList

-- Pretty instances for dependencies of this module (to avoid dependency cycles)

instance Pretty AbsolutePath where
  pretty :: AbsolutePath -> Doc Aspects
pretty = forall a. String -> Doc a
text forall b c a. (b -> c) -> (a -> b) -> a -> c
. AbsolutePath -> String
filePath

instance Pretty RangeFile where
  pretty :: RangeFile -> Doc Aspects
pretty = forall a. Pretty a => a -> Doc Aspects
pretty forall b c a. (b -> c) -> (a -> b) -> a -> c
. RangeFile -> AbsolutePath
rangeFilePath

instance Pretty a => Pretty (Position' (Strict.Maybe a)) where
  pretty :: Position' (Maybe a) -> Doc Aspects
pretty (Pn Maybe a
Strict.Nothing  Int32
_ Int32
l Int32
c) = forall a. Pretty a => a -> Doc Aspects
pretty Int32
l forall a. Semigroup a => a -> a -> a
<> Doc Aspects
"," forall a. Semigroup a => a -> a -> a
<> forall a. Pretty a => a -> Doc Aspects
pretty Int32
c
  pretty (Pn (Strict.Just a
f) Int32
_ Int32
l Int32
c) =
    forall a. Pretty a => a -> Doc Aspects
pretty a
f forall a. Semigroup a => a -> a -> a
<> Doc Aspects
":" forall a. Semigroup a => a -> a -> a
<> forall a. Pretty a => a -> Doc Aspects
pretty Int32
l forall a. Semigroup a => a -> a -> a
<> Doc Aspects
"," forall a. Semigroup a => a -> a -> a
<> forall a. Pretty a => a -> Doc Aspects
pretty Int32
c

instance Pretty PositionWithoutFile where
  pretty :: PositionWithoutFile -> Doc Aspects
pretty PositionWithoutFile
p = forall a. Pretty a => a -> Doc Aspects
pretty (PositionWithoutFile
p { srcFile :: Maybe RangeFile
srcFile = forall a. Maybe a
Strict.Nothing } :: Position)

instance Pretty IntervalWithoutFile where
  pretty :: IntervalWithoutFile -> Doc Aspects
pretty (Interval PositionWithoutFile
s PositionWithoutFile
e) = Doc Aspects
start forall a. Semigroup a => a -> a -> a
<> Doc Aspects
"-" forall a. Semigroup a => a -> a -> a
<> Doc Aspects
end
    where
      sl :: Int32
sl = forall a. Position' a -> Int32
posLine PositionWithoutFile
s
      el :: Int32
el = forall a. Position' a -> Int32
posLine PositionWithoutFile
e
      sc :: Int32
sc = forall a. Position' a -> Int32
posCol PositionWithoutFile
s
      ec :: Int32
ec = forall a. Position' a -> Int32
posCol PositionWithoutFile
e

      start :: Doc
      start :: Doc Aspects
start = forall a. Pretty a => a -> Doc Aspects
pretty Int32
sl forall a. Semigroup a => a -> a -> a
<> Doc Aspects
comma forall a. Semigroup a => a -> a -> a
<> forall a. Pretty a => a -> Doc Aspects
pretty Int32
sc

      Doc Aspects
end :: Doc
        | Int32
sl forall a. Eq a => a -> a -> Bool
== Int32
el  = forall a. Pretty a => a -> Doc Aspects
pretty Int32
ec
        | Bool
otherwise = forall a. Pretty a => a -> Doc Aspects
pretty Int32
el forall a. Semigroup a => a -> a -> a
<> Doc Aspects
comma forall a. Semigroup a => a -> a -> a
<> forall a. Pretty a => a -> Doc Aspects
pretty Int32
ec

instance Pretty a => Pretty (Interval' (Strict.Maybe a)) where
  pretty :: Interval' (Maybe a) -> Doc Aspects
pretty i :: Interval' (Maybe a)
i@(Interval Position' (Maybe a)
s Position' (Maybe a)
_) = Doc Aspects
file forall a. Semigroup a => a -> a -> a
<> forall a. Pretty a => a -> Doc Aspects
pretty (forall a b. a -> Interval' b -> Interval' a
setIntervalFile () Interval' (Maybe a)
i)
    where
      file :: Doc
      file :: Doc Aspects
file = case forall a. Position' a -> a
srcFile Position' (Maybe a)
s of
               Maybe a
Strict.Nothing -> forall a. Null a => a
empty
               Strict.Just a
f  -> forall a. Pretty a => a -> Doc Aspects
pretty a
f forall a. Semigroup a => a -> a -> a
<> Doc Aspects
colon

instance Pretty a => Pretty (Range' (Strict.Maybe a)) where
  pretty :: Range' (Maybe a) -> Doc Aspects
pretty Range' (Maybe a)
r = forall b a. b -> (a -> b) -> Maybe a -> b
maybe forall a. Null a => a
empty forall a. Pretty a => a -> Doc Aspects
pretty (forall a. Range' a -> Maybe (Interval' a)
rangeToIntervalWithFile Range' (Maybe a)
r)

instance (Pretty a, HasRange a) => Pretty (PrintRange a) where
  pretty :: PrintRange a -> Doc Aspects
pretty (PrintRange a
a) = forall a. Pretty a => a -> Doc Aspects
pretty a
a forall a. Doc a -> Doc a -> Doc a
<+> Doc Aspects -> Doc Aspects
parens (Doc Aspects
"at" forall a. Doc a -> Doc a -> Doc a
<+> forall a. Pretty a => a -> Doc Aspects
pretty (forall a. HasRange a => a -> Range
getRange a
a))


-- * Generalizing the original type from list to Foldable

sep, fsep, hsep, hcat, vcat :: Foldable t => t Doc -> Doc
sep :: forall (t :: * -> *). Foldable t => t (Doc Aspects) -> Doc Aspects
sep  = forall a. [Doc a] -> Doc a
P.sep  forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall (t :: * -> *) a. Foldable t => t a -> [a]
Fold.toList
fsep :: forall (t :: * -> *). Foldable t => t (Doc Aspects) -> Doc Aspects
fsep = forall a. [Doc a] -> Doc a
P.fsep forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall (t :: * -> *) a. Foldable t => t a -> [a]
Fold.toList
hsep :: forall (t :: * -> *). Foldable t => t (Doc Aspects) -> Doc Aspects
hsep = forall a. [Doc a] -> Doc a
P.hsep forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall (t :: * -> *) a. Foldable t => t a -> [a]
Fold.toList
hcat :: forall (t :: * -> *). Foldable t => t (Doc Aspects) -> Doc Aspects
hcat = forall a. [Doc a] -> Doc a
P.hcat forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall (t :: * -> *) a. Foldable t => t a -> [a]
Fold.toList
vcat :: forall (t :: * -> *). Foldable t => t (Doc Aspects) -> Doc Aspects
vcat = forall a. [Doc a] -> Doc a
P.vcat forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall (t :: * -> *) a. Foldable t => t a -> [a]
Fold.toList

punctuate :: Foldable t => Doc -> t Doc -> [Doc]
punctuate :: forall (t :: * -> *).
Foldable t =>
Doc Aspects -> t (Doc Aspects) -> [Doc Aspects]
punctuate Doc Aspects
d = forall a. Doc a -> [Doc a] -> [Doc a]
P.punctuate Doc Aspects
d forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall (t :: * -> *) a. Foldable t => t a -> [a]
Fold.toList

-- * 'Doc' utilities

pwords :: String -> [Doc]
pwords :: String -> [Doc Aspects]
pwords = forall a b. (a -> b) -> [a] -> [b]
map forall a. String -> Doc a
text forall b c a. (b -> c) -> (a -> b) -> a -> c
. String -> [String]
words

fwords :: String -> Doc
fwords :: String -> Doc Aspects
fwords = forall (t :: * -> *). Foldable t => t (Doc Aspects) -> Doc Aspects
fsep forall b c a. (b -> c) -> (a -> b) -> a -> c
. String -> [Doc Aspects]
pwords

-- | Separate, but only if both separees are not null.

hsepWith :: Doc -> Doc -> Doc -> Doc
hsepWith :: Doc Aspects -> Doc Aspects -> Doc Aspects -> Doc Aspects
hsepWith Doc Aspects
sep Doc Aspects
d1 Doc Aspects
d2
  | forall a. Null a => a -> Bool
null Doc Aspects
d2   = Doc Aspects
d1
  | forall a. Null a => a -> Bool
null Doc Aspects
d1   = Doc Aspects
d2
  | Bool
otherwise = Doc Aspects
d1 forall a. Doc a -> Doc a -> Doc a
<+> Doc Aspects
sep forall a. Doc a -> Doc a -> Doc a
<+> Doc Aspects
d2

-- | Comma separated list, without the brackets.
prettyList_ :: Pretty a => [a] -> Doc
prettyList_ :: forall a. Pretty a => [a] -> Doc Aspects
prettyList_ = forall (t :: * -> *). Foldable t => t (Doc Aspects) -> Doc Aspects
fsep forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall (t :: * -> *).
Foldable t =>
Doc Aspects -> t (Doc Aspects) -> [Doc Aspects]
punctuate Doc Aspects
comma forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall a b. (a -> b) -> [a] -> [b]
map forall a. Pretty a => a -> Doc Aspects
pretty

-- | Pretty print a set.
prettySet :: Pretty a => [a] -> Doc
prettySet :: forall a. Pretty a => [a] -> Doc Aspects
prettySet = Doc Aspects -> Doc Aspects
braces forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall a. Pretty a => [a] -> Doc Aspects
prettyList_

-- | Pretty print an association list.
prettyMap :: (Pretty k, Pretty v) => [(k,v)] -> Doc
prettyMap :: forall k v. (Pretty k, Pretty v) => [(k, v)] -> Doc Aspects
prettyMap = Doc Aspects -> Doc Aspects
braces forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall (t :: * -> *). Foldable t => t (Doc Aspects) -> Doc Aspects
fsep forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall (t :: * -> *).
Foldable t =>
Doc Aspects -> t (Doc Aspects) -> [Doc Aspects]
punctuate Doc Aspects
comma forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall a b. (a -> b) -> [a] -> [b]
map forall k v. (Pretty k, Pretty v) => (k, v) -> Doc Aspects
prettyAssign

-- | Pretty print a single association.
prettyAssign :: (Pretty k, Pretty v) => (k,v) -> Doc
prettyAssign :: forall k v. (Pretty k, Pretty v) => (k, v) -> Doc Aspects
prettyAssign (k
k, v
v) = forall (t :: * -> *). Foldable t => t (Doc Aspects) -> Doc Aspects
sep [ forall a. Pretty a => Int -> a -> Doc Aspects
prettyPrec Int
1 k
k forall a. Doc a -> Doc a -> Doc a
<+> Doc Aspects -> Doc Aspects
hlSymbol Doc Aspects
"->", forall a. Int -> Doc a -> Doc a
nest Int
2 forall a b. (a -> b) -> a -> b
$ forall a. Pretty a => a -> Doc Aspects
pretty v
v ]

-- ASR (2016-12-13): In pretty >= 1.1.2.0 the below function 'mparens'
-- is called 'maybeParens'. I didn't use that name due to the issue
-- https://github.com/haskell/pretty/issues/40.

-- | Apply 'parens' to 'Doc' if boolean is true.
mparens :: Bool -> Doc -> Doc
mparens :: Bool -> Doc Aspects -> Doc Aspects
mparens Bool
True  = Doc Aspects -> Doc Aspects
parens
mparens Bool
False = forall a. a -> a
id

-- | Only wrap in parens if not 'empty'
parensNonEmpty :: Doc -> Doc
parensNonEmpty :: Doc Aspects -> Doc Aspects
parensNonEmpty Doc Aspects
d = if forall a. Null a => a -> Bool
null Doc Aspects
d then forall a. Null a => a
empty else Doc Aspects -> Doc Aspects
parens Doc Aspects
d

-- | @align max rows@ lays out the elements of @rows@ in two columns,
-- with the second components aligned. The alignment column of the
-- second components is at most @max@ characters to the right of the
-- left-most column.
--
-- Precondition: @max > 0@.

align :: Int -> [(String, Doc)] -> Doc
align :: Int -> [(String, Doc Aspects)] -> Doc Aspects
align Int
max [(String, Doc Aspects)]
rows =
  forall (t :: * -> *). Foldable t => t (Doc Aspects) -> Doc Aspects
vcat forall a b. (a -> b) -> a -> b
$ forall a b. (a -> b) -> [a] -> [b]
map (\(String
s, Doc Aspects
d) -> forall a. String -> Doc a
text String
s forall a. Doc a -> Doc a -> Doc a
$$ forall a. Int -> Doc a -> Doc a
nest (Int
maxLen forall a. Num a => a -> a -> a
+ Int
1) Doc Aspects
d) forall a b. (a -> b) -> a -> b
$ [(String, Doc Aspects)]
rows
  where maxLen :: Int
maxLen = forall (t :: * -> *) a. (Foldable t, Ord a) => t a -> a
maximum forall a b. (a -> b) -> a -> b
$ Int
0 forall a. a -> [a] -> [a]
: forall a. (a -> Bool) -> [a] -> [a]
filter (forall a. Ord a => a -> a -> Bool
< Int
max) (forall a b. (a -> b) -> [a] -> [b]
map (forall (t :: * -> *) a. Foldable t => t a -> Int
length forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall a b. (a, b) -> a
fst) [(String, Doc Aspects)]
rows)

-- | Handles strings with newlines properly (preserving indentation)
multiLineText :: String -> Doc
multiLineText :: String -> Doc Aspects
multiLineText = forall (t :: * -> *). Foldable t => t (Doc Aspects) -> Doc Aspects
vcat forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall a b. (a -> b) -> [a] -> [b]
map forall a. String -> Doc a
text forall b c a. (b -> c) -> (a -> b) -> a -> c
. String -> [String]
lines

infixl 6 <?>
-- | @a <?> b = hang a 2 b@
(<?>) :: Doc -> Doc -> Doc
Doc Aspects
a <?> :: Doc Aspects -> Doc Aspects -> Doc Aspects
<?> Doc Aspects
b = forall a. Doc a -> Int -> Doc a -> Doc a
hang Doc Aspects
a Int
2 Doc Aspects
b

-- | @pshow = text . show@
pshow :: Show a => a -> Doc
pshow :: forall a. Show a => a -> Doc Aspects
pshow = forall a. String -> Doc a
text forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall a. Show a => a -> String
show

singPlural :: Sized a => a -> c -> c -> c
singPlural :: forall a c. Sized a => a -> c -> c -> c
singPlural a
xs c
singular c
plural = if forall a. Sized a => a -> Peano
natSize a
xs forall a. Eq a => a -> a -> Bool
== Peano
1 then c
singular else c
plural

-- | Used for with-like 'telescopes'

prefixedThings :: Doc -> [Doc] -> Doc
prefixedThings :: Doc Aspects -> [Doc Aspects] -> Doc Aspects
prefixedThings Doc Aspects
kw = \case
  []           -> forall a. Doc a
P.empty
  (Doc Aspects
doc : [Doc Aspects]
docs) -> forall (t :: * -> *). Foldable t => t (Doc Aspects) -> Doc Aspects
fsep forall a b. (a -> b) -> a -> b
$ (Doc Aspects
kw forall a. Doc a -> Doc a -> Doc a
<+> Doc Aspects
doc) forall a. a -> [a] -> [a]
: forall a b. (a -> b) -> [a] -> [b]
map (Doc Aspects -> Doc Aspects
hlSymbol Doc Aspects
"|" forall a. Doc a -> Doc a -> Doc a
<+>) [Doc Aspects]
docs

-- | Attach a simple 'Aspect', rather than a full set of 'Aspects', to a
-- document.
annotateAspect :: Aspect -> Doc -> Doc
annotateAspect :: Aspect -> Doc Aspects -> Doc Aspects
annotateAspect Aspect
a = forall a. a -> Doc a -> Doc a
annotate Aspects
a' where
  a' :: Aspects
a' = Aspects
    { aspect :: Maybe Aspect
aspect         = forall a. a -> Maybe a
Just Aspect
a
    , otherAspects :: Set OtherAspect
otherAspects   = forall a. Monoid a => a
mempty
    , note :: String
note           = String
""
    , definitionSite :: Maybe DefinitionSite
definitionSite = forall a. Maybe a
Nothing
    , tokenBased :: TokenBased
tokenBased     = TokenBased
TokenBased
    }

-- * Syntax highlighting helpers

hlComment, hlSymbol, hlKeyword, hlString, hlNumber, hlHole, hlPrimitiveType, hlPragma
  :: Doc -> Doc

hlComment :: Doc Aspects -> Doc Aspects
hlComment       = Aspect -> Doc Aspects -> Doc Aspects
annotateAspect Aspect
Comment
hlSymbol :: Doc Aspects -> Doc Aspects
hlSymbol        = Aspect -> Doc Aspects -> Doc Aspects
annotateAspect Aspect
Symbol
hlKeyword :: Doc Aspects -> Doc Aspects
hlKeyword       = Aspect -> Doc Aspects -> Doc Aspects
annotateAspect Aspect
Keyword
hlString :: Doc Aspects -> Doc Aspects
hlString        = Aspect -> Doc Aspects -> Doc Aspects
annotateAspect Aspect
String
hlNumber :: Doc Aspects -> Doc Aspects
hlNumber        = Aspect -> Doc Aspects -> Doc Aspects
annotateAspect Aspect
Number
hlHole :: Doc Aspects -> Doc Aspects
hlHole          = Aspect -> Doc Aspects -> Doc Aspects
annotateAspect Aspect
Hole
hlPrimitiveType :: Doc Aspects -> Doc Aspects
hlPrimitiveType = Aspect -> Doc Aspects -> Doc Aspects
annotateAspect Aspect
PrimitiveType
hlPragma :: Doc Aspects -> Doc Aspects
hlPragma        = Aspect -> Doc Aspects -> Doc Aspects
annotateAspect Aspect
Pragma

-- * Delimiter wrappers
--
-- These use the 'Symbol' highlight for the punctuation characters.

parens       :: Doc -> Doc -- ^ Wrap document in @(...)@
brackets     :: Doc -> Doc -- ^ Wrap document in @[...]@
braces       :: Doc -> Doc -- ^ Wrap document in @{...}@
quotes       :: Doc -> Doc -- ^ Wrap document in @\'...\'@
doubleQuotes :: Doc -> Doc -- ^ Wrap document in @\"...\"@
quotes :: Doc Aspects -> Doc Aspects
quotes Doc Aspects
p       = Doc Aspects -> Doc Aspects
hlSymbol (forall a. Char -> Doc a
char Char
'\'') forall a. Semigroup a => a -> a -> a
<> Doc Aspects
p forall a. Semigroup a => a -> a -> a
<> Doc Aspects -> Doc Aspects
hlSymbol (forall a. Char -> Doc a
char Char
'\'')
doubleQuotes :: Doc Aspects -> Doc Aspects
doubleQuotes Doc Aspects
p = Doc Aspects -> Doc Aspects
hlSymbol (forall a. Char -> Doc a
char Char
'"') forall a. Semigroup a => a -> a -> a
<> Doc Aspects
p forall a. Semigroup a => a -> a -> a
<> Doc Aspects -> Doc Aspects
hlSymbol (forall a. Char -> Doc a
char Char
'"')
parens :: Doc Aspects -> Doc Aspects
parens Doc Aspects
p       = Doc Aspects
lparen forall a. Semigroup a => a -> a -> a
<> Doc Aspects
p forall a. Semigroup a => a -> a -> a
<> Doc Aspects
rparen
brackets :: Doc Aspects -> Doc Aspects
brackets Doc Aspects
p     = Doc Aspects
lbrack forall a. Semigroup a => a -> a -> a
<> Doc Aspects
p forall a. Semigroup a => a -> a -> a
<> Doc Aspects
rbrack
braces :: Doc Aspects -> Doc Aspects
braces Doc Aspects
p       = Doc Aspects
lbrace forall a. Semigroup a => a -> a -> a
<> Doc Aspects
p forall a. Semigroup a => a -> a -> a
<> Doc Aspects
rbrace

semi, comma, colon, space, equals, lparen, rparen, lbrack, rbrack, lbrace, rbrace :: Doc
semi :: Doc Aspects
semi   = Doc Aspects -> Doc Aspects
hlSymbol forall a b. (a -> b) -> a -> b
$ forall a. Char -> Doc a
char Char
';'
comma :: Doc Aspects
comma  = Doc Aspects -> Doc Aspects
hlSymbol forall a b. (a -> b) -> a -> b
$ forall a. Char -> Doc a
char Char
','
colon :: Doc Aspects
colon  = Doc Aspects -> Doc Aspects
hlSymbol forall a b. (a -> b) -> a -> b
$ forall a. Char -> Doc a
char Char
':'
space :: Doc Aspects
space  = Doc Aspects -> Doc Aspects
hlSymbol forall a b. (a -> b) -> a -> b
$ forall a. Char -> Doc a
char Char
' '
equals :: Doc Aspects
equals = Doc Aspects -> Doc Aspects
hlSymbol forall a b. (a -> b) -> a -> b
$ forall a. Char -> Doc a
char Char
'='
lparen :: Doc Aspects
lparen = Doc Aspects -> Doc Aspects
hlSymbol forall a b. (a -> b) -> a -> b
$ forall a. Char -> Doc a
char Char
'('
rparen :: Doc Aspects
rparen = Doc Aspects -> Doc Aspects
hlSymbol forall a b. (a -> b) -> a -> b
$ forall a. Char -> Doc a
char Char
')'
lbrack :: Doc Aspects
lbrack = Doc Aspects -> Doc Aspects
hlSymbol forall a b. (a -> b) -> a -> b
$ forall a. Char -> Doc a
char Char
'['
rbrack :: Doc Aspects
rbrack = Doc Aspects -> Doc Aspects
hlSymbol forall a b. (a -> b) -> a -> b
$ forall a. Char -> Doc a
char Char
']'
lbrace :: Doc Aspects
lbrace = Doc Aspects -> Doc Aspects
hlSymbol forall a b. (a -> b) -> a -> b
$ forall a. Char -> Doc a
char Char
'{'
rbrace :: Doc Aspects
rbrace = Doc Aspects -> Doc Aspects
hlSymbol forall a b. (a -> b) -> a -> b
$ forall a. Char -> Doc a
char Char
'}'