2

In VSCode you can copy and paste selected lines of text up or down using Alt+Shift + Up or Down.

I switched to vim a few months ago, and I really miss this feature. I found out you can move selected lines in visual mode up or down using these visual mode bindings,

vnoremap J :m '>+1<CR>gv=gv
vnoremap K :m '<-2<CR>gv=gv

but it'd be great if you could copy and paste up and down as well without using yy and p because when you're done yanking, the cursor is placed at the initial position, exiting visual mode and reducing productivity.

romainl
  • 186,200
  • 21
  • 280
  • 313

1 Answers1

5

Well, that, here, is the problem with copying and pasting random snippets from the internet without understanding what they do: they are little black boxes that one can't modify or extend at will by lack of knowledge.

Let's deconstruct the first mapping:

vnoremap J :m '>+1<CR>gv=gv
  • :[range]m {address} moves the lines covered by [range] to below line {address}. Here, the range is automatically injected by Vim: '<,'> which means "from the first line of the latest visual selection to its last line", and the address is '>+1, meaning "the last line of the latest visual selection + 1 line". So :'<,'>m '>+1<CR> effectively moves the selected lines below themselves,
  • gv reselects the latest visual selection,
  • = indents it,
  • gv reselects it again for further Js or Ks.

Now, we want a similar mapping but for copying the given lines. Maybe we can start with :help :m and scroll around?

Sure enough we find :help :copy right above :help :move, which we can try right away:

xnoremap <key> :co '>+1<CR>gv=gv

Hmm, it doesn't really work the way we want but that was rather predictable:

  • the address is one line below the last line of the selection,
  • the selection is reselected and indented, which is pointless.

We can fix the first issue by removing the +1:

xnoremap <key> :co '><CR>gv=gv

and fix the second one by selecting the copied lines instead of reselecting the latest selection:

xnoremap <key> :co '><CR>V'[=gv

See :help :copy and :help '[.

romainl
  • 186,200
  • 21
  • 280
  • 313