No matter how many times I reload my .emacs
file,
M-x load-file RET ~/.emacs RET
I want the results to be the same as the first time. I want to make my .emacs
file be idempotent.
I know I can surgically evaluate a region (C-c C-r), a defun (C-M-x), or the last sexp (C-x C-e). I often take such a more refined approach when making small changes. However, when re-working a .emacs
file, I sometimes want to check results of the change conclusively by reloading the entire .emacs
file. Restarting emacs each time gets old quick, especially when doing major .emacs
housekeeping.
What specific steps must I take to update my .emacs
file to replace non-idempotent operations with idempotent ones?
For example,
add-hook
, which
will not re-add a function to the hook if already there.A comprehensive check-and-correct list would be ideal, but any key individual checks that occur to you would be helpful as well.
I don't know as it's possible to ensure this completely, as most .emacs files depend on libraries which may not have idempotent initialization routines. However, there are a few useful tricks to reduce problems:
Use named functions for add-hook
, and keybindings instead of anonymous functions. For add-hook
in particular, this allows it to swap out the existing reference.
Careful use of defvar
, by default the body is only evaluated if the variable is undefined. C-M-x
on a defvar
will re-eval the body, but eval-buffer
will not if the variable is already initialized.
Careful use of (quote function)
instead of function
to reference a named function instead of the value of the function. See Anonymous Functions for more advanced discussion about this.
Remember that require
will only load the corresponding library the first time it is executed, it will not re-eval on repeated calls as load
does. Autoload also uses require to load the corresponding library.
Prefer add-to-list
instead of cons
to only add an element if it doesn't exist.
For older mode activation, make sure to use (mode-name-mode t)
to activate instead of the toggle function. Likewise for turn-on-
minor mode functions instead of the mode toggle.
Guard blocks that do have side effects if executed repeatedly. In particular for server mode, (unless (server-running-p) (server-start))
, and similar guards for installing packages.
Being careful about side effects in eval-after-load
or custom mode hooks. Remember the default mode hooks run when a mode is first enabled, and on each subsequent buffer, but will not rerun in existing buffers when the hook function is modified. eval-after-load
is less likely to trip things up, it's still important to remember when it's evaluated.
Related to #2, makunbound
may be useful if a chain of vars that depend on each other need to be re-evaluated, as it will force the defvar
to always execute on evaluation of the file.
Running eval-buffer
on an init file should be as idempotent as possible, but it's important to remember that emacs lisp is fond of side effects and state. While it's possible to ameliorate this to some extent, re-evaling init will never return emacs to the state it was when it first started.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With