created January 3, 2002 · complexity intermediate · author Kontra Gergely · version 5.7
Swapping a line with the line directly above or below it is a common task when writing computer software. This tip provides some mappings for normal, insert and visual modes which make this more easily accomplished.
function! MoveLineUp() call MoveLineOrVisualUp(".", "") endfunction function! MoveLineDown() call MoveLineOrVisualDown(".", "") endfunction function! MoveVisualUp() call MoveLineOrVisualUp("'<", "'<,'>") normal gv endfunction function! MoveVisualDown() call MoveLineOrVisualDown("'>", "'<,'>") normal gv endfunction function! MoveLineOrVisualUp(line_getter, range) let l_num = line(a:line_getter) if l_num - v:count1 - 1 < 0 let move_arg = "0" else let move_arg = a:line_getter." -".(v:count1 + 1) endif call MoveLineOrVisualUpOrDown(a:range."move ".move_arg) endfunction function! MoveLineOrVisualDown(line_getter, range) let l_num = line(a:line_getter) if l_num + v:count1 > line("$") let move_arg = "$" else let move_arg = a:line_getter." +".v:count1 endif call MoveLineOrVisualUpOrDown(a:range."move ".move_arg) endfunction function! MoveLineOrVisualUpOrDown(move_arg) let col_num = virtcol(".") execute "silent! ".a:move_arg execute "normal! ".col_num."|" endfunction nnoremap <silent> <C-Up> :<C-u>call MoveLineUp()<CR> nnoremap <silent> <C-Down> :<C-u>call MoveLineDown()<CR> inoremap <silent> <C-Up> <C-o>:<C-u>call MoveLineUp()<CR> inoremap <silent> <C-Down> <C-o>:<C-u>call MoveLineDown()<CR> vnoremap <silent> <C-Up> :<C-u>call MoveVisualUp()<CR> vnoremap <silent> <C-Down> :<C-u>call MoveVisualDown()<CR>
The above mappings all take a count so 5<C-Up> would move the current line (or visual selection) 5 lines up.
They make use of the :move command to do the movement which avoids overwritting a register which other methods may suffer from. As :move wont move a line to an invalid location an extra check is made to move no further than the start (or end) of the file. The mappings are also careful to restore the original cursor location in the line (or selection) by first getting it with virtcol() and then restoring it with |.