Warum löscht: bd # den aktuellen Puffer, wenn kein alternativer Puffer vorhanden ist?

9

So reproduziere ich das beobachtete Verhalten.

Zuerst gebe ich diesen Befehl ein:

echo aaaaa > a
vim a

In Vim gebe ich folgende Befehle ein:

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

Hier ist die Ausgabe der obigen drei Befehle:

:ls
  1 %a   "a"                            line 1

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

:echo bufname('#')

Der bufname('#')Befehl erzeugt keine Ausgabe.

Jetzt gebe ich diesen Befehl ein:

:bd #

Der aktuelle Puffer wird gelöscht und durch einen Puffer "[No Name]" ersetzt:

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

Ich hatte erwartet, den E194Fehler beim Ausführen zu bekommen :bd #. Warum wurde stattdessen der aktuelle Puffer gelöscht?

Ich benutze VIM - Vi IMproved 8.0.

Einsamer Lernender
quelle
1
Das ist ein interessanter Punkt. Sie können in Ihrer Frage erwähnen, dass dies auch der Fall ist NVIM v0.3.0-dev, habe ich überprüft.
Klaus
@LoneLearner Ich habe dies wegen der Prämie nicht wirklich beantwortet, aber wenn Sie eine anbieten möchten, wäre es schön, wenn Sie eine verdiente Antwort vergeben würden ... leider haben Sie sich fast nicht angemeldet Woche und die Kopfgeldperiode ist vorbei ...
B Layer
1
@ BLayer Entschuldigung, ich habe vergessen, das Kopfgeld zu vergeben. Sie haben eine fantastische Antwort geschrieben. Sobald ich genug Punkte auf dieser Stack Exchange-Site habe, werde ich eine weitere Prämie für diese Frage starten und die Prämie an Sie vergeben. Ich hoffe das würde meinen Fehler beheben. Vielen Dank für die großartige Antwort, die Sie geschrieben haben.
Einsamer Lernender
@ LoneLearner Hey, du bist willkommen und keine Sorge. Ich freue mich über Ihren Kommentar. Mach dir keine Sorgen über das Kopfgeld. Wie ich schon sagte, es ging nicht um die Punkte. Ich wollte dir nur einen Kopf hoch geben, wenn du das nächste Mal ein Kopfgeld aufbringst. Setzen Sie die Punkte von hier in diese Richtung. Prost!
B-Schicht

Antworten:

7

Beweise

Da es keine alternative Datei gibt, die Sie gerade ausführen :bd, löschen Sie den aktuellen Puffer. Versuchen Sie es ohne #und Sie werden sehen, dass das Ergebnis dasselbe ist. Ähnliches passiert mit :buffer, :sbufferund zumindest ein paar andere Befehle , die akzeptieren #als Argument: sie so leise verhalten , wenn keine Argumente übergeben wurden.

In diesem Sinne erhalten Sie beim Versuch folgende :bunload #Fehlermeldung : E90: Cannot unload last buffer. Führen Sie es :bunloadohne Argumente aus, und Sie erhalten erneut das gleiche Ergebnis.

Die Docs

Wir haben also Beweise, #die durch "nichts" ersetzt werden (wahrscheinlich eine leere Zeichenfolge). Was machen wir jetzt? Ich stöberte eine Weile in den Hilfedateien herum und versuchte, dieses Verhalten zu erwähnen. Es gab nichts explizites als zu :h cmdline-linessagen (ein oder zwei Seiten nach unten scrollen) ...

Wenn das Zeichen '%' oder '#' verwendet wird, wenn ein Dateiname erwartet wird, werden sie auf den aktuellen und alternativen Dateinamen erweitert.

Ich habe das als Vim gelesen, der #die expand()Funktion (dh expand('#')) oder zumindest den gleichen zugrunde liegenden Code durchläuft, der dort verwendet wird.

:h expand() sagt:

Erweitern Sie .. spezielle Schlüsselwörter. .. Wenn Sie '%' oder '#' verwenden und der aktuelle oder alternative Dateiname nicht definiert ist, wird eine leere Zeichenfolge verwendet.

Klingt vertraut.

Der Code

Jetzt ist keines der oben genannten Punkte endgültig oder gibt einen Hinweis darauf, warum? Also habe ich noch etwas Zeit damit verbracht zu graben ... diesmal im Code. Mein C ist sehr rostig und ich habe keine guten Tools installiert, aber ich habe es geschafft, eine Funktion zu finden, die ein Setup für :bdeleteaufgerufen ausführt do_bufdel(). Dies sendet Befehlszeilenargumente, über buflist_findpat()die bei #Auftreten ein Wert zurückgegeben wird curwin->w_alt_fnum. Das ist die "Puffernummer" des alternativen Puffers ... was in unserem Szenario kein positiver Wert sein kann. (Es wird nicht überprüft, ob die Alt-Datei gültig ist / existiert, bevor dieser Rückgabewert ausgewählt wird.)

Bereits aus do_bufdel()einer Überprüfung vorgenommen , gegen diesen Rückgabewert für eine Puffernummer kleiner als 0 ist in diesem Fall der Parameter - Verarbeitungsschleife unterbrochen ist aus. Das würde dazu führen, dass dem Kerncode keine Parameter präsentiert :bdeletewerden ... was genau meinen früheren Intuitionen entspricht.

Was kommt als nächstes?

Es scheint so zu funktionieren, als hätte ich nichts gesehen, was wie ein klarer Fehler aussah. Möglicherweise jedoch Unterlassungssünde ... ein Eckfall, der übersehen wurde und daher keine anmutige Behandlung hat. Aber nur die Entwickler, die dies geschrieben haben, wissen es mit Sicherheit. Der letzte Schritt wäre also, zu versuchen, ihren Input zu bekommen. Wie Christian B. sagte, ist das Fragen auf der Vim-Dev-Liste der richtige Weg.

(Beachten Sie, dass buflist_findpat()eine Nutzenfunktion ist so wäre es nicht eine Ausdehnung der Phantasie erfordert , dass zu übernehmen :bunload, :bufferetc. verwendet es auch ... , die ihr gemeinsames Verhalten in Bezug auf erklären würden #.)

B Schicht
quelle
Ich würde denken, dass eine weitere Funktion, um nur zu überprüfen, ob ein erweiterter Puffer vorhanden ist oder nicht, den Job erledigen würde. Sind Sie sicher, dass dies beabsichtigt sein sollte? Ich denke, dies sollte als Fehler aufgeführt werden.
Klaus
Ich denke, Ihre Forschung ist richtig. Übrigens: Ich denke nicht, dass dies tatsächlich ein Fehler ist.
Christian Brabandt
Ich habe meine Schlussfolgerung nur ein wenig umformuliert ... es sieht nicht nach einem harten Fehler aus. OTOH, wenn man darüber nachdenkt, könnte man schließen, dass es eine bessere Handhabung braucht. Wahrscheinlich weiß nur der Entwickler sicher.
B-Schicht
Ja, man könnte auf der vim-dev-Liste nachfragen, um sicherzugehen.
Christian Brabandt