nvim-treesitter icon indicating copy to clipboard operation
nvim-treesitter copied to clipboard

if a language gets listed twice in ensure_installed, the installation fails

Open qwertzui11 opened this issue 1 year ago • 6 comments

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

  1. 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,
})
  1. start the latest nvim
  2. 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

qwertzui11 avatar Apr 19 '23 17:04 qwertzui11

This will race to installations against each other. This is currently not supported.

theHamsta avatar Apr 19 '23 18:04 theHamsta

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?

qwertzui11 avatar Apr 19 '23 18:04 qwertzui11

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.)

clason avatar Apr 19 '23 18:04 clason

I've thought to make error message more specific. I found suspiciously looking code and interesting behaviour.

  1. This code seems like always false. The get_ensure_installed_parsers always returns a table.
  2. This problem causes this condition be pointless for case with all parsers.
  3. I put vim.print(config) right at the first line of the get_ensure_installed_parsers and config.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 the config 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

IlyasYOY avatar Feb 03 '24 21:02 IlyasYOY

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.

clason avatar Feb 03 '24 21:02 clason

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

  1. 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,
  },
})

  1. Clear Neovim's cached and local state.
rm -rf ~/.cache/nvim
rm -rf ~/.local/share/nvim
rm -rf ~/.local/state/nvim
  1. Open init.lua (or any Lua file) in Neovim and observe the error.
nvim ~/.config/nvim/init.lua

image

pwnalone avatar Feb 25 '24 19:02 pwnalone