Vim Registers

Vim isn’t like your standard text editor, and as such it has it’s own
jargon or vocabulary; Registers are closely related to copy, cut and paste
operations, as they are normally known, but in Vim it’s called yank, delete and
put, at first it might just seem silly but it does have a reason as it’s much
more versatile than a regular editor’s copy, cut and paste! If you are new to
Vim and don’t know about registers, this is a good day! Just get some coffee,
relax and read along as I guide you though the way of Vim.

I’ll start by explaining a bit about yank, delete and put. Yank is equivalent
to copy, you yank the contents of a selection and store it, the difference
is that in regular editors you only have one place to store it, if you copy
another text, the old one dissapears, in Vim you have several registers, which
give you so much more control! Delete is actually more related to the standard “cut”, as the text is removed but also it’s stored in a register. Finally put is equivalent to “paste” but you can choose which register to paste from.

Vim’s registers can be seen as a dictionary which associates a name to a
stored text, Vim stores a lot of your actions in registers, such as the last change you’ve made, the current file name, the last search, and such. You can see all registers by running the :registers command.

Every time you perform a yank, delete and put operation you are working with
a register, by default it’s the unnamed register, you can choose which
register to use by writing "<register-name> before the command, for example
"ayw will yank the current word under the cursor onto register a.
As you might have deduced you can create up to 26 registers, one for each
letter in the english alphabet, be careful of using other names, as some are
used by Vim and some are even readonly.

You can also explicitly use the unnamed register by writing "" before the
command, for example doing ""yw is exactly the same as doing yw. It’s not
like it’s practical but it’s good to know!

 Usage example

I’ll use a simple example to demonstrate the usage of registers, which is an
use case you most likely have had already. Consider the following code

var name = 'Mike';
someFunction(something);

Understanding the code is not important in this case, all we want to do is
replace something with name.

var name = 'Mike';
someFunction(name);

At first one would try to do something like
this (v represents the cursor position):

                  v
text:         var name = 'Mike';
command:      yiw
explanation:  yank inside word

                          v
text:         someFunction(something);
command:      jf(
explanation:  move down one line and position the cursor at the open parentheses

                           v
text:         someFunction();
command:      di(
explanation:  delete the text inside parentheses

                                   v
text:         someFunction(something);
command:      P
explanation:  put the word before the cursor position

Oops! What happened there!? We yanked name, but when we wanted to put it we
got something! This is because all operations share the same register by
default (the unnamed register ") so when we used di( the delete operation
used the unnamed register to store something, replacing name along the
way.

There are several ways to solve this, but now that we know how to use named
registers, let’s use that one!

                  v
text:         var name = 'Mike';
command:      yiw
explanation:  yank inside word

                          v
text:         someFunction(something);
command:      jf(
explanation:  move down one line and position the cursor at the open parentheses

                           v
text:         someFunction();
command:      "adi(
explanation:  delete the text inside parentheses and store it in the a register

                              v
text:         someFunction(name);
command:      P
explanation:  put the word before the cursor position

Ta da! Now it works! The magic happens in step 3 where we use the register
a to store the deleted text, instead of the unnamed register, so we don’t lose
our yanked text. Another alternative would have been using the a register
for the yank command instead of the delete command.

An alternative solution also using named registers could be as follows:

                  v
text:         var name = 'Mike';
command:      "ayiw
explanation:  yank inside word and store it in the a register

                          v
text:         someFunction(something);
command:      jf(
explanation:  move down one line and position the cursor at the open parentheses

                           v
text:         someFunction();
command:      di(
explanation:  delete the text inside parentheses

                              v
text:         someFunction(name);
command:      "aP
explanation:  put the text in the register a before the cursor position

This also works, but we require to specify the register twice instead of just
once, making it a bit longer and repetitive.

 Vim’s registers

Vim has several registers with non-letter names, such as 0, :, ., #,
etc. These registers are shortcuts which Vim manages on it’s own! For example,
the register 0 is used to store the text of yank commands, whenever you yank
it stores the text in the unnamed register, and also in the register 0,
which is normally called the yank register.

Knowing this, we can now solve our problem as follows

                  v
text:         var name = 'Mike';
command:      yiw
explanation:  yank inside word

                          v
text:         someFunction(something);
command:      jf(
explanation:  move down one line and position the cursor at the open parentheses

                           v
text:         someFunction();
command:      di(
explanation:  delete the text inside parentheses

                              v
text:         someFunction(name);
command:      "0P
explanation:  put the text in the yank register before the cursor position

Knowledge is power, don’t you think?

 The black hole register

This register is a black hole, it completely removes anything you send it.
It’s named _ and we could actually use this to solve our problem from before!

                  v
text:         var name = 'Mike';
command:      yiw
explanation:  yank inside word

                          v
text:         someFunction(something);
command:      jf(
explanation:  move down one line and position the cursor at the open parentheses

                           v
text:         someFunction();
command:      "_di(
explanation:  delete the text inside parentheses and send the contents to a mystical black hole

                              v
text:         someFunction(name);
command:      P
explanation:  put the word before the cursor position

This is pretty similar as we did with the a register but this time we
make sure there’s nothing there we can replace, as we’ll never be able to
put the contents of the black hole register!

 Using registers in Insert Mode

Another way to use registers is from Insert Mode, here we just do <Ctrl> + <R>
or <C-R> for short, and the name of the register to add it’s contents after
the cursor position.

Going back to our awesome overused example

                  v
text:         var name = 'Mike';
command:      yiw
explanation:  yank inside word

                          v
text:         someFunction(something);
command:      jf(
explanation:  move down one line and position the cursor at the open parentheses

                              v
text:         someFunction(name);
command:      ci(<c-r>0<esc>
explanation:  change the contents of the text inside parentheses, put the contents of the yank register (register 0) and go back to normal mode

As you can see the last step is pretty big, as we are actually doing two things
at once, changing the text and putting the text from the yank register.

 Yet another example

Using visual mode we can do something pretty similar as we did above, but
it might be more intuitive.

                  v
text:         var name = 'Mike';
command:      yiw
explanation:  yank inside word

                          v
text:         someFunction(something);
command:      jf(
explanation:  move down one line and position the cursor at the open parentheses

                              v
text:         someFunction(name);
command:      vi(p
explanation:  Using visual mode select the text inside the parentheses, then replace it with the content of the unnamed register

Because we are actually doing two steps at once we don’t have the problem of
the register beeing replaced up until we already replaced the word we wanted.
Once the word has been replaced the unnamed register will be something.

 The system clipboard register

Registers are nice and dandy but regular system programs do not have registers,
and sometimes you want to share data back and forth, for example, copying some
text from a website. This is what the + register does, it’s the system
register, you can write and read from it, to paste the contents of something
you copied onto vim you just do "+p from Normal Mode or <C-R>+ from
Insert Mode.

Writing text onto the system’s clipboard is also easy! Just using "+y will do.

 Using Ctrl + V and Ctrl + C in Vim

This is something pretty much all editors on Windows share and it’s sometimes
quite shocking not having these hotkeys, you can easily use them in Vim by
adding the following to your vimrc file

" Windows-like clipboard
vm <c-x> "+x
vm <c-c> "+y
cno <c-v> <c-r>+
exe 'ino <script> <C-V>' paste#paste_cmd['i']

 The expression register

The expression register is named = and it’s an exception, meaning this
register does not store text, but you can use it to evaluate a vimscript
expression and use the returned value.

For example, from insert mode you can do <c-r>= now the command line mode
enables, simply by entering 2+2 and pressing <enter> you will now
insert the result of that expression, in this case 4.

 Some other registers

Vim handles several registers, such as

%   - Name of the current file
#   - Name of the alternate file
.   - Last inserted text
:   - Last ex command
/   - Last search pattern

For a complete list of Vim’s registers just do :help registers.

 Conclusion

Registers are one of the many features which make Vim different from the rest,
and once you get used to it, it’s quite convenient! It enables you to do some
nifty things in no time with very little effort. A related topic if you want
to dive deeper is Macros, which I might explain in another post, as it would be
an overkill in this one! Personally I like to absorb one topic per day, and
steadily work on it.

I Hope you find this little article useful! Cheers!

 
72
Kudos
 
72
Kudos

Now read this

How to get an awesome PHP DevEnv in no time with Nitrous and Vim

I’ve been playing around with PHP development environments for quite some time now, and I’d like to share the last setup I’m working on, which I find quite portable and just plain awesome. This will not be an in-depth tutorial of all the... Continue →