summary refs log tree commit diff stats
path: root/lib
diff options
context:
space:
mode:
authorAdam Strzelecki <ono@java.pl>2015-06-11 21:03:55 +0200
committerAdam Strzelecki <ono@java.pl>2015-06-15 11:26:53 +0200
commit1057770ce51c3ede38f743001bcb6e6d4a25d1c2 (patch)
treed3827034086a1256646dd2fef77216cc517cb3ec /lib
parent806dfe976d3771c242b9c6d8702a75773e6c9dab (diff)
downloadNim-1057770ce51c3ede38f743001bcb6e6d4a25d1c2.tar.gz
colors: Introduce resetStyle enum & use templates
1. Introduce TerminalCmd enum and resetStyle that can be issued to issue
   resetAttributes within styledEcho arguments.

2. Use templates to resolve styledEcho arguments for performance reasons.

3. Try to avoid calling trailing write "\n" and reset attributes where possible.
Diffstat (limited to 'lib')
-rw-r--r--lib/pure/terminal.nim35
1 files changed, 28 insertions, 7 deletions
diff --git a/lib/pure/terminal.nim b/lib/pure/terminal.nim
index 15e2eefec..2efdf72d5 100644
--- a/lib/pure/terminal.nim
+++ b/lib/pure/terminal.nim
@@ -406,22 +406,43 @@ proc isatty*(f: File): bool =
 
   result = isatty(getFileHandle(f)) != 0'i32
 
-proc styledEchoProcessArg(s: string) = write stdout, s
-proc styledEchoProcessArg(style: Style) = setStyle({style})
-proc styledEchoProcessArg(style: set[Style]) = setStyle style
-proc styledEchoProcessArg(color: ForegroundColor) = setForegroundColor color
-proc styledEchoProcessArg(color: BackgroundColor) = setBackgroundColor color
+type
+  TerminalCmd* = enum  ## commands that can be expressed as arguments
+    resetStyle         ## reset attributes
+
+template styledEchoProcessArg(s: string) = write stdout, s
+template styledEchoProcessArg(style: Style) = setStyle({style})
+template styledEchoProcessArg(style: set[Style]) = setStyle style
+template styledEchoProcessArg(color: ForegroundColor) = setForegroundColor color
+template styledEchoProcessArg(color: BackgroundColor) = setBackgroundColor color
+template styledEchoProcessArg(cmd: TerminalCmd) =
+  when cmd == resetStyle:
+    resetAttributes()
 
 macro styledEcho*(m: varargs[expr]): stmt =
   ## to be documented.
   let m = callsite()
+  var reset = false
   result = newNimNode(nnkStmtList)
 
   for i in countup(1, m.len - 1):
-    result.add(newCall(bindSym"styledEchoProcessArg", m[i]))
+    let item = m[i]
+    case item.kind
+    of nnkStrLit..nnkTripleStrLit:
+      if i == m.len - 1:
+        # optimize if string literal is last, just call writeln
+        result.add(newCall(bindSym"writeln", bindSym"stdout", item))
+        if reset: result.add(newCall(bindSym"resetAttributes"))
+        return
+      else:
+        # if it is string literal just call write, do not enable reset
+        result.add(newCall(bindSym"write", bindSym"stdout", item))
+    else:
+      result.add(newCall(bindSym"styledEchoProcessArg", item))
+      reset = true
 
   result.add(newCall(bindSym"write", bindSym"stdout", newStrLitNode("\n")))
-  result.add(newCall(bindSym"resetAttributes"))
+  if reset: result.add(newCall(bindSym"resetAttributes"))
 
 when defined(nimdoc):
   proc getch*(): char =