Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Moving multiple lines in vim visual mode

After pressing v and entering visual mode in vim, 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

like image 874
Konrad Avatar asked Dec 11 '16 09:12

Konrad


1 Answers

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>==
like image 90
romainl Avatar answered Sep 20 '22 22:09

romainl