当我使用 VIM 时,我总是有多个可见的窗口。有时我想有一个简单的方法,在某些地方交换这些窗口。是否有任何插件、宏等使这更容易?顺便说一句,我使用 MiniBufExplorer。
5 回答
内置了一些有用的命令,可以为您提供一定程度的控制,但并不全面。主要有:
Ctrl- W,r(即按住CTRL,按下W,释放CTRL,按下r)-旋转窗口(第一个窗口变成第二个,第二个变成第三个,等等)
Ctrl- W, x- 将当前窗口与下一个窗口交换
Ctrl- W, Shift- H- 把这个窗口移到最左边
Ctrl- W, Shift- K- 将此窗口移至顶部
(同样适用于Ctrl- W, Shift-J和Ctrl- W, Shift- L)。看:
:help window-moving
了解更多信息。
我在我的 vimrc 中编写并一直在使用以下代码片段来复制粘贴我的 Vim 窗口。
例如,这定义了以下快捷方式:
<c-w>y
:“拉开窗口”,即把当前窗口中缓冲区的编号存储在一个全局变量中。<c-w>pp
:“将窗口放在当前窗口的位置”,即它读取先前存储的缓冲区号并在当前窗口中打开该缓冲区。它还存储曾经在当前窗口中的缓冲区的编号。
如果通过“在某些地方交换那些窗口”,您的意思是“在窗口 B 中打开窗口 A 中的缓冲区,反之亦然,而不改变窗口的位置”,您可以使用以下键盘序列来交换窗口:
- 选择窗口 A(使用鼠标或键盘命令)
- 按
<c-w>y
(拉出缓冲区号) - 选择窗口 B
- 按
<c-w>pp
(粘贴缓冲区) - 选择窗口 A
- 按
<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
大约在同一时间,我问了一个类似的问题:我想要一种在不改变任意复杂布局的情况下专门交换窗口的方法。我最终根据建议的解决方案之一制作了一个 vim 插件。它被称为WindowSwap.vim;使用您喜欢的 vim 插件管理器安装它并试一试。
使用 WindowSwap.vim,您只需
<Leader>yw
拉开一扇窗户。- 将光标移动到另一个窗口。
<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 r
旋转所有窗口ctrl-w x
与其邻居交换当前窗口ctrl-w H
将当前窗口移到最左边ctrl-w J
将当前窗口移至底部ctrl-w K
将当前窗口移到顶部ctrl-w L
将当前窗口移到最右边
作为<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>