diff --git a/Documentation/config.txt b/Documentation/config.txt index ab26963d6..aa881fca1 100644 --- a/Documentation/config.txt +++ b/Documentation/config.txt @@ -860,7 +860,11 @@ color.grep.:: `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 c66803473..f950651ae 100644 --- 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; @@ -96,12 +97,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); + color_parse(value, var, opt->color_match_context); + color_parse(value, var, opt->color_match_selected); + return rc; + } if (color) { if (!value) @@ -139,7 +150,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); } @@ -1079,7 +1091,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) @@ -1117,6 +1129,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 == '-') @@ -1130,8 +1146,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 eaaced197..95f197a8d 100644 --- 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; diff --git a/t/t7810-grep.sh b/t/t7810-grep.sh index f698001c9..e3eeaf988 100755 --- a/t/t7810-grep.sh +++ b/t/t7810-grep.sh @@ -1195,4 +1195,98 @@ test_expect_success LIBPCRE 'grep -P "^ "' ' test_cmp expected actual ' +cat >expected <with leading space1 +space: line with leading space2 +space: line with leading space3 +space:line without leading space2 +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 <with leading space2 +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 <with leading space1 +space- line with leading space2 +space: line with 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 < +hello.c=int main(int argc, const char **argv) +hello.c-{ +hello.c: printf("Hello 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