TL;DR
Is there some standard fallback handling in the customize
system, for handling partially invalid composite customization
variables, e.g. an alist where one entry is not a cons?
Long Version
The customize-mechanism of emacs is quite powerful by using
composite :type
arguments to defcustom
provides a nifty
unified interface for customizing variables.
However, when for whatever reason a single entry of the variable is wrong the whole system breaks down and it will just show the bare s-expression. There is then no help to fix this expect for deleting the customizations hoping that the default value matches the type description.
At least that is what I have experienced so far.
If I have a customization variable that is a complicated data structure, is there some mechanism that allows showing only the corrupted part of the variable as a bare s-expression?
Think e.g. about
(defcustom x
'((org-mode . "a\\|b")
(text-mode . "b\\|c"))
"Some variable"
:group 'x
:type '(repeat
(cons :tag "Entry"
(function :tag "Mode" :value text-mode)
(regexp))))
Normally M-x customize-variable x
will no display a nice input mask.
Hide X:
INS DEL Entry:
Mode: org-mode
Regexp: a\|b
INS DEL Entry:
Mode: text-mode
Regexp: b\|c
INS
State : STANDARD.
Some variable
Groups: X
When I now do
(add-to-list 'x 1)
the mask becomes a significantly less user friendly
Hide x:
'(1
(org-mode . "a\\|b")
(text-mode . "b\\|c"))
State : CHANGED outside Customize. (mismatch)
Some variable
Groups: X
Now of course I can include a fallback option by changing the definition to something like
(defcustom x
'((org-mode . "a\\|b")
(text-mode . "b\\|c"))
"Some variable"
:group 'x
:type '(repeat
(choice
(cons :tag "Entry"
(function :tag "Mode" :value text-mode)
(regexp))
(sexp :tag "MISMATCHED ENTRY!"))))
which gives a customization mask
Hide X:
INS DEL Choice: Value Menu MISMATCHED ENTRY!: 1
INS DEL Choice: Value Menu Entry:
Mode: org-mode
Regexp: a\|b
INS DEL Choice: Value Menu Entry:
Mode: text-mode
Regexp: b\|c
INS
State : CHANGED outside Customize.
Some variable
Groups: X
However this does now include an awkward drop-down menu that gives the user the choice between an entry and an invalid value. Rather I'd have the drop down value hidden by default and shown only when there is a mismatch with the valid option. As a user my first thought seeing such would be along the lines of “”.
Is there some standard way in the customization system to handle partly invalid values? I couldn't find any in the documentation.¹