{-# 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
Bool
colours <- Handle -> IO Bool
hIsTerminalDevice Handle
h
if Bool
colours
then Handle -> SimpleDocStream AnsiStyle -> IO ()
Prettyprinter.Render.Terminal.renderIO Handle
h (Doc AnsiStyle -> SimpleDocStream AnsiStyle
forall {ann}. Doc ann -> SimpleDocStream ann
layouter Doc AnsiStyle
d)
else Handle -> Doc AnsiStyle -> IO ()
forall ann. Handle -> Doc ann -> IO ()
Prettyprinter.Render.Text.hPutDoc Handle
h Doc AnsiStyle
d
where
layouter :: Doc ann -> SimpleDocStream ann
layouter =
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
Bool
colours <- Handle -> IO Bool
hIsTerminalDevice Handle
h
let sds :: SimpleDocStream AnsiStyle
sds = LayoutOptions -> Doc AnsiStyle -> SimpleDocStream AnsiStyle
forall ann. LayoutOptions -> Doc ann -> SimpleDocStream ann
layoutSmart LayoutOptions
defaultLayoutOptions Doc AnsiStyle
d
Text -> IO Text
forall a. a -> IO a
forall (f :: * -> *) a. Applicative f => a -> f a
pure (Text -> IO Text) -> Text -> IO Text
forall a b. (a -> b) -> a -> b
$
if Bool
colours
then SimpleDocStream AnsiStyle -> Text
Prettyprinter.Render.Terminal.renderStrict SimpleDocStream AnsiStyle
sds
else SimpleDocStream AnsiStyle -> Text
forall ann. SimpleDocStream ann -> Text
Prettyprinter.Render.Text.renderStrict SimpleDocStream AnsiStyle
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 Any -> Text
forall a. Doc a -> Text
docText (Doc Any -> Text) -> (a -> Doc Any) -> a -> Text
forall b c a. (b -> c) -> (a -> b) -> a -> c
. a -> Doc Any
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 =
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 Any -> Text
forall ann. SimpleDocStream ann -> Text
Prettyprinter.Render.Text.renderStrict (SimpleDocStream Any -> Text)
-> (a -> SimpleDocStream Any) -> a -> Text
forall b c a. (b -> c) -> (a -> b) -> a -> c
. LayoutOptions -> Doc Any -> SimpleDocStream Any
forall ann. LayoutOptions -> Doc ann -> SimpleDocStream ann
layoutSmart LayoutOptions
oneLineLayout (Doc Any -> SimpleDocStream Any)
-> (a -> Doc Any) -> a -> SimpleDocStream Any
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Doc Any -> Doc Any
forall ann. Doc ann -> Doc ann
group (Doc Any -> Doc Any) -> (a -> Doc Any) -> a -> Doc Any
forall b c a. (b -> c) -> (a -> b) -> a -> c
. a -> Doc Any
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 Any -> Text
forall a. Doc a -> Text
docText (Doc Any -> Text) -> ([a] -> Doc Any) -> [a] -> Text
forall b c a. (b -> c) -> (a -> b) -> a -> c
. [Doc Any] -> Doc Any
forall a. [Doc a] -> Doc a
ppTuple' ([Doc Any] -> Doc Any) -> ([a] -> [Doc Any]) -> [a] -> Doc Any
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (a -> Doc Any) -> [a] -> [Doc Any]
forall a b. (a -> b) -> [a] -> [b]
map a -> Doc Any
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 Any -> Text
forall a. Doc a -> Text
docText (Doc Any -> Text) -> ([a] -> Doc Any) -> [a] -> Text
forall b c a. (b -> c) -> (a -> b) -> a -> c
. [Doc Any] -> Doc Any
forall a. [Doc a] -> Doc a
ppTupleLines' ([Doc Any] -> Doc Any) -> ([a] -> [Doc Any]) -> [a] -> Doc Any
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (a -> Doc Any) -> [a] -> [Doc Any]
forall a b. (a -> b) -> [a] -> [b]
map a -> Doc Any
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 Any -> Text
forall ann. SimpleDocStream ann -> Text
Prettyprinter.Render.Text.renderStrict (SimpleDocStream Any -> Text) -> SimpleDocStream Any -> Text
forall a b. (a -> b) -> a -> b
$ Doc a -> SimpleDocStream Any
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