You really never know. My post about persisting Emacs variables was a short tip, written in literally a few minutes to give me a respite from writing and time to complete some longer posts which are underway. It is no mystery that some posts are long (and I hope good) articles, and some are just short texts I put out when I’m overwhelmed with work – and the post about persist
was definitely in the latter category. While I still consider it a useful tip, I never expected to get serious feedback about it – and here it is.
First, a commenter told me about the savehist
feature, which has been part of Emacs since v22.1. I have to admit I didn’t know (or didn’t remember) about savehist
– it’s no shame, though, Emacs is huge and nobody can be reasonably expected to know everything about it.
Anyway, savehist
is something which indeed does roughly the same thing as persist
. There are some differences, though. For example, persist
saves the variables it knows about on killing Emacs, while savehist
also saves them every 5 minutes (which is a nice thing, since Emacs crashes are very rare but not unheard of, especially if you run the bleeding edge like me). The main difference, though, is that savehist
– as its name suggests – is really aimed at history variables. It uses a pretty clever trick to activate itself when the user enters the minibuffer, then checks if a history variable is used and if it is, it automatically adds it to its list of variables to keep. You can add custom, non-history variables for it to save with savehist-additional-variables
and prevent some histories from saving with savehist-ignored-variables
, so it can be used to keep any variable saved, though. (It also has a pretty interesting feature which makes sense for history variables but is absurd for most other uses, which is to automatically trim the saved list to a predefined number of elements – see the docstring for savehist-additional-variables
.) My understanding is that this is aimed at users who want to customize Emacs to persist (some or all) history variables and possibly something else. On the other hand, persist
is much smaller (about 120 lines compared to savehist
’s 250) and hence simpler, and looks like something aimed also (or maybe even mainly) at package writers who want their package to have the value of some variable remembered across Emacs sessions. This is something that savehist
explicitly doesn’t support – the list of saved and ignored variables are kept in user options, and I can’t imagine a package changing the value of a user option behind the scenes. With persist
, the list of kept variables is not “centralized” in an option (it is kept in an internal variable persist--symbols
, though) – every persisted variable’s value is saved to a different file, named after that variable, and you can just delete a file from the ~/.emacs/persist
directory to stop persisting a no longer used variable. (Of course, if you have a persist-defvar
invocation in your init.el
, the file will be recreated when you restart Emacs.) This has an interesting consequence – if the variable’s name contains a slash, then its value is kept deeper in the directory hierarchy. (If you are wondering what would happen if someone used an actual null byte in a variable name – which is technically possible, of course – well, I checked that, and rather predictably you get a wrong-type-argument filenamep
error.)
Quite unexpectedly, I also received an email with someone telling me that Emacs has yet another way to persist variables, and – surprise! – it’s built-in, too! Multisession variables are very similar to what persist
offers, with one important distinction – you need to use the function multisession-value
to access the value of a multisession variable. It also works as a setter, so (setf
(multisession-value my-variable) my-value)
is the way to set or update a value of such a variable. (If you wonder how it’s possible that multisession-value
is a function and not a macro, the answer is simple – multisession variables are in fact wrapped in objects holding more than just the current value of the variable, and multisession-value
is made to be a generalized variable, something I might be tempted to write about in a future blog post.)
Other than the syntax differences, multisession variables work very similarly to persist
ed variables, with some (minor) differences. One of them is that they support running more than one Emacs session simultaneously, although this support is very rudimentary – there is no locking, so if two Emacs sessions try to update the same variable at the same time, the result is unpredictable. More interestingly, there are two backends for multisession variables – they can be kept in files within ~/.emacs.d
(much like persist
) or in an SQLite database (provided your Emacs was compiled with SQLite support, which it really should). Also, each multisession variable can contain information about the package it belongs to – this is useful when you say M-x list-multisession-values
to see the list of all multisession variables, together with their packages and values, and the ability to interactively edit or delete them.
This means that multisession variables are a valid (and perhaps even better) alternative to persist
ed variables, slightly more expensive in terms of code complexity, but having a few features you might consider worth it (and built-in, although persist
almost is, too, being on Elpa). And as is often the case, this means that you – as an Elisp programmer – have a choice which one to choose. (The main reason I use persist
is that until very recently I had no idea about multisession variables. In fact, when I wrote my first code using persist
, multisession variables didn’t even exist – they are a relatively new addition to Emacs, dating to December 2021, just a few weeks after I used persist
for the first time.)
That’s it for today, happy hacking – and happy persisting your variables!