TL;DR
Vimや GUI エディタの Vim 拡張機能 (e.g. vscodevim) を普段使うとき、 jj
を esc
にマップして insert mode を抜けるのに使っているのですが、日本語入力中に jj
(つまり っj
) を入力したときも機能するよう、 Karabiner-Elementsの complex modificationsを設定する方法をまとめました。
Requirements
これを実現するためには日本語入力で っj
が入力されたら、
- 現在までに入力中の日本語文章の変換を確定させ、
- 入力を日本語から半角英数に変更し、
- Vim insert mode から何らかの方法で抜ける
ことが必要になります。1. と 2. は return
および 英数
キーを入力するよう設定すれば OK です。一方、3. については以下の2つの方針が考えられます。
っj
→esc
にマップする (jj
の入力はなかったことにする)っj
→jj
にマップする (jj
→esc
のマッピングは Vim や Vim 拡張機能の設定に任せる)
Karabiner-Elements を使うと macOS のグローバルなキーボード設定が変えることができるので (もちろん特定のアプリケーションに限定した設定も可能ですが)、ターミナルの Vim だろうが VS Code だろうが jj
が使えるようになるのが大きな魅力です。そこで、様々な場面で意図しない esc
が実行されないように、ここでは後者を選択することにします。
Installation
ここでは @s-showさんの Karabiner-Elementsを使ってキーの2連打に処理を割り当てる方法を参考に、以下の karabiner-vim.json
を作成しました (Gistにも置いておきました)。これを、 ~/.config/karabiner/assets/complex_modifications
に置いておけば、 Karabiner-Elements Preferences → Complex Modifications → Add rule から選択できるようになるはずです。
仕組みとしては、
- 日本語入力のときに1つ目の
j
が入力されたらvim-j-flag
を1
にする。もし一定時間何も入力されなかった場合 (to_if_invoked
) やj
以外の文字が入力された場合 (to_if_canceled
) は、vim-j-flag
を0
に戻す。 - 立て続けに2つ目の
j
が入力されたらvim-j-flag
を0
に戻し、return
→delete
(っ
を削除) →英数
→jj
(半角英数) を入力する。
となっています。あとは Vim の場合は .vimrc
で、
inoremap <silent> jj <ESC>
としておけば OK です。上で前者の方針を選択した場合も、これを参考に簡単に設定できると思います。macOS 限定のハックですが、 Vim-like な環境で快適に日本語入力ができるようになるので便利ですね!
Code
{"title":"For Vim","rules":[{"description":"日本語入力の っj を jj にマッピングする","manipulators":[{"type":"basic","from":{"key_code":"j"},"to":[{"set_variable":{"name":"vim-j-flag","value":0}},{"key_code":"return_or_enter"},{"key_code":"delete_or_backspace"},{"key_code":"japanese_eisuu"},{"key_code":"j"},{"key_code":"j"}],"conditions":[{"type":"variable_if","name":"vim-j-flag","value":1},{"type":"input_source_if","input_sources":[{"language":"ja"}]}]},{"type":"basic","from":{"key_code":"j"},"to":[{"set_variable":{"name":"vim-j-flag","value":1}},{"key_code":"j"}],"to_delayed_action":{"to_if_invoked":[{"set_variable":{"name":"vim-j-flag","value":0}}],"to_if_canceled":[{"set_variable":{"name":"vim-j-flag","value":0}}]},"conditions":[{"type":"variable_if","name":"vim-j-flag","value":0},{"type":"input_source_if","input_sources":[{"language":"ja"}]}]}]}]}