Skip to content

Commit

Permalink
fix: incsearch flickering when typing characters during search
Browse files Browse the repository at this point in the history
Setting the decoration provider on every renderer:draw() command caused
flickering of incsearch highlights when showing completions for / and ?
search modes on the cmdline as characters were typed.

Decoration providers only need to be set once and they remain active, so
the fix here is create it when the renderer is created and remember the
last bufnr that was drawn to, along with the columns.

Fixes #1061
  • Loading branch information
jdrouhard committed Feb 23, 2025
1 parent a4bb082 commit d39a45b
Showing 1 changed file with 31 additions and 28 deletions.
59 changes: 31 additions & 28 deletions lua/blink/cmp/completion/windows/render/init.lua
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
--- @field padding number[]
--- @field gap number
--- @field columns blink.cmp.DrawColumn[]
--- @field bufnr number?
---
--- @field new fun(draw: blink.cmp.Draw): blink.cmp.Renderer
--- @field draw fun(self: blink.cmp.Renderer, context: blink.cmp.Context, bufnr: number, items: blink.cmp.CompletionItem[], draw: blink.cmp.Draw): blink.cmp.DrawColumn[]
Expand All @@ -25,6 +26,35 @@ function renderer.new(draw)
self.padding = padding
self.gap = draw.gap
self.def = draw

-- Setting highlights is slow and we update on every keystroke so we instead use a decoration provider
-- which will only render highlights of the visible lines. This also avoids having to do virtual scroll
-- like nvim-cmp does, which breaks on UIs like neovide
vim.api.nvim_set_decoration_provider(ns, {
on_win = function(_, _, win_bufnr) return self.bufnr == win_bufnr end,
on_line = function(_, _, _, line)
local offset = self.padding[1]
for _, column in ipairs(self.columns) do
local text = column:get_line_text(line + 1)
if #text > 0 then
local highlights = column:get_line_highlights(line + 1)
for _, highlight in ipairs(highlights) do
local col = offset + highlight[1]
local end_col = offset + highlight[2]
vim.api.nvim_buf_set_extmark(self.bufnr, ns, line, col, {
end_col = end_col,
hl_group = highlight.group,
hl_mode = 'combine',
hl_eol = true,
ephemeral = true,
})
end
offset = offset + #text + self.gap
end
end
end,
})

return self
end

Expand Down Expand Up @@ -88,35 +118,8 @@ function renderer:draw(context, bufnr, items)
vim.api.nvim_buf_set_lines(bufnr, 0, -1, false, lines)
vim.api.nvim_set_option_value('modified', false, { buf = bufnr })

-- Setting highlights is slow and we update on every keystroke so we instead use a decoration provider
-- which will only render highlights of the visible lines. This also avoids having to do virtual scroll
-- like nvim-cmp does, which breaks on UIs like neovide
vim.api.nvim_set_decoration_provider(ns, {
on_win = function(_, _, win_bufnr) return bufnr == win_bufnr end,
on_line = function(_, _, _, line)
local offset = self.padding[1]
for _, column in ipairs(columns) do
local text = column:get_line_text(line + 1)
if #text > 0 then
local highlights = column:get_line_highlights(line + 1)
for _, highlight in ipairs(highlights) do
local col = offset + highlight[1]
local end_col = offset + highlight[2]
vim.api.nvim_buf_set_extmark(bufnr, ns, line, col, {
end_col = end_col,
hl_group = highlight.group,
hl_mode = 'combine',
hl_eol = true,
ephemeral = true,
})
end
offset = offset + #text + self.gap
end
end
end,
})

self.columns = columns
self.bufnr = bufnr
end

function renderer:get_component_column_location(columns, component_name)
Expand Down

0 comments on commit d39a45b

Please sign in to comment.