Come scambiare file tra finestre in VIM?


123

Quando lavoro con VIM, ho sempre più finestre visibili. A volte mi piacerebbe avere un modo semplice, per scambiare quelle finestre in alcuni punti. Esistono plugin, macro, ecc. Per renderlo più semplice? A proposito, io uso MiniBufExplorer.


2
Con "scambiare quelle finestre in posti", intendi "aprire il buffer che si trova nella finestra A nella finestra B, e viceversa, senza cambiare la posizione delle finestre"?
hcs42

1
Sì, questo è esattamente quello che voglio.
mdrozdziel

Risposte:


304

Ci sono alcuni comandi utili incorporati che ti danno una certa quantità di controllo, ma non sono completi. I principali sono:

  • Ctrl- W, r(cioè tieni premuto CTRL, premi W, rilascia CTRL, premi r) - che ruota le finestre (la prima finestra diventa la seconda, la seconda diventa la terza, ecc.)

  • Ctrl- W, x- scambia la finestra corrente con quella successiva

  • Ctrl- W, Shift- H- sposta questa finestra all'estrema sinistra

  • Ctrl- W, Shift- K- sposta questa finestra in alto

(e allo stesso modo per Ctrl- W, Shift- Je Ctrl- W, Shift- L). Vedere:

:help window-moving

per maggiori informazioni.


16
Questa dovrebbe essere la "risposta migliore": funzionalità nativa, non un Vimscript personalizzato.
David Rivers

1
Non completamente, no. Ci sono molti casi d'uso che non possono essere eseguiti utilizzando la gestione delle finestre incorporata senza distruggere e ricreare le finestre. Lo script dei buffer di scambio consente questi casi d'uso.
bobpaul

nota che anche ctl-w funziona. ctl-W chiuderà le finestre in alcuni emulatori di terminale.
datakid

7

Ho scritto e ho utilizzato il seguente frammento di codice nel mio vimrc per copiare e incollare le mie finestre Vim.

Questo definisce ad esempio le seguenti scorciatoie:

  • <c-w>y: "Yanks the window", cioè memorizza il numero del buffer nella finestra corrente in una variabile globale.
  • <c-w>pp: "Mette la finestra al posto della finestra corrente", cioè legge il numero di buffer memorizzato in precedenza e apre quel buffer nella finestra corrente. Memorizza anche il numero del buffer che si trovava nella finestra corrente.

Se per "scambiare quelle finestre in posti", intendi "aprire il buffer nella finestra A nella finestra B, e viceversa, senza cambiare la posizione delle finestre", puoi usare la seguente sequenza di tasti per scambiare le finestre:

  1. Seleziona la finestra A (con il mouse o con i comandi da tastiera)
  2. Premere <c-w>y(strappando il numero del buffer)
  3. Seleziona la finestra B
  4. Premere <c-w>pp(incollare il buffer)
  5. Seleziona la finestra A
  6. Premere <c-w>pp(incollando di nuovo il buffer)

Funziona solo in 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

Ho posto una domanda simile nello stesso periodo: volevo un modo per scambiare le finestre in modo specifico senza alterare un layout arbitrariamente complicato. Ho finito per creare un plugin vim da una delle soluzioni suggerite. Si chiama WindowSwap.vim ; installalo con il tuo gestore di plug-in vim preferito e fai un giro.

Con WindowSwap.vim, dovresti semplicemente

  1. <Leader>yw per strappare una finestra.
  2. Sposta il cursore in un'altra finestra.
  3. <Leader>pw per incollare quella finestra, scambiandola con la posizione della prima.

Le combinazioni di tasti sono ovviamente configurabili in base alle tue preferenze.


1

Come <c-w>ro <c-w>xha una restrizione che non è possibile ruotare o scambiare finestre Quando le divisioni delle finestre verticali e orizzontali sono mescolate. E <c-w>Hpuò far cambiare il layout della finestra oltre le tue aspettative, specialmente quando hai molte finestre.

Quindi potresti fare del lavoro per soddisfare le tue particolari esigenze di cambio finestra / buffer. Ecco un esempio per cambiare la finestra corrente con la finestra in alto a sinistra (in genere la ingrandisco 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

A mio parere, http://vimcasts.org/episodes/working-with-windows/ ha la risposta perfetta a questa domanda. In breve:

  • ctrl-w w ciclo tra le finestre aperte
  • ctrl-w h focalizza la finestra a sinistra
  • ctrl-w j focalizza la finestra verso il basso
  • ctrl-w k focalizza la finestra in alto
  • ctrl-w l focalizza la finestra a destra
  • ctrl-w r ruota tutte le finestre
  • ctrl-w x scambia la finestra corrente con il suo vicino
  • ctrl-w H sposta la finestra corrente all'estrema sinistra
  • ctrl-w J sposta la finestra corrente in basso
  • ctrl-w K sposta la finestra corrente in alto
  • ctrl-w L sposta la finestra corrente all'estrema destra

3
Qual è il motivo per aggiungere una risposta che non porta nuove informazioni utili al post? Questo è stato perfettamente risposto 6 anni fa. Stai facendo una campagna pubblicitaria per vimcast?
mdrozdziel

@mdrozdziel Apprezzo questa risposta 9 anni dopo l'OP. Risposta più concisa con solo le informazioni che volevo.
roro
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.