Next: Keymaps and Minor Modes, Up: Minor Modes [Contents][Index]
メジャーモードにあるように、マイナーモードの記述にも慣習があります。以下で、その慣習について説明します。これらの慣習にしたがうには、マクロdefine-minor-mode
を使用するのがもっとも簡単な方法です。Defining Minor Modesを参照してください。
nil
、有効な場合は非nil
になるだろう。そのマイナーモードがバッファーローカルなら、この変数もバッファーローカルであること。
この変数は、モードラインにマイナーモードの名前を表示するために、minor-mode-alist
と結合して使用される。これは、minor-mode-map-alist
を通じて、そのマイナーモードのキーマップがアクティブかどうかも判定する(Controlling Active Mapsを参照)。個々のコマンドやフックも、この変数の値をチェックできる。
モードコマンドは、1つのオプション引数を受け入れるべきである。プレフィクス引数なしでinteractiveに呼び出された場合は、モードをトグルする(toggle: 切り替える。たとえば無効なら有効に、有効なら無効にする)こと。プレフィクス引数とともにinteractiveに呼び出された場合、その引数が正であればモードを有効に、それ以外は無効にすべきである。
モードコマンドが、Lispから(つまりからの非interactiveに)呼び出された場合は、引数が省略、またはnil
の場合はモードを有効にすべきである。引数がシンボルtoggle
の場合はモードをトグルし、それ以外の場合は、上述の数引数とともにinteractiveに呼び出されたときと同じ方法により、その引数を扱うべきである。
以下は、この挙動の実装方法を示す例である(define-minor-mode
マクロが生成するコードも、これに類似する)。
(interactive (list (or current-prefix-arg 'toggle)))
(let ((enable (if (eq arg 'toggle)
(not foo-mode) ; このモードのモード変数
(> (prefix-numeric-value arg) 0))))
(if enable
do-enable
do-disable))
この、やや複雑な挙動の理由は、ユーザーが簡単かつinteractiveにマイナーモードをトグルでき、以下のようにモードフック内で簡単にマイナーモードを有効にできるからである:
(add-hook 'text-mode-hook 'foo-mode)
foo-mode
モードコマンドは、引数なしでLispから呼び出されたときは、無条件にそのマイナーモードを有効にするので、これはfoo-mode
がすでに有効でもそうでなくても正しく振る舞う。モードフック内でマイナーモードを無効にする場合は、少々醜くなる:
(add-hook 'text-mode-hook (lambda () (foo-mode -1)))
しかし、これは頻繁には行われない。
minor-mode-alist
に追加する(Definition of minor-mode-alistを参照)。この要素は以下の形式のリストであること:
(mode-variable string)
ここで、mode-variableはマイナーモードの有効化を制御する変数であり、stringはモードラインに標示するための、スペースで始まる短い文字列である。一度に複数モードの文字列がスペースを占めるので、これらの文字列は短くなければならない。
minor-mode-alist
に要素を追加する際は、重複を避けるために、既存要素のチェックにassq
を使用すること。たとえば:
(unless (assq 'leif-mode minor-mode-alist) (push '(leif-mode " Leif") minor-mode-alist))
または、以下のようにadd-to-list
(List Variablesを参照)を使用すること:
(add-to-list 'minor-mode-alist '(leif-mode " Leif"))
これらに加えて、メジャーモードにたいする慣習のいくつかは、マイナーモードにたいしても同様に適用されます。それらの慣習はグローバルシンボルの名前、初期化関数の最後でのフックの使用、キーマップおよびその他のテーブルの使用です。
マイナーモードは、可能ならばCustom(Customizationを参照)を通じての有効化および無効化をサポートするべきです。これを行うには、モード変数はは通常は:type
'boolean
とともにdefcustom
で定義されるべきです。その変数をセットするだけではモードの有効化に不足なら、モードコマンドを呼び出すことによりモードを有効にする:set
メソッドも指定するべきです。そして、その変数のドキュメント文字列にCustomを通じて変数をセットしなければ効果がないことを注記してください。さらに、その定義をautoload
cookie(autoload cookieを参照)でマークして、その変数のカスタマイズによりモードを定義するライブラリーがロードされるように:require
を指定します。たとえば:
;;;###autoload (defcustom msb-mode nil "msb-modeをトグルする この変数を直接セットしても効果がない \\[customize]か関数`msb-mode'を使用すること" :set 'custom-set-minor-mode :initialize 'custom-initialize-default :version "20.4" :type 'boolean :group 'msb :require 'msb)