LinuxのVimでfcitxの入力状態を復元する

Tools

WindowsのKaoriya版GVimでは、ノーマルモードから挿入モードに移行するときに、以前の入力状態を復元してくれる機能があります。

LinuxのVimで同じような動作を実現する方法をご紹介します。

vim -gで起動したGVimでは機能しない方法

ターミナルのVimやgvimコマンドのGVimをつかうのであれば、プラグイン(lilydjwg/fcitx.vim)や、fcitx-remoteを使う手法(Fcitx (简体中文) – ArchWiki)などによって、入力状態の復元が可能です。しかしこれらの手法はvim -gコマンドで起動したGVimでは上手く機能しません。

LinuxではgvimコマンドでGVimを呼び出すと、未変換状態の入力文字が正常に表示されない症状が起こることがあります。

fcitx の未変換状態が gvim で表示されない #730

従いましてvim -gで起動したGVimでも使える方法も別に取り入れるのがベターです。

GVimだけで有効な方法

GVimはimactivefuncにIM切り替え処理を、imstatusfuncにIM状態取得処理を指定することにより、IMの制御ができるようになっています。fcitxはfcitx-remoteコマンドで入力切替および状態取得ができるので、.gvimrcなどで以下のように処理を割り当あてることで、復元動作を実現できます。

この手法はvim -gのGVimでも機能しますが、おそらくターミナル上のVimでは機能しません。GVimとVimの両方で機能させたい場合は、先の方法と組み合わせる必要があります。

set imactivatefunc=ImActivate
function! ImActivate(active)
  if a:active
    call system('fcitx-remote -o')
  else
    call system('fcitx-remote -c')
  endif
endfunction
set imstatusfunc=ImStatus
function! ImStatus()
  return system('fcitx-remote')[0] is# '2'
endfunction

参考:Vimからfcitxを使う

※追記 v8.0.1274以前のGVimではこの手法はneocompleteとの干渉が起こってしまうようです(ややレアケースですが、日本語入力がONになる状態で挿入モードに入り、その後に日本語入力をOFFにしてneocompleteの補完が表示されているときに[ESC]してノーマルモードに移行し、再度挿入モード入るとIMEがオンになってしまう)
※さらに追記 v8.0.1344以降のGVimでこの手法を使うにはソースコードの変更が必要になっています(参考:Linux版 gvimで imactivatefunc / imstatusfunc が 8.0.1344以降、呼ばれなくなっている #1130)。

プラグイン作りました

二つの手法を設定として記述するとなると.vimrcなどがごちゃついてしまいます。なのでGVimとVimで切り替わけて処理をするプラグインを作りました。

fcitx-mem

has(‘unix’)のみで動くようにしているので、他の環境でインストールしてしまっても問題ありません。

注意点ですが、GVimで復元動作を有効にするにはiminsertの値を0または2に設定する必要があります。設定を1にしている場合は、以前の状態に関わらず直接入力で挿入モードに移行します。

※追記

上のプラグインはneocompleteとの干渉が起こってしまうようです。neocompleteを使わない選択肢は無いので、干渉しないものを作りました。

fcitx-mem-re

vim -g で起動したGVimではInsertLeave時にfcitxの状態を取得しようとしても上手くいかないので、このプラグインではimoremapで<Esc>キーに処理を割り当てています。ただしvimでは<Esc>キーのキーコードが方向キーなどのキーコードにも含まれているため、これはあまりマナーの良い行為ではないように思います。

GVimでは<Esc>キーが押された時と、方向キーが押されたときの判別ができるようなので問題となりませんが、同じ割り当てのままTerminal上のVimで動かすと、挿入モード時に方向キーが正常に使えなくなったりします。

fcitx-mem-reでは、GVimとVimで処理を分けているため、どちらでも正常に動くはずですが、私が理解できていない問題が潜んでいそうでやや心配です。もっと良い方法があればいいのですが。

コメント