8.2.4 Composite Sexp Widgets

The syntax for the composite widget construct is:

type ::= (construct [keyword argument]...  component...)

where each component must be a widget type. Each component widget will be displayed in the buffer, and will be editable by the user.

Widget: cons

A widget to edit cons-cell values. Its super is the group widget.

The value of a cons widget must be a cons-cell whose CAR and CDR have two specified types. It uses this syntax:

type ::= (cons [keyword argument]...  car-type cdr-type)
Widget: choice

A widget to hold a value of one of a fixed set of types. Its super is the menu-choice widget.

The widget’s syntax is as follows:

type ::= (choice [keyword argument]...  type ... )

The value of a choice widget can be anything that matches any of the types.

This widget only displays the widget that corresponds to the current choice.

Widget: radio

A widget to hold a value of one of a fixed set of options. Its super is the radio-button-choice widget.

Widget: list

A widget to edit a list value. Its super is the group widget.

The value of a list widget must be a list whose element types match the specified component types:

type ::= (list [keyword argument]...  component-type...)

Thus, for example, (list string number) matches lists of two elements, the first being a string and the second being a number.

Widget: vector

A widget to edit a vector value. Its super is the group widget.

The vector widget is like the list widget but matches vectors instead of lists. Thus, for example, (vector string number) matches vectors of two elements, the first being a string and the second being a number.

The above suffice for specifying fixed size lists and vectors. To get variable length lists and vectors, you can use a choice, set, or repeat widget together with the :inline keyword. If any component of a composite widget has the :inline keyword set, its value must be a list which will then be spliced into the composite. For example, to specify a list whose first element must be a file name, and whose remaining elements should either be the symbol t or two strings (file names), you can use the following widget specification:

(list file
      (choice (const t)
              (list :inline t
                    :value ("foo" "bar")
                    string string)))

The value of a widget of this type will either have the form (file t) or (file string string).

This concept of :inline may be hard to understand. It was certainly hard to implement, so instead of confusing you more by trying to explain it here, I’ll just suggest you meditate over it for a while.

Widget: set

A widget to hold a list of members from a fixed set. Its super is the checklist widget.

Its value is a list where the elements all belong to a given set. The order of elements of the list is not significant.

Here’s the syntax:

type ::= (set [keyword argument]...  permitted-element ... )

Use const to specify each permitted element, like this: (set (const a) (const b)).

Widget: repeat

Specifies a list of any number of elements that fit a certain type. Its super is the editable-list widget.

type ::= (repeat [keyword argument]...  type)
Widget: plist

A widget to edit property lists. Its super is the list widget.

It recognizes the following properties:

:options

A given set of recommended key-value values for the plist widget. Each option shows up as a checklist item.

:key-type

The widget type to use for the plist keys. By default, it uses the symbol widget.

:value-type

The widget type to use for the plist values. By default, it uses the sexp widget.

Widget: alist

A widget to edit association lists. Its super is the list widget.

It recognizes the same properties that the plist widget, with the difference that the :key-type uses by default a sexp widget.

Most composite widgets do not allow for recursion. That is, none of the contained widgets may be of the same type that is currently being defined. To allow for this kind of widgets, there’s the lazy widget.

Widget: lazy

A base widget for recursive data structures. Its super is the default widget.

When instantiated, it contains a single inferior widget of the widget type specified in the :type property. Its value is the same as the value of this inferior widget.