{-# LANGUAGE DeriveDataTypeable #-}
{-# LANGUAGE DeriveGeneric #-}
{-# LANGUAGE OverloadedStrings #-}
module Dhall.Src
(
Src(..)
) where
import Data.Data (Data)
import Data.Monoid ((<>))
import Data.Text (Text)
import Data.Text.Prettyprint.Doc (Pretty (..))
import GHC.Generics (Generic)
import Text.Megaparsec (SourcePos)
import {-# SOURCE #-} qualified Dhall.Util
import qualified Data.Text as Text
import qualified Text.Megaparsec as Megaparsec
import qualified Text.Printf as Printf
data Src = Src !SourcePos !SourcePos Text
deriving (Data, Eq, Generic, Ord, Show)
instance Pretty Src where
pretty (Src begin _ text) =
pretty (Dhall.Util.snip numberedLines)
<> "\n"
<> pretty (Megaparsec.sourcePosPretty begin)
where
prefix = Text.replicate (n - 1) " "
where
n = Megaparsec.unPos (Megaparsec.sourceColumn begin)
ls = Text.lines (prefix <> text)
numberOfLines = length ls
minimumNumber =
Megaparsec.unPos (Megaparsec.sourceLine begin)
maximumNumber = minimumNumber + numberOfLines - 1
numberWidth :: Int
numberWidth =
truncate (logBase (10 :: Double) (fromIntegral maximumNumber)) + 1
adapt n line = Text.pack outputString
where
inputString = Text.unpack line
outputString =
Printf.printf ("%" <> show numberWidth <> "d: %s") n inputString
numberedLines = Text.unlines (zipWith adapt [minimumNumber..] ls)