上面所有的答案都很好,不幸的是,这些解决方案与QuickFix或LocationList窗口结合使用不能很好地工作(我在尝试让Ale错误消息缓冲区与此一起工作时遇到了这个问题)。
解决方案
因此,我添加了额外的一行代码,在进行交换之前关闭所有这些窗口。
exe ' if windo &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>
交换功能的功劳归布兰登·奥瑟
为什么需要它
如果不先删除所有QuickFix (QF)和LocationList(LL)窗口,swap函数就不能正常工作的原因是,如果QF/LL缓冲区的父缓冲区get被隐藏(并且在窗口中不显示),耦合到它的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
|__________________|