Vim駅伝の2024/6/21の記事です。
SKKは快適な日本語入力を実現する素敵なインプットメソッドです。
WindowsやmacOSなどOS本体向けの実装もあるのですが、Vim向けにもskkeletonやtusskといった実装があります。
そして各種実装のルーツはemacsのddskkです。
私はNeovimでskkeletonを使っていますが、ddskkの接頭辞・接尾辞変換機能1がないことに長らくもどかしさを感じていました。
接頭辞・接尾辞は、たとえば「第三部」の「第」や「部」にあたる部分ですね。
フツーのIMEであれば「だいさんじゅうぶ」を丸ごと変換すれば、よしなにしてくれますが、SKKの場合は辞書に登録している範囲で適宜分割して入力・変換していく必要があります。
Dai_Sanjuu_Bu_
(_はスペースに相当)
ただし、「Dai」は代第台大題……とたくさん候補がありますし、「Bu」も部分武不……とやはり沢山の候補があります。
接頭辞・接尾辞変換は、>
を使って変換対象が接頭辞または接尾辞であることを明示することで、変換候補を絞り込む機能です。
Dai>Sanjuu_>Bu_
(_はスペースに相当)
こんな感じにすると、「Dai>」は接頭辞なので第や大が候補になりますが、題などは候補から外されます。
同様に「>Bu」は接尾辞なので、部や歩が候補になりますが、武などは候補から外されます。
なんて便利!
実際使ってみるとこんな感じ。
実装にあたってはddskkのドキュメントと、fcitx-skkの挙動を参考にしました。
接頭辞や接尾辞の変換候補は辞書の中で>
を使って明示されているので、とても扱いやすいです(https://ddskk.readthedocs.io/ja/latest/06_apps.html#id35)。
ちょう> /超/
>し /氏/
というわけでやるべきことは主に3つです。
>
の位置で接頭辞・接尾辞の変換開始を判定する- 変換中の
>
の表示を既存実装に合わせる- 今回はfcitx-skkに合わせて非表示とした
- 接尾辞・接頭辞変換の確定結果から
>
を取り除く
とても簡単そうですね。
実際には、この実装をユーザーが使えるインターフェースに落としこむ(>
にマッピングする)必要があり、そこでskkeletonの設計を理解する必要があります。
そこが一番大変だったかな?
PR上では、最初は接頭辞と接尾辞をひとまとめにしていました。
しかし、接頭辞はInputState
(変換対象の入力中)に>
を入力することで発動するのに対し、接尾辞はHenkanState
(入力した文字の変換中)に>
を入力することで、変換を確定させてから接尾辞の入力を開始するもので、実態が大きく異なります。InputState
に関連する関数はfunction/input.ts
に、HenkanState
に関連する関数はfunction/henkan.ts
に入っていたので、ひとまとめにすべきではないよね、ということで、後から分割しました。
その様子はコミットログから追って頂けるのではないかなと思います。
skkeletonはTypeScriptで実装されているおかげでコードが追いやすく、開発体験がよかったです。
型システムにもLSPにも感謝ですね。
そうそう、今回の開発で接頭辞と接尾辞をまとめて扱う言葉ってなんだろう……?となったのですが、ChatGPTに問い合わせて “affix” という単語を教えてもらいました。
検証しやすい場面でLLMは大活躍しますね。
ENJOY!