@matheusbsbs / matheus-bagliano / commits / 8b124135a9
Fork 0

color: allow multiple attributes

In configuration files (and "git config --color" command line), we supported one and only one attribute after foreground and background color. Accept combinations of attributes, e.g. [diff.color] old = red reverse bold Signed-off-by: Junio C Hamano <gitster@pobox.com>

Junio C Hamano committed Feb 27, 2010 at 18:56 UTC 8b124135a97b593d50a90abcec231552b31c7ade
3 files changed +41 -14
color.c
+16 -8
@@ -49,7 +49,7 @@ void color_parse_mem(const char *value, int value_len, const char *var,
49 {
50 const char *ptr = value;
51 int len = value_len;
52 - int attr = -1;
52 + unsigned int attr = 0;
53 int fg = -2;
54 int bg = -2;
55
@@ -58,7 +58,7 @@ void color_parse_mem(const char *value, int value_len, const char *var,
58 return;
59 }
60
61 - /* [fg [bg]] [attr] */
61 + /* [fg [bg]] [attr]... */
62 while (len > 0) {
63 const char *word = ptr;
64 int val, wordlen = 0;
@@ -87,19 +87,27 @@ void color_parse_mem(const char *value, int value_len, const char *var,
87 goto bad;
88 }
89 val = parse_attr(word, wordlen);
90 - if (val < 0 || attr != -1)
90 + if (0 <= val)
91 + attr |= (1 << val);
92 + else
93 goto bad;
92 - attr = val;
94 }
95
95 - if (attr >= 0 || fg >= 0 || bg >= 0) {
96 + if (attr || fg >= 0 || bg >= 0) {
97 int sep = 0;
98 + int i;
99
100 *dst++ = '\033';
101 *dst++ = '[';
100 - if (attr >= 0) {
101 - *dst++ = '0' + attr;
102 - sep++;
102 +
103 + for (i = 0; attr; i++) {
104 + unsigned bit = (1 << i);
105 + if (!(attr & bit))
106 + continue;
107 + attr &= ~bit;
108 + if (sep++)
109 + *dst++ = ';';
110 + *dst++ = '0' + i;
111 }
112 if (fg >= 0) {
113 if (sep++)
color.h
+14 -2
@@ -1,8 +1,20 @@
1 #ifndef COLOR_H
2 #define COLOR_H
3
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
18
19 /*
20 * This variable stores the value of color.ui
t/t4026-color.sh
+11 -4
@@ -8,14 +8,13 @@ test_description='Test diff/status color escape codes'
8
9 color()
10 {
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"
13 }
14
15 invalid_color()
16 {
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"
18 }
19
20 test_expect_success 'reset' '
@@ -42,6 +41,14 @@ test_expect_success 'fg bg attr' '
41 color "blue red ul" "[4;34;41m"
42 '
43
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 +
52 test_expect_success '256 colors' '
53 color "254 bold 255" "[1;38;5;254;48;5;255m"
54 '