Як перевірити, чи буфер відвідує файл?


9

Я хотів би перевірити, який-небудь (скажімо, поточний) буфер відвідує файл чи ні. Я можу сказати:

(if (buffer-file-name) ...)

але це здається не дуже елегантним - те, що мене цікавить, є лише булевим значенням, а не власне іменем відповідного буфера. Якби buffer-file-nameфункція була написана в Elisp, я міг би заглянути в її джерело, щоб дізнатися, що вона використовує - але вона написана на C, і хоча я могла встановити джерела Emacs, я боюся, що не знайду імені Elisp для функції, яка перевіряє те, що я все-таки шукаю.

Для чого мені потрібно, я хочу створити каталог на основі імені файлу поточного буфера, і в даний час я роблю це більш-менш:

(make-directory (if (buffer-file-name) (file-name-base) "default-dir"))

Отже, яким би був Елісп-ідіоматичний спосіб зробити це?


2
Не впевнений, чому ви заперечуєте проти використання buffer-file-nameдійсно, це правильний спосіб зробити це (якщо ви дійсно хочете t, зробіть це, (and (buffer-file-name) t)але це потворніше ІМО). Її реалізація полягає в зчитуванні filenameполя буфера С-структури, яке так чи інакше недоступне безпосередньо від Elisp. Зрештою, це просто вказівник, який є нульовим чи ні.
Зігма

Ну, якщо це правильний шлях, зі мною це добре. Як я вже сказав - я не знав реалізації C, і здоровий глузд говорить, що запитувати ім'я файлу, коли я хочу лише знати, чи може бути щось зайве.
mbork

І я згоден, це (and (buffer-file-name) t)виглядає дивно.
mbork

Якщо ви не вважаєте, що (if (buffer-file-name) ... )це елегантно, ви не дуже довго кодували в elisp. Звідси стає лише гірше.
nispio

Відповіді:


12

Я заперечую, що ваше використання є ідіоматичним elisp, оскільки ім'я буфера саме цілком відповідне булеве значення. Цитуючи посібник :

Існує важливий аспект тесту на істинність у виразі if. Поки що ми говорили про "правдиві" та "помилкові" як значення предикатів, ніби вони були новими об'єктами Emacs Lisp. Насправді, «помилковий» - це просто наш старий друг nil. Все інше - будь-що взагалі - «правда».

Щоб продовжити питання, ознайомтеся з кодом clone-buffer. Я думаю, ви побачите наступне:

(interactive
 (progn
   (if buffer-file-name
       (error "Cannot clone a file-visiting buffer"))
...

Зауважте, що це тестування змінної прив'язки buffer-file-nameзамість виклику функції без аргументу (buffer-file-name), але обидві завжди повинні поводитись однаково.


8

Ви можете використовувати або (buffer-file-name)(з додатковим аргументом буфера), або локальну buffer-file-nameзмінну буфера . Обидва оцінюють до однакового значення для даного буфера.

Те є ідіоматичний спосіб зробити це в Elisp, хоча, так що ваш код є штрафом. Якщо ви відчайдушно хотіли, ви завжди можете зробити функцію buffer-has-file-pобгортки.


Дякую. Чи є якась значна різниця у виборі функції чи змінної?
mbork

1
Я не думаю, що так. Якщо вам потрібно вказати аргумент буфера, то (buffer-file-name BUFFER)це, безумовно, приємніше ніж (with-current-buffer BUFFER buffer-file-name), але в іншому випадку я не думаю, що це важливо, який ви використовуєте (а як функція написана на C, я сумніваюся, що навіть велика різниця у продуктивності).
phils

3

Просто використовуйте buffer-file-name. У Lisp ми часто використовуємо не nilзначення, щоб означати істину .

Ви можете уникнути цього лише тоді, коли функція дорога або має небажані побічні ефекти.


Розумію. Я знаю, що нічого nilнеправдивого, я просто думав захопити ім'я, коли мені хочеться дізнатись, чи існує якесь ім'я - «дорого» - але, здається, це не так.
mbork

1

З розділу "Список буфера" документації:

Список, що повертається буферним списком, будується спеціально; це не внутрішня структура даних Emacs , і її зміна не впливає на порядок буферів.

Тож вам доведеться знайти спосіб пошуку у списку живих буферів. Ось один:

  (if (string-match-p (regexp-quote "My buffer name") (format "%s" (buffer-list)))
      (message "Open")
    (message "Not open"))
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.