Todas las respuestas anteriores son geniales, desafortunadamente estas soluciones no funcionan bien en combinación con las ventanas QuickFix o LocationList (encontré este problema al intentar que el búfer de mensaje de error Ale funcionara con esto).
Solución
Por lo tanto, agregué una línea de código adicional para cerrar todas estas ventanas antes de hacer el intercambio.
exe ':windo if &buftype == "quickfix" || &buftype == "locationlist" | lclose | endif'
El código total que parece;
" 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>
Créditos para la función de intercambio a Brandon Orther
Por qué es necesario
La razón por la que las funciones de intercambio no funcionan correctamente sin eliminar primero todas las ventanas QuickFix (QF) y LocationList (LL) es porque si el padre del buffer QF / LL se oculta (y no se muestra en ninguna parte de una ventana), el QF La ventana / LL acoplada a ella se elimina. Esto no es un problema en sí mismo, pero cuando la ventana se oculta, todos los números de ventana se reasignan y el intercambio está en mal estado, ya que el número guardado de la primera ventana marcada ya no existe (potencialmente).
Para poner esto en perspectiva:
Primera marca de ventana
____________________
| one | -> winnr = 1 marked first g:markedWinNum=1
| | -> bufnr = 1
|__________________|
| two (QF window | -> winnr = 2
| coupled to one |
|__________________|
| three | -> winnr = 3
| | -> bufnr = 2
|__________________|
Segunda marca de ventana
____________________
| 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
|__________________|
Primer interruptor de búfer, la ventana uno se llena con el búfer de la ventana tres. Por lo tanto, la ventana QF se elimina ya que ya no tiene ventana principal. Esto reorganiza los números de Windows. Tenga en cuenta que curNum (el número de la segunda ventana seleccionada) apunta a una ventana que ya no existe.
____________________
| three | -> winnr = 1 g:markedWinNum=1
| | -> bufnr = 2
|__________________|
| three | -> winnr = 2 curNum=3
| | -> bufnr = 2 curBuf=2
|__________________|
Entonces, al cambiar el segundo búfer, intenta seleccionar la ventana curNum, que ya no existe. Por lo tanto, lo crea y cambia el búfer, lo que da como resultado que una ventana no deseada se abra todavía.
____________________
| three | -> winnr = 1 g:markedWinNum=1
| | -> bufnr = 2
|__________________|
| three | -> winnr = 2
| | -> bufnr = 2
|__________________|
| one | -> winnr = 3 curNum=3
| | -> bufnr = 1 curBuf=2
|__________________|