aboutsummaryrefslogtreecommitdiff
path: root/runtime/lua/vim/treesitter/highlighter.lua
diff options
context:
space:
mode:
authorLewis Russell <lewis6991@gmail.com>2023-08-10 14:21:56 +0100
committerLewis Russell <me@lewisr.dev>2023-08-12 16:11:36 +0100
commit2ca076e45fb3f1c08f6a1a374834df0701b8d778 (patch)
tree3338df585168c4e6455137757519ca0bcd211c8c /runtime/lua/vim/treesitter/highlighter.lua
parent5a25dcc5a4c73f50902432e32335ab073950cceb (diff)
downloadrneovim-2ca076e45fb3f1c08f6a1a374834df0701b8d778.tar.gz
rneovim-2ca076e45fb3f1c08f6a1a374834df0701b8d778.tar.bz2
rneovim-2ca076e45fb3f1c08f6a1a374834df0701b8d778.zip
feat(treesitter)!: incremental injection parsing
Problem: Treesitter highlighting is slow for large files with lots of injections. Solution: Only parse injections we are going to render during a redraw cycle. --- - `LanguageTree:parse()` will no longer parse injections by default and now requires an explicit range argument to be passed. - `TSHighlighter` now parses injections incrementally during on_win callbacks for the line range being rendered. - Plugins which require certain injections to be parsed must run `parser:parse({ start_row, end_row })` before using the tree.
Diffstat (limited to 'runtime/lua/vim/treesitter/highlighter.lua')
-rw-r--r--runtime/lua/vim/treesitter/highlighter.lua24
1 files changed, 9 insertions, 15 deletions
diff --git a/runtime/lua/vim/treesitter/highlighter.lua b/runtime/lua/vim/treesitter/highlighter.lua
index f8ec5b175d..56b075b723 100644
--- a/runtime/lua/vim/treesitter/highlighter.lua
+++ b/runtime/lua/vim/treesitter/highlighter.lua
@@ -1,5 +1,6 @@
local api = vim.api
local query = vim.treesitter.query
+local Range = require('vim.treesitter._range')
---@alias TSHlIter fun(): integer, TSNode, TSMetadata
@@ -14,6 +15,7 @@ local query = vim.treesitter.query
---@field _highlight_states table<TSTree,TSHighlightState>
---@field _queries table<string,TSHighlighterQuery>
---@field tree LanguageTree
+---@field redraw_count integer
local TSHighlighter = rawget(vim.treesitter, 'TSHighlighter') or {}
TSHighlighter.__index = TSHighlighter
@@ -139,6 +141,7 @@ function TSHighlighter.new(tree, opts)
return self
end
+--- @nodoc
--- Removes all internal references to the highlighter
function TSHighlighter:destroy()
if TSHighlighter.active[self.bufnr] then
@@ -186,7 +189,7 @@ function TSHighlighter:on_detach()
end
---@package
----@param changes Range6[][]
+---@param changes Range6[]
function TSHighlighter:on_changedtree(changes)
for _, ch in ipairs(changes) do
api.nvim__buf_redraw_range(self.bufnr, ch[1], ch[4] + 1)
@@ -245,7 +248,7 @@ local function on_line_impl(self, buf, line, is_spell_nav)
end
local range = vim.treesitter.get_range(node, buf, metadata[capture])
- local start_row, start_col, _, end_row, end_col, _ = unpack(range)
+ local start_row, start_col, end_row, end_col = Range.unpack4(range)
local hl = highlighter_query.hl_cache[capture]
local capture_name = highlighter_query:query().captures[capture]
@@ -310,31 +313,22 @@ function TSHighlighter._on_spell_nav(_, _, buf, srow, _, erow, _)
end
---@private
----@param buf integer
-function TSHighlighter._on_buf(_, buf)
- local self = TSHighlighter.active[buf]
- if self then
- self.tree:parse()
- end
-end
-
----@private
---@param _win integer
---@param buf integer
----@param _topline integer
-function TSHighlighter._on_win(_, _win, buf, _topline)
+---@param topline integer
+---@param botline integer
+function TSHighlighter._on_win(_, _win, buf, topline, botline)
local self = TSHighlighter.active[buf]
if not self then
return false
end
-
+ self.tree:parse({ topline, botline })
self:reset_highlight_state()
self.redraw_count = self.redraw_count + 1
return true
end
api.nvim_set_decoration_provider(ns, {
- on_buf = TSHighlighter._on_buf,
on_win = TSHighlighter._on_win,
on_line = TSHighlighter._on_line,
_on_spell_nav = TSHighlighter._on_spell_nav,