How do I swap two lines in vim?
VimVim 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.