キーを再バインドするには、キーマップにおける当該項目を変更します。
グローバルキーマップでバインディングを変更すると、
その変更はすべてのバッファで効果を発揮します
(ただし、ローカルキーマップでグローバルバインディングを
隠しているバッファでは直接の効果はない)。
カレントバッファのローカルキーマップで変更すると、
通常、同じメジャーモードを使っているすべてのバッファに影響します。
関数global-set-key
やlocal-set-key
は、
これらの操作を行うための便利なインターフェイスです
(see Key Binding Commands)。
より汎用の関数define-key
を使うこともできますが、
変更対象のキーマップを明示する必要があります。
キー列の再バインドを書くときには、
コントロール文字やメタ文字向けの
特別なエスケープシーケンスを使うのがよいです(see String Type)。
構文‘\C-’は後続の文字がコントロール文字であること、
構文‘\M-’は後続の文字がメタ文字であることを意味します。
したがって、文字列"\M-x"
は単一のM-xを含むと読まれ、
"\C-f"
は単一のC-fを含むと読まれ、
"\M-\C-x"
や"\C-\M-x"
はいずれも単一のC-M-xを
含むと読まれます。
同じエスケープシーケンスは、
ベクトルでも使え、文字列が許されない他の場面でも使えます。
たとえば、‘[?\C-\H-x home]’です。
See Character Type。
キーを定義したり探索する関数では、
ベクトルで表したキー列内のイベント型に対して別の構文、
つまり、修飾子名と1つの基本イベント(文字やファンクションキー名)
から成るリストを受け付けます。
たとえば、(control ?a)
は?\C-a
に等価であり、
(hyper control left)
はC-H-left
に等価です。
このようなリストの利点の1つは、
コンパイル済みのファイルに修飾ビットの数値が現れないことです。
以下の関数では、keymapがキーマップでなかったり、 keyがキー列を表す文字列やベクトルでないと、エラーを通知します。 リストであるイベントの省略形としてイベント型(シンボル)を使えます。
この関数は、キーマップkeymapにおいて キーkeyに対するバインディングを設定する。 (keyが複数イベントの場合、 keymapから辿った別のキーマップが実際には変更される。) 引数bindingは任意のLispオブジェクトであるが、 ある種の型のものだけが意味を持つ。 (意味のある型の一覧については、Key Lookupを参照。)
define-key
が返す値はbindingである。keyのおのおののプレフィックスはプレフィックスキーである (キーマップにある)か未定義であること。 さもなければ、エラーを通知する。 keyのプレフィックスに未定義なものがあると、
define-key
は当該プレフィックスをプレフィックスキーと定義し、 keyの残りの部分を指定どおりに定義できるようにする。keymapにkeyのバインディングがなければ、 新たなバインディングをkeymapの先頭に追加する。 キーマップ内のバインディングの順序は多くの場合関係ないが、 メニューキーマップでは意味を持つ(see Menu Keymaps)。
疎なキーマップを作成し、そこにバインディングを作る例を示します。
(setq map (make-sparse-keymap)) ⇒ (keymap) (define-key map "\C-f" 'forward-char) ⇒ forward-char map ⇒ (keymap (6 . forward-char)) ;; C-x用の疎なサブマップを作り、 ;; そこにfのバインディングを入れる (define-key map "\C-xf" 'forward-word) ⇒ forward-word map ⇒ (keymap (24 keymap ; C-x (102 . forward-word)) ; f (6 . forward-char)) ; C-f ;; C-pをctl-x-map
にバインドする (define-key map "\C-p" ctl-x-map) ;;ctl-x-map
⇒ [nil ... find-file ... backward-kill-sentence] ;;ctl-x-map
で、C-fをfoo
にバインドする (define-key map "\C-p\C-f" 'foo) ⇒ 'foo map ⇒ (keymap ;foo
はctl-x-map
の中にある (16 keymap [nil ... foo ... backward-kill-sentence]) (24 keymap (102 . forward-word)) (6 . forward-char))
C-p C-fに対する新しいバインディングは、
実際にはctl-x-map
の項目を変更していて、
これには、C-p C-fとデフォルトのグローバルキーマップ内の
C-x C-fの両方のバインディングを変更する効果がある
ことに注意してください。
この関数は、keymap内のolddefにバインドされたキーの olddefをnewdefに置き換える。 いいかえると、olddefに出会うたびにそれをnewdefに置き換える。 関数は
nil
を返す。たとえば、Emacsの標準のバインディングであると、 つぎの例はC-x C-fを再定義する。
(substitute-key-definition 'find-file 'find-file-read-only (current-global-map))oldmapが
nil
以外であると、 そのバインディングによってどのキーを再バインドするかを決定する。 再バインディングはkeymapで行い、oldmapではない。 つまり、別のキーマップ内のバインディングの制御のもとに、 キーマップを変更できる。 たとえば、(substitute-key-definition 'delete-backward-char 'my-funny-delete my-map global-map)では、グローバルには標準の削除コマンドにバインドされているキーに対しては、
my-map
では特別な削除コマンドにする。変更前後のキーマップを以下に示す。
(setq map '(keymap (?1 . olddef-1) (?2 . olddef-2) (?3 . olddef-1))) ⇒ (keymap (49 . olddef-1) (50 . olddef-2) (51 . olddef-1)) (substitute-key-definition 'olddef-1 'newdef map) ⇒ nil map ⇒ (keymap (49 . newdef) (50 . olddef-2) (51 . newdef))
この関数は、完全なキーマップkeymapの内容を変更し、 すべての印字文字を未定義にする。 より正確には、それらにコマンド
undefined
をバインドする。 これにより、通常のテキストの挿入を不可能にする。suppress-keymap
はnil
を返す。nodigitsが
nil
であると、suppress-keymap
は、 数字文字ではdigit-argument
を実行し、 -ではnegative-argument
を実行するように定義する。 さもなければ、それらも他の印字文字と同様に未定義にする。関数
suppress-keymap
は、yank
やquoted-insert
などのコマンドを抑制しないので、 バッファを変更不可能にするわけではない。 バッファの変更を禁止するには、バッファを読み出し専用にする (see Read Only Buffers)。この関数はkeymapを変更するため、 読者は、通常、新たに作成したキーマップに対して使うであろう。 ある目的で使用中の既存のキーマップを操作すると、 問題を引き起こすことがある。 たとえば、
global-map
に適用するとEmacsをほとんど使用不能にしてしまう。多くの場合、テキストの挿入が必要なくバッファを読み出し専用で使う rmailやdiredなどのモードのローカルキーマップの初期化に
suppress-keymap
を使う。 ファイルemacs/lisp/dired.elから持ってきた例を示す。 これは、diredモード用のローカルキーマップの設定方法である。(setq dired-mode-map (make-keymap)) (suppress-keymap dired-mode-map) (define-key dired-mode-map "r" 'dired-rename-file) (define-key dired-mode-map "\C-d" 'dired-flag-file-deleted) (define-key dired-mode-map "d" 'dired-flag-file-deleted) (define-key dired-mode-map "v" 'dired-view-file) (define-key dired-mode-map "e" 'dired-find-file) (define-key dired-mode-map "f" 'dired-find-file) ...