The help for custom-set-variables
says:
The arguments should each be a list of the form:
(SYMBOL EXP [NOW [REQUEST [COMMENT]]])
This stores EXP (without evaluating it) as the saved value for SYMBOL.
If NOW is present and non-nil, then also evaluate EXP and set
the default value for the SYMBOL to the value of EXP.
REQUEST is a list of features we must require in order to
handle SYMBOL properly.
So if NOW
is nil
then EXP
won't be evaluated immediately, which suggests to me that it should be possible for EXP
to refer to variables or functions provided by features in the REQUEST
list which are not yet loaded.
Even if my interpretation is wrong, it should be possible to safely use custom-set-variables
to customize variables in features which are not yet loaded. For example, if I have something like:
(custom-set-variables
'(yas-snippet-dirs
('("~/.config/yasnippets/rails")) nil (yasnippet)))
Then I would expect this variable only to be set once yasnippet
is loaded.
It turns out that custom-set-variables
tries to load yasnippet
immediately. This means that the custom-file
containing this directive has to be loaded after all other user init code which takes care of ensuring that yasnippet
is available (e.g. loading it from MELPA or el-get
or via req-package
). That's all well and good if yasnippet
is available, but what if it isn't available, or at least not yet available, due to some deferred or lazy-loading?
Currently this will result in a backtrace ending in something like this:
Debugger entered--Lisp error: (file-error "Cannot open load file" "no such file or directory" "yasnippet")
require(yasnippet)
mapc(require (yasnippet))
custom-theme-set-variables(user (yas-snippet-dirs (quote ("~/.config/yasnippets/rails")) nil (yasnippet)))
which will then break the rest of the user's initialisation, which is really bad. OTOH, if I just remove the REQUEST
argument in order to allow deferred loading, then presumably the value of specifying that argument is lost.
So what's the correct way to safely customize variables for packages which are lazy-loaded or loaded on demand?
(BTW in case it's not obvious, I'm looking for a solution which doesn't bypass custom.el
, because then I lose the ability to customize via custom.el
's nice UI. Otherwise I would simply do setq
inside the :config
section of my use-package
declaration ... Doing custom-set-variables
in the same place doesn't work either, because updating the value via the custom.el
UI would still update the file pointed to by custom-file
rather than this correct location.)