Every couple of weeks, I run MiniDeps’s :DepsUpdate and cross my fingers that everything is going to be fine. Most of the time it is but not this morning1.
Immediately, I got the following errors:
Error detected while processing ~/.config/nvim/init.lua:
E5113: Error while calling lua chunk: ~/.config/nvim/lua/_/ui/treesitter.lua:1: module 'nvim-treesitter.configs' not found:
no field package.preload['nvim-treesitter.configs']
no file '/nix/store/w997z7g0ii6figi4z98id0b0yn2jzala-luajit-2.1.1741730670-env/share/lua/5.1/nvim-treesitter/configs.lua'
no file '/nix/store/w997z7g0ii6figi4z98id0b0yn2jzala-luajit-2.1.1741730670-env/share/lua/5.1/nvim-treesitter/configs/init.lua'
no file '/nix/store/bmdviv9ljgqb6siq2p3dsll497fjzpif-luajit2.1-fzy-1.0.3-1/share/lua/5.1/nvim-treesitter/configs.lua'
no file '/nix/store/bmdviv9ljgqb6siq2p3dsll497fjzpif-luajit2.1-fzy-1.0.3-1/share/lua/5.1/nvim-treesitter/configs/init.lua'
no file '/nix/store/w997z7g0ii6figi4z98id0b0yn2jzala-luajit-2.1.1741730670-env/lib/lua/5.1/nvim-treesitter/configs.so'
no file '/nix/store/bmdviv9ljgqb6siq2p3dsll497fjzpif-luajit2.1-fzy-1.0.3-1/lib/lua/5.1/nvim-treesitter/configs.so'
no file '/nix/store/w997z7g0ii6figi4z98id0b0yn2jzala-luajit-2.1.1741730670-env/lib/lua/5.1/nvim-treesitter.so'
no file '/nix/store/bmdviv9ljgqb6siq2p3dsll497fjzpif-luajit2.1-fzy-1.0.3-1/lib/lua/5.1/nvim-treesitter.so'
Investigating further, I saw that the master branch of nvim-treesitter is now frozen and they’re now working on the main branch. The new branch is a complete rewrite. The fix could have been a simple:
MiniDeps.add({
source = 'nvim-treesitter/nvim-treesitter',
- checkout = 'master',
+ checkout = 'main',
hooks = { post_checkout = function() vim.cmd('TSUpdate') end },
})
However, since I was there and I figured I’ll just do the update properly. First, my configuration looked like this:
local configs = require('nvim-treesitter.configs')
local mdx = require('mdx')
---@diagnostic disable-next-line: missing-fields
configs.setup({
auto_install = true,
highlight = { enable = true },
endwise = { enable = true },
indent = { enable = true },
})
The rewrite removes the need for manual config except for customization on where the parsers are installed. To keep the behaviours I had before, in my case, the auto_install option and the highlighting, I update my config like this:
- First, I installed parsers for files in my dotfile on startup. Thankfully, this is a no-op when they’re already installed:
local ts = require('nvim-treesitter')
-- Wait at most 30 seconds to finish installation.
ts.install(
{
'lua', 'vim', 'vimdoc', 'query',
'markdown', 'markdown_inline',
'json', 'yaml',
},
-- Do not print summary, as this will run at startup always, all the time.
{ summary = false }
):wait(30000)
- Then, I install the parser and enable highlighting and other plugin using an
autocmdthat triggers onFileType:
---@type fun(args: vim.api.keyset.create_autocmd.callback_args): boolean?
local install_parser_and_enable_features = function(event)
local lang = event.match
-- Try to start the parser install for the language.
local ok, task = pcall(ts.install, { lang }, { summary = true })
if not ok then return end
-- Wait for the installation to finish (up to 10 seconds).
task:wait(10000)
-- Enable syntax highlighting for the buffer
ok, _ = pcall(vim.treesitter.start, event.buf, lang)
if not ok then return end
-- Enable other features as needed.
-- Enable indentation based on treesitter for the buffer.
-- vim.bo.indentexpr = "v:lua.require'nvim-treesitter'.indentexpr()"
-- Enable folding based on treesitter for the buffer.
-- vim.wo.foldexpr = 'v:lua.vim.treesitter.foldexpr()'
end
-- Install missing parsers on file open.
vim.api.nvim_create_autocmd('FileType', {
group = vim.api.nvim_create_augroup('ui.treesitter', { clear = true }),
pattern = { '*' },
callback = install_parser_and_enable_features
})
And like that, no more errors and treesitter works as expected. I should probably read more about the reasons of the rewrite, but I’ll leave this for another Friday.
Footnotes
-
You’d think after more than 15 years, I’d understand that Friday are not the days to be nonchalant about potentially breaking things. ↩