tags : Emacs

ターミナルのEmacsでSuperを認識させる

ターミナル上のEmacsでAltキーをSuperキーとして認識させるための設定手順をまとめます。WezTermとEmacsの設定を行い、ターミナル環境でのキー入力を適切にマッピングします。

ロジックの説明

ターミナルでSuperキーが直接認識されない理由は、ターミナルエミュレータがSuperキーの入力をエスケープシーケンスとして扱わないためです。そこで、WezTermの設定でAltキーの入力を特定のエスケープシーケンス(例:\x1b[32;16)として送信するように設定します。

このエスケープシーケンスは任意のもので構いませんが、ターミナル側とEmacs側で一致させる必要があります。\x1b[32;16は、エスケープ文字(\x1b)、[、32;16という形式を持ち、一般的なエスケープシーケンスの形式に従っています。Emacs側でこのエスケープシーケンスをSuperキーとして認識させるために、キー設定を変更します。こうして、Altキーの入力をSuperキーとして扱えるようになります。

参考記事 :: key bindings

WezTermの設定

以下のコードをWezTermの設定ファイル(`~/.wezterm.lua`)に追加します。

local wezterm = require 'wezterm'
 
local config = {}
config.keys = {
  {key="r", mods="CMD", action=wezterm.action{SendKey={key="r", mods="OPT"}}},
  {key="q", mods="CMD", action="QuitApplication"}
}
 
-- キーバインドで使う文字列
local chars = [[abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789!@#$%^&*()-=_+[]{}|;:'",.<>/?\\`~]]
 
-- AltキーをSuperキーとして認識させるための設定を追加
for i = 1, #chars do
  local key = chars:sub(i, i)
  local seq = string.format("\x1b[32;16%c", key:byte())
  print(string.format("Mapping ALT+%s to %s", key, seq)) -- デバッグメッセージ
  table.insert(config.keys, {key=key, mods="ALT", action=wezterm.action{SendString=seq}})
end
 
-- CMDキーをOPTキーとして認識させるための設定を追加
for i = 1, #chars do
  local key = chars:sub(i, i)
  table.insert(config.keys, {key=key, mods="CMD", action=wezterm.action{SendKey={key=key, mods="OPT"}}})
end
 
return config

Emacsの設定

以下のコードをEmacsの設定ファイル(`init.el`や`~/.emacs.d/init.el`)に追加します。

(leaf *alt-to-super-key-bindings-in-cui
  :doc "CUI環境でAltキーをSuperキーとして認識させる設定。
ターミナルの設定で Alt キーでエスケープシーケンス \\x1b[32;16 を送るようにする。
例えば、Alt + h の場合は以下のように設定される:
(define-key local-function-key-map \"\\x1b[32;16h\" [(super ?h)])"
  :when (not (display-graphic-p))  ; CUI環境のみ実行
  :config
  ;; キーバインドで使う文字列
  (let ((chars "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789!@#$%^&*()-=_+[]{}|;:'\",.<>/?\\`~"))
    (dolist (key (string-to-list chars))  ; すべての文字と記号を対象にする
      (let* ((seq (format "\x1b[32;16%c" key))
             (key-def `[(super ,key)]))
        (define-key local-function-key-map seq key-def)))))

この設定により、ターミナル環境でAltキーをSuperキーとして認識させることができます。WezTermでAltキーを押すと、対応するエスケープシーケンスがEmacsに送信され、Superキーとして認識されます。