新しいメジャーモードを定義する推奨方法は、define-derived-mode
を用いて既存のモードから派生させることです。密接に関連するモードがない場合は、text-mode、special-mode、または
prog-mode のいずれかを継承してください。基本メジャーモードを参照してください。これらがいずれも適さない場合は、fundamental-mode を継承できます(メジャーモードを参照してください)。
このマクロは、variant をメジャーモードコマンドとして定義し、モード名の文字列形式として name を使用します。variant と parent はクォートなしのシンボルとする必要があります。
新しいコマンド variant は、関数 parent を呼び出し、その後、その親モードの特定の側面を上書きするように定義されています:
variant-map
という名前の独自のスパースキーマップがあります。variant-map が既に設定されており、かつ既に親を持っている場合を除き、define-derived-mode は親モードのキーマップを新しいマップの親とします。
variant-syntax-table に保持されています。ただし、:syntax-table キーワードを使用してこれを上書きした場合は除きます(後述)。define-derived-mode は、親モードの構文テーブルを variant-syntax-table
の親にします。ただし、後者が既に設定されており、かつ標準の構文テーブルとは異なる親を持っている場合は除きます。
variant-abbrev-table に格納されています。ただし、:abbrev-table キーワードを使用してこれを上書きした場合は除きます(後述)。
variant-hook. It runs this hook, after running the
hooks of its ancestor modes, with run-mode-hooks,
as the last thing it does, apart from running any :after-hook form it may have. See Mode Hooks.
さらに、body を用いて parent の他の側面をどのように上書きするかを指定できます。コマンド variant は、通常のオーバーライドをすべて適用した後、モードフックを実行する直前に body 内のフォームを評価します。
parent が nil mode-class 以外のシンボルプロパティを持つ場合、define-derived-mode は variant の
mode-class プロパティに同じ値を設定します。これにより、例えば parent が特殊モードであれば、variant
も特殊モードになることが保証されます(メジャーモードの規約 を参照)。
また、parent に nil
を指定することもできます。これにより、新しいモードに親がなくなります。すると define-derived-mode は前述の通りに動作しますが、当然ながら parent に関連するすべてのアクションは省略されます。逆に、後述する derived-mode-set-parent や derived-mode-add-parents
を使用して、新しいモードの祖先を明示的に設定することも可能です。
引数 docstring は、新しいモードのドキュメント文字列を指定します。define-derived-mode
は、そのドキュメント文字列の末尾に、モードのフックに関する一般的な情報と、続いてモードのキーマップを追加します。docstring を省略した場合、define-derived-mode がドキュメント文字列を生成します。
keyword-args はキーワードと値のペアです。:after-hook 以外の値は評価されます。現在、以下のキーワードがサポートされています:
:syntax-tableこれを使用して、新しいモード用の構文テーブルを明示的に指定できます。nil
の値を指定した場合、新しいモードは parent と同じ構文テーブルを使用し、parent が nil
の場合は標準の構文テーブルを使用します。(なお、これは非キーワード引数で用いられる「nil
の値は引数を指定しないのと同等である」という慣例に従わない点に注意してください。)
:abbrev-tableこれを使用して、新しいモード用の略語テーブルを明示的に指定できます。nil
の値を指定した場合、新しいモードは parent と同じ略語テーブルを使用し、parent が nil の場合は fundamental-mode-abbrev-table
と同じテーブルを使用します。(繰り返しになりますが、nil
の値は、このキーワードを指定しないことと同等ではありません。)
:interactiveモードはデフォルトでインタラクティブなコマンドです。nil
の値を指定すると、ここで定義されるモードはインタラクティブではなくなります。これは、ユーザーが手動で起動することを想定しておらず、特定の形式のバッファ内でのみ使用されるべきモードに有用です。
:groupこれを指定した場合、値はこのモード用のカスタマイズグループとする必要があります。(すべてのメジャーモードに設定されているわけではありません。)コマンド
customize-mode がこれを利用します。define-derived-mode は、指定したカスタマイズグループを自動的に定義しません。
:after-hookこのオプションキーワードは、モードフックが実行された後、モード関数の最終処理として評価する単一のLispフォームを指定します。クォートで囲んではいけません。このフォームはモード関数の終了後に評価される可能性があるため、モード関数のローカル状態のいかなる要素にもアクセスしてはなりません。:after-hook
フォームは、ユーザーの設定に依存するモードの各種設定を行う際に有用であり、こうした設定はモードフック内で変更されている場合があります。
以下に架空の例を挙げます。
(defvar-keymap hypertext-mode-map "<down-mouse-3>" #'do-hyper-link) (define-derived-mode hypertext-mode text-mode "Hypertext" "Major mode for hypertext." (setq-local case-fold-search nil))
定義に interactive の指定を記述しないでください。define-derived-mode が自動的に行います。
この関数は、現在のメジャーモードが modes
のシンボルリストに指定されたメジャーモードのいずれかから派生している場合、non-nil
を返します。modes にはリストの代わりに、単一のモードシンボルを指定することも可能です。
さらに、modes を個別の引数として渡すという非推奨の呼び出し規約も、引き続きサポートしています。
現在のメジャーモードの親モードを調べる際、この関数はdefine-derived-modeで設定された現在のモードの親に加え、後述するderived-mode-add-parentsで設定された追加の親も考慮します。
この関数は、mode が modes
のシンボルリストに指定された主要モードのいずれかから導出された場合に、non-nil
を返します。derived-mode-p と同様に、modes も単一のシンボルであることができ、また本関数は、modes
を個別のシンボル引数として渡すという非推奨の呼び出し規約にも対応しています。
modeの親モードを検討する際、この関数はdefine-derived-modeによって設定されたmodeの親に加え、後述するderived-mode-add-parentsによって設定された追加の親も考慮します。
メジャーモードの系譜グラフには、以下の低レベル関数を用いてアクセスおよび変更が可能です。
この関数は、mode が parent
を継承することを宣言します。これは、mode を定義した後に define-derived-mode が呼び出し、parent を再利用して mode
を定義したという事実を記録するための関数です。
この関数を使用すると、mode
の定義時に用いた親に加えて、さらに追加の親を登録することが可能です。これは、mode と extra-parents
内のモードとの類似性が高く、ディレクトリローカル変数やその他のモード固有の設定を適用するといった目的で、mode をそれらのモードの子として扱うことが妥当な場合に利用できます。追加の親モードは、extra-parents にシンボルのリストとして指定します。これらの追加の親モードは、derived-mode-p および provided-mode-derived-p によって mode
の親の一つとして扱われます。
この関数は、mode
の祖先にあるすべてのモードの一覧を、最も具体的なものから最も一般的なものに順に並べ、mode
自身を先頭として返します。これには、derived-mode-add-parents
を呼び出すことで追加された追加の親モード(もしあれば)も含まれます。