Skip to content
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

Disable injections for large files #6435

Closed
vanaigr opened this issue Apr 12, 2024 · 5 comments
Closed

Disable injections for large files #6435

vanaigr opened this issue Apr 12, 2024 · 5 comments
Labels
enhancement New feature or request

Comments

@vanaigr
Copy link

vanaigr commented Apr 12, 2024

Is your feature request related to a problem? Please describe.
Neovim runs injection queries for the entire buffer on each edit. For large files, a significant portion of the time is spent executing injection queries, even if the file doesn't contain any injections.

Describe the solution you'd like
I think something similar to the highlight's disable(lang, bufnr) could be added, but for injections.

Describe alternatives you've considered
Not running injection queries for the entire buffer. Though, I think it could break combined injections in some situations

injection.combined - indicates that all of the matching nodes in the tree should have their content parsed as one nested document.

Additional context

The redraw time and injection query execution time:
image

init.lua
local line = 'int func(int a, int b) { return a + b; }'
local lines = {}
for i = 1, 10000 do lines[i] = line end

vim.api.nvim_buf_set_lines(0, 0, 1, false, lines)
vim.cmd('set ft=c')


local path = "/tmp/nvim-treesitter-injections-perf"

local lazypath = path .. "/lazy/lazy.nvim"
if not (vim.uv or vim.loop).fs_stat(lazypath) then
    print('Downloading Lazy.nvim')
    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' } }, { root = path .. '/plugins' })

local tspath = path .. '/parsers'
vim.opt.runtimepath:append(tspath)
require'nvim-treesitter.configs'.setup{
    parser_install_dir = tspath,
    ensure_installed = { 'c' },
    sync_install = false,
    auto_install = true,
    highlight = {
        enable = true,
        additional_vim_regex_highlighting = false,
    },
}
patch for measuring time for neovim commit 2c5fd3f966
diff --git a/runtime/lua/vim/treesitter/highlighter.lua b/runtime/lua/vim/treesitter/highlighter.lua
index 3f7e31212..0b167b0c4 100644
--- a/runtime/lua/vim/treesitter/highlighter.lua
+++ b/runtime/lua/vim/treesitter/highlighter.lua
@@ -400,10 +400,13 @@ function TSHighlighter._on_win(_, _win, buf, topline, botline)
   return true
 end
 
+local start
 api.nvim_set_decoration_provider(ns, {
   on_win = TSHighlighter._on_win,
   on_line = TSHighlighter._on_line,
   _on_spell_nav = TSHighlighter._on_spell_nav,
+  on_start = function() start = vim.uv.hrtime() end,
+  on_end = function() print("Total: " .. ((vim.uv.hrtime() - start) / 1000000)..'ms') end,
 })
 
 return TSHighlighter
diff --git a/runtime/lua/vim/treesitter/languagetree.lua b/runtime/lua/vim/treesitter/languagetree.lua
index 990debc77..18b4a44e3 100644
--- a/runtime/lua/vim/treesitter/languagetree.lua
+++ b/runtime/lua/vim/treesitter/languagetree.lua
@@ -403,7 +403,7 @@ function LanguageTree:_add_injections()
     end
   end
 
-  return query_time
+  return query_time, injections_by_lang
 end
 
 --- Recursively parse all regions in the language tree using |treesitter-parsers|
@@ -441,7 +441,9 @@ function LanguageTree:parse(range)
   end
 
   if not self._injections_processed and range ~= false and range ~= nil then
-    query_time = self:_add_injections()
+    local injections
+    query_time, injections = self:_add_injections()
+    print("Injections: " .. query_time .. 'ms, '..vim.inspect(injections))
     self._injections_processed = true
   end
@vanaigr vanaigr added the enhancement New feature or request label Apr 12, 2024
@clason
Copy link
Contributor

clason commented Apr 12, 2024

Neovim runs injection queries for the entire buffer on each edit.

I don't think that's correct. After recent changes, it only runs injection queries for the viewport.

@vanaigr
Copy link
Author

vanaigr commented Apr 12, 2024

Neovim runs injection queries for the entire buffer on each edit.

I don't think that's correct. After recent changes, it only runs injection queries for the viewport.

Injections themselves are parsed lazily (neovim/neovim#22309, neovim/neovim#24647), but the queries are run if any region is invalidated according to task 4 in neovim/neovim#22426.
LanguageTree:_get_injections() uses root node's coordinates for iterating matches:
https://github.com/neovim/neovim/blob/4f3d018d15d299b66a341bed4d677d7ec03ad44f/runtime/lua/vim/treesitter/languagetree.lua#L856-L863

@clason
Copy link
Contributor

clason commented Apr 13, 2024

I'm not sure the complexity is worth it. In any case, highlighting (and injections) are completely handled by Neovim; this project only coordinates queries (and provides a thin wrapper around vim.treesitter.start(), which will be removed in the next version). So this issue -- if at all -- belongs at neovim/neovim.

@clason clason closed this as not planned Won't fix, can't repro, duplicate, stale Apr 13, 2024
@tomtomjhj
Copy link
Contributor

Not running injection queries for the entire buffer. Though, I think it could break combined injections in some situations

neovim/neovim#26827 implements this.

@clason
Copy link
Contributor

clason commented Apr 13, 2024

(was just about to edit my comment to point that out)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
enhancement New feature or request
Projects
None yet
Development

No branches or pull requests

3 participants