Convert styledWriteLine and styledEcho to templates

This also fixes a bug in the styledWriteLine behavior where the background color
leaked onto the next newline if that command did not end with resetStyle.

Now it is not necessary to end styledWriteLine calls that set BackgroundColor to
end in resetStyle.
This commit is contained in:
Kaushal Modi 2018-06-15 12:41:25 -04:00
commit abbf9ba9f7

View file

@ -726,11 +726,8 @@ macro styledWrite*(f: File, m: varargs[typed]): untyped =
reset = true reset = true
if reset: result.add(newCall(bindSym"resetAttributes", f)) if reset: result.add(newCall(bindSym"resetAttributes", f))
macro styledWriteLine*(f: File, m: varargs[typed]): untyped = template styledWriteLine*(f: File, args: varargs[untyped]) =
## Similar to ``writeLine``, but treating terminal style arguments specially. ## Calls ``styledWrite`` and appends a newline at the end.
## When some argument is ``Style``, ``set[Style]``, ``ForegroundColor``,
## ``BackgroundColor`` or ``TerminalCmd`` then it is not sent directly to
## ``f``, but instead corresponding terminal style proc is called.
## ##
## Example: ## Example:
## ##
@ -739,35 +736,12 @@ macro styledWriteLine*(f: File, m: varargs[typed]): untyped =
## proc error(msg: string) = ## proc error(msg: string) =
## styledWriteLine(stderr, fgRed, "Error: ", resetStyle, msg) ## styledWriteLine(stderr, fgRed, "Error: ", resetStyle, msg)
## ##
let m = callsite() styledWrite(f, args)
var reset = false write(f, "\n")
result = newNimNode(nnkStmtList)
for i in countup(2, m.len - 1): template styledEcho*(args: varargs[untyped]) =
let item = m[i]
case item.kind
of nnkStrLit..nnkTripleStrLit:
if i == m.len - 1:
# optimize if string literal is last, just call writeLine
result.add(newCall(bindSym"writeLine", f, item))
if reset: result.add(newCall(bindSym"resetAttributes", f))
return
else:
# if it is string literal just call write, do not enable reset
result.add(newCall(bindSym"write", f, item))
else:
result.add(newCall(bindSym"styledEchoProcessArg", f, item))
reset = true
result.add(newCall(bindSym"write", f, newStrLitNode("\n")))
if reset: result.add(newCall(bindSym"resetAttributes", f))
macro styledEcho*(args: varargs[untyped]): untyped =
## Echoes styles arguments to stdout using ``styledWriteLine``. ## Echoes styles arguments to stdout using ``styledWriteLine``.
result = newCall(bindSym"styledWriteLine") stdout.styledWriteLine(args)
result.add(bindSym"stdout")
for arg in children(args):
result.add(arg)
proc getch*(): char = proc getch*(): char =
## Read a single character from the terminal, blocking until it is entered. ## Read a single character from the terminal, blocking until it is entered.
@ -951,9 +925,7 @@ when not defined(testing) and isMainModule:
echo "ordinary text" echo "ordinary text"
stdout.styledWriteLine(fgRed, "red text ") stdout.styledWriteLine(fgRed, "red text ")
# Below, resetStyle is needed to prevent leaking the set bgRed to the next stdout.styledWriteLine(fgWhite, bgRed, "white text in red background")
# newline.
stdout.styledWriteLine(fgWhite, bgRed, "white text in red background", resetStyle)
stdout.styledWriteLine(" ordinary text ") stdout.styledWriteLine(" ordinary text ")
stdout.styledWriteLine(fgGreen, "green text") stdout.styledWriteLine(fgGreen, "green text")