nvim-treesitter
nvim-treesitter copied to clipboard
if a language gets listed twice in ensure_installed, the installation fails
Describe the bug
If a language like c
gets mentioned twice
require("nvim-treesitter.configs").setup({
-- `c` gets listed TWICE!
ensure_installed = { "c", "c" },
sync_install = false,
})
the installation fails with
nvim-treesitter[c]: Could not create tree-sitter-c-tmp
mkdir: cannot create directory ‘tree-sitter-c-tmp’: File exists
if sync_install
is true
, the installation succeeds!
To me it looks like nvim-treesitter
tries to install the language c
in parallel. Due to that, a folder tree-sitter-c-tmp
gets created, which results in errors on second installer trying to create the same folder.
Although a bunch of error messages get rendered the language c
will get installed successfully. So the error does not re-occur, when restarting nvim
.
To Reproduce
- set up a fresh nvim install with the
init.lua
local lazypath = vim.fn.stdpath("data") .. "/lazy/lazy.nvim"
if not vim.loop.fs_stat(lazypath) then
-- bootstrap lazy.nvim
-- stylua: ignore
vim.fn.system({ "git", "clone", "--filter=blob:none", "https://github.com/folke/lazy.nvim.git", "--branch=stable", lazypath })
end
vim.opt.rtp:prepend(vim.env.LAZY or lazypath)
require("lazy").setup({
"nvim-treesitter/nvim-treesitter",
})
require("nvim-treesitter.configs").setup({
-- `c` gets listed TWICE!
ensure_installed = { "c", "c" },
sync_install = false,
})
- start the latest nvim
- see the errors at
:messages
Expected behavior
The language c
should get installed only once (at a time).
A solution could be, making the items of list of ensure_installed
unique. Or, check for duplicates and raise a better error.
The issue occurred to me, when I created the list of ensure_installed
dynamically, through LazyVim.
Output of :checkhealth nvim-treesitter
nvim-treesitter: require("nvim-treesitter.health").check()
Installation ~
- WARNING `tree-sitter` executable not found (parser generator, only needed for :TSInstallFromGrammar, not required for :TSInstall)
- OK `node` found v19.7.0 (only needed for :TSInstallFromGrammar)
- OK `git` executable found.
- OK `cc` executable found. Selected from { vim.NIL, "cc", "gcc", "clang", "cl", "zig" }
Version: cc (SUSE Linux) 13.0.1 20230412 (experimental) [revision d339e9802f758e051b0a1ef6db732ff846cbf4e3]
- OK Neovim was compiled with tree-sitter runtime ABI version 14 (required >=13). Parsers must be compatible with runtime ABI.
OS Info:
{
machine = "x86_64",
release = "6.2.10-1-default",
sysname = "Linux",
version = "#1 SMP PREEMPT_DYNAMIC Thu Apr 6 10:36:55 UTC 2023 (ba7816e)"
} ~
Parser/Features H L F I J
- c ✓ ✓ ✓ ✓ ✓
Legend: H[ighlight], L[ocals], F[olds], I[ndents], In[j]ections
+) multiple parsers found, only one will be used
x) errors found in the query, try to run :TSUpdate {lang} ~
Output of nvim --version
NVIM v0.10.0-dev
Build type: Release
LuaJIT 2.1.0-beta3
system vimrc file: "$VIM/sysinit.vim"
fall-back for $VIM: "/usr/local/share/nvim"
Run :checkhealth for more info
Additional context
No response
This will race to installations against each other. This is currently not supported.
This will race to installations against each other. This is currently not supported.
Thanks for the quick reply. I agree, that this is currently not supported. But maybe this is easily fixable?
Shall I try to fix it and do a pull request?
Sanitizing the list so that each entry is unique would make sense.
(But this is such an obvious mistake that it's not high priority to guard against.)
I've thought to make error message more specific. I found suspiciously looking code and interesting behaviour.
-
This code seems like always
false
. Theget_ensure_installed_parsers
always returns a table. - This problem causes this condition be pointless for case with
all
parsers. - I put
vim.print(config)
right at the first line of theget_ensure_installed_parsers
andconfig.ensure_installed
is empty. I've checked this line, here we have the field populated. I still didn't manage to find out why, I don't have minimal setup at hand. But! Anyway I don't understand how it's even possible that the field disappears. Seems like there are no mutation of the table in theconfig
file and from the outside (the file is not accessible, at least it seems so for me; maybe it's some kind of data access issue). THe seettings is also empty when I do:lua vim.print(require('nvim-treesitter.configs').get_ensure_installed_parsers())
.
The problems I described above make it so that the user cannot see this warning: https://github.com/IlyasYOY/nvim-treesitter/blob/4fbf150a1621d52f17b099506e1a32f107079210/lua/nvim-treesitter/install.lua#L625-L631
Note that the whole plugin has been rewritten for 1.0 (see the Roadmap issue) on the main branch. There's little point of expending effort on the current master
code.
This also seems to be an issue when sync_install = false
, auto_install = true
, and you open a file with a file type corresponding to one of the parsers listed in ensure_installed
, which has not yet been installed.
Steps to reproduce
- Create the following
init.lua
.
local lazypath = vim.fn.stdpath("data") .. "/lazy/lazy.nvim"
if not vim.loop.fs_stat(lazypath) then
vim.fn.system({
"git",
"clone",
"--filter=blob:none",
"https://github.com/folke/lazy.nvim.git",
"--branch=stable",
lazypath,
})
end
vim.opt.rtp:prepend(lazypath)
require('lazy').setup({
{
'nvim-treesitter/nvim-treesitter',
opts = { ensure_installed = { 'lua' }, sync_install = false, auto_install = true },
config = function(_, opts)
require('nvim-treesitter.configs').setup(opts)
end,
},
})
- Clear Neovim's cached and local state.
rm -rf ~/.cache/nvim
rm -rf ~/.local/share/nvim
rm -rf ~/.local/state/nvim
- Open
init.lua
(or any Lua file) in Neovim and observe the error.
nvim ~/.config/nvim/init.lua