The terminal module now exports additional procs for generating ANSI color

codes as strings.
This commit is contained in:
Zahary Karadjov
2018-04-29 13:56:04 +03:00
committed by Andreas Rumpf
parent ae5c946a32
commit 4409c82228
2 changed files with 45 additions and 21 deletions

View File

@@ -72,6 +72,8 @@
- ``algorithm.smartBinarySearch`` and ``algorithm.binarySearch`` is
now joined in ``binarySearch``. ``smartbinarySearch`` is now
deprecated.
- The `terminal` module now exports additional procs for generating ANSI color
codes as strings.
### Language additions

View File

@@ -29,9 +29,7 @@ when not hasThreadSupport:
var
colorsFGCache = initTable[Color, string]()
colorsBGCache = initTable[Color, string]()
when not defined(windows):
var
styleCache = initTable[int, string]()
styleCache = initTable[int, string]()
var
trueColorIsSupported: bool
@@ -41,6 +39,7 @@ var
const
fgPrefix = "\x1b[38;2;"
bgPrefix = "\x1b[48;2;"
ansiResetCode* = "\e[0m"
when not defined(windows):
const
@@ -468,7 +467,7 @@ proc resetAttributes*(f: File) =
else:
discard setConsoleTextAttribute(hStdout, oldStdoutAttr)
else:
f.write("\e[0m")
f.write(ansiResetCode)
type
Style* = enum ## different styles for text output
@@ -487,15 +486,22 @@ when not defined(windows):
gFG {.threadvar.}: int
gBG {.threadvar.}: int
proc getStyleStr(style: int): string =
when hasThreadSupport:
result = fmt"{stylePrefix}{style}m"
proc ansiStyleCode*(style: int): string =
when hasThreadSupport:
result = fmt"{stylePrefix}{style}m"
else:
if styleCache.hasKey(style):
result = styleCache[style]
else:
if styleCache.hasKey(style):
result = styleCache[style]
else:
result = fmt"{stylePrefix}{style}m"
styleCache[style] = result
result = fmt"{stylePrefix}{style}m"
styleCache[style] = result
template ansiStyleCode*(style: Style): string =
ansiStyleCode(style.int)
# The styleCache can be skipped when `style` is known at compile-time
template ansiStyleCode*(style: static[Style]): string =
(static(stylePrefix & $style.int & "m"))
proc setStyle*(f: File, style: set[Style]) =
## Sets the terminal style.
@@ -510,7 +516,7 @@ proc setStyle*(f: File, style: set[Style]) =
discard setConsoleTextAttribute(h, old or a)
else:
for s in items(style):
f.write(getStyleStr(ord(s)))
f.write(ansiStyleCode(s))
proc writeStyled*(txt: string, style: set[Style] = {styleBright}) =
## Writes the text `txt` in a given `style` to stdout.
@@ -524,9 +530,9 @@ proc writeStyled*(txt: string, style: set[Style] = {styleBright}) =
stdout.write(txt)
stdout.resetAttributes()
if gFG != 0:
stdout.write(getStyleStr(gFG))
stdout.write(ansiStyleCode(gFG))
if gBG != 0:
stdout.write(getStyleStr(gBG))
stdout.write(ansiStyleCode(gBG))
type
ForegroundColor* = enum ## terminal's foreground colors
@@ -572,7 +578,7 @@ proc setForegroundColor*(f: File, fg: ForegroundColor, bright=false) =
else:
gFG = ord(fg)
if bright: inc(gFG, 60)
f.write(getStyleStr(gFG))
f.write(ansiStyleCode(gFG))
proc setBackgroundColor*(f: File, bg: BackgroundColor, bright=false) =
## Sets the terminal's background color.
@@ -594,10 +600,18 @@ proc setBackgroundColor*(f: File, bg: BackgroundColor, bright=false) =
else:
gBG = ord(bg)
if bright: inc(gBG, 60)
f.write(getStyleStr(gBG))
f.write(ansiStyleCode(gBG))
proc ansiForegroundColorCode*(fg: ForegroundColor, bright=false): string =
var style = ord(fg)
if bright: inc(style, 60)
return ansiStyleCode(style)
proc getFGColorStr(color: Color): string =
template ansiForegroundColorCode*(fg: static[ForegroundColor],
bright: static[bool] = false): string =
ansiStyleCode(fg.int + bright.int * 60)
proc ansiForegroundColorCode*(color: Color): string =
when hasThreadSupport:
let rgb = extractRGB(color)
result = fmt"{fgPrefix}{rgb.r};{rgb.g};{rgb.b}m"
@@ -609,7 +623,11 @@ proc getFGColorStr(color: Color): string =
result = fmt"{fgPrefix}{rgb.r};{rgb.g};{rgb.b}m"
colorsFGCache[color] = result
proc getBGColorStr(color: Color): string =
template ansiForegroundColorCode*(color: static[Color]): string =
let rgb = extractRGB(color)
(static(fmt"{fgPrefix}{rgb.r};{rgb.g};{rgb.b}m"))
proc ansiBackgroundColorCode*(color: Color): string =
when hasThreadSupport:
let rgb = extractRGB(color)
result = fmt"{bgPrefix}{rgb.r};{rgb.g};{rgb.b}m"
@@ -621,15 +639,19 @@ proc getBGColorStr(color: Color): string =
result = fmt"{bgPrefix}{rgb.r};{rgb.g};{rgb.b}m"
colorsFGCache[color] = result
template ansiBackgroundColorCode*(color: static[Color]): string =
const rgb = extractRGB(color)
(static(fmt"{bgPrefix}{rgb.r};{rgb.g};{rgb.b}m"))
proc setForegroundColor*(f: File, color: Color) =
## Sets the terminal's foreground true color.
if trueColorIsEnabled:
f.write(getFGColorStr(color))
f.write(ansiForegroundColorCode(color))
proc setBackgroundColor*(f: File, color: Color) =
## Sets the terminal's background true color.
if trueColorIsEnabled:
f.write(getBGColorStr(color))
f.write(ansiBackgroundColorCode(color))
proc setTrueColor(f: File, color: Color) =
if fgSetColor: