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;
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;
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 };
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 };
len--;
}
+ if (match_word(word, wordlen, "reset")) {
+ has_reset = 1;
+ continue;
+ }
+
if (!parse_color(&c, word, wordlen)) {
if (fg.type == COLOR_UNSPECIFIED) {
fg = c;
*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))