tharibo
tharibo

Reputation: 278

How to use vimgrep on several file extensions

So I'm working on a project with several resources: XML, javascript, QML, images, 3D scenes. I often want to search for patterns inside my project. Using vimgrep /mypattern/j ** is quite long, especially since it searches inside binary files. I could use

:vimgrep /mypattern/j *.xml
:vimgrepadd /mypattern/j *.js

But I would prefer to do it in one command.

Another way to look at it: how to prevent vimgrep to search inside binary files?

Upvotes: 13

Views: 3415

Answers (2)

alpha_989
alpha_989

Reputation: 5350

You can use a combination of vim, find and grep to perform very complicated searches. Here's an example:

:vim /pattern/g `find ~ \( -type f -regextype posix-extended -regex '.*js' -exec grep -lI '.*' {} \;`

Explanation of the commands:

find ~ \( -type f -regextype posix-extended -regex '.*js'

This enables you to define a starting directory to start your search, and then define a pattern on the filenames or dates that you want to search with.

-type f: defines that you should only look for files

-regextype posix-extended -regex '.*js': defines that you should search for file names that match the pattern .*js.

-exec grep -lI '.*' {} \;: this executes the grep command. This is needed because the find command doesn't have the ability to distinguish between binary and text files because it doesn't look inside files. grep does look inside files. The .* tells grep that any combination of characters are a match.

-lI: This indicates to grep to look at the first few bits and determine if the file is binary or not. If it is a binary file, it will just keep processing as if there is not match. -l here just prints out the name of the file name.

The entire command find ~ \( -type f -regextype posix-extended -regex '.*' -exec grep -lI '.*' {} \; is passed as an argslist to vim (http://vimcasts.org/episodes/meet-the-arglist/).


Advantage of this method:

  1. You don't have to define wildignore very careful to include all types of binary files
  2. You can keep the command in the saved commands, which is saved in .viminfo. By using q: you can bring up the previously entered ex mode commands and then search within the buffer to find this particular command and just change the necessary fields
  3. While you can do the same in the terminal, the advantage is that you have a quickfix list which is populated and you can just within the quickfix list with :cn
  4. While you are piping the command through multiple programs, the amount of actual execution time should be much lower, vim will not search through a lot of binary files which it will by default unless each and every binary file-type is listed.
  5. You don't have to maintain a large list of binary files to ignore in wildignore

You should still fill out wildignore carefully as @Ingo-karat pointed out because wildignore is used by a lot of program.


How can this be improved further

Instead of vimgrep, perhaps you can directly use gr and you may be able to directly provide the -lI arguments to it, through greprg. However, I haven't tried that yet.

Upvotes: 1

Ingo Karkat
Ingo Karkat

Reputation: 172510

You can pass multiple file globs to :vimgrep:

:vimgrep /mypattern/j *.xml *.js

To exclude certain files, you can configure the 'wildignore' option to exclude them, e.g.

:set wildignore=*.dll,*.exe

Upvotes: 20

Related Questions