mirror of
https://github.com/NixOS/nix
synced 2024-09-19 10:50:24 -04:00
Take ANSI and tree characters into account
This commit is contained in:
parent
abbaba9122
commit
d49e14ba4a
|
@ -1263,6 +1263,46 @@ struct CmdFlakeShow : FlakeCommand, MixJSON
|
||||||
attrPath.size() >= 1 && attrPathS[0] == "hydraJobs" ? "derivation" :
|
attrPath.size() >= 1 && attrPathS[0] == "hydraJobs" ? "derivation" :
|
||||||
"package";
|
"package";
|
||||||
if (description && !description->empty()) {
|
if (description && !description->empty()) {
|
||||||
|
|
||||||
|
// Takes a string and returns the # of characters displayed
|
||||||
|
auto columnLengthOfString = [](std::string_view s) -> unsigned int {
|
||||||
|
unsigned int columnCount = 0;
|
||||||
|
for (auto i = s.begin(); i < s.end();) {
|
||||||
|
// Test first character to determine if it is one of
|
||||||
|
// treeConn, treeLast, treeLine
|
||||||
|
if (*i == -30) {
|
||||||
|
i += 3;
|
||||||
|
++columnCount;
|
||||||
|
}
|
||||||
|
// Escape sequences
|
||||||
|
// https://en.wikipedia.org/wiki/ANSI_escape_code
|
||||||
|
else if (*i == '\e') {
|
||||||
|
// Eat '['
|
||||||
|
if (*(++i) == '[') {
|
||||||
|
++i;
|
||||||
|
// Eat parameter bytes
|
||||||
|
while(*i >= 0x30 && *i <= 0x3f) ++i;
|
||||||
|
|
||||||
|
// Eat intermediate bytes
|
||||||
|
while(*i >= 0x20 && *i <= 0x2f) ++i;
|
||||||
|
|
||||||
|
// Eat final byte
|
||||||
|
if(*i >= 0x40 && *i <= 0x73) ++i;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
// Eat Fe Escape sequence
|
||||||
|
if (*i >= 0x40 && *i <= 0x5f) ++i;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
++i;
|
||||||
|
++columnCount;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return columnCount;
|
||||||
|
};
|
||||||
|
|
||||||
// Maximum length to print
|
// Maximum length to print
|
||||||
size_t maxLength = getWindowSize().second > 0 ? getWindowSize().second : 80;
|
size_t maxLength = getWindowSize().second > 0 ? getWindowSize().second : 80;
|
||||||
|
|
||||||
|
@ -1271,29 +1311,25 @@ struct CmdFlakeShow : FlakeCommand, MixJSON
|
||||||
auto newLinePos = trimmed.find('\n');
|
auto newLinePos = trimmed.find('\n');
|
||||||
auto length = newLinePos != std::string::npos ? newLinePos : trimmed.length();
|
auto length = newLinePos != std::string::npos ? newLinePos : trimmed.length();
|
||||||
|
|
||||||
// Sanitize the description and calculate the two parts of the line
|
|
||||||
// In order to get the length of the printable characters we need to
|
|
||||||
// filter out escape sequences.
|
|
||||||
auto beginningOfLine = fmt("%s: %s '%s'", headerPrefix, type, name);
|
auto beginningOfLine = fmt("%s: %s '%s'", headerPrefix, type, name);
|
||||||
auto beginningOfLineLength = filterANSIEscapes(beginningOfLine, true).length();
|
auto line = fmt("%s: %s '%s' - '%s'", headerPrefix, type, name, trimmed.substr(0, length));
|
||||||
auto restOfLine = fmt(" - '%s'", filterANSIEscapes(trimmed, false, length));
|
|
||||||
|
|
||||||
// If we are already over the maximum length then do not trim
|
// If we are already over the maximum length then do not trim
|
||||||
// and don't print the description (preserves existing behavior)
|
// and don't print the description (preserves existing behavior)
|
||||||
if (beginningOfLineLength >= maxLength) {
|
if (columnLengthOfString(beginningOfLine) >= maxLength) {
|
||||||
logger->cout("%s", beginningOfLine);
|
logger->cout("%s", beginningOfLine);
|
||||||
}
|
}
|
||||||
|
// If the entire line fits then print that
|
||||||
|
else if (columnLengthOfString(line) < maxLength) {
|
||||||
|
logger->cout("%s", line);
|
||||||
|
}
|
||||||
|
// Otherwise we need to truncate
|
||||||
else {
|
else {
|
||||||
auto line = beginningOfLine + restOfLine;
|
auto lineLength = columnLengthOfString(line);
|
||||||
// FIXME: Specifying `true` here gives the correct length
|
auto chopOff = lineLength - maxLength;
|
||||||
// BUT removes colors/bold so something is not quite right here.
|
line.resize(line.length() - chopOff);
|
||||||
line = filterANSIEscapes(line, true, maxLength);
|
line = line.replace(line.length() - 3, 3, "...");
|
||||||
|
|
||||||
// NOTE: This test might be incorrect since I get things like:
|
|
||||||
// 168 or 161 > maxLength.
|
|
||||||
if (line.length() > maxLength) {
|
|
||||||
line = line.replace(line.length() - 3, 3, "...");
|
|
||||||
}
|
|
||||||
logger->cout("%s", line);
|
logger->cout("%s", line);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue