Moving multiple lines in vim visual mode
Asked Answered
P

1

13

After pressing v and entering visual mode in , I would like to move those lines up a few rows. The solution discussed here does not suit me as I would like to move lines visually, i.e. I don't want to be typing m:+n as I don't know the value of n. Is there are keyboard shortcut that would allow me to move the selected lines in visual mode one line at time down or up by pressing the key sequence?

Sample with selected lines

Proffitt answered 11/12, 2016 at 9:8 Comment(0)
C
26

There's no built-in command for that but you could build one with :help :move.

First iteration

" move selected lines up one line
xnoremap <somekey>  :m-2<CR>

" move selected lines down one line
xnoremap <otherkey> :m'>+<CR>

Move line up

What we want is to move the selection between the line above the current one and the second line above the current one:

             current line - 2 > aaa
             current line - 1 > aaa
                 current line > bbb <
                                bbb < visual selection
                                bbb <
                                ccc
                                ccc

The right ex command is thus :m-2.

Move line down

The current line is not a good starting point because it's the first line in our selection but we can use the '> mark (end of visual selection):

                                aaa
                                aaa
                 current line > bbb <
                                bbb < visual selection
      end of visual selection > bbb <
  end of visual selection + 1 > ccc
                                ccc

The right ex command is thus :m'>+1.

But we lost our selection so we have to do gv to get it back before moving the selection again. Not good.

Second iteration

" move selected lines up one line
xnoremap <somekey>  :m-2<CR>gv

" move selected lines down one line
xnoremap <otherkey> :m'>+<CR>gv

Where we simply append gv to the end of our previous mapping. Neat. But what about fixing indentation as we go?

Third and last iteration

" move selected lines up one line
xnoremap <somekey>  :m-2<CR>gv=gv

" move selected lines down one line
xnoremap <otherkey> :m'>+<CR>gv=gv

Where appending =gv to our mappings fixes the indentation (:help v_=) and reselects our lines.

demo

Bonus normal mode mappings

" move current line up one line
nnoremap <somekey>  :<C-u>m-2<CR>==

" move current line down one line
nnoremap <otherkey> :<C-u>m+<CR>==
Courtyard answered 11/12, 2016 at 10:34 Comment(2)
Amazing answer thanks very much. To map those moves to Alt + arrow can I just type <Alt+Up>?Proffitt
Ideally yes but <Alt> is not reliable at all.Courtyard

© 2022 - 2024 — McMap. All rights reserved.