以下はキーマップを作成する関数です。
この関数はエントリーをもたない新たなsparseキーマップを作成してそれをリターンする(sparseキーマップはあなたが通常望む類のキーマップのこと)。make-keymap
と異なり新たなキーマップは文字テーブルを含まず、何のイベントもバインドしない。
(make-sparse-keymap) ⇒ (keymap)
promptを指定すると、それはキーマップにたいするoverallプロンプト文字列になる。これはメニューキーマップ(メニューの定義を参照)にたいしてのみ指定すべきである。overallプロンプト文字列をともなうキーマップがアクティブなら、次の入力イベントのルックアップにたいしてマウスメニューとキーボードメニューを常に提示する。これはコマンドループにたいして毎回キーボードメニューを提示するので、overallプロンプト文字列をメインマップ、メジャーモードマップ、マイナーモードマップに指定しないこと。
この関数は新たなfullキーマップを作成してそれをリターンする。このキーマップは修飾されないすべての文字にたいするスロットをもつ文字テーブル(文字テーブルを参照)を含む。この新たなキーマップは初期状態ではすべての文字、およびその他の種類のイベントがnil
にバインドされている。引数promptはmake-sparse-keymap
のようにプロンプト文字列を指定する。
(make-keymap) ⇒ (keymap #^[nil nil keymap nil nil nil ...])
fullキーマップは多くのスロットを保持するときはsparseキーマップより効果的であり、少ししかスロットを保持しないときはsparseキーマップのほうが適している。
上述した関数によってキーマップを作成してから、keymap-set
(キーバインディングの変更を参照)を使用してそのマップ内のキーバインディングを指定する。ただしモードを記述する際には一度に大量のキーのバインドを要することが頻繁にあるため、keymap-set
を使用してそれらすべてをバインドするのは面倒かもしれないしエラーも起きやすいだろう。かわりにキーマップの作成と複数のキーのバインドを行うdefine-keymap
を使うことができる。基本的な例を以下に示す:
(define-keymap "n" #'forward-line "f" #'previous-line "C-c C-c" #'quit-window)
この関数はpairs内のキーストロークを定義するsparseキーマップを新たに作成して、そのキーマップをリターンする。pairs内に重複したキーバインディングがあればエラーをシグナルする。
pairsはkeymap-set
が受け入れるようなキーバインディングとキー定義が交互に指定されたリスト。更にキーは特別なシンボル:menu
でもよい。この場合には、定義easy-menu-define
(easy-menuを参照)が許容するようなメニュー定義であること。以下は使い方を示す簡単な例:
(define-keymap :full t "g" #'eww-reload :menu '("Eww" ["Exit" quit-window t] ["Reload" eww-reload t]))
新たなキーマップの機能を変更するために、キー/定義のペアーの前にいくつかのキーワードを使うことができる。define-keymap
の呼び出しに含まれていないキーワードの機能にたいするデフォルト値はnil
。利用可能な機能キーワードは以下のとおり:
:full
非nil
なら(make-sparse-keymap
が作成するような)sparseキーマップのかわりに、(make-keymap
が作成するような)文字テーブルキーマップを作成する(キーマップの作成を参照)。デフォルトはsparseキーマップ。
:parent
非nil
なら値は親として使用するキーマップであること(継承とキーマップを参照)。
:keymap
非nil
なら、値はキーマップであること。新たにキーマップを作成するかわりに指定されたキーマップを変更する。
:suppress
非nil
なら、そのキーマップはsuppress-keymap
によって抑制される(キーバインディングの変更を参照)。デフォルトでは数字とマイナス記号は抑制から除外されるが、値がnodigits
なら他の文字と同様に数字とマイナス記号も抑制する。
:name
非nil
、かつx-popup-menu
(ポップアップメニューを参照)によるメニューとして使用する場合には、値をメニューとして使用するような文字列にする必要がある。
:prefix
非nil
なら、値はプレフィックスコマンドとして使用するシンボルであること(プレフィクスキーを参照)。この場合にはマップ自体ではなく、このシンボルがdefine-keymap
によってリターンされる。
キーマップでもっとも一般的に行われるのは専ら変数へのバインドであろう。これはほぼすべてのモードが行っていることであり、foo
と呼ばれるモードにはほとんど常にfoo-mode-map
と呼ばれる変数が存在する。
このマクロはnameを変数として定義して、optionsとpairsをdefine-keymap
に渡した結果をその変数のデフォルト値として使用する。pairs内に重複したキーバインディングがあればエラーをシグナルする。
optionsはdefine-keymap
におけるキーワードと同様だが、定義される変数にたいしてdoc文字列を提供するためのキーワード:doc
が追加されている。
以下は例:
(defvar-keymap eww-textarea-map :parent text-mode-map :doc "Keymap for the eww text area." "RET" #'forward-line "TAB" #'shr-next-link)
キーマップ内のコマンドはそれぞれrepeat-map
プロパティを配置することによって、(repeat-mode
で便利なように)‘repeatable(繰り返し可能)’とマークすることができる、たとえば
(put 'undo 'repeat-map 'undo-repeat-map)
repeat-mode
によって使用されるマップがこのプロパティになる。
put
を繰り返し呼び出すことを避けるためのキーワードとして、defvar-keymap
には:repeat
がある。このキーワードを使えばキーマップのどのコマンドがrepeat-mode
で使用可能かを指定できる。使用できる値は以下のとおり:
t
キーマップのすべてのコマンドが繰り返し可能ということを意味する。もっとも一般的な使い方。
(:enter (commands ...) :exit (commands ...) :hints ((command . "hint") ...))
:enter
リストにあるコマンドでrepeat-mode
にエンター、:exit
リストにあるコマンドでrepeatモードからexitすることを指定する。
:enter
リストが空の場合には、そのマップのすべてのコマンドがrepeat-mode
にエンターする。このリストに1つ以上のコマンドを指定しておけば、定義しているマップには存在しないものの、repeat-map
プロパティをもつべきコマンドがある場合に役に立つだろう。
:exit
リストが空なら、そのマップにおいてrepeat-mode
をexitするコマンドは存在しない。このリストに1つ以上のコマンドを指定しておけば、定義しているマップにrepeat-map
プロパティをもつべきではないコマンドが含まれる場合に役に立つだろう。
:hints
リストにはCARがコマンド、CDRには繰り返し可能なキーと並べてエコーエリアに表示する文字列がセットされているようなコンスセルのペアーを含めることができる。
たとえばuでundo
コマンドを繰り返す場合には、以下の2節は等価である:
(defvar-keymap undo-repeat-map "u" #'undo) (put 'undo 'repeat-map 'undo-repeat-map)
または
(defvar-keymap undo-repeat-map :repeat t "u" #'undo)
マップに多くのコマンドがあり、それらすべてを繰り返し可能にする必要がある場合には後者を使うほうがよいだろう。
この関数はkeymapのコピーをリターンする。これはほとんど必要ないだろう。ほとんど差のないキーマップが必要なら、コピーより以下のように継承を使用するべきである:
(let ((map (make-sparse-keymap))) (set-keymap-parent map <theirmap>) (keymap-set map ...) ...)
copy-keymap
を処理する際には、keymap内でバインディングとして直接出現するすべてのキーマップも、すべてのレベルまで再帰的にコピーされる。しかしある文字の定義が関数定義にキーマップをもつ関数のときには再帰的なコピーは行われず、新たにコピーされたキーマップには同じシンボルがコピーされる。
(setq map (copy-keymap (current-local-map))) ⇒ (keymap
;; (これはメタ文字を実装する)
(27 keymap
(83 . center-paragraph)
(115 . center-line))
(9 . tab-to-tab-stop))
(eq map (current-local-map)) ⇒ nil
(equal map (current-local-map)) ⇒ t