40

How do you reload directory-local variables? I would like to modify a .dir-locals.el and have such changes applied to the current Emacs session.

3
  • 3
    The directory-local variables don't apply to the session - they apply to every buffer related to a file in that directory. So, one approach, if you are fine with reverting your open buffers, would be to simply revert all of them, by running through buffer-list.
    – Pradhan
    Commented Jun 11, 2015 at 2:52
  • @Pradhan: Albeit I would rather employ a more direct approach, your suggestion worked. Thanks.
    – Eleno
    Commented Jun 11, 2015 at 7:54
  • 3
    @Pradhan I was wrong: reverting the buffer does not work, unless the local variables have been registered as safe.
    – Eleno
    Commented Jun 11, 2015 at 9:57

2 Answers 2

40

This function will re-read the dir-locals file and set the new values for the current buffer:

(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)))

And if you want to reload dir-locals for every buffer in your current buffer's directory:

(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))))))

You could have all the dir locals refresh every time you save a dir-locals file by adding an after-save-hook to .dir-locals.el buffers.

(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 'after-save-hook
                        'my-reload-dir-locals-for-all-buffer-in-this-directory
                        nil t))))

Of course this could have unintended consequences because it will reset the variables values regardless of whether they have been changed elsewhere, so use at your own risk.

2
  • 13
    I almost feel like this should be built into Emacs.
    – PythonNut
    Commented Jun 11, 2015 at 18:14
  • alternatively, one can add a warning asking for confirmation in the autoreload function if some variable will be erase.
    – Welgriv
    Commented Aug 3, 2020 at 10:49
7

You can also use: M-: (hack-dir-local-variables-non-file-buffer)


To check it works: from a buffer (an org mode file for instance), type M-x add-dir-local-variable, then validate (default org-mode), then type demo RET, then "this is a demo" RET.

Your .dir-locals.el file will appear in a buffer:

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

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

You have to save it: C-x C-s

Then go back to your org mode buffer and check that the demo variable is not defined (C-h C-v demo)

Here you can use the trick: M-: (hack-dir-local-variables-non-file-buffer)

Now C-h C-v demo will print:

demo’s value is "this is a demo" Local in buffer poub.org; globally void

This variable’s value is directory-local, set by the file
‘/home/picaud/Temp/.dir-locals.el’.

Documentation: Not documented as a variable.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.