builtin/grep.c: add '--column' option to 'git-grep(1)'
Teach 'git-grep(1)' a new option, '--column', to show the column number of the first match on a non-context line. This makes it possible to teach 'contrib/git-jump/git-jump' how to seek to the first matching position of a grep match in your editor, and allows similar additional scripting capabilities. For example: $ git grep -n --column foo | head -n3 .clang-format:51:14:# myFunction(foo, bar, baz); .clang-format:64:7:# int foo(); .clang-format:75:8:# void foo() Signed-off-by: Taylor Blau <me@ttaylorr.com> Signed-off-by: Junio C Hamano <gitster@pobox.com>
Taylor Blau committed
Jun 22, 2018 at 10:49 UTC
a449f27ffa08de1b01ab5e4fe7daac38f25c9515
3 files changed
+101
-1
Documentation/git-grep.txt
+5
-1
@@ -13,7 +13,7 @@ SYNOPSIS
13
[-v | --invert-match] [-h|-H] [--full-name]
14
[-E | --extended-regexp] [-G | --basic-regexp]
15
[-P | --perl-regexp]
16
- [-F | --fixed-strings] [-n | --line-number]
16
+ [-F | --fixed-strings] [-n | --line-number] [--column]
17
[-l | --files-with-matches] [-L | --files-without-match]
18
[(-O | --open-files-in-pager) [<pager>]]
19
[-z | --null]
@@ -169,6 +169,10 @@ providing this option will cause it to die.
169
--line-number::
170
Prefix the line number to matching lines.
171
172
+--column::
173
+ Prefix the 1-indexed byte-offset of the first match from the start of the
174
+ matching line.
175
+
176
-l::
177
--files-with-matches::
178
--name-only::
builtin/grep.c
+1
@@ -828,6 +828,7 @@ int cmd_grep(int argc, const char **argv, const char *prefix)
828
GREP_PATTERN_TYPE_PCRE),
829
OPT_GROUP(""),
830
OPT_BOOL('n', "line-number", &opt.linenum, N_("show line numbers")),
831
+ OPT_BOOL(0, "column", &opt.columnnum, N_("show column number of first match")),
832
OPT_NEGBIT('h', NULL, &opt.pathname, N_("don't show filenames"), 1),
833
OPT_BIT('H', NULL, &opt.pathname, N_("show filenames"), 1),
834
OPT_NEGBIT(0, "full-name", &opt.relative,
t/t7810-grep.sh
+95
@@ -99,6 +99,101 @@ do
99
test_cmp expected actual
100
'
101
102
+ test_expect_success "grep -w $L (with --column)" '
103
+ {
104
+ echo ${HC}file:5:foo mmap bar
105
+ echo ${HC}file:14:foo_mmap bar mmap
106
+ echo ${HC}file:5:foo mmap bar_mmap
107
+ echo ${HC}file:14:foo_mmap bar mmap baz
108
+ } >expected &&
109
+ git grep --column -w -e mmap $H >actual &&
110
+ test_cmp expected actual
111
+ '
112
+
113
+ test_expect_success "grep -w $L (with --column, extended OR)" '
114
+ {
115
+ echo ${HC}file:14:foo_mmap bar mmap
116
+ echo ${HC}file:19:foo_mmap bar mmap baz
117
+ } >expected &&
118
+ git grep --column -w -e mmap$ --or -e baz $H >actual &&
119
+ test_cmp expected actual
120
+ '
121
+
122
+ test_expect_success "grep -w $L (with --column, --invert)" '
123
+ {
124
+ echo ${HC}file:1:foo mmap bar
125
+ echo ${HC}file:1:foo_mmap bar
126
+ echo ${HC}file:1:foo_mmap bar mmap
127
+ echo ${HC}file:1:foo mmap bar_mmap
128
+ } >expected &&
129
+ git grep --column --invert -w -e baz $H -- file >actual &&
130
+ test_cmp expected actual
131
+ '
132
+
133
+ test_expect_success "grep $L (with --column, --invert, extended OR)" '
134
+ {
135
+ echo ${HC}hello_world:6:HeLLo_world
136
+ } >expected &&
137
+ git grep --column --invert -e ll --or --not -e _ $H -- hello_world \
138
+ >actual &&
139
+ test_cmp expected actual
140
+ '
141
+
142
+ test_expect_success "grep $L (with --column, --invert, extended AND)" '
143
+ {
144
+ echo ${HC}hello_world:3:Hello world
145
+ echo ${HC}hello_world:3:Hello_world
146
+ echo ${HC}hello_world:6:HeLLo_world
147
+ } >expected &&
148
+ git grep --column --invert --not -e _ --and --not -e ll $H -- hello_world \
149
+ >actual &&
150
+ test_cmp expected actual
151
+ '
152
+
153
+ test_expect_success "grep $L (with --column, double-negation)" '
154
+ {
155
+ echo ${HC}file:1:foo_mmap bar mmap baz
156
+ } >expected &&
157
+ git grep --column --not \( --not -e foo --or --not -e baz \) $H -- file \
158
+ >actual &&
159
+ test_cmp expected actual
160
+ '
161
+
162
+ test_expect_success "grep -w $L (with --column, -C)" '
163
+ {
164
+ echo ${HC}file:5:foo mmap bar
165
+ echo ${HC}file-foo_mmap bar
166
+ echo ${HC}file:14:foo_mmap bar mmap
167
+ echo ${HC}file:5:foo mmap bar_mmap
168
+ echo ${HC}file:14:foo_mmap bar mmap baz
169
+ } >expected &&
170
+ git grep --column -w -C1 -e mmap $H >actual &&
171
+ test_cmp expected actual
172
+ '
173
+
174
+ test_expect_success "grep -w $L (with --line-number, --column)" '
175
+ {
176
+ echo ${HC}file:1:5:foo mmap bar
177
+ echo ${HC}file:3:14:foo_mmap bar mmap
178
+ echo ${HC}file:4:5:foo mmap bar_mmap
179
+ echo ${HC}file:5:14:foo_mmap bar mmap baz
180
+ } >expected &&
181
+ git grep -n --column -w -e mmap $H >actual &&
182
+ test_cmp expected actual
183
+ '
184
+
185
+ test_expect_success "grep -w $L (with non-extended patterns, --column)" '
186
+ {
187
+ echo ${HC}file:5:foo mmap bar
188
+ echo ${HC}file:10:foo_mmap bar
189
+ echo ${HC}file:10:foo_mmap bar mmap
190
+ echo ${HC}file:5:foo mmap bar_mmap
191
+ echo ${HC}file:10:foo_mmap bar mmap baz
192
+ } >expected &&
193
+ git grep --column -w -e bar -e mmap $H >actual &&
194
+ test_cmp expected actual
195
+ '
196
+
197
test_expect_success "grep -w $L" '
198
{
199
echo ${HC}file:1:foo mmap bar