Create a gist now

Instantly share code, notes, and snippets.

Vi風操作をWindows用IMEとして実装

Vi風操作をWindows用IMEとして実装

Vim Advent Calendar 2012の345日目(2013-11-10)の記事です。

普通のWindowsアプリにおいて、擬似的にViエディタのNormal mode編集操作を使えるようにするIMEを作りました。

背景・課題

Wordで報告書やOutlookでメールを書く際、日本語文章の編集操作に関し、 Vimでの操作に比べて、以下のまどろっこしさを感じていました。

  • ホームポジションから手を離してカーソルキーまで移動するのが面倒。
  • CTRL-←等での単語移動は短すぎ。日本語だと文節くらいの単位で移動したい。
  • 次の文までさっと移動したい。

目的

Windowsアプリでのテキスト編集をVi操作でできるようにすること。

解決方法

Vi風の編集操作を実現するにあたり、 )コマンドによる次の文への移動や、 fコマンドによる指定文字までの移動を行うには、 カーソル位置周辺の文字列を取得する必要があります。

最近のIMフレームワークには文脈依存変換等の用途向けに、 カーソル位置周辺文字列を取得する機能があります。 WindowsのTSF(Text Services Framework)の該当機能を使うため、 IMEとしてtsf-vimを作りました。

  • f``)``w等、カーソル位置周辺文字列を取得する必要のあるコマンドは、 基本的にTSF対応アプリでのみ動作します。
  • h``j``k``l等のコマンドはVK_LEFT等を送り付けているだけなので、 それ以外のアプリでも動作します。

以下のアプリでTSFの動作を確認しています。

  • Word 2010
  • Outlook 2010
  • WordPad
  • notepad

こだわった点

日本語向けWORD(W,E,B)

文節くらいの単位で移動・操作対象にできるようにするため、 漢字やカタカナの後の連続するひらがなまでをWORDとみなすようにしました。

nvi-m17nの処理を移植したものです。

例(tsf-vimのWORD):

Vim | は | 最もたくさんの | コンピュータ | /OS | で | 利用できる | テキストエディタです。

例(tsf-vimのword):

Vim | は | 最 | もたくさんの | コンピュータ | / | OS | で | 利用 | できる | テキストエディタ | です | 。

参考: Vim用日本語向けWORD対応プラグイン

日本語向けsentence()``()

文節よりも大きな単位で移動・操作対象にできるようにするため、 )``(で「。、」も文の終わりとみなすようにしました。

VimのKaoriya版パッチの処理を移植したものです。

他IME切り替え設定例(日本語入力用)

tsf-vimは、半/全キー等が押された時は、日本語入力用に、他IMEに切り替えます。

tsf-vimが他IMEに切り替える際に送り付けるキーは、 tsf-vimの設定ダイアログで指定可能です。 ここで指定したキー(Alt+Shiftを2回等)で、 日本語入力用のIMEに切り替えられるように、OS側の設定を行っておいてください。

例えば以下の使い方をするためには、下記の設定をします。

  • 通常はtsf-tutcodeを使用。

  • Ctrl+,でひらがなモードに

  • Ctrl+.でASCIIモードに

  • Ctrl+[でtsf-vimに切り替えてNormal modeに

  • tsf-vimで編集操作。

  • Ctrl+,でtsf-tutcodeに切り替えてひらがなモードに

  • Ctrl+.でtsf-tutcodeに切り替えてASCIIモードに

  • Ctrl+[でNormal modeに

  • OS側設定

  • 「インストールされているサービス」の順番はMS IME, tsf-tutcode, tsf-vim

  • 「キーボード レイアウトの切り替え」: 左 Alt+Shift

  • tsf-vim側設定

  • ホットキー(Normal mode): Ctrl+[ (0xDB)

  • ホットキー(他IME切替): Ctrl+, (0xBC)

  • ホットキー(他IME OFF切替): Ctrl+. (0xBE)

  • 他IME切替時送出キー(Windows 7の場合): Alt+Shift *2

  • 他IME切替時送出キー(Windows 8の場合): Win+Space *2

  • tsf-tutcode側設定(要tsf-tutcode-0.2.0以降)

  • キー設定(ON): Ctrl+, (0xBC)

  • キー設定(ON): 漢字 (0x19) (tsf-vimは他IME切替時に漢字キーを送り付け)

  • キー設定(OFF): Ctrl+/ (0xBF)

  • キー設定(ASCII): Ctrl+. (0xBE)

  • キー設定(ASCII): 英数 (0xF0) (tsf-vimは他IME OFF切替時に英数キーを送り付け)

  • キー設定(他IME切替): Ctrl+[ (0xDB)

改良の余地がある点

多数の未実装機能(text object, Visual mode, ., Exコマンド, /)

キーの送り付けでカーソル移動・編集している点

TSF非対応で、IMR_DOCUMENTFEEDによるカーソル周辺文字列取得にのみ対応している アプリ(Firefox等)でもある程度使えるように、 キーの送り付けでカーソル移動や編集を行うようにしています。

が、以下の課題があります。

  • 移動量や変更量が多いと、カーソル移動の完了まで待たされる場合がある。
  • yank後に選択されたままになるのはいまいち。

対策案: TSF対応アプリに関しては、TSFでのカーソル移動、文字列編集。

本来は行末まで対象なのに、単にVK_END等を送り付けている場合あり。

Add等。 まず動かすことを優先したので、簡易実装になっています。 jも現状はVK_DOWNを送り付けているだけなのでgj相当。

余談: tsf-vim作成の経緯

  • 数年前にUNIX用IMフレームワークuim向けに、 カーソル周辺文字列取得機能(surrounding text API)を使うIMをいくつか (uim-external-filter等) 作っている際に、Vimも作れるかもと思いつきました。
  • ただ、uimのsurrounding text APIにはカーソル移動が無く、 uimにも任意のキーの送り付け機能が無いので、当時は断念。
  • 後になって、xdotool等と同様にキーを送り付ける機能を プラグインとしてuimに追加すれば可能なことに気付きました。
  • 最近、tsf-tutcode (Windows用漢字直接入力IME)作成中に、 カーソル前文字列を取得・変換する処理を書いていて、 Vimも作れるかも、と再度思いついて半分ネタで作成開始。

関連

Vi風操作を実現するツール

参考にしたツール

  • KeyVi: 送り付けキー
  • wasavi: キーのハンドル処理の構成等の参考
  • Vim: 日本語のsentence移動
  • nvi-m17n: 日本語のWORD移動
  • CorvusSKK: IME動作
  • Mozc: TSFでの文字列取得

更新履歴

  • 2013-12-27
  • tsf-vim-0.1.0で、EscキーでNormal modeに戻れるようにしたので更新。
  • 2013-11-10
  • 新規作成。
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment