Я хотел бы проверить, посещает ли какой-нибудь (скажем, текущий) буфер файл или нет. Я мог бы сказать:
(if (buffer-file-name) ...)
но это кажется не очень элегантным - меня интересует только логическое значение, а не фактическое имя рассматриваемого буфера. Если бы buffer-file-name
функция была написана на Elisp, я мог бы заглянуть в ее источник, чтобы выяснить, что она использует - но она написана на C, и, хотя я мог бы установить исходники Emacs, я боюсь, что не смогу найти имя elisp для функции, которая проверяет, что я там после в любом случае.
Для этого мне нужно создать каталог на основе имени файла текущего буфера, и в настоящее время я делаю более или менее это:
(make-directory (if (buffer-file-name) (file-name-base) "default-dir"))
Итак, каков будет Elisp-идиоматический способ сделать это?
buffer-file-name
самом деле, это правильный способ сделать это (если вы действительно хотитеt
, делайте,(and (buffer-file-name) t)
но это уродливее ИМО). Его реализация читаетfilename
поле структуры C буфера, которое в любом случае недоступно непосредственно из Elisp. В конце концов, это просто указатель, который либо нулевой, либо нет.(and (buffer-file-name) t)
выглядит странно.(if (buffer-file-name) ... )
это элегантно, значит, вы давно не пишете в elisp. Отсюда становится только хуже.Ответы:
Я бы утверждать , что ваше использование является идиоматической Elisp, так как имя буфера является вполне подходящим логическим значением в своем собственном праве. Цитирование из руководства :
Чтобы продвинуться дальше, проверьте код для
clone-buffer
. Я ожидаю, что вы увидите следующее:Обратите внимание, что это тестирование привязки переменной
buffer-file-name
вместо вызова функции без аргумента(buffer-file-name)
, но они всегда должны вести себя одинаково.источник
Вы можете использовать либо
(buffer-file-name)
(с необязательным аргументом buffer), либо локальнуюbuffer-file-name
переменную buffer . Оба оценивают одно и то же значение для данного буфера.То есть идиоматический способ сделать это в Elisp, хотя, так что ваш код является штрафом. Если вы отчаянно хотите, вы всегда можете сделать функцию-
buffer-has-file-p
обертку.источник
(buffer-file-name BUFFER)
он, конечно, лучше(with-current-buffer BUFFER buffer-file-name)
, но в остальном я не думаю, что это имеет значение, какой из них вы используете (и поскольку функция написана на C, я сомневаюсь, что есть даже большая разница в производительности).Просто используйте
buffer-file-name
. В Лиспе мы часто используем ненулевоеnil
значение для обозначения истины .Единственный раз, когда вы можете избежать этого, это если функция дорогая или имеет нежелательные побочные эффекты.
источник
nil
является правдой, я просто думал, что схватить имя, когда я только хочу знать, существует ли какое-либо имя, «дорого» - но, похоже, это не так.Из главы «Список буферов» документации:
Таким образом, вы должны найти способ поиска в списке живых буферов. Вот один из них:
источник