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раньше тега не было; это хорошая идея, чтобы использовать его?