New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Windows: treesitter language parsers are not released, preventing reinstallation #28462
Comments
I'm not sure there's much we can do here, to be honest. Tree-sitter itself is not eager in releasing parsers, and we cache them for hard won performance reasons. I general, Neovim doesn't really support hot reloading, and this is a corollary of that. |
In this case, on Windows, (potentially) all Nvim processes would need to be closed in order to update a TS parser. That's a bit different than not supporting hot-reload. |
That is fair. Implementing proper garbage collection would be a significant overhead, though. |
@justinmk Correct. If any Neovim process has opened it at least once during its lifetime, the language parser cannot be deleted until that process ends or calls @clason For Neovim to facilitate proper reinstallation of language parsers on Windows, it would have to be modified to keep track of the file handle it creates with |
We can at least ensure that our parser object (er... "LanguageTree") has an API for releasing/destroying parsers. Making it work "properly" might require some work (maybe an upstream TS patch), it sounds like. |
I don't quite agree. People do expect that installed plugins/whatever are available immediately, and we shouldn't paper over that: Updating a parser that is in use is just not well-defined. And speaking of nvim-treesitter: it doesn't load parsers itself; that is handled by Neovim. It will be loaded when it is requested and is not yet loaded.
There is a tree-sitter API for that which is exposed (privately); the overhead is for tracking "use" of the parser, which we currently don't do at all. It's in fact not so obvious when a parser is to no longer "used" for a buffer (e.g., if injections are created or destroyed). |
I agree that people do expect that installed components are available immediately, but I'm not suggesting something that would interfere with that goal. Quite the contrary. The current behavior on Windows when reinstalling a loaded language parser with @justinmk If Neovim adds an API just for releasing or destroying language parsers, it would still have to coordinate with every running Neovim process and there is no guarantee that all of them would be capable of releasing a lock (there are many reasons why Neovim might freeze up, especially on Windows). Otherwise, the old parser would remain locked, and the algorithm I outlined in the To fix the bug on Windows, something -- either For Neovim to fix it, an API could be added for copying new language parsers to an installation location. Then Neovim could reliably replace the old parser (renaming and flagging the old one for deletion on Windows, if necessary), and immediately load the new one. Adding this functionality in Neovim would be beneficial to all users because it would bring with it the ability to immediately load a new language parser, which is lacking on all platforms. |
This is something libuv should handle. If you can find out the right flags for that, I'll happily use them on Windows. |
The correct flag when using
For example, using MoveFileEx(szDeleteFile, NULL, MOVEFILE_DELAY_UNTIL_REBOOT); What it actually does is create a registry entry, so the success or failure of the command indicates its ability to create that registry entry. |
That's not a libuv API, though -- and we use those exclusively. |
Okay, I've looked into So simply deleting the old one with |
Ok, so we don't need to manually clean up. That makes this much more tenable on the nvim-treesitter side. I'll see what I can do. |
Problem
Neovim opens language parsers in a way that blocks other processes from overwriting them, and does not release the associated file handle until Neovim closes. This prevents the reinstallation and upgrade of language parsers on Windows after the parser has been loaded.
Steps to reproduce
These reproduction steps use
lazy.nvim
andnvim-treesitter
, but manually installing a parser where Neovim can pick it up will trigger the error as well.:TSInstall rust
, or manually by installing it in the correct directory for Neovim to find it.:InspectTree
(this is just one way of being sure the language parser was loaded)I'm not sure why, but reinstalling immediately after the initial installation results in no message at all.
For reference, I reproduced this initially with a simple
init.lua
:Then I tried to rule out the involvement of
nvim-treesitter
and evenlazy.nvim
by cleaning out the configuration and data files, leaving behind onlyC:\Users\User\AppData\Local\nvim-data\site
, which held the parser inparser\rust.so
. Then I just used a sanity-checkinit.lua
:The problem still occurred.
Windows has a way of locking files, depending on how they are opened, so it seems like that is causing the problem, which is made worse because they don't seem to be closed until Neovim itself is closed.
Expected behavior
I would expect treesitter language parsers to be replaceable, even when in use, so they can always be upgraded from within Neovim.
Neovim version (nvim -v)
0.10.0-dev-2976+g208852126
Vim (not Nvim) behaves the same?
no?
Operating system/version
Windows 10 Pro 22H2
Terminal name/version
Windows Terminal 1.19.10821.0
$TERM environment variable
N/A - it's empty
Installation
Downloaded
nvim-win64.zip
from the repository's release assets, but it also exists in 0.9.x versions installed withwinget
, including 0.9.5.The text was updated successfully, but these errors were encountered: