140

What is the command (or shortcut) to move a line up or down in vim? My current workflow is to yank (copy) the line and than delete that line and than to put (paste) that line.

2

8 Answers 8

139

First, you do not need to yank and delete; the latter will also put the deleted contents into the (default or specified) register. Therefore, ddp / ddkP are common commands to move a line one down / up.

Alternatively, you can use the :move command, i.e. :move +1 / :move -2; this doesn't clobber the register, and you can also move entire ranges. You can easily define key mappings to shorten this.

If you don't mind plugins (and the additional comfort that often comes with them), both Tim Pope's unimpaired plugin and my LineJuggler plugin provide ]e / [e mappings to move lines (and several more; Tim's for a variety of uses, mine focused on handling line(s)).

3
  • 1
    recommend using the move method, because its faster.
    – alexzander
    Jun 7, 2021 at 14:27
  • 1
    I got the +1 arg to move it 1 line forward. but why the heck do I need -2 to move it just 1 line backward? (-1 doesn't do anything apparently...)
    – hbobenicio
    Jul 31, 2023 at 13:38
  • 1
    @hbobenicio :help :move says Move the lines given by [range] to below the line given by {address}. -1 is the line above the current one, moving below it is a move to the original position, therefore a no-op. We need -2 to address the line above the one above the current line, to move to between that and the line above the current one. Aug 2, 2023 at 9:15
107

The easiest is: :m+ or :m-2 which is abbreviation for :move as Ingo suggested.

Or using visual mode (V) by cutting the line (d/x) then paste it (p - below cursor, P above cursor) after you moved your cursor to the right place before pasting (so in summary it's Vxp/Vdp).

When moving multiple lines in visual mode, then you've to use :m '>+1 (to move one line down) or :m '<-2 (to move one line up).


Here is sample useful mapping (Shift+ ↑/Shift+↓):

nnoremap <S-Up> :m-2<CR>
nnoremap <S-Down> :m+<CR>
inoremap <S-Up> <Esc>:m-2<CR>
inoremap <S-Down> <Esc>:m+<CR>

which is similar to Sublime Text (Win / OSX).

Here are some suggested at vim wikia:

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

In normal mode or in insert mode, press Alt-j to move the current line down, or press Alt-k to move the current line up.

After visually selecting a block of lines (for example, by pressing V then moving the cursor down), press Alt-j to move the whole block down, or press Alt-k to move the block up.

See also:

2
  • 2
    Don't know why, but they work very well in Gvim, but don't work as expected in terminal vim.(It seems it is the problem of tmux)
    – CodyChan
    Jul 10, 2019 at 6:26
  • 2
    note: in the wikia examples "==" and "gv=" are used to "fix" identation. I am a lot more pleasant to be around when vim doesn't "fix" the identation, maybe you are too. Aug 14, 2020 at 13:02
31

If I want to swap one line with the line above I usually do the following

ddkP

Explanation

  • dd will delete the line and add it to the default register.
  • k will move up a line (j would move down a line)
  • P will paste above the current line
1
  • 10
    To move current line down, use ddp
    – Qinjie
    Jan 12, 2018 at 8:02
9

FWIW, here is what I've used for years. It moves the current line up and down in normal mode or the selection in visual mode, while adjusting the indentation automatically.

nnoremap ,<Up>   :<C-u>silent! move-2<CR>==
nnoremap ,<Down> :<C-u>silent! move+<CR>==
xnoremap ,<Up>   :<C-u>silent! '<,'>move-2<CR>gv=gv
xnoremap ,<Down> :<C-u>silent! '<,'>move'>+<CR>gv=gv
2

The other answers using :move haven't considered the edge case where you are on the first line or last line of the buffer and press the shortcut, you will see error messages saying the address is invalid. To avoid this error message, I have written a simple function to deal with the edge cases:

fun SwitchLine(src_line_idx, direction)
    if a:direction ==# 'up'
        if a:src_line_idx == 1
            return
        endif
        move-2
    elseif a:direction ==# 'down'
        if a:src_line_idx == line('$')
            return
        endif
        move+1
    endif
endf

The mapping to use this function:

nnoremap <silent> <A-k> :call SwitchLine(line('.'), 'up')<CR>
nnoremap <silent> <A-j> :call SwitchLine(line('.'), 'down')<CR>

If you use the above mapping, you won't see unpleasant error messages when you are on the first or last line of the buffer.

1

Adding another answer because nobody else did:

If you want to go a bit ahead and move a whole range of lines, you can also do this in command mode by specifying

:<begin>,<end>m<target>

In other words, say you want to move lines 133-145 to line 70 (and below), simply enter

:133,145m70
2
  • 1
    Welcome to vi SE and thank you for leaving an answer. I have to point out a tiny typo, though: there should be a comma between begin and end, not a colon.
    – Friedrich
    May 12, 2023 at 6:35
  • 1
    @Friedrich thank you, I fixed it.
    – andreee
    May 12, 2023 at 19:08
0

This works for me if you want something simple:

" Move selection up
xmap <kMinus> :move '<-2<CR>gv
" Move selection down
xmap <kPlus> :move '>+1<CR>gv
0

Here’s one way:

  1. first press yy to copy line
  2. after press dd to delete line
  3. and finally press p to paste

That is, press yyddp.

4
  • 4
    why the yy beforehand? Sep 14, 2021 at 11:56
  • 1
    This is just ddp, due to deleting also setting the unnamed register. Yanking is useful if you want to set register 0 though
    – D. Ben Knoble
    Sep 14, 2021 at 17:25
  • @ChristianBrabandt when you want copy line you must first press yy to copy that line Sep 28, 2021 at 8:41
  • 2
    @piroozjenabi no, you don't.dd will generally make the content available in your registers! Sep 28, 2021 at 8:55

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.