[layout] vim에서 두 개의 열린 파일 (스플릿 단위)의 위치를 ​​바꾸려면 어떻게해야합니까?

vim에 임의의 분할 레이아웃이 있다고 가정합니다.

____________________
| one       | two  |
|           |      |
|           |______|
|           | three|
|           |      |
|___________|______|

교환 할 수있는 방법이 있나요 onetwo동일한 레이아웃과 유지는? 이 예제에서는 간단하지만보다 복잡한 레이아웃에 도움이되는 솔루션을 찾고 있습니다.

최신 정보:

나는 더 분명해야한다고 생각합니다. 이전 예제는 실제 사용 사례를 단순화 한 것입니다. 실제 인스턴스의 경우 :
대체 텍스트

동일한 레이아웃을 유지하면서 두 분할을 어떻게 바꿀 수 있습니까?

최신 정보! 3 년 이상 후 …

나는 당신이 쉽게 설치할 수있는 Vim 플러그인에 sgriffin의 솔루션을 넣었습니다! 자주 사용하는 플러그인 관리자로 설치하고 사용해보십시오 : WindowSwap.vim

작은 데모



답변

게시물에 조금 늦었지만이 다른 것을 찾고 있습니다. 창을 표시하고 창간에 버퍼를 교환하기 위해 두 가지 기능을 다시 작성했습니다. 이것은 당신이 요구하는 것 같습니다.

.vimrc에서 이것들을 때리고 함수가 어떻게 보이는지 매핑하십시오.

function! MarkWindowSwap()
    let g:markedWinNum = winnr()
endfunction

function! DoWindowSwap()
    "Mark destination
    let curNum = winnr()
    let curBuf = bufnr( "%" )
    exe g:markedWinNum . "wincmd w"
    "Switch to source and shuffle dest->source
    let markedBuf = bufnr( "%" )
    "Hide and open so that we aren't prompted and keep history
    exe 'hide buf' curBuf
    "Switch to dest and shuffle source->dest
    exe curNum . "wincmd w"
    "Hide and open so that we aren't prompted and keep history
    exe 'hide buf' markedBuf
endfunction

nmap <silent> <leader>mw :call MarkWindowSwap()<CR>
nmap <silent> <leader>pw :call DoWindowSwap()<CR>

사용하려면 (당신의 mapleader가 \로 설정되어 있다고 가정) :

  1. ctrl-w 이동을 통해 스왑을 표시하려면 창으로
    이동
  2. \ mw를 입력하십시오
  3. 교환하려는 창으로 이동
  4. 유형 \ pw

짜잔! 창 레이아웃을 방해하지 않고 버퍼를 교체했습니다!


답변

이것으로 시작 :

____________________
| one       | two  |
|           |      |
|           |______|
|           | three|
|           |      |
|___________|______|

‘three’를 활성 창으로 만든 다음 ctrl+ 명령을 실행하십시오 w J. 현재 창을 이동하여 화면 하단을 채 웁니다.

____________________
| one       | two  |
|           |      |
|___________|______|
| three            |
|                  |
|__________________|

이제 ‘1’또는 ‘2’를 활성 창으로 만든 다음 ctrl+ 명령을 실행하십시오 w r. 이것은 현재 행의 창을 ‘회전’하여 다음을 남깁니다.

____________________
| two       | one  |
|           |      |
|___________|______|
| three            |
|                  |
|__________________|

이제 ‘2’를 활성 창으로 만들고 ctrl+ 명령을 실행하십시오 w H. 현재 창을 이동하여 화면 왼쪽을 채우고 다음을 수행합니다.

____________________
| two       | one  |
|           |      |
|           |______|
|           | three|
|           |      |
|___________|______|

보시다시피, manouevre는 약간 섞입니다. 3 개의 창으로, 그것은 ‘타일 게임’퍼즐 중 하나와 조금 비슷합니다. 4 개 이상의 창이있는 경우이 작업을 권장하지 않습니다. 창을 닫고 원하는 위치에서 다시 여는 것이 좋습니다.

Vim에서 분할 창으로 작업하는 방법을 보여주는 스크린 캐스트를 만들었습니다 .


답변

:h ctrl-w_ctrl-x및 / 또는 살펴보십시오 :h ctrl-w_ctrl-r. 이 명령을 사용하면 현재 레이아웃에서 창을 교환하거나 회전 할 수 있습니다.

편집 : 실제로 이것은 현재 열이나 행에서만 교환하기 때문에이 상황에서는 작동하지 않습니다. 대신 각 창으로 이동하여 대상 버퍼를 선택할 수 있지만 매우 장황합니다.


답변

랜디가 맞습니다CTRL-W x 열 / 행에없는 창을 바꾸고 싶지 것이 .

CTRL-W HJKL창을 조작 할 때 키가 가장 유용 하다는 것을 알았습니다 . 현재 창을 현재 위치 밖으로 강제로 밀고 누른 키 방향으로 표시된 전체 가장자리를 차지하도록 지시합니다. 보다:help window-moving 은 참조하십시오.

위의 예에서 “하나”창에서 시작하면 원하는 작업을 수행합니다.

CTRL-W K   # moves window "one" to be topmost,
           #   stacking "one", "two", "three" top to bottom
CTRL-W j   # moves cursor to window "two"
CTRL-W H   # moves window "two" to be leftmost,
           #   leaving "one" and "three" split at right

편의상 키 매핑에 필요한 시퀀스를 할당 할 수 있습니다 (참조 :help mapping).


답변

나는 sgriffin의 솔루션에서 약간 향상된 버전을 가지고 있으며 두 개의 명령을 사용하지 않고 직관적 인 HJKL 명령으로 창을 바꿀 수 있습니다.

다음은 그 방법입니다.

function! MarkWindowSwap()
    " marked window number
    let g:markedWinNum = winnr()
    let g:markedBufNum = bufnr("%")
endfunction

function! DoWindowSwap()
    let curWinNum = winnr()
    let curBufNum = bufnr("%")
    " Switch focus to marked window
    exe g:markedWinNum . "wincmd w"

    " Load current buffer on marked window
    exe 'hide buf' curBufNum

    " Switch focus to current window
    exe curWinNum . "wincmd w"

    " Load marked buffer on current window
    exe 'hide buf' g:markedBufNum
endfunction

nnoremap H :call MarkWindowSwap()<CR> <C-w>h :call DoWindowSwap()<CR>
nnoremap J :call MarkWindowSwap()<CR> <C-w>j :call DoWindowSwap()<CR>
nnoremap K :call MarkWindowSwap()<CR> <C-w>k :call DoWindowSwap()<CR>
nnoremap L :call MarkWindowSwap()<CR> <C-w>l :call DoWindowSwap()<CR>

일반 노드에서 대문자 HJKL을 사용하여 창을 이동하면 정말 멋집니다 🙂


답변

구축 크게 @ sgriffin의 대답에, 여기에 뭔가 더 가까이 당신이 요구하는지에있다 :

function! MarkWindow()
        let g:markedWinNum = winnr()
endfunction

function! SwapBufferWithMarkedWindow()
        " Capture current window and buffer
        let curWinNum = winnr()
        let curBufNum = bufnr("%")

        " Switch to marked window, mark buffer, and open current buffer
        execute g:markedWinNum . "wincmd w"
        let markedBufNum = bufnr("%")
        execute "hide buf" curBufNum

        " Switch back to current window and open marked buffer
        execute curWinNum . "wincmd w"
        execute "hide buf" markedBufNum
endfunction

function! CloseMarkedWindow()
        " Capture current window
        let curWinNum = winnr()

        " Switch to marked window and close it, then switch back to current window
        execute g:markedWinNum . "wincmd w"
        execute "hide close"
        execute "wincmd p"
endfunction

function! MoveWindowLeft()
        call MarkWindow()
        execute "wincmd h"
        if winnr() == g:markedWinNum
                execute "wincmd H"
        else
                let g:markedWinNum += 1
                execute "wincmd s"
                execute g:markedWinNum . "wincmd w"
                execute "wincmd h"
                call SwapBufferWithMarkedWindow()
                call CloseMarkedWindow()
        endif
endfunction

function! MoveWindowDown()
        call MarkWindow()
        execute "wincmd j"
        if winnr() == g:markedWinNum
                execute "wincmd J"
        else
                execute "wincmd v"
                execute g:markedWinNum . "wincmd w"
                execute "wincmd j"
                call SwapBufferWithMarkedWindow()
                call CloseMarkedWindow()
        endif
endfunction

function! MoveWindowUp()
        call MarkWindow()
        execute "wincmd k"
        if winnr() == g:markedWinNum
                execute "wincmd K"
        else
                let g:markedWinNum += 1
                execute "wincmd v"
                execute g:markedWinNum . "wincmd w"
                execute "wincmd k"
                call SwapBufferWithMarkedWindow()
                call CloseMarkedWindow()
        endif
endfunction

function! MoveWindowRight()
        call MarkWindow()
        execute "wincmd l"
        if winnr() == g:markedWinNum
                execute "wincmd L"
        else
                execute "wincmd s"
                execute g:markedWinNum . "wincmd w"
                execute "wincmd l"
                call SwapBufferWithMarkedWindow()
                call CloseMarkedWindow()
        endif
endfunction

nnoremap <silent> <Leader>wm :call MarkWindow()<CR>
nnoremap <silent> <Leader>ws :call SwapBufferWithMarkedWindow()<CR>
nnoremap <silent> <Leader>wh :call MoveWindowLeft()<CR>
nnoremap <silent> <Leader>wj :call MoveWindowDown()<CR>
nnoremap <silent> <Leader>wk :call MoveWindowUp()<CR>
nnoremap <silent> <Leader>wl :call MoveWindowRight()<CR>

행동이 귀하의 기대와 일치하지 않는 경우 알려주십시오.


답변

또한 sgriffin의 솔루션에 따라 교환하려는 창으로 이동하고을 누르고 교환하려는 창으로 CTRL-w m이동 한 다음을 누릅니다.CTRL-w m 다시 .

CTRL-w m 니모닉 선택이 좋지 않으므로 더 나은 사람이 있으면 수정하십시오.

또한 스크립트 “창에 표시되었습니다. 대상에 반복하십시오”라는 피드백을 받고 싶습니다.하지만 vimscript 멍청한 놈이지만 그 방법을 모르겠습니다.

말한대로 스크립트는 그대로 작동합니다.

" <CTRL>-w m : mark first window
" <CTRL>-w m : swap with that window
let s:markedWinNum = -1

function! MarkWindowSwap()
    let s:markedWinNum = winnr()
endfunction

function! DoWindowSwap()
    "Mark destination
    let curNum = winnr()
    let curBuf = bufnr( "%" )
    exe s:markedWinNum . "wincmd w"
    "Switch to source and shuffle dest->source
    let markedBuf = bufnr( "%" )
    "Hide and open so that we aren't prompted and keep history
    exe 'hide buf' curBuf
    "Switch to dest and shuffle source->dest
    exe curNum . "wincmd w"
    "Hide and open so that we aren't prompted and keep history
    exe 'hide buf' markedBuf
endfunction

function! WindowSwapping()
    if s:markedWinNum == -1
        call MarkWindowSwap()
    else
        call DoWindowSwap()
        let s:markedWinNum = -1
    endif
endfunction

nnoremap <C-w>m :call WindowSwapping()<CR>