1

I want to have a key binding to yank the current line into the system clipboard. My current mapping is as follows:

nnoremap <C-y> "+yy

However, this also yanks the newline. I often use this to copy shell commands so an automatic "Enter/Return" is a big problem.

I've also tried using Vy instead of yy but that moves my cursor to the beginning of the line, but I don't want my cursor to move in the process. Same problem with 0y$.

How can I yank a line without also yanking the newline and/or moving the cursor?

2 Answers 2

3

One way you can accomplish this is by calling the setreg() function. You can also use the getline() function to get the contents of the current line, which is also convenient since it doesn't include the final newline.

For the specific case of yanking the current line:

call setreg('+', getline('.'))

And you can create a mapping for it with:

nnoremap <silent> <C-y> :call setreg('+', getline('.'))<CR>

Using the function call will not affect your cursor position in any way.

UPDATE: You can extend this definition to take a count (to work with 3<C-y> by passing getline() a second argument with the ending line, and using v:count1 to figure out the end line from the count.

UPDATE 2: We pass a second argument of v to setreg() to force characterwise mode, which means Vim will not add a final newline, even when multiple lines are yanked with a count.

nnoremap <silent> <C-y> :<C-u>call setreg('+',
    \ getline('.', line('.') + v:count1 - 1), 'v')<CR>

Perhaps it makes sense to create an analogous mapping for Visual mode (and Select mode). The one for Visual mode doesn't preserve the cursor position (since it drops the Visual selection), but it might still be useful in cases where you want to copy lines to the "+ register without having to count them.

I went with a definition that will always copy lines, even if the Visual selection is characterwise or blockwise. In a way that's convenient to implement using the same setreg() + getline() combo, but it might also be a reasonable way to define it anyways.

vnoremap <silent> <C-y> :<C-u>call setreg('+',
    \ getline("'<", "'>"), 'v')<CR>gV
4
  • Can this be used with a count e.g. 3<C-y>? It currently doesn't work as is when I append a count. Dec 7, 2020 at 11:30
  • @JohnZhau Updated the answer to include a mapping that works with a count. Also added an analogous mapping for Visual mode. I hope you find those helpful!
    – filbranden
    Dec 7, 2020 at 15:03
  • With the updated nmap with count, using it as is also yanks the newline like with yy. I've tried changing count1 - 1 to count1 - 2 and that works but only when used with a count. Without a count, it doesn't yank. Dec 8, 2020 at 2:45
  • Ah yes good point, I forgot about that requirement! I fixed it by passing an extra 'v' argument to setreg() to force characterwise mode (see :help setreg() and :help getregtype() for more details.)
    – filbranden
    Dec 8, 2020 at 3:43
1
nnoremap <c-y> mmVy`m

should work. mm marks the cursor position and after yanking with Vy, `m takes the cursor back to the original cursor position.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge that you have read and understand our privacy policy and code of conduct.

Not the answer you're looking for? Browse other questions tagged or ask your own question.