Quantcast
Viewing all articles
Browse latest Browse all 10

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 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!


Viewing all articles
Browse latest Browse all 10

Trending Articles