如何在 VIM 窗口之间交换文件?

当我使用 VIM 时,我总是可以看到多个窗口。有时候,我想有一个简单的方法,交换这些窗口的地方。有没有任何插件,宏等,使这更容易?顺便说一下,我用的是 MiniBufExplorer。

35122 次浏览

有一些内置的有用的命令可以提供一定程度的控制,但是并不全面。其中主要有:

  • Ctrl-Wr(即按住 CTRL,按 W,释放 CTRL,按 r)-旋转窗口(第一个窗口变成第二个,第二个变成第三个,等等)

  • Ctrl-Wx-将当前窗口与下一个窗口交换

  • Ctrl-WShift-H-把这个窗口移到最左边

  • Ctrl-WShift-K-把这个窗口移到顶部

(类似于 Ctrl-WShift-JCtrl-WShift-L)参见:

:help window-moving

了解更多信息。

我在我的 vimrc 中编写并一直在使用下面的代码片段 复制粘贴我的 Vim 窗口。

例如,它定义了以下捷径:

  • <c-w>y: “扬起窗口”,即将缓冲区的数量存储在 全局变量中的当前窗口。
  • <c-w>pp: “将窗口放在当前窗口的位置”,即它读取 以前存储的缓冲区号,并在当前窗口中打开该缓冲区。 它还存储当前 窗户。

如果“在某些地方交换这些窗口”的意思是“在 在窗口 B 中的窗口 A,反之亦然,而不改变 视窗」 ,可使用以下键盘序列交换视窗:

  1. 选择窗口 A (使用鼠标或键盘命令)
  2. <c-w>y(猛拉缓冲区号)
  3. 选择窗口 B
  4. <c-w>pp(粘贴缓冲区)
  5. 选择窗口 A
  6. <c-w>pp(再次粘贴缓冲区)

它只能在 Vim > = 7.0中工作。

if version >= 700
function! HOpen(dir,what_to_open)


let [type,name] = a:what_to_open


if a:dir=='left' || a:dir=='right'
vsplit
elseif a:dir=='up' || a:dir=='down'
split
end


if a:dir=='down' || a:dir=='right'
exec "normal! \<c-w>\<c-w>"
end


if type=='buffer'
exec 'buffer '.name
else
exec 'edit '.name
end
endfunction


function! HYankWindow()
let g:window = winnr()
let g:buffer = bufnr('%')
let g:bufhidden = &bufhidden
endfunction


function! HDeleteWindow()
call HYankWindow()
set bufhidden=hide
close
endfunction


function! HPasteWindow(direction)
let old_buffer = bufnr('%')
call HOpen(a:direction,['buffer',g:buffer])
let g:buffer = old_buffer
let &bufhidden = g:bufhidden
endfunction


noremap <c-w>d :call HDeleteWindow()<cr>
noremap <c-w>y :call HYankWindow()<cr>
noremap <c-w>p<up> :call HPasteWindow('up')<cr>
noremap <c-w>p<down> :call HPasteWindow('down')<cr>
noremap <c-w>p<left> :call HPasteWindow('left')<cr>
noremap <c-w>p<right> :call HPasteWindow('right')<cr>
noremap <c-w>pk :call HPasteWindow('up')<cr>
noremap <c-w>pj :call HPasteWindow('down')<cr>
noremap <c-w>ph :call HPasteWindow('left')<cr>
noremap <c-w>pl :call HPasteWindow('right')<cr>
noremap <c-w>pp :call HPasteWindow('here')<cr>
noremap <c-w>P :call HPasteWindow('here')<cr>


endif

由于 <c-w>r<c-w>x有一个限制,当垂直和水平窗口分割混合时,不能旋转或交换窗口。而且 <c-w>H可能会使窗口布局的变化超出您的预期,特别是当您有许多窗口时。

因此,您可能需要做一些工作来满足窗口/缓冲区切换的特殊需要。下面是一个用左上角窗口切换当前窗口的例子(通常我使它垂直最大化) :

function! SwitchMainWindow()
let l:current_buf = winbufnr(0)
exe "buffer" . winbufnr(1)
1wincmd w
exe "buffer" . l:current_buf
endfunction
nnoremap <c-w><c-e> :call SwitchMainWindow()<cr>

与此同时,我询问了一个 类似的问题: 我想要一种特别交换窗口的方法,而不需要改变任意复杂的布局。最后,我用其中一个建议的解决方案做了一个 vim 插件。它被称为 WindowSwap.vim; 安装它与您首选的 vim 插件管理器,并给它一个旋转。

使用 WindowSwap.vim,您可以简单地

  1. <Leader>yw拉窗户。
  2. 将光标移动到另一个窗口。
  3. <Leader>pw粘贴该窗口,并将其与 第一个。

密钥组合当然可以根据您的首选项进行配置。

在我看来,http://vimcasts.org/episodes/working-with-windows/对这个问题有一个完美的答案。简而言之:

  • 打开窗口之间的 ctrl-w w循环
  • ctrl-w h将窗口聚焦到左边
  • ctrl-w j将窗口对准下方
  • ctrl-w k将窗口对焦到向上
  • ctrl-w l把窗口对准右边
  • 旋转所有窗口
  • ctrl-w x与邻居交换电流窗口
  • ctrl-w H将当前窗口移动到最左边
  • 将当前窗口移到底部
  • 将当前窗口移到顶部
  • ctrl-w L将当前窗口移动到最右边