diff options
Diffstat (limited to 'devdocs/elisp/composite-types.html')
| -rw-r--r-- | devdocs/elisp/composite-types.html | 82 |
1 files changed, 82 insertions, 0 deletions
diff --git a/devdocs/elisp/composite-types.html b/devdocs/elisp/composite-types.html new file mode 100644 index 00000000..29ed8516 --- /dev/null +++ b/devdocs/elisp/composite-types.html @@ -0,0 +1,82 @@ + <h4 class="subsection">Composite Types</h4> <p>When none of the simple types is appropriate, you can use composite types, which build new types from other types or from specified data. The specified types or data are called the <em>arguments</em> of the composite type. The composite type normally looks like this: </p> <div class="example"> <pre class="example">(<var>constructor</var> <var>arguments</var>…) +</pre> +</div> <p>but you can also add keyword-value pairs before the arguments, like this: </p> <div class="example"> <pre class="example">(<var>constructor</var> <span class="roman">{</span><var>keyword</var> <var>value</var><span class="roman">}</span>… <var>arguments</var>…) +</pre> +</div> <p>Here is a table of constructors and how to use them to write composite types: </p> <dl compact> <dt><code>(cons <var>car-type</var> <var>cdr-type</var>)</code></dt> <dd> +<p>The value must be a cons cell, its <small>CAR</small> must fit <var>car-type</var>, and its <small>CDR</small> must fit <var>cdr-type</var>. For example, <code>(cons string +symbol)</code> is a customization type which matches values such as <code>("foo" . foo)</code>. </p> <p>In the customization buffer, the <small>CAR</small> and <small>CDR</small> are displayed and edited separately, each according to their specified type. </p> </dd> <dt><code>(list <var>element-types</var>…)</code></dt> <dd> +<p>The value must be a list with exactly as many elements as the <var>element-types</var> given; and each element must fit the corresponding <var>element-type</var>. </p> <p>For example, <code>(list integer string function)</code> describes a list of three elements; the first element must be an integer, the second a string, and the third a function. </p> <p>In the customization buffer, each element is displayed and edited separately, according to the type specified for it. </p> </dd> <dt><code>(group <var>element-types</var>…)</code></dt> <dd> +<p>This works like <code>list</code> except for the formatting of text in the Custom buffer. <code>list</code> labels each element value with its tag; <code>group</code> does not. </p> </dd> <dt><code>(vector <var>element-types</var>…)</code></dt> <dd> +<p>Like <code>list</code> except that the value must be a vector instead of a list. The elements work the same as in <code>list</code>. </p> </dd> <dt><code>(alist :key-type <var>key-type</var> :value-type <var>value-type</var>)</code></dt> <dd> +<p>The value must be a list of cons-cells, the <small>CAR</small> of each cell representing a key of customization type <var>key-type</var>, and the <small>CDR</small> of the same cell representing a value of customization type <var>value-type</var>. The user can add and delete key/value pairs, and edit both the key and the value of each pair. </p> <p>If omitted, <var>key-type</var> and <var>value-type</var> default to <code>sexp</code>. </p> <p>The user can add any key matching the specified key type, but you can give some keys a preferential treatment by specifying them with the <code>:options</code> (see <a href="variable-definitions">Variable Definitions</a>). The specified keys will always be shown in the customize buffer (together with a suitable value), with a checkbox to include or exclude or disable the key/value pair from the alist. The user will not be able to edit the keys specified by the <code>:options</code> keyword argument. </p> <p>The argument to the <code>:options</code> keywords should be a list of specifications for reasonable keys in the alist. Ordinarily, they are simply atoms, which stand for themselves. For example: </p> <div class="example"> <pre class="example">:options '("foo" "bar" "baz") +</pre> +</div> <p>specifies that there are three known keys, namely <code>"foo"</code>, <code>"bar"</code> and <code>"baz"</code>, which will always be shown first. </p> <p>You may want to restrict the value type for specific keys, for example, the value associated with the <code>"bar"</code> key can only be an integer. You can specify this by using a list instead of an atom in the list. The first element will specify the key, like before, while the second element will specify the value type. For example: </p> <div class="example"> <pre class="example">:options '("foo" ("bar" integer) "baz") +</pre> +</div> <p>Finally, you may want to change how the key is presented. By default, the key is simply shown as a <code>const</code>, since the user cannot change the special keys specified with the <code>:options</code> keyword. However, you may want to use a more specialized type for presenting the key, like <code>function-item</code> if you know it is a symbol with a function binding. This is done by using a customization type specification instead of a symbol for the key. </p> <div class="example"> <pre class="example">:options '("foo" + ((function-item some-function) integer) + "baz") +</pre> +</div> <p>Many alists use lists with two elements, instead of cons cells. For example, </p> <div class="example"> <pre class="example">(defcustom list-alist + '(("foo" 1) ("bar" 2) ("baz" 3)) + "Each element is a list of the form (KEY VALUE).") +</pre> +</div> <p>instead of </p> <div class="example"> <pre class="example">(defcustom cons-alist + '(("foo" . 1) ("bar" . 2) ("baz" . 3)) + "Each element is a cons-cell (KEY . VALUE).") +</pre> +</div> <p>Because of the way lists are implemented on top of cons cells, you can treat <code>list-alist</code> in the example above as a cons cell alist, where the value type is a list with a single element containing the real value. </p> <div class="example"> <pre class="example">(defcustom list-alist '(("foo" 1) ("bar" 2) ("baz" 3)) + "Each element is a list of the form (KEY VALUE)." + :type '(alist :value-type (group integer))) +</pre> +</div> <p>The <code>group</code> widget is used here instead of <code>list</code> only because the formatting is better suited for the purpose. </p> <p>Similarly, you can have alists with more values associated with each key, using variations of this trick: </p> <div class="example"> <pre class="example">(defcustom person-data '(("brian" 50 t) + ("dorith" 55 nil) + ("ken" 52 t)) + "Alist of basic info about people. +Each element has the form (NAME AGE MALE-FLAG)." + :type '(alist :value-type (group integer boolean))) +</pre> +</div> </dd> <dt><code>(plist :key-type <var>key-type</var> :value-type <var>value-type</var>)</code></dt> <dd> +<p>This customization type is similar to <code>alist</code> (see above), except that (i) the information is stored as a property list, (see <a href="property-lists">Property Lists</a>), and (ii) <var>key-type</var>, if omitted, defaults to <code>symbol</code> rather than <code>sexp</code>. </p> </dd> <dt><code>(choice <var>alternative-types</var>…)</code></dt> <dd> +<p>The value must fit one of <var>alternative-types</var>. For example, <code>(choice integer string)</code> allows either an integer or a string. </p> <p>In the customization buffer, the user selects an alternative using a menu, and can then edit the value in the usual way for that alternative. </p> <p>Normally the strings in this menu are determined automatically from the choices; however, you can specify different strings for the menu by including the <code>:tag</code> 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, </p> <div class="example"> <pre class="example">(choice (integer :tag "Number of spaces") + (string :tag "Literal text")) +</pre> +</div> <p>so that the menu offers ‘<samp>Number of spaces</samp>’ and ‘<samp>Literal text</samp>’. </p> <p>In any alternative for which <code>nil</code> is not a valid value, other than a <code>const</code>, you should specify a valid default for that alternative using the <code>:value</code> keyword. See <a href="type-keywords">Type Keywords</a>. </p> <p>If some values are covered by more than one of the alternatives, customize will choose the first alternative that the value fits. This means you should always list the most specific types first, and the most general last. Here’s an example of proper usage: </p> <div class="example"> <pre class="example">(choice (const :tag "Off" nil) + symbol (sexp :tag "Other")) +</pre> +</div> <p>This way, the special value <code>nil</code> is not treated like other symbols, and symbols are not treated like other Lisp expressions. </p> </dd> <dt><code>(radio <var>element-types</var>…)</code></dt> <dd> +<p>This is similar to <code>choice</code>, 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 (<code>function-item</code> customization types). </p> </dd> <dt><code>(const <var>value</var>)</code></dt> <dd> +<p>The value must be <var>value</var>—nothing else is allowed. </p> <p>The main use of <code>const</code> is inside of <code>choice</code>. For example, <code>(choice integer (const nil))</code> allows either an integer or <code>nil</code>. </p> <p><code>:tag</code> is often used with <code>const</code>, inside of <code>choice</code>. For example, </p> <div class="example"> <pre class="example">(choice (const :tag "Yes" t) + (const :tag "No" nil) + (const :tag "Ask" foo)) +</pre> +</div> <p>describes a variable for which <code>t</code> means yes, <code>nil</code> means no, and <code>foo</code> means “ask”. </p> </dd> <dt><code>(other <var>value</var>)</code></dt> <dd> +<p>This alternative can match any Lisp value, but if the user chooses this alternative, that selects the value <var>value</var>. </p> <p>The main use of <code>other</code> is as the last element of <code>choice</code>. For example, </p> <div class="example"> <pre class="example">(choice (const :tag "Yes" t) + (const :tag "No" nil) + (other :tag "Ask" foo)) +</pre> +</div> <p>describes a variable for which <code>t</code> means yes, <code>nil</code> means no, and anything else means “ask”. If the user chooses ‘<samp>Ask</samp>’ from the menu of alternatives, that specifies the value <code>foo</code>; but any other value (not <code>t</code>, <code>nil</code> or <code>foo</code>) displays as ‘<samp>Ask</samp>’, just like <code>foo</code>. </p> </dd> <dt><code>(function-item <var>function</var>)</code></dt> <dd> +<p>Like <code>const</code>, 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 <code>:doc</code>, or <var>function</var>’s own documentation string. </p> </dd> <dt><code>(variable-item <var>variable</var>)</code></dt> <dd> +<p>Like <code>const</code>, 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 <code>:doc</code>, or <var>variable</var>’s own documentation string. </p> </dd> <dt><code>(set <var>types</var>…)</code></dt> <dd> +<p>The value must be a list, and each element of the list must match one of the <var>types</var> specified. </p> <p>This appears in the customization buffer as a checklist, so that each of <var>types</var> may have either one corresponding element or none. It is not possible to specify two different elements that match the same one of <var>types</var>. For example, <code>(set integer symbol)</code> 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 <code>integer</code> in a <code>set</code>. </p> <p>Most often, the <var>types</var> in a <code>set</code> are <code>const</code> types, as shown here: </p> <div class="example"> <pre class="example">(set (const :bold) (const :italic)) +</pre> +</div> <p>Sometimes they describe possible elements in an alist: </p> <div class="example"> <pre class="example">(set (cons :tag "Height" (const height) integer) + (cons :tag "Width" (const width) integer)) +</pre> +</div> <p>That lets the user specify a height value optionally and a width value optionally. </p> </dd> <dt><code>(repeat <var>element-type</var>)</code></dt> <dd> +<p>The value must be a list and each element of the list must fit the type <var>element-type</var>. This appears in the customization buffer as a list of elements, with ‘<samp>[INS]</samp>’ and ‘<samp>[DEL]</samp>’ buttons for adding more elements or removing elements. </p> </dd> <dt><code>(restricted-sexp :match-alternatives <var>criteria</var>)</code></dt> <dd> +<p>This is the most general composite type construct. The value may be any Lisp object that satisfies one of <var>criteria</var>. <var>criteria</var> should be a list, and each element should be one of these possibilities: </p> <ul> <li> A predicate—that is, a function of one argument that returns either <code>nil</code> or non-<code>nil</code> according to the argument. Using a predicate in the list says that objects for which the predicate returns non-<code>nil</code> are acceptable. </li> +<li> A quoted constant—that is, <code>'<var>object</var></code>. This sort of element in the list says that <var>object</var> itself is an acceptable value. </li> +</ul> <p>For example, </p> <div class="example"> <pre class="example">(restricted-sexp :match-alternatives + (integerp 't 'nil)) +</pre> +</div> <p>allows integers, <code>t</code> and <code>nil</code> as legitimate values. </p> <p>The customization buffer shows all legitimate values using their read syntax, and the user edits them textually. </p> +</dd> </dl> <p>Here is a table of the keywords you can use in keyword-value pairs in a composite type: </p> <dl compact> <dt><code>:tag <var>tag</var></code></dt> <dd> +<p>Use <var>tag</var> as the name of this alternative, for user communication purposes. This is useful for a type that appears inside of a <code>choice</code>. </p> </dd> <dt><code>:match-alternatives <var>criteria</var></code></dt> <dd> + <p>Use <var>criteria</var> to match possible values. This is used only in <code>restricted-sexp</code>. </p> </dd> <dt><code>:args <var>argument-list</var></code></dt> <dd> + <p>Use the elements of <var>argument-list</var> as the arguments of the type construct. For instance, <code>(const :args (foo))</code> is equivalent to <code>(const foo)</code>. You rarely need to write <code>:args</code> explicitly, because normally the arguments are recognized automatically as whatever follows the last keyword-value pair. </p> +</dd> </dl><div class="_attribution"> + <p class="_attribution-p"> + Copyright © 1990-1996, 1998-2022 Free Software Foundation, Inc. <br>Licensed under the GNU GPL license.<br> + <a href="https://www.gnu.org/software/emacs/manual/html_node/elisp/Composite-Types.html" class="_attribution-link">https://www.gnu.org/software/emacs/manual/html_node/elisp/Composite-Types.html</a> + </p> +</div> |
