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:
parent
1057770ce5
commit
2ba3642544
1 changed files with 90 additions and 53 deletions
|
|
@ -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)
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue