{-# OPTIONS_GHC -fno-warn-orphans #-}
module Futhark.Util.Pretty
(
prettyTuple,
prettyTupleLines,
prettyString,
prettyStringOneLine,
prettyText,
prettyTextOneLine,
docText,
docTextForHandle,
docString,
putDoc,
hPutDoc,
putDocLn,
hPutDocLn,
module Prettyprinter,
module Prettyprinter.Symbols.Ascii,
module Prettyprinter.Render.Terminal,
apply,
oneLine,
annot,
nestedBlock,
textwrap,
shorten,
commastack,
commasep,
semistack,
stack,
parensIf,
ppTuple',
ppTupleLines',
(</>),
)
where
import Data.Text (Text)
import Data.Text qualified as T
import Numeric.Half
import Prettyprinter
import Prettyprinter.Render.Terminal (AnsiStyle, Color (..), bgColor, bgColorDull, bold, color, colorDull, italicized, underlined)
import Prettyprinter.Render.Terminal qualified
import Prettyprinter.Render.Text qualified
import Prettyprinter.Symbols.Ascii
import System.IO (Handle, hIsTerminalDevice, hPutStrLn, stdout)
hPutDoc :: Handle -> Doc AnsiStyle -> IO ()
hPutDoc :: Handle -> Doc AnsiStyle -> IO ()
hPutDoc Handle
h Doc AnsiStyle
d = do
colours <- Handle -> IO Bool
hIsTerminalDevice Handle
h
if colours
then Prettyprinter.Render.Terminal.renderIO h (layouter d)
else Prettyprinter.Render.Text.renderIO h (layouter d)
where
layouter :: Doc ann -> SimpleDocStream ann
layouter =
SimpleDocStream ann -> SimpleDocStream ann
forall ann. SimpleDocStream ann -> SimpleDocStream ann
removeTrailingWhitespace
(SimpleDocStream ann -> SimpleDocStream ann)
-> (Doc ann -> SimpleDocStream ann)
-> Doc ann
-> SimpleDocStream ann
forall b c a. (b -> c) -> (a -> b) -> a -> c
. LayoutOptions -> Doc ann -> SimpleDocStream ann
forall ann. LayoutOptions -> Doc ann -> SimpleDocStream ann
layoutSmart LayoutOptions
defaultLayoutOptions {layoutPageWidth = Unbounded}
hPutDocLn :: Handle -> Doc AnsiStyle -> IO ()
hPutDocLn :: Handle -> Doc AnsiStyle -> IO ()
hPutDocLn Handle
h Doc AnsiStyle
d = do
Handle -> Doc AnsiStyle -> IO ()
hPutDoc Handle
h Doc AnsiStyle
d
Handle -> String -> IO ()
hPutStrLn Handle
h String
""
putDoc :: Doc AnsiStyle -> IO ()
putDoc :: Doc AnsiStyle -> IO ()
putDoc = Handle -> Doc AnsiStyle -> IO ()
hPutDoc Handle
stdout
putDocLn :: Doc AnsiStyle -> IO ()
putDocLn :: Doc AnsiStyle -> IO ()
putDocLn Doc AnsiStyle
d = do
Doc AnsiStyle -> IO ()
putDoc Doc AnsiStyle
d
String -> IO ()
putStrLn String
""
docTextForHandle :: Handle -> Doc AnsiStyle -> IO T.Text
docTextForHandle :: Handle -> Doc AnsiStyle -> IO Text
docTextForHandle Handle
h Doc AnsiStyle
d = do
colours <- Handle -> IO Bool
hIsTerminalDevice Handle
h
let sds = SimpleDocStream AnsiStyle -> SimpleDocStream AnsiStyle
forall ann. SimpleDocStream ann -> SimpleDocStream ann
removeTrailingWhitespace (SimpleDocStream AnsiStyle -> SimpleDocStream AnsiStyle)
-> SimpleDocStream AnsiStyle -> SimpleDocStream AnsiStyle
forall a b. (a -> b) -> a -> b
$ LayoutOptions -> Doc AnsiStyle -> SimpleDocStream AnsiStyle
forall ann. LayoutOptions -> Doc ann -> SimpleDocStream ann
layoutSmart LayoutOptions
defaultLayoutOptions Doc AnsiStyle
d
pure $
if colours
then Prettyprinter.Render.Terminal.renderStrict sds
else Prettyprinter.Render.Text.renderStrict sds
prettyString :: (Pretty a) => a -> String
prettyString :: forall a. Pretty a => a -> String
prettyString = Text -> String
T.unpack (Text -> String) -> (a -> Text) -> a -> String
forall b c a. (b -> c) -> (a -> b) -> a -> c
. a -> Text
forall a. Pretty a => a -> Text
prettyText
prettyStringOneLine :: (Pretty a) => a -> String
prettyStringOneLine :: forall a. Pretty a => a -> String
prettyStringOneLine = Text -> String
T.unpack (Text -> String) -> (a -> Text) -> a -> String
forall b c a. (b -> c) -> (a -> b) -> a -> c
. a -> Text
forall a. Pretty a => a -> Text
prettyTextOneLine
prettyText :: (Pretty a) => a -> Text
prettyText :: forall a. Pretty a => a -> Text
prettyText = Doc (ZonkAny 4) -> Text
forall a. Doc a -> Text
docText (Doc (ZonkAny 4) -> Text) -> (a -> Doc (ZonkAny 4)) -> a -> Text
forall b c a. (b -> c) -> (a -> b) -> a -> c
. a -> Doc (ZonkAny 4)
forall ann. a -> Doc ann
forall a ann. Pretty a => a -> Doc ann
pretty
docText :: Doc a -> T.Text
docText :: forall a. Doc a -> Text
docText = SimpleDocStream a -> Text
forall ann. SimpleDocStream ann -> Text
Prettyprinter.Render.Text.renderStrict (SimpleDocStream a -> Text)
-> (Doc a -> SimpleDocStream a) -> Doc a -> Text
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Doc a -> SimpleDocStream a
forall {ann}. Doc ann -> SimpleDocStream ann
layouter
where
layouter :: Doc ann -> SimpleDocStream ann
layouter =
SimpleDocStream ann -> SimpleDocStream ann
forall ann. SimpleDocStream ann -> SimpleDocStream ann
removeTrailingWhitespace
(SimpleDocStream ann -> SimpleDocStream ann)
-> (Doc ann -> SimpleDocStream ann)
-> Doc ann
-> SimpleDocStream ann
forall b c a. (b -> c) -> (a -> b) -> a -> c
. LayoutOptions -> Doc ann -> SimpleDocStream ann
forall ann. LayoutOptions -> Doc ann -> SimpleDocStream ann
layoutSmart LayoutOptions
defaultLayoutOptions {layoutPageWidth = Unbounded}
docString :: Doc a -> String
docString :: forall a. Doc a -> String
docString = Text -> String
T.unpack (Text -> String) -> (Doc a -> Text) -> Doc a -> String
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Doc a -> Text
forall a. Doc a -> Text
docText
prettyTextOneLine :: (Pretty a) => a -> Text
prettyTextOneLine :: forall a. Pretty a => a -> Text
prettyTextOneLine = SimpleDocStream (ZonkAny 1) -> Text
forall ann. SimpleDocStream ann -> Text
Prettyprinter.Render.Text.renderStrict (SimpleDocStream (ZonkAny 1) -> Text)
-> (a -> SimpleDocStream (ZonkAny 1)) -> a -> Text
forall b c a. (b -> c) -> (a -> b) -> a -> c
. LayoutOptions -> Doc (ZonkAny 1) -> SimpleDocStream (ZonkAny 1)
forall ann. LayoutOptions -> Doc ann -> SimpleDocStream ann
layoutSmart LayoutOptions
oneLineLayout (Doc (ZonkAny 1) -> SimpleDocStream (ZonkAny 1))
-> (a -> Doc (ZonkAny 1)) -> a -> SimpleDocStream (ZonkAny 1)
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Doc (ZonkAny 1) -> Doc (ZonkAny 1)
forall ann. Doc ann -> Doc ann
group (Doc (ZonkAny 1) -> Doc (ZonkAny 1))
-> (a -> Doc (ZonkAny 1)) -> a -> Doc (ZonkAny 1)
forall b c a. (b -> c) -> (a -> b) -> a -> c
. a -> Doc (ZonkAny 1)
forall ann. a -> Doc ann
forall a ann. Pretty a => a -> Doc ann
pretty
where
oneLineLayout :: LayoutOptions
oneLineLayout = LayoutOptions
defaultLayoutOptions {layoutPageWidth = Unbounded}
ppTuple' :: [Doc a] -> Doc a
ppTuple' :: forall a. [Doc a] -> Doc a
ppTuple' [Doc a]
ets = Doc a -> Doc a
forall ann. Doc ann -> Doc ann
braces (Doc a -> Doc a) -> Doc a -> Doc a
forall a b. (a -> b) -> a -> b
$ [Doc a] -> Doc a
forall a. [Doc a] -> Doc a
commasep ([Doc a] -> Doc a) -> [Doc a] -> Doc a
forall a b. (a -> b) -> a -> b
$ (Doc a -> Doc a) -> [Doc a] -> [Doc a]
forall a b. (a -> b) -> [a] -> [b]
map Doc a -> Doc a
forall ann. Doc ann -> Doc ann
align [Doc a]
ets
ppTupleLines' :: [Doc a] -> Doc a
ppTupleLines' :: forall a. [Doc a] -> Doc a
ppTupleLines' [Doc a]
ets = Doc a -> Doc a
forall ann. Doc ann -> Doc ann
braces (Doc a -> Doc a) -> Doc a -> Doc a
forall a b. (a -> b) -> a -> b
$ [Doc a] -> Doc a
forall a. [Doc a] -> Doc a
commastack ([Doc a] -> Doc a) -> [Doc a] -> Doc a
forall a b. (a -> b) -> a -> b
$ (Doc a -> Doc a) -> [Doc a] -> [Doc a]
forall a b. (a -> b) -> [a] -> [b]
map Doc a -> Doc a
forall ann. Doc ann -> Doc ann
align [Doc a]
ets
prettyTuple :: (Pretty a) => [a] -> Text
prettyTuple :: forall a. Pretty a => [a] -> Text
prettyTuple = Doc (ZonkAny 2) -> Text
forall a. Doc a -> Text
docText (Doc (ZonkAny 2) -> Text)
-> ([a] -> Doc (ZonkAny 2)) -> [a] -> Text
forall b c a. (b -> c) -> (a -> b) -> a -> c
. [Doc (ZonkAny 2)] -> Doc (ZonkAny 2)
forall a. [Doc a] -> Doc a
ppTuple' ([Doc (ZonkAny 2)] -> Doc (ZonkAny 2))
-> ([a] -> [Doc (ZonkAny 2)]) -> [a] -> Doc (ZonkAny 2)
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (a -> Doc (ZonkAny 2)) -> [a] -> [Doc (ZonkAny 2)]
forall a b. (a -> b) -> [a] -> [b]
map a -> Doc (ZonkAny 2)
forall ann. a -> Doc ann
forall a ann. Pretty a => a -> Doc ann
pretty
prettyTupleLines :: (Pretty a) => [a] -> Text
prettyTupleLines :: forall a. Pretty a => [a] -> Text
prettyTupleLines = Doc (ZonkAny 3) -> Text
forall a. Doc a -> Text
docText (Doc (ZonkAny 3) -> Text)
-> ([a] -> Doc (ZonkAny 3)) -> [a] -> Text
forall b c a. (b -> c) -> (a -> b) -> a -> c
. [Doc (ZonkAny 3)] -> Doc (ZonkAny 3)
forall a. [Doc a] -> Doc a
ppTupleLines' ([Doc (ZonkAny 3)] -> Doc (ZonkAny 3))
-> ([a] -> [Doc (ZonkAny 3)]) -> [a] -> Doc (ZonkAny 3)
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (a -> Doc (ZonkAny 3)) -> [a] -> [Doc (ZonkAny 3)]
forall a b. (a -> b) -> [a] -> [b]
map a -> Doc (ZonkAny 3)
forall ann. a -> Doc ann
forall a ann. Pretty a => a -> Doc ann
pretty
apply :: [Doc a] -> Doc a
apply :: forall a. [Doc a] -> Doc a
apply = Doc a -> Doc a
forall ann. Doc ann -> Doc ann
parens (Doc a -> Doc a) -> ([Doc a] -> Doc a) -> [Doc a] -> Doc a
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Doc a -> Doc a
forall ann. Doc ann -> Doc ann
align (Doc a -> Doc a) -> ([Doc a] -> Doc a) -> [Doc a] -> Doc a
forall b c a. (b -> c) -> (a -> b) -> a -> c
. [Doc a] -> Doc a
forall a. [Doc a] -> Doc a
commasep ([Doc a] -> Doc a) -> ([Doc a] -> [Doc a]) -> [Doc a] -> Doc a
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (Doc a -> Doc a) -> [Doc a] -> [Doc a]
forall a b. (a -> b) -> [a] -> [b]
map Doc a -> Doc a
forall ann. Doc ann -> Doc ann
align
oneLine :: Doc a -> Doc a
oneLine :: forall ann. Doc ann -> Doc ann
oneLine = Doc a -> Doc a
forall ann. Doc ann -> Doc ann
group
textwrap :: T.Text -> Doc a
textwrap :: forall a. Text -> Doc a
textwrap = [Doc a] -> Doc a
forall a. [Doc a] -> Doc a
fillSep ([Doc a] -> Doc a) -> (Text -> [Doc a]) -> Text -> Doc a
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (Text -> Doc a) -> [Text] -> [Doc a]
forall a b. (a -> b) -> [a] -> [b]
map Text -> Doc a
forall a. Text -> Doc a
forall a ann. Pretty a => a -> Doc ann
pretty ([Text] -> [Doc a]) -> (Text -> [Text]) -> Text -> [Doc a]
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Text -> [Text]
T.words
annot :: [Doc a] -> Doc a -> Doc a
annot :: forall a. [Doc a] -> Doc a -> Doc a
annot [] Doc a
s = Doc a
s
annot [Doc a]
l Doc a
s = [Doc a] -> Doc a
forall a. [Doc a] -> Doc a
vsep ([Doc a]
l [Doc a] -> [Doc a] -> [Doc a]
forall a. [a] -> [a] -> [a]
++ [Doc a
s])
nestedBlock :: Doc a -> Doc a -> Doc a -> Doc a
nestedBlock :: forall a. Doc a -> Doc a -> Doc a -> Doc a
nestedBlock Doc a
pre Doc a
post Doc a
body = [Doc a] -> Doc a
forall a. [Doc a] -> Doc a
vsep [Doc a
pre, Int -> Doc a -> Doc a
forall ann. Int -> Doc ann -> Doc ann
indent Int
2 Doc a
body, Doc a
post]
shorten :: Doc a -> Doc b
shorten :: forall a b. Doc a -> Doc b
shorten Doc a
a
| Text -> Int
T.length Text
s Int -> Int -> Bool
forall a. Ord a => a -> a -> Bool
> Int
70 = Text -> Doc b
forall a. Text -> Doc a
forall a ann. Pretty a => a -> Doc ann
pretty (Int -> Text -> Text
T.take Int
70 Text
s) Doc b -> Doc b -> Doc b
forall a. Semigroup a => a -> a -> a
<> Doc b
"..."
| Bool
otherwise = Text -> Doc b
forall a. Text -> Doc a
forall a ann. Pretty a => a -> Doc ann
pretty Text
s
where
s :: Text
s = SimpleDocStream (ZonkAny 0) -> Text
forall ann. SimpleDocStream ann -> Text
Prettyprinter.Render.Text.renderStrict (SimpleDocStream (ZonkAny 0) -> Text)
-> SimpleDocStream (ZonkAny 0) -> Text
forall a b. (a -> b) -> a -> b
$ Doc a -> SimpleDocStream (ZonkAny 0)
forall ann1 ann2. Doc ann1 -> SimpleDocStream ann2
layoutCompact Doc a
a
commastack :: [Doc a] -> Doc a
commastack :: forall a. [Doc a] -> Doc a
commastack = Doc a -> Doc a
forall ann. Doc ann -> Doc ann
align (Doc a -> Doc a) -> ([Doc a] -> Doc a) -> [Doc a] -> Doc a
forall b c a. (b -> c) -> (a -> b) -> a -> c
. [Doc a] -> Doc a
forall a. [Doc a] -> Doc a
vsep ([Doc a] -> Doc a) -> ([Doc a] -> [Doc a]) -> [Doc a] -> Doc a
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Doc a -> [Doc a] -> [Doc a]
forall ann. Doc ann -> [Doc ann] -> [Doc ann]
punctuate Doc a
forall ann. Doc ann
comma
semistack :: [Doc a] -> Doc a
semistack :: forall a. [Doc a] -> Doc a
semistack = Doc a -> Doc a
forall ann. Doc ann -> Doc ann
align (Doc a -> Doc a) -> ([Doc a] -> Doc a) -> [Doc a] -> Doc a
forall b c a. (b -> c) -> (a -> b) -> a -> c
. [Doc a] -> Doc a
forall a. [Doc a] -> Doc a
vsep ([Doc a] -> Doc a) -> ([Doc a] -> [Doc a]) -> [Doc a] -> Doc a
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Doc a -> [Doc a] -> [Doc a]
forall ann. Doc ann -> [Doc ann] -> [Doc ann]
punctuate Doc a
forall ann. Doc ann
semi
commasep :: [Doc a] -> Doc a
commasep :: forall a. [Doc a] -> Doc a
commasep = [Doc a] -> Doc a
forall a. [Doc a] -> Doc a
hsep ([Doc a] -> Doc a) -> ([Doc a] -> [Doc a]) -> [Doc a] -> Doc a
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Doc a -> [Doc a] -> [Doc a]
forall ann. Doc ann -> [Doc ann] -> [Doc ann]
punctuate Doc a
forall ann. Doc ann
comma
stack :: [Doc a] -> Doc a
stack :: forall a. [Doc a] -> Doc a
stack = Doc a -> Doc a
forall ann. Doc ann -> Doc ann
align (Doc a -> Doc a) -> ([Doc a] -> Doc a) -> [Doc a] -> Doc a
forall b c a. (b -> c) -> (a -> b) -> a -> c
. [Doc a] -> Doc a
forall a. Monoid a => [a] -> a
mconcat ([Doc a] -> Doc a) -> ([Doc a] -> [Doc a]) -> [Doc a] -> Doc a
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Doc a -> [Doc a] -> [Doc a]
forall ann. Doc ann -> [Doc ann] -> [Doc ann]
punctuate Doc a
forall ann. Doc ann
line
parensIf :: Bool -> Doc a -> Doc a
parensIf :: forall a. Bool -> Doc a -> Doc a
parensIf Bool
True Doc a
doc = Doc a -> Doc a
forall ann. Doc ann -> Doc ann
parens Doc a
doc
parensIf Bool
False Doc a
doc = Doc a
doc
instance Pretty Half where
pretty :: forall ann. Half -> Doc ann
pretty = Half -> Doc ann
forall a ann. Show a => a -> Doc ann
viaShow
(</>) :: Doc a -> Doc a -> Doc a
Doc a
a </> :: forall a. Doc a -> Doc a -> Doc a
</> Doc a
b = Doc a
a Doc a -> Doc a -> Doc a
forall a. Semigroup a => a -> a -> a
<> Doc a
forall ann. Doc ann
line Doc a -> Doc a -> Doc a
forall a. Semigroup a => a -> a -> a
<> Doc a
b