Perché: bd # elimina il buffer corrente quando non esiste un buffer alternativo?


9

Ecco come riproduco il comportamento che sto osservando.

Per prima cosa, inserisco questo comando:

echo aaaaa > a
vim a

In Vim, inserisco questi comandi:

:ls
:e #
:echo bufname('#')

Ecco l'output dei tre comandi precedenti:

:ls
  1 %a   "a"                            line 1

:e #
E194: No alternate file name to substitute for '#'

:echo bufname('#')

Il bufname('#')comando non produce output.

Ora inserisco questo comando:

:bd #

Il buffer corrente viene eliminato e viene sostituito con un buffer "[Nessun nome]":

:ls
  2 %a   "[No Name]"                    line 1

Mi aspettavo di ottenere l' E194errore nell'esecuzione :bd #. Perché invece ha eliminato il buffer corrente?

Sto usando VIM - Vi IMproved 8.0.


1
Questo è un argomento interessante. Puoi menzionare nella tua domanda che anche questo è il caso NVIM v0.3.0-dev, ho verificato.
klaus,

@LoneLearner Non ho davvero risposto a questo a causa della generosità, ma se ne offrirai uno sarebbe bello se lo assegnassi a una risposta meritevole ... ahimè, non hai effettuato l'accesso a quasi un settimana e il periodo delle taglie è finito ...
B Layer

1
@BLayer Siamo spiacenti, ho dimenticato di assegnare la taglia. Hai scritto una risposta fantastica. Una volta che avrò abbastanza punti in questo sito di scambio di stack, inizierò un altro premio per questa domanda e ti assegnerò il premio. Spero che ciò risolva il mio errore. Grazie per l'ottima risposta che hai scritto.
Lone Learner,

@LoneLearner Ehi, sei il benvenuto e non preoccuparti. Apprezzo il tuo commento Non preoccuparti per la generosità. Come ho detto, non si trattava di punti. Volevo solo farti un testa a testa per la prossima volta che hai fatto una taglia. Metti i punti da qui verso quello. Saluti!
B Layer

Risposte:


7

Prova

Poiché non esiste alcun file alternativo che stai eseguendo semplicemente :bd, eliminando il buffer corrente ... provalo senza #e vedrai che il risultato è lo stesso. Una cosa simile accade con :buffer, :sbuffere almeno un paio di altri comandi che accettano #come argomento: si comportano silenziosamente come se non fossero passati argomenti.

Sulla stessa linea, se si tenta :bunload #si ottiene questo errore: E90: Cannot unload last buffer. Esegui :bunloadsenza argomenti e, ancora una volta, otterrai lo stesso risultato.

The Docs

Quindi abbiamo prove che #vengono sostituite da "niente" (probabilmente una stringa vuota). Dove andiamo da qui? Ho cercato per un po 'i file della guida cercando di trovare menzione di questo comportamento. Non c'era nulla di esplicito, ma :h cmdline-linesdice (scorrere verso il basso una pagina o due) ...

Quando viene utilizzato il carattere '%' o '#' laddove è previsto un nome file, vengono espansi nel nome file corrente e alternativo.

L'ho letto come Vim che #utilizza la expand()funzione (cioè expand('#')) o almeno lo stesso codice sottostante utilizzato lì.

:h expand() dice:

Espandi .. parole chiave speciali. .. Quando si utilizza '%' o '#' e il nome del file corrente o alternativo non è definito, viene utilizzata una stringa vuota.

Suona familiare.

Il codice

Ora nessuna delle precedenti è definitiva o fornisce un indizio sul perché? così ho trascorso un po 'più di tempo a scavare ... questa volta nel codice. La mia C è molto arrugginita e non ho alcun buon strumento installato, ma sono riuscito a trovare una funzione che fa qualche configurazione per :bdeletechiamare do_bufdel(). In questo modo vengono inviati argomenti della riga di comando attraverso i buflist_findpat()quali, se #rilevato, restituisce valore curwin->w_alt_fnum. Questo è il "numero di buffer" del buffer alternativo ... che non può essere un valore positivo nel nostro scenario. (Non è possibile verificare se il file alt è valido / esiste prima che sia selezionato quel valore restituito.)

Il back-out in do_bufdel()un controllo viene eseguito rispetto al valore restituito per un numero di buffer inferiore a 0, nel qual caso il ciclo di elaborazione dei parametri viene interrotto. Ciò comporterebbe la mancata presentazione di parametri al :bdeletecodice principale ... che è perfettamente in linea con le mie intuizioni precedenti.

Qual è il prossimo?

Sembra funzionare come progettato in quanto non ho visto nulla che sembrava un chiaro bug. Forse peccato di omissione, sebbene ... un caso d'angolo che è stato trascurato e quindi non ha una gestione aggraziata. Ma solo gli sviluppatori che hanno scritto questo lo sanno per certo. Quindi il passo finale sarebbe cercare di ottenere il loro contributo. Come ha detto Christian B. chiedere sulla lista di vim-dev è la strada da percorrere.

(Si noti che buflist_findpat()è una funzione di utilità in modo che non richiederebbe uno sforzo di immaginazione per pensare che :bunload, :bufferecc si utilizza, anche ... che spiegherebbe il loro comportamento comune rispetto al #.)


Penserei che un'altra funzione solo per verificare se esiste un buffer espanso o meno farebbe il lavoro. Sei sicuro che questo doveva essere progettato? Penso che questo dovrebbe essere elencato come un bug.
klaus,

Penso che la tua ricerca sia corretta. BTW: Non penso che questo sia in realtà un bug.
Christian Brabandt,

Ho appena riformulato un po 'le mie conclusioni ... non sembra un bug difficile. OTOH, se ci si pensa, si potrebbe concludere che ha bisogno di una migliore gestione. Probabilmente lo sa solo lo sviluppatore.
B Layer

Sì, si potrebbe chiedere nell'elenco vim-dev per assicurarsi.
Christian Brabandt,
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.