{"thread":{"id":"37771","subject":"[PATCH] grep: fix match highlighting for combined patterns with context lines","startedAt":"2014-10-21T05:56:03Z","lastAt":"2014-10-28T18:19:46Z","messageCount":12,"participants":["Zoltan Klinger","Junio C Hamano","René Scharfe"],"isPatch":true,"patchVersion":1,"patchTotal":null},"messages":[{"id":"250886","messageId":"1413870963-66431-1-git-send-email-zoltan.klinger@gmail.com","threadId":"37771","inReplyTo":null,"subject":"[PATCH] grep: fix match highlighting for combined patterns with context lines","fromName":"Zoltan Klinger","fromEmail":"zoltan.klinger@gmail.com","sentAt":"2014-10-21T05:56:03Z","receivedAt":"2014-10-21T05:56:03Z","isPatch":true,"sender":{"key":"zoltan.klinger@gmail.com","avatar":"https://avatars.githubusercontent.com/u/95923?v=4"},"body":"When git grep is run with combined patterns such as '-e p1 --and -e p2'\nand surrounding context lines are requested, the output contains\nincorrectly highlighted matches.\n\nConsider the following output (highlighted matches are surrounded by '*'\ncharacters):\n    $ cat testfile\n    foo a\n    foo b\n    foo bar\n    baz bar foo\n    bar x\n    bar y\n    $ git grep -n -C2 -e foo --and -e bar testfile\n    testfile-1-*foo* a\n    testfile-2-*foo* b\n    testfile:3:*foo* *bar*\n    testfile:4:baz *bar* *foo*\n    testfile-5-*bar* x\n    testfile-6-*bar* y\n\nLines 1, 2, 5 and 6 do not match the combined patterns, they only\ncontain incorrectly highlighted 'false positives'.\n\nModify the show_line() function in grep.c to highlight matches only on\nlines that match the combined pattern. Do not highlight matches on lines\nthat provide only context or contain only the function name of the match.\n\nThe output of the same command after the change:\n    $ git grep -n -C2 -e foo --and -e bar testfile\n    testfile-1-foo a\n    testfile-2-foo b\n    testfile:3:*foo* *bar*\n    testfile:4:baz *bar* *foo*\n    testfile-5-bar x\n    testfile-6-bar y\n\nSigned-off-by: Zoltan Klinger <zoltan.klinger@gmail.com>\n---\n grep.c          |  7 +++--\n t/t7810-grep.sh | 90 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++\n 2 files changed, 95 insertions(+), 2 deletions(-)\n\ndiff --git a/grep.c b/grep.c\nindex 4dc31ea..3c4d68e 100644\n--- a/grep.c\n+++ b/grep.c\n@@ -1121,9 +1121,12 @@ static void show_line(struct grep_opt *opt, char *bol, char *eol,\n \t\tenum grep_context ctx = GREP_CONTEXT_BODY;\n \t\tint ch = *eol;\n \t\tint eflags = 0;\n+\t\tchar *match_color = NULL;\n \n-\t\tif (sign == ':')\n+\t\tif (sign == ':') {\n \t\t\tline_color = opt->color_selected;\n+\t\t\tmatch_color = opt->color_match;\n+\t\t}\n \t\telse if (sign == '-')\n \t\t\tline_color = opt->color_context;\n \t\telse if (sign == '=')\n@@ -1136,7 +1139,7 @@ static void show_line(struct grep_opt *opt, char *bol, char *eol,\n \t\t\toutput_color(opt, bol, match.rm_so, line_color);\n \t\t\toutput_color(opt, bol + match.rm_so,\n \t\t\t\t     match.rm_eo - match.rm_so,\n-\t\t\t\t     opt->color_match);\n+\t\t\t\t     match_color);\n \t\t\tbol += match.rm_eo;\n \t\t\trest -= match.rm_eo;\n \t\t\teflags = REG_NOTBOL;\ndiff --git a/t/t7810-grep.sh b/t/t7810-grep.sh\nindex 40615de..b0d6b6f 100755\n--- a/t/t7810-grep.sh\n+++ b/t/t7810-grep.sh\n@@ -1202,4 +1202,94 @@ test_expect_success LIBPCRE 'grep -P \"^ \"' '\n \ttest_cmp expected actual\n '\n \n+cat >expected <<EOF\n+space-line without leading space1\n+space: line <RED>with <RESET>leading space1\n+space: line <RED>with <RESET>leading <RED>space2<RESET>\n+space: line <RED>with <RESET>leading space3\n+space:line without leading <RED>space2<RESET>\n+EOF\n+\n+test_expect_success 'grep --color -e A -e B with context' '\n+\ttest_config color.grep.context\t\tnormal &&\n+\ttest_config color.grep.filename\t\tnormal &&\n+\ttest_config color.grep.function\t\tnormal &&\n+\ttest_config color.grep.linenumber\tnormal &&\n+\ttest_config color.grep.match\t\tred &&\n+\ttest_config color.grep.selected\t\tnormal &&\n+\ttest_config color.grep.separator\tnormal &&\n+\n+\tgit grep --color=always -C2 -e \"with \" -e space2  space |\n+\ttest_decode_color >actual &&\n+\ttest_cmp expected actual\n+'\n+\n+cat >expected <<EOF\n+space-line without leading space1\n+space- line with leading space1\n+space: line <RED>with <RESET>leading <RED>space2<RESET>\n+space- line with leading space3\n+space-line without leading space2\n+EOF\n+\n+test_expect_success 'grep --color -e A --and -e B with context' '\n+\ttest_config color.grep.context\t\tnormal &&\n+\ttest_config color.grep.filename\t\tnormal &&\n+\ttest_config color.grep.function\t\tnormal &&\n+\ttest_config color.grep.linenumber\tnormal &&\n+\ttest_config color.grep.match\t\tred &&\n+\ttest_config color.grep.selected\t\tnormal &&\n+\ttest_config color.grep.separator\tnormal &&\n+\n+\tgit grep --color=always -C2 -e \"with \" --and -e space2  space |\n+\ttest_decode_color >actual &&\n+\ttest_cmp expected actual\n+'\n+\n+cat >expected <<EOF\n+space-line without leading space1\n+space: line <RED>with <RESET>leading space1\n+space- line with leading space2\n+space: line <RED>with <RESET>leading space3\n+space-line without leading space2\n+EOF\n+\n+test_expect_success 'grep --color -e A --and --not -e B with context' '\n+\ttest_config color.grep.context\t\tnormal &&\n+\ttest_config color.grep.filename\t\tnormal &&\n+\ttest_config color.grep.function\t\tnormal &&\n+\ttest_config color.grep.linenumber\tnormal &&\n+\ttest_config color.grep.match\t\tred &&\n+\ttest_config color.grep.selected\t\tnormal &&\n+\ttest_config color.grep.separator\tnormal &&\n+\n+\tgit grep --color=always -C2 -e \"with \" --and --not -e space2  space |\n+\ttest_decode_color >actual &&\n+\ttest_cmp expected actual\n+'\n+\n+cat >expected <<EOF\n+hello.c-#include <stdio.h>\n+hello.c=int main(int argc, const char **argv)\n+hello.c-{\n+hello.c:\tpr<RED>int<RESET>f(\"<RED>Hello<RESET> world.\\n\");\n+hello.c-\treturn 0;\n+hello.c-\t/* char ?? */\n+hello.c-}\n+EOF\n+\n+test_expect_success 'grep --color -e A --and -e B -p with context' '\n+\ttest_config color.grep.context\t\tnormal &&\n+\ttest_config color.grep.filename\t\tnormal &&\n+\ttest_config color.grep.function\t\tnormal &&\n+\ttest_config color.grep.linenumber\tnormal &&\n+\ttest_config color.grep.match\t\tred &&\n+\ttest_config color.grep.selected\t\tnormal &&\n+\ttest_config color.grep.separator\tnormal &&\n+\n+\tgit grep --color=always -p -C3 -e int --and -e Hello --no-index hello.c |\n+\ttest_decode_color >actual &&\n+\ttest_cmp expected actual\n+'\n+\n test_done\n-- \n2.1.1\n"},{"id":"250907","messageId":"xmqqh9yxz0pc.fsf@gitster.dls.corp.google.com","threadId":"37771","inReplyTo":"1413870963-66431-1-git-send-email-zoltan.klinger@gmail.com","subject":"Re: [PATCH] grep: fix match highlighting for combined patterns with context lines","fromName":"Junio C Hamano","fromEmail":"gitster@pobox.com","sentAt":"2014-10-21T19:23:27Z","receivedAt":"2014-10-21T19:23:27Z","isPatch":true,"sender":{"key":"gitster@pobox.com","avatar":"https://avatars.githubusercontent.com/u/54884?v=4"},"body":"Zoltan Klinger <zoltan.klinger@gmail.com> writes:\n\n> When git grep is run with combined patterns such as '-e p1 --and -e p2'\n> and surrounding context lines are requested, the output contains\n> incorrectly highlighted matches.\n>\n> Consider the following output (highlighted matches are surrounded by '*'\n> characters):\n>     $ cat testfile\n>     foo a\n>     foo b\n>     foo bar\n>     baz bar foo\n>     bar x\n>     bar y\n>     $ git grep -n -C2 -e foo --and -e bar testfile\n>     testfile-1-*foo* a\n>     testfile-2-*foo* b\n>     testfile:3:*foo* *bar*\n>     testfile:4:baz *bar* *foo*\n>     testfile-5-*bar* x\n>     testfile-6-*bar* y\n>\n> Lines 1, 2, 5 and 6 do not match the combined patterns, they only\n> contain incorrectly highlighted 'false positives'.\n>\n> Modify the show_line() function in grep.c to highlight matches only on\n> lines that match the combined pattern. Do not highlight matches on lines\n> that provide only context or contain only the function name of the match.\n>\n> The output of the same command after the change:\n>     $ git grep -n -C2 -e foo --and -e bar testfile\n>     testfile-1-foo a\n>     testfile-2-foo b\n>     testfile:3:*foo* *bar*\n>     testfile:4:baz *bar* *foo*\n>     testfile-5-bar x\n>     testfile-6-bar y\n\nIf your goal is to stop colouring words on context and other kinds\nof lines, do you still need the \"while (next_match(...))\" loop for\nthem?  Can't you make the resulting code clearer by restructuring\nthe inside of the whole \"if (opt->color)\" block further, something\nalong the lines of...\n\n\tif (sign != ':') {\n\t\tregmatch_t match; ...\n\t\tenum grep_context ctx = GREP_CONTEXT_BODY;\n                ...\n        \twhile (next_match(...)) {\n                \t... the \"word-by-word\" loop ...\n\t\t}\n\t} else {\n        \tswitch (sign) {\n\t\tcase '-':\n                       \tline_color = opt->color_context;\n                        break;\n\t\tcase ':':\n                       \tline_color = opt->color_function;\n                        break;\n\t\t}\n                output_color(opt, bol, ..., line_color);\n\t}\n\nHmm?\n"},{"id":"250954","messageId":"xmqqoat5hwri.fsf@gitster.dls.corp.google.com","threadId":"37771","inReplyTo":"xmqqh9yxz0pc.fsf@gitster.dls.corp.google.com","subject":"Re: [PATCH] grep: fix match highlighting for combined patterns with context lines","fromName":"Junio C Hamano","fromEmail":"gitster@pobox.com","sentAt":"2014-10-21T22:40:33Z","receivedAt":"2014-10-21T22:40:33Z","isPatch":true,"sender":{"key":"gitster@pobox.com","avatar":"https://avatars.githubusercontent.com/u/54884?v=4"},"body":"Junio C Hamano <gitster@pobox.com> writes:\n\n> If your goal is to stop colouring words on context and other kinds\n> of lines, do you still need the \"while (next_match(...))\" loop for\n> them?  Can't you make the resulting code clearer by restructuring\n> the inside of the whole \"if (opt->color)\" block further, something\n> along the lines of...\n> Hmm?\n\nIt turns out that the result of such a change becomes more readable\nthan the original, in that it makes it clear that reinspection of\nthe lines are done only for matched ones and not context lines.\n\nThe diff looks unnecessarily noisy because it indents the while ()\nloop that is only needed for sign == ':', though.\n\n grep.c | 42 ++++++++++++++++++++++--------------------\n 1 file changed, 22 insertions(+), 20 deletions(-)\n\ndiff --git a/grep.c b/grep.c\nindex c668034..b363a94 100644\n--- a/grep.c\n+++ b/grep.c\n@@ -1112,31 +1112,33 @@ static void show_line(struct grep_opt *opt, char *bol, char *eol,\n \t\toutput_sep(opt, sign);\n \t}\n \tif (opt->color) {\n-\t\tregmatch_t match;\n-\t\tenum grep_context ctx = GREP_CONTEXT_BODY;\n-\t\tint ch = *eol;\n-\t\tint eflags = 0;\n+\t\tif (sign == ':') {\n+\t\t\t/* paint the hits on matched lines */\n+\t\t\tregmatch_t match;\n+\t\t\tenum grep_context ctx = GREP_CONTEXT_BODY;\n+\t\t\tint ch = *eol;\n+\t\t\tint eflags = 0;\n \n-\t\tif (sign == ':')\n \t\t\tline_color = opt->color_selected;\n-\t\telse if (sign == '-')\n+\t\t\t*eol = '\\0';\n+\t\t\twhile (next_match(opt, bol, eol, ctx, &match, eflags)) {\n+\t\t\t\tif (match.rm_so == match.rm_eo)\n+\t\t\t\t\tbreak;\n+\n+\t\t\t\toutput_color(opt, bol, match.rm_so, line_color);\n+\t\t\t\toutput_color(opt, bol + match.rm_so,\n+\t\t\t\t\t     match.rm_eo - match.rm_so,\n+\t\t\t\t\t     opt->color_match);\n+\t\t\t\tbol += match.rm_eo;\n+\t\t\t\trest -= match.rm_eo;\n+\t\t\t\teflags = REG_NOTBOL;\n+\t\t\t}\n+\t\t\t*eol = ch;\n+\t\t} else if (sign == '-') {\n \t\t\tline_color = opt->color_context;\n-\t\telse if (sign == '=')\n+\t\t} else if (sign == '=') {\n \t\t\tline_color = opt->color_function;\n-\t\t*eol = '\\0';\n-\t\twhile (next_match(opt, bol, eol, ctx, &match, eflags)) {\n-\t\t\tif (match.rm_so == match.rm_eo)\n-\t\t\t\tbreak;\n-\n-\t\t\toutput_color(opt, bol, match.rm_so, line_color);\n-\t\t\toutput_color(opt, bol + match.rm_so,\n-\t\t\t\t     match.rm_eo - match.rm_so,\n-\t\t\t\t     opt->color_match);\n-\t\t\tbol += match.rm_eo;\n-\t\t\trest -= match.rm_eo;\n-\t\t\teflags = REG_NOTBOL;\n \t\t}\n-\t\t*eol = ch;\n \t}\n \toutput_color(opt, bol, rest, line_color);\n \topt->output(opt, \"\\n\", 1);\n"},{"id":"250957","messageId":"CAKJhZwTQpxiFp1BLed9jHRaPeF_ZuXQ7u6YGNp--UjyAyGZerw@mail.gmail.com","threadId":"37771","inReplyTo":"xmqqoat5hwri.fsf@gitster.dls.corp.google.com","subject":"Re: [PATCH] grep: fix match highlighting for combined patterns with context lines","fromName":"Zoltan Klinger","fromEmail":"zoltan.klinger@gmail.com","sentAt":"2014-10-22T00:45:19Z","receivedAt":"2014-10-22T00:45:19Z","isPatch":true,"sender":{"key":"zoltan.klinger@gmail.com","avatar":"https://avatars.githubusercontent.com/u/95923?v=4"},"body":"> Junio C Hamano <gitster@pobox.com> writes:\n>\n> It turns out that the result of such a change becomes more readable\n> than the original, in that it makes it clear that reinspection of\n> the lines are done only for matched ones and not context lines.\n>\n>\nAgree, it looks much clearer now. Happy if you squashed your\nchange (commit da736e6) in zk/grep-color-words branch.\n"},{"id":"250974","messageId":"xmqq38afj4sa.fsf@gitster.dls.corp.google.com","threadId":"37771","inReplyTo":"CAKJhZwTQpxiFp1BLed9jHRaPeF_ZuXQ7u6YGNp--UjyAyGZerw@mail.gmail.com","subject":"Re: [PATCH] grep: fix match highlighting for combined patterns with context lines","fromName":"Junio C Hamano","fromEmail":"gitster@pobox.com","sentAt":"2014-10-22T19:14:13Z","receivedAt":"2014-10-22T19:14:13Z","isPatch":true,"sender":{"key":"gitster@pobox.com","avatar":"https://avatars.githubusercontent.com/u/54884?v=4"},"body":"Zoltan Klinger <zoltan.klinger@gmail.com> writes:\n\n>> Junio C Hamano <gitster@pobox.com> writes:\n>>\n>> It turns out that the result of such a change becomes more readable\n>> than the original, in that it makes it clear that reinspection of\n>> the lines are done only for matched ones and not context lines.\n>>\n>>\n> Agree, it looks much clearer now. Happy if you squashed your\n> change (commit da736e6) in zk/grep-color-words branch.\n\nOK, will do.  Thanks.\n"},{"id":"251067","messageId":"544D3A3C.4080906@web.de","threadId":"37771","inReplyTo":"1413870963-66431-1-git-send-email-zoltan.klinger@gmail.com","subject":"Re: [PATCH] grep: fix match highlighting for combined patterns with context lines","fromName":"René Scharfe","fromEmail":"l.s.r@web.de","sentAt":"2014-10-26T18:15:24Z","receivedAt":"2014-10-26T18:15:24Z","isPatch":true,"sender":{"key":"l.s.r@web.de","avatar":"https://avatars.githubusercontent.com/u/26122331?v=4"},"body":"Am 21.10.2014 um 07:56 schrieb Zoltan Klinger:\n> When git grep is run with combined patterns such as '-e p1 --and -e p2'\n> and surrounding context lines are requested, the output contains\n> incorrectly highlighted matches.\n>\n> Consider the following output (highlighted matches are surrounded by '*'\n> characters):\n>      $ cat testfile\n>      foo a\n>      foo b\n>      foo bar\n>      baz bar foo\n>      bar x\n>      bar y\n>      $ git grep -n -C2 -e foo --and -e bar testfile\n>      testfile-1-*foo* a\n>      testfile-2-*foo* b\n>      testfile:3:*foo* *bar*\n>      testfile:4:baz *bar* *foo*\n>      testfile-5-*bar* x\n>      testfile-6-*bar* y\n>\n> Lines 1, 2, 5 and 6 do not match the combined patterns, they only\n> contain incorrectly highlighted 'false positives'.\n\nThe old code highlights all search terms, anywhere. I wouldn't call the \nones in the context lines false positives.  The user might be interested \nin those occurrences as well (I know I am ;).\n\nGNU grep allows coloring to be configured in much greater detail with \nits GREP_COLORS variable.  I didn't think that level of tuning is \ndesirable until now.  What your patch does is equivalent to change the \ndefault of \"ms=01;31:mc=01;31\" (color matching string in selected lines \nand context lines) to \"ms=01;31:mc=\" (color matching string in selected \nlines).\n\nThe difference is only visible with -v or git grep's --not and --and.\n\nSo, if you really don't want matching string in context lines to be \ncolored, perhaps it's time to add a color.grep.contextmatch for matching \ntext in context lines?\n\nRené\n"},{"id":"251124","messageId":"544E8D89.3030201@web.de","threadId":"37771","inReplyTo":"544D3A3C.4080906@web.de","subject":"[PATCH][RFC] grep: add color.grep.matchcontext and color.grep.matchselected","fromName":"René Scharfe","fromEmail":"l.s.r@web.de","sentAt":"2014-10-27T18:23:05Z","receivedAt":"2014-10-27T18:23:05Z","isPatch":true,"sender":{"key":"l.s.r@web.de","avatar":"https://avatars.githubusercontent.com/u/26122331?v=4"},"body":"The config option color.grep.match can be used to specify the highlighting\ncolor for matching strings.  Add the options matchContext and matchSelected\nto allow different colors to be specified for matching strings in the\ncontext vs. in selected lines.  This is similar to the ms and mc specifiers\nin GNU grep's environment variable GREP_COLORS.\n\nSigned-off-by: Rene Scharfe <l.s.r@web.de>\n---\nOnly *very* lightly tested, and a test for t/is missing anyway.  Just\nwanted to quickly show what I meant.  You'd set color.grep.matchContext=\"\"\nto turn off highlighting in context lines.  What do you think?\n\n Documentation/config.txt |  6 +++++-\n grep.c                   | 29 ++++++++++++++++++++++-------\n grep.h                   |  3 ++-\n 3 files changed, 29 insertions(+), 9 deletions(-)\n\ndiff --git a/Documentation/config.txt b/Documentation/config.txt\nindex 8b49813..78832ae 100644\n--- a/Documentation/config.txt\n+++ b/Documentation/config.txt\n@@ -885,7 +885,11 @@ color.grep.<slot>::\n `linenumber`;;\n \tline number prefix (when using `-n`)\n `match`;;\n-\tmatching text\n+\tmatching text (same as setting `matchContext` and `matchSelected`)\n+`matchContext`;;\n+\tmatching text in context lines\n+`matchSelected`;;\n+\tmatching text in selected lines\n `selected`;;\n \tnon-matching text in selected lines\n `separator`;;\ndiff --git a/grep.c b/grep.c\nindex 4dc31ea..6e085f8 100644\n--- a/grep.c\n+++ b/grep.c\n@@ -35,7 +35,8 @@ void init_grep_defaults(void)\n \tstrcpy(opt->color_filename, \"\");\n \tstrcpy(opt->color_function, \"\");\n \tstrcpy(opt->color_lineno, \"\");\n-\tstrcpy(opt->color_match, GIT_COLOR_BOLD_RED);\n+\tstrcpy(opt->color_match_context, GIT_COLOR_BOLD_RED);\n+\tstrcpy(opt->color_match_selected, GIT_COLOR_BOLD_RED);\n \tstrcpy(opt->color_selected, \"\");\n \tstrcpy(opt->color_sep, GIT_COLOR_CYAN);\n \topt->color = -1;\n@@ -101,12 +102,22 @@ int grep_config(const char *var, const char *value, void *cb)\n \t\tcolor = opt->color_function;\n \telse if (!strcmp(var, \"color.grep.linenumber\"))\n \t\tcolor = opt->color_lineno;\n-\telse if (!strcmp(var, \"color.grep.match\"))\n-\t\tcolor = opt->color_match;\n+\telse if (!strcmp(var, \"color.grep.matchcontext\"))\n+\t\tcolor = opt->color_match_context;\n+\telse if (!strcmp(var, \"color.grep.matchselected\"))\n+\t\tcolor = opt->color_match_selected;\n \telse if (!strcmp(var, \"color.grep.selected\"))\n \t\tcolor = opt->color_selected;\n \telse if (!strcmp(var, \"color.grep.separator\"))\n \t\tcolor = opt->color_sep;\n+\telse if (!strcmp(var, \"color.grep.match\")) {\n+\t\tint rc = 0;\n+\t\tif (!value)\n+\t\t\treturn config_error_nonbool(var);\n+\t\trc |= color_parse(value, opt->color_match_context);\n+\t\trc |= color_parse(value, opt->color_match_selected);\n+\t\treturn rc;\n+\t}\n \n \tif (color) {\n \t\tif (!value)\n@@ -144,7 +155,8 @@ void grep_init(struct grep_opt *opt, const char *prefix)\n \tstrcpy(opt->color_filename, def->color_filename);\n \tstrcpy(opt->color_function, def->color_function);\n \tstrcpy(opt->color_lineno, def->color_lineno);\n-\tstrcpy(opt->color_match, def->color_match);\n+\tstrcpy(opt->color_match_context, def->color_match_context);\n+\tstrcpy(opt->color_match_selected, def->color_match_selected);\n \tstrcpy(opt->color_selected, def->color_selected);\n \tstrcpy(opt->color_sep, def->color_sep);\n }\n@@ -1084,7 +1096,7 @@ static void show_line(struct grep_opt *opt, char *bol, char *eol,\n \t\t      const char *name, unsigned lno, char sign)\n {\n \tint rest = eol - bol;\n-\tchar *line_color = NULL;\n+\tconst char *match_color, *line_color = NULL;\n \n \tif (opt->file_break && opt->last_shown == 0) {\n \t\tif (opt->show_hunk_mark)\n@@ -1123,6 +1135,10 @@ static void show_line(struct grep_opt *opt, char *bol, char *eol,\n \t\tint eflags = 0;\n \n \t\tif (sign == ':')\n+\t\t\tmatch_color = opt->color_match_selected;\n+\t\telse\n+\t\t\tmatch_color = opt->color_match_context;\n+\t\tif (sign == ':')\n \t\t\tline_color = opt->color_selected;\n \t\telse if (sign == '-')\n \t\t\tline_color = opt->color_context;\n@@ -1135,8 +1151,7 @@ static void show_line(struct grep_opt *opt, char *bol, char *eol,\n \n \t\t\toutput_color(opt, bol, match.rm_so, line_color);\n \t\t\toutput_color(opt, bol + match.rm_so,\n-\t\t\t\t     match.rm_eo - match.rm_so,\n-\t\t\t\t     opt->color_match);\n+\t\t\t\t     match.rm_eo - match.rm_so, match_color);\n \t\t\tbol += match.rm_eo;\n \t\t\trest -= match.rm_eo;\n \t\t\teflags = REG_NOTBOL;\ndiff --git a/grep.h b/grep.h\nindex eaaced1..95f197a 100644\n--- a/grep.h\n+++ b/grep.h\n@@ -124,7 +124,8 @@ struct grep_opt {\n \tchar color_filename[COLOR_MAXLEN];\n \tchar color_function[COLOR_MAXLEN];\n \tchar color_lineno[COLOR_MAXLEN];\n-\tchar color_match[COLOR_MAXLEN];\n+\tchar color_match_context[COLOR_MAXLEN];\n+\tchar color_match_selected[COLOR_MAXLEN];\n \tchar color_selected[COLOR_MAXLEN];\n \tchar color_sep[COLOR_MAXLEN];\n \tint regflags;\n-- \n2.1.2\n"},{"id":"251128","messageId":"xmqqy4s1s44h.fsf@gitster.dls.corp.google.com","threadId":"37771","inReplyTo":"544E8D89.3030201@web.de","subject":"Re: [PATCH][RFC] grep: add color.grep.matchcontext and color.grep.matchselected","fromName":"Junio C Hamano","fromEmail":"gitster@pobox.com","sentAt":"2014-10-27T19:29:34Z","receivedAt":"2014-10-27T19:29:34Z","isPatch":true,"sender":{"key":"gitster@pobox.com","avatar":"https://avatars.githubusercontent.com/u/54884?v=4"},"body":"René Scharfe <l.s.r@web.de> writes:\n\n> The config option color.grep.match can be used to specify the highlighting\n> color for matching strings.  Add the options matchContext and matchSelected\n> to allow different colors to be specified for matching strings in the\n> context vs. in selected lines.  This is similar to the ms and mc specifiers\n> in GNU grep's environment variable GREP_COLORS.\n>\n> Signed-off-by: Rene Scharfe <l.s.r@web.de>\n> ---\n> Only *very* lightly tested, and a test for t/is missing anyway.  Just\n> wanted to quickly show what I meant.  You'd set color.grep.matchContext=\"\"\n> to turn off highlighting in context lines.  What do you think?\n\nI didn't realize that people wanted to see pieces on non-matching\nlines highlighted.  It makes certain sense, e.g. it would allow you\nto spot near-misses, but that is only true for lines that neighbour\nreal hits, so...\n\nI like this approach better in that it makes those who want a\ndifferent behaviour to do the work without breaking the expectation\nof those who are used to the established behaviour.\n\nZoltan?\n\n\n\n>  Documentation/config.txt |  6 +++++-\n>  grep.c                   | 29 ++++++++++++++++++++++-------\n>  grep.h                   |  3 ++-\n>  3 files changed, 29 insertions(+), 9 deletions(-)\n>\n> diff --git a/Documentation/config.txt b/Documentation/config.txt\n> index 8b49813..78832ae 100644\n> --- a/Documentation/config.txt\n> +++ b/Documentation/config.txt\n> @@ -885,7 +885,11 @@ color.grep.<slot>::\n>  `linenumber`;;\n>  \tline number prefix (when using `-n`)\n>  `match`;;\n> -\tmatching text\n> +\tmatching text (same as setting `matchContext` and `matchSelected`)\n> +`matchContext`;;\n> +\tmatching text in context lines\n> +`matchSelected`;;\n> +\tmatching text in selected lines\n>  `selected`;;\n>  \tnon-matching text in selected lines\n>  `separator`;;\n> diff --git a/grep.c b/grep.c\n> index 4dc31ea..6e085f8 100644\n> --- a/grep.c\n> +++ b/grep.c\n> @@ -35,7 +35,8 @@ void init_grep_defaults(void)\n>  \tstrcpy(opt->color_filename, \"\");\n>  \tstrcpy(opt->color_function, \"\");\n>  \tstrcpy(opt->color_lineno, \"\");\n> -\tstrcpy(opt->color_match, GIT_COLOR_BOLD_RED);\n> +\tstrcpy(opt->color_match_context, GIT_COLOR_BOLD_RED);\n> +\tstrcpy(opt->color_match_selected, GIT_COLOR_BOLD_RED);\n>  \tstrcpy(opt->color_selected, \"\");\n>  \tstrcpy(opt->color_sep, GIT_COLOR_CYAN);\n>  \topt->color = -1;\n> @@ -101,12 +102,22 @@ int grep_config(const char *var, const char *value, void *cb)\n>  \t\tcolor = opt->color_function;\n>  \telse if (!strcmp(var, \"color.grep.linenumber\"))\n>  \t\tcolor = opt->color_lineno;\n> -\telse if (!strcmp(var, \"color.grep.match\"))\n> -\t\tcolor = opt->color_match;\n> +\telse if (!strcmp(var, \"color.grep.matchcontext\"))\n> +\t\tcolor = opt->color_match_context;\n> +\telse if (!strcmp(var, \"color.grep.matchselected\"))\n> +\t\tcolor = opt->color_match_selected;\n>  \telse if (!strcmp(var, \"color.grep.selected\"))\n>  \t\tcolor = opt->color_selected;\n>  \telse if (!strcmp(var, \"color.grep.separator\"))\n>  \t\tcolor = opt->color_sep;\n> +\telse if (!strcmp(var, \"color.grep.match\")) {\n> +\t\tint rc = 0;\n> +\t\tif (!value)\n> +\t\t\treturn config_error_nonbool(var);\n> +\t\trc |= color_parse(value, opt->color_match_context);\n> +\t\trc |= color_parse(value, opt->color_match_selected);\n> +\t\treturn rc;\n> +\t}\n>  \n>  \tif (color) {\n>  \t\tif (!value)\n> @@ -144,7 +155,8 @@ void grep_init(struct grep_opt *opt, const char *prefix)\n>  \tstrcpy(opt->color_filename, def->color_filename);\n>  \tstrcpy(opt->color_function, def->color_function);\n>  \tstrcpy(opt->color_lineno, def->color_lineno);\n> -\tstrcpy(opt->color_match, def->color_match);\n> +\tstrcpy(opt->color_match_context, def->color_match_context);\n> +\tstrcpy(opt->color_match_selected, def->color_match_selected);\n>  \tstrcpy(opt->color_selected, def->color_selected);\n>  \tstrcpy(opt->color_sep, def->color_sep);\n>  }\n> @@ -1084,7 +1096,7 @@ static void show_line(struct grep_opt *opt, char *bol, char *eol,\n>  \t\t      const char *name, unsigned lno, char sign)\n>  {\n>  \tint rest = eol - bol;\n> -\tchar *line_color = NULL;\n> +\tconst char *match_color, *line_color = NULL;\n>  \n>  \tif (opt->file_break && opt->last_shown == 0) {\n>  \t\tif (opt->show_hunk_mark)\n> @@ -1123,6 +1135,10 @@ static void show_line(struct grep_opt *opt, char *bol, char *eol,\n>  \t\tint eflags = 0;\n>  \n>  \t\tif (sign == ':')\n> +\t\t\tmatch_color = opt->color_match_selected;\n> +\t\telse\n> +\t\t\tmatch_color = opt->color_match_context;\n> +\t\tif (sign == ':')\n>  \t\t\tline_color = opt->color_selected;\n>  \t\telse if (sign == '-')\n>  \t\t\tline_color = opt->color_context;\n> @@ -1135,8 +1151,7 @@ static void show_line(struct grep_opt *opt, char *bol, char *eol,\n>  \n>  \t\t\toutput_color(opt, bol, match.rm_so, line_color);\n>  \t\t\toutput_color(opt, bol + match.rm_so,\n> -\t\t\t\t     match.rm_eo - match.rm_so,\n> -\t\t\t\t     opt->color_match);\n> +\t\t\t\t     match.rm_eo - match.rm_so, match_color);\n>  \t\t\tbol += match.rm_eo;\n>  \t\t\trest -= match.rm_eo;\n>  \t\t\teflags = REG_NOTBOL;\n> diff --git a/grep.h b/grep.h\n> index eaaced1..95f197a 100644\n> --- a/grep.h\n> +++ b/grep.h\n> @@ -124,7 +124,8 @@ struct grep_opt {\n>  \tchar color_filename[COLOR_MAXLEN];\n>  \tchar color_function[COLOR_MAXLEN];\n>  \tchar color_lineno[COLOR_MAXLEN];\n> -\tchar color_match[COLOR_MAXLEN];\n> +\tchar color_match_context[COLOR_MAXLEN];\n> +\tchar color_match_selected[COLOR_MAXLEN];\n>  \tchar color_selected[COLOR_MAXLEN];\n>  \tchar color_sep[COLOR_MAXLEN];\n>  \tint regflags;\n"},{"id":"251129","messageId":"xmqqtx2ps3b1.fsf@gitster.dls.corp.google.com","threadId":"37771","inReplyTo":"xmqqy4s1s44h.fsf@gitster.dls.corp.google.com","subject":"Re: [PATCH][RFC] grep: add color.grep.matchcontext and color.grep.matchselected","fromName":"Junio C Hamano","fromEmail":"gitster@pobox.com","sentAt":"2014-10-27T19:47:14Z","receivedAt":"2014-10-27T19:47:14Z","isPatch":true,"sender":{"key":"gitster@pobox.com","avatar":"https://avatars.githubusercontent.com/u/54884?v=4"},"body":"Junio C Hamano <gitster@pobox.com> writes:\n\n> René Scharfe <l.s.r@web.de> writes:\n>\n>> The config option color.grep.match can be used to specify the highlighting\n>> color for matching strings.  Add the options matchContext and matchSelected\n>> to allow different colors to be specified for matching strings in the\n>> context vs. in selected lines.  This is similar to the ms and mc specifiers\n>> in GNU grep's environment variable GREP_COLORS.\n>>\n>> Signed-off-by: Rene Scharfe <l.s.r@web.de>\n>> ---\n>> Only *very* lightly tested, and a test for t/is missing anyway.  Just\n>> wanted to quickly show what I meant.  You'd set color.grep.matchContext=\"\"\n>> to turn off highlighting in context lines.  What do you think?\n>\n> I didn't realize that people wanted to see pieces on non-matching\n> lines highlighted.  It makes certain sense, e.g. it would allow you\n> to spot near-misses, but that is only true for lines that neighbour\n> real hits, so...\n>\n> I like this approach better in that it makes those who want a\n> different behaviour to do the work without breaking the expectation\n> of those who are used to the established behaviour.\n\nFWIW, here is a backport on top of maint-1.8.5 with Zoltan's tests,\nnot because I wanted to apply this as a bugfix to maintenance track,\nbut because I wanted to compare with what has been queued already.\n\nTo apply to post f6c5a296 (color_parse: do not mention variable name\nin error message, 2014-10-07) codebase, the mangling I did for two\ncalls to color_parse() function needs to be undone, obviously.\n\n\n\n Documentation/config.txt |  6 +++-\n grep.c                   | 29 +++++++++++----\n grep.h                   |  3 +-\n t/t7810-grep.sh          | 94 ++++++++++++++++++++++++++++++++++++++++++++++++\n 4 files changed, 123 insertions(+), 9 deletions(-)\n\ndiff --git a/Documentation/config.txt b/Documentation/config.txt\nindex ab26963..aa881fc 100644\n--- a/Documentation/config.txt\n+++ b/Documentation/config.txt\n@@ -860,7 +860,11 @@ color.grep.<slot>::\n `linenumber`;;\n \tline number prefix (when using `-n`)\n `match`;;\n-\tmatching text\n+\tmatching text (same as setting `matchContext` and `matchSelected`)\n+`matchContext`;;\n+\tmatching text in context lines\n+`matchSelected`;;\n+\tmatching text in selected lines\n `selected`;;\n \tnon-matching text in selected lines\n `separator`;;\ndiff --git a/grep.c b/grep.c\nindex c668034..f950651 100644\n--- a/grep.c\n+++ b/grep.c\n@@ -35,7 +35,8 @@ void init_grep_defaults(void)\n \tstrcpy(opt->color_filename, \"\");\n \tstrcpy(opt->color_function, \"\");\n \tstrcpy(opt->color_lineno, \"\");\n-\tstrcpy(opt->color_match, GIT_COLOR_BOLD_RED);\n+\tstrcpy(opt->color_match_context, GIT_COLOR_BOLD_RED);\n+\tstrcpy(opt->color_match_selected, GIT_COLOR_BOLD_RED);\n \tstrcpy(opt->color_selected, \"\");\n \tstrcpy(opt->color_sep, GIT_COLOR_CYAN);\n \topt->color = -1;\n@@ -96,12 +97,22 @@ int grep_config(const char *var, const char *value, void *cb)\n \t\tcolor = opt->color_function;\n \telse if (!strcmp(var, \"color.grep.linenumber\"))\n \t\tcolor = opt->color_lineno;\n-\telse if (!strcmp(var, \"color.grep.match\"))\n-\t\tcolor = opt->color_match;\n+\telse if (!strcmp(var, \"color.grep.matchcontext\"))\n+\t\tcolor = opt->color_match_context;\n+\telse if (!strcmp(var, \"color.grep.matchselected\"))\n+\t\tcolor = opt->color_match_selected;\n \telse if (!strcmp(var, \"color.grep.selected\"))\n \t\tcolor = opt->color_selected;\n \telse if (!strcmp(var, \"color.grep.separator\"))\n \t\tcolor = opt->color_sep;\n+\telse if (!strcmp(var, \"color.grep.match\")) {\n+\t\tint rc = 0;\n+\t\tif (!value)\n+\t\t\treturn config_error_nonbool(var);\n+\t\tcolor_parse(value, var, opt->color_match_context);\n+\t\tcolor_parse(value, var, opt->color_match_selected);\n+\t\treturn rc;\n+\t}\n \n \tif (color) {\n \t\tif (!value)\n@@ -139,7 +150,8 @@ void grep_init(struct grep_opt *opt, const char *prefix)\n \tstrcpy(opt->color_filename, def->color_filename);\n \tstrcpy(opt->color_function, def->color_function);\n \tstrcpy(opt->color_lineno, def->color_lineno);\n-\tstrcpy(opt->color_match, def->color_match);\n+\tstrcpy(opt->color_match_context, def->color_match_context);\n+\tstrcpy(opt->color_match_selected, def->color_match_selected);\n \tstrcpy(opt->color_selected, def->color_selected);\n \tstrcpy(opt->color_sep, def->color_sep);\n }\n@@ -1079,7 +1091,7 @@ static void show_line(struct grep_opt *opt, char *bol, char *eol,\n \t\t      const char *name, unsigned lno, char sign)\n {\n \tint rest = eol - bol;\n-\tchar *line_color = NULL;\n+\tconst char *match_color, *line_color = NULL;\n \n \tif (opt->file_break && opt->last_shown == 0) {\n \t\tif (opt->show_hunk_mark)\n@@ -1118,6 +1130,10 @@ static void show_line(struct grep_opt *opt, char *bol, char *eol,\n \t\tint eflags = 0;\n \n \t\tif (sign == ':')\n+\t\t\tmatch_color = opt->color_match_selected;\n+\t\telse\n+\t\t\tmatch_color = opt->color_match_context;\n+\t\tif (sign == ':')\n \t\t\tline_color = opt->color_selected;\n \t\telse if (sign == '-')\n \t\t\tline_color = opt->color_context;\n@@ -1130,8 +1146,7 @@ static void show_line(struct grep_opt *opt, char *bol, char *eol,\n \n \t\t\toutput_color(opt, bol, match.rm_so, line_color);\n \t\t\toutput_color(opt, bol + match.rm_so,\n-\t\t\t\t     match.rm_eo - match.rm_so,\n-\t\t\t\t     opt->color_match);\n+\t\t\t\t     match.rm_eo - match.rm_so, match_color);\n \t\t\tbol += match.rm_eo;\n \t\t\trest -= match.rm_eo;\n \t\t\teflags = REG_NOTBOL;\ndiff --git a/grep.h b/grep.h\nindex eaaced1..95f197a 100644\n--- a/grep.h\n+++ b/grep.h\n@@ -124,7 +124,8 @@ struct grep_opt {\n \tchar color_filename[COLOR_MAXLEN];\n \tchar color_function[COLOR_MAXLEN];\n \tchar color_lineno[COLOR_MAXLEN];\n-\tchar color_match[COLOR_MAXLEN];\n+\tchar color_match_context[COLOR_MAXLEN];\n+\tchar color_match_selected[COLOR_MAXLEN];\n \tchar color_selected[COLOR_MAXLEN];\n \tchar color_sep[COLOR_MAXLEN];\n \tint regflags;\ndiff --git a/t/t7810-grep.sh b/t/t7810-grep.sh\nindex f698001..e3eeaf9 100755\n--- a/t/t7810-grep.sh\n+++ b/t/t7810-grep.sh\n@@ -1195,4 +1195,98 @@ test_expect_success LIBPCRE 'grep -P \"^ \"' '\n \ttest_cmp expected actual\n '\n \n+cat >expected <<EOF\n+space-line without leading space1\n+space: line <RED>with <RESET>leading space1\n+space: line <RED>with <RESET>leading <RED>space2<RESET>\n+space: line <RED>with <RESET>leading space3\n+space:line without leading <RED>space2<RESET>\n+EOF\n+\n+test_expect_success 'grep --color -e A -e B with context' '\n+\ttest_config color.grep.context\t\tnormal &&\n+\ttest_config color.grep.filename\t\tnormal &&\n+\ttest_config color.grep.function\t\tnormal &&\n+\ttest_config color.grep.linenumber\tnormal &&\n+\ttest_config color.grep.matchContext\tnormal &&\n+\ttest_config color.grep.matchSelected\tred &&\n+\ttest_config color.grep.selected\t\tnormal &&\n+\ttest_config color.grep.separator\tnormal &&\n+\n+\tgit grep --color=always -C2 -e \"with \" -e space2  space |\n+\ttest_decode_color >actual &&\n+\ttest_cmp expected actual\n+'\n+\n+cat >expected <<EOF\n+space-line without leading space1\n+space- line with leading space1\n+space: line <RED>with <RESET>leading <RED>space2<RESET>\n+space- line with leading space3\n+space-line without leading space2\n+EOF\n+\n+test_expect_success 'grep --color -e A --and -e B with context' '\n+\ttest_config color.grep.context\t\tnormal &&\n+\ttest_config color.grep.filename\t\tnormal &&\n+\ttest_config color.grep.function\t\tnormal &&\n+\ttest_config color.grep.linenumber\tnormal &&\n+\ttest_config color.grep.matchContext\tnormal &&\n+\ttest_config color.grep.matchSelected\tred &&\n+\ttest_config color.grep.selected\t\tnormal &&\n+\ttest_config color.grep.separator\tnormal &&\n+\n+\tgit grep --color=always -C2 -e \"with \" --and -e space2  space |\n+\ttest_decode_color >actual &&\n+\ttest_cmp expected actual\n+'\n+\n+cat >expected <<EOF\n+space-line without leading space1\n+space: line <RED>with <RESET>leading space1\n+space- line with leading space2\n+space: line <RED>with <RESET>leading space3\n+space-line without leading space2\n+EOF\n+\n+test_expect_success 'grep --color -e A --and --not -e B with context' '\n+\ttest_config color.grep.context\t\tnormal &&\n+\ttest_config color.grep.filename\t\tnormal &&\n+\ttest_config color.grep.function\t\tnormal &&\n+\ttest_config color.grep.linenumber\tnormal &&\n+\ttest_config color.grep.matchContext\tnormal &&\n+\ttest_config color.grep.matchSelected\tred &&\n+\ttest_config color.grep.selected\t\tnormal &&\n+\ttest_config color.grep.separator\tnormal &&\n+\n+\tgit grep --color=always -C2 -e \"with \" --and --not -e space2  space |\n+\ttest_decode_color >actual &&\n+\ttest_cmp expected actual\n+'\n+\n+cat >expected <<EOF\n+hello.c-#include <stdio.h>\n+hello.c=int main(int argc, const char **argv)\n+hello.c-{\n+hello.c:\tpr<RED>int<RESET>f(\"<RED>Hello<RESET> world.\\n\");\n+hello.c-\treturn 0;\n+hello.c-\t/* char ?? */\n+hello.c-}\n+EOF\n+\n+test_expect_success 'grep --color -e A --and -e B -p with context' '\n+\ttest_config color.grep.context\t\tnormal &&\n+\ttest_config color.grep.filename\t\tnormal &&\n+\ttest_config color.grep.function\t\tnormal &&\n+\ttest_config color.grep.linenumber\tnormal &&\n+\ttest_config color.grep.matchContext\tnormal &&\n+\ttest_config color.grep.matchSelected\tred &&\n+\ttest_config color.grep.selected\t\tnormal &&\n+\ttest_config color.grep.separator\tnormal &&\n+\n+\tgit grep --color=always -p -C3 -e int --and -e Hello --no-index hello.c |\n+\ttest_decode_color >actual &&\n+\ttest_cmp expected actual\n+'\n+\n test_done\n"},{"id":"251138","messageId":"CAKJhZwRShbV14=BihxiTzayR4kg3GaAPN_NFXwFZ-4kAD-QHTA@mail.gmail.com","threadId":"37771","inReplyTo":"xmqqy4s1s44h.fsf@gitster.dls.corp.google.com","subject":"Re: [PATCH][RFC] grep: add color.grep.matchcontext and color.grep.matchselected","fromName":"Zoltan Klinger","fromEmail":"zoltan.klinger@gmail.com","sentAt":"2014-10-27T23:32:23Z","receivedAt":"2014-10-27T23:32:23Z","isPatch":true,"sender":{"key":"zoltan.klinger@gmail.com","avatar":"https://avatars.githubusercontent.com/u/95923?v=4"},"body":"I like René's approach, too. It's more flexible, supports the old\nbehaviour and it scratches my itch as well.\nDon't mind if you dropped my patch and used René's instead.\n\n>> Only *very* lightly tested, and a test for t/is missing anyway.  Just\n>> wanted to quickly show what I meant.  You'd set color.grep.matchContext=\"\"\n>> to turn off highlighting in context lines.  What do you think?\n>\n> I didn't realize that people wanted to see pieces on non-matching\n> lines highlighted.  It makes certain sense, e.g. it would allow you\n> to spot near-misses, but that is only true for lines that neighbour\n> real hits, so...\n>\n> I like this approach better in that it makes those who want a\n> different behaviour to do the work without breaking the expectation\n> of those who are used to the established behaviour.\n>\n> Zoltan?\n"},{"id":"251145","messageId":"xmqqzjcg3zqo.fsf@gitster.dls.corp.google.com","threadId":"37771","inReplyTo":"CAKJhZwRShbV14=BihxiTzayR4kg3GaAPN_NFXwFZ-4kAD-QHTA@mail.gmail.com","subject":"Re: [PATCH][RFC] grep: add color.grep.matchcontext and color.grep.matchselected","fromName":"Junio C Hamano","fromEmail":"gitster@pobox.com","sentAt":"2014-10-28T16:50:23Z","receivedAt":"2014-10-28T16:50:23Z","isPatch":true,"sender":{"key":"gitster@pobox.com","avatar":"https://avatars.githubusercontent.com/u/54884?v=4"},"body":"Zoltan Klinger <zoltan.klinger@gmail.com> writes:\n\n> I like René's approach, too. It's more flexible, supports the old\n> behaviour and it scratches my itch as well.\n\nOK, then let's go with that one.\n"},{"id":"251150","messageId":"544FDE42.4050905@web.de","threadId":"37771","inReplyTo":"CAKJhZwRShbV14=BihxiTzayR4kg3GaAPN_NFXwFZ-4kAD-QHTA@mail.gmail.com","subject":"Re: [PATCH][RFC] grep: add color.grep.matchcontext and color.grep.matchselected","fromName":"René Scharfe","fromEmail":"l.s.r@web.de","sentAt":"2014-10-28T18:19:46Z","receivedAt":"2014-10-28T18:19:46Z","isPatch":true,"sender":{"key":"l.s.r@web.de","avatar":"https://avatars.githubusercontent.com/u/26122331?v=4"},"body":"Am 28.10.2014 um 00:32 schrieb Zoltan Klinger:\n> I like René's approach, too. It's more flexible, supports the old\n> behaviour and it scratches my itch as well.\n> Don't mind if you dropped my patch and used René's instead.\n\n\nGood. :)  And here's the t/ part of your patch, slightly changed to\nexercise the new config options.\n\n---\n t/t7810-grep.sh | 93 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++\n 1 file changed, 93 insertions(+)\n\ndiff --git a/t/t7810-grep.sh b/t/t7810-grep.sh\nindex 40615de..5d3e161 100755\n--- a/t/t7810-grep.sh\n+++ b/t/t7810-grep.sh\n@@ -1202,4 +1202,97 @@ test_expect_success LIBPCRE 'grep -P \"^ \"' '\n \ttest_cmp expected actual\n '\n \n+cat >expected <<EOF\n+space-line without leading space1\n+space: line <RED>with <RESET>leading space1\n+space: line <RED>with <RESET>leading <RED>space2<RESET>\n+space: line <RED>with <RESET>leading space3\n+space:line without leading <RED>space2<RESET>\n+EOF\n+\n+test_expect_success 'grep --color -e A -e B with context' '\n+\ttest_config color.grep.context\t\tnormal &&\n+\ttest_config color.grep.filename\t\tnormal &&\n+\ttest_config color.grep.function\t\tnormal &&\n+\ttest_config color.grep.linenumber\tnormal &&\n+\ttest_config color.grep.match\t\tred &&\n+\ttest_config color.grep.selected\t\tnormal &&\n+\ttest_config color.grep.separator\tnormal &&\n+\n+\tgit grep --color=always -C2 -e \"with \" -e space2  space |\n+\ttest_decode_color >actual &&\n+\ttest_cmp expected actual\n+'\n+\n+cat >expected <<EOF\n+space-line without leading space1\n+space- line <GREEN>with <RESET>leading space1\n+space: line <RED>with <RESET>leading <RED>space2<RESET>\n+space- line <GREEN>with <RESET>leading space3\n+space-line without leading <GREEN>space2<RESET>\n+EOF\n+\n+test_expect_success 'grep --color -e A --and -e B with context' '\n+\ttest_config color.grep.context\t\tnormal &&\n+\ttest_config color.grep.filename\t\tnormal &&\n+\ttest_config color.grep.function\t\tnormal &&\n+\ttest_config color.grep.linenumber\tnormal &&\n+\ttest_config color.grep.matchContext\tgreen &&\n+\ttest_config color.grep.matchSelected\tred &&\n+\ttest_config color.grep.selected\t\tnormal &&\n+\ttest_config color.grep.separator\tnormal &&\n+\n+\tgit grep --color=always -C2 -e \"with \" --and -e space2  space |\n+\ttest_decode_color >actual &&\n+\ttest_cmp expected actual\n+'\n+\n+cat >expected <<EOF\n+space-line without leading space1\n+space: line <RED>with <RESET>leading space1\n+space- line <GREEN>with <RESET>leading <GREEN>space2<RESET>\n+space: line <RED>with <RESET>leading space3\n+space-line without leading <GREEN>space2<RESET>\n+EOF\n+\n+test_expect_success 'grep --color -e A --and --not -e B with context' '\n+\ttest_config color.grep.context\t\tnormal &&\n+\ttest_config color.grep.filename\t\tnormal &&\n+\ttest_config color.grep.function\t\tnormal &&\n+\ttest_config color.grep.linenumber\tnormal &&\n+\ttest_config color.grep.matchContext\tgreen &&\n+\ttest_config color.grep.matchSelected\tred &&\n+\ttest_config color.grep.selected\t\tnormal &&\n+\ttest_config color.grep.separator\tnormal &&\n+\n+\tgit grep --color=always -C2 -e \"with \" --and --not -e space2  space |\n+\ttest_decode_color >actual &&\n+\ttest_cmp expected actual\n+'\n+\n+cat >expected <<EOF\n+hello.c-#include <stdio.h>\n+hello.c=<GREEN>int<RESET> main(<GREEN>int<RESET> argc, const char **argv)\n+hello.c-{\n+hello.c:\tpr<RED>int<RESET>f(\"<RED>Hello<RESET> world.\\n\");\n+hello.c-\treturn 0;\n+hello.c-\t/* char ?? */\n+hello.c-}\n+EOF\n+\n+test_expect_success 'grep --color -e A --and -e B -p with context' '\n+\ttest_config color.grep.context\t\tnormal &&\n+\ttest_config color.grep.filename\t\tnormal &&\n+\ttest_config color.grep.function\t\tnormal &&\n+\ttest_config color.grep.linenumber\tnormal &&\n+\ttest_config color.grep.matchContext\tgreen &&\n+\ttest_config color.grep.matchSelected\tred &&\n+\ttest_config color.grep.selected\t\tnormal &&\n+\ttest_config color.grep.separator\tnormal &&\n+\n+\tgit grep --color=always -p -C3 -e int --and -e Hello --no-index hello.c |\n+\ttest_decode_color >actual &&\n+\ttest_cmp expected actual\n+'\n+\n test_done\n-- \n2.1.2\n"}]}