{"thread":{"id":"27970","subject":"[PATCH] grep: add option to show whole function as context","startedAt":"2011-07-31T15:59:30Z","lastAt":"2011-08-02T18:08:50Z","messageCount":11,"participants":["René Scharfe","Sverre Rabbelier","Junio C Hamano","Tait"],"isPatch":true,"patchVersion":1,"patchTotal":null},"messages":[{"id":"172455","messageId":"4E357BE2.8030409@lsrfire.ath.cx","threadId":"27970","inReplyTo":null,"subject":"[PATCH] grep: add option to show whole function as context","fromName":"René Scharfe","fromEmail":"rene.scharfe@lsrfire.ath.cx","sentAt":"2011-07-31T15:59:30Z","receivedAt":"2011-07-31T15:59:30Z","isPatch":true,"sender":{"key":"l.s.r@web.de","avatar":"https://avatars.githubusercontent.com/u/26122331?v=4"},"body":"Add a new option, -S, to show the whole surrounding function of a match.\n\nIt uses the same regular expressions as -p and diff to find the beginning\nof sections.\n\nCurrently it will not display comments in front of a function, but those\nthat are following one.  Despite this shortcoming it is already useful,\ne.g. to simply see a more complete applicable context or to extract whole\nfunctions.\n\nSigned-off-by: Rene Scharfe <rene.scharfe@lsrfire.ath.cx>\n---\nExtending userdiff to allow comments to be recognized would be a bit more\ninvolved, especially since we'd need to able to handle nested multi-line\ncomment blocks.\n\n Documentation/git-grep.txt |    6 ++++++\n builtin/grep.c             |    5 ++++-\n grep.c                     |   32 ++++++++++++++++++++++----------\n grep.h                     |    1 +\n t/t7810-grep.sh            |   14 ++++++++++++++\n 5 files changed, 47 insertions(+), 11 deletions(-)\n\ndiff --git a/Documentation/git-grep.txt b/Documentation/git-grep.txt\nindex 07b3c6a..78e6fc4 100644\n--- a/Documentation/git-grep.txt\n+++ b/Documentation/git-grep.txt\n@@ -172,6 +172,12 @@ OPTIONS\n \tpatch hunk headers (see 'Defining a custom hunk-header' in\n \tlinkgit:gitattributes[5]).\n \n+-S::\n+\tShow the surrounding text from the previous line containing a\n+\tfunction name up to the one before the next function name,\n+\teffectively showing the whole function in which the match was\n+\tfound.\n+\n -f <file>::\n \tRead patterns from <file>, one per line.\n \ndiff --git a/builtin/grep.c b/builtin/grep.c\nindex cccf8da..fc50859 100644\n--- a/builtin/grep.c\n+++ b/builtin/grep.c\n@@ -838,6 +838,8 @@ int cmd_grep(int argc, const char **argv, const char *prefix)\n \t\t\tcontext_callback),\n \t\tOPT_BOOLEAN('p', \"show-function\", &opt.funcname,\n \t\t\t\"show a line with the function name before matches\"),\n+\t\tOPT_BOOLEAN('S', NULL, &opt.funcbody,\n+\t\t\t\"show the surrounding function\"),\n \t\tOPT_GROUP(\"\"),\n \t\tOPT_CALLBACK('f', NULL, &opt, \"file\",\n \t\t\t\"read patterns from file\", file_callback),\n@@ -980,7 +982,8 @@ int cmd_grep(int argc, const char **argv, const char *prefix)\n \t\tuse_threads = 0;\n \n \tif (use_threads) {\n-\t\tif (opt.pre_context || opt.post_context || opt.file_break)\n+\t\tif (opt.pre_context || opt.post_context || opt.file_break ||\n+\t\t    opt.funcbody)\n \t\t\tskip_first_line = 1;\n \t\tstart_threads(&opt);\n \t}\ndiff --git a/grep.c b/grep.c\nindex 04e9ba4..26e8d8e 100644\n--- a/grep.c\n+++ b/grep.c\n@@ -724,7 +724,7 @@ static void show_line(struct grep_opt *opt, char *bol, char *eol,\n \tif (opt->file_break && opt->last_shown == 0) {\n \t\tif (opt->show_hunk_mark)\n \t\t\topt->output(opt, \"\\n\", 1);\n-\t} else if (opt->pre_context || opt->post_context) {\n+\t} else if (opt->pre_context || opt->post_context || opt->funcbody) {\n \t\tif (opt->last_shown == 0) {\n \t\t\tif (opt->show_hunk_mark) {\n \t\t\t\toutput_color(opt, \"--\", 2, opt->color_sep);\n@@ -819,10 +819,13 @@ static void show_funcname_line(struct grep_opt *opt, const char *name,\n }\n \n static void show_pre_context(struct grep_opt *opt, const char *name, char *buf,\n-\t\t\t     char *bol, unsigned lno)\n+\t\t\t     char *bol, char *end, unsigned lno)\n {\n \tunsigned cur = lno, from = 1, funcname_lno = 0;\n-\tint funcname_needed = opt->funcname;\n+\tint funcname_needed = !!opt->funcname;\n+\n+\tif (opt->funcbody && !match_funcname(opt, bol, end))\n+\t\tfuncname_needed = 2;\n \n \tif (opt->pre_context < lno)\n \t\tfrom = lno - opt->pre_context;\n@@ -830,7 +833,8 @@ static void show_pre_context(struct grep_opt *opt, const char *name, char *buf,\n \t\tfrom = opt->last_shown + 1;\n \n \t/* Rewind. */\n-\twhile (bol > buf && cur > from) {\n+\twhile (bol > buf &&\n+\t       cur > (funcname_needed == 2 ? opt->last_shown + 1 : from)) {\n \t\tchar *eol = --bol;\n \n \t\twhile (bol > buf && bol[-1] != '\\n')\n@@ -942,13 +946,15 @@ static int grep_buffer_1(struct grep_opt *opt, const char *name,\n \tint binary_match_only = 0;\n \tunsigned count = 0;\n \tint try_lookahead = 0;\n+\tint show_function = 0;\n \tenum grep_context ctx = GREP_CONTEXT_HEAD;\n \txdemitconf_t xecfg;\n \n \tif (!opt->output)\n \t\topt->output = std_output;\n \n-\tif (opt->pre_context || opt->post_context || opt->file_break) {\n+\tif (opt->pre_context || opt->post_context || opt->file_break ||\n+\t    opt->funcbody) {\n \t\t/* Show hunk marks, except for the first file. */\n \t\tif (opt->last_shown)\n \t\t\topt->show_hunk_mark = 1;\n@@ -1004,7 +1010,8 @@ static int grep_buffer_1(struct grep_opt *opt, const char *name,\n \t\t */\n \t\tif (try_lookahead\n \t\t    && !(last_hit\n-\t\t\t && lno <= last_hit + opt->post_context)\n+\t\t\t && (show_function ||\n+\t\t\t     lno <= last_hit + opt->post_context))\n \t\t    && look_ahead(opt, &left, &lno, &bol))\n \t\t\tbreak;\n \t\teol = end_of_line(bol, &left);\n@@ -1051,15 +1058,20 @@ static int grep_buffer_1(struct grep_opt *opt, const char *name,\n \t\t\t/* Hit at this line.  If we haven't shown the\n \t\t\t * pre-context lines, we would need to show them.\n \t\t\t */\n-\t\t\tif (opt->pre_context)\n-\t\t\t\tshow_pre_context(opt, name, buf, bol, lno);\n+\t\t\tif (opt->pre_context || opt->funcbody)\n+\t\t\t\tshow_pre_context(opt, name, buf, bol, eol, lno);\n \t\t\telse if (opt->funcname)\n \t\t\t\tshow_funcname_line(opt, name, buf, bol, lno);\n \t\t\tshow_line(opt, bol, eol, name, lno, ':');\n \t\t\tlast_hit = lno;\n+\t\t\tif (opt->funcbody)\n+\t\t\t\tshow_function = 1;\n+\t\t\tgoto next_line;\n \t\t}\n-\t\telse if (last_hit &&\n-\t\t\t lno <= last_hit + opt->post_context) {\n+\t\tif (show_function && match_funcname(opt, bol, eol))\n+\t\t\tshow_function = 0;\n+\t\tif (show_function ||\n+\t\t    (last_hit && lno <= last_hit + opt->post_context)) {\n \t\t\t/* If the last hit is within the post context,\n \t\t\t * we need to show this line.\n \t\t\t */\ndiff --git a/grep.h b/grep.h\nindex c568297..ae50c45 100644\n--- a/grep.h\n+++ b/grep.h\n@@ -98,6 +98,7 @@ struct grep_opt {\n \tint color;\n \tint max_depth;\n \tint funcname;\n+\tint funcbody;\n \tchar color_context[COLOR_MAXLEN];\n \tchar color_filename[COLOR_MAXLEN];\n \tchar color_function[COLOR_MAXLEN];\ndiff --git a/t/t7810-grep.sh b/t/t7810-grep.sh\nindex a29ae45..3f127ac 100755\n--- a/t/t7810-grep.sh\n+++ b/t/t7810-grep.sh\n@@ -509,6 +509,20 @@ test_expect_success 'grep -p -B5' '\n \ttest_cmp expected actual\n '\n \n+cat >expected <<EOF\n+hello.c=int main(int argc, const char **argv)\n+hello.c-{\n+hello.c-\tprintf(\"Hello world.\\n\");\n+hello.c:\treturn 0;\n+hello.c-\t/* char ?? */\n+hello.c-}\n+EOF\n+\n+test_expect_success 'grep -S' '\n+\tgit grep -S return >actual &&\n+\ttest_cmp expected actual\n+'\n+\n test_expect_success 'grep from a subdirectory to search wider area (1)' '\n \tmkdir -p s &&\n \t(\n-- \n1.7.6\n"},{"id":"172460","messageId":"CAGdFq_ikKu2E44tyadtKNS=GNRw_1qkfFN-UxEtz-Rsv__Z+jg@mail.gmail.com","threadId":"27970","inReplyTo":"4E357BE2.8030409@lsrfire.ath.cx","subject":"Re: [PATCH] grep: add option to show whole function as context","fromName":"Sverre Rabbelier","fromEmail":"srabbelier@gmail.com","sentAt":"2011-07-31T17:34:12Z","receivedAt":"2011-07-31T17:34:12Z","isPatch":true,"sender":{"key":"srabbelier@gmail.com","avatar":"https://avatars.githubusercontent.com/u/3098?v=4"},"body":"Heya,\n\nOn Sun, Jul 31, 2011 at 17:59, René Scharfe <rene.scharfe@lsrfire.ath.cx> wrote:\n> Add a new option, -S, to show the whole surrounding function of a match.\n\nPerhaps a different option name so as not to conflict with the -S from\n'git log'? It would be nice to have this available in 'git log -p'.\n\n-- \nCheers,\n\nSverre Rabbelier\n"},{"id":"172538","messageId":"4E36C840.9000808@lsrfire.ath.cx","threadId":"27970","inReplyTo":"CAGdFq_ikKu2E44tyadtKNS=GNRw_1qkfFN-UxEtz-Rsv__Z+jg@mail.gmail.com","subject":"Re: [PATCH] grep: add option to show whole function as context","fromName":"René Scharfe","fromEmail":"rene.scharfe@lsrfire.ath.cx","sentAt":"2011-08-01T15:37:36Z","receivedAt":"2011-08-01T15:37:36Z","isPatch":true,"sender":{"key":"l.s.r@web.de","avatar":"https://avatars.githubusercontent.com/u/26122331?v=4"},"body":"Am 31.07.2011 19:34, schrieb Sverre Rabbelier:\n> On Sun, Jul 31, 2011 at 17:59, René Scharfe <rene.scharfe@lsrfire.ath.cx> wrote:\n>> Add a new option, -S, to show the whole surrounding function of a match.\n> \n> Perhaps a different option name so as not to conflict with the -S from\n> 'git log'? It would be nice to have this available in 'git log -p'.\n\nDo you mean a diff option to show whole affected functions as context\ninstead of the fixed number of context lines -U gives you?  That sounds\nuseful as well.\n\nHow about -W?  It's not used by GNU grep either.\n\nRené\n"},{"id":"172540","messageId":"CAGdFq_go0xYy9BZWRDxAFGV95G7V-P9-=7VhsodLd+z-ho09Qw@mail.gmail.com","threadId":"27970","inReplyTo":"4E36C840.9000808@lsrfire.ath.cx","subject":"Re: [PATCH] grep: add option to show whole function as context","fromName":"Sverre Rabbelier","fromEmail":"srabbelier@gmail.com","sentAt":"2011-08-01T15:39:37Z","receivedAt":"2011-08-01T15:39:37Z","isPatch":true,"sender":{"key":"srabbelier@gmail.com","avatar":"https://avatars.githubusercontent.com/u/3098?v=4"},"body":"Heya,\n\nOn Mon, Aug 1, 2011 at 17:37, René Scharfe <rene.scharfe@lsrfire.ath.cx> wrote:\n> Do you mean a diff option to show whole affected functions as context\n> instead of the fixed number of context lines -U gives you?  That sounds\n> useful as well.\n\nExactly.\n\n> How about -W?  It's not used by GNU grep either.\n\nWhy not give it an easy-to-remember long name instead?\n--show-function-context or such :)\n\n-- \nCheers,\n\nSverre Rabbelier\n"},{"id":"172542","messageId":"4E36E053.7050407@lsrfire.ath.cx","threadId":"27970","inReplyTo":"CAGdFq_go0xYy9BZWRDxAFGV95G7V-P9-=7VhsodLd+z-ho09Qw@mail.gmail.com","subject":"Re: [PATCH] grep: add option to show whole function as context","fromName":"René Scharfe","fromEmail":"rene.scharfe@lsrfire.ath.cx","sentAt":"2011-08-01T17:20:19Z","receivedAt":"2011-08-01T17:20:19Z","isPatch":true,"sender":{"key":"l.s.r@web.de","avatar":"https://avatars.githubusercontent.com/u/26122331?v=4"},"body":"Am 01.08.2011 17:39, schrieb Sverre Rabbelier:\n>> How about -W?  It's not used by GNU grep either.\n> \n> Why not give it an easy-to-remember long name instead?\n> --show-function-context or such :)\n\nBecause I tend to forget them. ;)\n\nRené\n"},{"id":"172543","messageId":"4E36E075.20603@lsrfire.ath.cx","threadId":"27970","inReplyTo":"CAGdFq_go0xYy9BZWRDxAFGV95G7V-P9-=7VhsodLd+z-ho09Qw@mail.gmail.com","subject":"[PATCH v2 1/2] grep: add option to show whole function as context","fromName":"René Scharfe","fromEmail":"rene.scharfe@lsrfire.ath.cx","sentAt":"2011-08-01T17:20:53Z","receivedAt":"2011-08-01T17:20:53Z","isPatch":true,"sender":{"key":"l.s.r@web.de","avatar":"https://avatars.githubusercontent.com/u/26122331?v=4"},"body":"Add a new option, -W, to show the whole surrounding function of a match.\n\nIt uses the same regular expressions as -p and diff to find the beginning\nof sections.\n\nCurrently it will not display comments in front of a function, but those\nthat are following one.  Despite this shortcoming it is already useful,\ne.g. to simply see a more complete applicable context or to extract whole\nfunctions.\n\nSigned-off-by: Rene Scharfe <rene.scharfe@lsrfire.ath.cx>\n---\nChanges since v1: use -W instead of -S to avoid clash with git log -S\nand added second patch to add long options as well.\n\n Documentation/git-grep.txt |    6 ++++++\n builtin/grep.c             |    5 ++++-\n grep.c                     |   32 ++++++++++++++++++++++----------\n grep.h                     |    1 +\n t/t7810-grep.sh            |   14 ++++++++++++++\n 5 files changed, 47 insertions(+), 11 deletions(-)\n\ndiff --git a/Documentation/git-grep.txt b/Documentation/git-grep.txt\nindex 07b3c6a..6cd0c50 100644\n--- a/Documentation/git-grep.txt\n+++ b/Documentation/git-grep.txt\n@@ -172,6 +172,12 @@ OPTIONS\n \tpatch hunk headers (see 'Defining a custom hunk-header' in\n \tlinkgit:gitattributes[5]).\n \n+-W::\n+\tShow the surrounding text from the previous line containing a\n+\tfunction name up to the one before the next function name,\n+\teffectively showing the whole function in which the match was\n+\tfound.\n+\n -f <file>::\n \tRead patterns from <file>, one per line.\n \ndiff --git a/builtin/grep.c b/builtin/grep.c\nindex cccf8da..1fae662 100644\n--- a/builtin/grep.c\n+++ b/builtin/grep.c\n@@ -838,6 +838,8 @@ int cmd_grep(int argc, const char **argv, const char *prefix)\n \t\t\tcontext_callback),\n \t\tOPT_BOOLEAN('p', \"show-function\", &opt.funcname,\n \t\t\t\"show a line with the function name before matches\"),\n+\t\tOPT_BOOLEAN('W', NULL, &opt.funcbody,\n+\t\t\t\"show the surrounding function\"),\n \t\tOPT_GROUP(\"\"),\n \t\tOPT_CALLBACK('f', NULL, &opt, \"file\",\n \t\t\t\"read patterns from file\", file_callback),\n@@ -980,7 +982,8 @@ int cmd_grep(int argc, const char **argv, const char *prefix)\n \t\tuse_threads = 0;\n \n \tif (use_threads) {\n-\t\tif (opt.pre_context || opt.post_context || opt.file_break)\n+\t\tif (opt.pre_context || opt.post_context || opt.file_break ||\n+\t\t    opt.funcbody)\n \t\t\tskip_first_line = 1;\n \t\tstart_threads(&opt);\n \t}\ndiff --git a/grep.c b/grep.c\nindex 04e9ba4..26e8d8e 100644\n--- a/grep.c\n+++ b/grep.c\n@@ -724,7 +724,7 @@ static void show_line(struct grep_opt *opt, char *bol, char *eol,\n \tif (opt->file_break && opt->last_shown == 0) {\n \t\tif (opt->show_hunk_mark)\n \t\t\topt->output(opt, \"\\n\", 1);\n-\t} else if (opt->pre_context || opt->post_context) {\n+\t} else if (opt->pre_context || opt->post_context || opt->funcbody) {\n \t\tif (opt->last_shown == 0) {\n \t\t\tif (opt->show_hunk_mark) {\n \t\t\t\toutput_color(opt, \"--\", 2, opt->color_sep);\n@@ -819,10 +819,13 @@ static void show_funcname_line(struct grep_opt *opt, const char *name,\n }\n \n static void show_pre_context(struct grep_opt *opt, const char *name, char *buf,\n-\t\t\t     char *bol, unsigned lno)\n+\t\t\t     char *bol, char *end, unsigned lno)\n {\n \tunsigned cur = lno, from = 1, funcname_lno = 0;\n-\tint funcname_needed = opt->funcname;\n+\tint funcname_needed = !!opt->funcname;\n+\n+\tif (opt->funcbody && !match_funcname(opt, bol, end))\n+\t\tfuncname_needed = 2;\n \n \tif (opt->pre_context < lno)\n \t\tfrom = lno - opt->pre_context;\n@@ -830,7 +833,8 @@ static void show_pre_context(struct grep_opt *opt, const char *name, char *buf,\n \t\tfrom = opt->last_shown + 1;\n \n \t/* Rewind. */\n-\twhile (bol > buf && cur > from) {\n+\twhile (bol > buf &&\n+\t       cur > (funcname_needed == 2 ? opt->last_shown + 1 : from)) {\n \t\tchar *eol = --bol;\n \n \t\twhile (bol > buf && bol[-1] != '\\n')\n@@ -942,13 +946,15 @@ static int grep_buffer_1(struct grep_opt *opt, const char *name,\n \tint binary_match_only = 0;\n \tunsigned count = 0;\n \tint try_lookahead = 0;\n+\tint show_function = 0;\n \tenum grep_context ctx = GREP_CONTEXT_HEAD;\n \txdemitconf_t xecfg;\n \n \tif (!opt->output)\n \t\topt->output = std_output;\n \n-\tif (opt->pre_context || opt->post_context || opt->file_break) {\n+\tif (opt->pre_context || opt->post_context || opt->file_break ||\n+\t    opt->funcbody) {\n \t\t/* Show hunk marks, except for the first file. */\n \t\tif (opt->last_shown)\n \t\t\topt->show_hunk_mark = 1;\n@@ -1004,7 +1010,8 @@ static int grep_buffer_1(struct grep_opt *opt, const char *name,\n \t\t */\n \t\tif (try_lookahead\n \t\t    && !(last_hit\n-\t\t\t && lno <= last_hit + opt->post_context)\n+\t\t\t && (show_function ||\n+\t\t\t     lno <= last_hit + opt->post_context))\n \t\t    && look_ahead(opt, &left, &lno, &bol))\n \t\t\tbreak;\n \t\teol = end_of_line(bol, &left);\n@@ -1051,15 +1058,20 @@ static int grep_buffer_1(struct grep_opt *opt, const char *name,\n \t\t\t/* Hit at this line.  If we haven't shown the\n \t\t\t * pre-context lines, we would need to show them.\n \t\t\t */\n-\t\t\tif (opt->pre_context)\n-\t\t\t\tshow_pre_context(opt, name, buf, bol, lno);\n+\t\t\tif (opt->pre_context || opt->funcbody)\n+\t\t\t\tshow_pre_context(opt, name, buf, bol, eol, lno);\n \t\t\telse if (opt->funcname)\n \t\t\t\tshow_funcname_line(opt, name, buf, bol, lno);\n \t\t\tshow_line(opt, bol, eol, name, lno, ':');\n \t\t\tlast_hit = lno;\n+\t\t\tif (opt->funcbody)\n+\t\t\t\tshow_function = 1;\n+\t\t\tgoto next_line;\n \t\t}\n-\t\telse if (last_hit &&\n-\t\t\t lno <= last_hit + opt->post_context) {\n+\t\tif (show_function && match_funcname(opt, bol, eol))\n+\t\t\tshow_function = 0;\n+\t\tif (show_function ||\n+\t\t    (last_hit && lno <= last_hit + opt->post_context)) {\n \t\t\t/* If the last hit is within the post context,\n \t\t\t * we need to show this line.\n \t\t\t */\ndiff --git a/grep.h b/grep.h\nindex c568297..ae50c45 100644\n--- a/grep.h\n+++ b/grep.h\n@@ -98,6 +98,7 @@ struct grep_opt {\n \tint color;\n \tint max_depth;\n \tint funcname;\n+\tint funcbody;\n \tchar color_context[COLOR_MAXLEN];\n \tchar color_filename[COLOR_MAXLEN];\n \tchar color_function[COLOR_MAXLEN];\ndiff --git a/t/t7810-grep.sh b/t/t7810-grep.sh\nindex a29ae45..0d60016 100755\n--- a/t/t7810-grep.sh\n+++ b/t/t7810-grep.sh\n@@ -509,6 +509,20 @@ test_expect_success 'grep -p -B5' '\n \ttest_cmp expected actual\n '\n \n+cat >expected <<EOF\n+hello.c=int main(int argc, const char **argv)\n+hello.c-{\n+hello.c-\tprintf(\"Hello world.\\n\");\n+hello.c:\treturn 0;\n+hello.c-\t/* char ?? */\n+hello.c-}\n+EOF\n+\n+test_expect_success 'grep -W' '\n+\tgit grep -W return >actual &&\n+\ttest_cmp expected actual\n+'\n+\n test_expect_success 'grep from a subdirectory to search wider area (1)' '\n \tmkdir -p s &&\n \t(\n-- \n1.7.6\n"},{"id":"172544","messageId":"4E36E0EC.1000508@lsrfire.ath.cx","threadId":"27970","inReplyTo":"CAGdFq_go0xYy9BZWRDxAFGV95G7V-P9-=7VhsodLd+z-ho09Qw@mail.gmail.com","subject":"[PATCH v2 2/2] grep: long context options","fromName":"René Scharfe","fromEmail":"rene.scharfe@lsrfire.ath.cx","sentAt":"2011-08-01T17:22:52Z","receivedAt":"2011-08-01T17:22:52Z","isPatch":true,"sender":{"key":"l.s.r@web.de","avatar":"https://avatars.githubusercontent.com/u/26122331?v=4"},"body":"Take long option names for -A (--after-context), -B (--before-context)\nand -C (--context) from GNU grep and add a similar long option name\nfor -W (--function-context).\n\nSigned-off-by: Rene Scharfe <rene.scharfe@lsrfire.ath.cx>\n---\n Documentation/git-grep.txt |   26 +++++++++++++++++---------\n builtin/grep.c             |    8 ++++----\n 2 files changed, 21 insertions(+), 13 deletions(-)\n\ndiff --git a/Documentation/git-grep.txt b/Documentation/git-grep.txt\nindex 6cd0c50..af501d2 100644\n--- a/Documentation/git-grep.txt\n+++ b/Documentation/git-grep.txt\n@@ -155,15 +155,6 @@ OPTIONS\n \tShow the filename above the matches in that file instead of\n \tat the start of each shown line.\n \n--[ABC] <context>::\n-\tShow `context` trailing (`A` -- after), or leading (`B`\n-\t-- before), or both (`C` -- context) lines, and place a\n-\tline containing `--` between contiguous groups of\n-\tmatches.\n-\n--<num>::\n-\tA shortcut for specifying `-C<num>`.\n-\n -p::\n --show-function::\n \tShow the preceding line that contains the function name of\n@@ -172,7 +163,24 @@ OPTIONS\n \tpatch hunk headers (see 'Defining a custom hunk-header' in\n \tlinkgit:gitattributes[5]).\n \n+-<num>::\n+-C <num>::\n+--context <num>::\n+\tShow <num> leading and trailing lines, and place a line\n+\tcontaining `--` between contiguous groups of matches.\n+\n+-A <num>::\n+--after-context <num>::\n+\tShow <num> trailing lines, and place a line containing\n+\t`--` between contiguous groups of matches.\n+\n+-B <num>::\n+--before-context <num>::\n+\tShow <num> leading lines, and place a line containing\n+\t`--` between contiguous groups of matches.\n+\n -W::\n+--function-context::\n \tShow the surrounding text from the previous line containing a\n \tfunction name up to the one before the next function name,\n \teffectively showing the whole function in which the match was\ndiff --git a/builtin/grep.c b/builtin/grep.c\nindex 1fae662..1851797 100644\n--- a/builtin/grep.c\n+++ b/builtin/grep.c\n@@ -827,18 +827,18 @@ int cmd_grep(int argc, const char **argv, const char *prefix)\n \t\tOPT_BOOLEAN(0, \"heading\", &opt.heading,\n \t\t\t\"show filename only once above matches from same file\"),\n \t\tOPT_GROUP(\"\"),\n-\t\tOPT_CALLBACK('C', NULL, &opt, \"n\",\n+\t\tOPT_CALLBACK('C', \"context\", &opt, \"n\",\n \t\t\t\"show <n> context lines before and after matches\",\n \t\t\tcontext_callback),\n-\t\tOPT_INTEGER('B', NULL, &opt.pre_context,\n+\t\tOPT_INTEGER('B', \"before-context\", &opt.pre_context,\n \t\t\t\"show <n> context lines before matches\"),\n-\t\tOPT_INTEGER('A', NULL, &opt.post_context,\n+\t\tOPT_INTEGER('A', \"after-context\", &opt.post_context,\n \t\t\t\"show <n> context lines after matches\"),\n \t\tOPT_NUMBER_CALLBACK(&opt, \"shortcut for -C NUM\",\n \t\t\tcontext_callback),\n \t\tOPT_BOOLEAN('p', \"show-function\", &opt.funcname,\n \t\t\t\"show a line with the function name before matches\"),\n-\t\tOPT_BOOLEAN('W', NULL, &opt.funcbody,\n+\t\tOPT_BOOLEAN('W', \"function-context\", &opt.funcbody,\n \t\t\t\"show the surrounding function\"),\n \t\tOPT_GROUP(\"\"),\n \t\tOPT_CALLBACK('f', NULL, &opt, \"file\",\n-- \n1.7.6\n"},{"id":"172614","messageId":"7vei14hgcd.fsf@alter.siamese.dyndns.org","threadId":"27970","inReplyTo":"4E36E075.20603@lsrfire.ath.cx","subject":"Re: [PATCH v2 1/2] grep: add option to show whole function as context","fromName":"Junio C Hamano","fromEmail":"gitster@pobox.com","sentAt":"2011-08-01T23:17:22Z","receivedAt":"2011-08-01T23:17:22Z","isPatch":true,"sender":{"key":"gitster@pobox.com","avatar":"https://avatars.githubusercontent.com/u/54884?v=4"},"body":"René Scharfe <rene.scharfe@lsrfire.ath.cx> writes:\n\n> Add a new option, -W, to show the whole surrounding function of a match.\n\nThanks, will queue both patches.\n\nIt feels somewhat dirty to take the range between the previous \"funcname\"\nand the next \"funcname\" and consider it the whole function, as if there is\nnothing outside the function, though. I certainly understand that this is\na natural and unfortunate consequence that \"funcname\" is a mechanism\ndesigned to mark only the _beginning_, and we didn't have any need for a\nmechanism to mark the _end_.\n\nI am not complaining; just making an observation.  I do not offhand have a\nsuggestion for improving this, and I think the obvious \"then let's come up\nwith another configuration to mark the end\" is not an improvement but\nmaking things worse, so...\n"},{"id":"172617","messageId":"20110802010143.GL13795@ece.pdx.edu","threadId":"27970","inReplyTo":"4E36E0EC.1000508@lsrfire.ath.cx","subject":"Re: [PATCH v2 2/2] grep: long context options","fromName":"Tait","fromEmail":"git.git@t41t.com","sentAt":"2011-08-02T01:01:43Z","receivedAt":"2011-08-02T01:01:43Z","isPatch":true,"sender":{"key":"git.git@t41t.com","avatar":null},"body":"René Scharfe <rene.scharfe_lsrfire.ath.cx> said (on 2011/08/01):\n> Take long option names for -A (--after-context), -B (--before-context)\n> and -C (--context) from GNU grep and add a similar long option name\n> for -W (--function-context).\n\nWhy not just add --context=function? Then when I want --context=indent\nto give context based on the indent-level, it is an intuitive extension\nof the existing options. (Of course, --context=<number> would still do\nexactly what it does now.)\n"},{"id":"172675","messageId":"4E3832B1.1030408@lsrfire.ath.cx","threadId":"27970","inReplyTo":"20110802010143.GL13795@ece.pdx.edu","subject":"Re: [PATCH v2 2/2] grep: long context options","fromName":"René Scharfe","fromEmail":"rene.scharfe@lsrfire.ath.cx","sentAt":"2011-08-02T17:24:01Z","receivedAt":"2011-08-02T17:24:01Z","isPatch":true,"sender":{"key":"l.s.r@web.de","avatar":"https://avatars.githubusercontent.com/u/26122331?v=4"},"body":"Am 02.08.2011 03:01, schrieb Tait:\n> René Scharfe <rene.scharfe_lsrfire.ath.cx> said (on 2011/08/01):\n>> Take long option names for -A (--after-context), -B (--before-context)\n>> and -C (--context) from GNU grep and add a similar long option name\n>> for -W (--function-context).\n> \n> Why not just add --context=function? Then when I want --context=indent\n> to give context based on the indent-level, it is an intuitive extension\n> of the existing options. (Of course, --context=<number> would still do\n> exactly what it does now.)\n\nWith the current patches, you can use --function-context together with\n--context=<num> to specify a minimum number of context lines to show,\neven beyond function boundaries.\n\nI'd expect a --context=function option to be equivalent to -W -C0 and\n--context=<num> to be equivalent to -C<num> --no-function-context, so\nthe syntax would be limited in that regard (or be unintuitive to me).\n\nWe can still add it on top, though.\n\nRené\n"},{"id":"172680","messageId":"4E383D32.5090604@lsrfire.ath.cx","threadId":"27970","inReplyTo":"7vei14hgcd.fsf@alter.siamese.dyndns.org","subject":"Re: [PATCH v2 1/2] grep: add option to show whole function as context","fromName":"René Scharfe","fromEmail":"rene.scharfe@lsrfire.ath.cx","sentAt":"2011-08-02T18:08:50Z","receivedAt":"2011-08-02T18:08:50Z","isPatch":true,"sender":{"key":"l.s.r@web.de","avatar":"https://avatars.githubusercontent.com/u/26122331?v=4"},"body":"Am 02.08.2011 01:17, schrieb Junio C Hamano:\n> René Scharfe <rene.scharfe@lsrfire.ath.cx> writes:\n> \n>> Add a new option, -W, to show the whole surrounding function of a match.\n> \n> Thanks, will queue both patches.\n> \n> It feels somewhat dirty to take the range between the previous \"funcname\"\n> and the next \"funcname\" and consider it the whole function, as if there is\n> nothing outside the function, though. I certainly understand that this is\n> a natural and unfortunate consequence that \"funcname\" is a mechanism\n> designed to mark only the _beginning_, and we didn't have any need for a\n> mechanism to mark the _end_.\n> \n> I am not complaining; just making an observation.  I do not offhand have a\n> suggestion for improving this, and I think the obvious \"then let's come up\n> with another configuration to mark the end\" is not an improvement but\n> making things worse, so...\n\nA certain amount of dirtyness is unavoidable unless we use a real\nparser.  Apropos, labels are function boundaries as well, so there we\nhave another limitation (i.e. we won't get a function whole if it\ncontains labels without leading whitespace).\n\nIdeally I'd like to see the whole function text up to the closing brace\nbut including any leading comments, if present.  Which is even more\ncomplicated, of course.\n\nFor C-style and Shell files, /^}/ would probably suffice as a regex to\nfind function endings..\n\nFirst I'm curious to see how useful the simple start-to-start heuristic\nis, though.  Even the -[ABC] options are kind of fuzzy -- how do you\nknow the number is high enough before running grep?  Let's see how far\nthis quick and dirty approach to present a smarter context can take us.\n\nRené\n"}]}