Вот как я воспроизвожу поведение, которое наблюдаю.
Сначала я ввожу эту команду:
echo aaaaa > a
vim a
В Vim я ввожу эти команды:
:ls
:e #
:echo bufname('#')
Вот вывод трех вышеупомянутых команд:
:ls
1 %a "a" line 1
:e #
E194: No alternate file name to substitute for '#'
:echo bufname('#')
Команда bufname('#')
не производит вывод.
Теперь я ввожу эту команду:
:bd #
Текущий буфер удаляется и заменяется буфером «[No Name]»:
:ls
2 %a "[No Name]" line 1
Я ожидал получить E194
ошибку при выполнении :bd #
. Почему вместо этого удаляется текущий буфер?
Я использую VIM - Vi IMproved 8.0
.
buffers
vim-windows
Одинокий ученик
источник
источник
NVIM v0.3.0-dev
, я проверил.Ответы:
Доказательство
Поскольку нет альтернативного файла, вы на самом деле просто запускаете обычный старый файл
:bd
, удаляя текущий буфер ... попробуйте без него,#
и вы увидите, что результат будет таким же. Подобное происходит и с:buffer
,:sbuffer
по крайней мере, парой других команд, которые принимают#
в качестве аргумента: они молча ведут себя так, как будто не было передано никаких аргументов.В том же ключе, если вы попробуете
:bunload #
вы получите эту ошибку:E90: Cannot unload last buffer
. Запустите:bunload
без аргументов и, опять же, вы получите тот же результат.Документы
Таким образом, у нас есть свидетельство того, что
#
его заменяют словом «ничего» (вероятно, пустой строкой). Куда мы отправимся отсюда? Некоторое время я копался в файлах справки, пытаясь найти упоминание об этом поведении. Там не было ничего явно, но:h cmdline-lines
говорит (прокрутите страницу вниз или две) ...Я прочитал , что , как Вим ввод
#
черезexpand()
функцию (т.е.expand('#')
) или , по крайней мере , тот же исходный код используется там.:h expand()
говорит:Звучит знакомо.
Код
Теперь ни одно из вышеперечисленного не является окончательным или дает представление о том, почему? так что я потратил немного времени на копание ... на этот раз в коде. Мой C очень ржавый, и у меня не установлено никаких хороших инструментов, но мне удалось найти функцию, которая выполняет некоторые настройки для
:bdelete
вызываемогоdo_bufdel()
. Это посылает аргументы командной строки, черезbuflist_findpat()
которые, если#
встречается, возвращает значениеcurwin->w_alt_fnum
. Это «номер буфера» альтернативного буфера ... который не может быть положительным значением в нашем сценарии. (Там нет проверки, является ли файл alt действительным / существует до того, как это возвращаемое значение выбрано.)Отклонение в
do_bufdel()
проверке выполняется для этого возвращаемого значения для номера буфера меньше 0, и в этом случае цикл обработки параметров прерывается. Это привело бы к тому, что в основной:bdelete
код не были бы переданы никакие параметры ... что соответствует моим ранним представлениям.Что дальше?
Кажется, он работает так, как задумано, и я не увидел ничего похожего на явную ошибку. Возможно, грех упущения, хотя ... угловой случай, который был упущен из виду и поэтому не имеет изящного обращения. Но только разработчики, написавшие это, знают наверняка. Таким образом, последний шаг - попытаться получить их вклад. Как сказал Кристиан Б., спросить в списке vim-dev - это путь.
(Обратите внимание , что
buflist_findpat()
это функция полезности , поэтому он не будет требовать натяжки предположить , что:bunload
,:buffer
и т.д. использует это тоже ... что бы объяснить их общее поведение по отношению к#
.)источник