Wikia

Vim Tips Wiki

Shell script to use grep with gvim

Talk0
1,613pages on
this wiki

This tip is deprecated for the following reasons:

Use Vim's built-in :grep or :vimgrep command instead.

See Find in files within Vim.


Tip 1392 Printable Monobook Previous Next

created November 21, 2006 · complexity basic · author Mauro · version 6.0


With bash or ksh add on .bashrc or on .kshrc:

function vimgrep
{
  vimgrep_temp_file=/tmp/vimgrep_$$.tmp
  find . \( -name "*.cc" -o -name "*.h" -o -name "*.i" -o -name "*.icc" \) -print -follow | grep -v "CVS/" | sed "s/ /\\\/g" | xargs egrep -H -n -e $* > $vimgrep_temp_file
  gvim -q $vimgrep_temp_file -c copen
  rm $vimgrep_temp_file
}

and type from shell:

$ vimgrep searchstring

In Vim you can set grepprg to vimgrep:

:set grepprg=vimgrep

CommentsEdit

fix: In Vim set grepprg=vimgrep where vimgrep is:

find . \( -name "*.cc" -o -name "*.h" -o -name "*.i" -o -name "*.icc" \) -print -follow | grep -v "CVS/" | sed "s/ /\\\/g" | xargs egrep -H -n -e

Why not use the built-in :vimgrep command?


Yes It's correct anyway If we want to grep recursively all the *.cc *.h *.i we have to redefine the grepprg corectly


If your shell is zsh, or another that supports similar extended globbing you can just use:

:grep foo **/*.c

to do pretty much the same thing.


I did something very similar to this a while ago, and I agree it's very useful to do this from the shell. However, because I use it in all kinds of ways, I prefer to just have the shell script vimgrep emulate grep exactly. So that I can do:

find /etc | xargs vimgrep userid (for example)

So my vimgrep shell script behaves just like grep does and takes all greps args. It also doesn't bother starting Vim if grep returns zero matches.

#!/bin/bash
date=`date +%s`;
grep -n "$@" > /tmp/grep-$date
fs=`du -b /tmp/grep-$date | cut -f1`
if [ $fs -gt 0 ]
then
  gvim -q /tmp/grep-$date
fi
rm /tmp/grep-$date

I have another variant of the above that's a little cleaner, a little nicer:

#!/bin/sh
if [ "$1" == "" ]; then
  echo "Usage : $0 <grep arguments>"
  echo "  eg: $0 -i string *.v"
  exit 255
fi
file=/tmp/vimgrep.$$
if grep -m 1 -l "$@" > $file; then
  echo "Calling vim on these files :"
  cat $file | sed -e 's/^/  /;'
  grep -n "$@" > $file
  vim -q $file
else
  echo "No match found."
fi
rm $file

I built on the above to allow grep to pipe to vim. It's nice to use like this

grep something * | grep -v removeotherthing | vimgrep

I open the temp file in vim so that I might edit it if I have to remove someotherthing and then save and cfile %.

#!/bin/sh
if [ "$1" == "-h" ]; then
    echo "Usage : $0 <grep arguments>"
    echo "  eg: $0 -i string *.v"
    echo "Usage : grep <args> | $0"
    exit 255
fi

file=/tmp/vimgrep.$$

if [ "$1" == "" ]; then
    cat > $file;
    fs=`du $file | cut -f1`
    if [ $fs -eq 0 ]; then
        echo "No match found."
        exit;
    else
        awk '/^[^:]+\:[0-9]+\:/ { exit 0; } NR == 2 {exit 1}' $file
        if [ "$?" -ne "0" ]; then
            echo "You must use grep -H -n to have the right format for vim."
            exit 1;
        fi
    fi
else
    if grep -m 1 -l "$@" > $file; then
        echo "Calling vim on these files :"
        cat $file | sed -e 's/^/  /;'
        grep -H -n "$@" > $file
    else
        echo "No match found."
        exit;
    fi
fi
vim $file -c "cfile $file" -c "copen" </dev/tty
rm $file

Around Wikia's network

Random Wiki