Come posso chiudere un buffer senza chiudere la finestra?


120

Le viste a più livelli di Vim (Windows, Buffer e Tab) mi hanno lasciato un po 'confuso. Diciamo che ho diviso il display (: sp) e quindi seleziono un buffer diverso da visualizzare in ciascuna finestra. Ora voglio chiudere uno dei buffer, ma non voglio che la finestra si chiuda (dopo la chiusura può visualizzare il buffer successivo nell'elenco o un buffer vuoto, non importa). Come posso fare questo?

Grazie.


C'è un motivo per cui vuoi chiudere il buffer invece di non vederlo più lì?
rampion

9
In realtà mi stavo chiedendo anche questo. Eliminare un buffer e dover ricostruire successivamente qualsiasi parte delle mie divisioni è stata distrutta nel processo è fastidioso.
brettkelly

3
29 voti positivi finora. Penso che questo sia un caso d'uso piuttosto comune. Ne ho bisogno quando lavoro con molti buffer. A volte utilizzo 2 finestre e desidero chiudere un buffer. Non voglio che quella finestra vada via. Voglio solo che il prossimo buffer venga visualizzato lì.
Wilson Freitas


Risposte:



145

Ho sbagliato un po 'con questo e alla fine ho pensato:

:bp | sp | bn | bd

Ecco la versione copia / incolla per la mappatura dei tasti:

:bp<bar>sp<bar>bn<bar>bd<CR>

L'ho testato un bel po 'e funziona costantemente in varie condizioni. Quando viene utilizzato sull'ultimo buffer, ti lascerà con un nuovo buffer vuoto.

Metti questo nel tuo .vimrc:

map <leader>q :bp<bar>sp<bar>bn<bar>bd<CR>

Riavvia Vim, o solo :source ~/.vimrcaffinché le modifiche abbiano effetto. La prossima volta che vuoi chiudere un buffer basta digitare: \q(se \è la tua chiave leader)


1
Grazie! Bello e semplice, a differenza di quasi tutte le altre soluzioni che ho visto.
jwd

16
Per i principianti, buttare questo nel vostro .vimrc : map <leader>q :bp<bar>sp<bar>bn<bar>bd<CR>. Riavvia VIM, la prossima volta che vuoi chiudere un buffer basta digitare:\q
EasyCo

5
Questo avrà un risultato inaspettato se hai una finestra divisa verticalmente. In effetti, qualsiasi configurazione di suddivisione della finestra diversa da quella standard (creata da sp).
hitzg

2
Penso che lo snippet di cosa inserire in .vimrc non dovrebbe includere il punto alla fine. A parte questo, fantastico! Questa dovrebbe essere la risposta accettata.
Ernesto

3
questo è elegante. come altre persone hanno detto, se usi principalmente le divisioni verticali, cambia spcon vsp. la mia voce .vimrc ha questo aspetto:cnoremap bd bp<bar>vsp<bar>bn<bar>bd
Connor

38

Ho cercato questo oggi e mi è venuto in mente

:b#|bd#

che cambia la finestra corrente nel buffer precedentemente aperto e cancella / nasconde il buffer da cui sei appena uscito.

Ciò richiede almeno due buffer noti.

Se un'altra finestra ma quella corrente mostra lo stesso buffer, la divisione verrà comunque distrutta. È possibile modificare tutte le finestre nel buffer precedentemente aperto con

:windo b#

Ho aggiunto maggiori dettagli sul comando precedente discutendo una mappatura per esso (e alcune insidie) in una risposta a una domanda simile .


Anche questo può essere fatto ... :#b|#bdBasta scambiare il comando del buffer e il numero del buffer sopra.
Ashish

L'ho usato un po ', ma continuavo a infastidirmi perché ha riaperto un buffer precedentemente chiuso.
pean

@pean Questo è quello che ho menzionato nella risposta collegata - vedi "Note importanti". Sì, sarebbe più bello se questo passasse a un altro buffer aperto.
valido il

1
Puoi anche fare :bn|bd#o :bp|bd#per passare al buffer aperto precedente o successivo, rispettivamente, piuttosto che al buffer a cui hai avuto accesso più di recente (b #).
padiglione

12
nmap <leader>d :bprevious<CR>:bdelete #<CR>

Funziona come dovrebbe finché un buffer non è aperto in più finestre. Abbastanza buono a meno che tu non voglia usare gli script più grandi là fuori.

Modifica: questo è quello che uso in questo momento:

function! BufferDelete()
    if &modified
        echohl ErrorMsg
        echomsg "No write since last change. Not closing buffer."
        echohl NONE
    else
        let s:total_nr_buffers = len(filter(range(1, bufnr('$')), 'buflisted(v:val)'))

        if s:total_nr_buffers == 1
            bdelete
            echo "Buffer deleted. Created new buffer."
        else
            bprevious
            bdelete #
            echo "Buffer deleted."
        endif
    endif
endfunction

1
Ho provato in questo modo ma non ha funzionato molto bene durante l'utilizzo di più finestre divise. Ecco la mia soluzione se qualcuno ha lo stesso problema:nmap <leader>d :ene<CR>:bd #<CR>
caio

7

Penso che questo sia quello che stai cercando

http://www.vim.org/htmldoc/windows.html#window-moving

Prova questo:

Guarda il tuo ID buffer usando

:buffers

vedrai un elenco di buffer come

1  a.cpp
2  b.py
3  c.php

se vuoi rimuovere b.py dal buffer

:2bw

se vuoi rimuovere / chiudere tutto dai buffer

:1,3bw

1
Non voglio spostare la finestra. Voglio chiudere il buffer senza toccare la posizione, la dimensione o l'esistenza della finestra.
Mosh

5

Per coloro che usano NERDTree.

Risolvo questo problema usando questo plugin https://github.com/jistr/vim-nerdtree-tabs e ora posso chiudere l'unico buff / file / tab senza chiudere la finestra.

Dopo aver installato il plugin sopra, metti il ​​seguente codice sul mio .vimrc:

let g:nerdtree_tabs_autoclose=0

La descrizione per la variabile sopra è: Chiudi la scheda corrente se c'è solo una finestra in essa ed è NERDTree (predefinito 1)

Maggiori informazioni qui: https://github.com/jistr/vim-nerdtree-tabs#configuration


2

Non penso che ci sia un modo univoco per farlo, ma potresti fare :enewo :lselencare i tuoi buffer e passare a uno diverso usando :b [number].

Una volta ottenuto un buffer diverso nella finestra, :bd #verrà eliminato il buffer precedente nella finestra e poiché il buffer corrente esiste ancora, la finestra non verrà chiusa.


2

Ho usato per usare:

:bp<bar>sp<bar>bn<bar>bd<CR>

Ma ho trovato certe occasioni in cui chiudeva la mia finestra.

Recentemente ho notato che lo uso sempre quando lavoro a un progetto e ho bisogno di aprire rapidamente il mio .tmux.conf .zshrcprima di tornare al lavoro.

Per questo utilizzo, trovo meglio:

  • torna al buffer su cui stavo lavorando in precedenza C-6
  • digita :bd#per eliminare il buffer precedente (l'ho mappato in questo modo nnoremap <leader>d :bd#<CR>:)

Mi permette di controllare il buffer a cui torno e mi sembra più naturale.


1

Voluto

:enew

Fai quello che vuoi? modificherà un nuovo buffer senza nome nella finestra corrente lasciando il file esistente aperto in qualsiasi altra finestra.


Questo aprirà un nuovo buffer vuoto. Voglio chiudere il buffer corrente senza chiudere la finestra.
Mosh

1

La mia soluzione preferita per questo è il plugin bufkill.vim ( GitHub ). Fornisce versioni alternative dei vari :bcomandi -prefix che funzionano allo stesso modo delle loro controparti, ma lasciano la finestra aperta. Visualizzano qualunque sia l'ultimo buffer visibile contenuto, o un buffer vuoto / nuovo se non c'era un buffer precedente.

Dalla documentazione:

Quando vuoi scaricare / eliminare / cancellare un buffer, usa:
  : bun /: bd /: bw per chiudere anche la finestra (comando vim), o
  : BUN /: BD /: BW per lasciare intatte le finestre (questo script).

1

Per "chiudere" una vista, utilizzare :hid[e]. Funziona se sei riuscito a dividere il viewport o hai aperto più file. Non puoi nascondere l'ultimo buffer visualizzato.

1 Ulteriore suggerimento che mi ha aiutato: utilizzare :e ./path/to/file.workper aprire un file nella finestra senza dividere la finestra.

PS A due giorni dall'inizio di vim ho ancora problemi a trovare i comandi di aiuto precisi. Si spera che questo aiuti qualcun altro a continuare a lavorare finché non avrà davvero il tempo di capire vim.


1

Ecco una funzione vimscript molto leggibile, che gestisce bene tutti i casi ,

  • si comportano in modo simile al built-in :bd(se solo una finestra, basta invocarla!),
    • emettere un avviso e non fare nulla se il buffer è modificato.
    • se nessun altro buffer, creane uno, tramite :enew.
    • se esiste un buffer alternativo e dentro buffer-list, passa ad esso, altrimenti vai avanti, tramite :bn.
  • comportamento più ragionevole per layout a più finestre
    • non chiudere nessuna finestra,
    • rimani sempre sulla finestra originale.
    • per ogni finestra che visualizza il buffer corrente, eseguire le operazioni elencate sopra, quindi eliminare il vecchio buffer corrente.
nnoremap <Leader> b: chiama DeleteCurBufferNotCloseWindow () <CR>

func! DeleteCurBufferNotCloseWindow () interrompe
    se e modificato
        echohl ErrorMsg
        echom "E89: nessuna scrittura dall'ultima modifica"
        echohl Nessuno
    elseif winnr ('$') == 1
        bd
    altro "finestra multipla
        let oldbuf = bufnr ('%')
        lascia oldwin = winnr ()
        mentre 1 "tutte le finestre che visualizzano oldbuf rimarranno aperte
            se buflisted (bufnr ('#'))
                b #
            altro
                bn
                let curbuf = bufnr ('%')
                se curbuf == oldbuf
                    enew "oldbuf è l'unico buffer, creane uno
                finisci se
            finisci se
            lascia vincere = bufwinnr (oldbuf)
            se vinci == -1
                rompere
            altro "ci sono altre finestre che visualizzano oldbuf
                exec win "wincmd w"
            finisci se
        ENDWHILE
        "elimina oldbuf e ripristina la finestra su oldwin
        exec oldbuf 'bd'
        exec oldwin 'wincmd w'
    finisci se
EndFunc

0

Se sei come me e sei venuto qui cercando di fare il contrario , chiudi la finestra senza chiudere il buffer, puoi farlo tramite:

:close


0

Una versione semplice che uso personalmente è

:bp|bd#

Va al buffer precedente ed elimina l'altro buffer (che in realtà è l'originale da cui siamo saltati). Questo fa quello che ti aspetteresti nel 99% dei casi senza script complicati.

Come scorciatoia da tastiera utilizzo quanto segue

nnoremap <silent> <Leader>c :bp<BAR>bd#<CR>

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.