¿Cómo intercambiar archivos entre ventanas en VIM?


123

Cuando trabajo con VIM, siempre tengo varias ventanas visibles. A veces me gustaría tener una manera fácil, intercambiar esas ventanas en lugares. ¿Hay algún complemento, macro, etc. para hacer esto más fácil? Por cierto, yo uso MiniBufExplorer.


2
Al "intercambiar esas ventanas en lugares", ¿quiere decir "abrir el búfer que está en la ventana A en la ventana B, y viceversa, sin cambiar la posición de las ventanas"?
hcs42

1
Sí, esto es exactamente lo que quiero.
mdrozdziel

Respuestas:


304

Hay algunos comandos útiles incorporados que le dan una cierta cantidad de control, pero no es exhaustivo. Los principales son:

  • Ctrl- W, r(es decir CTRL, mantener , presionar W, soltar CTRL, presionar r) - que gira las ventanas (la primera ventana se convierte en la segunda, la segunda se convierte en la tercera, etc.)

  • Ctrl- W, x- intercambia la ventana actual con la siguiente

  • Ctrl- W, Shift- H- mueva esta ventana al extremo izquierdo

  • Ctrl- W, Shift- K- mueve esta ventana a la parte superior

(y de manera similar para Ctrl- W, Shift- Jy Ctrl- W, Shift- L). Ver:

:help window-moving

para más información.


16
Esta debería ser la "mejor respuesta": funcionalidad nativa, no un Vimscript personalizado.
David Rivers

1
No del todo, no. Hay muchos casos de uso que no se pueden hacer con la administración de ventanas integrada sin destruir y volver a crear ventanas. El script de almacenamiento intermedio de intercambio permite estos casos de uso.
bobpaul

tenga en cuenta que ctl-w también funciona. ctl-W cerrará ventanas en algunos emuladores de terminal.
datakid

7

Escribí y he estado usando el siguiente fragmento de código en mi vimrc para copiar y pegar mis ventanas Vim.

Esto define, por ejemplo, los siguientes atajos:

  • <c-w>y: "Yanks the window", es decir, almacena el número del búfer en la ventana actual en una variable global.
  • <c-w>pp: "Pone la ventana en lugar de la ventana actual", es decir, lee el número de búfer almacenado previamente y abre ese búfer en la ventana actual. También almacena el número del búfer que solía estar en la ventana actual.

Si "intercambiando esas ventanas en lugares", quiere decir "abriendo el búfer en la ventana A en la ventana B, y viceversa, sin cambiar la posición de las ventanas", puede usar la siguiente secuencia de teclado para intercambiar las ventanas:

  1. Seleccione la ventana A (ya sea con el mouse o con los comandos del teclado)
  2. Presione <c-w>y(tirando del número de búfer)
  3. Seleccionar ventana B
  4. Presione <c-w>pp(pegar el búfer)
  5. Seleccionar ventana A
  6. Presione <c-w>pp(pegar el búfer nuevamente)

Funciona solo en Vim> = 7.0.

if version >= 700
function! HOpen(dir,what_to_open)

    let [type,name] = a:what_to_open

    if a:dir=='left' || a:dir=='right'
        vsplit
    elseif a:dir=='up' || a:dir=='down'
        split
    end

    if a:dir=='down' || a:dir=='right'
        exec "normal! \<c-w>\<c-w>"
    end

    if type=='buffer'
        exec 'buffer '.name
    else
        exec 'edit '.name
    end
endfunction

function! HYankWindow()
    let g:window = winnr()
    let g:buffer = bufnr('%')
    let g:bufhidden = &bufhidden
endfunction

function! HDeleteWindow()
    call HYankWindow()
    set bufhidden=hide
    close
endfunction

function! HPasteWindow(direction)
    let old_buffer = bufnr('%')
    call HOpen(a:direction,['buffer',g:buffer])
    let g:buffer = old_buffer
    let &bufhidden = g:bufhidden
endfunction

noremap <c-w>d :call HDeleteWindow()<cr>
noremap <c-w>y :call HYankWindow()<cr>
noremap <c-w>p<up> :call HPasteWindow('up')<cr>
noremap <c-w>p<down> :call HPasteWindow('down')<cr>
noremap <c-w>p<left> :call HPasteWindow('left')<cr>
noremap <c-w>p<right> :call HPasteWindow('right')<cr>
noremap <c-w>pk :call HPasteWindow('up')<cr>
noremap <c-w>pj :call HPasteWindow('down')<cr>
noremap <c-w>ph :call HPasteWindow('left')<cr>
noremap <c-w>pl :call HPasteWindow('right')<cr>
noremap <c-w>pp :call HPasteWindow('here')<cr>
noremap <c-w>P :call HPasteWindow('here')<cr>

endif

4

Hice una pregunta similar al mismo tiempo: quería una forma de intercambiar ventanas específicamente sin alterar un diseño arbitrariamente complicado. Terminé haciendo un complemento vim de una de las soluciones sugeridas. Se llama WindowSwap.vim ; instálelo con su administrador de complementos vim preferido y dele un giro.

Con WindowSwap.vim, simplemente

  1. <Leader>yw tirar de una ventana.
  2. Mueve el cursor a otra ventana.
  3. <Leader>pw para pegar esa ventana, intercambiándola con la posición de la primera.

Las combinaciones de teclas son, por supuesto, configurables según sus preferencias.


1

Como <c-w>ro <c-w>xtiene una restricción que no puede rotar o intercambiar ventanas cuando las divisiones de ventanas verticales y horizontales se mezclan. Y <c-w>Hpuede hacer que el diseño de la ventana cambie más allá de sus expectativas, especialmente cuando tiene muchas ventanas.

Por lo tanto, puede hacer un trabajo para satisfacer sus necesidades particulares de cambio de ventana / búfer. Aquí hay un ejemplo para cambiar la ventana actual con la ventana superior izquierda (normalmente la hago maximizada verticalmente):

function! SwitchMainWindow()
  let l:current_buf = winbufnr(0)
  exe "buffer" . winbufnr(1)
  1wincmd w
  exe "buffer" . l:current_buf
endfunction
nnoremap <c-w><c-e> :call SwitchMainWindow()<cr>

1

En mi opinión, http://vimcasts.org/episodes/working-with-windows/ tiene la respuesta perfecta para esta pregunta. En breve:

  • ctrl-w w ciclo entre las ventanas abiertas
  • ctrl-w h enfoca la ventana a la izquierda
  • ctrl-w j enfocar la ventana hacia abajo
  • ctrl-w k enfocar la ventana hacia arriba
  • ctrl-w l enfoca la ventana a la derecha
  • ctrl-w r rotar todas las ventanas
  • ctrl-w x intercambiar ventana actual con su vecino
  • ctrl-w H mover la ventana actual a la izquierda
  • ctrl-w J mover la ventana actual a la parte inferior
  • ctrl-w K mover la ventana actual hacia arriba
  • ctrl-w L mover la ventana actual a la extrema derecha

3
¿Cuál es la razón para agregar una respuesta que no aporta nueva información útil a la publicación? Esto fue respondido perfectamente hace 6 años. ¿Estás haciendo una campaña publicitaria para vimcasts?
mdrozdziel

@mdrozdziel Agradezco esta respuesta 9 años después del OP. La respuesta más concisa con solo la información que quería.
roro
Al usar nuestro sitio, usted reconoce que ha leído y comprende nuestra Política de Cookies y Política de Privacidad.
Licensed under cc by-sa 3.0 with attribution required.