Wednesday, April 9, 2008

More Global Fun

Today I had a friend ask me, "is there a way to load every line matching a pattern into a single register?" This lead me to look into a way to append to a register. I've come to find out that yanking something into a register using a capital rather than lowercase letter appends instead of overwriting the register. From there, it was just a matter of using the global command to invoke a yank on all the matches. Here's the result.

:%g/.*foo.*/normal "Ayy/

Note that `A and `a share the same register. So you can simply put using "ap (as usual). Another neat trick is a quick way to clear a register. Registers often persist among sessions (depending on your Vim setup). You can clear any register a to z as follows.

:let @a=@_

I knew there was a use for the blackhole register ;-).


Anonymous said...

Could you explain that a little?

I'm familiar with :%g/search/ meaning search the entire file for the search regex, but what does the rest do?

Travis Whitton said...

Sure. The global command works as follows:


in this context:

% - operate on the entire file
g - global command
/search pattern/

now you can give any ex command as [cmd] (see :help holy-grail for the complete list).

In this case, the ex command I used was "normal" which means to execute normal mode commands (normal mode being the mode you enter when you press Esc).

You can specify a register before a yank by using "(a through z). This pulls whatever was yanked into that register; however, I've recently learned that using an upper-case letter appends to the register rather than overwriting. In plain english the command (:%g/.*foo.*/normal "Z yy/) means:

Scan the entire file for the pattern foo, for every line matched, enter normal mode and append the enter line to register @z. The yy command simply yanks the current line.

Hope that helps and thanks for the comment.

Anonymous said... explain it well.

The "see :help topic" parts are good, they teach you how to fish for yourself with vim.


Will said...

Just so you know, % is the default range for :g[lobal], so that's unnecessary.

And instead of using :normal to do the yank, you can use the command-line version :y[ank].

Also, the .* in the search patter is unnecessary.

Better example:

:g/foo/y "Z

David said...

Minor correction to Will's comment: The :yank command doesn't use a " before the register. The correct command would be:

:g/foo/y Z

Also, don't forget to clear the register first!