これは Vim Advent Calendar 2015 の9日目の記事です。
はい、タイトルは盛りました。正直﹁実装﹂と言えるほどのものではないので最初に謝っておきます。すみませんすみません。
サクラエディタ (以下サクラ) というのは Windows 用のテキストエディタなんですが、とある事情でこのエディタを Vim ライクなキーバインドで使えるようにしたことがありました。これはその時の思い出話になります。
Powered by 悪循環画像ジェネレータ
どうにかしてサクラを Vim のキーバインドで作業できるようにしたい。私は模索を始めました。
自己紹介
当時、私はとある零細下請け SIer で働くシステムエンジニアでした。回ってくるのは客先常駐の堅い現場ばかり。ネットに繋がっていないPCで作業することが殆どでした。サクラエディタとは
サクラエディタ サクラエディタはMSWindows上で動作する日本語テキストエディタです. 行く先々の現場では必ずと言っていいほどサクラが使われていて、私もほとんどのショートカットキーを覚えるほど使い込みました。特に気に入っていたのは正規表現ライブラリが付属している点で、テキストの整形なんかはコマンドラインよりサクラでやることが多かったです。 そんなふうに永らくサクラユーザだった私は、ある日たまたま読んだ記事でとあるエディタと運命的な出会いを果たします。Vim との出会い
そう、 Vim です。たしか 2012 年くらいだったと思います。もともと Solaris のviを仕事で使っていたことがあったので、モードの概念や特徴的なキーバインドに抵抗はありませんでした。ちょうど、珍しくネットを使える現場に配属されたところだったので仕事でも Vim を使うようになりました。私はすぐにその強力なエディタの虜になりました。Vim との別れ
そんな幸せな時間もつかの間、またネットのない現場に異動させられてしまいました。用意されていたのは当然サクラエディタ。まぁ、何とかなるだろうとその時は思っていました。私はヘビーな Vim ユーザではなかったからです。一応自分の vimrc はありますが、キーバインドはデフォルトを崩さない派ですし、入れているプラグインの数も多くありません。以前使っていたエディタに戻るだけじゃないか。そんな風に考えていました。 ... ダメだ ...! カーソル移動ひとつとってもホームポジションを離れなければいけませんでした。耐えられない。Vim でなければ満足できない。もはや私は Vim 依存症だったのです。![f:id:tchssk:20151209202759p:plain f:id:tchssk:20151209202759p:plain](https://cdn-ak.f.st-hatena.com/images/fotolife/t/tchssk/20151209/20151209202759.png)
サクラの仕様調査
サクラにはキーバインド設定のインポート / エクスポート機能があります。 Vim のモード毎に設定ファイルを作って切り替えれば擬似的にモードを再現できると思いましたが、設定ダイアログからしかインポートができないことがわかり、この方法はボツに。 次に思いついたのはマクロを使う方法。サクラのマクロ機能ではサクラ独自記法の他に、 Windows Script Host (VBScript や JScript) が利用可能です。そして特定のキーが押された時にマクロを実行するよう設定することができます。これを使えば何とかできるかもしれない。 謎のモチベーションと勢いでコードを書き続け、半日ほどで何となく動くものができました。サクラ上に Vim を実装する
Vim の特徴のひとつにモードがあります。これを再現できなければ話になりません。しかしサクラのマクロ (というより VBS) には、スクリプトをまたいで使いまわせるグローバルな変数などありません。どうやってエディタ上に状態を保持させるか。 これは制御用のファイルを作ることで解決しました。処理は以下の流れです。 (一)あるキーが押される (二)キーに割り当てられたマクロ (VBS) が実行される (三)マクロが制御ファイルから現在のモードを判定 (四)マクロがモードに応じた処理を実行 制御ファイルは 0 バイトファイルです。状態はファイル名に持たせていました。なのでモードが変わるたびにファイル名も変わります。Setfs= CreateObject("Scripting.FileSystemObject") For EachfInfs.GetFolder("..").Files If InStr(1,f.Name, "mode") = 1 Then Select Case Replace(f.Name, "mode=", "") Case "n" Editor.Rightf.Name = "mode=i" Case "i" Editor.InsText("a") End Select Exit For End If Nextこれは当時を思い出しながら書いてみたコードです。
InStr()
で判定しているように、制御ファイルは mode=
で始まるファイル名となっています。mode=
のあとはモードによって書き換わるようになっています。ノーマルモードは n
、挿入モードは i
というように決めて、 Select Case
の分岐でモードに応じた処理がされるようにしていました。
その後
コツコツと機能を追加して、ビジュアルモードなども使えるようにしました。半年ほどしてその現場を離れることになり、少し名残惜しさもありましたがコードはすべて削除しました。ネットが使えないので持ち出すことはできないですし、そもそもネットが使えたら書くこともなかったコードです。あれはそういう蜃気楼のようなコードだったのです。 ですが、上記のコードを書いたついでに一部分だけコードを再現してみました。 github.com/tchssk/sakura-vim 使えるのは以下のキーです。h左に移動j下に移動k下に移動l右に移動w次の単語に移動b前の単語に移動 gg 1 行目に移動xカーソル位置の文字を削除aカーソル位置の後に文字列を追加iカーソル位置の前に文字列を追加最初はもっと再現しようと思っていたのですが辛くなってきたのでやめました。こんなコードは必要に迫られなければ書けたものではありません。 ちなみに今は Web な会社に転職して﹁本物の﹂ Vim で毎日Goを書いています。Go楽しいです。 おわり。