🐷

Alacrittyで複数の修飾キーを識別させる

2024/09/28に公開

動機

自分はエディタにneovimを使っているのですが、<cr><s-cr>にそれぞれ別のコマンドを割り当てています

<cr>はneovim上でリターンキーのことです <s-cr>はシフトとリターンキーの同時押し

ところがAlacrittyは、デフォルトではこれら二つを区別してくれません</br>
ではどのようにすれば区別してくれるのか、を書き留めておきます

あと、CSIに詳しいニキはマサカリ投擲してください
neovim詳しいニキも自分の設定に色々ダメだしおなしゃす

結論

alacritty.toml
[keyboard]
bindings = [
	{ key = "Enter", mods = "Shift", chars = "\u001b[13;2u" },
]

alacritty.ymlを使用している場合

alacritty.yml
key_bindings:
  - { key: Enter, mods: Shift, chars: "\x1b[13;2u" }

charsの部分を"\x1b[13;2u"にしても設定できます

大まかな解説

まずターミナル上で普通の文字を入力すると
その文字のユニコード が入力されます
修飾キーが押されている場合、どのキーが押されているかはCSIというルールに則って区別します

CSI <文字のユニコード>;<修飾キーのパラメータ>u

例えばコントロールキーとfを同時押ししたとしましょう
この時、fのユニコードは102、コントロールキーのパラメータは

shift alt ctrl
+1 +2 +4

となっています 修飾キーのパラメータは初期値(何も修飾キーを押してない状態)が1なので、最終的に

CSI 102;5u

となります 同様に、<cr>のユニコードは13なので<s-cr>をCSIルールで表すと

CSI 13;2u

となります

次にこの情報をAlacrittyに渡すことができれば<cr><s-cr>を区別してくれそうです。
CSIルールの表現であることを示すにはCSI ~;~uCSIの部分を\x1b[に置き換える必要があります 従って

alacritty.toml
[keyboard]
bindings={
	{ key = "Enter", mods = "Shift", chars = "\x1b[13;2u" },
}

とすれば完了..のはずなんですが、このように記述するとAlacrittyがエラーを吐きます(Alacrittyの設定にymlを使用している場合はこれで問題ありません)
なんでも、\x1bはエスケーブシーケンスとしてサポートされていないそうです
なので、代わりに\u001bを使います

alacritty.toml
[keyboard]
bindings = [
	{ key = "Enter", mods = "Shift", chars = "\u001b[13;2u" },
]

参考文献

https://alacritty.org/config-alacritty.html

http://www.leonerd.org.uk/hacks/fixterms/

https://www.reddit.com/r/neovim/comments/mbj8m5/how_to_setup_ctrlshiftkey_mappings_in_neovim_and/

https://github.com/alacritty/alacritty/issues/6592#issuecomment-1598119246

GitHubで編集を提案

Discussion