Vim에서 전체 라인을 위아래로 이동


311

메모장 ++에서는 Ctrl+ Shift+ Up/ Down를 사용 하여 현재 줄을 위아래로 이동할 수 있습니다 . Vim에서도 이와 비슷한 명령이 있습니까? 나는 끝없는 가이드를 보았지만 아무것도 찾지 못했습니다.

없는 경우 해당 키 조합에 작업을 어떻게 바인딩 할 수 있습니까?

편집 : Mykola의 대답은 버퍼의 시작과 끝을 제외한 모든 줄에 적용됩니다. 첫 번째 줄을 위로 올리거나 맨 아래 줄을 아래로 내리면 줄이 삭제되고 맨 아래 줄을 위로 올리면 폰처럼 처음 두 칸씩 점프합니다! 누구나 개선을 제안 할 수 있습니까?


스크립팅 솔루션을 구현하는 것 외에는 선택의 여지가 없었습니다. 나는 그것이 당신의 요구에 깨끗하고 채택되기를 바랍니다.
Mykola Golubyev

31
미래의 아이들을 위해 : vim.wikia.com/wiki/Moving_lines_up_or_down

왜 스크립트가 필요한지 잘 모르겠습니다. Wikia 기사 예제가 작동합니다. 3 가지 매핑 모드가있는 Wikia의 예제가 다소 까다로울 수 있기 때문에 단순화 된 버전을 게시했습니다. 블록 선택 매핑 만 사용하는 경우 단순히 선택 (Shift V)을 차단하고 사용하는 것을 기억할 수 있습니다 바로 가기 (아래 내 답변 참조)

주제에 대한 스크린 캐스트 : vimcasts.org/e/26
glts

또한 vi SE
cfi

답변:


81

.vimrc에 다음을 넣어 작업을 수행하십시오.

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

줄이 사라지면 Vim 버그처럼 보입니다. 나는 그것을 피하기 위해 핵을 두었다. 아마도 더 정확한 해결책이있을 것입니다.

최신 정보

Vim 조합 만 사용하면 설명 할 수없는 어려움이 많이 있습니다. 이것들은 라인이 누락되고 여분의 라인 점프입니다.

.vimrc 또는 ~ / .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>

1
설정과 충돌이있는 것처럼 보이는 <cj>와 <ck>로 변경해야했지만 환상적인 답변입니다! 정말 감사합니다
user4812

1
감사합니다, git rebase --interactive. <cj>와 <ck>에 바인딩했습니다. cs-up / down이 작동하지 않았습니다.
Lari Hotari

2
누군가가 다른 지름길을 원한다면 : c는 통제를위한 것이고, A는 대체를위한 것입니다, 나는 <A-up>일식에서 사용되는 것처럼 사용합니다.
jan

1
사라지는 라인은 Vim 버그가 아닙니다! 오히려 ddkP문서의 마지막 줄 에서 수행되기 때문 입니다. 3 줄 파일로 직접 사용해보십시오. 이러한 문제를 피하려면 :mVim 위키에 제공된 훨씬 쉬운 매핑을 사용하십시오 .
Sroo Stroobandt

1
나는에 마지막으로 라인을 변경 <A-up>하고 <A-down>하지만 시각적 실행에 정력에 그 열쇠를하려고 할 때 TMUX 선택 사라지고 커서가 이동 줄; 선택된 선을 움직이지 않고
Konrad

574

한 줄을 위의 줄로 바꾸려면 일반적으로 다음을 수행하십시오.

ddkP

설명

  • dd는 행을 삭제하고 기본 레지스터에 추가합니다.
  • k는 한 줄 위로 이동합니다 (j는 줄 아래로 이동합니다)
  • P는 현재 줄 위에 붙여 넣습니다.

5
그리고 항상 사용 가능합니다. :-)
Henno

71
그리고 ddp줄을 아래로 이동하려면 (줄을 삭제하고 현재 줄 아래에 붙여 넣기)
bcoughlan

2
여러 줄을 이동하려면 4라고 말한 4 dd다음 2 줄로 이동 한 다음 :2붙여 넣기하려는 위치 로 이동하십시오 P.
Guru

2
@Guru가 4dd대신 해야 4 dd합니까?
패트릭 맥도날드

3
그리고 dd<number>jp현재 줄 <number> +1 줄을 아래로 이동합니다. 그리고 dd<number>kp현재 줄 <number> 개를 위로 이동합니다.
egelev

230

커서가 이동하려는 행에 있다고 가정합니다.

위아래 :m로 이동 : 이동

:m +1 -한 줄 아래로 이동

:m -2 -한 줄 위로 이동

(위 또는 아래로 이동하려는 행 수에 따라 +1을 임의의 숫자로 바꿀 수 있습니다. 즉, +2는 2 행 아래로 이동하고, -3은 2 행 위로 이동합니다)

특정 줄로 이동

:set number -번호 줄 표시 (이동하는 위치를 더 쉽게 볼 수 있음)

:m 3 -세 번째 줄 다음으로 줄을 이동하십시오 (3을 원하는 줄로 바꾸십시오)

여러 줄 이동 :

V(예 Shift- V) 상하 이동 준마는 VIM에서 여러 행을 선택합니다

히트를 선택하면 :위의 명령을 실행 m +1


14
나를 위해 : m -2는 한 줄만 올라갑니다.
Hermann Ingjaldsson

2
이 방법을 vimrc에 넣었지만 '.'를 사용하여 명령을 반복 할 수 없습니다. 왜 그런지 아는 사람이 있습니까?
Hermann Ingjaldsson

아주 좋아요! 메모장 ++의 솔루션만큼 편안하지는 않지만 여전히 실제적이고 작동합니다.
Arturas M

Hermann, 죄송합니다. 오타 / 실수입니다. 귀하는 옳습니다. : m -2 한 줄 위로 올립니다. 나는 그것을 바꿨다. 매우 늦게 답장을 드려 죄송합니다 (.vimrc 부분에 대해 잘 모르겠 음) Cheers
Serg

2
OP를 사용하여 메모장 ++의 바인딩과 같은 바인딩에 명령을 사용하려면 명령을 사용하여 이동하십시오. .vimrc에 다음을 입력해야합니다.noremap <c-s-up> :m -2<CR> noremap <c-s-down> :m +1<CR>
kap

74

줄을 위로 이동하십시오. ddkP

줄을 아래로 이동하십시오. ddp


1
vimrc에서 이것을 사용하면 '.'을 사용하여 명령을 반복 할 수 없습니다.
Hermann Ingjaldsson 2016 년

@HermannIngjaldsson, .반복 을 사용하려면 명령을 함수로 래핑 할 수 있다고 가정합니다 .
jacobsimeon

예, .. 더 많은 행을 이동해야하는 경우 dd 대신 V를 사용할 수 있습니다.
sensorario

15

이것은 나를 위해 일했다 :

http://vim.wikia.com/wiki/Moving_lines_up_or_down_in_a_file

BTW, ALT + some_key를 사용하고 터미널 (urxvt 가이 작업을 수행하지 않음)을 거부하려면 .vimrc에 다음과 같이 입력해야합니다.

" For moving lines (^] is a special character; use <M-k> and <M-j> if it works)
nnoremap ^]k mz:m-2<CR>`z==
inoremap ^]j <Esc>:m+<CR>==gi
inoremap ^]k <Esc>:m-2<CR>==gi
vnoremap ^]j :m'>+<CR>gv=`<my`>mzgv`yo`z
nnoremap ^]j mz:m+<CR>`z==
vnoremap ^]k :m'<-2<CR>gv=`>my`<mzgv`yo`z

여기서 ^]는 ALT 키를 나타내는 단일 문자 입니다. 해당 문자를 입력하려면 C+v, EscVim 에서 사용하십시오 ( C+q, EscWindows).


1
Vim의 내장 명령을 사용하여 선을 이동하는 것이 좋습니다. 실행 취소 또는 오류가 발생했을 때 잘 작동합니다.
Josh Lee

1
<kbd> Cv <kbd /> <kbd> Esc </ kbd> (linux)로 Esc를 입력하지 마십시오. 윈도우를 대체 <KBD> 이력서 <KBD />의 <KBD> Cq와 <KBD /> 특별한 삽입 / 명령 모드에서 키 입력 같은 방법이 있지만 전반적으로
sehe

@sehe : 감사합니다. 당시에는 몰랐습니다. 답변을 업데이트했습니다.
emil.p.stanchev

1
@RafaelRinaldi [niv]noremap는 일반 모드의 리맵 입니다. <CR>입니다 Carriage Return( Enter키).
vp_arth

1
@vp_arth 없어요
sehe

13

~ / .vimrc 파일에 다음을 추가하십시오 (n, m에 대한 매핑이 없는지 확인하십시오)

nmap n :m +1<CR>
nmap m :m -2<CR>

이제 n키를 누르면 줄이 아래 m로 이동하고 줄이 위로 이동합니다.


12

명령 모드에서 아래로 이동하려는 줄에 커서를 놓은 다음

ddp

설명 : dd는 일반 버퍼에 대한 현재 행을 삭제합니다. p는 커서 위치 이후 또는 전체 행의 경우 한 행 아래에 다시 넣습니다.

많은 문서에서 명령 p 및 P와 관련하여 약간의 혼동이 있습니다. 실제로 p는 AFTER 커서와 P AT 커서를 붙여 넣습니다.


8

이 코드를 .vimrc (또는 .gvimrc)에 추가하십시오.

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

1
당으로 vim.wikia.com/wiki/... 포괄적 인 설명이 참조하십시오.
Sroo Stroobandt

Mac에서 <A-something>이 ​​작동하지 않아 이유를 모르겠습니다. <Cj> <Ck>로 교체했으며 Ctrl 키를 사용하여 잘 작동합니다.
Cédric NICOLAS



3

내 .vimrc 파일 끝에 다음을 넣습니다.

noremap H ddkkp
noremap N ddp

이제 'H'와 'N'은 각각 전류 라인을 위아래로 움직입니다.


H와 N은 실제로 유용한 명령입니다 (H는 커서를 화면의 상단과 시작으로 이동하고 N은 이전 검색 결과로 이동합니다). 다른 키를 사용하는 것이 좋습니다
villapx

내가 참조. 나는 또한 그것들을 재구성했다. 화면 상단으로 이동하려면 a를 누른 다음 위로를 누릅니다. 항상 내 책에서 항상 의미합니다. 그리고 이전 결과를 검색하려면 f를 누른 다음 떠납니다. 그런 다음 F는 찾기를 나타냅니다. 그러나 그런 것을 가지고 있지 않은 사람들에게는 그렇습니다.
Hermann Ingjaldsson 16:16에

1

다음은 Wikia 기사 예제를 사용하여 MacVim 용으로 단순화 된 버전입니다 ( 주석의 링크 참조 ).

" Move selection up/down (add =gv to reindent after move)
:vmap <D-S-Up> :m-2<CR>gv
:vmap <D-S-Down> :m'>+<CR>gv

현재 줄을 선택하려면 Shift-V 만 사용하고 선택적으로 더 많은 줄을 선택하려면 위 / 아래로 커서를 이동하기 때문에 블록 선택 변형 만 사용하고 있습니다.

위의 단축키에 따라 Cmd-Shift-Up / Down을 누르면 블록 선택이 위 / 아래로 이동합니다. "D"는 MacVim의 Command 키입니다. Windows의 경우 "C"(Control) 또는 "A"(Alt)를 시도하십시오 (예 : <CAf>는 Control Alt f 임).

Wikia 아티클에 "= gv"를 추가하면 주변 텍스트를 기준으로 이동 후 블록의 들여 쓰기를 조정하는 효과가 있습니다. 혼란 스럽기 때문에 제거하고 선택 항목을 빠르게 들여 쓰기위한 바로 가기를 추가했습니다.

" Indent selection left/right (Cmd Shift Left/Right is used for Tab switching)
:vmap <D-A-Left> <gv
:vmap <D-A-Right> >gv

<< 및 >>로도 동일한 작업을 수행 할 수 있지만 선택 항목이 손실되므로 위의 바로 가기를 사용하면 여러 번 들여 쓰기를 할 수 있으며 선택 항목이 유지되므로 블록을 계속 이동할 수 있습니다.

MacVim은 Cmd-Shift-Left / Right로 탭을 전환하도록 구성되어 있으므로 Cmd-Alt-Left / Right를 사용했습니다.

MacVim의 탭 전환은 다음과 같습니다 (위의 나머지 부분은 .gvimrc에 입력).

:macm Window.Select\ Previous\ Tab key=<D-S-Left>
:macm Window.Select\ Next\ Tab key=<D-S-Right>

1

vim 플러그인 unimpaired.vim [e and] e


2
이것은 과잉처럼 보이지만 실제로는 완전한 플러그인이 필요하다고 생각하지 않습니다. vimrc에서 2 줄은 OP가 원하는 것을 정확하게 수행합니다.
Daniel Gratzer

1

:help move에서 command를 누르면 vim결과는 다음과 같습니다.

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

예 : 현재 줄을 한 줄 아래로 이동 => :m+1 .

예 : 숫자가 100 인 행을 숫자가 80 => 인 행 아래로 이동합니다 :100 m 80 .

예 : 숫자가 100 인 행을 숫자가 200 => 인 행 아래로 이동합니다 :100 m 200 .

예 : [100, 120] 내에 숫자가있는 행을 숫자 200 =>가있는 행 아래로 이동하십시오 :100,120 m 200 .


1

내 컴퓨터에서 작동하는 솔루션은 다음과 같습니다 . VIM 8.1을 실행하는 MacBook Pro

이 명령은 버퍼의 맨 위나 맨 아래 줄을 삭제하지 않습니다.

Alt-J 및 Alt-K 출력의 실제 기호를 사용하면 내 환경에서 키 코드가 올바르게 매핑되지 않는 해결 방법이 있습니다.

오래된 .vimrc에 이것을 던져서 당신에게 맞는지 확인하십시오.

" Maps Alt-J and Alt-K to macros for moving lines up and down
" Works for modes: Normal, Insert and Visual
nnoremap ∆ :m .+1<CR>==
nnoremap ˚ :m .-2<CR>==
inoremap ∆ <Esc>:m .+1<CR>==gi
inoremap ˚ <Esc>:m .-2<CR>==gi
vnoremap ∆ :m '>+1<CR>gv=gv
vnoremap ˚ :m '<-2<CR>gv=gv


0

한 줄을 이동하면 : m. + 1 또는 : m.-2가 수행합니다. 다음은 여러 줄을 이동하는 스크립트입니다. 비주얼 모드에서 Alt-up / Alt-down은 비주얼 선택을 포함하는 라인을 한 라인 씩 위 / 아래로 이동합니다. 삽입 모드 또는 일반 모드에서 카운트 접두사가 제공되지 않으면 Alt-up / Alt-down은 현재 행을 이동합니다. 카운트 접두사가 있으면 Alt-up / Alt-down은 현재 줄부터 시작하여 한 줄씩 많은 줄을 이동합니다.

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

특정 검색과 일치하는 여러 줄에서이 작업을 수행하려는 경우 :

  • 위로 : :g/Your query/ normal ddp또는:g/Your query/ m -1
  • 아래로 :g/Your query/ normal ddp또는:g/Your query/ m +1
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.