Add some color

This commit is contained in:
Eelco Dolstra 2014-08-20 16:01:16 +02:00
parent 392430b2c4
commit 373fad75e1
6 changed files with 56 additions and 52 deletions

View file

@ -143,7 +143,7 @@ std::ostream & operator << (std::ostream & str, const Pos & pos)
if (!pos) if (!pos)
str << "undefined position"; str << "undefined position";
else else
str << (format("%1%:%2%:%3%") % pos.file % pos.line % pos.column).str(); str << (format(ANSI_BOLD "%1%" ANSI_NORMAL ":%2%:%3%") % pos.file % pos.line % pos.column).str();
return str; return str;
} }

View file

@ -247,6 +247,7 @@ void showManPage(const string & name)
int handleExceptions(const string & programName, std::function<void()> fun) int handleExceptions(const string & programName, std::function<void()> fun)
{ {
string error = ANSI_RED "error:" ANSI_NORMAL " ";
try { try {
try { try {
fun(); fun();
@ -263,21 +264,19 @@ int handleExceptions(const string & programName, std::function<void()> fun)
return e.status; return e.status;
} catch (UsageError & e) { } catch (UsageError & e) {
printMsg(lvlError, printMsg(lvlError,
format( format(error + " %1%\nTry `%2% --help' for more information.")
"error: %1%\n"
"Try `%2% --help' for more information.")
% e.what() % programName); % e.what() % programName);
return 1; return 1;
} catch (BaseError & e) { } catch (BaseError & e) {
printMsg(lvlError, format("error: %1%%2%") % (settings.showTrace ? e.prefix() : "") % e.msg()); printMsg(lvlError, format(error + "%1%%2%") % (settings.showTrace ? e.prefix() : "") % e.msg());
if (e.prefix() != "" && !settings.showTrace) if (e.prefix() != "" && !settings.showTrace)
printMsg(lvlError, "(use `--show-trace' to show detailed location information)"); printMsg(lvlError, "(use `--show-trace' to show detailed location information)");
return e.status; return e.status;
} catch (std::bad_alloc & e) { } catch (std::bad_alloc & e) {
printMsg(lvlError, "error: out of memory"); printMsg(lvlError, error + "out of memory");
return 1; return 1;
} catch (std::exception & e) { } catch (std::exception & e) {
printMsg(lvlError, format("error: %1%") % e.what()); printMsg(lvlError, error + e.what());
return 1; return 1;
} }

View file

@ -2441,42 +2441,6 @@ void DerivationGoal::deleteTmpDir(bool force)
} }
/* Filter out the special ANSI escape codes generated by Nixpkgs'
stdenv (used to denote nesting etc.). */
static string filterNixEscapes(const string & s)
{
string t, r;
enum { stTop, stEscape, stCSI } state = stTop;
for (auto c : s) {
if (state == stTop) {
if (c == '\e') {
state = stEscape;
r = c;
} else
t += c;
} else if (state == stEscape) {
r += c;
if (c == '[')
state = stCSI;
else {
t += r;
state = stTop;
}
} else {
r += c;
if (c >= 0x40 && c != 0x7e) {
if (c != 'p' && c != 'q' && c != 's' && c != 'a' && c != 'b')
t += r;
state = stTop;
r.clear();
}
}
}
t += r;
return t;
}
void DerivationGoal::handleChildOutput(int fd, const string & data) void DerivationGoal::handleChildOutput(int fd, const string & data)
{ {
if ((hook && fd == hook->builderOut.readSide) || if ((hook && fd == hook->builderOut.readSide) ||
@ -2491,7 +2455,7 @@ void DerivationGoal::handleChildOutput(int fd, const string & data)
return; return;
} }
if (verbosity >= settings.buildVerbosity) if (verbosity >= settings.buildVerbosity)
writeToStderr(filterNixEscapes(data)); writeToStderr(filterANSIEscapes(data, true));
if (bzLogFile) { if (bzLogFile) {
int err; int err;
BZ2_bzWrite(&err, bzLogFile, (unsigned char *) data.data(), data.size()); BZ2_bzWrite(&err, bzLogFile, (unsigned char *) data.data(), data.size());

View file

@ -453,6 +453,7 @@ void printMsg_(Verbosity level, const FormatOrString & fs)
else if (logType == ltEscapes && level != lvlInfo) else if (logType == ltEscapes && level != lvlInfo)
prefix = "\033[" + escVerbosity(level) + "s"; prefix = "\033[" + escVerbosity(level) + "s";
string s = (format("%1%%2%\n") % prefix % fs.s).str(); string s = (format("%1%%2%\n") % prefix % fs.s).str();
if (!isatty(STDERR_FILENO)) s = filterANSIEscapes(s);
writeToStderr(s); writeToStderr(s);
} }
@ -1106,4 +1107,38 @@ void ignoreException()
} }
string filterANSIEscapes(const string & s, bool nixOnly)
{
string t, r;
enum { stTop, stEscape, stCSI } state = stTop;
for (auto c : s) {
if (state == stTop) {
if (c == '\e') {
state = stEscape;
r = c;
} else
t += c;
} else if (state == stEscape) {
r += c;
if (c == '[')
state = stCSI;
else {
t += r;
state = stTop;
}
} else {
r += c;
if (c >= 0x40 && c != 0x7e) {
if (nixOnly && (c != 'p' && c != 'q' && c != 's' && c != 'a' && c != 'b'))
t += r;
state = stTop;
r.clear();
}
}
}
t += r;
return t;
}
} }

View file

@ -369,4 +369,16 @@ string decodeOctalEscaped(const string & s);
void ignoreException(); void ignoreException();
/* Some ANSI escape sequences. */
#define ANSI_NORMAL "\e[0m"
#define ANSI_BOLD "\e[1m"
#define ANSI_RED "\e[31;1m"
/* Filter out ANSI escape codes from the given string. If nixOnly is
set, only filter escape codes generated by Nixpkgs' stdenv (used to
denote nesting etc.). */
string filterANSIEscapes(const string & s, bool nixOnly = false);
} }

View file

@ -847,13 +847,6 @@ static VersionDiff compareVersionAgainstSet(
} }
static string colorString(const string & s)
{
if (!isatty(STDOUT_FILENO)) return s;
return "\e[1;31m" + s + "\e[0m";
}
static void queryJSON(Globals & globals, vector<DrvInfo> & elems) static void queryJSON(Globals & globals, vector<DrvInfo> & elems)
{ {
JSONObject topObj(cout); JSONObject topObj(cout);
@ -1056,7 +1049,8 @@ static void opQuery(Globals & globals, Strings opFlags, Strings opArgs)
} }
} else { } else {
string column = (string) "" + ch + " " + version; string column = (string) "" + ch + " " + version;
if (diff == cvGreater) column = colorString(column); if (diff == cvGreater && isatty(STDOUT_FILENO))
column = ANSI_RED + column + ANSI_NORMAL;
columns.push_back(column); columns.push_back(column);
} }
} }