{-# LANGUAGE Safe #-}
module System.Console.ANSI.Codes
(
module System.Console.ANSI.Types
, cursorUpCode, cursorDownCode, cursorForwardCode, cursorBackwardCode
, cursorUpLineCode, cursorDownLineCode
, setCursorColumnCode, setCursorPositionCode
, saveCursorCode, restoreCursorCode, reportCursorPositionCode
, clearFromCursorToScreenEndCode, clearFromCursorToScreenBeginningCode
, clearScreenCode, clearFromCursorToLineEndCode
, clearFromCursorToLineBeginningCode, clearLineCode
, scrollPageUpCode, scrollPageDownCode
, useAlternateScreenBufferCode, useNormalScreenBufferCode
, reportLayerColorCode
, setSGRCode
, hideCursorCode, showCursorCode
, hyperlinkCode, hyperlinkWithIdCode, hyperlinkWithParamsCode
, setTitleCode
, colorToCode, csi, osc, sgrToCode
) where
import Data.Char (isPrint)
import Data.List (intercalate)
import Data.Colour.SRGB (toSRGB24, RGB (..))
import System.Console.ANSI.Types
csi ::
[Int]
-> String
-> String
csi :: [Int] -> String -> String
csi [Int]
args String
code = String
"\ESC[" String -> String -> String
forall a. [a] -> [a] -> [a]
++ String -> [String] -> String
forall a. [a] -> [[a]] -> [a]
intercalate String
";" ((Int -> String) -> [Int] -> [String]
forall a b. (a -> b) -> [a] -> [b]
map Int -> String
forall a. Show a => a -> String
show [Int]
args) String -> String -> String
forall a. [a] -> [a] -> [a]
++ String
code
osc ::
String
-> String
-> String
osc :: String -> String -> String
osc String
pS String
pT = String
"\ESC]" String -> String -> String
forall a. [a] -> [a] -> [a]
++ String
pS String -> String -> String
forall a. [a] -> [a] -> [a]
++ String
";" String -> String -> String
forall a. [a] -> [a] -> [a]
++ String
pT String -> String -> String
forall a. [a] -> [a] -> [a]
++ String
"\ESC\\"
colorToCode :: Color -> Int
colorToCode :: Color -> Int
colorToCode Color
color = case Color
color of
Color
Black -> Int
0
Color
Red -> Int
1
Color
Green -> Int
2
Color
Yellow -> Int
3
Color
Blue -> Int
4
Color
Magenta -> Int
5
Color
Cyan -> Int
6
Color
White -> Int
7
sgrToCode ::
SGR
-> [Int]
sgrToCode :: SGR -> [Int]
sgrToCode SGR
sgr = case SGR
sgr of
SGR
Reset -> [Int
0]
SetConsoleIntensity ConsoleIntensity
intensity -> case ConsoleIntensity
intensity of
ConsoleIntensity
BoldIntensity -> [Int
1]
ConsoleIntensity
FaintIntensity -> [Int
2]
ConsoleIntensity
NormalIntensity -> [Int
22]
SetItalicized Bool
True -> [Int
3]
SetItalicized Bool
False -> [Int
23]
SetUnderlining Underlining
underlining -> case Underlining
underlining of
Underlining
SingleUnderline -> [Int
4]
Underlining
DoubleUnderline -> [Int
21]
Underlining
NoUnderline -> [Int
24]
SetBlinkSpeed BlinkSpeed
blink_speed -> case BlinkSpeed
blink_speed of
BlinkSpeed
SlowBlink -> [Int
5]
BlinkSpeed
RapidBlink -> [Int
6]
BlinkSpeed
NoBlink -> [Int
25]
SetVisible Bool
False -> [Int
8]
SetVisible Bool
True -> [Int
28]
SetSwapForegroundBackground Bool
True -> [Int
7]
SetSwapForegroundBackground Bool
False -> [Int
27]
SetColor ConsoleLayer
Foreground ColorIntensity
Dull Color
color -> [Int
30 Int -> Int -> Int
forall a. Num a => a -> a -> a
+ Color -> Int
colorToCode Color
color]
SetColor ConsoleLayer
Foreground ColorIntensity
Vivid Color
color -> [Int
90 Int -> Int -> Int
forall a. Num a => a -> a -> a
+ Color -> Int
colorToCode Color
color]
SetColor ConsoleLayer
Background ColorIntensity
Dull Color
color -> [Int
40 Int -> Int -> Int
forall a. Num a => a -> a -> a
+ Color -> Int
colorToCode Color
color]
SetColor ConsoleLayer
Background ColorIntensity
Vivid Color
color -> [Int
100 Int -> Int -> Int
forall a. Num a => a -> a -> a
+ Color -> Int
colorToCode Color
color]
SetPaletteColor ConsoleLayer
Foreground Word8
index -> [Int
38, Int
5, Word8 -> Int
forall a b. (Integral a, Num b) => a -> b
fromIntegral Word8
index]
SetPaletteColor ConsoleLayer
Background Word8
index -> [Int
48, Int
5, Word8 -> Int
forall a b. (Integral a, Num b) => a -> b
fromIntegral Word8
index]
SetRGBColor ConsoleLayer
Foreground Colour Float
color -> [Int
38, Int
2] [Int] -> [Int] -> [Int]
forall a. [a] -> [a] -> [a]
++ Colour Float -> [Int]
forall {b} {b}. (RealFrac b, Floating b, Num b) => Colour b -> [b]
toRGB Colour Float
color
SetRGBColor ConsoleLayer
Background Colour Float
color -> [Int
48, Int
2] [Int] -> [Int] -> [Int]
forall a. [a] -> [a] -> [a]
++ Colour Float -> [Int]
forall {b} {b}. (RealFrac b, Floating b, Num b) => Colour b -> [b]
toRGB Colour Float
color
SetDefaultColor ConsoleLayer
Foreground -> [Int
39]
SetDefaultColor ConsoleLayer
Background -> [Int
49]
where
toRGB :: Colour b -> [b]
toRGB Colour b
color = let RGB Word8
r Word8
g Word8
b = Colour b -> RGB Word8
forall b. (RealFrac b, Floating b) => Colour b -> RGB Word8
toSRGB24 Colour b
color
in (Word8 -> b) -> [Word8] -> [b]
forall a b. (a -> b) -> [a] -> [b]
map Word8 -> b
forall a b. (Integral a, Num b) => a -> b
fromIntegral [Word8
r, Word8
g, Word8
b]
cursorUpCode, cursorDownCode, cursorForwardCode, cursorBackwardCode ::
Int
-> String
cursorUpCode :: Int -> String
cursorUpCode Int
n = if Int
n Int -> Int -> Bool
forall a. Eq a => a -> a -> Bool
== Int
0 then String
"" else [Int] -> String -> String
csi [Int
n] String
"A"
cursorDownCode :: Int -> String
cursorDownCode Int
n = if Int
n Int -> Int -> Bool
forall a. Eq a => a -> a -> Bool
== Int
0 then String
"" else [Int] -> String -> String
csi [Int
n] String
"B"
cursorForwardCode :: Int -> String
cursorForwardCode Int
n = if Int
n Int -> Int -> Bool
forall a. Eq a => a -> a -> Bool
== Int
0 then String
"" else [Int] -> String -> String
csi [Int
n] String
"C"
cursorBackwardCode :: Int -> String
cursorBackwardCode Int
n = if Int
n Int -> Int -> Bool
forall a. Eq a => a -> a -> Bool
== Int
0 then String
"" else [Int] -> String -> String
csi [Int
n] String
"D"
cursorDownLineCode, cursorUpLineCode ::
Int
-> String
cursorDownLineCode :: Int -> String
cursorDownLineCode Int
n = if Int
n Int -> Int -> Bool
forall a. Eq a => a -> a -> Bool
== Int
0 then [Int] -> String -> String
csi [Int
1] String
"G" else [Int] -> String -> String
csi [Int
n] String
"E"
cursorUpLineCode :: Int -> String
cursorUpLineCode Int
n = if Int
n Int -> Int -> Bool
forall a. Eq a => a -> a -> Bool
== Int
0 then [Int] -> String -> String
csi [Int
1] String
"G" else [Int] -> String -> String
csi [Int
n] String
"F"
setCursorColumnCode ::
Int
-> String
setCursorColumnCode :: Int -> String
setCursorColumnCode Int
n = [Int] -> String -> String
csi [Int
n Int -> Int -> Int
forall a. Num a => a -> a -> a
+ Int
1] String
"G"
setCursorPositionCode ::
Int
-> Int
-> String
setCursorPositionCode :: Int -> Int -> String
setCursorPositionCode Int
n Int
m = [Int] -> String -> String
csi [Int
n Int -> Int -> Int
forall a. Num a => a -> a -> a
+ Int
1, Int
m Int -> Int -> Int
forall a. Num a => a -> a -> a
+ Int
1] String
"H"
saveCursorCode, restoreCursorCode :: String
saveCursorCode :: String
saveCursorCode = String
"\ESC7"
restoreCursorCode :: String
restoreCursorCode = String
"\ESC8"
reportCursorPositionCode :: String
reportCursorPositionCode :: String
reportCursorPositionCode = [Int] -> String -> String
csi [] String
"6n"
reportLayerColorCode :: ConsoleLayer -> String
reportLayerColorCode :: ConsoleLayer -> String
reportLayerColorCode ConsoleLayer
Foreground = String -> String -> String
osc String
"10" String
"?"
reportLayerColorCode ConsoleLayer
Background = String -> String -> String
osc String
"11" String
"?"
clearFromCursorToScreenEndCode, clearFromCursorToScreenBeginningCode,
clearScreenCode :: String
clearFromCursorToLineEndCode, clearFromCursorToLineBeginningCode,
clearLineCode :: String
clearFromCursorToScreenEndCode :: String
clearFromCursorToScreenEndCode = [Int] -> String -> String
csi [Int
0] String
"J"
clearFromCursorToScreenBeginningCode :: String
clearFromCursorToScreenBeginningCode = [Int] -> String -> String
csi [Int
1] String
"J"
clearScreenCode :: String
clearScreenCode = [Int] -> String -> String
csi [Int
2] String
"J"
clearFromCursorToLineEndCode :: String
clearFromCursorToLineEndCode = [Int] -> String -> String
csi [Int
0] String
"K"
clearFromCursorToLineBeginningCode :: String
clearFromCursorToLineBeginningCode = [Int] -> String -> String
csi [Int
1] String
"K"
clearLineCode :: String
clearLineCode = [Int] -> String -> String
csi [Int
2] String
"K"
scrollPageUpCode, scrollPageDownCode ::
Int
-> String
scrollPageUpCode :: Int -> String
scrollPageUpCode Int
n = if Int
n Int -> Int -> Bool
forall a. Eq a => a -> a -> Bool
== Int
0 then String
"" else [Int] -> String -> String
csi [Int
n] String
"S"
scrollPageDownCode :: Int -> String
scrollPageDownCode Int
n = if Int
n Int -> Int -> Bool
forall a. Eq a => a -> a -> Bool
== Int
0 then String
"" else [Int] -> String -> String
csi [Int
n] String
"T"
useAlternateScreenBufferCode, useNormalScreenBufferCode :: String
useAlternateScreenBufferCode :: String
useAlternateScreenBufferCode = [Int] -> String -> String
csi [] String
"?1049h"
useNormalScreenBufferCode :: String
useNormalScreenBufferCode = [Int] -> String -> String
csi [] String
"?1049l"
setSGRCode ::
[SGR]
-> String
setSGRCode :: [SGR] -> String
setSGRCode [SGR]
sgrs = [Int] -> String -> String
csi ((SGR -> [Int]) -> [SGR] -> [Int]
forall (t :: * -> *) a b. Foldable t => (a -> [b]) -> t a -> [b]
concatMap SGR -> [Int]
sgrToCode [SGR]
sgrs) String
"m"
hideCursorCode, showCursorCode :: String
hideCursorCode :: String
hideCursorCode = [Int] -> String -> String
csi [] String
"?25l"
showCursorCode :: String
showCursorCode = [Int] -> String -> String
csi [] String
"?25h"
hyperlinkWithParamsCode ::
[(String, String)]
-> String
-> String
-> String
hyperlinkWithParamsCode :: [(String, String)] -> String -> String -> String
hyperlinkWithParamsCode [(String, String)]
params String
uri String
link =
String -> String -> String
osc String
"8" String
pT String -> String -> String
forall a. [a] -> [a] -> [a]
++ String
link String -> String -> String
forall a. [a] -> [a] -> [a]
++ String -> String -> String
osc String
"8" String
";"
where
pT :: String
pT = String
params' String -> String -> String
forall a. [a] -> [a] -> [a]
++ String
";" String -> String -> String
forall a. [a] -> [a] -> [a]
++ String
uri
params' :: String
params' = String -> [String] -> String
forall a. [a] -> [[a]] -> [a]
intercalate String
":" ([String] -> String) -> [String] -> String
forall a b. (a -> b) -> a -> b
$ ((String, String) -> String) -> [(String, String)] -> [String]
forall a b. (a -> b) -> [a] -> [b]
map (\(String
k, String
v) -> String
k String -> String -> String
forall a. [a] -> [a] -> [a]
++ String
"=" String -> String -> String
forall a. [a] -> [a] -> [a]
++ String
v) [(String, String)]
params
hyperlinkCode ::
String
-> String
-> String
hyperlinkCode :: String -> String -> String
hyperlinkCode = [(String, String)] -> String -> String -> String
hyperlinkWithParamsCode []
hyperlinkWithIdCode ::
String
-> String
-> String
-> String
hyperlinkWithIdCode :: String -> String -> String -> String
hyperlinkWithIdCode String
linkId = [(String, String)] -> String -> String -> String
hyperlinkWithParamsCode [(String
"id", String
linkId)]
setTitleCode ::
String
-> String
setTitleCode :: String -> String
setTitleCode String
title = String -> String -> String
osc String
"0" ((Char -> Bool) -> String -> String
forall a. (a -> Bool) -> [a] -> [a]
filter Char -> Bool
isPrint String
title)