Skip to content

Commit 87f17d7

Browse files
committed
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
2 parents d0038f4 + c444f03 commit 87f17d7

File tree

3 files changed

+69
-22
lines changed

3 files changed

+69
-22
lines changed

Documentation/config.txt

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -263,7 +263,9 @@ color::
263263
+
264264
The basic colors accepted are `normal`, `black`, `red`, `green`, `yellow`,
265265
`blue`, `magenta`, `cyan` and `white`. The first color given is the
266-
foreground; the second is the background.
266+
foreground; the second is the background. All the basic colors except
267+
`normal` have a bright variant that can be speficied by prefixing the
268+
color with `bright`, like `brightred`.
267269
+
268270
Colors may also be given as numbers between 0 and 255; these use ANSI
269271
256-color mode (but note that not all terminals may support this). If

color.c

Lines changed: 54 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,14 @@ const char *column_colors_ansi[] = {
2424
GIT_COLOR_RESET,
2525
};
2626

27+
enum {
28+
COLOR_BACKGROUND_OFFSET = 10,
29+
COLOR_FOREGROUND_ANSI = 30,
30+
COLOR_FOREGROUND_RGB = 38,
31+
COLOR_FOREGROUND_256 = 38,
32+
COLOR_FOREGROUND_BRIGHT_ANSI = 90,
33+
};
34+
2735
/* Ignore the RESET at the end when giving the size */
2836
const int column_colors_ansi_max = ARRAY_SIZE(column_colors_ansi) - 1;
2937

@@ -61,15 +69,38 @@ static int get_hex_color(const char *in, unsigned char *out)
6169
return 0;
6270
}
6371

64-
static int parse_color(struct color *out, const char *name, int len)
72+
/*
73+
* If an ANSI color is recognized in "name", fill "out" and return 0.
74+
* Otherwise, leave out unchanged and return -1.
75+
*/
76+
static int parse_ansi_color(struct color *out, const char *name, int len)
6577
{
6678
/* Positions in array must match ANSI color codes */
6779
static const char * const color_names[] = {
6880
"black", "red", "green", "yellow",
6981
"blue", "magenta", "cyan", "white"
7082
};
71-
char *end;
7283
int i;
84+
int color_offset = COLOR_FOREGROUND_ANSI;
85+
86+
if (strncasecmp(name, "bright", 6) == 0) {
87+
color_offset = COLOR_FOREGROUND_BRIGHT_ANSI;
88+
name += 6;
89+
len -= 6;
90+
}
91+
for (i = 0; i < ARRAY_SIZE(color_names); i++) {
92+
if (match_word(name, len, color_names[i])) {
93+
out->type = COLOR_ANSI;
94+
out->value = i + color_offset;
95+
return 0;
96+
}
97+
}
98+
return -1;
99+
}
100+
101+
static int parse_color(struct color *out, const char *name, int len)
102+
{
103+
char *end;
73104
long val;
74105

75106
/* First try the special word "normal"... */
@@ -89,12 +120,8 @@ static int parse_color(struct color *out, const char *name, int len)
89120
}
90121

91122
/* Then pick from our human-readable color names... */
92-
for (i = 0; i < ARRAY_SIZE(color_names); i++) {
93-
if (match_word(name, len, color_names[i])) {
94-
out->type = COLOR_ANSI;
95-
out->value = i;
96-
return 0;
97-
}
123+
if (parse_ansi_color(out, name, len) == 0) {
124+
return 0;
98125
}
99126

100127
/* 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)
109136
else if (val < 0) {
110137
out->type = COLOR_NORMAL;
111138
return 0;
112-
/* Rewrite low numbers as more-portable standard colors. */
139+
/* Rewrite 0-7 as more-portable standard colors. */
113140
} else if (val < 8) {
114141
out->type = COLOR_ANSI;
115-
out->value = val;
142+
out->value = val + COLOR_FOREGROUND_ANSI;
143+
return 0;
144+
/* Rewrite 8-15 as more-portable aixterm colors. */
145+
} else if (val < 16) {
146+
out->type = COLOR_ANSI;
147+
out->value = val - 8 + COLOR_FOREGROUND_BRIGHT_ANSI;
116148
return 0;
117149
} else if (val < 256) {
118150
out->type = COLOR_256;
@@ -166,23 +198,26 @@ int color_parse(const char *value, char *dst)
166198
* already have the ANSI escape code in it. "out" should have enough
167199
* space in it to fit any color.
168200
*/
169-
static char *color_output(char *out, int len, const struct color *c, char type)
201+
static char *color_output(char *out, int len, const struct color *c, int background)
170202
{
203+
int offset = 0;
204+
205+
if (background)
206+
offset = COLOR_BACKGROUND_OFFSET;
171207
switch (c->type) {
172208
case COLOR_UNSPECIFIED:
173209
case COLOR_NORMAL:
174210
break;
175211
case COLOR_ANSI:
176-
if (len < 2)
177-
BUG("color parsing ran out of space");
178-
*out++ = type;
179-
*out++ = '0' + c->value;
212+
out += xsnprintf(out, len, "%d", c->value + offset);
180213
break;
181214
case COLOR_256:
182-
out += xsnprintf(out, len, "%c8;5;%d", type, c->value);
215+
out += xsnprintf(out, len, "%d;5;%d", COLOR_FOREGROUND_256 + offset,
216+
c->value);
183217
break;
184218
case COLOR_RGB:
185-
out += xsnprintf(out, len, "%c8;2;%d;%d;%d", type,
219+
out += xsnprintf(out, len, "%d;2;%d;%d;%d",
220+
COLOR_FOREGROUND_RGB + offset,
186221
c->red, c->green, c->blue);
187222
break;
188223
}
@@ -279,14 +314,12 @@ int color_parse_mem(const char *value, int value_len, char *dst)
279314
if (!color_empty(&fg)) {
280315
if (sep++)
281316
OUT(';');
282-
/* foreground colors are all in the 3x range */
283-
dst = color_output(dst, end - dst, &fg, '3');
317+
dst = color_output(dst, end - dst, &fg, 0);
284318
}
285319
if (!color_empty(&bg)) {
286320
if (sep++)
287321
OUT(';');
288-
/* background colors are all in the 4x range */
289-
dst = color_output(dst, end - dst, &bg, '4');
322+
dst = color_output(dst, end - dst, &bg, 1);
290323
}
291324
OUT('m');
292325
}

t/t4026-color.sh

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,14 @@ test_expect_success 'attribute before color name' '
3030
color "bold red" "[1;31m"
3131
'
3232

33+
test_expect_success 'aixterm bright fg color' '
34+
color "brightred" "[91m"
35+
'
36+
37+
test_expect_success 'aixterm bright bg color' '
38+
color "green brightblue" "[32;104m"
39+
'
40+
3341
test_expect_success 'color name before attribute' '
3442
color "red bold" "[1;31m"
3543
'
@@ -74,6 +82,10 @@ test_expect_success '0-7 are aliases for basic ANSI color names' '
7482
color "0 7" "[30;47m"
7583
'
7684

85+
test_expect_success '8-15 are aliases for aixterm color names' '
86+
color "12 13" "[94;105m"
87+
'
88+
7789
test_expect_success '256 colors' '
7890
color "254 bold 255" "[1;38;5;254;48;5;255m"
7991
'

0 commit comments

Comments
 (0)