Oto jak odtwarzam zachowanie, które obserwuję.
Najpierw wpisuję to polecenie:
echo aaaaa > a
vim a
W Vimie wprowadzam następujące polecenia:
:ls
:e #
:echo bufname('#')
Oto wynik powyższych trzech poleceń:
:ls
1 %a "a" line 1
:e #
E194: No alternate file name to substitute for '#'
:echo bufname('#')
bufname('#')
Polecenie tworzy żadnego wyjścia.
Teraz wprowadzam to polecenie:
:bd #
Bieżący bufor zostanie usunięty i zastąpiony buforem „[Brak nazwy]”:
:ls
2 %a "[No Name]" line 1
Spodziewałem się E194
błędu podczas wykonywania :bd #
. Dlaczego zamiast tego usunął bieżący bufor?
Używam VIM - Vi IMproved 8.0
.
buffers
vim-windows
Samotny uczeń
źródło
źródło
NVIM v0.3.0-dev
, sprawdziłem.Odpowiedzi:
Dowód
Ponieważ nie ma alternatywnego pliku, w rzeczywistości po prostu używasz zwykłego
:bd
, usuwając bieżący bufor ... wypróbuj go bez,#
a zobaczysz, że wynik jest taki sam. Podobna rzecz dzieje się:buffer
,:sbuffer
a co najmniej kilka innych poleceń, które akceptują#
jako argument: oni cicho zachowywać się tak, jakby były przekazywane żadne argumenty.Według tych samych zasad, jeśli starają
:bunload #
się ten błąd:E90: Cannot unload last buffer
. Uruchom:bunload
bez argumentów i ponownie otrzymasz ten sam wynik.The Docs
Mamy więc dowody, które
#
są zastępowane przez „nic” (prawdopodobnie pusty ciąg znaków). Dokąd zmierzamy? Przez chwilę przeglądałem pliki pomocy, próbując znaleźć wzmiankę o tym zachowaniu. Nie było nic wyraźnego oprócz:h cmdline-lines
powiedzenia (przewiń stronę lub dwie) ...Czytałem, że jak Vim oddanie
#
przezexpand()
funkcję (npexpand('#')
) lub przynajmniej tego samego kodu bazowego tam wykorzystywane.:h expand()
mówi:Brzmi znajomo.
Kod
Teraz żadne z powyższych nie jest ostateczne ani nie daje wskazówek, dlaczego? więc poświęciłem trochę więcej czasu na kopanie ... tym razem w kodzie. Moje C jest bardzo zardzewiałe i nie mam zainstalowanych żadnych dobrych narzędzi, ale udało mi się znaleźć funkcję, która wykonuje pewne
:bdelete
wywołaniedo_bufdel()
. To wysyła argumenty wiersza poleceń, przezbuflist_findpat()
które, jeśli#
zostanie napotkany, zwraca wartośćcurwin->w_alt_fnum
. To jest „numer bufora” alternatywnego bufora ... który nie może być wartością dodatnią w naszym scenariuszu. (Nie jest sprawdzane, czy plik alt jest prawidłowy / istnieje przed wybraniem tej wartości zwracanej).Wycofywanie w
do_bufdel()
celu sprawdzenia jest wykonywane względem tej wartości zwracanej dla numeru bufora mniejszego niż 0, w którym to przypadku pętla przetwarzania parametrów jest przerywana. Spowodowałoby to, że żadne parametry nie byłyby prezentowane w:bdelete
kodzie podstawowym ... co jest zgodne z moimi wcześniejszymi intuicjami.Co dalej?
Wygląda na to, że działa zgodnie z przeznaczeniem, ponieważ nie widziałem niczego, co wyglądałoby jak wyraźny błąd. Być może grzech zaniedbania, choć ... narożny przypadek, który został przeoczony, a zatem nie ma wdzięcznego sposobu obsługi. Ale tylko programiści, którzy to napisali, wiedzą na pewno. Ostatnim krokiem będzie próba uzyskania ich wkładu. Jak powiedział Christian B., pytaniem na liście vim-dev jest droga.
(Należy pamiętać, że
buflist_findpat()
jest to funkcja użyteczności więc nie wymagałby odcinek wyobraźni, aby przypuszczać, że:bunload
,:buffer
itp używasz go też ... to by tłumaczyło ich wspólne zachowanie względem#
).źródło