Move entire line up and down in Vim

后端 未结 19 974
无人及你
无人及你 2020-11-29 14:27

In Notepad++, I can use Ctrl + Shift + Up / Down to move the current line up and down. Is there a similar command to this in Vim?

相关标签:
19条回答
  • 2020-11-29 15:07

    can use command:

    :g/^/move 0
    

    reference: https://vi.stackexchange.com/questions/2105/how-to-reverse-the-order-of-lines

    0 讨论(0)
  • 2020-11-29 15:08

    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
    0 讨论(0)
  • 2020-11-29 15:08

    :m.+1 or :m.-2 would do if you're moving a single line. Here's my script to move multiple lines. In visual mode, Alt-up/Alt-down will move the lines containing the visual selection up/down by one line. In insert mode or normal mode, Alt-up/Alt-down will move the current line if no count prefix is given. If there's a count prefix, Alt-up/Alt-down will move that many lines beginning from the current line up/down by one line.

    function! MoveLines(offset) range
        let l:col = virtcol('.')
        let l:offset = str2nr(a:offset)
        exe 'silent! :' . a:firstline . ',' . a:lastline . 'm'
            \ . (l:offset > 0 ? a:lastline + l:offset : a:firstline + l:offset)
        exe 'normal ' . l:col . '|'
    endf
    
    imap <silent> <M-up> <C-O>:call MoveLines('-2')<CR>
    imap <silent> <M-down> <C-O>:call MoveLines('+1')<CR>
    nmap <silent> <M-up> :call MoveLines('-2')<CR>
    nmap <silent> <M-down> :call MoveLines('+1')<CR>
    vmap <silent> <M-up> :call MoveLines('-2')<CR>gv
    vmap <silent> <M-down> :call MoveLines('+1')<CR>gv
    
    0 讨论(0)
  • 2020-11-29 15:12

    When you hit command :help move in vim, here is the result:

    :[range]m[ove] {address} *:m* *:mo* *:move* *E134* Move the lines given by [range] to below the line given by {address}.

    E.g: Move current line one line down => :m+1.

    E.g: Move line with number 100 below the line with number 80 => :100 m 80.

    E.g: Move line with number 100 below the line with number 200 => :100 m 200.

    E.g: Move lines with number within [100, 120] below the line with number 200 => :100,120 m 200.

    0 讨论(0)
  • 2020-11-29 15:13

    Move a line up: ddkP

    Move a line down: ddp

    0 讨论(0)
  • 2020-11-29 15:15

    Put the following to your .vimrc to do the job

    noremap <c-s-up> :call feedkeys( line('.')==1 ? '' : 'ddkP' )<CR>
    noremap <c-s-down> ddp
    

    Disappearing of the line looks like a Vim bug. I put a hack to avoid it. Probably there is some more accurate solution.

    Update

    There are a lot of unexplained difficulties with just using Vim combinations. These are line missing and extra line jumping.

    So here is the scripting solution which can be placed either inside .vimrc or ~/.vim/plugin/swap_lines.vim

    function! s:swap_lines(n1, n2)
        let line1 = getline(a:n1)
        let line2 = getline(a:n2)
        call setline(a:n1, line2)
        call setline(a:n2, line1)
    endfunction
    
    function! s:swap_up()
        let n = line('.')
        if n == 1
            return
        endif
    
        call s:swap_lines(n, n - 1)
        exec n - 1
    endfunction
    
    function! s:swap_down()
        let n = line('.')
        if n == line('$')
            return
        endif
    
        call s:swap_lines(n, n + 1)
        exec n + 1
    endfunction
    
    noremap <silent> <c-s-up> :call <SID>swap_up()<CR>
    noremap <silent> <c-s-down> :call <SID>swap_down()<CR>
    
    0 讨论(0)
提交回复
热议问题