Vim Y behavior and yankring
July 13, 2015
I’m a loyal Vi(m) soldier in the Editors Holy War, but unfortunately there are
some things on Vi(m) that just don’t make sense to me. One of those things is
the Y behavior.
One of the cool things about Vim is that there is a pattern, a logic that
governs those seemingly chaotic commands. It combines simple commands to perform
tasks (like d[elete]i[nner]w[ord] and d[elete]a[round]w[ord]) and keeps a
certain pattern on how those commands are modified (like d/c and D/C). The yank
command, however, deviates from this last rule in a kind of annoying way.
Just to recap, d command deletes text over motion, while c changes text over
motion (or more accurately, deletes and enter insert mode). So y, as expected,
yanks text over motion. Both d and c have a correspondent D and C
command that deletes/changes text from current position until the end of the
line. So, naturally, you would expect Y to do that same, however, instead it
will copy the whole line! Even Vim documentation acknowledges how illogical that
is.
Y
["x]Y yank [count] lines [into register x] (synonym for
yy, linewise). If you like "Y" to work from the
cursor to the end of line (which is more logical,
but not Vi-compatible) use ":map Y y$".
I’ve used that mapping the documentation suggests on my vimrc for so long that I
even forget that’s not the original behavior. So imagine my surprise when Y
suddenly stops working after I enabled a few new plugins the other day.
It turns out YankRing
was overriding my map and using the default Vi(m) Y behavior.
nnoremap Y :<C-U>YRYankCount 'Y'<CR>
Unfortunately yankring doesn’t have a clean way of customizing mappings it uses
for each yankring key, so it created a workaround with a function
YRRunAfterMaps(), which yankring calls after it has created the maps. So to
get my beloved Y mapping back, all I have to do is use this function to set
the correct mapping on my vimrc:
"make Y consistent with C and D on yankring
function! YRRunAfterMaps()
nnoremap <silent> Y :<C-U>YRYankCount 'y$'<CR>
endfunction