以前書いた記事ではnvim-treesitterのブランチをmasterにしていたのでmainに移行したらハイライトが効かなくなったその黙示録
結果はタイトルの通りハイライトが有効にできませんでした。
構文解析は完璧に動作し、UEマクロがエラーとして扱われることはなくなったものの、肝心のシンタックスハイライト(色付け)を有効にすることはできませんでした。
この記事は、ハイライトを有効にするために行った、考えうるほぼすべてのデバッグの軌跡を記したものです。同じように深い沼にはまろうとしている未来の挑戦者への道標となれば幸いです。
第一章:構文解析の成功と、最初の希望 ✅
まず、目標の半分は驚くほどすんなり達成できました。nvim-treesitterのmainブランチで推奨されているauto cmd経由でテーブルを自作パーサーをcppに上書き設定します。
-- lazy.nvimでの設定
{
"nvim-treesitter/nvim-treesitter",
build = ":TSUpdate",
opts = {
-- ...
}
onfig = function(_, opts)
vim.api.nvim_create_autocmd('User', { pattern = 'TSUpdate',
callback = function()
require('nvim-treesitter.parsers').cpp = {
install_info = {
url = 'https://github.com/taku25/tree-sitter-unreal-cpp',
revision = '04ee0a7bbb303940e89e446e710192651ae14965',
},
}
end})
require("nvim-treesitter").setup(opts)
end,
-- ...
}
この設定で:TSInstall cppを実行すると、狙い通り自作パーサーがインストールされます。
:TSPlaygroundや:InspectTreeコマンドで確認すると、UCLASSやBlueprintableといったUE固有の構文が、意図した通りの構文木として完璧に解析されていることが確認できました。

標準のパーサーででるエラーが消え、インデントも正しく機能する。この時点で開発体験はすでに向上しており、「あとは色をつけるだけだ!」と、この時はまだ希望に満ちていました。
第二章:ハイライトを巡る長い戦い ⚔️
しかし、ここからが本当の地獄の始まりでした。
- クエリファイルは本当に読み込まれているのか?
highlights.scmは正しい場所に配置されているのに、色がつきません。ファイルが読み込まれていない可能性を疑い、中身を「すべての識別子を関数の色にする」という単純なテスト用のクエリに書き換えてみました。
Scheme
; smoke test
((identifier) @function)
結果: ダメ。 何も変わりません。この時点で、カスタムクエリファイルが全く読み込まれていないことがほぼ確定しました。
- LSPセマンティックトークンの妨害?
nvim-treesitterのハイライトは、LSPのセマンティックトークンに上書きされることがあります。:Inspectコマンドで確認すると、確かに@lsp.*系のハイライトが適用されている箇所もありました。
対策: LSPのハイライトグループをTree-sitterのグループにリンクしたり、additional_vim_regex_highlighting = falseを設定してTree-sitterを強制的に優先させたりしました。
結果: ダメ。 問題のBlueprintableなどには相変わらず色がつきません。
- 設定方法の全パターンを試す
キャッシュの完全な手動削除とクリーンインストール…。考えうる限りの設定方法とインストール手順を試しました。
結果: ダメ。 状況は一切変わりませんでした。
最終章:深淵からの回答、そして敗北 😭
万策尽きたため 長い戦いの終わりを告げる、残酷な答えでした。
自作パーサーは正しくインストールされ、クエリファイルも物理的に正しい場所に配置されている。設定もドキュメントとベストプラクティスに沿っている。それにも関わらず、Neovimのクエリエンジンは、理由不明のままcpp言語用のカスタムクエリファイルをロードすることを拒否していたのです。
まとめと、コミュニティへの問い
最終的に、自作パーサーによる構文解析の改善は成功したものの、ハイライトの有効化は失敗に終わりました。
この経験から学んだのは、nvim-treesitterのカスタマイズは非常に強力である一方、一度内部で問題が発生すると、その原因を特定するのが極めて困難なブラックボックスになりうるということです。
もし、この不可解な現象について何か心当たりのある方や、試すべき別のデバッグ方法をご存知の方がいらっしゃいましたら、ぜひコメントで教えていただけると嬉しいです。
今のところは、構文解析が正常になっただけでも良しとして、ハイライトについては妥協案としてafter/syntax/cpp.vimを使ったシンプルなキーワードマッチングで対応しようと思います。
長い戦いの記録を読んでいただき、ありがとうございました。
Tree-sitter、完全に理解した…とは、とても言えそうにありません。
以上 今回も下書きをたくさん書いてそれをgeminiで正書してもらいました。
やっぱりなんかすごくアメリカンな感じですね。。。
いやしかし。。ほんと tree-sitter難しい。