Tutte le risposte di cui sopra sono ottime, purtroppo queste soluzioni non funzionano bene in combinazione con le finestre QuickFix o LocationList (ho riscontrato questo problema durante il tentativo di far funzionare il buffer dei messaggi di errore Ale).
Soluzione
Pertanto ho aggiunto una riga aggiuntiva di codice per chiudere tutte queste finestre prima di eseguire lo scambio.
exe ':windo if &buftype == "quickfix" || &buftype == "locationlist" | lclose | endif'
Il codice totale sembra;
" 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>
Crediti per la funzione di scambio a Brandon Orther
Perché è necessario
Il motivo per cui le funzioni di scambio non funzionano correttamente senza rimuovere prima tutte le finestre QuickFix (QF) e LocationList (LL) è perché se il genitore del buffer QF / LL viene nascosto (e non mostrato in nessuna finestra), il QF La finestra / LL accoppiata ad essa viene rimossa. Questo non è un problema in sé, ma quando la finestra nasconde tutti i numeri di finestra vengono riassegnati e lo scambio è incasinato poiché il numero salvato della prima finestra contrassegnata non esiste (potenzialmente) non esiste più.
Per dirla in questa prospettiva:
Primo segno della finestra
____________________
| one | -> winnr = 1 marked first g:markedWinNum=1
| | -> bufnr = 1
|__________________|
| two (QF window | -> winnr = 2
| coupled to one |
|__________________|
| three | -> winnr = 3
| | -> bufnr = 2
|__________________|
Segno della seconda finestra
____________________
| 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
|__________________|
Primo interruttore buffer, la finestra uno è riempita con il buffer della finestra tre. Pertanto, la finestra QF viene rimossa poiché non ha più una finestra padre. Questo riorganizza i numeri di Windows. Nota che curNum (il numero della finestra selezionata per seconda) punta a una finestra che non esiste più.
____________________
| three | -> winnr = 1 g:markedWinNum=1
| | -> bufnr = 2
|__________________|
| three | -> winnr = 2 curNum=3
| | -> bufnr = 2 curBuf=2
|__________________|
Quindi, quando si cambia il secondo buffer, tenta di selezionare la finestra curNum, che non esiste più. Quindi lo crea e cambia il buffer, risultando in una finestra indesiderata per essere ancora aperta.
____________________
| three | -> winnr = 1 g:markedWinNum=1
| | -> bufnr = 2
|__________________|
| three | -> winnr = 2
| | -> bufnr = 2
|__________________|
| one | -> winnr = 3 curNum=3
| | -> bufnr = 1 curBuf=2
|__________________|