views:

217

answers:

2

Is there a way in Vim (or a plugin) to search for a term and iterate through the search results (as per n in Vim), by column, rather than row? So if my file was this:

foo1  bar   bar
baz   baz   foo3
baz   baz   foo4
foo2  bar   bar

If I search for foo I want to iterate through the results in order 1,2,3,4. Normally n would move me through them in order 1,3,4,2.

I want this for example to browse through search results in a huge fixed-width data file or CSV file, where columns represent fields.

(I'll also settle for a way to do it in Emacs instead. :)

+2  A: 

EDIT: I just found an overview of using vim regular expressions for tables here. That's a lot cleaner than my amateur attempt (although this works too ;)):

searching for ^foo will search the first column, while searching for .*\ foo will search the second column, and .*\ .*\ foo will search the third.

This is not complete of course since it matches a whole block from the start of the line, so it will find foo3 and foo4 but puts the cursor at position 0.

You can however automate this with the recording function. Type exactly the following in normal mode:

qa/.*\ .*\ foo
/foo
q

(where I have used new lines to indicate you should hit the return key).

This puts two searches under the a register (qa starts recording under a, qb under b, etc). Now hit @a and you should search only the third column....

I'm sure you can turn this into a command that takes a column number, but I'm off now, sorry :)

yungchin
+2  A: 

After seeing this question I decided to try and write a vim plugin to handle it. It's my first vim plugin, so it's probably very bad. However, it does work for the example you gave.

You can download the plugin from vim.org: SearchCols.vim

Note that it also requires the multvals plugin from the same site: multvals.vim

It creates a command :SearchCols <string>, which can be used to search for the <string> in fixed-width columns so that the search looks in the first column first, then the second column, etc. rather than the row-by-row search which is standard for vim. Repeat the command via @: and then @@ since it's a colon-command.

Assumptions:

  • Assumes that your file is formatted with whitespace-delimited fixed width columns, i.e. there are no spaces inside the data items, only in between them.
  • Assumes that the first line of your file is formatted so that the column widths can be deduced from it.

Obvious improvements that I can think of would be to make searching for the next item easier than using @: and @@, including search highlighting (the code is there but it's commented out because it uses :match and you would have to use :match none to turn it off), and eliminating the dependency on multvals.vim.

Adam Bellaire