aboutsummaryrefslogtreecommitdiff
path: root/src/libutil/terminal.cc
diff options
context:
space:
mode:
Diffstat (limited to 'src/libutil/terminal.cc')
-rw-r--r--src/libutil/terminal.cc23
1 files changed, 18 insertions, 5 deletions
diff --git a/src/libutil/terminal.cc b/src/libutil/terminal.cc
index b58331d04..2ba1cb81b 100644
--- a/src/libutil/terminal.cc
+++ b/src/libutil/terminal.cc
@@ -9,12 +9,25 @@ namespace nix {
bool shouldANSI()
{
- return isatty(STDERR_FILENO)
- && getEnv("TERM").value_or("dumb") != "dumb"
- && !(getEnv("NO_COLOR").has_value() || getEnv("NOCOLOR").has_value());
+ // Implements the behaviour described by https://bixense.com/clicolors/
+ // As well as https://force-color.org/ for compatibility, since it fits in the same shape.
+ // NO_COLOR CLICOLOR CLICOLOR_FORCE Colours?
+ // set x x No
+ // unset x set Yes
+ // unset x unset If attached to a terminal
+ // [we choose the "modern" approach of colour-by-default]
+ auto compute = []() -> bool {
+ bool mustNotColour = getEnv("NO_COLOR").has_value() || getEnv("NOCOLOR").has_value();
+ bool shouldForce = getEnv("CLICOLOR_FORCE").has_value() || getEnv("FORCE_COLOR").has_value();
+ bool isTerminal = isatty(STDERR_FILENO) && getEnv("TERM").value_or("dumb") != "dumb";
+ return !mustNotColour && (shouldForce || isTerminal);
+ };
+ static bool cached = compute();
+ return cached;
}
-std::string filterANSIEscapes(std::string_view s, bool filterAll, unsigned int width)
+// FIXME(jade): replace with TerminalCodeEater. wowie this is evil code.
+std::string filterANSIEscapes(std::string_view s, bool filterAll, unsigned int width, bool eatTabs)
{
std::string t, e;
size_t w = 0;
@@ -43,7 +56,7 @@ std::string filterANSIEscapes(std::string_view s, bool filterAll, unsigned int w
t += e;
}
- else if (*i == '\t') {
+ else if (*i == '\t' && eatTabs) {
i++; t += ' '; w++;
while (w < (size_t) width && w % 8) {
t += ' '; w++;