Merge branch 'es/bright-colors'
The basic 7 colors learned the brighter counterparts (e.g. "brightred"). * es/bright-colors: color.c: alias RGB colors 8-15 to aixterm colors color.c: support bright aixterm colors color.c: refactor color_output arguments
This commit is contained in:
@ -263,7 +263,9 @@ color::
|
|||||||
+
|
+
|
||||||
The basic colors accepted are `normal`, `black`, `red`, `green`, `yellow`,
|
The basic colors accepted are `normal`, `black`, `red`, `green`, `yellow`,
|
||||||
`blue`, `magenta`, `cyan` and `white`. The first color given is the
|
`blue`, `magenta`, `cyan` and `white`. The first color given is the
|
||||||
foreground; the second is the background.
|
foreground; the second is the background. All the basic colors except
|
||||||
|
`normal` have a bright variant that can be speficied by prefixing the
|
||||||
|
color with `bright`, like `brightred`.
|
||||||
+
|
+
|
||||||
Colors may also be given as numbers between 0 and 255; these use ANSI
|
Colors may also be given as numbers between 0 and 255; these use ANSI
|
||||||
256-color mode (but note that not all terminals may support this). If
|
256-color mode (but note that not all terminals may support this). If
|
||||||
|
75
color.c
75
color.c
@ -24,6 +24,14 @@ const char *column_colors_ansi[] = {
|
|||||||
GIT_COLOR_RESET,
|
GIT_COLOR_RESET,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
enum {
|
||||||
|
COLOR_BACKGROUND_OFFSET = 10,
|
||||||
|
COLOR_FOREGROUND_ANSI = 30,
|
||||||
|
COLOR_FOREGROUND_RGB = 38,
|
||||||
|
COLOR_FOREGROUND_256 = 38,
|
||||||
|
COLOR_FOREGROUND_BRIGHT_ANSI = 90,
|
||||||
|
};
|
||||||
|
|
||||||
/* Ignore the RESET at the end when giving the size */
|
/* Ignore the RESET at the end when giving the size */
|
||||||
const int column_colors_ansi_max = ARRAY_SIZE(column_colors_ansi) - 1;
|
const int column_colors_ansi_max = ARRAY_SIZE(column_colors_ansi) - 1;
|
||||||
|
|
||||||
@ -61,15 +69,38 @@ static int get_hex_color(const char *in, unsigned char *out)
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int parse_color(struct color *out, const char *name, int len)
|
/*
|
||||||
|
* If an ANSI color is recognized in "name", fill "out" and return 0.
|
||||||
|
* Otherwise, leave out unchanged and return -1.
|
||||||
|
*/
|
||||||
|
static int parse_ansi_color(struct color *out, const char *name, int len)
|
||||||
{
|
{
|
||||||
/* Positions in array must match ANSI color codes */
|
/* Positions in array must match ANSI color codes */
|
||||||
static const char * const color_names[] = {
|
static const char * const color_names[] = {
|
||||||
"black", "red", "green", "yellow",
|
"black", "red", "green", "yellow",
|
||||||
"blue", "magenta", "cyan", "white"
|
"blue", "magenta", "cyan", "white"
|
||||||
};
|
};
|
||||||
char *end;
|
|
||||||
int i;
|
int i;
|
||||||
|
int color_offset = COLOR_FOREGROUND_ANSI;
|
||||||
|
|
||||||
|
if (strncasecmp(name, "bright", 6) == 0) {
|
||||||
|
color_offset = COLOR_FOREGROUND_BRIGHT_ANSI;
|
||||||
|
name += 6;
|
||||||
|
len -= 6;
|
||||||
|
}
|
||||||
|
for (i = 0; i < ARRAY_SIZE(color_names); i++) {
|
||||||
|
if (match_word(name, len, color_names[i])) {
|
||||||
|
out->type = COLOR_ANSI;
|
||||||
|
out->value = i + color_offset;
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int parse_color(struct color *out, const char *name, int len)
|
||||||
|
{
|
||||||
|
char *end;
|
||||||
long val;
|
long val;
|
||||||
|
|
||||||
/* First try the special word "normal"... */
|
/* First try the special word "normal"... */
|
||||||
@ -89,12 +120,8 @@ static int parse_color(struct color *out, const char *name, int len)
|
|||||||
}
|
}
|
||||||
|
|
||||||
/* Then pick from our human-readable color names... */
|
/* Then pick from our human-readable color names... */
|
||||||
for (i = 0; i < ARRAY_SIZE(color_names); i++) {
|
if (parse_ansi_color(out, name, len) == 0) {
|
||||||
if (match_word(name, len, color_names[i])) {
|
return 0;
|
||||||
out->type = COLOR_ANSI;
|
|
||||||
out->value = i;
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* And finally try a literal 256-color-mode number */
|
/* And finally try a literal 256-color-mode number */
|
||||||
@ -109,10 +136,15 @@ static int parse_color(struct color *out, const char *name, int len)
|
|||||||
else if (val < 0) {
|
else if (val < 0) {
|
||||||
out->type = COLOR_NORMAL;
|
out->type = COLOR_NORMAL;
|
||||||
return 0;
|
return 0;
|
||||||
/* Rewrite low numbers as more-portable standard colors. */
|
/* Rewrite 0-7 as more-portable standard colors. */
|
||||||
} else if (val < 8) {
|
} else if (val < 8) {
|
||||||
out->type = COLOR_ANSI;
|
out->type = COLOR_ANSI;
|
||||||
out->value = val;
|
out->value = val + COLOR_FOREGROUND_ANSI;
|
||||||
|
return 0;
|
||||||
|
/* Rewrite 8-15 as more-portable aixterm colors. */
|
||||||
|
} else if (val < 16) {
|
||||||
|
out->type = COLOR_ANSI;
|
||||||
|
out->value = val - 8 + COLOR_FOREGROUND_BRIGHT_ANSI;
|
||||||
return 0;
|
return 0;
|
||||||
} else if (val < 256) {
|
} else if (val < 256) {
|
||||||
out->type = COLOR_256;
|
out->type = COLOR_256;
|
||||||
@ -166,23 +198,26 @@ int color_parse(const char *value, char *dst)
|
|||||||
* already have the ANSI escape code in it. "out" should have enough
|
* already have the ANSI escape code in it. "out" should have enough
|
||||||
* space in it to fit any color.
|
* space in it to fit any color.
|
||||||
*/
|
*/
|
||||||
static char *color_output(char *out, int len, const struct color *c, char type)
|
static char *color_output(char *out, int len, const struct color *c, int background)
|
||||||
{
|
{
|
||||||
|
int offset = 0;
|
||||||
|
|
||||||
|
if (background)
|
||||||
|
offset = COLOR_BACKGROUND_OFFSET;
|
||||||
switch (c->type) {
|
switch (c->type) {
|
||||||
case COLOR_UNSPECIFIED:
|
case COLOR_UNSPECIFIED:
|
||||||
case COLOR_NORMAL:
|
case COLOR_NORMAL:
|
||||||
break;
|
break;
|
||||||
case COLOR_ANSI:
|
case COLOR_ANSI:
|
||||||
if (len < 2)
|
out += xsnprintf(out, len, "%d", c->value + offset);
|
||||||
BUG("color parsing ran out of space");
|
|
||||||
*out++ = type;
|
|
||||||
*out++ = '0' + c->value;
|
|
||||||
break;
|
break;
|
||||||
case COLOR_256:
|
case COLOR_256:
|
||||||
out += xsnprintf(out, len, "%c8;5;%d", type, c->value);
|
out += xsnprintf(out, len, "%d;5;%d", COLOR_FOREGROUND_256 + offset,
|
||||||
|
c->value);
|
||||||
break;
|
break;
|
||||||
case COLOR_RGB:
|
case COLOR_RGB:
|
||||||
out += xsnprintf(out, len, "%c8;2;%d;%d;%d", type,
|
out += xsnprintf(out, len, "%d;2;%d;%d;%d",
|
||||||
|
COLOR_FOREGROUND_RGB + offset,
|
||||||
c->red, c->green, c->blue);
|
c->red, c->green, c->blue);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
@ -279,14 +314,12 @@ int color_parse_mem(const char *value, int value_len, char *dst)
|
|||||||
if (!color_empty(&fg)) {
|
if (!color_empty(&fg)) {
|
||||||
if (sep++)
|
if (sep++)
|
||||||
OUT(';');
|
OUT(';');
|
||||||
/* foreground colors are all in the 3x range */
|
dst = color_output(dst, end - dst, &fg, 0);
|
||||||
dst = color_output(dst, end - dst, &fg, '3');
|
|
||||||
}
|
}
|
||||||
if (!color_empty(&bg)) {
|
if (!color_empty(&bg)) {
|
||||||
if (sep++)
|
if (sep++)
|
||||||
OUT(';');
|
OUT(';');
|
||||||
/* background colors are all in the 4x range */
|
dst = color_output(dst, end - dst, &bg, 1);
|
||||||
dst = color_output(dst, end - dst, &bg, '4');
|
|
||||||
}
|
}
|
||||||
OUT('m');
|
OUT('m');
|
||||||
}
|
}
|
||||||
|
@ -30,6 +30,14 @@ test_expect_success 'attribute before color name' '
|
|||||||
color "bold red" "[1;31m"
|
color "bold red" "[1;31m"
|
||||||
'
|
'
|
||||||
|
|
||||||
|
test_expect_success 'aixterm bright fg color' '
|
||||||
|
color "brightred" "[91m"
|
||||||
|
'
|
||||||
|
|
||||||
|
test_expect_success 'aixterm bright bg color' '
|
||||||
|
color "green brightblue" "[32;104m"
|
||||||
|
'
|
||||||
|
|
||||||
test_expect_success 'color name before attribute' '
|
test_expect_success 'color name before attribute' '
|
||||||
color "red bold" "[1;31m"
|
color "red bold" "[1;31m"
|
||||||
'
|
'
|
||||||
@ -74,6 +82,10 @@ test_expect_success '0-7 are aliases for basic ANSI color names' '
|
|||||||
color "0 7" "[30;47m"
|
color "0 7" "[30;47m"
|
||||||
'
|
'
|
||||||
|
|
||||||
|
test_expect_success '8-15 are aliases for aixterm color names' '
|
||||||
|
color "12 13" "[94;105m"
|
||||||
|
'
|
||||||
|
|
||||||
test_expect_success '256 colors' '
|
test_expect_success '256 colors' '
|
||||||
color "254 bold 255" "[1;38;5;254;48;5;255m"
|
color "254 bold 255" "[1;38;5;254;48;5;255m"
|
||||||
'
|
'
|
||||||
|
Reference in New Issue
Block a user