pretty: add %C(auto) for auto-coloring
authorNguyễn Thái Ngọc Duy <pclouds@gmail.com>
Thu, 18 Apr 2013 23:08:49 +0000 (09:08 +1000)
committerJunio C Hamano <gitster@pobox.com>
Thu, 18 Apr 2013 23:28:28 +0000 (16:28 -0700)
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>
Documentation/pretty-formats.txt
pretty.c

index 6bde67e..bad627a 100644 (file)
@@ -156,7 +156,8 @@ The placeholders are:
   adding `auto,` at the beginning will emit color only when colors are
   enabled for log output (by `color.diff`, `color.ui`, or `--color`, and
   respecting the `auto` settings of the former if we are going to a
-  terminal)
+  terminal). `auto` alone (i.e. `%C(auto)`) will turn on auto coloring
+  on the next placeholders until the color is switched again.
 - '%m': left, right or boundary mark
 - '%n': newline
 - '%%': a raw '%'
index e0413e3..3612f82 100644 (file)
--- a/pretty.c
+++ b/pretty.c
@@ -778,6 +778,7 @@ struct format_commit_context {
        char *message;
        char *commit_encoding;
        size_t width, indent1, indent2;
+       int auto_color;
 
        /* These offsets are relative to the start of the commit message. */
        struct chunk author;
@@ -1005,7 +1006,20 @@ static size_t format_commit_one(struct strbuf *sb, /* in UTF-8 */
        /* these are independent of the commit */
        switch (placeholder[0]) {
        case 'C':
-               return parse_color(sb, placeholder, c);
+               if (!prefixcmp(placeholder + 1, "(auto)")) {
+                       c->auto_color = 1;
+                       return 7; /* consumed 7 bytes, "C(auto)" */
+               } else {
+                       int ret = parse_color(sb, placeholder, c);
+                       if (ret)
+                               c->auto_color = 0;
+                       /*
+                        * Otherwise, we decided to treat %C<unknown>
+                        * as a literal string, and the previous
+                        * %C(auto) is still valid.
+                        */
+                       return ret;
+               }
        case 'n':               /* newline */
                strbuf_addch(sb, '\n');
                return 1;
@@ -1051,13 +1065,19 @@ static size_t format_commit_one(struct strbuf *sb, /* in UTF-8 */
 
        switch (placeholder[0]) {
        case 'H':               /* commit hash */
+               strbuf_addstr(sb, diff_get_color(c->auto_color, DIFF_COMMIT));
                strbuf_addstr(sb, sha1_to_hex(commit->object.sha1));
+               strbuf_addstr(sb, diff_get_color(c->auto_color, DIFF_RESET));
                return 1;
        case 'h':               /* abbreviated commit hash */
-               if (add_again(sb, &c->abbrev_commit_hash))
+               strbuf_addstr(sb, diff_get_color(c->auto_color, DIFF_COMMIT));
+               if (add_again(sb, &c->abbrev_commit_hash)) {
+                       strbuf_addstr(sb, diff_get_color(c->auto_color, DIFF_RESET));
                        return 1;
+               }
                strbuf_addstr(sb, find_unique_abbrev(commit->object.sha1,
                                                     c->pretty_ctx->abbrev));
+               strbuf_addstr(sb, diff_get_color(c->auto_color, DIFF_RESET));
                c->abbrev_commit_hash.len = sb->len - c->abbrev_commit_hash.off;
                return 1;
        case 'T':               /* tree hash */
@@ -1095,7 +1115,7 @@ static size_t format_commit_one(struct strbuf *sb, /* in UTF-8 */
                return 1;
        case 'd':
                load_ref_decorations(DECORATE_SHORT_REFS);
-               format_decorations(sb, commit, 0);
+               format_decorations(sb, commit, c->auto_color);
                return 1;
        case 'g':               /* reflog info */
                switch(placeholder[1]) {