Peeter Joot's (OLD) Blog.

Math, physics, perl, and programming obscurity.

A vim -q Plus grep -n. An editor trick everybody should know.

Posted by peeterjoot on July 20, 2009

If you use vi as your editor (and by vi I assume vi == vim), then you want to know about the vim -q option, and grep -n to go with it.

This can be used to navigate through code (or other files) looking at matches to patterns of interest. Suppose you want to look at calls of strchr() that match some pattern. One way to do this is to find the subset of the files that are of interest. Say:

$ grep strchr.*ode sqle*ca*C
sqlecatd.C:                              sres = strchr(SQLZ_IDENT, (Uint8)nodename[i]);
sqlecatn.C:                  if ((sres = strchr(SQLZ_DBNAME, (Uint8)mode[0])) != NULL)
sqlecatn.C:                        sres = strchr(SQLZ_IDENT_AID, (Uint8)mode[i]);

and edit all those files, searching again for the pattern of interest in each file. If there aren’t many such matches, your job is easy and can be done manually. Suppose however that there’s 20 such matches, and 3 or 4 are of interest for editing, but you won’t know till you’ve seen them with a bit more context. What’s an easy way to go from one to the next? The trick is grep -n plus vim. Example:

$ grep -n strchr.*ode sqle*ca*C | tee grep.out
sqlecatd.C:710:                              sres = strchr(SQLZ_IDENT, (Uint8)nodename[i]);
sqlecatn.C:505:                  if ((sres = strchr(SQLZ_DBNAME, (Uint8)mode[0])) != NULL)
sqlecatn.C:518:                        sres = strchr(SQLZ_IDENT_AID, (Uint8)mode[i]);

$ vim -q grep.out

vim will bring you right to line 710 of sqlecatd.C in this case. To go to the next pattern, which will be in this case also in the next file, use the vim command

:cn

You can move backwards with :cN, and see where you are and the associated pattern with :cc

vim -q understands a lot of common filename/linenumber formats (and can probably be taught more but I haven’t tried that). Of particular utility is compile error output. Redirect your compilation error output (from gcc/g++ for example) to a file, and when that file is stripped down to just the error lines, you can navigate from error to error with ease (until you muck up the line numbers too much).

A small note. If you are grepping only one file, then the grep -n output won’t have the filename and vim -q will get confused. Example:

grep -n strchr.*ode sqlecatn.C
505:                  if ((sres = strchr(SQLZ_DBNAME, (Uint8)mode[0])) != NULL)
518:                        sres = strchr(SQLZ_IDENT_AID, (Uint8)mode[i]);

Here just include a filename that doesn’t exist in the grep command line string

grep -n strchr.*ode sqlecatn.C blah 2>/dev/null
sqlecatn.C:505:                  if ((sres = strchr(SQLZ_DBNAME, (Uint8)mode[0])) != NULL)
sqlecatn.C:518:                        sres = strchr(SQLZ_IDENT_AID, (Uint8)mode[i]);

I’m assuming here that you don’t have a file called blah in the current directory. The result is something that vim -q will still be happy about.

Advertisements

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s

 
%d bloggers like this: