import Control.Applicative (Applicative(..))
import Data.Bool
import Data.Function (($), (.), id)
-import Data.Int (Int)
import Data.Monoid (Monoid(..))
import Data.Ord (Ord(..))
import Data.Semigroup (Semigroup(..))
import Data.String (IsString(..))
import GHC.Exts (IsList(..))
-import Prelude ((+), pred)
+import Prelude (pred, fromIntegral, Num(..))
import System.Console.ANSI
import System.IO (IO)
import Text.Show (Show(..))
import qualified Data.List as List
-import qualified Data.Text as Text
import qualified Data.Text.IO as Text
-import qualified Data.Text.Lazy as TL
import qualified Data.Text.Lazy.IO as TL
import qualified System.IO as IO
-- * Type 'Reader'
data Reader
= Reader
- { reader_indent :: !(Indent TermIO) -- ^ Current indentation level, used by 'newline'.
- , reader_newline :: TermIO -- ^ How to display 'newline'.
- , reader_wrap_column :: !(Column TermIO) -- ^ 'Column' after which 'wrap' breaks on a 'breakpoint' or 'breakspace'.
- , reader_sgr :: ![SGR] -- ^ Active ANSI codes.
- , reader_handle :: !IO.Handle -- ^ Where to write.
- , reader_colorable :: !Bool -- ^ Whether colors are activated or not.
- , reader_decorable :: !Bool -- ^ Whether decorations are activated or not.
+ { reader_indent :: !Indent -- ^ Current indentation level, used by 'newline'.
+ , reader_newline :: TermIO -- ^ How to display 'newline'.
+ , reader_wrap_column :: !Column -- ^ 'Column' after which 'wrap' breaks on a 'breakpoint' or 'breakspace'.
+ , reader_sgr :: ![SGR] -- ^ Active ANSI codes.
+ , reader_handle :: !IO.Handle -- ^ Where to write.
+ , reader_colorable :: !Bool -- ^ Whether colors are activated or not.
+ , reader_decorable :: !Bool -- ^ Whether decorations are activated or not.
}
-- | Default 'Reader'.
defReader = Reader
{ reader_indent = 0
, reader_newline = newlineWithIndent
- , reader_wrap_column = 80
+ , reader_wrap_column = Nat 80
, reader_sgr = []
, reader_handle = IO.stdout
, reader_colorable = True
}
-- * Type 'State'
-type State = Column TermIO
+type State = Column
-- | Default 'State'.
defState :: State
(State -> IO () -> IO ()) -> -- should-wrap continuation
IO () }
-type instance Column TermIO = Int
-type instance Indent TermIO = Int
-
-- | Write a 'TermIO'.
runTermIO :: IO.Handle -> TermIO -> IO ()
runTermIO h (TermIO p) = p defReader{reader_handle=h} defState oko oko
instance IsString TermIO where
fromString = string
-writeH :: Column TermIO -> (IO.Handle -> IO ()) -> TermIO
+writeH :: Column -> (IO.Handle -> IO ()) -> TermIO
writeH len t =
TermIO $ \ro st ok ko ->
let newCol = st + len in
instance Textable TermIO where
empty = TermIO $ \_ro st ok _ko -> ok st mempty
charH t = writeH 1 (`IO.hPutChar` t)
- stringH t = writeH (List.length t) (`IO.hPutStr` t)
- textH t = writeH (Text.length t) (`Text.hPutStr` t)
- ltextH t = writeH (intOfInt64 $ TL.length t) (`TL.hPutStr` t)
+ stringH t = writeH (length t) (`IO.hPutStr` t)
+ textH t = writeH (length t) (`Text.hPutStr` t)
+ ltextH t = writeH (length t) (`TL.hPutStr` t)
int = stringH . show
integer = stringH . show
replicate cnt p | cnt <= 0 = empty
newlineWithIndent = TermIO $ \ro@Reader{reader_handle=h} _st ok _ko ->
ok (reader_indent ro) $ do
IO.hPutChar h '\n'
- IO.hPutStr h $ List.replicate (reader_indent ro) ' '
+ IO.hPutStr h $ List.replicate (fromIntegral $ reader_indent ro) ' '
instance Wrapable TermIO where
ifWrap y x = TermIO $ \ro st ok ko ->
unTermIO x ro st ok (\_sx _tx -> unTermIO y ro st ok ko)