From 2ba36425447fee5459126aa7da8ebd21b539f187 Mon Sep 17 00:00:00 2001 From: Adam Strzelecki Date: Thu, 11 Jun 2015 21:46:17 +0200 Subject: [PATCH] msgs: styledMsgWriteln compatible with styledEcho 1. Introduce styledMsgWriteln which can be used same way as styledEcho. 2. Make file names and positions use bright white like in other compilers, so only message types are colored. --- compiler/msgs.nim | 143 +++++++++++++++++++++++++++++----------------- 1 file changed, 90 insertions(+), 53 deletions(-) diff --git a/compiler/msgs.nim b/compiler/msgs.nim index 2d7094e631..2edb869d87 100644 --- a/compiler/msgs.nim +++ b/compiler/msgs.nim @@ -8,7 +8,7 @@ # import - options, strutils, os, tables, ropes, platform, terminal + options, strutils, os, tables, ropes, platform, terminal, macros type TMsgKind* = enum @@ -605,13 +605,15 @@ proc suggestQuit*() = # this format is understood by many text editors: it is the same that # Borland and Freepascal use const - PosErrorFormat* = "$1($2, $3) Error: " - PosWarningFormat* = "$1($2, $3) Warning: " - PosHintFormat* = "$1($2, $3) Hint: " - PosContextFormat = "$1($2, $3) Info: " - RawError* = "Error: " - RawWarning* = "Warning: " - RawHint* = "Hint: " + PosFormat = "$1($2, $3) " + ErrorTitle = "Error: " + ErrorColor = fgRed + WarningTitle = "Warning: " + WarningColor = fgYellow + HintTitle = "Hint: " + HintColor = fgGreen + InfoTitle = "Info: " + InfoColor = fgCyan proc getInfoContextLen*(): int = return msgContext.len proc setInfoContextLen*(L: int) = setLen(msgContext, L) @@ -686,27 +688,58 @@ proc outWriteln*(s: string) = ## Writes to stdout. Always. if eStdOut in errorOutputs: writeln(stdout, s) -proc msgWriteln*(s: string, color: ForegroundColor = fgWhite, coloredText: string = "") = - ## Writes to stdout. If --stderr option is given, writes to stderr instead. +proc msgWriteln*(s: string) = + ## Writes to stdout. If --stdout option is given, writes to stderr instead. #if gCmd == cmdIdeTools and optCDebug notin gGlobalOptions: return - var hasColor = optUseColors in gGlobalOptions if not isNil(writelnHook): - writelnHook(coloredText & s) + writelnHook(s) + elif optStdout in gGlobalOptions: + if eStdErr in errorOutputs: writeln(stderr, s) else: - if optStdout in gGlobalOptions: - if eStdErr in errorOutputs: - if hasColor: setForegroundColor(color) - write(stderr, coloredText) - if hasColor: resetAttributes() - writeln(stderr, s) - else: - if eStdOut in errorOutputs: - if hasColor: setForegroundColor(color) - write(stdout, coloredText) - if hasColor: resetAttributes() - writeln(stdout, s) + if eStdOut in errorOutputs: writeln(stdout, s) + +macro callIgnoringStyle(theProc: typed, first: typed, + args: varargs[expr]): stmt = + let typForegroundColor = bindSym"ForegroundColor".getType + let typBackgroundColor = bindSym"BackgroundColor".getType + let typStyle = bindSym"Style".getType + let typTerminalCmd = bindSym"TerminalCmd".getType + result = newCall(theProc) + if first.kind != nnkNilLit: result.add(first) + for arg in children(args[0][1]): + if arg.kind == nnkNilLit: continue + let typ = arg.getType + if typ.kind != nnkEnumTy or + typ != typForegroundColor and + typ != typBackgroundColor and + typ != typStyle and + typ != typTerminalCmd: + result.add(arg) + +macro callStyledEcho(args: varargs[expr]): stmt = + result = newCall(bindSym"styledEcho") + for arg in children(args[0][1]): + result.add(arg) + +template callWritelnHook(args: varargs[string, `$`]) = + var s = "" + for arg in args: + s.add arg + writelnHook s + +template styledMsgWriteln*(args: varargs[expr]) = + if not isNil(writelnHook): + callIgnoringStyle(callWritelnHook, nil, args) + elif optStdout in gGlobalOptions: + if eStdErr in errorOutputs: callIgnoringStyle(writeln, stderr, args) + else: + if eStdOut in errorOutputs: + if optUseColors in gGlobalOptions: + callStyledEcho(args) + else: + callIgnoringStyle(writeln, stdout, args) proc coordToStr(coord: int): string = if coord == -1: result = "???" @@ -728,7 +761,7 @@ proc handleError(msg: TMsgKind, eh: TErrorHandling, s: string) = if stackTraceAvailable() and isNil(writelnHook): writeStackTrace() else: - msgWriteln("", fgRed, "No stack traceback available\nTo create a stacktrace, rerun compilation with ./koch temp " & options.command & " ") + styledMsgWriteln(fgRed, "No stack traceback available\nTo create a stacktrace, rerun compilation with ./koch temp " & options.command & " ") quit 1 if msg >= fatalMin and msg <= fatalMax: @@ -750,10 +783,12 @@ proc writeContext(lastinfo: TLineInfo) = var info = lastinfo for i in countup(0, len(msgContext) - 1): if msgContext[i] != lastinfo and msgContext[i] != info: - msgWriteln(PosContextFormat % [toMsgFilename(msgContext[i]), - coordToStr(msgContext[i].line), - coordToStr(msgContext[i].col+1), - getMessageStr(errInstantiationFrom, "")]) + styledMsgWriteln(styleBright, + PosFormat % [toMsgFilename(msgContext[i]), + coordToStr(msgContext[i].line), + coordToStr(msgContext[i].col+1)], + styleDim, + getMessageStr(errInstantiationFrom, "")) info = msgContext[i] proc ignoreMsgBecauseOfIdeTools(msg: TMsgKind): bool = @@ -761,29 +796,29 @@ proc ignoreMsgBecauseOfIdeTools(msg: TMsgKind): bool = proc rawMessage*(msg: TMsgKind, args: openArray[string]) = var - frmt: string + title: string color: ForegroundColor case msg of errMin..errMax: writeContext(unknownLineInfo()) - frmt = RawError - color = fgRed + title = ErrorTitle + color = ErrorColor of warnMin..warnMax: if optWarns notin gOptions: return if msg notin gNotes: return writeContext(unknownLineInfo()) - frmt = RawWarning + title = WarningTitle + color = WarningColor inc(gWarnCounter) - color = fgYellow of hintMin..hintMax: if optHints notin gOptions: return if msg notin gNotes: return - frmt = RawHint + title = HintTitle + color = HintColor inc(gHintCounter) - color = fgGreen let s = `%`(msgKindToString(msg), args) if not ignoreMsgBecauseOfIdeTools(msg): - msgWriteln(s, color, frmt) + styledMsgWriteln(color, title, resetStyle, s) handleError(msg, doAbort, s) proc rawMessage*(msg: TMsgKind, arg: string) = @@ -795,47 +830,49 @@ proc writeSurroundingSrc(info: TLineInfo) = msgWriteln(indent & spaces(info.col) & '^') proc formatMsg*(info: TLineInfo, msg: TMsgKind, arg: string): string = - let frmt = case msg - of warnMin..warnMax: PosWarningFormat - of hintMin..hintMax: PosHintFormat - else: PosErrorFormat - result = frmt % [toMsgFilename(info), coordToStr(info.line), - coordToStr(info.col+1), getMessageStr(msg, arg)] + let title = case msg + of warnMin..warnMax: WarningTitle + of hintMin..hintMax: HintTitle + else: ErrorTitle + result = PosFormat % [toMsgFilename(info), coordToStr(info.line), + coordToStr(info.col+1)] & + title & + getMessageStr(msg, arg) proc liMessage(info: TLineInfo, msg: TMsgKind, arg: string, eh: TErrorHandling) = var - frmt: string + title: string ignoreMsg = false color: ForegroundColor case msg of errMin..errMax: writeContext(info) - frmt = PosErrorFormat + title = ErrorTitle + color = ErrorColor # we try to filter error messages so that not two error message # in the same file and line are produced: #ignoreMsg = lastError == info and eh != doAbort lastError = info - color = fgRed of warnMin..warnMax: ignoreMsg = optWarns notin gOptions or msg notin gNotes if not ignoreMsg: writeContext(info) - frmt = PosWarningFormat + title = WarningTitle + color = WarningColor inc(gWarnCounter) - color = fgYellow of hintMin..hintMax: ignoreMsg = optHints notin gOptions or msg notin gNotes - frmt = PosHintFormat + title = HintTitle + color = HintColor inc(gHintCounter) - color = fgGreen # NOTE: currently line info line numbers start with 1, # but column numbers start with 0, however most editors expect # first column to be 1, so we need to +1 here - let x = frmt % [toMsgFilename(info), coordToStr(info.line), - coordToStr(info.col+1)] + let x = PosFormat % [toMsgFilename(info), coordToStr(info.line), + coordToStr(info.col+1)] let s = getMessageStr(msg, arg) if not ignoreMsg and not ignoreMsgBecauseOfIdeTools(msg): - msgWriteln(s, color, x) + styledMsgWriteln(styleBright, x, resetStyle, color, title, resetStyle, s) if optPrintSurroundingSrc and msg in errMin..errMax: info.writeSurroundingSrc handleError(msg, eh, s)