はじめに
Windows Terminal などのターミナルエミュレータはキー入力をアスキーコードとして受け取る。その場合、1部の特殊キーは認識されない。
Emacs で良く利用するキー、コマンドとして C-SPC を使った set-mark-command があるが、C-SPC が Windows Terminal 上では使えないため、Windows Terminal から ssh 接続した先で Emacs を利用する際、set-mark-command が使えない。
一方で Emacs には event-apply-*-modifiers という関数があり、後続のキーの前にモディファイアキーが押されているとしてキー入力を受け付けることができ、C-x @ [hsmaSc] に割当られている。例えば C-x @ c SPC と入力すれば C-SPC に割当られたコマンドを呼び出すことができる。
そこで、AutoHotKey で Windows Terminal を利用しているときに C-SPC が押されたら、
C-x @ c SPC を送信するように設定する。
Emacs 設定
event-apply-*-modifers にはコントロールキーとメタキーの同時利用のための関数は用意されていない。そのための関数を定義する(StackOverflow より)
; https://superuser.com/questions/83166/using-c-m-to-do-a-query-replace-regexp-in-emacs-running-in-mac-terminal
; cargo cult adaptation of event-apply-control-modifier
(defun event-apply-control-meta-modifiers (ignore-prompt)
(vector
(event-apply-modifier
(event-apply-modifier (read-event)
'control 26 "C-")
'meta 27 "M-")))
(define-key function-key-map (kbd "C-x @ %") 'event-apply-control-meta-modifiers)
AutoHotKey 設定
※ sleep は気持ち、無くても動くはず
#IfWinActive, ahk_exe WindowsTerminal.exe
{
^Space::
{
Send, ^x
Sleep, 50
Send, @
Sleep, 50
Send, c
Sleep, 50
Send, {Space}
Return
}
}
#IfWinActive, ahk_exe WindowsTerminal.exe
{
^!Space::
{
Send, ^x
Sleep, 50
Send, @
Sleep, 50
Send, `%
Sleep, 50
Send, {Space}
Return
}
}
#IfWinActive, ahk_exe WindowsTerminal.exe
{
!Enter::
{
Send, ^x
Sleep, 50
Send, @
Sleep, 50
Send, m
Sleep, 50
Send, {Enter}
Return
}
}
参考 (WezTerm バージョン)
config.keys = {
{
key = 'Enter',
mods = 'META|SHIFT',
-- action = wezterm.action.SendString 'Test'
action = wezterm.action_callback(function(win, pane)
win:perform_action(wezterm.action.SendKey{ key = 'x', mods = 'CTRL' }, pane)
win:perform_action(wezterm.action.SendKey{ key = '@', mods = '' }, pane)
win:perform_action(wezterm.action.SendKey{ key = '%', mods = '' }, pane)
win:perform_action(wezterm.action.SendKey{ key = 'Enter', mods = '' }, pane)
end),
},
}