Merge branch 'jk/ansi-color'
The output coloring scheme learned two new attributes, italic and strike, in addition to existing bold, reverse, etc. * jk/ansi-color: color: support strike-through attribute color: support "italic" attribute color: allow "no-" for negating attributes color: refactor parse_attr add skip_prefix_mem helper doc: refactor description of color format color: fix max-size comment
This commit is contained in:
commit
3c5de5c77b
@ -150,27 +150,34 @@ integer::
|
|||||||
1024", "by 1024x1024", etc.
|
1024", "by 1024x1024", etc.
|
||||||
|
|
||||||
color::
|
color::
|
||||||
The value for a variables that takes a color is a list of
|
The value for a variable that takes a color is a list of
|
||||||
colors (at most two) and attributes (at most one), separated
|
colors (at most two, one for foreground and one for background)
|
||||||
by spaces. The colors accepted are `normal`, `black`,
|
and attributes (as many as you want), separated by spaces.
|
||||||
`red`, `green`, `yellow`, `blue`, `magenta`, `cyan` and
|
|
||||||
`white`; the attributes are `bold`, `dim`, `ul`, `blink` and
|
|
||||||
`reverse`. The first color given is the foreground; the
|
|
||||||
second is the background. The position of the attribute, if
|
|
||||||
any, doesn't matter. Attributes may be turned off specifically
|
|
||||||
by prefixing them with `no` (e.g., `noreverse`, `noul`, etc).
|
|
||||||
+
|
+
|
||||||
Colors (foreground and background) may also be given as numbers between
|
The basic colors accepted are `normal`, `black`, `red`, `green`, `yellow`,
|
||||||
0 and 255; these use ANSI 256-color mode (but note that not all
|
`blue`, `magenta`, `cyan` and `white`. The first color given is the
|
||||||
terminals may support this). If your terminal supports it, you may also
|
foreground; the second is the background.
|
||||||
specify 24-bit RGB values as hex, like `#ff0ab3`.
|
|
||||||
+
|
+
|
||||||
The attributes are meant to be reset at the beginning of each item
|
Colors may also be given as numbers between 0 and 255; these use ANSI
|
||||||
in the colored output, so setting color.decorate.branch to `black`
|
256-color mode (but note that not all terminals may support this). If
|
||||||
will paint that branch name in a plain `black`, even if the previous
|
your terminal supports it, you may also specify 24-bit RGB values as
|
||||||
thing on the same output line (e.g. opening parenthesis before the
|
hex, like `#ff0ab3`.
|
||||||
list of branch names in `log --decorate` output) is set to be
|
+
|
||||||
painted with `bold` or some other attribute.
|
The accepted attributes are `bold`, `dim`, `ul`, `blink`, `reverse`,
|
||||||
|
`italic`, and `strike` (for crossed-out or "strikethrough" letters).
|
||||||
|
The position of any attributes with respect to the colors
|
||||||
|
(before, after, or in between), doesn't matter. Specific attributes may
|
||||||
|
be turned off by prefixing them with `no` or `no-` (e.g., `noreverse`,
|
||||||
|
`no-ul`, etc).
|
||||||
|
+
|
||||||
|
For git's pre-defined color slots, the attributes are meant to be reset
|
||||||
|
at the beginning of each item in the colored output. So setting
|
||||||
|
`color.decorate.branch` to `black` will paint that branch name in a
|
||||||
|
plain `black`, even if the previous thing on the same output line (e.g.
|
||||||
|
opening parenthesis before the list of branch names in `log --decorate`
|
||||||
|
output) is set to be painted with `bold` or some other attribute.
|
||||||
|
However, custom log formats may do more complicated and layered
|
||||||
|
coloring, and the negated forms may be useful there.
|
||||||
|
|
||||||
pathname::
|
pathname::
|
||||||
A variable that takes a pathname value can be given a
|
A variable that takes a pathname value can be given a
|
||||||
|
35
color.c
35
color.c
@ -123,19 +123,34 @@ static int parse_color(struct color *out, const char *name, int len)
|
|||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int parse_attr(const char *name, int len)
|
static int parse_attr(const char *name, size_t len)
|
||||||
{
|
{
|
||||||
static const int attr_values[] = { 1, 2, 4, 5, 7,
|
static const struct {
|
||||||
22, 22, 24, 25, 27 };
|
const char *name;
|
||||||
static const char * const attr_names[] = {
|
size_t len;
|
||||||
"bold", "dim", "ul", "blink", "reverse",
|
int val, neg;
|
||||||
"nobold", "nodim", "noul", "noblink", "noreverse"
|
} attrs[] = {
|
||||||
|
#define ATTR(x, val, neg) { (x), sizeof(x)-1, (val), (neg) }
|
||||||
|
ATTR("bold", 1, 22),
|
||||||
|
ATTR("dim", 2, 22),
|
||||||
|
ATTR("italic", 3, 23),
|
||||||
|
ATTR("ul", 4, 24),
|
||||||
|
ATTR("blink", 5, 25),
|
||||||
|
ATTR("reverse", 7, 27),
|
||||||
|
ATTR("strike", 9, 29)
|
||||||
|
#undef ATTR
|
||||||
};
|
};
|
||||||
|
int negate = 0;
|
||||||
int i;
|
int i;
|
||||||
for (i = 0; i < ARRAY_SIZE(attr_names); i++) {
|
|
||||||
const char *str = attr_names[i];
|
if (skip_prefix_mem(name, len, "no", &name, &len)) {
|
||||||
if (!strncasecmp(name, str, len) && !str[len])
|
skip_prefix_mem(name, len, "-", &name, &len);
|
||||||
return attr_values[i];
|
negate = 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
for (i = 0; i < ARRAY_SIZE(attrs); i++) {
|
||||||
|
if (attrs[i].len == len && !memcmp(attrs[i].name, name, len))
|
||||||
|
return negate ? attrs[i].neg : attrs[i].val;
|
||||||
}
|
}
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
15
color.h
15
color.h
@ -3,20 +3,23 @@
|
|||||||
|
|
||||||
struct strbuf;
|
struct strbuf;
|
||||||
|
|
||||||
/* 2 + (2 * num_attrs) + 8 + 1 + 8 + 'm' + NUL */
|
|
||||||
/* "\033[1;2;4;5;7;38;5;2xx;48;5;2xxm\0" */
|
|
||||||
/*
|
/*
|
||||||
* The maximum length of ANSI color sequence we would generate:
|
* The maximum length of ANSI color sequence we would generate:
|
||||||
* - leading ESC '[' 2
|
* - leading ESC '[' 2
|
||||||
* - attr + ';' 3 * 10 (e.g. "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;")
|
* - fg color + ';' 17 (e.g. "38;2;255;255;255;")
|
||||||
* - bg color + ';' 17 (e.g. "48;2;255;255;255;")
|
* - bg color + ';' 17 (e.g. "48;2;255;255;255;")
|
||||||
* - terminating 'm' NUL 2
|
* - terminating 'm' NUL 2
|
||||||
*
|
*
|
||||||
* The above overcounts attr (we only use 5 not 8) and one semicolon
|
* The above overcounts by one semicolon but it is close enough.
|
||||||
* but it is close enough.
|
*
|
||||||
|
* The space for attributes is also slightly overallocated, as
|
||||||
|
* the negation for some attributes is the same (e.g., nobold and nodim).
|
||||||
|
*
|
||||||
|
* We allocate space for 7 attributes.
|
||||||
*/
|
*/
|
||||||
#define COLOR_MAXLEN 70
|
#define COLOR_MAXLEN 75
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* IMPORTANT: Due to the way these color codes are emulated on Windows,
|
* IMPORTANT: Due to the way these color codes are emulated on Windows,
|
||||||
|
@ -473,6 +473,23 @@ static inline int skip_prefix(const char *str, const char *prefix,
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Like skip_prefix, but promises never to read past "len" bytes of the input
|
||||||
|
* buffer, and returns the remaining number of bytes in "out" via "outlen".
|
||||||
|
*/
|
||||||
|
static inline int skip_prefix_mem(const char *buf, size_t len,
|
||||||
|
const char *prefix,
|
||||||
|
const char **out, size_t *outlen)
|
||||||
|
{
|
||||||
|
size_t prefix_len = strlen(prefix);
|
||||||
|
if (prefix_len <= len && !memcmp(buf, prefix, prefix_len)) {
|
||||||
|
*out = buf + prefix_len;
|
||||||
|
*outlen = len - prefix_len;
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* If buf ends with suffix, return 1 and subtract the length of the suffix
|
* If buf ends with suffix, return 1 and subtract the length of the suffix
|
||||||
* from *len. Otherwise, return 0 and leave *len untouched.
|
* from *len. Otherwise, return 0 and leave *len untouched.
|
||||||
|
@ -50,14 +50,19 @@ test_expect_success 'attr negation' '
|
|||||||
color "nobold nodim noul noblink noreverse" "[22;24;25;27m"
|
color "nobold nodim noul noblink noreverse" "[22;24;25;27m"
|
||||||
'
|
'
|
||||||
|
|
||||||
|
test_expect_success '"no-" variant of negation' '
|
||||||
|
color "no-bold no-blink" "[22;25m"
|
||||||
|
'
|
||||||
|
|
||||||
test_expect_success 'long color specification' '
|
test_expect_success 'long color specification' '
|
||||||
color "254 255 bold dim ul blink reverse" "[1;2;4;5;7;38;5;254;48;5;255m"
|
color "254 255 bold dim ul blink reverse" "[1;2;4;5;7;38;5;254;48;5;255m"
|
||||||
'
|
'
|
||||||
|
|
||||||
test_expect_success 'absurdly long color specification' '
|
test_expect_success 'absurdly long color specification' '
|
||||||
color \
|
color \
|
||||||
"#ffffff #ffffff bold nobold dim nodim ul noul blink noblink reverse noreverse" \
|
"#ffffff #ffffff bold nobold dim nodim italic noitalic
|
||||||
"[1;2;4;5;7;22;24;25;27;38;2;255;255;255;48;2;255;255;255m"
|
ul noul blink noblink reverse noreverse strike nostrike" \
|
||||||
|
"[1;2;3;4;5;7;9;22;23;24;25;27;29;38;2;255;255;255;48;2;255;255;255m"
|
||||||
'
|
'
|
||||||
|
|
||||||
test_expect_success '0-7 are aliases for basic ANSI color names' '
|
test_expect_success '0-7 are aliases for basic ANSI color names' '
|
||||||
|
Loading…
Reference in New Issue
Block a user