Skip to content

Commit

Permalink
Improve compatibility with 16-color terminals.
Browse files Browse the repository at this point in the history
Fish assumed that you could use tparm setaf/bg as long
as the color was under 16 without even checking terminfo.

Now, we will always let tparm take care of a color if it
can. It will never use tparm if the terminal indicates a lack
of support. When tparm cannot safely take care of this, we
construct the escape ourselves. Now, fish no longer makes
such a assumption, either, that it can use a fancy 256-color
format for colors 0-16 when tparm can't do it natively.
Add an intermediate formatter that can handle colors 0-16.

That fixes the issue when tparm was pushed beyond its limits:

env TERM='linux' ./fish -c 'set_color --background brred | xxd'

... and producing bogus escape output.

Restores harmony to white, black ANSI color names and removes "grey".

Fixes fish-shell#3176
  • Loading branch information
Aaron Gyes committed Jul 21, 2016
1 parent 2fa4bd8 commit 016807a
Show file tree
Hide file tree
Showing 2 changed files with 18 additions and 12 deletions.
6 changes: 3 additions & 3 deletions src/color.cpp
Expand Up @@ -161,8 +161,8 @@ static const named_color_t named_colors[] = {
{L"magenta", 5, {0xFF, 0, 0xFF}},
{L"purple", 5, {0xFF, 0, 0xFF}},
{L"cyan", 6, {0, 0xFF, 0xFF}},
{L"grey", 7, {0xE5, 0xE5, 0xE5}},
{L"brgrey", 8, {0x55, 0x55, 0x55}},
{L"white", 7, {0xE5, 0xE5, 0xE5}},
{L"brblack", 8, {0x55, 0x55, 0x55}},
{L"brred", 9, {0xFF, 0x55, 0x55}},
{L"brgreen", 10, {0x55, 0xFF, 0x55}},
{L"brbrown", 11, {0xFF, 0xFF, 0x55}},
Expand All @@ -171,7 +171,7 @@ static const named_color_t named_colors[] = {
{L"brmagenta", 13, {0xFF, 0x55, 0xFF}},
{L"brpurple", 13, {0xFF, 0x55, 0xFF}},
{L"brcyan", 14, {0x55, 0xFF, 0xFF}},
{L"white", 15, {0xFF, 0xFF, 0xFF}},
{L"brwhite", 15, {0xFF, 0xFF, 0xFF}},
};

wcstring_list_t rgb_color_t::named_color_names(void) {
Expand Down
24 changes: 15 additions & 9 deletions src/output.cpp
Expand Up @@ -44,8 +44,8 @@ void output_set_writer(int (*writer)(char)) {

int (*output_get_writer())(char) { return out; }

// Returns true if we think the term256 support is "native" as opposed to forced.
static bool term256_support_is_native(void) { return max_colors >= 256; }
/// Returns true if we think tparm can handle outputting a color index
static bool term_supports_color_natively(unsigned int c) { return max_colors >= c; }

color_support_t output_get_color_support(void) { return color_support; }

Expand All @@ -59,15 +59,22 @@ unsigned char index_for_color(rgb_color_t c) {
}

static bool write_color_escape(char *todo, unsigned char idx, bool is_fg) {
bool result = false;
if (idx < 16 || term256_support_is_native()) {
if (term_supports_color_natively(idx)) {
// Use tparm to emit color escape.
writembs(tparm(todo, idx));
result = true;
return true;
} else {
// We are attempting to bypass the term here. Generate the ANSI escape sequence ourself.
char buff[128] = "";
snprintf(buff, sizeof buff, "\x1b[%d;5;%dm", is_fg ? 38 : 48, idx);
char buff[64] = "";
if (idx < 16) {
// 30-37 select foreground color, 40-47 background. \e%d for dim, \e%d;1 for bright
snprintf(buff, sizeof buff, "\x1b[%d%sm",
is_fg ? 30 + ((idx > 8) ? idx - 8 : idx) :
40 + ((idx > 8) ? idx - 8 : idx),
idx < 8 ? "" : ";1");
} else {
snprintf(buff, sizeof buff, "\x1b[%d;5;%dm", is_fg ? 38 : 48, idx);
}

int (*writer)(char) = output_get_writer();
if (writer) {
Expand All @@ -76,9 +83,8 @@ static bool write_color_escape(char *todo, unsigned char idx, bool is_fg) {
}
}

result = true;
return true;
}
return result;
}

static bool write_foreground_color(unsigned char idx) {
Expand Down

0 comments on commit 016807a

Please sign in to comment.