How to properly write the default value for a non-trivial defcustom
form for something like I have below: a list of 3-element lists, with choices of the types?
The defcustom
form is: defcustom option standard doc [keyword value]...
The following defcustom
works fine as long as:
- it's default is nil
- it's a list of one or several elements of the first type
It fails with a "mismatch" warning in the customize buffer as soon as the default is a list of heterogeneous types (e.g. one element is from the second or third choice).
#1: My defcustom form: (with a nil
default, it works fine)
(defcustom pel-key-chords nil
"..."
:group 'pel-pkg-for-key-chord
:type '(repeat
(choice
(list
:tag "expansion-keys"
(symbol :tag "mode " :value global)
(string :tag "the 2 keys ")
(repeat
(key-sequence :tag "key")))
(list
:tag "command"
(symbol :tag "mode " :value global)
(string :tag "the 2 keys ")
(function :tag "command "))
(list
:tag "lambda"
(symbol :tag "mode " :value global)
(string :tag "the 2 keys ")
(function :tag "elisp code "
:value (lambda () (interactive) <YOUR CODE HERE>))))))
If, instead of nil
as the default I write a list with several items of different types, the customization menu fails with a mismatch and does not to properly show the widgets to enter new entries. If the list contains elements of the first type, it's fine.
#2: My defcustom form: (same code, but with an explicit default that works fine: a list of elements of the first choice:
(defcustom pel-key-chords
'((global "<>" ("<>\C-b"))
(global "[]" ("[]\C-b"))
(c++-mode "{}" ("{\n\n}\C-p")))
"..."
...
#3: My defcustom form: (same code, but with an explicit default that fails with a mismatch: a list of 3 elements of the first choice, then 1 element of the second choice:
(defcustom pel-key-chords
'((global "<>" ("<>\C-b"))
(global "[]" ("[]\C-b"))
(c++-mode "{}" ("{\n\n}\C-p"))
(global ".;" pel-search-word-from-top))
"..."
...
Interesting note: Additions of second and/or third type elements via the customize buffer while the default has accepted data (as in #2 above), are accepted, saved to the custom-set-variables form properly and restored properly back in the customize buffer!
This is a copy/paste of the content of the relevant portion of my custom-set-variables form after manually adding the last list element (global ".;" pel-search-word-from-top)
via the customize buffer and then saved it gives:
'(pel-key-chords
(quote
((global "<>"
("<>^B"))
(global "[]"
("[]^B"))
(c-mode "{}"
("{
}^P"))
(c++-mode "{}"
("{
}^P"))
(global ".;" pel-search-word-from-top))))
I can then read it back without any mismatch. If I try to put this inside the default I get the mismatch warning...
I read Emacs Lisp Customization Settings section and some code like the dump-jump.el
code that defines some complex data with initialization. I assume I must identify some keywords in my declaration of the default, but for some reason I can't find the proper syntax for initializing the data I defined above.
Note: this question evolved from my previous question How to properly specify defcustom default value for non-trivial data type?