grep: add --heading
authorRené Scharfe <rene.scharfe@lsrfire.ath.cx>
Sun, 5 Jun 2011 15:24:36 +0000 (17:24 +0200)
committerJunio C Hamano <gitster@pobox.com>
Mon, 6 Jun 2011 01:15:27 +0000 (18:15 -0700)
With --heading, the filename is printed once before matches from that
file instead of at the start of each line, giving more screen space to
the actual search results.

This option is taken from ack (http://betterthangrep.com/).  And now
git grep can dress up like it:

$ git config alias.ack "grep --break --heading --line-number"

$ git ack -e --heading
Documentation/git-grep.txt
154:--heading::

t/t7810-grep.sh
785:test_expect_success 'grep --heading' '
786:    git grep --heading -e char -e lo_w hello.c hello_world >actual &&
808:    git grep --break --heading -n --color \

Signed-off-by: Rene Scharfe <rene.scharfe@lsrfire.ath.cx>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
Documentation/git-grep.txt
builtin/grep.c
grep.c
grep.h
t/t7810-grep.sh

index dea7cad0c2a617530be8fa132d9e14abbd9c1273..07b3c6a0866c5b4ff0b4653b462b332ea0d348c9 100644 (file)
@@ -151,6 +151,10 @@ OPTIONS
 --break::
        Print an empty line between matches from different files.
 
+--heading::
+       Show the filename above the matches in that file instead of
+       at the start of each shown line.
+
 -[ABC] <context>::
        Show `context` trailing (`A` -- after), or leading (`B`
        -- before), or both (`C` -- context) lines, and place a
index 42bb87f5446b129c1db3f8e6c23e5a058c641266..cccf8da6d2a600154536ea642250699d9356f148 100644 (file)
@@ -824,6 +824,8 @@ int cmd_grep(int argc, const char **argv, const char *prefix)
                OPT__COLOR(&opt.color, "highlight matches"),
                OPT_BOOLEAN(0, "break", &opt.file_break,
                        "print empty line between matches from different files"),
+               OPT_BOOLEAN(0, "heading", &opt.heading,
+                       "show filename only once above matches from same file"),
                OPT_GROUP(""),
                OPT_CALLBACK('C', NULL, &opt, "n",
                        "show <n> context lines before and after matches",
diff --git a/grep.c b/grep.c
index b0b860a984d6516caf960fae847aea6272959c20..04e9ba4ec46b9f2002135293ede1bc5570fa73dc 100644 (file)
--- a/grep.c
+++ b/grep.c
@@ -735,9 +735,13 @@ static void show_line(struct grep_opt *opt, char *bol, char *eol,
                        opt->output(opt, "\n", 1);
                }
        }
+       if (opt->heading && opt->last_shown == 0) {
+               output_color(opt, name, strlen(name), opt->color_filename);
+               opt->output(opt, "\n", 1);
+       }
        opt->last_shown = lno;
 
-       if (opt->pathname) {
+       if (!opt->heading && opt->pathname) {
                output_color(opt, name, strlen(name), opt->color_filename);
                output_sep(opt, sign);
        }
diff --git a/grep.h b/grep.h
index 638bee848d4fc36edb80e57fd8b8b550dc2c6e72..c5682973eaf696099b0d0367e21df6c0a4624836 100644 (file)
--- a/grep.h
+++ b/grep.h
@@ -111,6 +111,7 @@ struct grep_opt {
        unsigned last_shown;
        int show_hunk_mark;
        int file_break;
+       int heading;
        void *priv;
 
        void (*output)(struct grep_opt *opt, const void *data, size_t size);
index f55793e3cb25c731215c82d1b68ebca097670037..1227fa69b4840d6eb8f9e915d911fcddb55076dd 100755 (executable)
@@ -774,4 +774,41 @@ test_expect_success 'grep --break with context' '
        test_cmp expected actual
 '
 
+cat >expected <<EOF
+hello.c
+int main(int argc, const char **argv)
+       /* char ?? */
+hello_world
+Hello_world
+EOF
+
+test_expect_success 'grep --heading' '
+       git grep --heading -e char -e lo_w hello.c hello_world >actual &&
+       test_cmp expected actual
+'
+
+cat >expected <<EOF
+<BOLD;GREEN>hello.c<RESET>
+2:int main(int argc, const <BLACK;BYELLOW>char<RESET> **argv)
+6:     /* <BLACK;BYELLOW>char<RESET> ?? */
+
+<BOLD;GREEN>hello_world<RESET>
+3:Hel<BLACK;BYELLOW>lo_w<RESET>orld
+EOF
+
+test_expect_success 'mimic ack-grep --group' '
+       test_config color.grep.context          normal &&
+       test_config color.grep.filename         "bold green" &&
+       test_config color.grep.function         normal &&
+       test_config color.grep.linenumber       normal &&
+       test_config color.grep.match            "black yellow" &&
+       test_config color.grep.selected         normal &&
+       test_config color.grep.separator        normal &&
+
+       git grep --break --heading -n --color \
+               -e char -e lo_w hello.c hello_world |
+       test_decode_color >actual &&
+       test_cmp expected actual
+'
+
 test_done