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

by
カテゴリ:
タグ:

Neovimユーザーの多くが、シンタックスハイライトにTreesitterを利用していると思います。

このとき、nvim-treesitterプラグインを使って様々な言語に対応するケースがほとんどだと思います。

従来、nvim-treesitterプラグインの開発はmasterブランチで進んでいましたが、Neovim 0.11のリリースに伴ってmasterブランチは凍結され、現在はmainブランチで開発を継続しています。

公式ではNeovim 0.11がでたらデフォルトブランチをmainブランチに変更するとしています。その割にmasterブランチがデフォルトのままですが、2025-05-24で更新が止まっているので、早々にmainブランチに切り替えたほうがいいでしょう。

after Neovim 0.11 is released with wasm support, main will become the new default branch
https://github.com/nvim-treesitter/nvim-treesitter/issues/4767

ただし、mainブランチの内容はmasterブランチと互換性がないため、切り替えには一手間必要です。

mainブランチの変更概要

mainブランチ版nvim-treesitterは、基本的にパーサーとクエリファイルの管理を目的にしていると考えるといいです。

masterブランチ版は自動ハイライトやインデント、拡張機能の管理などと盛り盛りでしたが、mainブランチでは相当の機能が削られています。

  • highlightの自動適用廃止
    • 代わりにユーザー側でvim.treesitter.start()をバッファ単位に実行する
  • setup関数のindent有効化オプション廃止
    • 代わりにユーザー側でオプションを指定する
      • vim.bo.indentexpr = "v:lua.require'nvim-treesitter'.indentexpr()"
  • incremental-selection廃止
    • 文法を鑑みながら徐々に選択範囲を広げたり狭めたりする機能
    • 欲しい人はプラグイン作ってねとのこと
  • 自動インストール機能廃止
    • 代わりにユーザー側で必要なパーサーを:TSInstallでインストール
    • これに伴い、カスタムパーサー(nvim-treesitterで管理していないパーサー)のインストール方法も変更
  • モジュール機構廃止
    • 従来、nvim-treesitterに依存するプラグインの中にはnvim-treesitter.configs.setup関数を使って、拡張機能を登録しているものがあった
    • mainブランチではnvim-treesitter.configsモジュール自体がなくなった

特にモジュール機構廃止は、他の様々なプラグインに影響があるので、切り替え作業の障壁になりがちですね。

このあたりもふまえつつ、切り替え手順を紹介できればと思います。

mainブランチ切り替え大作戦

nvim-treesitterプラグインのブランチ切り替え

多くのプラグインマネージャーはブランチの指定をサポートしています。

lazy.nvimを使う場合は以下のようにbranchキーを生やすといいでしょう。

{
  "https://github.com/nvim-treesitter/nvim-treesitter",
  branch = "main",
}

この状態で:Lazy syncなどしてプラグインを更新してから:restartすると、大量のエラーが出るかもしれません。これはnvim-treesitterの破壊的変更に伴って、nvim-treesitterの設定そのものや他のプラグインがmasterブランチに依存しているせいでしょう。いったん、他のプラグインについてはcond = falseなどを指定して無効化するといいです。

なお、リポジトリ指定に"nvim-treesitter/nvim-treesitter"ではなく、フルのURLを指定しているのは趣味です。

こうしておくと、gxコマンドを使ってブラウザを開いたり、GitHub上でダブルクリックできたりして便利です。

関連記事もあるので、よければ見てみてください。

プラグインをURLで指定しやすくするために、tree-sitterでURIパーサーを作ってNeovimを彩ってみた
https://blog.atusy.net/2023/11/17/tree-sitter-uri/

nvim-treesitterプラグインの設定更新

自動ハイライトを目指す

やるべきことは以下の3点です

  • nvim-treesitterの有効化
  • ハイライトの自動化
  • パーサー・クエリのインストール

nvim-treesitterを有効化するには、単にsetup関数を呼べばOKです。オプションはinstall_dirしかないので、ほとんどのユーザーは何も考える必要がありません。

require("nvim-treesitter").setup({})

ただし、先述の通り、有効化しただけではシンタックスハイライトが効きません。以下のようにFileTypeイベントをトリガーにした自動コマンドを使って、vim.treesitter.start関数を実行してください。

vim.api.nvim_create_autocmd("FileType", {
  group = vim.api.nvim_create_augroup("vim-treesitter-start", {}),
  callback = function(ctx)
    -- 必要に応じて`ctx.match`に入っているファイルタイプの値に応じて挙動を制御
    -- `pcall`でエラーを無視することでパーサーやクエリがあるか気にしなくてすむ
    pcall(vim.treesitter.start)
  end,
})

もし、[nvim-treestter]プラグインを遅延ロードしている場合は、vim.treesitter.start関数を呼ぶ前に手動読み込みするといいでしょう。 lazy.nvimユーザーであればpcal(require, "nvim-treesitter")を足せばOKです。

あとは:TSInstall! allなどして、必要なパーサーを一通り入れておきましょう。

もし、これでもハイライトに失敗する場合は、パーサーのインストール先を初期化して、再挑戦してみてください。 require('nvim-treesitter.config').get_install_dir()で取得できるディレクトリを削除すればOKです。

カスタムパーサーを導入する

マイナーな言語などの場合、nvim-treesitterで管理していないパーサーを導入する必要があります。従来はnvim-treesitter.parsersモジュールにパーサー情報を追加すれば、インストール可能でしたが、軽く試した感じでは一筋縄でいかなさそうです。

代替案として、lazy.nvimを使ってパーサーそのものをプラグインとして扱う手を紹介します。

この方法ではnvim-treesitterによるパーサーのインストール先をあらかじめ指定しておきます。そして、カスタムパーサーのビルド時にパーサーの置き場所としてnvim-treesitterのパーサーのインストール先を指定します。加えてクエリファイルのインストールなども必要ですが、masterブランチの時点である程度経験のあるユーザーを想定するため、ここでは省略します。

local treesitter_path = vim.fs.joinpath(vim.fn.stdpath("data"), "/treesitter")
vim.uv.fs_mkdir(parser_dir, tonumber("755", 8))

return {
  {
    "https://github.com/nvim-treesitter/nvim-treesitter",
    branch = "main",
    config = function()
      -- パーサーのインストール先を指定
      require("nvim-treesitter").setup({ install_dir = treesitter_path })

      -- 自動ハイライトの有効化
      vim.api.nvim_create_autocmd("FileType", {
        group = vim.api.nvim_create_augroup("vim-treesitter-start", {}),
        callback = function()
          pcall(vim.treesitter.start)
        end,
      })
    end
  },
  {
    "https://github.com/monaqa/tree-sitter-unifieddiff",
    build = function(opts)
      -- nvim-treesitterと同じ場所にパーサーをインストール
      local output = vim.fs.joinpath(parser_path, "unifieddiff.so")
      vim.system({ "tree-sitter", "build", "--output", output }, { cwd = opts.dir }, function() end)
    end
  }
}

依存プラグインの更新

メモ書き程度ですが、Atusyが利用しているプラグインのうち、nvim-treesitterのmainブランチ対応作業について、記録しておきます。

nvim-treesitter-endwise

一部の言語では関数定義やif文などの末尾にendfiが必要です。このプラグインを使うと、これらのキーワードを改行のタイミングで自動挿入してくれます。

-- lua
local function f() -- ここで改行すると自動でendが挿入される

本家のRRethy版はnvim-treesitterのmainブランチに未対応なので、AbaoFromCUG版を使うといいでしょう。

従来はrequire("nvim-treesitteer.config").setup関数経由で有効化していましたが、プラグイン本体側で有効化するように設定を変更してください。

require("nvim-treesitter-endwise").init()

vim-matchup

https://github.com/andymass/vim-matchup

%キーで対応する括弧にジャンプする機能を提供するプラグインです。 treesitterとの連携を使うと、引用符やHTMLタグなどの対応する箇所にもジャンプできるようになります。

従来はrequire("nvim-treesitter.configs").setup関数経由で設定していましたが、mainブランチではグローバル変数を使うように変更されています。

vim.g.matchup_matchparen_offscreen = { method = "status_manual" }
vim.g.matchup_treesitter_enable_quotes = true
vim.g.matchup_treesitter_disable_virtual_text = true
vim.g.matchup_treesitter_include_match_words = true

nvim-treesitter-textobjects

https://github.com/nvim-treesitter/nvim-treesitter-textobjects/

言語の構文を利用したテキストオブジェクトを提供するプラグインです。関数のボディを選択するなどといった操作が可能になります。

このプラグインはnvim-treesitterのmainブランチに対応するにあたって、同様にmainブランチ版を用意したようです。ただし、なぜかmasterブランチ版の方が更新が活発な模様……。

ちょっと不穏ではありますが、mainブランチ版を使ってみています。

また、Atusy自身はmini.aiの依存プラグインとして使用しており、nvim-treesitter-textobjectsを直接使っていないため、実際にsetupしたときにまともに使えるかまでは検証していません。

nvim-treesitter-context

https://github.com/nvim-treesitter/nvim-treesitter-context

VSCodeでいうSticky scroll相当の機能を提供するプラグインです。実際の様子はリポジトリのREADMEを参照してください。 > nvim-treesitter-context

特に設定の変更なくnvim-treesitterのmainブランチ対応ができます。

nvim-treesitter-refactor

https://github.com/nvim-treesitter/nvim-treesitter-refactor

変数のrename機能が便利そうと思って入れたプラグインです。

残念ながらnvim-treesitter-refactorは現時点でmainブランチ対応していません。主要な言語であればLanguage Server Protocol(LSP)のrename機能の方が優秀なので、いったん無効化することにしました。

ENJOY

ややざっくり目ですが、nvim-treesitterのmainブランチへの移行方法を紹介しました。少しでも皆さんの設定更新の助けになれば幸いです。