メジャーモードにたいするすべてのコードはさまざまなコーディング規約にしたがうべきであり、それらの規約にはローカルキーマップおよび構文テーブルの初期化、関数名や変数名、フックにたいする規約が含まれます。
define-derived-mode
マクロを使用すれば、これらの規約を自動的に配慮します。派生モードの定義を参照してください。FundamentalモードはEmacsのデフォルト状態を表すモードなので、これらの規約が該当しないことに注意してください。
以下の規約リストはほんの一部です。一般的にすべてのメジャーモードはEmacs全体が首尾一貫するよう、他のEmacsメジャーモードとの一貫性を目指すべきです。ここでこの問題を洗い出すすべての想定される要点をリストするのは不可能です。自身の開発するメジャーモードが通常の規約を逸脱する領域を示すような場合には、Emacs開発者は互換性を保つようにしてください。
そのユーザー自身のキーバインディングに自動的に適合してヘルプが表示されるように、ドキュメント文字列に特別なドキュメントサブストリング‘\[command]’、‘\{keymap}’、‘\<keymap>’を含めるとよいかもしれない。ドキュメント内でのキーバインディングの置き換えを参照のこと。
kill-all-local-variables
を呼び出すことによって開始すること。これはノーマルフックchange-major-mode-hook
を実行してから、前のメジャーモードで効力のあったバッファーローカル変数を解放する。バッファーローカルなバインディングの作成と削除を参照のこと。
major-mode
にメジャーモードコマンドのシンボルをセットすること。これはdescribe-mode
がプリントするドキュメントを探す手掛かりとなる。
mode-name
にそのモードの“愛称(pretty
name)”をセットすること(これは通常は文字列だが他の利用可能な形式についてはモードラインのデータ構造を参照)。このモード名はモードラインに表示される。
indent-line-function
に適切な関数をセットするとともに、インデント用のその他の変数をカスタマイズするべきだろう。コードの自動インデントを参照のこと。
use-local-map
を呼び出すこと。詳細はアクティブなキーマップを参照されたい。
このキーマップはmodename-mode-map
という名前のグローバル変数に永続的に格納されること。そのモードを定義するライブラリーは、通常はこの変数をセットする。
モード用のキーマップ変数をセットアップするコードの記述する方法に関するアドバイスは堅牢な変数定義のためのヒントを参照されたい。
メジャーモードはM-n、M-p、M-sなどのキーもリバインドできる。M-nとM-pにたいするバインディングは、通常は 前方か後方への移動を意味するような類のものであるべきだが、これが必ずしもカーソル移動を意味する必要はない。
そのモードにより適した方法でテキストに同じ処理を行うコマンドを提供する場合には、メジャーモードが標準的なキーシーケンスをリバインドするのは正当性がある。たとえばプログラム言語を編集するためのメジャーモードは、その言語にとって関数の先頭に移動するために、より良く機能する方法でC-M-aを再定義するかもしれない。メジャーモードにニーズに応じてC-M-aを構成するための推奨方法は、そのモード固有の関数を呼び出すためにbeginning-of-defun-function
をセットすること(バランスのとれたカッコを越えた移動を参照)。
ある標準的なキーシーケンスの標準的な意味がそのモードではほとんど役に立たないような場合にも、メジャーモードが標準的なキーシーケンスをリバインドする正当性がある。たとえばM-rの標準的な意味はミニバッファーではほとんど使用されないので、このキーシーケンスをリバインドする。テキストの自己挿入を許さないDiredやRmailのようなメジャーモードがアルファベット文字や、その他のプリント文字を特別なコマンドに再定義することには正当性がある。
modename-mode-syntax-table
という名前の変数にそれを格納すること。構文テーブルを参照されたい。
modename-mode-abbrev-table
という名前の変数にそれを格納すること。メジャーモードコマンドが自身で何らかのabbrevを定義する場合には、define-abbrev
のsystem-flag引数にt
を渡すこと。abbrevの定義を参照されたい。
font-lock-defaults
にバッファーローカルな値をセットすることによって、Font
Lockモードにたいしてハイライトする方法を指定すること(Font Lockモードを参照)。
context-menu-mode
(Menu Mouse Clicks in The Emacs
Manualを参照)をアクティブにした際に使用されるモード固有のコンテキストメニューの追加を検討すること。これを達成するにはバッファー内でmouse-3がクリックされた位置に応じて1つ以上のメニューを構築するモード固有関数の定義して、context-menu-functions
のバッファーローカル値にその関数を追加すればよい。
imenu-generic-expression
、imenu-prev-index-position-function
とimenu-extract-index-name-function
の2つの変数、または変数imenu-create-index-function
にバッファーローカルな値をセットすることによってImenuがバッファー内の定義やセクションを探す方法を指定すること(Imenuを参照)。
outline-regexp
とoutline-search-function
、さらに変数outline-level
(Outlineマイナーモードを参照)にバッファーローカル値をセットアップして、どのようにしてOutlineマイナーモードがヘッダー行を見つけられるかを指定する必要がある。
eldoc-documentation-functions
に1つ以上のバッファーローカルエントリーを追加することにより、ポイント位置にあるものにたいして異なるタイプのドキュメントを取得する方法をElDocモードに指示できる。
completion-at-point-functions
に1つ以上のバッファーローカルエントリーを追加することにより、さまざまなキーワードの補完方法を指定できる。通常バッファーでの補完を参照のこと。
make-variable-buffer-local
ではなくメジャーモードコマンド内でmake-local-variable
を使用すること。関数make-variable-buffer-local
はそれ以降にカスタマイズ変数をセットするすべてのバッファーにたいしてその変数をローカルにして、そのモードを使用しないバッファーにたいしても影響があるだろう。そのようなグローバルな効果はモードにとって好ましくない。バッファーローカル変数を参照のこと。
稀な例外としてLispパッケージ内でmake-variable-buffer-local
を使用する唯一の正当な方法は、そのパッケージ内でのみ使用される変数にたいして使用をする場合である。他のパッケージにより使用される変数にたいしてこの関数を使用すると競合が発生するだろう。
modename-mode-hook
という名前のノーマルなモードフック(mode
hook)をもつこと。メジャーモードコマンドが一番最後にrun-mode-hooks
を呼び出すこと。これはノーマルフックchange-major-mode-after-body-hook
、モードフック、(バッファーがファイルをvisitしていれば)関数hack-local-variables
、その後にノーマルフックafter-change-major-mode-hook
を実行する。モードフックを参照のこと。
define-derived-mode
マクロの使用だが必須ではない。そのようなモードはdelay-mode-hooks
フォーム内で親のモードコマンドを呼び出すこと(define-derived-mode
は自動的にこれを行う)。派生モードの定義とモードフックを参照されたい。
change-major-mode-hook
にたいしてバッファーローカル値をセットアップできる(バッファーローカルなバインディングの作成と削除を参照)。
mode-class
という名前のプロパティに値special
をputすること:
(put 'funny-mode 'mode-class 'special)
これはEmacsにたいしてカレントバッファーがFunnyモードのときに新たなバッファーを作成したとき、たとえmajor-mode
のデフォルト値がnil
であってもそのバッファーをFunnyモードにしないよう指示する。デフォルトではmajor-mode
にたいする値nil
は新たなバッファー作成時にカレントバッファーのメジャーモードを使用することを意味するが(Emacsがメジャーモードを選択する方法を参照)、special
なモードにたいしてはかわりにFundamentalモードが使用される。Dired、Rmail、Buffer
Listのようなモードはこの機能を使用する。
関数view-buffer
はmode-classがspecialであるようなバッファーではViewモードを有効にしない。そのようなモードは通常は自身でViewに相当するバインディングを提供するからである。
define-derived-mode
マクロは親モードがspecialなら、自動的に派生モードをspecialにマークする。親モードでspecialモードが有用ならそれを継承したモードでも有用だろう。基本的なメジャーモードを参照のこと。
auto-mode-alist
に要素を追加する。autoload用にモードコマンドを定義する場合には、autoload
を呼び出すのと同じファイル内にその要素を追加すること。モードコマンドにたいしてautoload
cookieを使用する場合はに、その要素を追加するフォームにたいしてもautoload cookieを使用できる(autoload cookieを参照)。モードコマンドをautoloadしない場合には、モード定義を含むファイル内で要素を追加すれば十分である。
defvar
かdefcustom
を使用する(グローバル変数の定義を参照)。