ddc-war-0.2.1.1: DDC/War/Interface/VT100.hs
{-# OPTIONS -fno-warn-missing-signatures #-}
-- | Generation of VT100 terminal control codes.
module DDC.War.Interface.VT100
( Color(..), codeOfColor
, Mode (..), codeOfMode
, ModeState (..), modeStateInit, applyMode
, eraseDisplay
, eraseLine
, setCursorPos
, moveCursorUp
, moveCursorDown
, moveCursorLeft
, moveCursorRight
, saveCursorPosition
, restoreCursorPosition
, setMode )
where
import Data.List
-- Color ----------------------------------------------------------------------
-- | VT100 / ANSI colors
data Color
= Black
| Red
| Green
| Yellow
| Blue
| Magenta
| Cyan
| White
deriving (Show, Eq, Ord)
-- | Control code offset for rendering colors.
-- Need to add 30 for foreground, 40 for background to get real code.
codeOfColor :: Color -> Int
codeOfColor color
= case color of
Black -> 0
Red -> 1
Green -> 2
Yellow -> 3
Blue -> 4
Magenta -> 5
Cyan -> 6
White -> 7
-- Mode -----------------------------------------------------------------------
-- | Rendering mode commands.
data Mode
= Reset
| Bold
| Dim
| Underscore
| Blink
| Reverse
| Concealed
| Foreground Color
| Background Color
deriving (Show, Eq, Ord)
-- | Control codes for rendering mode commands.
codeOfMode :: Mode -> Int
codeOfMode mode
= case mode of
Reset -> 0
Bold -> 1
Dim -> 3
Underscore -> 4
Blink -> 5
Reverse -> 7
Concealed -> 8
Foreground color -> 30 + codeOfColor color
Background color -> 40 + codeOfColor color
-- ModeState ------------------------------------------------------------------
-- Model of VT100 terminal state, to help keep track what state
-- the terminal is in after accepting a string of commands.
data ModeState
= ModeState
{ sBold :: Bool
, sDim :: Bool
, sUnderscore :: Bool
, sBlink :: Bool
, sReverse :: Bool
, sConcealed :: Bool
, sForeground :: Color
, sBackground :: Color }
deriving (Show, Eq)
modeStateInit
= ModeState
{ sBold = False
, sDim = False
, sUnderscore = False
, sBlink = False
, sReverse = False
, sConcealed = False
, sForeground = White
, sBackground = Black }
applyMode :: ModeState -> Mode -> ModeState
applyMode state m
= case m of
Reset -> modeStateInit
Bold -> state { sBold = True }
Dim -> state { sDim = True }
Underscore -> state { sUnderscore = True }
Blink -> state { sBlink = True }
Reverse -> state { sReverse = True }
Concealed -> state { sConcealed = True }
Foreground c -> state { sForeground = c }
Background c -> state { sBackground = c }
-- Commands -------------------------------------------------------------------
-- | Erase entire display.
eraseDisplay = "\27[2J"
-- | Erase current line of display.
eraseLine = "\27[K"
-- | Set the position of the cursor.
setCursorPos x y = "\27[" ++ show y ++ ";" ++ show x ++ "H"
-- | Move cursor up some number of lines.
moveCursorUp n = "\27[" ++ show n ++ "A"
-- | Move cursor down some number of lines.
moveCursorDown n = "\27[" ++ show n ++ "B"
-- | Move cursor right / forward some number of columns.
moveCursorRight n = "\27[" ++ show n ++ "C"
-- | Move cursor left / backward some number of columns.
moveCursorLeft n = "\27[" ++ show n ++ "D"
-- | Save cursor position
saveCursorPosition = "\27[s"
-- | Restore cursor position
restoreCursorPosition = "\27[u"
-- | Set graphics mode
setMode modes
= "\27["
++ concat
(intersperse ";"
$ map (show . codeOfMode) modes)
++ "m"