如何在vim中交换两个打开文件(在拆分中)的位置?

wes*_*wes 304 vim layout split editor

假设我在vim中有一些任意分割布局.

____________________
| one       | two  |
|           |      |
|           |______|
|           | three|
|           |      |
|___________|______|
Run Code Online (Sandbox Code Playgroud)

有没有一种方法来交换onetwo维护相同的布局?在这个例子中它很简单,但我正在寻找一种有助于更复杂布局的解决方案.

更新:

我想我应该更清楚.我之前的例子是对实际用例的简化.使用实际的实例: 替代文字

我怎么能交换任何两个分裂,保持相同的布局?

更新!3年多以后......

我把sgriffin的解决方案放在你可以轻松安装的Vim插件中!使用您喜欢的插件管理器安装它并尝试一下:WindowSwap.vim

一个小小的演示

nel*_*rom 284

从这开始:

____________________
| one       | two  |
|           |      |
|           |______|
|           | three|
|           |      |
|___________|______|
Run Code Online (Sandbox Code Playgroud)

将'三'设为活动窗口,然后发出命令ctrl+ w J.这会移动当前窗口以填充屏幕底部,让您:

____________________
| one       | two  |
|           |      |
|___________|______|
| three            |
|                  |
|__________________|
Run Code Online (Sandbox Code Playgroud)

现在将"一个"或"两个"设置为活动窗口,然后发出命令ctrl+ w r.这会'旋转'当前行中的窗口,让您:

____________________
| two       | one  |
|           |      |
|___________|______|
| three            |
|                  |
|__________________|
Run Code Online (Sandbox Code Playgroud)

现在将'two'设置为活动窗口,然后发出命令ctrl+ w H.这会移动当前窗口以填充屏幕左侧,让您:

____________________
| two       | one  |
|           |      |
|           |______|
|           | three|
|           |      |
|___________|______|
Run Code Online (Sandbox Code Playgroud)

正如你所看到的,manouevre有点混乱.有3个窗口,它有点像那些'瓷砖游戏'谜题之一.如果你有4个或更多的窗户,我不建议尝试这个 - 你最好关闭它们然后再在期望的位置打开它们.

我做了一个截屏视频演示如何在Vim中使用分割窗口.

  • 对于喜欢我的人来说,只想学习如何交换两个窗口:`ctrl-w r`就像一个魅力.谢谢你的提示!这是我的+1. (90认同)
  • 你进行了额外的努力制作截屏视频,但这并不是我想要的.我可以使用基本的移动命令进行拆分,但我很好奇的是,如果有一种方法可以在任意复杂的布局中交换拆分位置. (2认同)

小智 221

这个帖子有点晚了,但却发现了其他的东西.我写了两个函数,以标记一个窗口,然后在窗口之间交换缓冲区.这似乎是你要求的.

只需在你的.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>
Run Code Online (Sandbox Code Playgroud)

要使用(假设你的mapleader设置为\),你会:

  1. 移动到窗口以通过ctrl-w移动标记交换
  2. 输入\ mw
  3. 移动到要交换的窗口
  4. 输入\ pw

瞧!交换缓冲区而不会搞砸窗口布局!

  • 我希望我可以投票十次!我确实必须在映射中使用`noremap`才能使它工作.不知道为什么,但希望有助于后来发现这一点的人.:d (16认同)
  • 我把你的解决方案放到我的第一个Vim插件中:[WindowSwap.vim](https://github.com/wesQ3/vim-windowswap).我在自述文件中将此问题与您的答案联系起来:D (6认同)

Ran*_*ris 95

看看:h ctrl-w_ctrl-x和/或:h ctrl-w_ctrl-r.这些命令允许您在当前布局中交换或旋转窗口.

编辑:实际上,这在这种情况下不起作用,因为它只会交换当前列或行.您可以转到每个窗口并选择目标缓冲区,但这非常详细.


Mik*_*itz 30

Randy的正确之处是CTRL-W x不想交换不在同一列/行中的窗口.

我发现CTRL-W HJKL在操作窗口时键是最有用的.它们会强制您当前窗口离开当前位置并告诉它占据您按下的键方向指示的整个边缘.有关:help window-moving详细信息,请参阅

对于上面的例子,如果你从窗口"one"开始,这可以做你想要的:

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
Run Code Online (Sandbox Code Playgroud)

为方便起见,您可以将所需的序列分配给键映射(请参阅参考资料:help mapping).


Pen*_*eck 10

我从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>
Run Code Online (Sandbox Code Playgroud)

尝试在正常节点中使用大写HJKL移动窗口,这真的很酷:)