]> git.ipfire.org Git - thirdparty/git.git/commitdiff
color: allow colors to be prefixed with "reset"
authorRobert Estelle <robertestelle@gmail.com>
Tue, 26 Oct 2021 01:03:47 +0000 (01:03 +0000)
committerJunio C Hamano <gitster@pobox.com>
Thu, 28 Oct 2021 16:37:18 +0000 (09:37 -0700)
"reset" was previously treated as a standalone special color name
representing `\e[m`. Now, it can apply to other color properties,
allowing exact specifications without implicit attribute inheritance.

For example, "reset green" now renders `\e[;32m`, which is interpreted
as "reset everything; then set foreground to green". This means the
background and other attributes are also reset to their defaults.

Previously, this was impossible to represent in a single color:
"reset" could be specified alone, or a color with attributes, but some
thing like clearing a background color were impossible.

There is a separate change that introduces the "default" color name to
assist with that, but even then, the above could only to be represented
by explicitly disabling each of the attributes:
  green default no-bold no-dim no-italic no-ul no-blink no-reverse no-strike

Signed-off-by: Robert Estelle <robertestelle@gmail.com>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
Documentation/config.txt
color.c
color.h
t/t4026-color.sh

index 636e722f300b66d6b1b878888d1785eddce12d9d..f21790dd76bc525c3d79e2ad0038ee3a94a27369 100644 (file)
@@ -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 a5fa9b79a7aa4d8c558374dfac34d840e22156fb..4f884c6b3dc1d98c99d3b5e5be0e990f58434d8e 100644 (file)
--- 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 27e817016bf1d371fe91b3c3506967b5828d01d3..cfc8f841b237c72a0a2ea8b7e42d58dc1cab5f9f 100644 (file)
--- 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;")
index d6907a66c3575ec5ab766e232d76390f5bd38c7f..cc3f60d468f4c51e7a6149ce8ef014bdf5a5a92b 100755 (executable)
@@ -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"