How do I swap two lines in vim?

Vim

Vim Problem Overview


I have this:

pick 887b66f add 222 Dziewiecsil to flowers new title
pick dc331cb new name of beginning commit

And I want to get this:

pick dc331cb new name of beginning commit
pick 887b66f add 222 Dziewiecsil to flowers new title

Is there a way to do this in a quick way using keyboard shortcuts?

Vim Solutions


Solution 1 - Vim

To swap the current line with the next one, type ddp while in command mode.

  • dd - delete line (actually called cut in other editors) and save it in register
  • p - paste line from register

Solution 2 - Vim

dd deletes the current line, then you can paste the removed line using p. There's another way though using m. With m you can move lines around i.e.

:m 1 will move the current line after line 1

:m 0 will move the current line to top

:m $ will move the current line to bottom

In your example, place the cursor in the first line and type :m $

More info: http://vim.wikia.com/wiki/Moving_lines_up_or_down

Solution 3 - Vim

Despite the fact that question is quite old and marked as answered, I'd like to extend the answer by saying that you can use normal mode commands, which were provided by Sven Marnach with nnoremap like so:

:nnoremap <C-Up> <Up>ddp<Up>
:nnoremap <C-Down> ddp

This will allow you to move lines with Ctrl + Up and Ctrl + Down within your file. However this will overwrite @" register, which stores your last copied string/word/letter/etc. So by adding "(reg) before dd and p commands we can fix this:

:nnoremap <C-Up> <Up>"add"ap<Up>
:nnoremap <C-Down> "add"ap

Here we add "a before delete and paste commands to store our line in @a register, so your default copy register will not be overwritten. However it may overwrite contents of @a register (who knows, but you may use it for something important in your use-case, but this step bit paranoid, you can skip it if you want to), let's fix that too:

:nnoremap <silent><C-Up> :let save_a=@a<Cr><Up>"add"ap<Up>:let @a=save_a<Cr>
:nnoremap <silent><C-Down> :let save_a=@a<Cr>"add"ap:let @a=save_a<Cr>

(<silent> needed to prevent echoing our commands to message-line at the bottom.)

Now we have two mappings which allow us to move lines within the file with keyboard shortcuts. You can redefine buttons, I use Alt + j/k, which would be <A-j> and <A-k> for those commands. However not all terminal emulators support Alt key mappings AFAIK.

Solution 4 - Vim

Example:

  1. one
> 2. two

with :m-2, switch (current line - 2)

> 2. two
  1. one

with :m+1 switch (current line + 1)

  1. one
> 2. two

You could map this if you want.

Solution 5 - Vim

The mappings proposed in the Vim wikia page are actually the best way to map key combinations that emulate the way Sublime and other editors implement this feature.

This includes an indentation action after the move, which is also great (that's the double equal == signs, in case you don't want that).

It also supports visual and insert modes, so that you can move lines while editing or with fulblocks.

nnoremap <A-j> :m .+1<CR>==
nnoremap <A-k> :m .-2<CR>==
inoremap <A-j> <Esc>:m .+1<CR>==gi
inoremap <A-k> <Esc>:m .-2<CR>==gi
vnoremap <A-j> :m '>+1<CR>gv=gv
vnoremap <A-k> :m '<-2<CR>gv=gv

I personally mapped them to <D-J> and <D-K> on my Mac, instead of <A- which maps to the Alt key. That way I use Cmd + Shift + j/k, which feels more natural to my fingertips.

Attributions

All content for this solution is sourced from the original question on Stackoverflow.

The content on this page is licensed under the Attribution-ShareAlike 4.0 International (CC BY-SA 4.0) license.

Content TypeOriginal AuthorOriginal Content on Stackoverflow
QuestionBartłomiej SemańczykView Question on Stackoverflow
Solution 1 - VimSven MarnachView Answer on Stackoverflow
Solution 2 - VimMr. EigenbartView Answer on Stackoverflow
Solution 3 - Vimuser9801105View Answer on Stackoverflow
Solution 4 - VimcjadeveloperView Answer on Stackoverflow
Solution 5 - VimojosilvaView Answer on Stackoverflow