前のセクションでは、defcustom
にたいして型の詳細な仕様を作成する方法を説明しました。そのような型仕様に名前を与えたい場合があるかもしれません。理解しやすいケースとしては、多くのユーザーオプションに同じ型を使用する場合などです。各オプションにたいして仕様を繰り返すよりその型に名前を与えて、defcustom
それぞれにその名前を使用することができます。他にもユーザーオプションの値が再帰的なデータ構造のケースがあります。あるデータ型がそれ自身を参照できるようにするためには、それが名前をもつ必要があります。
カスタマイゼーション型はウィジェットとして実装されているめ、新しいカスタマイゼーション型を定義するには、新たにウィジェット型を定義します。ここではウィジェットインターフェイスの詳細は説明しません。Introduction in The Emacs Widget Libraryを参照してください。かわりにシンプルな例を用いて、カスタマイゼーション型を新たに定義するために必要な最小限の機能について説明します。
(define-widget 'binary-tree-of-string 'lazy "A binary tree made of cons-cells and strings." :offset 4 :tag "Node" :type '(choice (string :tag "Leaf" :value "") (cons :tag "Interior" :value ("" . "") binary-tree-of-string binary-tree-of-string))) (defcustom foo-bar "" "Sample variable holding a binary tree of strings." :type 'binary-tree-of-string)
新しいウィジェットを定義するための関数はdefine-widget
と呼ばれます。1つ目の引数は新たなウィジェット型にしたいシンボルです。2つ目の引数は既存のウィジェットを表すシンボルで、新しいウィジェットではこの既存のウィジェットと異なる部分を定義することになります。新たなカスタマイゼーション型を定義する目的にたいしてはlazy
ウィジェットが最適です。なぜならこれはdefcustom
にたいするキーワード引数と同じ構文と名前でキーワード引数:type
を受け取るからです。3つ目の引数は新しいウィジェットにたいするドキュメント文字列です。この文字列はM-x
widget-browse RET binary-tree-of-string RETコマンドで参照することができます。
これらの必須の引数の後にキーワード引数が続きます。もっとも重要なのは:type
で、これはこのウィジェットにマッチさせたいデータ型を表します。上記の例ではbinary-tree-of-string
は文字列、またはcarとcdrがbinary-tree-of-string
であるようなコンスセルです。この定義中でのウィジェット型への参照に注意してください。:tag
属性はユーザーインターフェイスでウィジェット名となる文字列、:offset
引数はカスタマイゼーションバッファーでのツリー構造の外観で,子ノードと関連する親ノードの間に4つのスペースを確保します。
defcustom
は通常のカスタマイゼーション型に使用される方法で新しいウィジェットを表示します。
lazy
という名前の由来は、他のウィジェットではそれらがバッファーでインスタンス化されるとき、他の合成されたウィジェットが下位のウィジェットを内部形式に変換するからです。この変換は再帰的なので、下位のウィジェットはそれら自身の下位ウィジェットへと変換されます。データ構造自体が再帰的なら、その変換は無限再帰(infinite
recursion)となります。lazy
ウィジェットは、:type
引数を必要なときだけ変換することによってこの再帰を防ぎます。