GNU Emacs 32.0.50 (9008bf64c3) のマニュアルを PLaMo 翻訳で機械翻訳したものです。誤訳を含むことがあります。原文: https://www.gnu.org/software/emacs/manual/html_node/elisp/Derived-Modes.html ・ emacs-doc.conao3.com

24.2.4 派生モードの定義

新しいメジャーモードを定義する推奨方法は、define-derived-mode を用いて既存のモードから派生させることです。密接に関連するモードがない場合は、text-mode、special-mode、または prog-mode のいずれかを継承してください。基本メジャーモードを参照してください。これらがいずれも適さない場合は、fundamental-mode を継承できます(メジャーモードを参照してください)。

マクロ: define-derived-mode variant parent name docstring keyword-args… body…

このマクロは、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 キーワードを使用してこれを上書きした場合は除きます(後述)。
  • The new mode has its own mode hook, 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 が自動的に行います。

関数: derived-mode-p modes

この関数は、現在のメジャーモードが modes のシンボルリストに指定されたメジャーモードのいずれかから派生している場合、non-nil を返します。modes にはリストの代わりに、単一のモードシンボルを指定することも可能です。

さらに、modes を個別の引数として渡すという非推奨の呼び出し規約も、引き続きサポートしています。

現在のメジャーモードの親モードを調べる際、この関数はdefine-derived-modeで設定された現在のモードの親に加え、後述するderived-mode-add-parentsで設定された追加の親も考慮します。

関数: provided-mode-derived-p mode modes

この関数は、mode が modes のシンボルリストに指定された主要モードのいずれかから導出された場合に、non-nil を返します。derived-mode-p と同様に、modes も単一のシンボルであることができ、また本関数は、modes を個別のシンボル引数として渡すという非推奨の呼び出し規約にも対応しています。

modeの親モードを検討する際、この関数はdefine-derived-modeによって設定されたmodeの親に加え、後述するderived-mode-add-parentsによって設定された追加の親も考慮します。

メジャーモードの系譜グラフには、以下の低レベル関数を用いてアクセスおよび変更が可能です。

関数: derived-mode-set-parent mode parent

この関数は、mode が parent を継承することを宣言します。これは、mode を定義した後に define-derived-mode が呼び出し、parent を再利用して mode を定義したという事実を記録するための関数です。

関数: derived-mode-add-parents mode extra-parents

この関数を使用すると、mode の定義時に用いた親に加えて、さらに追加の親を登録することが可能です。これは、mode と extra-parents 内のモードとの類似性が高く、ディレクトリローカル変数やその他のモード固有の設定を適用するといった目的で、mode をそれらのモードの子として扱うことが妥当な場合に利用できます。追加の親モードは、extra-parents にシンボルのリストとして指定します。これらの追加の親モードは、derived-mode-p および provided-mode-derived-p によって mode の親の一つとして扱われます。

関数: derived-mode-all-parents mode

この関数は、mode の祖先にあるすべてのモードの一覧を、最も具体的なものから最も一般的なものに順に並べ、mode 自身を先頭として返します。これには、derived-mode-add-parents を呼び出すことで追加された追加の親モード(もしあれば)も含まれます。