January 17, 2020.
I want to write about an annoying behaviour of vim editor when copying and pasting text. For some time, I lived with this fact, resisted to dig it out and understand the root cause but now the time has come to uncover it.
I tried the demonstrate the case in a screencast. I have vim started in the project root and a module called
otp/core.py is in the current window. In this module, there is a function
progress() that starts on line 61 and does some stuff. Since it’s been tested and works well, I want to make it more flexible and overload it. To do that, I will first copy the whole function so I go to line line 61 and yank it till the end by hitting
13yy. Just before calling the paste command, 3 blank lines gets my eye so I go one line up and clear it with
3dd. Ready to paste above the cursor line and pressing
shift+p. Well, the result is not quite what I expected because it didn’t work out. 3 blank lines got back as if resurrected. It’s useless to
undo, the copy is long gone away.
What happened? delete, yank and put commands in vim make use of a special text holder called register. These commands do not only carry out what they claim, also put the resulting text into the register.
dd command, for instance. It not only deletes the whole line but it also stores the output in a specific register. To read the line from this register, I press
p which is paste or put command. This register is called the unnamed register. In fact, registers can be referenced by name, but this is done in explicit way. When I run put command, I don’t necessarily need to specify any name in which case the default unnamed register is referenced. The same register can be considered as a shared place across different commands. This is not good because it can get easily overwritten if mixed between different commands, delete, cut, copy etc. This is exactly just what happened to me in screencast.
Besides the default register, I can provide a register name next to the command in the context. I do that by prefixing actual command with a register name. And this name here is a single letter in the range of [a-z] and specified in the form
"[a-z]. For example, to yank current line into a named register
t, I hit
"tyy. This puts the output into a register named t. put works the same way - I just prefix command with the register name
"tp to read the line.
Again, if I don’t specify any, vim falls back to the default built-in unnamed egister. Similar to unnamed one, there are other built-in registers in vim.
One of them is the so-called yank register which accompanies yank commands only. This register is denoted with
"0. I don’t need to specify it when yanking though, vim puts the text there for me anyway, by default. But, it’s good to know that the text also goes to the unnamed register because I didn’t specify any. yank register provides a more reliable way to paste text as it’s limited to yank commands and others cannot touch there. yank register is good, I use it often. Lastly, here is a quick overview of some registers.