Compare commits

..

No commits in common. "56bb2bb7c1da402c2c52fb3f7f10620c7c2fca7e" and "7385a93110f95e1d67d803780efa014fdc960779" have entirely different histories.

4 changed files with 40 additions and 52 deletions

View file

@ -4,7 +4,8 @@
use BB style markup to add color to strings using VT100 escape codes use BB style markup to add color to strings using VT100 escape codes
]## ]##
{.push raises:[].} # TODO:
#{.push raises:[].}
import std/[ import std/[
macros, os, sequtils, strformat, strutils, terminal macros, os, sequtils, strformat, strutils, terminal
@ -71,41 +72,7 @@ const ColorXTermNames = enumNames(ColorXterm).mapIt(firstCapital(it))
const BbStyleNames = enumNames(BbStyle).mapIt(firstCapital(it)) const BbStyleNames = enumNames(BbStyle).mapIt(firstCapital(it))
const ColorDigitStrings = (1..255).toSeq().mapIt($it) const ColorDigitStrings = (1..255).toSeq().mapIt($it)
# TODO: write non-fallible parseStyle(s) procedure
template parseUnsafe(body: untyped): untyped =
try: body
except: discard
proc parseStyle(codes: var seq[string], style: string) =
var style = normalizeStyle(style)
if style in ["B", "I", "U"]:
parseUnsafe: codes.add parseEnum[BbStyleAbbr](style).toCode()
elif style in BbStyleNames:
parseUnsafe: codes.add parseEnum[BbStyle](style).toCode()
if not (bbMode == On): return
if style in ColorXtermNames:
parseUnsafe: codes.add parseEnum[ColorXterm](style).toCode()
elif style.isHex():
codes.add style.hexToRgb.toCode()
elif style in ColorDigitStrings:
parseUnsafe: codes.add parseInt(style).toCode()
else:
when defined(debugBB): echo "unknown style: " & normalizedStyle
func parseBgStyle(codes: var seq[string], style: string) =
var style = normalizeStyle(style)
if style in ColorXtermNames:
parseUnsafe: codes.add parseEnum[ColorXTerm](style).toBgCode()
elif style.isHex():
codes.add style.hexToRgb().toBgCode()
elif style in ColorDigitStrings:
parseUnsafe: codes.add parseInt(style).toBgCode()
else:
when defined(debugBB): echo "unknown bg style: " & style
proc toAnsiCode*(s: string): string = proc toAnsiCode*(s: string): string =
if bbMode == Off: return if bbMode == Off: return
var var
@ -119,10 +86,33 @@ proc toAnsiCode*(s: string): string =
else: else:
styles = s.splitWhitespace() styles = s.splitWhitespace()
for style in styles: for style in styles:
parseStyle codes, style let normalizedStyle = normalizeStyle(style)
if normalizedStyle in ["B", "I", "U"]:
codes.add parseEnum[BbStyleAbbr](normalizedStyle).toCode()
elif normalizedStyle in BbStyleNames:
codes.add parseEnum[BbStyle](normalizedStyle).toCode()
if not (bbMode == On): continue
if normalizedStyle in ColorXtermNames:
codes.add parseEnum[ColorXterm](normalizedStyle).toCode()
elif normalizedStyle.isHex():
codes.add normalizedStyle.hexToRgb.toCode()
elif normalizedStyle in ColorDigitStrings:
codes.add parseInt(normalizedStyle).toCode()
else:
when defined(debugBB): echo "unknown style: " & normalizedStyle
if bbMode == On and bgStyle != "": if bbMode == On and bgStyle != "":
parseBgStyle codes, bgStyle let normalizedBgStyle = normalizeStyle(bgStyle)
if normalizedBgStyle in ColorXtermNames:
codes.add parseEnum[ColorXTerm](normalizedBgStyle).toBgCode()
elif normalizedBgStyle.isHex():
codes.add normalizedBgStyle.hexToRgb().toBgCode()
elif normalizedBgStyle in ColorDigitStrings:
codes.add parseInt(normalizedBgStyle).toBgCode()
else:
when defined(debugBB): echo "unknown bg style: " & normalizedBgStyle
if codes.len > 0: if codes.len > 0:
result.add "\e[" result.add "\e["
@ -335,7 +325,7 @@ proc `&`*(x: BbString, y: BbString): Bbstring =
proc bbEscape*(s: string): string {.inline.} = proc bbEscape*(s: string): string {.inline.} =
s.replace("[", "[[").replace("\\", "\\\\") s.replace("[", "[[").replace("\\", "\\\\")
proc bbEcho*(args: varargs[string, `$`]) {.raises: [IOError]} = proc bbEcho*(args: varargs[string, `$`]) {.sideEffect.} =
for x in args: for x in args:
stdout.write(x.bb) stdout.write(x.bb)
stdout.write('\n') stdout.write('\n')

View file

@ -0,0 +1 @@

View file

@ -19,7 +19,7 @@ import ./bbansi
template tryImport(x, body) = template tryImport(x, body) =
when not (compiles do: import x): body else: import x when not (compiles do: import x): body else: import x
tryImport pkg/cligen: tryImport pkg/cligen:
{.fatal: "hwylterm/cligen requires cligen>=1.7.5".} {.fatal: "hwylterm/cli requires cligen>=1.7.5".}
type type

View file

@ -1,9 +1,6 @@
## hwylterm/logging
##
## wrapper around std/logging to provide a fancy console logger
import std/[logging, strutils] import std/[logging, strutils]
export logging export logging
import ./bbansi import ./bbansi
var var
@ -22,10 +19,10 @@ Level* = enum ## \
]# ]#
type type
HwylConsoleLogger* = ref object of Logger FancyConsoleLogger* = ref object of Logger
## A logger that writes log messages to the console. ## A logger that writes log messages to the console.
## ##
## Create a new ``HwylConsoleLogger`` with the `newHwylConsoleLogger proc ## Create a new ``FancyConsoleLogger`` with the `newFancyConsoleLogger proc
## <#newConsoleLogger>`_. ## <#newConsoleLogger>`_.
## ##
useStderr*: bool ## If true, writes to stderr; otherwise, writes to stdout useStderr*: bool ## If true, writes to stderr; otherwise, writes to stdout
@ -53,11 +50,11 @@ proc genFmtStr(
): string = ): string =
var parts: seq[string] var parts: seq[string]
if fmtPrefix != "": parts.add fmtPrefix if fmtPrefix != "": parts.add fmtPrefix
parts.add $LevelNames[level].alignLeft(6).bb(levelStyle) parts.add $LevelNames[level].bb(levelStyle)
return parts.join(fmtSep) & fmtSuffix return parts.join(fmtSep) & fmtSuffix
proc newHwylConsoleLogger*( proc newFancyConsoleLogger*(
levelThreshold = lvlAll, levelThreshold = lvlAll,
fmtPrefix = "", fmtPrefix = "",
fmtSep = "|", fmtSep = "|",
@ -70,8 +67,8 @@ proc newHwylConsoleLogger*(
warnStyle = "bold yellow", warnStyle = "bold yellow",
errorStyle = "bold red", errorStyle = "bold red",
fatalStyle = "bold red" fatalStyle = "bold red"
): HwylConsoleLogger = ): FancyConsoleLogger =
## Creates a new `HwylConsoleLogger<#HwylConsoleLogger>`_. ## Creates a new `FancyConsoleLogger<#ConsoleLogger>`_.
new result new result
## log needs to be gcsafe so we pregenerate the log formats when making the handler ## log needs to be gcsafe so we pregenerate the log formats when making the handler
let fmtStrs: array[Level, string] = [ let fmtStrs: array[Level, string] = [
@ -92,8 +89,8 @@ proc newHwylConsoleLogger*(
result.fmtStrs = fmtStrs result.fmtStrs = fmtStrs
method log*(logger: HwylConsoleLogger, level: Level, args: varargs[string, `$`]) {.gcsafe.} = method log*(logger: FancyConsoleLogger, level: Level, args: varargs[string, `$`]) {.gcsafe.} =
## Logs to the console with the given `HwylConsoleLogger<#HwylConsoleLogger>`_ only. ## Logs to the console with the given `FancyConsoleLogger<#ConsoleLogger>`_ only.
## ##
## This method ignores the list of registered handlers. ## This method ignores the list of registered handlers.
## ##