Initial work to support for term-24bit ("true color")

This commit is contained in:
ridiculousfish 2014-09-19 15:37:31 -07:00
parent 6083c6fc72
commit 555ff00a30
9 changed files with 61 additions and 28 deletions

View File

@ -125,7 +125,7 @@ bool rgb_color_t::try_parse_rgb(const wcstring &name)
{
int val = parse_hex_digit(name.at(digit_idx++));
if (val < 0) break;
data.rgb[i] = val*16+val;
data.color.rgb[i] = val*16+val;
}
success = (i == 3);
}
@ -137,7 +137,7 @@ bool rgb_color_t::try_parse_rgb(const wcstring &name)
int hi = parse_hex_digit(name.at(digit_idx++));
int lo = parse_hex_digit(name.at(digit_idx++));
if (lo < 0 || hi < 0) break;
data.rgb[i] = hi*16+lo;
data.color.rgb[i] = hi*16+lo;
}
success = (i == 3);
}
@ -298,7 +298,13 @@ static unsigned char term256_color_for_rgb(const unsigned char rgb[3])
unsigned char rgb_color_t::to_term256_index() const
{
assert(type == type_rgb);
return term256_color_for_rgb(data.rgb);
return term256_color_for_rgb(data.color.rgb);
}
color24_t rgb_color_t::to_color24() const
{
assert(type == type_rgb);
return data.color;
}
unsigned char rgb_color_t::to_name_index() const
@ -310,7 +316,7 @@ unsigned char rgb_color_t::to_name_index() const
}
else if (type == type_rgb)
{
return term8_color_for_rgb(data.rgb);
return term8_color_for_rgb(data.color.rgb);
}
else
{
@ -327,7 +333,7 @@ void rgb_color_t::parse(const wcstring &str)
if (! success) success = try_parse_rgb(str);
if (! success)
{
bzero(this->data.rgb, sizeof this->data.rgb);
bzero(&this->data, sizeof this->data);
this->type = type_none;
}
}
@ -351,7 +357,7 @@ wcstring rgb_color_t::description() const
case type_named:
return format_string(L"named(%d: %ls)", (int)data.name_idx, name_for_color_idx(data.name_idx));
case type_rgb:
return format_string(L"rgb(0x%02x%02x%02x)", data.rgb[0], data.rgb[1], data.rgb[2]);
return format_string(L"rgb(0x%02x%02x%02x)", data.color.rgb[0], data.color.rgb[1], data.color.rgb[2]);
case type_reset:
return L"reset";
case type_normal:

11
color.h
View File

@ -8,6 +8,10 @@
#include "config.h"
#include "common.h"
/* 24 bit color */
struct color24_t {
unsigned char rgb[3];
};
/* A type that represents a color. We work hard to keep it at a size of 4 bytes. */
class rgb_color_t
@ -36,7 +40,7 @@ class rgb_color_t
union
{
unsigned char name_idx; //0-10
unsigned char rgb[3];
color24_t color;
} data;
/** Try parsing a special color name like "normal" */
@ -129,9 +133,12 @@ public:
/** Returns the name index for the given color. Requires that the color be named or RGB. */
unsigned char to_name_index() const;
/** Returns the term256 index for the given color. Requires that the color be named or RGB. */
/** Returns the term256 index for the given color. Requires that the color be RGB. */
unsigned char to_term256_index() const;
/** Returns the 24 bit color for the given color. Requires that the color be RGB. */
color24_t to_color24() const;
/** Returns whether the color is bold */
bool is_bold() const
{

View File

@ -325,7 +325,7 @@ static void react_to_variable_change(const wcstring &key)
}
else if (key == L"fish_term256")
{
update_fish_term256();
update_fish_color_support();
reader_react_to_color_change();
}
else if (string_prefixes_string(L"fish_color_", key))

View File

@ -435,7 +435,7 @@ int main(int argc, char **argv)
reader_init();
history_init();
/* For setcolor to support term256 in config.fish (#1022) */
update_fish_term256();
update_fish_color_support();
parser_t &parser = parser_t::principal_parser();

View File

@ -423,7 +423,7 @@ static int interrupt_handler()
return R_NULL;
}
void update_fish_term256(void)
void update_fish_color_support(void)
{
/* Infer term256 support. If fish_term256 is set, we respect it; otherwise try to detect it from the TERM variable */
env_var_t fish_term256 = env_get_string(L"fish_term256");
@ -456,7 +456,20 @@ void update_fish_term256(void)
support_term256 = false;
}
}
output_set_supports_term256(support_term256);
env_var_t fish_term24bit = env_get_string(L"fish_term24bit");
bool support_term24bit;
if (! fish_term24bit.missing_or_empty())
{
support_term24bit = from_string<bool>(fish_term24bit);
}
else
{
support_term24bit = false;
}
color_support_t support = (support_term256 ? color_support_term256 : 0) | (support_term24bit ? color_support_term24bit : 0);
output_set_color_support(support);
}
int input_init()
@ -496,7 +509,7 @@ int input_init()
input_terminfo_init();
update_fish_term256();
update_fish_color_support();
/* If we have no keybindings, add a few simple defaults */
if (mapping_list.empty())

View File

@ -185,8 +185,8 @@ wchar_t input_function_get_code(const wcstring &name);
/** Returns a list of all existing input function names */
wcstring_list_t input_function_get_names(void);
/** Updates our idea of whether we support term256 */
void update_fish_term256();
/** Updates our idea of whether we support term256 and term24bit */
void update_fish_color_support();
#endif

View File

@ -107,8 +107,8 @@ static int (*out)(char c) = &writeb_internal;
*/
static wcstring current_term;
/* Whether term256 is supported */
static bool support_term256 = false;
/* Whether term256 and term24bit are supported */
static color_support_t color_support = 0;
void output_set_writer(int (*writer)(char))
@ -125,22 +125,22 @@ int (*output_get_writer())(char)
static bool term256_support_is_native(void)
{
/* Return YES if we think the term256 support is "native" as opposed to forced. */
return max_colors == 256;
return max_colors >= 256;
}
bool output_get_supports_term256(void)
color_support_t output_get_color_support(void)
{
return support_term256;
return color_support;
}
void output_set_supports_term256(bool val)
void output_set_color_support(color_support_t val)
{
support_term256 = val;
color_support = val;
}
unsigned char index_for_color(rgb_color_t c)
{
if (c.is_named() || ! output_get_supports_term256())
if (c.is_named() || ! (output_get_color_support() & color_support_term256))
{
return c.to_name_index();
}
@ -686,7 +686,8 @@ rgb_color_t parse_color(const wcstring &val, bool is_background)
// If we have both RGB and named colors, then prefer rgb if term256 is supported
rgb_color_t result;
if ((!first_rgb.is_none() && output_get_supports_term256()) || first_named.is_none())
bool has_term256 = !! (output_get_color_support() & color_support_term256);
if ((!first_rgb.is_none() && has_term256) || first_named.is_none())
{
result = first_rgb;
}

View File

@ -134,9 +134,15 @@ void output_set_term(const wcstring &term);
/** Return the terminal name */
const wchar_t *output_get_term();
/** Sets whether term256 colors are supported */
bool output_get_supports_term256();
void output_set_supports_term256(bool val);
/** Sets what colors are supported */
enum
{
color_support_term256 = 1 << 0,
color_support_term24bit = 1 << 1
};
typedef unsigned int color_support_t;
color_support_t output_get_color_support();
void output_set_color_support(color_support_t support);
/* Exported for builtin_set_color's usage only */
bool write_foreground_color(unsigned char idx);

View File

@ -1428,7 +1428,7 @@ void s_reset(screen_t *s, screen_reset_mode_t mode)
int non_space_width = wcwidth(omitted_newline_char);
if (screen_width >= non_space_width)
{
if (output_get_supports_term256())
if (output_get_color_support() & color_support_term256)
{
// draw the string in term256 gray
abandon_line_string.append(L"\x1b[38;5;245m");