How can I easily reload file-local variables, after I have changes their values in the file buffer?
I know a work around
Save and close the file and re-open.
But this is pretty cumbersome.
Emacs Stack Exchange is a question and answer site for those using, extending or developing Emacs. It only takes a minute to sign up.Sign up to join this community
I stumbled myself over a way to do this when looking at the Elisp code in
This command re-applies the local file variable list by calling the function
normal-mode does a lot of other stuff too, so this is not just re-reading the local variables...
I just use
find-alternate-file which is bound to
C-x C-v by default.
C-x C-v Ret is lightning fast for me.
revert-buffer will also work, but
M-x revert-buffer Ret is more typing.
Both of these options will reset local variables. For instance, if you have
indent-tabs-mode: nil in your local variable list and you remove it outright, save,
revert-buffer your buffer,
indent-tabs-mode will now be set to
t (assuming you haven't changed its default elsewhere of course.) Note: I only confirmed this with file-local variables, and not directory-local variables.
@drew brings up a good point. If you're not careful, or use these functions non-interactively you can overwrite unsaved changes in your buffer. Also, if you have unsaved changes, using these functions can break your flow.
find-alternate-file will ask to save your buffer, and
revert-buffer will ask to overwrite your unsaved changes. As you develop muscle memory and good editing habit, you'll find it gets in your way less and less.
Warning: It does not reset local variables. That means if you remove a variable from the list of local variables this variable is still bound (and set to the old value) after running
hack-local-variables. I think that could be the reason why it is just a function and not an interactive command.
You can easily turn
hack-local-variables into an interactive command with the following advice:
(defun hack-local-variables-make-interactive (&rest _args) "Just add the `interactive'-specification to `hack-local-variables'." (interactive)) (advice-add 'hack-local-variables :before #'hack-local-variables-make-interactive)
I most often need
hack-local-variables in Orgmode files. Therefore I wrote a context-aware binding for C-c C-c. It runs
hack-local-variables when it is in a Local Variables section of an Orgmode document.
(require 'subr-x) (require 'org) (defun org+-ctrl-c-ctrl-c-local-variables (&optional noerror) "Run `hack-local-variable' when we are in the \"Local Variables\" section. If the Local Variables section is not found and NOERROR is nil or omitted this function signals a user error." (interactive "P") (save-excursion (when-let ((heading (condition-case nil (save-excursion (org-back-to-heading t) (when (looking-at "\\*[[:space:]]") (cons (point) (org-get-tags)))) (error nil))) (heading-pos (car heading)) (heading-tags (cdr heading)) (re "^[[:space:]]*\\(#+\\)?[[:space:]]*\\(local[[:space:]]+\\(variables\\)\\|\\(end\\)\\):[[:space:]]*$") (local-variables-start (progn (save-excursion (re-search-backward re heading-pos t)) (match-string 3))) (in-comment (match-string 1)) (local-variables-end (progn (re-search-forward (format "%s\\|^\\*+[[:space:]]" re) nil t) (match-string 4)))) (if (and local-variables-start local-variables-end (or in-comment (member "noexport" heading-tags))) (progn (hack-local-variables) (message "Hacked local variables") t) (user-error "Local Variables not found") )))) (add-to-list 'org-ctrl-c-ctrl-c-hook #'org+-ctrl-c-ctrl-c-local-variables)