2025-11-25

Ruby のブロック記法 do~end と {} を切り替える Neovim プラグインを作った

ruby-block-toggle.nvim という Neovim プラグインを作りました。

できることはただ1つ...
Ruby のブロックの2種類ある書き方 do ~ end{} を切り替えることだけです。

ruby-block-toggle.nvim demo

ただ、上のデモのように単一行のブロック、複数行のブロック、ネストしたブロックなど、ブロックが使われる多くのケースには対応しているはずです。

また、実装レベルにおいても nvim-treesitter を使っており、AST からブロックの対応関係を判定しているため、変換の精度は安定していると思います。

モチベーション

AI エージェントがコードの多くを生成する時代となり、人は AI が生成したコードを読んで手直しするようなシーンが増えてきました。 私は最近は特に、Questal という Web アプリケーションを個人で新規開発していたため、開発中はそのようなシーンが多々ありました。

特にテストコードを拡充するシーンでAIには活躍してもらっていましたが、以下のような RSpec のコードを生成しがちでした。

expect do
  subject
end.to change ..

個人的には以下のように書きたいです。

expect { subject }.to change ..

他にも let を使うコードで以下のようなコードがよく生成されます。

let(:user) do
  create(:user, ...)
end

create(:user) に属性を多く指定して長くなるようなケースなら問題ないですが、特別な属性が不要なら1行にしたほうがスッキリします。

let(:user) { create(:user) }

これらは好みの問題といえばそれまでですが、個人プロジェクトでそういうところにこだわらずしてどうする?と、私は思いました。

また、これらのコードは RuboCop でも違反扱いはならないので手動で直すことになりますが、Neovim を持ってしてもサクッとは修正ができず地味に面倒でした。

解決策としてのプラグイン

最初のコード例の場合、ruby-block-toggle.nvim を使ってブロックを切り替えたあとに Shift + j を2回押すだけで望み通りの結果を得られます。

ruby-block-toggle-demo2

実際には :RubyBlockToggle というコマンドを打つのが面倒なので、私の場合は <leader>rb で変換をできるようにしています。合計5キーのタイプです。

このあたりは個人のキーマップの好みが出てくるところだと思うので、お好みで設定していけばよいでしょう。

おわりに

このプラグインを作っている中で、LLM の Neovim プラグイン開発のクオリティの高さに驚きました。 また、今さらではありますが、プラグイン開発における nvim-treesitter の可能性を改めて感じた経験でした。

実は Treesitter を使ってブロックの対応関係を特定するコアロジックは初期生成の状態に近いのですが、treesitter には興味が湧いたので後追いでインプットしようと考えています。

「Vibe Coding 駆動学習」という学習形式も悪くないかもしれません。

h3pei's icon

h3pei

フリーランスのソフトウェアエンジニア。Ruby / Rails アプリケーションの開発が得意領域。設計・実装・運用まで含めてプロダクト開発が好きです。

Questalという目標達成コミュニティサービスを開発しました。仲間と一緒に目標達成に取り組みたい方はぜひご利用ください。