Composite Types
---------------
When none of the simple types is appropriate, you can use composite
types, which build new types from other types. Here are several ways of
doing that:
`(restricted-sexp :match-alternatives CRITERIA)'
The value may be any Lisp object that satisfies one of CRITERIA.
CRITERIA should be a list, and each element should be one of these
possibilities:
* A predicate--that is, a function of one argument that has no
side effects, and returns either `nil' or non-`nil' according
to the argument. Using a predicate in the list says that
objects for which the predicate returns non-`nil' are
acceptable.
* A quoted constant--that is, `'OBJECT'. This sort of element
in the list says that OBJECT itself is an acceptable value.
For example,
(restricted-sexp :match-alternatives
(integerp 't 'nil))
allows integers, `t' and `nil' as legitimate values.
The customization buffer shows all legitimate values using their
read syntax, and the user edits them textually.
`(cons CAR-TYPE CDR-TYPE)'
The value must be a cons cell, its CAR must fit CAR-TYPE, and its
CDR must fit CDR-TYPE. For example, `(cons string symbol)' is a
customization type which matches values such as `("foo" . foo)'.
In the customization buffer, the CAR and the CDR are displayed and
edited separately, each according to the type that you specify for
it.
`(list ELEMENT-TYPES...)'
The value must be a list with exactly as many elements as the
ELEMENT-TYPES you have specified; and each element must fit the
corresponding ELEMENT-TYPE.
For example, `(list integer string function)' describes a list of
three elements; the first element must be an integer, the second a
string, and the third a function.
In the customization buffer, each element is displayed and edited
separately, according to the type specified for it.
`(vector ELEMENT-TYPES...)'
Like `list' except that the value must be a vector instead of a
list. The elements work the same as in `list'.
`(choice ALTERNATIVE-TYPES...)'
The value must fit at least one of ALTERNATIVE-TYPES. For
example, `(choice integer string)' allows either an integer or a
string.
In the customization buffer, the user selects one of the
alternatives using a menu, and can then edit the value in the
usual way for that alternative.
Normally the strings in this menu are determined automatically
from the choices; however, you can specify different strings for
the menu by including the `:tag' keyword in the alternatives. For
example, if an integer stands for a number of spaces, while a
string is text to use verbatim, you might write the customization
type this way,
(choice (integer :tag "Number of spaces")
(string :tag "Literal text"))
so that the menu offers `Number of spaces' and `Literal Text'.
In any alternative for which `nil' is not a valid value, other than
a `const', you should specify a valid default for that alternative
using the `:value' keyword. Note:Type Keywords.
`(radio ELEMENT-TYPES...)'
This is similar to `choice', except that the choices are displayed
using `radio buttons' rather than a menu. This has the advantage
of displaying documentation for the choices when applicable and so
is often a good choice for a choice between constant functions
(`function-item' customization types).
`(const VALUE)'
The value must be VALUE--nothing else is allowed.
The main use of `const' is inside of `choice'. For example,
`(choice integer (const nil))' allows either an integer or `nil'.
`:tag' is often used with `const', inside of `choice'. For
example,
(choice (const :tag "Yes" t)
(const :tag "No" nil)
(const :tag "Ask" foo))
describes a variable for which `t' means yes, `nil' means no, and
`foo' means "ask."
`(other VALUE)'
This alternative can match any Lisp value, but if the user chooses
this alternative, that selects the value VALUE.
The main use of `other' is as the last element of `choice'. For
example,
(choice (const :tag "Yes" t)
(const :tag "No" nil)
(other :tag "Ask" foo))
describes a variable for which `t' means yes, `nil' means no, and
anything else means "ask." If the user chooses `Ask' from the
menu of alternatives, that specifies the value `foo'; but any
other value (not `t', `nil' or `foo') displays as `Ask', just like
`foo'.
`(function-item FUNCTION)'
Like `const', but used for values which are functions. This
displays the documentation string as well as the function name.
The documentation string is either the one you specify with
`:doc', or FUNCTION's own documentation string.
`(variable-item VARIABLE)'
Like `const', but used for values which are variable names. This
displays the documentation string as well as the variable name.
The documentation string is either the one you specify with
`:doc', or VARIABLE's own documentation string.
`(set TYPES...)'
The value must be a list, and each element of the list must match
one of the TYPES specified.
This appears in the customization buffer as a checklist, so that
each of TYPES may have either one corresponding element or none.
It is not possible to specify two different elements that match
the same one of TYPES. For example, `(set integer symbol)' allows
one integer and/or one symbol in the list; it does not allow
multiple integers or multiple symbols. As a result, it is rare to
use nonspecific types such as `integer' in a `set'.
Most often, the TYPES in a `set' are `const' types, as shown here:
(set (const :bold) (const :italic))
Sometimes they describe possible elements in an alist:
(set (cons :tag "Height" (const height) integer)
(cons :tag "Width" (const width) integer))
That lets the user specify a height value optionally and a width
value optionally.
`(repeat ELEMENT-TYPE)'
The value must be a list and each element of the list must fit the
type ELEMENT-TYPE. This appears in the customization buffer as a
list of elements, with `[INS]' and `[DEL]' buttons for adding more
elements or removing elements.