Give the hunk comment its own color
authorBert Wesarg <bert.wesarg@googlemail.com>
Fri, 27 Nov 2009 06:55:18 +0000 (07:55 +0100)
committerJunio C Hamano <gitster@pobox.com>
Sat, 28 Nov 2009 18:05:44 +0000 (10:05 -0800)
Inspired by the coloring of quilt.

Introduce a separate color and paint the hunk comment part, i.e. the name
of the function, in a separate color "diff.func" (defaults to plain).

Whitespace between hunk header and hunk comment is printed in plain color.

Signed-off-by: Bert Wesarg <bert.wesarg@googlemail.com>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
Documentation/config.txt
combine-diff.c
diff.c
diff.h
t/t4034-diff-words.sh

index a8e0876a2add7bb53d3194b1f5e0a2031dd19a42..a1e36d7e423e01de796ac5f866536280618199d1 100644 (file)
@@ -635,10 +635,10 @@ color.diff.<slot>::
        Use customized color for diff colorization.  `<slot>` specifies
        which part of the patch to use the specified color, and is one
        of `plain` (context text), `meta` (metainformation), `frag`
-       (hunk header), `old` (removed lines), `new` (added lines),
-       `commit` (commit headers), or `whitespace` (highlighting
-       whitespace errors). The values of these variables may be specified as
-       in color.branch.<slot>.
+       (hunk header), 'func' (function in hunk header), `old` (removed lines),
+       `new` (added lines), `commit` (commit headers), or `whitespace`
+       (highlighting whitespace errors). The values of these variables may be
+       specified as in color.branch.<slot>.
 
 color.grep::
        When set to `always`, always highlight matches.  When `false` (or
index 5b63af1eeb71907f23117bc552fa7a4019f09722..61626912e3bca2571b41fd1256067470dc170cc1 100644 (file)
@@ -524,6 +524,7 @@ static void dump_sline(struct sline *sline, unsigned long cnt, int num_parent,
        int i;
        unsigned long lno = 0;
        const char *c_frag = diff_get_color(use_color, DIFF_FRAGINFO);
+       const char *c_func = diff_get_color(use_color, DIFF_FUNCINFO);
        const char *c_new = diff_get_color(use_color, DIFF_FILE_NEW);
        const char *c_old = diff_get_color(use_color, DIFF_FILE_OLD);
        const char *c_plain = diff_get_color(use_color, DIFF_PLAIN);
@@ -588,7 +589,9 @@ static void dump_sline(struct sline *sline, unsigned long cnt, int num_parent,
                                    comment_end = i;
                        }
                        if (comment_end)
-                               putchar(' ');
+                               printf("%s%s %s%s", c_reset,
+                                                   c_plain, c_reset,
+                                                   c_func);
                        for (i = 0; i < comment_end; i++)
                                putchar(hunk_comment[i]);
                }
diff --git a/diff.c b/diff.c
index 108c7d76441398386dd887e9ab608262c31286b4..d952686926e2e97aab3e369ad192027b4d7e676b 100644 (file)
--- a/diff.c
+++ b/diff.c
@@ -39,6 +39,7 @@ static char diff_colors[][COLOR_MAXLEN] = {
        GIT_COLOR_GREEN,        /* NEW */
        GIT_COLOR_YELLOW,       /* COMMIT */
        GIT_COLOR_BG_RED,       /* WHITESPACE */
+       GIT_COLOR_NORMAL,       /* FUNCINFO */
 };
 
 static void diff_filespec_load_driver(struct diff_filespec *one);
@@ -60,6 +61,8 @@ static int parse_diff_color_slot(const char *var, int ofs)
                return DIFF_COMMIT;
        if (!strcasecmp(var+ofs, "whitespace"))
                return DIFF_WHITESPACE;
+       if (!strcasecmp(var+ofs, "func"))
+               return DIFF_FUNCINFO;
        die("bad config variable '%s'", var);
 }
 
@@ -345,6 +348,42 @@ static void emit_add_line(const char *reset,
        }
 }
 
+static void emit_hunk_header(struct emit_callback *ecbdata,
+                            const char *line, int len)
+{
+       const char *plain = diff_get_color(ecbdata->color_diff, DIFF_PLAIN);
+       const char *frag = diff_get_color(ecbdata->color_diff, DIFF_FRAGINFO);
+       const char *func = diff_get_color(ecbdata->color_diff, DIFF_FUNCINFO);
+       const char *reset = diff_get_color(ecbdata->color_diff, DIFF_RESET);
+       static const char atat[2] = { '@', '@' };
+       const char *cp, *ep;
+
+       /*
+        * As a hunk header must begin with "@@ -<old>, +<new> @@",
+        * it always is at least 10 bytes long.
+        */
+       if (len < 10 ||
+           memcmp(line, atat, 2) ||
+           !(ep = memmem(line + 2, len - 2, atat, 2))) {
+               emit_line(ecbdata->file, plain, reset, line, len);
+               return;
+       }
+       ep += 2; /* skip over @@ */
+
+       /* The hunk header in fraginfo color */
+       emit_line(ecbdata->file, frag, reset, line, ep - line);
+
+       /* blank before the func header */
+       for (cp = ep; ep - line < len; ep++)
+               if (*ep != ' ' && *ep != '\t')
+                       break;
+       if (ep != cp)
+               emit_line(ecbdata->file, plain, reset, cp, ep - cp);
+
+       if (ep < line + len)
+               emit_line(ecbdata->file, func, reset, ep, line + len - ep);
+}
+
 static struct diff_tempfile *claim_diff_tempfile(void) {
        int i;
        for (i = 0; i < ARRAY_SIZE(diff_temp); i++)
@@ -782,9 +821,7 @@ static void fn_out_consume(void *priv, char *line, unsigned long len)
                        diff_words_flush(ecbdata);
                len = sane_truncate_line(ecbdata, line, len);
                find_lno(line, ecbdata);
-               emit_line(ecbdata->file,
-                         diff_get_color(ecbdata->color_diff, DIFF_FRAGINFO),
-                         reset, line, len);
+               emit_hunk_header(ecbdata, line, len);
                if (line[len-1] != '\n')
                        putc('\n', ecbdata->file);
                return;
diff --git a/diff.h b/diff.h
index 2740421cfe9985a57f61855dc6372e8402231e0e..15fcecdecd9b033700902de44138eafdb66932eb 100644 (file)
--- a/diff.h
+++ b/diff.h
@@ -130,6 +130,7 @@ enum color_diff {
        DIFF_FILE_NEW = 5,
        DIFF_COMMIT = 6,
        DIFF_WHITESPACE = 7,
+       DIFF_FUNCINFO = 8,
 };
 const char *diff_get_color(int diff_use_color, enum color_diff ix);
 #define diff_get_color_opt(o, ix) \
index 2d24fbeda67772e0dd5e3331d74b0befabff272c..1c21276c55400c594f71bc01eba17b0d3820b420 100755 (executable)
@@ -8,6 +8,7 @@ test_expect_success setup '
 
        git config diff.color.old red
        git config diff.color.new green
+       git config diff.color.func magenta
 
 '
 
@@ -16,6 +17,7 @@ decrypt_color () {
                -e 's/.\[1m/<WHITE>/g' \
                -e 's/.\[31m/<RED>/g' \
                -e 's/.\[32m/<GREEN>/g' \
+               -e 's/.\[35m/<MAGENTA>/g' \
                -e 's/.\[36m/<BROWN>/g' \
                -e 's/.\[m/<RESET>/g'
 }
@@ -70,7 +72,7 @@ cat > expect <<\EOF
 <WHITE>+++ b/post<RESET>
 <BROWN>@@ -1 +1 @@<RESET>
 <RED>h(4)<RESET><GREEN>h(4),hh[44]<RESET>
-<BROWN>@@ -3,0 +4,4 @@ a = b + c<RESET>
+<BROWN>@@ -3,0 +4,4 @@<RESET> <RESET><MAGENTA>a = b + c<RESET>
 
 <GREEN>aa = a<RESET>