module Dhall.LSP.Backend.Formatting (formatExpr, formatExprWithHeader) where

import Data.Maybe   (fromMaybe)
import Data.Text    (Text)
import Dhall.Core   (Expr)
import Dhall.Parser (Header (..))
import Dhall.Pretty (CharacterSet (..))
import Dhall.Src    (Src)

import qualified Dhall.Pretty
import qualified Prettyprinter             as Pretty
import qualified Prettyprinter.Render.Text as Pretty

-- | Pretty-print the given Dhall expression.
formatExpr :: Pretty.Pretty b => Maybe CharacterSet -> Expr Src b -> Text
formatExpr :: Maybe CharacterSet -> Expr Src b -> Text
formatExpr Maybe CharacterSet
chosenCharacterSet Expr Src b
expr =
      SimpleDocStream Ann -> Text
forall ann. SimpleDocStream ann -> Text
Pretty.renderStrict
    (SimpleDocStream Ann -> Text)
-> (Doc Ann -> SimpleDocStream Ann) -> Doc Ann -> Text
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Doc Ann -> SimpleDocStream Ann
forall ann. Doc ann -> SimpleDocStream ann
Dhall.Pretty.layout
    (Doc Ann -> Text) -> Doc Ann -> Text
forall a b. (a -> b) -> a -> b
$ CharacterSet -> Expr Src b -> Doc Ann
forall a. Pretty a => CharacterSet -> Expr Src a -> Doc Ann
Dhall.Pretty.prettyCharacterSet CharacterSet
charSet Expr Src b
expr
  where
    charSet :: CharacterSet
charSet = CharacterSet -> Maybe CharacterSet -> CharacterSet
forall a. a -> Maybe a -> a
fromMaybe (Expr Src b -> CharacterSet
forall a. Expr Src a -> CharacterSet
Dhall.Pretty.detectCharacterSet Expr Src b
expr) Maybe CharacterSet
chosenCharacterSet

-- | Pretty-print the given Dhall expression, prepending the given a "header"
--   (usually consisting of comments and whitespace).
formatExprWithHeader :: Pretty.Pretty b => Maybe CharacterSet -> Expr Src b -> Header -> Text
formatExprWithHeader :: Maybe CharacterSet -> Expr Src b -> Header -> Text
formatExprWithHeader Maybe CharacterSet
chosenCharacterSet Expr Src b
expr (Header Text
header) = SimpleDocStream Ann -> Text
forall ann. SimpleDocStream ann -> Text
Pretty.renderStrict
  (Doc Ann -> SimpleDocStream Ann
forall ann. Doc ann -> SimpleDocStream ann
Dhall.Pretty.layout Doc Ann
doc)
  where
    charSet :: CharacterSet
charSet = CharacterSet -> Maybe CharacterSet -> CharacterSet
forall a. a -> Maybe a -> a
fromMaybe (Expr Src b -> CharacterSet
forall a. Expr Src a -> CharacterSet
Dhall.Pretty.detectCharacterSet Expr Src b
expr) Maybe CharacterSet
chosenCharacterSet

    doc :: Doc Ann
doc =
      Text -> Doc Ann
forall a ann. Pretty a => a -> Doc ann
Pretty.pretty Text
header
        Doc Ann -> Doc Ann -> Doc Ann
forall a. Semigroup a => a -> a -> a
<> CharacterSet -> Expr Src b -> Doc Ann
forall a. Pretty a => CharacterSet -> Expr Src a -> Doc Ann
Dhall.Pretty.prettyCharacterSet CharacterSet
charSet Expr Src b
expr
        Doc Ann -> Doc Ann -> Doc Ann
forall a. Semigroup a => a -> a -> a
<> Doc Ann
"\n"