mirror of
https://github.com/neovim/neovim
synced 2025-07-15 16:51:49 +00:00
fix(treesitter): eliminate flicker for single windows #33842
This commit will eliminate flicker while editing one open window. It
works by querying previously calculated trees for highlight marks, in
the case that we are still asynchronously parsing in `on_win`.
It will not fully solve the case of flicker when there are multiple open
windows, since the parser will drop previously parsed injection trees
whenever it receives a call to parse a different region of the buffer.
This will require a refactor of `languagetree.lua`.
(cherry picked from commit 8d75910ef9
)
This commit is contained in:
committed by
github-actions[bot]
parent
0db89468d7
commit
5c6ee251a6
@ -131,6 +131,7 @@ function TSHighlighter.new(tree, opts)
|
||||
self.redraw_count = 0
|
||||
self._conceal_checked = {}
|
||||
self._queries = {}
|
||||
self._highlight_states = {}
|
||||
|
||||
-- Queries for a specific language can be overridden by a custom
|
||||
-- string query... if one is not provided it will be looked up by file.
|
||||
@ -460,19 +461,37 @@ end
|
||||
---@param buf integer
|
||||
---@param topline integer
|
||||
---@param botline integer
|
||||
function TSHighlighter._on_win(_, _, buf, topline, botline)
|
||||
function TSHighlighter._on_win(_, win, buf, topline, botline)
|
||||
local self = TSHighlighter.active[buf]
|
||||
if not self or self.parsing then
|
||||
if not self then
|
||||
return false
|
||||
end
|
||||
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
|
||||
self:prepare_highlight_states(topline, botline)
|
||||
self.parsing = self.parsing
|
||||
or nil
|
||||
== self.tree:parse({ topline, botline + 1 }, function(_, trees)
|
||||
if trees and self.parsing then
|
||||
self.parsing = false
|
||||
api.nvim__redraw({ win = win, valid = false, flush = false })
|
||||
end
|
||||
end)
|
||||
if not self.parsing then
|
||||
self.redraw_count = self.redraw_count + 1
|
||||
self:prepare_highlight_states(topline, botline)
|
||||
else
|
||||
self:for_each_highlight_state(function(state)
|
||||
-- TODO(ribru17): Inefficient. Eventually all marks should be applied in on_buf, and all
|
||||
-- non-folded ranges of each open window should be merged, and iterators should only be
|
||||
-- created over those regions. This would also fix #31777.
|
||||
--
|
||||
-- Currently this is not possible because the parser discards previously parsed injection
|
||||
-- trees upon parsing a different region.
|
||||
--
|
||||
-- It would also be nice if rather than re-querying extmarks for old trees, we could tell the
|
||||
-- decoration provider to not clear previous ephemeral marks for this redraw cycle.
|
||||
state.iter = nil
|
||||
state.next_row = 0
|
||||
end)
|
||||
end
|
||||
return #self._highlight_states > 0
|
||||
end
|
||||
|
||||
|
Reference in New Issue
Block a user