Nekostack

Golang, Swift, Vim, Cat, Curry, Whisky.

Vim でインサートモードを抜けた時にインプットメソッドを切り替える

Posted on 02 January 2017.

1. はじめに

Vim で日本語を書く人によくありがちなのが, ノーマルモードを抜ける際にインプットメソッドを戻すのを忘れてしまうことなのかなと思っている.

dont-forget-switch-im

うっかりインプットメソッドを切り替えるのを忘れて保存しようとするとこうなって, ストレスがマッハに… この辺りの話は散々されているはずで, Vimを使う上でのIME(日本語入力)の取り扱い や, Vim/GVimで「日本語入力固定モード」を使用する などを見ると色々やりようはありそうな感じ.

  • Mac & Vim だと Karabiner を使って, インサートモード離脱にインプットメソッドを切り替える.
  • MacVim などで iminsert を使う.

自分は大体 CUI 版の Vim, NeoVim を使うのだが, 2017/01/02 時点では karabiner は macOS Sierra 上で使えるようになっておらず, 上で挙げられている対処ができないはず. そこで, Vim から自作コマンドラインツールを使って, autocmd InsertLeave でインプットメソッドを切り替えるというのが今回の試み (macOS のみ).

2. コマンドラインからインプットメソッドを切り替える

ざっくり探してみた感じだと見つからなかったので, 書いてみた.

Swim - A command line tool to switch the current input method by identifier for macOS.

使い方としては, README に書いてある通り. swim use com.apple.inputmethod.Kotoeri とすると日本語入力にコマンドラインから切り替えられる.

3. Vim でインサートモードを抜けたら swim を叩く

インサートモードを抜けたら ABC - Extended に切り替えたいので, swim use com.apple.keyboardlayout.all を叩くようにする.

ABC - Extended に com.apple.keyboardlayout.all という識別子がついているのは, swim list --name で確認できる (System Preferences -> Keyboard -> Input Sources で追加してる場合のみ).

4. GUI 版 Vim と iminsert を使う

GUI 版の Vim (CUI 版でもコンパイル時オプションできる・できないまでは把握してない) で iminsert 使うと, この記事の目的を果たすことは可能. vimdoc を読む限り set noimdisable して set iminsert=2 すれば良いように見える. なお Homebrew からインストールした MacVim (tag: snapshot 119) で試した. なので, (少なくとも今は) MacVim-Kaoriya である必要もない.

Vimでコマンドモードに戻るときにIMEをオフにする - ほとラボ

上の記事では, 方法の一つとして set imdisable が挙げられてる. ただ vimdoc によると “When set the Input Method is never used.” であるそうなので, 常にインットメソッドを切りたいわけじゃなければ, set imdisableset noimdisable を適宜呼ぶことになるんじゃなかろうか. それよりは, 先に書いたように (set noimdisable にしている上で) set iminsert=2 した方が, インサートモード離脱時にインプットメソッド切ることができるので (vimdoc-ja の訳注 参照).

あと imdisable は MacVim だとちゃんと機能してないんじゃないかな…という印象. set imdisable したタイミングではインプットメソッドが切れるが, 永続的に切れるというわけではないようだし… そもそも +xim されてるとはいえ, X Input Method ではないし… この辺は実装とドキュメントで異なる部分があるのかもしれないが.

5. 所感

Swim, Carbon の API 使わざるを得なかった (ほんまか) ので, ちょっともにょりがある. 全面的に Deperecated になったのかと思ってたけど, setSelectionKeysKeylayout(_:) とか引数の型に TISInputSource とか出でくるので謎. Carbon 周りの API ドキュメントは表に残ってないようなのだが. とりあえず現状を誤魔化そうというモチベーションでやったので, まあその辺りの死活具合は深く考えないことにしておく.

理想的には, Vim 自体がインプットメソッドと直接通信してしまうのがいいのかなあ. 一方で MacVim だとインプットメソッドを細かく制御できそうだが… そのうち GUI でも Vim 触ってみるべきか.