]> git.ipfire.org Git - thirdparty/git.git/blobdiff - color.c
Sync with 2.34.7
[thirdparty/git.git] / color.c
diff --git a/color.c b/color.c
index 64f52a4f93a21c4abe5e40e8957ec6115ca46c2a..4f884c6b3dc1d98c99d3b5e5be0e990f58434d8e 100644 (file)
--- a/color.c
+++ b/color.c
@@ -40,7 +40,7 @@ struct color {
        enum {
                COLOR_UNSPECIFIED = 0,
                COLOR_NORMAL,
-               COLOR_ANSI, /* basic 0-7 ANSI colors */
+               COLOR_ANSI, /* basic 0-7 ANSI colors + "default" (value = 9) */
                COLOR_256,
                COLOR_RGB
        } type;
@@ -83,6 +83,27 @@ static int parse_ansi_color(struct color *out, const char *name, int len)
        int i;
        int color_offset = COLOR_FOREGROUND_ANSI;
 
+       if (match_word(name, len, "default")) {
+               /*
+                * Restores to the terminal's default color, which may not be
+                * the same as explicitly setting "white" or "black".
+                *
+                * ECMA-48 - Control Functions \
+                *  for Coded Character Sets, 5th edition (June 1991):
+                * > 39 default display colour (implementation-defined)
+                * > 49 default background colour (implementation-defined)
+                *
+                * Although not supported /everywhere/--according to terminfo,
+                * some terminals define "op" (original pair) as a blunt
+                * "set to white on black", or even "send full SGR reset"--
+                * it's standard and well-supported enough that if a user
+                * asks for it in their config this will do the right thing.
+                */
+               out->type = COLOR_ANSI;
+               out->value = 9 + color_offset;
+               return 0;
+       }
+
        if (strncasecmp(name, "bright", 6) == 0) {
                color_offset = COLOR_FOREGROUND_BRIGHT_ANSI;
                name += 6;
@@ -234,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 };
@@ -248,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 };
@@ -270,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;
@@ -295,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))