Emacs は原則としてモード毎に独自のキーマップを持っている。これには、ど
のキーを押した時にどのコマンドが実行されるかとか、プレフィクスキーはど
れか、ということが書かれている。(正確にはマウスのクリックなども含めた
イベントにコマンドループで実行できる定義を対応させる表と言うべき。具体的
には (keymap 「なんとか」)
というリストなのだが、「なんとか」
の部分が何かは後で述べる。)
普通は nantoka-mode には nantoka-mode-map という名前のキー マップを用意する。
キーマップを作る方法は基本的には次の二通りある。
最初のは殆どのキーを変更するような時に使い、二番目のは少数のキーのみを (global-map から)変更するような場合に使う。
具体的には次のような感じで使ったりする。これは、my-mode-map というマップを作り、n, p, RTN, SPC などのキーに対するコマンドを変更している。
(defvar my-mode-map (let ((km (make-keymap))) (define-key km [backspace] 'scroll-down) (define-key km "n" 'next-line) (define-key km "p" 'previous-line) (define-key km "\r" 'my-select) (define-key km " " 'scroll-up) (define-key km "?" 'my-help) (define-key km "h" 'my-brief-help) (define-key km "q" 'my-quit) km))
こうしておいて、前節のように
(defun my-mode () "My mode の説明" (interactive) (kill-all-local-variables) (use-local-map my-mode-map) (setq mode-name "My") (run-hooks 'my-mode-hook))
でモードを定義すれば、my-mode では、n や p や RTN ("\r" は改 行を表す) にはその後に書かれているコマンドが定義される。(それぞれのコ マンドの定義は別に書く必要があるが。)
簡単なモードであれば、以上の説明で十分だろう。これ以降は、もっと凝った ことをしたい人向けなので、そうでない人は飛ばしてしまって構わない。
上では定義しない残りのキーは無効になるかというとそうではなく、グローバ ルなキーマップ (global-map というマップの定義) を受け継ぐ ようなものになる。その辺りの事情はmake-keymap
と
make-sparse-keymap
とでちょっと違うので、
次で説明する。
これは、次のようなシンボルとベクタのリストを返す関数である。
(keymap [nil nil ... nil])
nil は全部で 256 個ある。define-key
で、
ここにいろんな定義をぶちこむわけである。沢山のキーをコンパクトに記述す
るのにむいた形式で、このようなキーマップは full keymap と呼ばれる。
nil になっている部分のイベントには global-map の
定義が優先して実行される。
これは、単に (keymap)
というリストを返す関数である。これ
に、define-key
でキーを定義すると、
(keymap (TYPE1 . BINDING1) (TYPE2 . BINDING2) ...)
のような感じのキーマップに変化する。この場合も定義されていない残りのキー では global-map に記述されたコマンドが実行されることになる。
ゲームなんかだと、特定のキー以外は無効にしたい場合が多いだろう。こうい
う場合は、suppress-keymap
という関数を使
う。具体的には次のような感じ。
こうすると、普通の a, b,... などの自分自身を挿入するキーが無定義になる。 この場合でも数字や - は前置引数のために有効な ままだが、二番目の引数に nil 以外を指定すると、そのキーも無定義になる。