Merge branch 'rs/grep-color-words'
authorJunio C Hamano <gitster@pobox.com>
Fri, 31 Oct 2014 18:49:37 +0000 (11:49 -0700)
committerJunio C Hamano <gitster@pobox.com>
Fri, 31 Oct 2014 18:49:47 +0000 (11:49 -0700)
Allow painting or not painting (partial) matches in context lines
when showing "grep -C<num>" output in color.

* rs/grep-color-words:
grep: add color.grep.matchcontext and color.grep.matchselected

Documentation/config.txt
grep.c
grep.h
t/t7810-grep.sh
index 8212897cf19aa5515cb388be33e57fd432c8419b..7a3294d947cc2c89b23733c2498561536789484e 100644 (file)
@@ -885,7 +885,11 @@ color.grep.<slot>::
 `linenumber`;;
        line number prefix (when using `-n`)
 `match`;;
-       matching text
+       matching text (same as setting `matchContext` and `matchSelected`)
+`matchContext`;;
+       matching text in context lines
+`matchSelected`;;
+       matching text in selected lines
 `selected`;;
        non-matching text in selected lines
 `separator`;;
diff --git a/grep.c b/grep.c
index 4dc31ea38656f72c51bae96155053cd1cd0f6d64..6e085f829731146c319fff57da0ae482de97ff77 100644 (file)
--- a/grep.c
+++ b/grep.c
@@ -35,7 +35,8 @@ void init_grep_defaults(void)
        strcpy(opt->color_filename, "");
        strcpy(opt->color_function, "");
        strcpy(opt->color_lineno, "");
-       strcpy(opt->color_match, GIT_COLOR_BOLD_RED);
+       strcpy(opt->color_match_context, GIT_COLOR_BOLD_RED);
+       strcpy(opt->color_match_selected, GIT_COLOR_BOLD_RED);
        strcpy(opt->color_selected, "");
        strcpy(opt->color_sep, GIT_COLOR_CYAN);
        opt->color = -1;
@@ -101,12 +102,22 @@ int grep_config(const char *var, const char *value, void *cb)
                color = opt->color_function;
        else if (!strcmp(var, "color.grep.linenumber"))
                color = opt->color_lineno;
-       else if (!strcmp(var, "color.grep.match"))
-               color = opt->color_match;
+       else if (!strcmp(var, "color.grep.matchcontext"))
+               color = opt->color_match_context;
+       else if (!strcmp(var, "color.grep.matchselected"))
+               color = opt->color_match_selected;
        else if (!strcmp(var, "color.grep.selected"))
                color = opt->color_selected;
        else if (!strcmp(var, "color.grep.separator"))
                color = opt->color_sep;
+       else if (!strcmp(var, "color.grep.match")) {
+               int rc = 0;
+               if (!value)
+                       return config_error_nonbool(var);
+               rc |= color_parse(value, opt->color_match_context);
+               rc |= color_parse(value, opt->color_match_selected);
+               return rc;
+       }
 
        if (color) {
                if (!value)
@@ -144,7 +155,8 @@ void grep_init(struct grep_opt *opt, const char *prefix)
        strcpy(opt->color_filename, def->color_filename);
        strcpy(opt->color_function, def->color_function);
        strcpy(opt->color_lineno, def->color_lineno);
-       strcpy(opt->color_match, def->color_match);
+       strcpy(opt->color_match_context, def->color_match_context);
+       strcpy(opt->color_match_selected, def->color_match_selected);
        strcpy(opt->color_selected, def->color_selected);
        strcpy(opt->color_sep, def->color_sep);
 }
@@ -1084,7 +1096,7 @@ static void show_line(struct grep_opt *opt, char *bol, char *eol,
                      const char *name, unsigned lno, char sign)
 {
        int rest = eol - bol;
-       char *line_color = NULL;
+       const char *match_color, *line_color = NULL;
 
        if (opt->file_break && opt->last_shown == 0) {
                if (opt->show_hunk_mark)
@@ -1122,6 +1134,10 @@ static void show_line(struct grep_opt *opt, char *bol, char *eol,
                int ch = *eol;
                int eflags = 0;
 
+               if (sign == ':')
+                       match_color = opt->color_match_selected;
+               else
+                       match_color = opt->color_match_context;
                if (sign == ':')
                        line_color = opt->color_selected;
                else if (sign == '-')
@@ -1135,8 +1151,7 @@ static void show_line(struct grep_opt *opt, char *bol, char *eol,
 
                        output_color(opt, bol, match.rm_so, line_color);
                        output_color(opt, bol + match.rm_so,
-                                    match.rm_eo - match.rm_so,
-                                    opt->color_match);
+                                    match.rm_eo - match.rm_so, match_color);
                        bol += match.rm_eo;
                        rest -= match.rm_eo;
                        eflags = REG_NOTBOL;
diff --git a/grep.h b/grep.h
index eaaced19737dfd46e718779cecadc352ff8d5f69..95f197a8d9bfc2a264530d17fcfa90f68dfa840d 100644 (file)
--- a/grep.h
+++ b/grep.h
@@ -124,7 +124,8 @@ struct grep_opt {
        char color_filename[COLOR_MAXLEN];
        char color_function[COLOR_MAXLEN];
        char color_lineno[COLOR_MAXLEN];
-       char color_match[COLOR_MAXLEN];
+       char color_match_context[COLOR_MAXLEN];
+       char color_match_selected[COLOR_MAXLEN];
        char color_selected[COLOR_MAXLEN];
        char color_sep[COLOR_MAXLEN];
        int regflags;
index 40615debc42479970c6a38565b71227bcf7f27c8..028ffe4a05c066c112655822a351b64ed80f9c99 100755 (executable)
@@ -1202,4 +1202,98 @@ test_expect_success LIBPCRE 'grep -P "^ "' '
        test_cmp expected actual
 '
 
+cat >expected <<EOF
+space-line without leading space1
+space: line <RED>with <RESET>leading space1
+space: line <RED>with <RESET>leading <RED>space2<RESET>
+space: line <RED>with <RESET>leading space3
+space:line without leading <RED>space2<RESET>
+EOF
+
+test_expect_success 'grep --color -e A -e B with context' '
+       test_config color.grep.context          normal &&
+       test_config color.grep.filename         normal &&
+       test_config color.grep.function         normal &&
+       test_config color.grep.linenumber       normal &&
+       test_config color.grep.matchContext     normal &&
+       test_config color.grep.matchSelected    red &&
+       test_config color.grep.selected         normal &&
+       test_config color.grep.separator        normal &&
+
+       git grep --color=always -C2 -e "with " -e space2  space |
+       test_decode_color >actual &&
+       test_cmp expected actual
+'
+
+cat >expected <<EOF
+space-line without leading space1
+space- line with leading space1
+space: line <RED>with <RESET>leading <RED>space2<RESET>
+space- line with leading space3
+space-line without leading space2
+EOF
+
+test_expect_success 'grep --color -e A --and -e B with context' '
+       test_config color.grep.context          normal &&
+       test_config color.grep.filename         normal &&
+       test_config color.grep.function         normal &&
+       test_config color.grep.linenumber       normal &&
+       test_config color.grep.matchContext     normal &&
+       test_config color.grep.matchSelected    red &&
+       test_config color.grep.selected         normal &&
+       test_config color.grep.separator        normal &&
+
+       git grep --color=always -C2 -e "with " --and -e space2  space |
+       test_decode_color >actual &&
+       test_cmp expected actual
+'
+
+cat >expected <<EOF
+space-line without leading space1
+space: line <RED>with <RESET>leading space1
+space- line with leading space2
+space: line <RED>with <RESET>leading space3
+space-line without leading space2
+EOF
+
+test_expect_success 'grep --color -e A --and --not -e B with context' '
+       test_config color.grep.context          normal &&
+       test_config color.grep.filename         normal &&
+       test_config color.grep.function         normal &&
+       test_config color.grep.linenumber       normal &&
+       test_config color.grep.matchContext     normal &&
+       test_config color.grep.matchSelected    red &&
+       test_config color.grep.selected         normal &&
+       test_config color.grep.separator        normal &&
+
+       git grep --color=always -C2 -e "with " --and --not -e space2  space |
+       test_decode_color >actual &&
+       test_cmp expected actual
+'
+
+cat >expected <<EOF
+hello.c-#include <stdio.h>
+hello.c=int main(int argc, const char **argv)
+hello.c-{
+hello.c:       pr<RED>int<RESET>f("<RED>Hello<RESET> world.\n");
+hello.c-       return 0;
+hello.c-       /* char ?? */
+hello.c-}
+EOF
+
+test_expect_success 'grep --color -e A --and -e B -p with context' '
+       test_config color.grep.context          normal &&
+       test_config color.grep.filename         normal &&
+       test_config color.grep.function         normal &&
+       test_config color.grep.linenumber       normal &&
+       test_config color.grep.matchContext     normal &&
+       test_config color.grep.matchSelected    red &&
+       test_config color.grep.selected         normal &&
+       test_config color.grep.separator        normal &&
+
+       git grep --color=always -p -C3 -e int --and -e Hello --no-index hello.c |
+       test_decode_color >actual &&
+       test_cmp expected actual
+'
+
 test_done