Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to use vimgrep on several file extensions

Tags:

vim

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?

like image 702
tharibo Avatar asked Sep 24 '13 09:09

tharibo


1 Answers

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.

like image 161
alpha_989 Avatar answered Nov 16 '22 02:11

alpha_989