garypippi.net

NeovimバックエンドのWayland用オレオレIMEを作ってみた

2026/03/13 06:56#Neovim#Rust

作ってみたもの。
https://github.com/garypippi/jacin

きっかけ

普段、Gentoo+Hyprland+Neovim+Skkeleton環境で過ごしています。
日本語入力環境の構築が面倒なので、ここ2~3年はNeovimをメモ用に起動するスクリプトでコピペ運用していました。
それでもやや面倒ではあるので、流行りのAIならNeovimバックエンドで自作IMEを作れるのではないかと思いClaude Codeさんと一緒にやってみました。

初期実装

ChatGPTでWaylandプロトコルのみ対応する事で比較的簡単に実装が可能かどうかを探り、ChatGPTに作ってもらった実装方針をClaude Codeに投げると数分で起動コマンドの実行まで進みました。

ただ、この時点ではガチャガチャ入力していると頻繁にハングするし、なんかすごく動作が遅い状態でした。
しかもハングするとキー入力が全て取られます。

skkeleton,nvim-cmpの依存はが

初期段階では、「skkeleton + nvim-cmp」を前提にしており、skkeletonとnvim-cmpのイベントや関数を直接触っている状態でした。
これをTextChanged/CompleteChanged等のautocmdにフックするようにして両者の依存を落とし、今後の実装方針について見通しを立てやすくする作戦にしました。

ここからひたすら「動作確認」「修正」のループに入ります。

Neovimとの融合

最初まったく考えもしてなかったですが、そもそもNeovim側でも様々な状態があり、その管理が大変です。
operator-pending,register-pending等の次の入力を待つ状態、コマンドモード、input()での@モード等、それぞれに対応するのが現実的ではなくなってきた段階でnvim_attachを部分的に導入しました。

これで@モードにも一応対応できました。
でも使い道は無いかもしれない...

今後の課題

一旦実装は落ち着きましたが、ちまちまやっていきたいです。

一行編集の

IMEの「一行編集」という性質上、縦方向の編集が得意なNeovimとの融合が難しいです。
むりやり複数行編集にすると普通にNeovimを立ち上げてコピペした方が良い、みたいなことになりますし、悩み中。
また、「一行編集」でNeovimを縛るとNeovimの良さがほぼ発揮できません。

ハイライト

現状、visualモードで明示的に範囲選択した場合のみトラッキングしてpreedit表示領域でハイライトしていますが、検索結果などのハイライトは対応できていません。
これをやろうとするとnvim_attachでext_hlstate/ext_linegridも使用しないといけないですが、一気に扱う情報量が膨大になるためいまはやってません。

おまけ

ポップアップウィンドウ上でスクロールするとHyprlandがセグフォする事象が発生していました。
Claude CodeにHyprland本体のコードを調べさせたところすぐに原因を見つけてくれたので、修正PR出したらマージされました。
https://github.com/hyprwm/Hyprland/pull/13255