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.
This commit is contained in:
Adam Strzelecki 2015-06-11 21:46:17 +02:00
commit 2ba3642544

View file

@ -8,7 +8,7 @@
# #
import import
options, strutils, os, tables, ropes, platform, terminal options, strutils, os, tables, ropes, platform, terminal, macros
type type
TMsgKind* = enum TMsgKind* = enum
@ -605,13 +605,15 @@ proc suggestQuit*() =
# this format is understood by many text editors: it is the same that # this format is understood by many text editors: it is the same that
# Borland and Freepascal use # Borland and Freepascal use
const const
PosErrorFormat* = "$1($2, $3) Error: " PosFormat = "$1($2, $3) "
PosWarningFormat* = "$1($2, $3) Warning: " ErrorTitle = "Error: "
PosHintFormat* = "$1($2, $3) Hint: " ErrorColor = fgRed
PosContextFormat = "$1($2, $3) Info: " WarningTitle = "Warning: "
RawError* = "Error: " WarningColor = fgYellow
RawWarning* = "Warning: " HintTitle = "Hint: "
RawHint* = "Hint: " HintColor = fgGreen
InfoTitle = "Info: "
InfoColor = fgCyan
proc getInfoContextLen*(): int = return msgContext.len proc getInfoContextLen*(): int = return msgContext.len
proc setInfoContextLen*(L: int) = setLen(msgContext, L) proc setInfoContextLen*(L: int) = setLen(msgContext, L)
@ -686,27 +688,58 @@ proc outWriteln*(s: string) =
## Writes to stdout. Always. ## Writes to stdout. Always.
if eStdOut in errorOutputs: writeln(stdout, s) if eStdOut in errorOutputs: writeln(stdout, s)
proc msgWriteln*(s: string, color: ForegroundColor = fgWhite, coloredText: string = "") = proc msgWriteln*(s: string) =
## Writes to stdout. If --stderr option is given, writes to stderr instead. ## Writes to stdout. If --stdout option is given, writes to stderr instead.
#if gCmd == cmdIdeTools and optCDebug notin gGlobalOptions: return #if gCmd == cmdIdeTools and optCDebug notin gGlobalOptions: return
var hasColor = optUseColors in gGlobalOptions
if not isNil(writelnHook): if not isNil(writelnHook):
writelnHook(coloredText & s) writelnHook(s)
elif optStdout in gGlobalOptions:
if eStdErr in errorOutputs: writeln(stderr, s)
else: else:
if optStdout in gGlobalOptions: if eStdOut in errorOutputs: writeln(stdout, s)
if eStdErr in errorOutputs:
if hasColor: setForegroundColor(color) macro callIgnoringStyle(theProc: typed, first: typed,
write(stderr, coloredText) args: varargs[expr]): stmt =
if hasColor: resetAttributes() let typForegroundColor = bindSym"ForegroundColor".getType
writeln(stderr, s) 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: else:
if eStdOut in errorOutputs: if eStdOut in errorOutputs:
if hasColor: setForegroundColor(color) if optUseColors in gGlobalOptions:
write(stdout, coloredText) callStyledEcho(args)
if hasColor: resetAttributes() else:
writeln(stdout, s) callIgnoringStyle(writeln, stdout, args)
proc coordToStr(coord: int): string = proc coordToStr(coord: int): string =
if coord == -1: result = "???" if coord == -1: result = "???"
@ -728,7 +761,7 @@ proc handleError(msg: TMsgKind, eh: TErrorHandling, s: string) =
if stackTraceAvailable() and isNil(writelnHook): if stackTraceAvailable() and isNil(writelnHook):
writeStackTrace() writeStackTrace()
else: else:
msgWriteln("", fgRed, "No stack traceback available\nTo create a stacktrace, rerun compilation with ./koch temp " & options.command & " <file>") styledMsgWriteln(fgRed, "No stack traceback available\nTo create a stacktrace, rerun compilation with ./koch temp " & options.command & " <file>")
quit 1 quit 1
if msg >= fatalMin and msg <= fatalMax: if msg >= fatalMin and msg <= fatalMax:
@ -750,10 +783,12 @@ proc writeContext(lastinfo: TLineInfo) =
var info = lastinfo var info = lastinfo
for i in countup(0, len(msgContext) - 1): for i in countup(0, len(msgContext) - 1):
if msgContext[i] != lastinfo and msgContext[i] != info: if msgContext[i] != lastinfo and msgContext[i] != info:
msgWriteln(PosContextFormat % [toMsgFilename(msgContext[i]), styledMsgWriteln(styleBright,
PosFormat % [toMsgFilename(msgContext[i]),
coordToStr(msgContext[i].line), coordToStr(msgContext[i].line),
coordToStr(msgContext[i].col+1), coordToStr(msgContext[i].col+1)],
getMessageStr(errInstantiationFrom, "")]) styleDim,
getMessageStr(errInstantiationFrom, ""))
info = msgContext[i] info = msgContext[i]
proc ignoreMsgBecauseOfIdeTools(msg: TMsgKind): bool = proc ignoreMsgBecauseOfIdeTools(msg: TMsgKind): bool =
@ -761,29 +796,29 @@ proc ignoreMsgBecauseOfIdeTools(msg: TMsgKind): bool =
proc rawMessage*(msg: TMsgKind, args: openArray[string]) = proc rawMessage*(msg: TMsgKind, args: openArray[string]) =
var var
frmt: string title: string
color: ForegroundColor color: ForegroundColor
case msg case msg
of errMin..errMax: of errMin..errMax:
writeContext(unknownLineInfo()) writeContext(unknownLineInfo())
frmt = RawError title = ErrorTitle
color = fgRed color = ErrorColor
of warnMin..warnMax: of warnMin..warnMax:
if optWarns notin gOptions: return if optWarns notin gOptions: return
if msg notin gNotes: return if msg notin gNotes: return
writeContext(unknownLineInfo()) writeContext(unknownLineInfo())
frmt = RawWarning title = WarningTitle
color = WarningColor
inc(gWarnCounter) inc(gWarnCounter)
color = fgYellow
of hintMin..hintMax: of hintMin..hintMax:
if optHints notin gOptions: return if optHints notin gOptions: return
if msg notin gNotes: return if msg notin gNotes: return
frmt = RawHint title = HintTitle
color = HintColor
inc(gHintCounter) inc(gHintCounter)
color = fgGreen
let s = `%`(msgKindToString(msg), args) let s = `%`(msgKindToString(msg), args)
if not ignoreMsgBecauseOfIdeTools(msg): if not ignoreMsgBecauseOfIdeTools(msg):
msgWriteln(s, color, frmt) styledMsgWriteln(color, title, resetStyle, s)
handleError(msg, doAbort, s) handleError(msg, doAbort, s)
proc rawMessage*(msg: TMsgKind, arg: string) = proc rawMessage*(msg: TMsgKind, arg: string) =
@ -795,47 +830,49 @@ proc writeSurroundingSrc(info: TLineInfo) =
msgWriteln(indent & spaces(info.col) & '^') msgWriteln(indent & spaces(info.col) & '^')
proc formatMsg*(info: TLineInfo, msg: TMsgKind, arg: string): string = proc formatMsg*(info: TLineInfo, msg: TMsgKind, arg: string): string =
let frmt = case msg let title = case msg
of warnMin..warnMax: PosWarningFormat of warnMin..warnMax: WarningTitle
of hintMin..hintMax: PosHintFormat of hintMin..hintMax: HintTitle
else: PosErrorFormat else: ErrorTitle
result = frmt % [toMsgFilename(info), coordToStr(info.line), result = PosFormat % [toMsgFilename(info), coordToStr(info.line),
coordToStr(info.col+1), getMessageStr(msg, arg)] coordToStr(info.col+1)] &
title &
getMessageStr(msg, arg)
proc liMessage(info: TLineInfo, msg: TMsgKind, arg: string, proc liMessage(info: TLineInfo, msg: TMsgKind, arg: string,
eh: TErrorHandling) = eh: TErrorHandling) =
var var
frmt: string title: string
ignoreMsg = false ignoreMsg = false
color: ForegroundColor color: ForegroundColor
case msg case msg
of errMin..errMax: of errMin..errMax:
writeContext(info) writeContext(info)
frmt = PosErrorFormat title = ErrorTitle
color = ErrorColor
# we try to filter error messages so that not two error message # we try to filter error messages so that not two error message
# in the same file and line are produced: # in the same file and line are produced:
#ignoreMsg = lastError == info and eh != doAbort #ignoreMsg = lastError == info and eh != doAbort
lastError = info lastError = info
color = fgRed
of warnMin..warnMax: of warnMin..warnMax:
ignoreMsg = optWarns notin gOptions or msg notin gNotes ignoreMsg = optWarns notin gOptions or msg notin gNotes
if not ignoreMsg: writeContext(info) if not ignoreMsg: writeContext(info)
frmt = PosWarningFormat title = WarningTitle
color = WarningColor
inc(gWarnCounter) inc(gWarnCounter)
color = fgYellow
of hintMin..hintMax: of hintMin..hintMax:
ignoreMsg = optHints notin gOptions or msg notin gNotes ignoreMsg = optHints notin gOptions or msg notin gNotes
frmt = PosHintFormat title = HintTitle
color = HintColor
inc(gHintCounter) inc(gHintCounter)
color = fgGreen
# NOTE: currently line info line numbers start with 1, # NOTE: currently line info line numbers start with 1,
# but column numbers start with 0, however most editors expect # but column numbers start with 0, however most editors expect
# first column to be 1, so we need to +1 here # first column to be 1, so we need to +1 here
let x = frmt % [toMsgFilename(info), coordToStr(info.line), let x = PosFormat % [toMsgFilename(info), coordToStr(info.line),
coordToStr(info.col+1)] coordToStr(info.col+1)]
let s = getMessageStr(msg, arg) let s = getMessageStr(msg, arg)
if not ignoreMsg and not ignoreMsgBecauseOfIdeTools(msg): 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: if optPrintSurroundingSrc and msg in errMin..errMax:
info.writeSurroundingSrc info.writeSurroundingSrc
handleError(msg, eh, s) handleError(msg, eh, s)