nvim-treesitterのmainブランチ移行

Vim駅伝

この記事はVim駅伝の2025-08-13向けの記事です。
前回の記事はmitsu-yukiさんの『Vimへコピぺする時に置き換え元の文字でクリップボードを上書きしないいくつかの方法』です。

始めに

執筆時現在(2025-08-13)、nvim-treesitterのGitHub上のデフォルトブランチはmasterになっていますが、今後はmainブランチに移行するようです。

masterブランチのREADMEより

The master branch is frozen and provided for backward compatibility only. All future updates happen on the main branch, which will become the default branch in the future.

マスターブランチは凍結されており、後方互換性のみを提供しています。 今後のアップデートはすべてmainブランチで行われ、将来的にはデフォルトブランチになります。

このアナウンス自体は2025-05-24にはアナウンスされています。
アナウンス自体は別の経路でも確認はしていましたが、nvim-treesitterの移行に対応できていないプラグインもあったので、移行作業は見送っていました。

時期を置いてあらためて確認したところ、移行できそうな雰囲気を感じたのと、最近vimの設定を育てられていないと思っていたので、リハビリがてら移行作業の内容を垂れ流そうと思います。

同様の事例として、参考記事として次の記事も読むと、より理解が深まります。

Neovim ≧ 0.11ユーザーのためのnvim-treesitter最新版利用ガイド(mainブランチ切り替え)

自分が使用している関連プラグイン

私が使用しているnvim-treesitter関連のプラグインは以下の通りです。

nvim-treesitter本体とtextobjectsを増やしてくれるプラグインはmainブランチに移行してきます。
どちらもnvim-treesitterのorganizationで管理されている物ですので、参照するブランチをmasterからmainに変更すると対応するドキュメントを確認できます。

nvim-yatiに関しては、サードパーティ製のプラグインであり、main移行に対応できていない状態です。
このプラグイン自体は、nvim-treesitterのインデント計算に不満があったころに開発された物のため、最新で不満がなければ使用しなくても大丈夫と書いてあります。
また、このプラグイン自体の更新が1年前で停止していることもあり、今回の作業では削除しました。

主な変更点

masterからmainの変更内容はかなりドラスティックではありますが、どれも納得の行く内容だと思いました。
ただ同時に、どうして「そうなっていなかった…」と思うほど整理されて、個人的には「とても行儀が良いプラグインになった」という感想です。

依存関係の変更

masterから以下の依存関係が追加されます。

  • tree-sitter本体
  • Nodeの最新版
  • Neovim v0.11.0以上のバージョン

そのほかは変わらず、CCompilerやtarcurlは必須となっています。

Nodeも必須にはなっていますが、使うことが無さそうな言語1のため、なくても問題ないと思います。

tree-sitter本体に関しては、各言語のパーサをインストールするために必須となっています。

共通IFの廃止

個人的に一番うれしかった変更で、require("nvim-treesitter.configs").setup()というIFが廃止になりました。
このIFの悪いところとして、マスタとなる設定の定義はnvim-treesitter本体に存在するが、別のプラグインとしてnvim-treesitterの機能を使うために、設定を拡張するようになっていました。
今回の移行に関連するプラグイン達は同じようなIFになっており、nvim-yatiに関してはrequire("nvim-treesitter.configs").setup()のIFのままだったため、移行せず削除するという対応になりました。

自動起動によるtreesitterの解析を廃止

これも個人的にうれしい変更で、masterではrequire("nvim-treesitter.configs").setup()呼び出し以降、すべてのFileTypeに対してtreesitterの利用を半強制されていました。
無効にする方法はありますが、少々面倒な手続きをsetup内に記述する必要がありました。

後述しますが、treesitterを利用するFileTypeは明示することが可能になりました。

実際に移行していく

主な変更点を確認できたところで、実際に移行作業をやっていきます。

移行作業中にrequire("nvim-treesitter.configs").setupを呼び出す度に、そんなフィールドは存在しないというエラーが発生するので、 まずは過去の設定をコメントアウトしてから、新しい設定に移植してくのが良いでしょう。

nvim-treesitter

-require("nvim-treesitter.configs").setup({
-  -- 中略
-})
+require("nvim-treesitter").setup({
+  install_dir = vim.fs.joinpath(vim.fn.stdpath("data"), "site"),
+})

masterまではsetup関数内に大量の項目を設定するようになっていましたが、mainにおいて設定項目はinstall_dirしかありません。
現状の設定項目自体もデフォルトの値を設定しているだけですが、私は明示的に設定しています。

setup関数呼び出し後、パーサのインストールが可能になります。

require("nvim-treesitter").install({
  "bash",
  "markdown",
  "kotlin",
  --[[
    この辺に使う言語を列挙していってください。
    @see https://github.com/nvim-treesitter/nvim-treesitter/blob/main/SUPPORTED_LANGUAGES.md
  ]]
}, {
  force = false, -- force installation of already installed parsers
  generate = true, -- generate `parser.c` from `grammar.json` or `grammar.js` before compiling.
  max_jobs = 4, -- limit parallel tasks (useful in combination with {generate} on memory-limited systems).
  summary = false, -- print summary of successful and total operations for multiple languages.
} --[[@as InstallOptions]])

install関数の呼び出しによって、パーサのインストールが始まりますが、インストール先はsetup関数内で設定したinstall_dirに以下のようなディレクトリ構成でパーサがインストールされます。

~/.local/share/nvim/site
├── parser/
│   └── *.so
├── parser-info/
│   └── *.revision
└── queries/
    └── */ nvim-treesitter内の`runtime/queries`からのsymlink
        ├── folds.scm
        ├── highlights.scm
        ├── indents.scm
        ├── injections.scm
        └── locals.scm

queries内の物がnvim-treesitterの本体と言っても良いほど重要なデータであり、素敵なハイライト・インデント・折り畳みを提供するためのクエリ達です。
各言語毎にこれらのファイルがある訳ではないため、あくまで一例となります。
nvim-treesitterとしてどこまでサポートされているかは、SUPPORT_LANGUAGES.mdを参照してください。

ちなみにtree-sitter本体をインストールしておかないと、インストール処理だけが始まったように見えて、完了しない現象が発生します。
私はtree-sitter本体のインストールを忘れて、小一時間ほど悩んでいました。

また、これまでsetup関数で有効化していたハイライト・インデント・折り畳みはどのように設定するかと言うと、以下のような記述が必要です。

vim.api.nvim_create_autocmd({ "FileType" }, {
  pattern = {"bash", "markdown", "kotlin"},
  callback = function()
    -- syntax highlighting, provided by Neovim
    vim.treesitter.start()
    -- folds, provided by Neovim
    vim.wo.foldexpr = "v:lua.vim.treesitter.foldexpr()"
    -- indentation, provided by nvim-treesitter
    vim.bo.indentexpr = "v:lua.require'nvim-treesitter'.indentexpr()"
  end,
})

ーー お分かりいただけただろうか?

これまで明示せずとも、勝手にtreesitterが各FileTypeで適応されていたのが、特定のFileTypeにだけ適応されるようになったのです!
これはもしや、『設定させていただきありがとうございます』の精神をNeovim本体も理解しだしたように見えないでしょうか?

今回の例ではbashを開いたときはtreesitterが有効になりますが、同じようなsyntaxをしているshzshでもtreesitterが有効になってほしいというパターンがあると思います。
その場合、autocmdpatternにFileTypeを追加するだけでなく、以下のような宣言も追加で必要になります。

vim.treesitter.language.register("bash", { "sh", "zsh" })

これにより、bashのクエリを使ってshzshも同じようにハイライトするという振る舞いに変わります。

:h vim.treesitter.language.register()
register({lang}, {filetype})              *vim.treesitter.language.register()*
    Register a parser named {lang} to be used for {filetype}(s).

    Note: this adds or overrides the mapping for {filetype}, any existing
    mappings from other filetypes to {lang} will be preserved.

    Parameters: ~
      • {lang}      (`string`) Name of parser
      • {filetype}  (`string|string[]`) Filetype(s) to associate with lang

ここで気がついてほしいのは、nvim-treesitterというプラグインの役割はパーサの管理とクエリ集になっているのです。
パーサの管理自体は別にすることだって事実上可能ではないでしょうか?

nvim-treesitter-textobjects

-require("nvim-treesitter.configs").setup({
-  textobjects = {
-    -- 中略
-  }
-})
+require("nvim-treesitter-textobjects").setup({
+  select = { --[[中略]] }
+  move = { --[[中略]] }
+})

textobjectsの方もnvim-treesitter.configsの拡張から独自のsetup関数に設定を記述するようになっています。
ほかにもmasterではsetup関数内でキーマップの独自DSLが組み込まれていましたが、mainでは各textobjectsの振る舞いの設定のみを宣言し、 実際のキーマップの設定は公開されているAPIを呼び出す形に変わっています。

これは明らかに、『設定させていただきありがとうございます』の精神を(ry。

こちらのキーマップ設定に関しては、好みの問題もあるため、公式のドキュメントを読みながらvim.keymap.setを呼び出しを列挙したら良いと思います。

https://github.com/yasunori0418/dotfiles/blob/b9c9122b6e2a47cb47b0703fa8b2ce67fcb32085/home/.config/nvim/hooks/ts_textobjects.lua

参考例として、私の設定のリンクを置いておきます。

まとめ

今回の大きな変更ですが、とてもシンプルになり余計なことをしなくなって変更としては大満足です。 やはり、『設定させていただきありがとうございます』の精神を本体側は理解しだしたと私は考察します。

久々のvimの設定リハビリとしてもちょうど良いと思いました。


  1. scfgというFileTypeに対応するらしい。設定言語っぽいが知らべても使われている物が見つからなかった。 ↩︎

Licensed under CC BY-NC-SA 4.0
最終更新 2025-08-15T10:52:49
Hugo で構築されています。
テーマ StackJimmy によって設計されています。