如何在VIM中的Windows之间交换文件?


123

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


2
“将这些窗口交换到位”是指“在不更改窗口位置的情况下在窗口B中打开窗口A中的缓冲区,反之亦然”吗?
hcs42 2010年

1
是的,这正是我想要的。
mdrozdziel

Answers:


304

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

  • Ctrl- Wr(即按住CTRL,按下W,释放CTRL,按下r)-旋转窗口(第一个窗口成为第二个窗口,第二个窗口成为第三个窗口,依此类推)

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

  • Ctrl- WShift-- H将此窗口移到最左边

  • Ctrl- WShift-- K将此窗口移到顶部

(以及类似的Ctrl- WShift- JCtrl- WShift- L)。看到:

:help window-moving

想要查询更多的信息。


16
这应该是“最佳答案”-本机功能,而不是自定义的Vimscript。
David Rivers

1
不完全,不。在不破坏和重新创建窗口的情况下,使用内置窗口管理无法完成许多用例。交换缓冲区脚本允许这些用例。
bobpaul

请注意,ctl-w也可以。ctl-W将关闭某些终端仿真器中的窗口。
datakid

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

4

大约在同一时间,我问了一个类似的问题:我想要一种专门交换窗口的方法,而无需更改任意复杂的布局。我最终从建议的解决方案之一中制作了一个vim插件。它叫做WindowSwap.vim ; 用您喜欢的vim插件管理器安装它,然后旋转一下。

使用WindowSwap.vim,您只需

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

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


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>

1

我认为,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 将当前窗口移到最右边

3
添加答案的原因是什么?该答案没有任何新的有用信息?这是6年前的完美答案。您是否正在为Vimcast做广告活动?
mdrozdziel

@mdrozdziel我很欣赏OP发表9年后的回答。最简洁的答案仅包含我想要的信息。
roro
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.