TL; DR : у find-file-noselect
вас нет контроля над тем, что на самом деле происходит, и вы можете получить произвольные второстепенные режимы, включенные в буфере, в зависимости от того, что пользователь включил в них init.el
. Кроме того, очистка это сложно.
Используйте with-temp-buffer
и insert-file-contents
вместо. Если вам нужны определенные основные или второстепенные режимы в буфере, включите их явно . with-temp-file
Вместо этого используйте для записи файлов, который, несмотря на его имя, позволяет писать в произвольные файлы.
Побочные эффекты
find-file-noselect
имеет много побочных эффектов, в том числе
- интерактивно задаваемые вопросы (это само по себе не допускается при неинтерактивном использовании),
- автоматическое включение режима просмотра файлов только для чтения,
- в противном случае вход в нормальный режим,
- и работает
find-file-hook
.
Нормальный режим сам
- автоматически выбирает правильный основной режим для текущего буфера,
- запускает все соответствующие основные и второстепенные перехваты режима,
- и считывает все локальные переменные для текущего буфера, то есть файловые переменные и переменные каталога, что снова может задавать интерактивные вопросы о небезопасных локальных переменных.
Поскольку все перехваты запускаются, вы получаете все второстепенные режимы и функции перехвата, которые пользователь включил в свои функции init.el
, что может вызвать все, от незначительных неудобств (если включены нежелательные второстепенные режимы) до серьезного хаоса (если пользователь добавил функцию перехвата, которая ожидает вызываться из интерактивного контекста).
См. Https://github.com/flycheck/flycheck/issues/366 для примера. В результате использования find-file-noselect
файла Flycheck была проверена синтаксическая проверка файла данных, и, поскольку это происходило при завершении работы Emacs, не было времени для правильной очистки, оставив временный файл.
уборка
С find-file-noselect
вами нужно быть очень осторожным, чтобы снова убить буфер. find-file-noselect
не делает это для вас.
Вам нужно запомнить буфер в каком-то месте и тщательно использовать unwind-protect
его, чтобы убедиться, что буфер уничтожен даже в случае нелокальных выходов.
альтернативы
Для чтения файлов используйте with-temp-buffer
и insert-file-contents
, который выполняет только самые простые действия, например, преобразование системы кодирования, но не задает вопросов, не включает хуки и не устанавливает локальные переменные:
(with-temp-buffer
(insert-file-contents (locate-user-emacs-file "foo.el"))
;; Enter the major mode explicitly
(emacs-lisp-mode)
;; …
)
with-temp-buffer
заботится, чтобы правильно убить временный буфер в конце его тела.
Для записи файлов используйте with-temp-file
команду, которая создает временный буфер и записывает содержимое в указанное имя файла в конце его тела:
(with-temp-file (locate-user-emacs-file "foo.el")
(prin1 (list 'my 'data) (current-buffer)))
good-practices
раньше тега не было; это хорошая идея, чтобы использовать его?