134

当我使用 VIM 时,我总是有多个可见的窗口。有时我想有一个简单的方法,在某些地方交换这些窗口。是否有任何插件、宏等使这更容易?顺便说一句,我使用 MiniBufExplorer。

4

5 回答 5

331

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

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

  • Ctrl- W, x- 将当前窗口与下一个窗口交换

  • Ctrl- W, Shift- H- 把这个窗口移到最左边

  • Ctrl- W, Shift- K- 将此窗口移至顶部

(同样适用于Ctrl- W, Shift-JCtrl- W, Shift- L)。看:

:help window-moving

了解更多信息。

于 2010-02-09T10:45:25.810 回答
7

我在我的 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
于 2010-02-09T13:52:09.887 回答
4

大约在同一时间,我问了一个类似的问题:我想要一种在不改变任意复杂布局的情况下专门交换窗口的方法。我最终根据建议的解决方案之一制作了一个 vim 插件。它被称为WindowSwap.vim;使用您喜欢的 vim 插件管理器安装它并试一试。

使用 WindowSwap.vim,您只需

  1. <Leader>yw拉开一扇窗户。
  2. 将光标移动到另一个窗口。
  3. <Leader>pw粘贴该窗口,将其与第一个窗口的位置交换。

组合键当然可以根据您的喜好进行配置。

于 2013-12-11T22:36:02.820 回答
3

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

  • ctrl-w w 在打开的窗口之间循环
  • ctrl-w h 将窗口聚焦到左侧
  • ctrl-w j 将窗口聚焦到下方
  • ctrl-w k 将窗口聚焦到上方
  • ctrl-w l 将窗口聚焦到右侧
  • ctrl-w r 旋转所有窗口
  • ctrl-w x 与其邻居交换当前窗口
  • ctrl-w H 将当前窗口移到最左边
  • ctrl-w J 将当前窗口移至底部
  • ctrl-w K 将当前窗口移到顶部
  • ctrl-w L 将当前窗口移到最右边
于 2015-12-18T02:01:21.390 回答
1

作为<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>
于 2013-01-11T05:24:51.117 回答