Fix output rendering (#280)

This change fixes two issues with output rendering

The first was the following panic in the prettyprinter library when
calling `Data.Text.Prettyprinter.Doc.Render.Terminal.renderIO` on an
expression without any annotations:

```
$ dhall <<< '1' > stdout.dhall
Integer

Peeked an empty style stack! Please report this as a bug.
CallStack (from HasCallStack):
  error, called at src/Data/Text/Prettyprint/Doc/Render/Util/Panic.hs:38:15 in prettyprinter-1.1.1-1CDqnG9d6HQ5GZzz2F5LpU:Data.Text.Prettyprint.Doc.Render.Util.Panic
```

The fix is to use `Data.Text.Prettyprinter.Doc.Render.Text.renderIO`
instead when the expression has no annotations.

The second issue is that the color detection was not correctly
working for `stderr`, meaning that this:

```
$ dhall <<< '1' 2> stderr.dhall
```

... would write escape codes to `stderr.dhall`.  The fix is to
separately check if `stderr` supports color or not when writing
to `stderr`.
This commit is contained in:
Gabriel Gonzalez 2018-02-18 16:34:53 -08:00 committed by GitHub
parent 7ed619e690
commit e24b3d90fa
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
2 changed files with 27 additions and 28 deletions

View File

@ -43,7 +43,8 @@ import qualified Data.Text.IO
import qualified Data.Text.Lazy
import qualified Data.Text.Lazy.IO
import qualified Data.Text.Prettyprint.Doc as Pretty
import qualified Data.Text.Prettyprint.Doc.Render.Terminal as Pretty (renderIO)
import qualified Data.Text.Prettyprint.Doc.Render.Text as Pretty.Text
import qualified Data.Text.Prettyprint.Doc.Render.Terminal as Pretty.Terminal
import qualified Options.Generic
import qualified System.Console.ANSI
import qualified System.IO
@ -84,7 +85,7 @@ main = do
let doc = Pretty.pretty header <> Pretty.pretty expr
System.IO.withFile file System.IO.WriteMode (\handle -> do
Pretty.renderIO handle (Pretty.layoutSmart opts doc)
Pretty.Terminal.renderIO handle (Pretty.layoutSmart opts doc)
Data.Text.IO.hPutStrLn handle "" )
Nothing -> do
System.IO.hSetEncoding System.IO.stdin System.IO.utf8
@ -100,11 +101,11 @@ main = do
if supportsANSI
then
Pretty.renderIO
Pretty.Terminal.renderIO
System.IO.stdout
(fmap annToAnsiStyle (Pretty.layoutSmart opts doc))
else
Pretty.renderIO
Pretty.Text.renderIO
System.IO.stdout
(Pretty.layoutSmart opts (Pretty.unAnnotate doc))
Data.Text.IO.putStrLn "")

View File

@ -24,7 +24,8 @@ import qualified Paths_dhall as Meta
import qualified Control.Exception
import qualified Data.Text.Lazy.IO
import qualified Data.Text.Prettyprint.Doc as Pretty
import qualified Data.Text.Prettyprint.Doc.Render.Terminal as Pretty (renderIO)
import qualified Data.Text.Prettyprint.Doc.Render.Terminal as Pretty.Terminal
import qualified Data.Text.Prettyprint.Doc.Render.Text as Pretty.Text
import qualified Dhall.Core
import qualified Dhall.TypeCheck
import qualified Options.Generic
@ -44,6 +45,9 @@ opts =
Pretty.defaultLayoutOptions
{ Pretty.layoutPageWidth = Pretty.AvailablePerLine 80 1.0 }
unbounded :: Pretty.LayoutOptions
unbounded = Pretty.LayoutOptions { Pretty.layoutPageWidth = Pretty.Unbounded }
main :: IO ()
main = do
options <- Options.Generic.getRecord "Compiler for the Dhall language"
@ -88,7 +92,23 @@ main = do
Left err -> Control.Exception.throwIO err
Right x -> return x
render <- makeRender options header
let render handle e = do
supportsANSI <- System.Console.ANSI.hSupportsANSI handle
let renderIO doc =
if supportsANSI
then Pretty.Terminal.renderIO handle (fmap annToAnsiStyle doc)
else Pretty.Text.renderIO handle (Pretty.unAnnotateS doc)
if unHelpful (pretty options)
then do
let doc = Pretty.pretty header <> prettyExpr e
renderIO (Pretty.layoutSmart opts doc)
else do
let doc = prettyExpr e
renderIO (Pretty.layoutPretty unbounded doc)
Data.Text.Lazy.IO.hPutStrLn handle ""
expr' <- load expr
typeExpr <- case Dhall.TypeCheck.typeOf expr' of
@ -98,25 +118,3 @@ main = do
render System.IO.stderr (normalize typeExpr)
Data.Text.Lazy.IO.hPutStrLn System.IO.stderr mempty
render System.IO.stdout (normalize expr') )
makeRender :: (Pretty.Pretty t, Pretty.Pretty a) => Options -> t -> IO (System.IO.Handle -> Dhall.Core.Expr s a -> IO ())
makeRender options header = do
supportsANSI <- System.Console.ANSI.hSupportsANSI System.IO.stdout
let render h doc =
if supportsANSI
then Pretty.renderIO h (fmap annToAnsiStyle doc)
else Pretty.renderIO h (Pretty.unAnnotateS doc)
return $ \h e -> do
if unHelpful (pretty options)
then do
let doc = Pretty.pretty header <> prettyExpr e
render h (Pretty.layoutSmart opts doc)
else do
render h (Pretty.layoutPretty unbounded (prettyExpr e))
Data.Text.Lazy.IO.hPutStrLn h ""
where
unbounded = Pretty.LayoutOptions { Pretty.layoutPageWidth = Pretty.Unbounded }