【入門編】Vimのテキストオブジェクトの限界を超える:treesitter-textobjectsで『関数スコープ単位』の爆速編集 – 軽量・高機能テキストエディタ生産性向上バイブル

Vimの「その先」へ:Tree-sitterで実現する、コード構造を操る「外科手術」のような編集術

こんにちは。エディタの深淵へようこそ。

あなたは今、Vimの標準機能である `iw` (inner word) や `ap` (a paragraph) を使いこなし、「Vimは速い」と実感している頃かもしれません。しかし、現実はどうでしょうか? 複雑な関数、入れ子になった条件分岐、あるいは巨大な引数リストを編集するとき、結局マウスに手を伸ばしたり、`jjjjj` とカーソル移動を繰り返して時間を浪費していませんか?

Vimの真の力は「テキスト」を編集することではなく、「コードという構文木」を操作することにあります。今日は、Tree-sitterという技術を使い、Vimを単なるテキストエディタから「コードを理解する知的なインターフェース」へと進化させる方法を伝授します。

—

1. なぜ「テキストオブジェクト」の限界を超える必要があるのか

標準のVimは、ファイルを「単なる文字の羅列」として扱います。`diw`(単語を削除)や `dap`(段落を削除)は便利ですが、これらは「空白や改行」で区切られた範囲を認識しているに過ぎません。

しかし、現代の開発において、我々が触れているのは「段落」ではなく「関数」「クラス」「引数リスト」といった論理構造です。

Tree-sitterを導入すると、エディタはソースコードを解析し、その場で「構文木(AST: Abstract Syntax Tree)」を構築します。これにより、Vimは「ここからここまでが関数の本体である」と正確に認識できるようになります。つまり、あなたが移動したいのは「次の行」ではなく「次の関数の開始位置」であり、削除したいのは「文字」ではなく「引数の一つ」なのです。

—

2. 準備:nvim-treesitterとtextobjectsのインストール

Neovimを使っているなら、まずは基礎となるライブラリを導入しましょう。ここでは `lazy.nvim` をプラグインマネージャーとして想定します。

— lua/plugins/treesitter.lua
return {
{
“nvim-treesitter/nvim-treesitter”,
build = “:TSUpdate”, — インストール時に構文解析器を最新化
config = function()
require(“nvim-treesitter.configs”).setup({
— 使用する言語のパーサーを自動インストール
ensure_installed = { “lua”, “python”, “javascript”, “typescript”, “rust” },
highlight = { enable = true }, — 高精度なシンタックスハイライト
})
end,
},
{
“nvim-treesitter/nvim-treesitter-textobjects”,
dependencies = { “nvim-treesitter/nvim-treesitter” },
config = function()
require(“nvim-treesitter.configs”).setup({
textobjects = {
select = {
enable = true,
lookahead = true, — 次の対象まで自動的にカーソルを飛ばす
keymaps = {
— 爆速リファクタリング用のキーマッピング
[“af”] = “@function.outer”, — 関数の外側(関数全体)
[“if”] = “@function.inner”, — 関数の内側(中身)
[“ac”] = “@class.outer”, — クラス全体
[“ic”] = “@class.inner”, — クラスの中身
[“aa”] = “@parameter.outer”, — 引数全体
[“ia”] = “@parameter.inner”, — 引数の中身
},
},
},
})
end,
},
}

—

3. 「HelloWorld」的な動作確認:構造を自在に操る

インストールが完了したら、適当なコードファイル(例えばPythonやTypeScript)を開いてみてください。

動作確認:関数の入れ替え(リファクタリング)

1. 適当な関数の中にカーソルを置きます。
2. ノーマルモードで `dif` (Delete Inner Function)と打ってみてください。

  • 結果: 関数の中身だけが綺麗に削除され、`{}` や `def …:` の構造が残ります。

3. 次に `daf` (Delete A Function)を試してください。

  • 結果: 関数全体がコードブロックごと消滅します。

これの何が凄いかというと、「インデントの深さを気にしなくていい」という点です。どれほど巨大な関数でも、`dif` 一発で中身を空っぽにできる。この精度は、標準の `d%`(対応する括弧まで削除)では決して得られないものです。

応用:引数の並び替え

`ia`(inner argument)を使えば、長い引数リストの一部を `vi a` で選択し、そのまま `p` で貼り付けるといった操作が可能です。コンマの区切り位置を気にする必要はもうありません。

—

4. なぜこの設定が「現場」で最強なのか

多くの初心者は、エディタの設定を「見た目」や「キーバインドの好み」だけで終わらせてしまいます。しかし、プロのアーキテクトは「認知負荷をどう減らすか」を考えます。

  • コンテキストスイッチの削減: Tree-sitterを使うと、「どこからどこまでが関数のスコープか」を脳内で計算する必要がなくなります。エディタが示してくれる構造に従うだけで、常に正しい範囲選択が行えます。
  • リファクタリングの高速化: コードを移動させる際、標準の移動コマンドではミスが起こりがちですが、Tree-sitterなら構造単位でカット&ペーストできるため、構文エラーを出す確率が劇的に下がります。

最後に:Vimはあなたの脳の拡張機能です

最初はキーを覚えるのが面倒に感じるかもしれません。しかし、この「構造を意識した編集」に慣れてしまうと、もはやマウスやカーソルキーを使う生活には戻れません。

今日設定した `af` や `if` は、あなたの指先に「コードを抽象的な構造として捉える感覚」を植え付けてくれます。毎日数千行のコードを読み書きするエンジニアにとって、このわずかな差が、1年後には数週間分の開発時間の短縮に繋がります。

まずは今日、既存のプロジェクトを一つ開いて、`dif` と `daf` だけでも試してみてください。その時、あなたのエディタはただのテキストエディタから、「コードを理解するパートナー」へと変貌を遂げているはずです。

それでは、素晴らしいVimライフを!

タイトルとURLをコピーしました