Neovimプラグイン開発: snacks.nvimのpickerでskkeleton日本語入力を可能にする
snacks.nvimのpickerで日本語入力できるようにするプラグインを作った
はじめに
SKKは最高です。私はPC内の全ての入力でSKKを利用しています。
(SKKについては、↓のtoriwasaさんの記事が詳しいです。 私もSKK入門しようか悩んだ時に参考にさせていただきました)
エディタはNeovim愛用しているのですが、例に漏れず、skkeletonというSKK実装のプラグインを使っています。
最近、snacks.nvimというファインダー系のプラグインを使い始めたのですが、検索ウィンドウでSKKの日本語入力モードが起動できないという問題がありました。
良い機会だと思い、AIの恩恵を最大限受けつつ、今回始めて自分でプラグインを作ってみることにしました。
この記事では、自作したskkeleton-snacksプラグインについて紹介したいと思います。
問題の背景
snacks.nvimとは
snacks.nvimは、Neovimのための多機能ユーティリティプラグインです。ファイル検索、コマンド実行、ダッシュボード表示など、様々な機能を提供しています。特にpicker機能は、ファイル検索やgrepなどを行うための強力なインターフェースを提供します。
skkeletonとは
skkeletonは、Neovimで動作するSKK(Simple Kana to Kanji conversion program)の実装です。日本語入力をするための効率的な方法を提供します。
問題点
snacks.nvimのpickerは、通常のNeovimのバッファとは異なる特殊なフローティングウィンドウを使用しています。このウィンドウでは、skkeletonによる日本語入力が正常に機能しません。
具体的には、以下のような問題がありました:
- pickerのinputウィンドウでskkeletonのトグルキー(
<C-j>
)が機能しない - skkeletonの設定がpickerのウィンドウに適用されない
解決策:skkeleton-snacksプラグイン
この問題を解決するために、skkeleton-snacksというプラグインを開発しました。
プラグインの基本的な仕組み
このプラグインは、以下の方法で問題を解決します:
- snacks.nvimのpickerのフローティングウィンドウを検出する
- 検出したウィンドウのバッファに対して、skkeletonを有効にする設定を適用する
- バッファローカルなキーマッピングを設定して、skkeletonのトグルキーを機能させる
実装の詳細
プラグインの核となる部分は、フローティングウィンドウを検出して、そのウィンドウでskkeletonを有効にする処理です。
-- snacks の picker の input ウィンドウが開かれたときに実行される関数
local function enable_skkeleton_in_snacks()
-- バッファのタイプやウィンドウの特性を確認
local buf = vim.api.nvim_get_current_buf()
local win = vim.api.nvim_get_current_win()
-- snacks の picker の input ウィンドウかどうかを確認
-- ウィンドウの名前や特性で判断
local win_config = vim.api.nvim_win_get_config(win)
if win_config.relative ~= "" then -- フローティングウィンドウの場合
-- skkeleton プラグインが利用可能かどうかを確認
local has_skkeleton = pcall(function() return vim.fn["skkeleton#is_enabled"] end)
if not has_skkeleton then
if M.config.debug then
vim.notify("skkeleton is not available, skipping", vim.log.levels.DEBUG)
end
return
end
-- バッファローカルなキーマッピングを設定
vim.api.nvim_buf_set_keymap(buf, "i", M.config.toggle_key, "<Plug>(skkeleton-toggle)", { silent = true, noremap = false })
-- skkeleton を有効にする
vim.b[buf].skkeleton = true
-- デバッグ用のメッセージ
if M.config.debug then
vim.notify("skkeleton enabled in snacks picker", vim.log.levels.INFO)
end
end
end
この関数を、以下のイベントで実行するように設定しています:
-- WinEnter イベントで自動コマンドを設定
vim.api.nvim_create_autocmd("WinEnter", {
group = group,
callback = enable_skkeleton_in_snacks,
})
-- BufEnter イベントでも自動コマンドを設定
vim.api.nvim_create_autocmd("BufEnter", {
group = group,
callback = enable_skkeleton_in_snacks,
})
-- 特にフローティングウィンドウが作成されたときのイベント
vim.api.nvim_create_autocmd("WinNew", {
group = group,
callback = function()
-- 少し遅延させて実行
vim.defer_fn(enable_skkeleton_in_snacks, 10)
end,
})
開発中に遭遇した問題と解決策
問題1: プラグインの読み込み順序
最初の実装では、プラグインの初期化時に依存関係(skkeleton、snacks.nvim)をチェックしていました。しかし、プラグインマネージャー(lazy.nvim)の読み込み順序によっては、依存プラグインが読み込まれる前にskkeleton-snacksが初期化されることがありました。
これにより、「skkeleton is not available」というエラーが表示されることがありました。
解決策1: 遅延初期化と動的チェック
この問題を解決するために、以下の変更を行いました:
- プラグインの読み込みを遅延させる(
event = "VeryLazy"
) - 依存関係のチェックを初期化時ではなく、実際に機能が必要になったときに行う
- エラーメッセージの代わりに静かにスキップする処理に変更
問題2: キーマッピングの競合
最初の実装では、pickerのinputウィンドウで<C-j>
キーを押すと、pickerが閉じられてしまう問題がありました。これは、snacks.nvimの既存のキーマッピングと競合していたためです。
解決策2: バッファローカルなキーマッピング
この問題を解決するために、バッファローカルなキーマッピングを使用しました。これにより、特定のバッファ(pickerのinputウィンドウ)でのみキーマッピングが有効になり、他のキーマッピングと競合しなくなりました。
プラグインについて
インストール方法は README をご確認ください。
まとめ
skkeleton-snacksプラグインを作成することで、snacks.nvimのpickerでもskkeleton日本語入力を使用できるようになりました。これにより、Neovimでの日本語環境がより快適になりました。
同じ悩みを抱えている方の役に立てれば嬉しいです。
Discussion