16

I want to get automatically to the positions of the results in Vim after grepping, on command line. Is there such feature?

Files to open in Vim on the lines given by grep:

% grep --colour -n checkWordInFile *
SearchToUser.java:170:  public boolean checkWordInFile(String word, File file) {
SearchToUser.java~:17:  public boolean checkWordInFile(String word, File file) {
SearchToUser.java~:41:          if(checkWordInFile(word, f))
hhh
  • 50,788
  • 62
  • 179
  • 282
  • 3
    what's wrong with `:grep` and the quick fix buffer (`:copen`)? – Benjamin Bannier Apr 16 '10 at 14:29
  • Thanks @BenjaminBannier how do you use `:copen` with `git grep`? – Paul Rougieux May 08 '20 at 10:57
  • @PaulRougieux In general see https://stackoverflow.com/questions/18115534/vim-redirect-output-to-quickfix, but for `git grep` I personally would go with https://github.com/tpope/vim-fugitive/blob/master/doc/fugitive.txt#L91 (and even for other shell commands I'd probably use https://github.com/tpope/vim-dispatch). – Benjamin Bannier May 08 '20 at 13:06

8 Answers8

29

If you pipe the output from grep into vim

% grep -n checkWordInFile * | vim -

you can put the cursor on the filename and hit gF to jump to the line in that file that's referenced by that line of grep output. ^WF will open it in a new window.

From within vim you can do the same thing with

:tabedit
:r !grep -n checkWordInFile *

which is equivalent to but less convenient than

:lgrep checkWordInFile *
:lopen

which brings up the superfantastic quickfix window so you can conveniently browse through search results.

You can alternatively get slower but in-some-ways-more-flexible results by using vim's native grep:

:lvimgrep checkWordInFile *
:lopen

This one uses vim REs and paths (eg allowing **). It can take 2-4 times longer to run (maybe more), but you get to use fancy \(\)\@<=s and birds of a feather.

intuited
  • 23,174
  • 7
  • 66
  • 88
  • :lp, :lnf to browse in quickfix list. If :grep, then use :cn and :cp. Cannot see any difference btw :lgrep and grep, instead of different moving commands. – hhh Apr 17 '10 at 10:52
  • :lopen for :lgrep and :copen for :grep. – hhh Apr 17 '10 at 10:54
  • lgrep creates a separate list for the current tab. Otherwise you end up clobbering the same global list if you do `:grep`s from different tabs. At least I think so; I usually use `lvimgrep` or `r !grep...` and just added `:lgrep` in here for the sake of completeness. I guess `*open` is not really within the scope of the question actually, that's just how I usually roll. – intuited Apr 17 '10 at 11:33
  • err actually it's for the current window, not tab. – intuited Apr 17 '10 at 11:52
  • hnnnnngggghhhh incredible! – ThePosey Feb 18 '14 at 19:25
  • 1
    *put the cursor on the filename and hit `gF`* --> doesn't work for me.. Any configuration to enable this? I don't see result by using these commands. Any specific vim version for this? I am using VIM8 – mtk Oct 04 '17 at 07:01
  • Pressing gf reading this way from stdin, I had an error `E37: No write since last change (add ! to override)` , however I overcame it by a readonly flag -R https://vi.stackexchange.com/a/2728/11459 , `% grep -n checkWordInFile * | vim -R -` – FantomX1 Oct 23 '20 at 14:58
9

Have a look at "Grep search tools integration with Vim" and "Find in files within Vim". Basically vim provides these commands for searching files:

:grep
:lgrep
:vimgrep
:lvimgrep

The articles feature more information regarding their usage.

the Tin Man
  • 158,662
  • 42
  • 215
  • 303
Bozhidar Batsov
  • 55,802
  • 13
  • 100
  • 117
5

I think this is what you are looking for:

http://www.vim.org/scripts/script.php?script_id=2184

When you open a file:line, for instance when coping and pasting from an error from your compiler (or grep output) vim tries to open a file with a colon in its name. With this little script in your plugins folder if the stuff after the colon is a number and a file exists with the name especified before the colon vim will open this file and take you to the line you wished in the first place.

It's definitely what I was looking for.

Mike McKay
  • 2,388
  • 1
  • 29
  • 32
5

You could do this:

% vim "+/checkWordInFile" $(grep -l checkWordInFile *)

This will put in the vim command line a list of all the files that match the regex. The "+/..." option will tell vim to search from the start of each file until it finds the first line that matches the regex.

Correction:

The +/... option will only search the first file for the regex. To search in every file you need this:

% vim "-c bufdo /checkWordInFile" $(grep -l checkWordInFile *)

If this is something you need to do often you could write a bash function so that you only need to specify the regex once (assuming that the regex is valid for both grep and vim).

Dave Kirby
  • 25,806
  • 5
  • 67
  • 84
2

You probably want to make functions for these. :)

Sequential vim calls (console)

grep -rn "implements" app | # Or any (with "-n") you like
  awk '{
    split($0,a,":"); # split on ":"
    print "</dev/tty vim", a[1], "+" a[2] # results in lines with "</dev/tty vim <foundfile> +<linenumber>
  }' |
  parallel --halt-on-error 1 -j1 --tty bash -ec # halt on error and "-e" important to make it possible to quit in the middle

Use :cq from vim to stop editing.

Concurrent opening in tabs (gvim)

Start the server:

gvim --servername GVIM

Open the tabs:

grep -rn "implements" app | # again, any grep you like (with "-n")
  awk "{ # double quotes because of $PWD
    split(\$0,a,\":\"); # split on ":"
    print \":tabedit $PWD/\" a[1] \"<CR>\" a[2] \"G\" # Vim commands. Open file, then jump to line
  }" | 
  parallel gvim --servername GVIM --remote-send # of course the servername needs to match
Janus Troelsen
  • 20,267
  • 14
  • 135
  • 196
2

I highly recommend ack.vim over grep for this functionality.

http://github.com/mileszs/ack.vim

http://betterthangrep.com/

Logan Koester
  • 1,126
  • 8
  • 22
1

If you use git, results are often more meaningful when you search only in the files tracked by git. To open files at the given line which is a search result of git grep in vim you will need the fugitive plugin, then

:copen
:Ggrep pattern

Will give you the list in a buffer and you can choose to open files from your git grep results.

Paul Rougieux
  • 10,289
  • 4
  • 68
  • 110
-3

In this particular example:

vim SearchToUser.java +170