mini.aiで日本語の括弧の中身をrepeatableに編集する

by
カテゴリ:

本記事はVim駅伝2024-11-27の記事です。 274本目とのこと。凄いですね。前回の記事はgingkさんによる「Vim のプラグイン管理にパッケージ機能を使っている」でした。 Vim組込みの機能、膨大で使い込なせていないので、尊敬です。

さて本題。

mini.aiによるテキストオブジェクトの拡張の例として、過去の記事では、mini.aiを使ってaj[で「 foo 」のような日本語のカッコを選択する方法を紹介しました。

Neovimのテキストオブジェクトをカスタムできるmini.aiが便利 https://blog.atusy.net/2023/01/27/mini-ai-nvim/

しかし、当時の記事の方法ではdot-repeatできない弱点がありました。 mini.aiが開発方針として、j[などの2文字以上のキーワードの利用を禁止しています。これをなんとかするために、ajと入力したらgetcharstr()して追加で1文字受けとり、その内容に応じて利用する括弧を条件分岐していました。この対話的なインターフェースがdot-repeatを阻害していたようです。

日本語の括弧の中身の編集にdot-repeatが必要になる場面が少ないとは言え、地味にストレスでした。

というわけで、なんとかしたいと考えていたのですが、mini.aiに組込みのi?/a?というテキストオブジェクトを流用すればいいと気付きました。

i?は、テキストオブジェクトの左端と右端をユーザー入力で指定するテキストオブジェクトです。先のijと同様に対話的なテキストオブジェクトですが、mini.ai側の工夫により、dot-repeatに対応しています。

というわけで、以下のようにすれば、「foo」のような日本語の括弧に対応した編集が可能になります。事故が怖いので避けがちなremapの出番ですね。

vim.keymap.set({"x", "o"}, "ij[", "i?「<cr>」<cr>", { remap = true })
vim.keymap.set({"x", "o"}, "aj[", "a?「<cr>」<cr>", { remap = true })

同様に、<{なども設定しておくといいでしょう。

vim.keymap.set({"x", "o"}, "ij<", "i?<<cr>><cr>", { remap = true })
vim.keymap.set({"x", "o"}, "aj<", "a?<<cr>><cr>", { remap = true })
vim.keymap.set({"x", "o"}, "ij{", "i?{<cr>}<cr>", { remap = true })
vim.keymap.set({"x", "o"}, "aj{", "a?{<cr>}<cr>", { remap = true })

他にも]など閉じ括弧の場合は二重括弧にするなど、アイデアが広がりますね。

vim.keymap.set({"x", "o"}, "ij]", "i?『<cr>』<cr>", { remap = true })
vim.keymap.set({"x", "o"}, "aj]", "a?『<cr>』<cr>", { remap = true })

remapを避けがちでこの発想になかなか至れませんでしたが、macroを使っているときにふと閃きました。固定観念、うまく捨ててきたいですね。

ENJOY!