Все вышеприведенные ответы хороши, к сожалению, эти решения не работают в сочетании с окнами 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>
Кредиты на обменную функцию Брэндону Ортеру
Зачем это нужно
Причина, по которой функции подкачки не работают должным образом без удаления сначала всех окон QuickFix (QF) и LocationList (LL), заключается в том, что если родитель 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
|__________________|
Первый переключатель буфера, первое окно заполняется буфером третьего окна. Таким образом, окно 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
|__________________|