Skip to content

Commit 79a7710

Browse files
rscharfegitster
authored andcommitted
grep: add color.grep.matchcontext and color.grep.matchselected
The config option color.grep.match can be used to specify the highlighting color for matching strings. Add the options matchContext and matchSelected to allow different colors to be specified for matching strings in the context vs. in selected lines. This is similar to the ms and mc specifiers in GNU grep's environment variable GREP_COLORS. Tests are from Zoltan Klinger's earlier attempt to solve the same issue in a different way. Signed-off-by: Rene Scharfe <[email protected]> Signed-off-by: Junio C Hamano <[email protected]>
1 parent eeff891 commit 79a7710

File tree

4 files changed

+123
-9
lines changed

4 files changed

+123
-9
lines changed

Documentation/config.txt

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -860,7 +860,11 @@ color.grep.<slot>::
860860
`linenumber`;;
861861
line number prefix (when using `-n`)
862862
`match`;;
863-
matching text
863+
matching text (same as setting `matchContext` and `matchSelected`)
864+
`matchContext`;;
865+
matching text in context lines
866+
`matchSelected`;;
867+
matching text in selected lines
864868
`selected`;;
865869
non-matching text in selected lines
866870
`separator`;;

grep.c

Lines changed: 22 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -35,7 +35,8 @@ void init_grep_defaults(void)
3535
strcpy(opt->color_filename, "");
3636
strcpy(opt->color_function, "");
3737
strcpy(opt->color_lineno, "");
38-
strcpy(opt->color_match, GIT_COLOR_BOLD_RED);
38+
strcpy(opt->color_match_context, GIT_COLOR_BOLD_RED);
39+
strcpy(opt->color_match_selected, GIT_COLOR_BOLD_RED);
3940
strcpy(opt->color_selected, "");
4041
strcpy(opt->color_sep, GIT_COLOR_CYAN);
4142
opt->color = -1;
@@ -96,12 +97,22 @@ int grep_config(const char *var, const char *value, void *cb)
9697
color = opt->color_function;
9798
else if (!strcmp(var, "color.grep.linenumber"))
9899
color = opt->color_lineno;
99-
else if (!strcmp(var, "color.grep.match"))
100-
color = opt->color_match;
100+
else if (!strcmp(var, "color.grep.matchcontext"))
101+
color = opt->color_match_context;
102+
else if (!strcmp(var, "color.grep.matchselected"))
103+
color = opt->color_match_selected;
101104
else if (!strcmp(var, "color.grep.selected"))
102105
color = opt->color_selected;
103106
else if (!strcmp(var, "color.grep.separator"))
104107
color = opt->color_sep;
108+
else if (!strcmp(var, "color.grep.match")) {
109+
int rc = 0;
110+
if (!value)
111+
return config_error_nonbool(var);
112+
color_parse(value, var, opt->color_match_context);
113+
color_parse(value, var, opt->color_match_selected);
114+
return rc;
115+
}
105116

106117
if (color) {
107118
if (!value)
@@ -139,7 +150,8 @@ void grep_init(struct grep_opt *opt, const char *prefix)
139150
strcpy(opt->color_filename, def->color_filename);
140151
strcpy(opt->color_function, def->color_function);
141152
strcpy(opt->color_lineno, def->color_lineno);
142-
strcpy(opt->color_match, def->color_match);
153+
strcpy(opt->color_match_context, def->color_match_context);
154+
strcpy(opt->color_match_selected, def->color_match_selected);
143155
strcpy(opt->color_selected, def->color_selected);
144156
strcpy(opt->color_sep, def->color_sep);
145157
}
@@ -1079,7 +1091,7 @@ static void show_line(struct grep_opt *opt, char *bol, char *eol,
10791091
const char *name, unsigned lno, char sign)
10801092
{
10811093
int rest = eol - bol;
1082-
char *line_color = NULL;
1094+
const char *match_color, *line_color = NULL;
10831095

10841096
if (opt->file_break && opt->last_shown == 0) {
10851097
if (opt->show_hunk_mark)
@@ -1117,6 +1129,10 @@ static void show_line(struct grep_opt *opt, char *bol, char *eol,
11171129
int ch = *eol;
11181130
int eflags = 0;
11191131

1132+
if (sign == ':')
1133+
match_color = opt->color_match_selected;
1134+
else
1135+
match_color = opt->color_match_context;
11201136
if (sign == ':')
11211137
line_color = opt->color_selected;
11221138
else if (sign == '-')
@@ -1130,8 +1146,7 @@ static void show_line(struct grep_opt *opt, char *bol, char *eol,
11301146

11311147
output_color(opt, bol, match.rm_so, line_color);
11321148
output_color(opt, bol + match.rm_so,
1133-
match.rm_eo - match.rm_so,
1134-
opt->color_match);
1149+
match.rm_eo - match.rm_so, match_color);
11351150
bol += match.rm_eo;
11361151
rest -= match.rm_eo;
11371152
eflags = REG_NOTBOL;

grep.h

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -124,7 +124,8 @@ struct grep_opt {
124124
char color_filename[COLOR_MAXLEN];
125125
char color_function[COLOR_MAXLEN];
126126
char color_lineno[COLOR_MAXLEN];
127-
char color_match[COLOR_MAXLEN];
127+
char color_match_context[COLOR_MAXLEN];
128+
char color_match_selected[COLOR_MAXLEN];
128129
char color_selected[COLOR_MAXLEN];
129130
char color_sep[COLOR_MAXLEN];
130131
int regflags;

t/t7810-grep.sh

Lines changed: 94 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1195,4 +1195,98 @@ test_expect_success LIBPCRE 'grep -P "^ "' '
11951195
test_cmp expected actual
11961196
'
11971197

1198+
cat >expected <<EOF
1199+
space-line without leading space1
1200+
space: line <RED>with <RESET>leading space1
1201+
space: line <RED>with <RESET>leading <RED>space2<RESET>
1202+
space: line <RED>with <RESET>leading space3
1203+
space:line without leading <RED>space2<RESET>
1204+
EOF
1205+
1206+
test_expect_success 'grep --color -e A -e B with context' '
1207+
test_config color.grep.context normal &&
1208+
test_config color.grep.filename normal &&
1209+
test_config color.grep.function normal &&
1210+
test_config color.grep.linenumber normal &&
1211+
test_config color.grep.matchContext normal &&
1212+
test_config color.grep.matchSelected red &&
1213+
test_config color.grep.selected normal &&
1214+
test_config color.grep.separator normal &&
1215+
1216+
git grep --color=always -C2 -e "with " -e space2 space |
1217+
test_decode_color >actual &&
1218+
test_cmp expected actual
1219+
'
1220+
1221+
cat >expected <<EOF
1222+
space-line without leading space1
1223+
space- line with leading space1
1224+
space: line <RED>with <RESET>leading <RED>space2<RESET>
1225+
space- line with leading space3
1226+
space-line without leading space2
1227+
EOF
1228+
1229+
test_expect_success 'grep --color -e A --and -e B with context' '
1230+
test_config color.grep.context normal &&
1231+
test_config color.grep.filename normal &&
1232+
test_config color.grep.function normal &&
1233+
test_config color.grep.linenumber normal &&
1234+
test_config color.grep.matchContext normal &&
1235+
test_config color.grep.matchSelected red &&
1236+
test_config color.grep.selected normal &&
1237+
test_config color.grep.separator normal &&
1238+
1239+
git grep --color=always -C2 -e "with " --and -e space2 space |
1240+
test_decode_color >actual &&
1241+
test_cmp expected actual
1242+
'
1243+
1244+
cat >expected <<EOF
1245+
space-line without leading space1
1246+
space: line <RED>with <RESET>leading space1
1247+
space- line with leading space2
1248+
space: line <RED>with <RESET>leading space3
1249+
space-line without leading space2
1250+
EOF
1251+
1252+
test_expect_success 'grep --color -e A --and --not -e B with context' '
1253+
test_config color.grep.context normal &&
1254+
test_config color.grep.filename normal &&
1255+
test_config color.grep.function normal &&
1256+
test_config color.grep.linenumber normal &&
1257+
test_config color.grep.matchContext normal &&
1258+
test_config color.grep.matchSelected red &&
1259+
test_config color.grep.selected normal &&
1260+
test_config color.grep.separator normal &&
1261+
1262+
git grep --color=always -C2 -e "with " --and --not -e space2 space |
1263+
test_decode_color >actual &&
1264+
test_cmp expected actual
1265+
'
1266+
1267+
cat >expected <<EOF
1268+
hello.c-#include <stdio.h>
1269+
hello.c=int main(int argc, const char **argv)
1270+
hello.c-{
1271+
hello.c: pr<RED>int<RESET>f("<RED>Hello<RESET> world.\n");
1272+
hello.c- return 0;
1273+
hello.c- /* char ?? */
1274+
hello.c-}
1275+
EOF
1276+
1277+
test_expect_success 'grep --color -e A --and -e B -p with context' '
1278+
test_config color.grep.context normal &&
1279+
test_config color.grep.filename normal &&
1280+
test_config color.grep.function normal &&
1281+
test_config color.grep.linenumber normal &&
1282+
test_config color.grep.matchContext normal &&
1283+
test_config color.grep.matchSelected red &&
1284+
test_config color.grep.selected normal &&
1285+
test_config color.grep.separator normal &&
1286+
1287+
git grep --color=always -p -C3 -e int --and -e Hello --no-index hello.c |
1288+
test_decode_color >actual &&
1289+
test_cmp expected actual
1290+
'
1291+
11981292
test_done

0 commit comments

Comments
 (0)