Skip to content

Commit 0476228

Browse files
committed
Merge branch 'jc/color-attrs' into maint
* jc/color-attrs: color: allow multiple attributes
2 parents bcbbe4f + 8b12413 commit 0476228

File tree

3 files changed

+41
-14
lines changed

3 files changed

+41
-14
lines changed

color.c

Lines changed: 16 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -47,7 +47,7 @@ void color_parse_mem(const char *value, int value_len, const char *var,
4747
{
4848
const char *ptr = value;
4949
int len = value_len;
50-
int attr = -1;
50+
unsigned int attr = 0;
5151
int fg = -2;
5252
int bg = -2;
5353

@@ -56,7 +56,7 @@ void color_parse_mem(const char *value, int value_len, const char *var,
5656
return;
5757
}
5858

59-
/* [fg [bg]] [attr] */
59+
/* [fg [bg]] [attr]... */
6060
while (len > 0) {
6161
const char *word = ptr;
6262
int val, wordlen = 0;
@@ -85,19 +85,27 @@ void color_parse_mem(const char *value, int value_len, const char *var,
8585
goto bad;
8686
}
8787
val = parse_attr(word, wordlen);
88-
if (val < 0 || attr != -1)
88+
if (0 <= val)
89+
attr |= (1 << val);
90+
else
8991
goto bad;
90-
attr = val;
9192
}
9293

93-
if (attr >= 0 || fg >= 0 || bg >= 0) {
94+
if (attr || fg >= 0 || bg >= 0) {
9495
int sep = 0;
96+
int i;
9597

9698
*dst++ = '\033';
9799
*dst++ = '[';
98-
if (attr >= 0) {
99-
*dst++ = '0' + attr;
100-
sep++;
100+
101+
for (i = 0; attr; i++) {
102+
unsigned bit = (1 << i);
103+
if (!(attr & bit))
104+
continue;
105+
attr &= ~bit;
106+
if (sep++)
107+
*dst++ = ';';
108+
*dst++ = '0' + i;
101109
}
102110
if (fg >= 0) {
103111
if (sep++)

color.h

Lines changed: 14 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,20 @@
11
#ifndef COLOR_H
22
#define COLOR_H
33

4-
/* "\033[1;38;5;2xx;48;5;2xxm\0" is 23 bytes */
5-
#define COLOR_MAXLEN 24
4+
/* 2 + (2 * num_attrs) + 8 + 1 + 8 + 'm' + NUL */
5+
/* "\033[1;2;4;5;7;38;5;2xx;48;5;2xxm\0" */
6+
/*
7+
* The maximum length of ANSI color sequence we would generate:
8+
* - leading ESC '[' 2
9+
* - attr + ';' 2 * 8 (e.g. "1;")
10+
* - fg color + ';' 9 (e.g. "38;5;2xx;")
11+
* - fg color + ';' 9 (e.g. "48;5;2xx;")
12+
* - terminating 'm' NUL 2
13+
*
14+
* The above overcounts attr (we only use 5 not 8) and one semicolon
15+
* but it is close enough.
16+
*/
17+
#define COLOR_MAXLEN 40
618

719
/*
820
* IMPORTANT: Due to the way these color codes are emulated on Windows,

t/t4026-color.sh

Lines changed: 11 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -8,14 +8,13 @@ test_description='Test diff/status color escape codes'
88

99
color()
1010
{
11-
git config diff.color.new "$1" &&
12-
test "`git config --get-color diff.color.new`" = "$2"
11+
actual=$(git config --get-color no.such.slot "$1") &&
12+
test "$actual" = "$2"
1313
}
1414

1515
invalid_color()
1616
{
17-
git config diff.color.new "$1" &&
18-
test -z "`git config --get-color diff.color.new 2>/dev/null`"
17+
test_must_fail git config --get-color no.such.slot "$1"
1918
}
2019

2120
test_expect_success 'reset' '
@@ -42,6 +41,14 @@ test_expect_success 'fg bg attr' '
4241
color "blue red ul" "[4;34;41m"
4342
'
4443

44+
test_expect_success 'fg bg attr...' '
45+
color "blue bold dim ul blink reverse" "[1;2;4;5;7;34m"
46+
'
47+
48+
test_expect_success 'long color specification' '
49+
color "254 255 bold dim ul blink reverse" "[1;2;4;5;7;38;5;254;48;5;255m"
50+
'
51+
4552
test_expect_success '256 colors' '
4653
color "254 bold 255" "[1;38;5;254;48;5;255m"
4754
'

0 commit comments

Comments
 (0)