diff --git a/Documentation/config.txt b/Documentation/config.txt index 636e722f30..f21790dd76 100644 --- a/Documentation/config.txt +++ b/Documentation/config.txt @@ -288,6 +288,11 @@ The position of any attributes with respect to the colors be turned off by prefixing them with `no` or `no-` (e.g., `noreverse`, `no-ul`, etc). + +The pseudo-attribute `reset` resets all colors and attributes before +applying the specified coloring. For example, `reset green` will result +in a green foreground and default background without any active +attributes. ++ An empty color string produces no color effect at all. This can be used to avoid coloring specific elements without disabling color entirely. + diff --git a/color.c b/color.c index a5fa9b79a7..4f884c6b3d 100644 --- a/color.c +++ b/color.c @@ -255,6 +255,7 @@ int color_parse_mem(const char *value, int value_len, char *dst) const char *ptr = value; int len = value_len; char *end = dst + COLOR_MAXLEN; + unsigned int has_reset = 0; unsigned int attr = 0; struct color fg = { COLOR_UNSPECIFIED }; struct color bg = { COLOR_UNSPECIFIED }; @@ -269,12 +270,7 @@ int color_parse_mem(const char *value, int value_len, char *dst) return 0; } - if (!strncasecmp(ptr, "reset", len)) { - xsnprintf(dst, end - dst, GIT_COLOR_RESET); - return 0; - } - - /* [fg [bg]] [attr]... */ + /* [reset] [fg [bg]] [attr]... */ while (len > 0) { const char *word = ptr; struct color c = { COLOR_UNSPECIFIED }; @@ -291,6 +287,11 @@ int color_parse_mem(const char *value, int value_len, char *dst) len--; } + if (match_word(word, wordlen, "reset")) { + has_reset = 1; + continue; + } + if (!parse_color(&c, word, wordlen)) { if (fg.type == COLOR_UNSPECIFIED) { fg = c; @@ -316,13 +317,16 @@ int color_parse_mem(const char *value, int value_len, char *dst) *dst++ = (x); \ } while(0) - if (attr || !color_empty(&fg) || !color_empty(&bg)) { + if (has_reset || attr || !color_empty(&fg) || !color_empty(&bg)) { int sep = 0; int i; OUT('\033'); OUT('['); + if (has_reset) + sep++; + for (i = 0; attr; i++) { unsigned bit = (1 << i); if (!(attr & bit)) diff --git a/color.h b/color.h index 27e817016b..cfc8f841b2 100644 --- a/color.h +++ b/color.h @@ -6,6 +6,7 @@ struct strbuf; /* * The maximum length of ANSI color sequence we would generate: * - leading ESC '[' 2 + * - reset ';' .................1 * - attr + ';' 2 * num_attr (e.g. "1;") * - no-attr + ';' 3 * num_attr (e.g. "22;") * - fg color + ';' 17 (e.g. "38;2;255;255;255;") diff --git a/t/t4026-color.sh b/t/t4026-color.sh index d6907a66c3..cc3f60d468 100755 --- a/t/t4026-color.sh +++ b/t/t4026-color.sh @@ -60,6 +60,10 @@ test_expect_success 'fg bg attr...' ' color "blue bold dim ul blink reverse" "[1;2;4;5;7;34m" ' +test_expect_success 'reset fg bg attr...' ' + color "reset blue bold dim ul blink reverse" "[;1;2;4;5;7;34m" +' + # note that nobold and nodim are the same code (22) test_expect_success 'attr negation' ' color "nobold nodim noul noblink noreverse" "[22;24;25;27m"