単純な型のいずれも適切でない場合は、他の型や指定されたデータから新しい型を構築する複合型を使用できます。指定された型やデータは、複合型の引数と呼ばれます。複合型は通常、次のような形式になります。
(constructor arguments...)
また、引数の前に次のようにキーワードと値のペアを追加することもできます。
(constructor {keyword value}... arguments...)
以下に、コンストラクタと、それらを用いて複合型を記述する方法をまとめた表を示します。
(cons car-type cdr-type)値はコンスセルである必要があり、そのCARはcar-typeに、CDRはcdr-typeにそれぞれ適合しなければなりません。例えば、(cons
string symbol)は("foo"
. foo)などの値に一致するカスタマイズタイプです。
カスタマイズバッファでは、CAR と CDR が、それぞれ指定されたタイプに応じて個別に表示・編集されます。
(list element-types…)値は、指定された element-types とちょうど同じ数の要素を持つリストである必要があり、各要素は対応する element-type に適合しなければなりません。
例えば、(list integer string function)
は3つの要素からなるリストを記述しており、1番目の要素は整数、2番目は文字列、3番目は関数である必要があります。
カスタマイズバッファでは、各要素は指定されたタイプに応じて、個別に表示・編集されます。
(group element-types…)これは、カスタムバッファ内のテキストの書式設定を除けば、listと同様に動作します。listは各要素の値にそのタグを付与しますが、groupは付与しません。
(vector element-types…)listと同様ですが、値はリストではなくベクトルである必要があります。要素の扱いはlistと同じです。
(alist :key-type key-type
:value-type value-type)値は cons-cell のリストである必要があり、各セルの CAR はカスタマイズタイプ key-type のキーを、同じセルの CDR はカスタマイズタイプ value-type の値をそれぞれ表します。ユーザーはキー/値のペアを追加・削除できるほか、各ペアのキーと値の両方を編集できます。
省略した場合、key-type と value-type
はデフォルトで sexp となります。
ユーザーは指定したキータイプに一致する任意のキーを追加できますが、:options
で指定することで一部のキーを優先させることも可能です(カスタマイズ変数の定義を参照)。指定されたキーは常にカスタマイズバッファに(適切な値とともに)表示され、チェックボックスによってそのキー/値ペアをalistに含めるか、除外するか、あるいは無効にするかを選択できます。ユーザーは
:options キーワード引数で指定されたキーを編集することはできません。
:options キーワードに渡す引数は、alist
内の妥当なキーに関する仕様のリストである必要があります。通常、これらは単にアトムであり、それ自体で機能します。例えば:
:options '("foo" "bar" "baz")
既知のキーが "foo"、"bar"、"baz" の3つあり、これらが常に最初に表示されることを規定しています。
特定のキーに対して値の型を制限したい場合があります。例えば、"bar"
キーに関連付けられる値は整数のみとする、といったケースです。これは、リスト内でアトムの代わりにリストを使用することで指定できます。1番目の要素で前述と同様にキーを指定し、2番目の要素で値の型を指定します。例えば:
:options '("foo" ("bar" integer) "baz")
最後に、キーの表示方法を変更したい場合もあるでしょう。デフォルトでは、:options
キーワードで指定された特殊キーをユーザーが変更できないため、キーは単に const
として表示されます。しかし、関数バインディングを持つシンボルであることがわかっている場合は、function-item
のようなより特化した型をキーの表示に使用したいこともあるでしょう。これは、キーにシンボルではなくカスタマイズ型の指定を用いることで実現します。
:options '("foo"
((function-item some-function) integer)
"baz")
多くのalist利用者は、consセルの代わりに2つの要素を持つリストを使用しています。例えば、
(defcustom list-alist
'(("foo" 1) ("bar" 2) ("baz" 3))
"Each element is a list of the form (KEY VALUE).")
の代わりに
(defcustom cons-alist
'(("foo" . 1) ("bar" . 2) ("baz" . 3))
"Each element is a cons-cell (KEY . VALUE).")
リストがコンスセルの上に実装されているため、上記の例における list-alist
をコンスセルのアリスタとして扱うことができ、その値の型は、実際の値を含む単一の要素からなるリストとなります。
(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)))
ここでlistではなくgroupウィジェットを使用しているのは、単に書式の方が目的に適しているためです。
同様に、この手法を応用することで、各キーにより多くの値を関連付けたリストを作成することも可能です:
(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)))
(plist :key-type key-type
:value-type value-type)このカスタマイズタイプは alist(上記参照)に似ていますが、(i)
情報がプロパティリストとして格納される点(プロパティリストを参照)、および (ii) key-type が省略された場合、sexp ではなく
symbol が既定値となる点が異なります。
(choice alternative-types…)値は alternative-types のいずれかに一致する必要があります。例えば、(choice integer string) では整数または文字列のいずれも許可されます。
カスタマイズバッファでは、ユーザーはメニューから代替案を選択し、その後、その代替案の値を通常の方法で編集できます。
通常、このメニューの文字列は選択肢に基づいて自動的に決定されますが、alternatives に :tag
キーワードを含めることで、メニューに別の文字列を指定することも可能です。例えば、整数がスペースの数を表し、文字列がそのまま使用されるテキストである場合、カスタマイズタイプを次のように記述できます。
(choice (integer :tag "Number of spaces")
(string :tag "Literal text"))
メニューに‘Number of spaces’と‘Literal text’が表示されるように。
nil が有効な値とならない代替案(const
を除く)については、:value
キーワードを使用して、その代替案に有効なデフォルト値を指定してください。型キーワードを参照してください。
複数の代替値に該当する値がある場合、customizeはその値に適合する最初の代替値を選択します。つまり、常に最も具体的な型を最初に、最も一般的な型を最後に記載するようにしてください。以下に正しい使用例を示します:
(choice (const :tag "Off" nil)
symbol (sexp :tag "Other"))
これにより、特殊値 nil が他の記号と同様に扱われず、また記号が他の Lisp
式と同様に扱われることもありません。
(radio element-types…)
¶これは choice
と同様ですが、選択肢がメニューではなくラジオボタンで表示される点が異なります。これにより、必要に応じて選択肢のドキュメントを表示できるという利点があるため、定数関数(function-item カスタマイズタイプ)間の選択には適していることが多いです。
(const value)値は value である必要があります—それ以外の値は認められません。
constの主な用途はchoice内です。例えば、(choice integer (const
nil))では整数またはnilのいずれかが指定可能です。
:tagは、choice内でconstと共に使われることが多いです。例えば、
(choice (const :tag "Yes" t)
(const :tag "No" nil)
(const :tag "Ask" foo))
tが「はい」、nilが「いいえ」、fooが「尋ねる」を意味する変数を記述します。
(other value)この代替案は任意のLisp値に一致しますが、ユーザーがこの代替案を選択した場合、値 value が選択されます。
otherの主な用途は、choiceの最後の要素として用いることです。例えば、
(choice (const :tag "Yes" t)
(const :tag "No" nil)
(other :tag "Ask" foo))
tが「はい」、nilが「いいえ」、それ以外のすべてが「ask」を意味する変数について説明します。ユーザーが選択肢メニューから「Ask」を選択した場合、値fooが指定されます。それ以外の値(t、nil、foo以外)は、fooと同様に「Ask」と表示されます。
(function-item function)constと同様ですが、関数である値に対して使用します。これにより、関数名に加えてドキュメント文字列も表示されます。ドキュメント文字列は、:docで指定したもの、またはfunction自身のドキュメント文字列のいずれかとなります。
(variable-item variable)constと同様ですが、変数名の値に対して使用します。これにより、変数名とともにドキュメント文字列も表示されます。ドキュメント文字列は、:docで指定したもの、またはvariable自身のドキュメント文字列のいずれかとなります。
(set types…)値はリストである必要があり、リストの各要素は指定された types のいずれかと一致しなければなりません。
これはカスタマイズバッファにチェックリストとして表示されるため、types
のそれぞれに対して、対応する要素を1つ持つか、あるいは全く持たないかのいずれかとなります。types
の同一の要素に一致する2つの異なる要素を指定することはできません。例えば、(set integer
symbol)
ではリスト内に整数1つおよび/または記号1つを許可しますが、複数の整数や複数の記号を許可することはありません。その結果、set において integer
のような非特定の型を使用することは稀です。
多くの場合、set 内の types
は、ここに示すように const 型となります。
(set (const :bold) (const :italic))
場合によっては、alistに含まれる可能性のある要素を記述することがあります:
(set (cons :tag "Height" (const height) integer)
(cons :tag "Width" (const width) integer))
これにより、ユーザーは高さの値を任意で、幅の値を任意で指定できるようになります。
(repeat element-type)値はリストである必要があり、リストの各要素は型 element-type に適合している必要があります。これはカスタマイズバッファに要素のリストとして表示され、要素の追加や削除を行うための ‘[INS]’ および ‘[DEL]’ ボタンが用意されています。
(restricted-sexp :match-alternatives criteria)
¶これは最も汎用的な複合型構文です。値は、criteriaのいずれかを満たす任意のLispオブジェクトとなります。criteriaはリストである必要があり、各要素は以下のいずれかである必要があります:
nil または non-nil のいずれかを返す1引数関数。リスト内で述語を用いることは、その述語が non-nil を返すオブジェクトが許容されることを意味する。
'object。リストにおけるこの種の要素は、object
自体が許容される値であることを示しています。
例えば、
(restricted-sexp :match-alternatives
(integerp 't 'nil))
整数、t、およびnilを有効な値として許容します。
カスタマイズバッファには、すべての有効な値が読み取り用構文で表示され、ユーザーはそれらをテキスト形式で編集します。
複合型のキーワード・値ペアで使用できるキーワードの一覧を以下に示します。
:tag tagユーザー向けの案内用として、この代替名に tag を使用してください。これは、choice 内に表示される型に有用です。
:match-alternatives criteria
¶取り得る値に一致させるには criteria を使用します。これは restricted-sexp でのみ使用されます。
:args argument-list
¶argument-list の要素を型構成の引数として使用します。例えば、(const :args (foo)) は (const
foo) と同等です。通常、引数は最後のキーワードと値のペアに続くものとして自動的に認識されるため、:args と明示的に記述する必要はほとんどありません。