In an Emacs package I have a defcustom
, say custom-string
, that is defined as an atom of type string
like so:
(defcustom custom-string "foo"
"A customizable string."
:type 'string)
I need to generalize the variable so that it can be a sequence of strings, but if the user has already chosen a single string it will be fine to continue using that string as before. (For example, the variable could be a list of paths to search. One path is sufficient, but some users may want to use multiple paths.) I'd like to update the package in a way that doesn't break existing configurations. I see two ways forward, but I don't know which is preferable or if there is some other standard approach for this:
Deprecate
custom-string
withmake-obsolete-variable
and and create a new variable calledcustom-strings
which is of type(repeat string)
. In this case, if the user has defined the atomic variable, then it can be detected and used to initialize the list variable. This approach looks like this:(make-obsolete-variable 'custom-string 'custom-strings "2017-11-10") (defcustom custom-strings (if (boundp 'custom-string) (list custom-string) '("first" "second" "third")) "Customizable list of strings." :type '(repeat string))
The benefits of this approach are that the user doesn't have to change his or her configuration and the new variable name is plural, an indication that it is a sequence.
Keep the variable name the same but change the
defcustom
type to(repeat string)
. In the code where the variable is used, add a conditional to check if it is a string or a list.(if (stringp custom-string) ... ; handle single string ...) ; handle list case
This approach also has the benefit of allowing the user init file to remain unchanged, and furthermore it leaves the variable name the same so that documentation, tutorials, etc. don't need to be updated. But it may be confusing that it is a list with a singular variable name (i.e.,
-string
not-strings
). I also worry that this might break existing configurations for users who use the customize interface, where it has been stored as a string. (I don't usecustomize
, so I'm not sure how this is handled.)
I have used the first approach before in markdown-mode
, when I changed markdown-css-path
to markdown-css-paths
so that users could link multiple stylesheets. However, this time I have several variables to change at once and I'd like this to be as unobtrusive as possible. I haven't been able to find examples from other packages. Which of these is the most "Emacs-like" way of proceeding? Or is there another, better solution I haven't thought of?
PATH
.