以上所有答案都很不错,不幸的是,这些解决方案与QuickFix或LocationList窗口结合使用时效果不佳(我在尝试使Ale错误消息缓冲区与之配合使用时遇到了此问题)。
解
因此,在进行交换之前,我添加了一行额外的代码以关闭所有这些窗口。
exe ':windo if &buftype == "quickfix" || &buftype == "locationlist" | lclose | endif'
总代码看起来像;
" Making swapping windows easy
function! SwapWindowBuffers()
exe ':windo if &buftype == "quickfix" || &buftype == "locationlist" | lclose | endif'
if !exists("g:markedWinNum")
" set window marked for swap
let g:markedWinNum = winnr()
:echo "window marked for swap"
else
" mark destination
let curNum = winnr()
let curBuf = bufnr( "%" )
if g:markedWinNum == curNum
:echo "window unmarked for swap"
else
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
:echo "windows swapped"
endif
" unset window marked for swap
unlet g:markedWinNum
endif
endfunction
nmap <silent> <leader>mw :call SwapWindowBuffers()<CR>
兑换功能归功于Brandon Orther
为什么需要它
在不先删除所有QuickFix(QF)和LocationList(LL)窗口的情况下,交换功能无法正常工作的原因是,如果QF / LL的父级缓冲了获取的内容(并且在窗口中未显示),则该QF被隐藏了。与其耦合的/ LL窗口被删除。这本身不是问题,但是当窗口隐藏时,所有窗口号都将重新分配,并且由于第一个已标记窗口的保存号(可能)不再存在,交换变得混乱。
为了说明这一点:
第一个窗口标记
____________________
| one | -> winnr = 1 marked first g:markedWinNum=1
| | -> bufnr = 1
|__________________|
| two (QF window | -> winnr = 2
| coupled to one |
|__________________|
| three | -> winnr = 3
| | -> bufnr = 2
|__________________|
第二个窗口标记
____________________
| one | -> winnr = 1 g:markedWinNum=1
| | -> bufnr = 1
|__________________|
| two (QF window | -> winnr = 2
| coupled to one) |
|__________________|
| three | -> winnr = 3 marked second curNum=3
| | -> bufnr = 2 curBuf=2
|__________________|
第一个缓冲区开关,窗口1充满了窗口3的缓冲区。由于QF窗口不再具有父窗口,因此将其删除。这将重新排列窗口编号。请注意,curNum(第二个选择的窗口的编号)指向不再存在的窗口。
____________________
| three | -> winnr = 1 g:markedWinNum=1
| | -> bufnr = 2
|__________________|
| three | -> winnr = 2 curNum=3
| | -> bufnr = 2 curBuf=2
|__________________|
因此,当切换第二个缓冲区时,它将尝试选择curNum窗口,该窗口不再存在。因此,它创建了它并切换了缓冲区,导致一个不需要的窗口仍然打开。
____________________
| three | -> winnr = 1 g:markedWinNum=1
| | -> bufnr = 2
|__________________|
| three | -> winnr = 2
| | -> bufnr = 2
|__________________|
| one | -> winnr = 3 curNum=3
| | -> bufnr = 1 curBuf=2
|__________________|