愛用していたAutoKeyというWindowsのAutoHotkeyと同等のアプリケーションも2012年から開発が止まっている様なので、乗り換えを検討することにした。

やりたいこと

Vimを使っていて、「Escape」キー又は「Ctrl+[」キーが押されたら、IMEがオフになってノーマルモードになってほしい

他の代替アプリケーション

  • XKB
    設定ファイルを作るのもなんだか面倒。
    なんでも出来そうな感じはするんだけど・・・。

  • IronAHK
    AutoKey以上にメンテされてない模様。

  • Xmodmap
    CapsLockキーをControlキーに変更する際に使用中。
    1つのキーをバインドすることは可能だけど、複数のキーの組み合わせは駄目っぽい。

ということで、そのものズバリというアプリケーションは多分存在しない。
まさかここまではとは!

Fcitx+Xbindkeys+Xdotoolを組み合わせてやってみる

この人気の無さっぷりから推測するに、今後も息の長いアプリケーションが登場するのは難しそうな気がしている。
至れり尽くせりな専用アプリケーションは諦め、シンプルなツールの組み合わせて実現した方が、長く使えるかなと思った。
で、色々調べていたら、下記3つのツールを使えば、なんとなかなりそうなことがわかった。

  • Fcitx
  • Xbindkeys
  • Xdotool

大まかな流れ

  1. Xbindkeysでショートカットキーを補足して、自作シェルスクリプトを動かす
  2. 自作シェルスクリプト内で、fcitx-remoteを利用してIMEを操作
  3. 自作シェルスクリプト内で、本来押したキー(Escape等)のキーをエミュレート

Fcitx

インストール作業は省略。

自分はFcitx+Mozcというメジャーな組み合わせにしといた。
fcitx-remoteというコマンドでIMEを操作するので、fcitx-remoteコマンドもインストール済みか確認すること。

Xbindkeys

インストール作業は省略。

設定ファイルの作成。

vi ~/.xbindkeysrc

"~/.xbindkeys/imeoff-ctrl+bracketleft"
    Control + bracketleft
"~/.xbindkeys/imeoff-escape"
    Escape

ログイン時に起動するように。

vi ~/.xprofile

if [ -x "$(which xbindkeys)" ]; then
  xbindkeys &
fi

Xdotool

インストール作業は省略。

自作シェルスクリプト

vi ~/.xbindkeys/imeoff

#!/usr/bin/env bash

wait=3

start=$(date +%s)

loop=1

while [ $loop -eq 1 ]
do
  status=$(fcitx-remote)
  case $status in
    1 ) loop=0
        continue
        ;;
    2 ) fcitx-remote -c
        continue
        ;;
    * ) current=$(date +%s)
        if [ $(expr $current - $start) -gt $wait ]; then
          loop=0
        fi
        continue
        ;;
  esac
done

if [ -x "`which xdotool`" ]; then
  xdotool key --clearmodifiers ctrl+c
fi

cd ~/.xbindkeys
ln -s ./imeoff ./imeoff-ctrl+bracketleft
ln -s ./imeoff ./imeoff-escape

やっていることは結構泥臭くて、ショートカットキーが押されたら、3秒間IMEをオフにする様にfcitx-remoteを実行し続けるというシェルになっている。
なんでこんな面倒なことをやっているかというと、Xbindkeysからこのシェルを実行されたタイミングだと、Fcitxが一時的に無効になっていて、いくらIMEをオフにしようとしても出来ない状態なんだよね。
ちなみにfcitx-remoteの返り値も0という、ようわからん感じになっておる。
sleepとか入れるとちゃんと実行されるんで、とりあえずタイムラグってことで、3秒間の余裕をもたせている感じ。
まあ、3秒間なんて制限せずに無限ループという男らしいやり方もあるけども、もし無限ループになったらプロセス殺さないといけないんで、面倒臭いから時間制限つけといた。

あと、Xbindkeysで捕獲されたキーは、送信されないっぽいから、再度Xdotoolでエミュレートしてキーを送信してやってる。
うおお、クソめんどくせー。

まとめ

上記のやり方で一応やりたいことは達成できた。
fcitx.vimなんてプラグインもあるけど、自分はSSHで接続した先にリモートのVimでも同じように動いて欲しいんで、こんな感じにしている。

結論

多分IMEをオフにするクセを自分で身に付けた方が早い。

参考サイト