The so called ‘kill ring’ is that the content you kill (delete or yank) in an editor will be stored in a stack like place. Later you could cycle through the items in the stack by pressing shortcuts without worrying about losing the text you killed previously.

There’re a lot plugins for vim to mimic this behavior, like yankstack.vim, yankring.vim. Unfortunately, these plugins change too much of vim’s default behavior and often conflict with many other plugins.

So I did a little research to see if I could achieve this function with vim’s built-in features, and it turns out vim’s register could fulfill my need easily.

The problem

A common editing scenario for me in vim is:

  1. yank something
  2. go to where I’d like to paste it
  3. delete what’s there
  4. paste what I thought was just yanked and find that the text deleted in step 3 was pasted instead

Vim’s registers

There’re several types of registers in vim. Those worth mentioning are:

  • The unnamed register ""
  • The yank register "0
  • The delete register "1 to "9
  • The small delete register "-

Vim fills the unnamed register "" with the text deleted or yanked regardless of whether or not a specific register is used (except the blackhole register). So the unnamed register almost always keeps the last killed text. And its content will be used for any put command if no register is specified. That’s where the problem arises from.

The numbered register "0 keeps the text from the most recently yank command, hence called yank register.

The numbered register "1 keeps the text from the most recently delete or change command. But if the text deleted is less than one line, the small delete register "- is used instead. After deleting successfully, vim shifts the content of "1 to "2, "2 to "3, and so forth, and the content of "9 is lost.

As for the delete registers, there’s one interesting feature of the repeat (dot) command, such that it will increase the number of the register used. For example, first you do "1p, if the content of register 1 is not what you want, you undo it by normal command u, then the following . (dot command) will act as "2p. Repeat the u. will effectively cycle through register 1 to 9.

The solution

With the aforementioned knowledge of vim registers, here’s the solution I came up with to fit my workflow.

let mapleader = "\<Space>"

nnoremap <Leader>0 "0p
nnoremap <Leader>1 "1p

Now my workflow was like:

  1. yank something
  2. go to target position
  3. delete what’s there
  4. press <Space>0 to paste the text yanked in step 1

And the extra bonus mapping <Leader>1 is for cycling through register 1 to 9 easily by first doing <Leader>1 and then doing u. repeatedly.

Conclusion

That’s it, with vim’s registers we could get what ‘killring’ brings us, though not perfectly, enough for my workflow.

For more information, please read vim’s help files!

:h registers

:h redo-register