feat: cache textobjects created from a ts query #692
Closed
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
Problem
When the user opens a file with this plugin installed (most notably latex, dart, zig and rust files), a slow ts.get_query will get called, that can take 3500ms for a latex file on an older machine. The reason for this is tree-sitter is trying to do some aggressive initial analysis of the query (eg. latex/textobjects.scm).
Neovim acknowledged that this function call is slow and memoized it, however it doesn't get cached for too long, as the cache gets garbage collected. For me this cache gets cleared after opening 2-3 files, so it's not that useful.
This PR's solution
This PR puts computed queries in a cache which lives as long as neovim is open.
Further work
A proper upstream fix would be the best, but this performance issue is present for months and I don't see any progress on it.
In order to persist the cache between neovim sessions, we could store the cache somewhere in probably ~/.local/state/nvim. And for cache invalidation, we could also store the hash of the .scm files and invalidate the cache when the hash changes.
Other issues and PRs
Helps a lot with #461, #627.
Upstream issue this PR is working around: tree-sitter/tree-sitter#973.
In neovim a similar caching system was implemented in neovim/neovim#24222, but got replaced with the garbage collected memoization in neovim/neovim#25201.
Other plugins are resorting to this kind of workaround, for example noice.