The terminal module now exports additional procs for generating ANSI color
codes as strings.
This commit is contained in:
parent
ae5c946a32
commit
4409c82228
2 changed files with 45 additions and 21 deletions
|
|
@ -72,6 +72,8 @@
|
||||||
- ``algorithm.smartBinarySearch`` and ``algorithm.binarySearch`` is
|
- ``algorithm.smartBinarySearch`` and ``algorithm.binarySearch`` is
|
||||||
now joined in ``binarySearch``. ``smartbinarySearch`` is now
|
now joined in ``binarySearch``. ``smartbinarySearch`` is now
|
||||||
deprecated.
|
deprecated.
|
||||||
|
- The `terminal` module now exports additional procs for generating ANSI color
|
||||||
|
codes as strings.
|
||||||
|
|
||||||
### Language additions
|
### Language additions
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -29,9 +29,7 @@ when not hasThreadSupport:
|
||||||
var
|
var
|
||||||
colorsFGCache = initTable[Color, string]()
|
colorsFGCache = initTable[Color, string]()
|
||||||
colorsBGCache = initTable[Color, string]()
|
colorsBGCache = initTable[Color, string]()
|
||||||
when not defined(windows):
|
styleCache = initTable[int, string]()
|
||||||
var
|
|
||||||
styleCache = initTable[int, string]()
|
|
||||||
|
|
||||||
var
|
var
|
||||||
trueColorIsSupported: bool
|
trueColorIsSupported: bool
|
||||||
|
|
@ -41,6 +39,7 @@ var
|
||||||
const
|
const
|
||||||
fgPrefix = "\x1b[38;2;"
|
fgPrefix = "\x1b[38;2;"
|
||||||
bgPrefix = "\x1b[48;2;"
|
bgPrefix = "\x1b[48;2;"
|
||||||
|
ansiResetCode* = "\e[0m"
|
||||||
|
|
||||||
when not defined(windows):
|
when not defined(windows):
|
||||||
const
|
const
|
||||||
|
|
@ -468,7 +467,7 @@ proc resetAttributes*(f: File) =
|
||||||
else:
|
else:
|
||||||
discard setConsoleTextAttribute(hStdout, oldStdoutAttr)
|
discard setConsoleTextAttribute(hStdout, oldStdoutAttr)
|
||||||
else:
|
else:
|
||||||
f.write("\e[0m")
|
f.write(ansiResetCode)
|
||||||
|
|
||||||
type
|
type
|
||||||
Style* = enum ## different styles for text output
|
Style* = enum ## different styles for text output
|
||||||
|
|
@ -487,15 +486,22 @@ when not defined(windows):
|
||||||
gFG {.threadvar.}: int
|
gFG {.threadvar.}: int
|
||||||
gBG {.threadvar.}: int
|
gBG {.threadvar.}: int
|
||||||
|
|
||||||
proc getStyleStr(style: int): string =
|
proc ansiStyleCode*(style: int): string =
|
||||||
when hasThreadSupport:
|
when hasThreadSupport:
|
||||||
result = fmt"{stylePrefix}{style}m"
|
result = fmt"{stylePrefix}{style}m"
|
||||||
|
else:
|
||||||
|
if styleCache.hasKey(style):
|
||||||
|
result = styleCache[style]
|
||||||
else:
|
else:
|
||||||
if styleCache.hasKey(style):
|
result = fmt"{stylePrefix}{style}m"
|
||||||
result = styleCache[style]
|
styleCache[style] = result
|
||||||
else:
|
|
||||||
result = fmt"{stylePrefix}{style}m"
|
template ansiStyleCode*(style: Style): string =
|
||||||
styleCache[style] = result
|
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]) =
|
proc setStyle*(f: File, style: set[Style]) =
|
||||||
## Sets the terminal style.
|
## Sets the terminal style.
|
||||||
|
|
@ -510,7 +516,7 @@ proc setStyle*(f: File, style: set[Style]) =
|
||||||
discard setConsoleTextAttribute(h, old or a)
|
discard setConsoleTextAttribute(h, old or a)
|
||||||
else:
|
else:
|
||||||
for s in items(style):
|
for s in items(style):
|
||||||
f.write(getStyleStr(ord(s)))
|
f.write(ansiStyleCode(s))
|
||||||
|
|
||||||
proc writeStyled*(txt: string, style: set[Style] = {styleBright}) =
|
proc writeStyled*(txt: string, style: set[Style] = {styleBright}) =
|
||||||
## Writes the text `txt` in a given `style` to stdout.
|
## 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.write(txt)
|
||||||
stdout.resetAttributes()
|
stdout.resetAttributes()
|
||||||
if gFG != 0:
|
if gFG != 0:
|
||||||
stdout.write(getStyleStr(gFG))
|
stdout.write(ansiStyleCode(gFG))
|
||||||
if gBG != 0:
|
if gBG != 0:
|
||||||
stdout.write(getStyleStr(gBG))
|
stdout.write(ansiStyleCode(gBG))
|
||||||
|
|
||||||
type
|
type
|
||||||
ForegroundColor* = enum ## terminal's foreground colors
|
ForegroundColor* = enum ## terminal's foreground colors
|
||||||
|
|
@ -572,7 +578,7 @@ proc setForegroundColor*(f: File, fg: ForegroundColor, bright=false) =
|
||||||
else:
|
else:
|
||||||
gFG = ord(fg)
|
gFG = ord(fg)
|
||||||
if bright: inc(gFG, 60)
|
if bright: inc(gFG, 60)
|
||||||
f.write(getStyleStr(gFG))
|
f.write(ansiStyleCode(gFG))
|
||||||
|
|
||||||
proc setBackgroundColor*(f: File, bg: BackgroundColor, bright=false) =
|
proc setBackgroundColor*(f: File, bg: BackgroundColor, bright=false) =
|
||||||
## Sets the terminal's background color.
|
## Sets the terminal's background color.
|
||||||
|
|
@ -594,10 +600,18 @@ proc setBackgroundColor*(f: File, bg: BackgroundColor, bright=false) =
|
||||||
else:
|
else:
|
||||||
gBG = ord(bg)
|
gBG = ord(bg)
|
||||||
if bright: inc(gBG, 60)
|
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:
|
when hasThreadSupport:
|
||||||
let rgb = extractRGB(color)
|
let rgb = extractRGB(color)
|
||||||
result = fmt"{fgPrefix}{rgb.r};{rgb.g};{rgb.b}m"
|
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"
|
result = fmt"{fgPrefix}{rgb.r};{rgb.g};{rgb.b}m"
|
||||||
colorsFGCache[color] = result
|
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:
|
when hasThreadSupport:
|
||||||
let rgb = extractRGB(color)
|
let rgb = extractRGB(color)
|
||||||
result = fmt"{bgPrefix}{rgb.r};{rgb.g};{rgb.b}m"
|
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"
|
result = fmt"{bgPrefix}{rgb.r};{rgb.g};{rgb.b}m"
|
||||||
colorsFGCache[color] = result
|
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) =
|
proc setForegroundColor*(f: File, color: Color) =
|
||||||
## Sets the terminal's foreground true color.
|
## Sets the terminal's foreground true color.
|
||||||
if trueColorIsEnabled:
|
if trueColorIsEnabled:
|
||||||
f.write(getFGColorStr(color))
|
f.write(ansiForegroundColorCode(color))
|
||||||
|
|
||||||
proc setBackgroundColor*(f: File, color: Color) =
|
proc setBackgroundColor*(f: File, color: Color) =
|
||||||
## Sets the terminal's background true color.
|
## Sets the terminal's background true color.
|
||||||
if trueColorIsEnabled:
|
if trueColorIsEnabled:
|
||||||
f.write(getBGColorStr(color))
|
f.write(ansiBackgroundColorCode(color))
|
||||||
|
|
||||||
proc setTrueColor(f: File, color: Color) =
|
proc setTrueColor(f: File, color: Color) =
|
||||||
if fgSetColor:
|
if fgSetColor:
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue