確認環境
PC | Thinkpad X1 Carbon 2nd Gen |
OS | FreeBSD 12.1-RELEASE-p1 |
Neovim | NVIM v0.4.3 |
CLI IME | uim-fep version 1.8.8 / Mozc-2.23.2815.102.00_5 |
GUI IME | fcitx version: 4.2.9.5 / Mozc-2.23.2815.102.00_5 |
課題
以前の記事で、Normalモード遷移時にIMEを自動でOFFするようにした。
とても快適になった。
しかし、Vimで日本語の文章を書いていると下記の状況になることが多い。
- 日本語入力中、
でNormalモードへ遷移 (IME ON -> OFF) - Normalモードで何かしら操作実施
- 再び挿入モードへ遷移 (IME OFFのまま)
- 日本語を入力するため手動でIME OFF -> ON
2.のNormalモード遷移前にIMEがONだった場合は、
4.の挿入モード遷移時に自動でIME ONにしたい。
対策
ここでは、自前のシェルスクリプトとVimスクリプトで対応する。
- IME(uim-fep/fcitx)のON/OFF状態取得 (シェルスクリプトの作成)
- Vimのモード遷移時の処理追加 (.vimrcの設定)
1. IME(uim-fep/fcitx)のON/OFF状態取得
IMEの状態を取得するシェルスクリプトは以下の通り。
このスクリプトは、下記のような動作をする。
- IME ONなら標準出力に
1
を出力 - IME OFFなら標準出力に
0
を出力 - 仮想コンソールで
$UIM_GET_FILE
が未設定(uim-fep未起動)の場合は、標準出力に0
を出力
このシェルスクリプトをVimから呼び出せるように、パスが通ったディレクトリ(1)に保存して、実行権限を追加(chmod +x
)しておこう。
1 ... 参考) パスを通す
以降は、シェルスクリプトのファイル名はimests
で保存した想定で説明を行う。
ちょっと注意点
以前の記事同様、Vimが動いている環境が仮想コンソール上なのかXウィンドウ上なのかという判定は、
$XMODIFERS
の設定有無で行っている。
実は、このやり方にはちょっと問題が出るケースが見つかった。
それは、Xウィンドウを立ち上げる前にtmux
を起動していた場合だ。
その場合、Xウィンドウ上でさらにtmux
を起動すると、tmux
上のシェルでは$XMODIFERS
が存在しなかった。
この挙動で困る人は$XAUTHORITY
あたりをCUI/GUIの判定に使った方がいいかもめ。
2. Vimのモード遷移時の処理追加
次に、~/.vimrc
(Neovimは~/.config/nvim/init.vim
)に下記を追加しよう。
" IME control command command! ImeOff silent !imectrl 0 command! ImeOn silent !imectrl 1 function! ImeAutoOff() let w:ime_status=system('imests') :silent ImeOff endfunction function! ImeAutoOn() if !exists('w:ime_status') let w:ime_status=0 endif if w:ime_status==1 :silent ImeOn endif endfunction " IME off when in insert mode augroup InsertHook autocmd! autocmd InsertLeave * call ImeAutoOff() autocmd InsertEnter * call ImeAutoOn() augroup END
imectrl
については、以前の記事を参照されたし。
もしくは、普段使っているIMEの制御コマンドに置き換えて頂きたい。
ちょっと解説
挿入モードを抜ける時、ImeAutoOff関数を呼び出す。
このとき、今回作成したスクリプト(imests)を呼び出してIMの状態を保存しておく。
挿入モードに入る時、ImeAutoOn関数を呼び出す。
このとき、保存していたIME状態がONだった場合は、IMEをONする。
関数内の最初のif文はちょっと手抜きだけど初回時の変数設定。
コードで怪しい箇所があればツッコミ下さいまし。
IME状態を管理する単位を調整したい場合
上のサンプルでは、Vimのウィンドウ単位でIMEの状態を保存している。
つまり、あるウィンドウのIME状態は、他のウィンドウには影響しない。
これをバッファごとに管理したい場合は、w:ime_status
をb:ime_status
にすればいい。
もし、プロセスごとに管理したい場合は、w:ime_status
をg:ime_status
にすればいい。
w:ime_status
は4箇所あるので、全部置き換えてねと。
最後に
今回の修正でVimでの日本語文章を書くのがちょっと気軽になった。
あと、C-o
でのワンショットノーマルモードが使いやすくなった。
例えば、下のよう表形式のデータを入力している際、「ははは」まで入力したときに、
挿入モードのまま<C-o>j
で次のitem2
の行も続けて日本語を入力できる。
地味に嬉しい。
item1, ははは item2, item3,
今回紹介したやり方より良さげな方法があれば、ぜひ教えて下さいましまし。
参考
以上。