XやWindowsやCocoa上のEmacsでは、Control+Return
だろうがControl+,
だろうがCtrl+Shift+Space
だろうが、好きな機能を割り当てることができる。これらのGUI環境ではアプリケーションが検出できる修飾キーの組合せに制約がほとんどないためだ。
ところが、ターミナル(エミュレータ)上では原則として一つのキー入力は一つのASCIIコードとしてアプリケーションに渡されるため、上記のように対応するASCIIコードのないキーの組合せはEmacsなどでそれとして認識することができない。Meta+X
をEscape X
の二ストロークに置換する仕掛けがせいぜいだ。
…と思いきや、実はEmacsにはいわゆるスティッキー修飾キーに相当するevent-apply-*-modifier
というギミック的関数が用意されており、たとえばC-x @ c
(event-apply-control-modifier
)と押してからRET
を押すと、C-RET
を押したのと同じことになる。つまり、たとえばiTermであればPreferences→Keys→Global Shortcut Keysで+を押し、
Shortcut Keyboard: | ^↩ |
---|---|
Action: | Send Hex Code |
18 40 63 0d |
のように設定すれば、EmacsでC-RET
が効くようになる。もちろん、「18 40 63 0d」とはC-x @ c RET
をASCIIコードに置き換えたものだ。C-,
なども同様に設定すればいい。
ところが、C-S-SPC
のような組合せはすんなりとはいかない。C
とS-SPC
に分解してみても、依然としてS-SPC
にはASCIIコードがないのだ。C
とS
とSPC
に分解しようと思っても、event-apply-*-modifier
は直後の一ストロークに作用するので、C-x @ c C-x @ s SPC
のC-x @ c
の効用は直後のC-x
に食われ、そこで連鎖が終了してしまう。ならばとS
とC-SPC
に分解してみても、C-SPC
はASCIIコードでは00
すなわちC-@
であるため、C-S-@
という組合せになってC-S-SPC
とは認識されない。(ところでinput-decode-map
やkey-translation-map
を使う別解もあるが、ここでは詳しくは触れない)
解決策としては、「スティッキーControl+Shiftキー」を自作すれば良い。つまり、こんな関数を作り:
1 2 3 4 5 6 7 |
(defun event-apply-control-shift-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) 'shift 25 "S-") 'control 26 "C-"))) (define-key function-key-map (kbd "C-x @ C") 'event-apply-control-shift-modifier) |
次のような設定を加える。
Shortcut Keyboard: | ^⇧Space |
---|---|
Action: | Send Hex Code |
18 40 43 20 |
同様に、たくさん使いたいquery-replace-regexp
(正規表現による文字列置換)はEmacsの標準ではC-M-%
などというターミナル住民にとっては鬼畜なキーに割り当てられているわけだが、これも次のような関数を作り:
1 2 3 4 5 6 7 |
(defun event-apply-meta-control-modifier (ignore-prompt) "\\Add the Meta-Control modifier to the following event. For example, type \\[event-apply-meta-control-modifier] % to enter Meta-Control-%." (vector (event-apply-modifier (event-apply-modifier (read-event) 'control 26 "C-") 'meta 27 "M-"))) (define-key function-key-map (kbd "C-x @ M") 'event-apply-meta-control-modifier) |
下のようなキー設定を加えれば良い。
Shortcut Keyboard: | ^⌥⇧% |
---|---|
Action: | Send Hex Code |
18 40 4d 25 |
世の中、カビくさい道具であってもやりようはあるもんです。どんなところでも、妥協せずに使えるものを何でも使って自らを足らしむる。それがハック。
追記:zshもマルチストロークのキーバインディングに対応しているので、たとえば上記のように設定したC-RET
に機能を割り当てるには
1 |
bindkey '^X@c^M' accept-line |
でOK。(上記はC-RET
をRET
と同じにする設定)