pretty: add %C(auto) for auto-coloring

This is not simply convenient over %C(auto,xxx). Some placeholders (actually only one, %d) do multi coloring and we can't emit a multiple colors with %C(auto,xxx). Signed-off-by: Nguyễn Thái Ngọc Duy <pclouds@gmail.com> Signed-off-by: Junio C Hamano <gitster@pobox.com>

Nguyễn Thái Ngọc Duy committed Apr 19, 2013 at 09:08 UTC a95f067e3fc2b7c50c69680ac10bef528b160446
2 files changed +25 -4
Documentation/pretty-formats.txt
+2 -1
@@ -156,7 +156,8 @@ The placeholders are:
156 adding `auto,` at the beginning will emit color only when colors are
157 enabled for log output (by `color.diff`, `color.ui`, or `--color`, and
158 respecting the `auto` settings of the former if we are going to a
159 - terminal)
159 + terminal). `auto` alone (i.e. `%C(auto)`) will turn on auto coloring
160 + on the next placeholders until the color is switched again.
161 - '%m': left, right or boundary mark
162 - '%n': newline
163 - '%%': a raw '%'
pretty.c
+23 -3
@@ -778,6 +778,7 @@ struct format_commit_context {
778 char *message;
779 char *commit_encoding;
780 size_t width, indent1, indent2;
781 + int auto_color;
782
783 /* These offsets are relative to the start of the commit message. */
784 struct chunk author;
@@ -1005,7 +1006,20 @@ static size_t format_commit_one(struct strbuf *sb, /* in UTF-8 */
1006 /* these are independent of the commit */
1007 switch (placeholder[0]) {
1008 case 'C':
1008 - return parse_color(sb, placeholder, c);
1009 + if (!prefixcmp(placeholder + 1, "(auto)")) {
1010 + c->auto_color = 1;
1011 + return 7; /* consumed 7 bytes, "C(auto)" */
1012 + } else {
1013 + int ret = parse_color(sb, placeholder, c);
1014 + if (ret)
1015 + c->auto_color = 0;
1016 + /*
1017 + * Otherwise, we decided to treat %C<unknown>
1018 + * as a literal string, and the previous
1019 + * %C(auto) is still valid.
1020 + */
1021 + return ret;
1022 + }
1023 case 'n': /* newline */
1024 strbuf_addch(sb, '\n');
1025 return 1;
@@ -1051,13 +1065,19 @@ static size_t format_commit_one(struct strbuf *sb, /* in UTF-8 */
1065
1066 switch (placeholder[0]) {
1067 case 'H': /* commit hash */
1068 + strbuf_addstr(sb, diff_get_color(c->auto_color, DIFF_COMMIT));
1069 strbuf_addstr(sb, sha1_to_hex(commit->object.sha1));
1070 + strbuf_addstr(sb, diff_get_color(c->auto_color, DIFF_RESET));
1071 return 1;
1072 case 'h': /* abbreviated commit hash */
1057 - if (add_again(sb, &c->abbrev_commit_hash))
1073 + strbuf_addstr(sb, diff_get_color(c->auto_color, DIFF_COMMIT));
1074 + if (add_again(sb, &c->abbrev_commit_hash)) {
1075 + strbuf_addstr(sb, diff_get_color(c->auto_color, DIFF_RESET));
1076 return 1;
1077 + }
1078 strbuf_addstr(sb, find_unique_abbrev(commit->object.sha1,
1079 c->pretty_ctx->abbrev));
1080 + strbuf_addstr(sb, diff_get_color(c->auto_color, DIFF_RESET));
1081 c->abbrev_commit_hash.len = sb->len - c->abbrev_commit_hash.off;
1082 return 1;
1083 case 'T': /* tree hash */
@@ -1095,7 +1115,7 @@ static size_t format_commit_one(struct strbuf *sb, /* in UTF-8 */
1115 return 1;
1116 case 'd':
1117 load_ref_decorations(DECORATE_SHORT_REFS);
1098 - format_decorations(sb, commit, 0);
1118 + format_decorations(sb, commit, c->auto_color);
1119 return 1;
1120 case 'g': /* reflog info */
1121 switch(placeholder[1]) {