iTerm2上のemacsは基本的にcontrol + 記号のキーバインドが使えません。
詳しいことはこちらの記事に書かれています。
どうやらコントロールキーが制御できるASCIIの範囲が決まっているからっぽいです。
もう1つのC-S-アルファベットキーが使えないのは別の問題でCUI版のemacsでは使えません。例えばC-vキーバインドもC-S-vキーバインドもemacsには同じC-vとして処理されてしまうからです。
さまざまなサイトを閲覧してどうにかこの2つのバインドに対処したので紹介します。
こちらの記事を参考にさせてもらいました。元サイトが壊れていたのでgoogleのキャッシュを参照しています。
iTerm2では直接control + 記号のキーバインドは打てません。そこで、emacsのevent-apply-controll-modifierを使ってあたかもcontrol + 記号を打ったようにします。たとえばC-x @ cを押してからrを押すと、C-rを押したのと同じことになります。
これを使えば記号を含めたキーバインドが可能になります。C-. を実現するならC-x @ c .とすれば実行できます。
毎回C-x @ c .と入力するのは大変なので、iTerm2のグローバルショートカットキーでHexコード送信を割り当てて、C-.と打ったらemacsにはC-x @ c .を送信すれば、C-.のキーバインドが使えます。
iTerm2を開いて、上のメニューから「iTerm2」から「Preferences...」を選びます。「Keys」を選び、+ボタンを押します。
試しにC-.を追加します。「keyboard shortcut」のフィールドがアクティブな状態で control + .を打ち込みます。打ち込むと^.になります。プルダウンメニューから「Send Hex Code」を選びます。新しく出てきたテキストフィールドに以下を記述します。
18 40 63 2eHex codeはこの様に対応しいて、C-x @ c .を表しています。
18 = C-x
40 = @
63 = c
2e = .
ショートカットキー Hex code
C-, 18 40 63 2c
C-. 18 40 63 2e
C-: 18 40 63 3a
C-; 18 40 63 3b
C-< 18 40 63 3c
C-> 18 40 63 3e
例外的に、C-<はControl + Shift + <でC->はControl + Shift + >で登録します。
上の画像を見てもわかる様に、違っているのは最後のhex codeだけです。
他にもC-(やC-/を割り当てたい方は以下のサイトの表から16進数のhex codeを参照してください。
試しに、先ほど設定したC-.にキーバインドを割り当てます。
ファイルのパスを表示する関数を作りショートカットを割り当ています。
emacsの設定ファイルを開きます。
(defun show-file-name ()
"Show the full path file name in the minibuffer."
(interactive)
(message (buffer-file-name)))
(global-set-key (kbd "C-.") 'show-file-name)
ファイル名を表示するC-.を実行しすると、エコーエリアにファイル名が表示されます。
キーボードで入力したC-.がiTerm2でC-x @ c .に変換されemacs上でキーバインドが機能したことをあらわしています。
Control + Shift +アルファベットバインド
最初にも書いたように、C-S-fみたいなシフトを使ったキーバインドはCUI版のemacsではC-fと処理されてしまいます。shiftキーを別のバインドとして使うにはトリックが必要です。event-apply-control-super-modifier関数を作成し、event-apply-shift-modifier
を上書きして、iTerm2の入力はC-S-fになりますがemacs内部ではC-s-fとして処理させます。C-s-fはControl + super + fを表しており、スーパーキーを押しているという体に変換します。
とりあえず、C-s-fを利用できるようにします。init.el に独自に作成したevent-apply-control-super-modifier関数を加えます。作成した関数でevent-apply-shift-modifierを上書きします。本来はC-x @ Sでevent-apply-shift-modifierが処理するところをcontrol + superにしてしまいます。
(defun event-apply-control-super-modifier (ignore-prompt)
"\\\\Add the Control+Shift modifier to the following event.
For example, type \\\\[event-apply-control-shift-modifier] SPC to enter Control-Shift-SPC."
(vector (event-apply-modifier
(event-apply-modifier (read-event) 'control 26 "C-")
'super 23 "s-")))
(define-key function-key-map (kbd "C-x @ S") 'event-apply-control-super-modifier)
ちなみに上のコードのsuper 23 "s-"はここを参照しています。
Emacs側でC-s-fを使う準備が整いました。iTerm2で記号のキーバインドでやったようにHexコードを送る設定を加えます。
18 40 53 66Hex codeはこの様に対応しいて、C-x @ S fを表しています。
18 = C-x
40 = @
53 = S
66 = f
動作確認で、上で作ったshow-file-name をC-s-fにバインドします。
(global-set-key (kbd "C-s-f") 'show-file-name)
上の画像はC-h kでC-s-fをタイプしてcontrol + Shift + fがC-s-fとして処理されているのを確認しています。
この方法でより多くのショートカットキーを簡単なキーバインドで定義できるようになりました。emacsを使った素早いコーディングが可能になりますね。