feat(treesitter): async parsing

**Problem:** Parsing can be slow for large files, and it is a blocking
operation which can be disruptive and annoying.

**Solution:** Provide a function for asynchronous parsing, which accepts
a callback to be run after parsing completes.

Co-authored-by: Lewis Russell <lewis6991@gmail.com>
Co-authored-by: Luuk van Baal <luukvbaal@gmail.com>
Co-authored-by: VanaIgr <vanaigranov@gmail.com>
This commit is contained in:
Riley Bruins
2024-12-18 10:48:33 -08:00
parent 3fdc430241
commit 45e606b1fd
11 changed files with 395 additions and 41 deletions

View File

@@ -69,6 +69,7 @@ end
---@field private _queries table<string,vim.treesitter.highlighter.Query>
---@field tree vim.treesitter.LanguageTree
---@field private redraw_count integer
---@field parsing boolean true if we are parsing asynchronously
local TSHighlighter = {
active = {},
}
@@ -147,7 +148,7 @@ function TSHighlighter.new(tree, opts)
vim.opt_local.spelloptions:append('noplainbuffer')
end)
self.tree:parse()
self.tree:parse(nil, function() end)
return self
end
@@ -384,19 +385,23 @@ function TSHighlighter._on_spell_nav(_, _, buf, srow, _, erow, _)
end
---@private
---@param _win integer
---@param buf integer
---@param topline integer
---@param botline integer
function TSHighlighter._on_win(_, _win, buf, topline, botline)
function TSHighlighter._on_win(_, _, buf, topline, botline)
local self = TSHighlighter.active[buf]
if not self then
if not self or self.parsing then
return false
end
self.tree:parse({ topline, botline + 1 })
self:prepare_highlight_states(topline, botline + 1)
self.parsing = self.tree:parse({ topline, botline + 1 }, function(_, trees)
if trees and self.parsing then
self.parsing = false
api.nvim__redraw({ buf = buf, valid = false, flush = false })
end
end) == nil
self.redraw_count = self.redraw_count + 1
return true
self:prepare_highlight_states(topline, botline)
return #self._highlight_states > 0
end
api.nvim_set_decoration_provider(ns, {