module Z.IO.StdStream.Ansi
(
bold, italicize, underline,
color, color', palette, palette', rgb, rgb',
cursorUp, cursorDown, cursorForward, cursorBackward,
cursorDownLine, cursorUpLine ,
setCursorColumn, setCursorPosition, saveCursor, restoreCursor,
clearFromCursorToScreenEnd, clearFromCursorToScreenBeginning, clearScreen,
clearFromCursorToLineEnd, clearFromCursorToLineBeginning, clearLine,
scrollPageUp, scrollPageDown,
hideCursor, showCursor,
setTitle,
reset,
boldIntensity, faintIntensity, resetIntensity,
italicized, noItalicized,
singleUnderline, doubleUnderline, noUnderline,
slowBlink, rapidBlink, blinkOff,
conceal, reveal,
invert, invertOff,
setForeground, setBrightForeground, setBackground, setBrightBackground,
setPaletteForeground, setPaletteBackground,
setRGBForeground, setRGBBackground,
setDefaultForeground, setDefaultBackground,
AnsiColor(..), PaletteColor, RGBColor,
csi, sgr, colorToCode
) where
import qualified Z.Data.Builder as B
import qualified Z.Data.Text as T
import qualified Z.Data.Text.ShowT as T
import Data.Word
import GHC.Generics
csi :: [Int]
-> B.Builder ()
-> B.Builder ()
csi args code = do
B.char8 '\ESC'
B.char8 '['
B.intercalateList (B.char8 ';') B.int args
code
cursorUp, cursorDown, cursorForward, cursorBackward
:: Int
-> B.Builder ()
cursorDownLine, cursorUpLine :: Int
-> B.Builder ()
cursorUp n = csi [n] (B.char8 'A')
cursorDown n = csi [n] (B.char8 'B')
cursorForward n = csi [n] (B.char8 'C')
cursorBackward n = csi [n] (B.char8 'D')
cursorDownLine n = csi [n] (B.char8 'E')
cursorUpLine n = csi [n] (B.char8 'F')
setCursorColumn :: Int
-> B.Builder ()
setCursorColumn n = csi [n] (B.char8 'G')
setCursorPosition :: Int
-> Int
-> B.Builder ()
setCursorPosition n m = csi [n, m] (B.char8 'G')
saveCursor, restoreCursor :: B.Builder ()
saveCursor = B.char8 '\ESC' >> B.char8 '7'
restoreCursor = B.char8 '\ESC' >> B.char8 '8'
clearFromCursorToScreenEnd, clearFromCursorToScreenBeginning, clearScreen :: B.Builder ()
clearFromCursorToLineEnd, clearFromCursorToLineBeginning, clearLine :: B.Builder ()
clearFromCursorToScreenEnd = csi [0] (B.char8 'J')
clearFromCursorToScreenBeginning = csi [1] (B.char8 'J')
clearScreen = csi [2] (B.char8 'J')
clearFromCursorToLineEnd = csi [0] (B.char8 'K')
clearFromCursorToLineBeginning = csi [1] (B.char8 'K')
clearLine = csi [2] (B.char8 'K')
scrollPageUp, scrollPageDown :: Int
-> B.Builder()
scrollPageUp n = csi [n] (B.char8 'S')
scrollPageDown n = csi [n] (B.char8 'T')
hideCursor, showCursor :: B.Builder ()
hideCursor = csi [] "?25l"
showCursor = csi [] "?25h"
setTitle :: T.Text
-> B.Builder ()
setTitle title = do
"\ESC]0;"
B.text (T.filter (/= '\007') title)
B.char8 '\007'
sgr :: [Word8]
-> B.Builder ()
sgr args = do
B.char8 '\ESC'
B.char8 '['
B.intercalateList (B.char8 ';') B.int args
B.char8 'm'
reset :: B.Builder ()
reset = sgr [0]
boldIntensity, faintIntensity, resetIntensity :: B.Builder ()
boldIntensity = sgr [1]
faintIntensity = sgr [2]
resetIntensity = sgr [22]
bold :: B.Builder () -> B.Builder ()
bold t = boldIntensity >> t >> resetIntensity
italicized, noItalicized :: B.Builder ()
italicized = sgr [3]
noItalicized = sgr [23]
italicize :: B.Builder () -> B.Builder ()
italicize t = italicized >> t >> noItalicized
singleUnderline, doubleUnderline, noUnderline :: B.Builder ()
singleUnderline = sgr [4]
doubleUnderline = sgr [21]
noUnderline = sgr [24]
underline :: B.Builder () -> B.Builder ()
underline t = singleUnderline >> t >> singleUnderline
slowBlink, rapidBlink, blinkOff :: B.Builder ()
slowBlink = sgr [5]
rapidBlink = sgr [6]
blinkOff = sgr [25]
conceal, reveal :: B.Builder ()
conceal = sgr [8]
reveal = sgr [28]
invert, invertOff :: B.Builder ()
invert = sgr [7]
invertOff = sgr [27]
color :: AnsiColor -> B.Builder () -> B.Builder ()
color c t = do
setForeground c
t
setDefaultForeground
color' :: AnsiColor -> AnsiColor -> B.Builder () -> B.Builder ()
color' c1 c2 t = do
setForeground c1
setBackground c2
t
setDefaultForeground
setDefaultBackground
palette :: PaletteColor -> B.Builder () -> B.Builder ()
palette c t = do
setPaletteForeground c
t
setDefaultForeground
palette' :: PaletteColor -> PaletteColor -> B.Builder () -> B.Builder ()
palette' c1 c2 t = do
setPaletteForeground c1
setPaletteBackground c2
t
setDefaultForeground
setDefaultBackground
rgb :: RGBColor -> B.Builder () -> B.Builder ()
rgb c t = do
setRGBForeground c
t
setDefaultForeground
rgb' :: RGBColor -> RGBColor -> B.Builder () -> B.Builder ()
rgb' c1 c2 t = do
setRGBForeground c1
setRGBBackground c2
t
setDefaultForeground
setDefaultBackground
setForeground, setBrightForeground, setBackground, setBrightBackground :: AnsiColor -> B.Builder ()
setForeground c = sgr [30 + colorToCode c]
setBrightForeground c = sgr [90 + colorToCode c]
setBackground c = sgr [40 + colorToCode c]
setBrightBackground c = sgr [100 + colorToCode c]
setPaletteForeground, setPaletteBackground :: PaletteColor -> B.Builder ()
setPaletteForeground index = sgr [38, 5, index]
setPaletteBackground index = sgr [48, 5, index]
setRGBForeground, setRGBBackground :: RGBColor -> B.Builder ()
setRGBForeground (r,g,b) = sgr [38, 2, r, g, b]
setRGBBackground (r,g,b) = sgr [48, 2, r, g, b]
setDefaultForeground, setDefaultBackground :: B.Builder ()
setDefaultForeground = sgr [39]
setDefaultBackground = sgr [49]
data AnsiColor = Black
| Red
| Green
| Yellow
| Blue
| Magenta
| Cyan
| White
deriving (Eq, Ord, Bounded, Enum, Show, Read, Generic)
deriving anyclass T.ShowT
colorToCode :: AnsiColor -> Word8
colorToCode c = case c of
Black -> 0
Red -> 1
Green -> 2
Yellow -> 3
Blue -> 4
Magenta -> 5
Cyan -> 6
White -> 7
type PaletteColor = Word8
type RGBColor = (Word8, Word8, Word8)