Перезагрузка каталогов локальных переменных

27

Как вы перезагрузите локальные переменные каталога? Я хотел бы изменить .dir-locals.elи применить такие изменения к текущей сессии Emacs.

Елена
источник
3
Локальные переменные каталога не применяются к сеансу - они применяются к каждому буферу, связанному с файлом в этом каталоге. Таким образом, один из подходов, если у вас все в порядке с возвратом ваших открытых буферов, заключается в простом возврате всех из них, путем прогона buffer-list.
Прадхан
@Pradhan: Хотя я бы предпочел использовать более прямой подход, ваше предложение сработало. Спасибо.
Елена
3
@Pradhan Я был неправ: возврат буфера не работает, если локальные переменные не были зарегистрированы как безопасные.
Елена

Ответы:

21

Эта функция перечитает файл dir-locals и установит новые значения для текущего буфера:

(defun my-reload-dir-locals-for-current-buffer ()
  "reload dir locals for the current buffer"
  (interactive)
  (let ((enable-local-variables :all))
    (hack-dir-local-variables-non-file-buffer)))

И если вы хотите перезагрузить dir-locals для каждого буфера в каталоге вашего текущего буфера:

(defun my-reload-dir-locals-for-all-buffer-in-this-directory ()
  "For every buffer with the same `default-directory` as the 
current buffer's, reload dir-locals."
  (interactive)
  (let ((dir default-directory))
    (dolist (buffer (buffer-list))
      (with-current-buffer buffer
        (when (equal default-directory dir))
        (my-reload-dir-locals-for-current-buffer)))))

Все after-save-hookлокальные каталоги dir можно обновлять каждый раз, когда вы сохраняете файл dir-locals, добавляя буферы в .dir-locals.el.

(add-hook 'emacs-lisp-mode-hook
          (defun enable-autoreload-for-dir-locals ()
            (when (and (buffer-file-name)
                       (equal dir-locals-file
                              (file-name-nondirectory (buffer-file-name))))
              (add-hook (make-variable-buffer-local 'after-save-hook)
                        'my-reload-dir-locals-for-all-buffer-in-this-directory))))

Конечно, это может привести к непредвиденным последствиям, так как будет сбрасывать значения переменных независимо от того, были ли они изменены в другом месте, поэтому используйте их на свой страх и риск.

Джордон Биондо
источник
5
Я почти чувствую, что это должно быть встроено в Emacs.
PythonNut
3

Вы также можете использовать: M-: (hack-dir-local-variables-non-file-buffer)


Чтобы проверить, работает ли он : из буфера (например, файла режима org) введите M-x add-dir-local-variable, затем подтвердите (по умолчанию режим org), затем введите demo RET, затем «this is demo» RET.

Ваш файл .dir-locals.el появится в буфере:

;;; Directory Local Variables
;;; For more information see (info "(emacs) Directory Variables")

((org-mode
  (demo . "this is a demo")))

Вы должны сохранить это: C-x C-s

Затем вернитесь в буфер режима org и убедитесь, что демонстрационная переменная не определена ( C-h C-v demo)

Здесь вы можете использовать трюк: M-: (hack-dir-local-variables-non-file-buffer)

Теперь C-h C-v demoнапечатает:

значение демо - это «это демо» Local в буфере poub.org; глобально недействительным

Значение этой переменной является локальным для каталога и устанавливается файлом
'/home/picaud/Temp/.dir-locals.el'.

Документация: не задокументировано как переменная.

Пикауд Винсент
источник