Skip to content

Commit 3a4e83e

Browse files
authored
perf: mitigate the cursor flickering issue (#298)
Instead of letting the `:hl` to redraw all things globally, use the `nvim__redraw` api to limit the redraw on the notification windows only. The api also handles the case of redrawing during blocking events by flushing the screen changes.
1 parent 29b33ef commit 3a4e83e

File tree

4 files changed

+28
-47
lines changed

4 files changed

+28
-47
lines changed

lua/notify/config/init.lua

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -71,8 +71,8 @@ local function validate_highlight(colour_or_group, needs_opacity)
7171
end
7272
end
7373
return function()
74-
local group = vim.api.nvim_get_hl_by_name(colour_or_group, true)
75-
if not group or not group.background then
74+
local group = vim.api.nvim_get_hl(0, { name = colour_or_group, create = false, link = false })
75+
if not group or not group.bg then
7676
if needs_opacity and not opacity_warned then
7777
opacity_warned = true
7878
vim.schedule(function()
@@ -88,14 +88,14 @@ Defaulting to #000000]], "warn", {
8888
title = "nvim-notify",
8989
on_open = function(win)
9090
local buf = vim.api.nvim_win_get_buf(win)
91-
vim.api.nvim_buf_set_option(buf, "filetype", "markdown")
91+
vim.api.nvim_set_option_value("filetype", "markdown", { buf = buf })
9292
end,
9393
})
9494
end)
9595
end
9696
return "#000000"
9797
end
98-
return string.format("#%x", group.background)
98+
return string.format("#%x", group.bg)
9999
end
100100
end
101101

lua/notify/service/buffer/highlights.lua

Lines changed: 18 additions & 34 deletions
Original file line numberDiff line numberDiff line change
@@ -11,24 +11,6 @@ local util = require("notify.util")
1111
---@field _config table
1212
local NotifyBufHighlights = {}
1313

14-
local function manual_get_hl(name)
15-
local synID = vim.fn.synIDtrans(vim.fn.hlID(name))
16-
local result = {
17-
foreground = tonumber(vim.fn.synIDattr(synID, "fg"):gsub("#", ""), 16),
18-
background = tonumber(vim.fn.synIDattr(synID, "bg"):gsub("#", ""), 16),
19-
}
20-
return result
21-
end
22-
23-
local function get_hl(name)
24-
local definition = vim.api.nvim_get_hl_by_name(name, true)
25-
if definition[true] then
26-
-- https://github.com/neovim/neovim/issues/18024
27-
return manual_get_hl(name)
28-
end
29-
return definition
30-
end
31-
3214
function NotifyBufHighlights:new(level, buffer, config)
3315
local function linked_group(section)
3416
local orig = "Notify" .. level .. section
@@ -38,8 +20,11 @@ function NotifyBufHighlights:new(level, buffer, config)
3820
local new = orig .. buffer
3921

4022
vim.api.nvim_set_hl(0, new, { link = orig })
23+
local hl = vim.api.nvim_get_hl(0, { name = orig, create = false, link = false })
24+
-- Removes the unwanted 'default' key, as we will copy the table for updating the highlight later.
25+
hl.default = nil
4126

42-
return new, get_hl(new)
27+
return new, hl
4328
end
4429

4530
local title, title_def = linked_group("Title")
@@ -83,7 +68,7 @@ function NotifyBufHighlights:_redefine_treesitter()
8368
return new
8469
end
8570
vim.api.nvim_set_hl(0, new, { link = orig })
86-
self.groups[new] = get_hl(new)
71+
self.groups[new] = vim.api.nvim_get_hl(0, { name = new, link = false })
8772
return new
8873
end
8974

@@ -150,31 +135,30 @@ end
150135
function NotifyBufHighlights:set_opacity(alpha)
151136
if
152137
not self._treesitter_redefined
153-
and vim.api.nvim_buf_get_option(self.buffer, "filetype") ~= "notify"
138+
and vim.api.nvim_get_option_value("filetype", { buf = self.buffer }) ~= "notify"
154139
then
155140
self:_redefine_treesitter()
156141
end
157142
self.opacity = alpha
158143
local background = self._config.background_colour()
144+
local updated = false
159145
for group, fields in pairs(self.groups) do
160-
local updated_fields = {}
161-
vim.api.nvim_set_hl(0, group, updated_fields)
162-
local hl_string = ""
163-
if fields.foreground then
164-
hl_string = "guifg=#"
165-
.. string.format("%06x", util.blend(fields.foreground, background, alpha / 100))
146+
local fg = fields.fg
147+
if fg then
148+
fg = util.blend(fg, background, alpha / 100)
166149
end
167-
if fields.background then
168-
hl_string = hl_string
169-
.. " guibg=#"
170-
.. string.format("%06x", util.blend(fields.background, background, alpha / 100))
150+
local bg = fields.bg
151+
if bg then
152+
bg = util.blend(bg, background, alpha / 100)
171153
end
172154

173-
if hl_string ~= "" then
174-
-- Can't use nvim_set_hl https://github.com/neovim/neovim/issues/18160
175-
vim.cmd("hi " .. group .. " " .. hl_string)
155+
if fg ~= fields.fg or bg ~= fields.bg then
156+
local hl = vim.tbl_extend('force', fields, { fg = fg, bg = bg })
157+
vim.api.nvim_set_hl(0, group, hl)
158+
updated = true
176159
end
177160
end
161+
return updated
178162
end
179163

180164
function NotifyBufHighlights:get_opacity()

lua/notify/service/init.lua

Lines changed: 0 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -55,12 +55,7 @@ function NotificationService:push(notif)
5555
self._pending:push(notif_buf)
5656
if not self._running then
5757
self:_run()
58-
else
59-
-- Forces a render during blocking events
60-
-- https://github.com/rcarriga/nvim-notify/issues/5
61-
pcall(self._animator.render, self._animator, self._pending, 1 / self._fps)
6258
end
63-
vim.cmd("redraw")
6459
return buf
6560
end
6661

lua/notify/windows/init.lua

Lines changed: 6 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -273,12 +273,11 @@ function WindowAnimator:_get_dimensions(notif_buf)
273273
end
274274

275275
function WindowAnimator:_apply_win_state(win, win_state)
276-
local win_updated = false
276+
local hl_updated = false
277277
if win_state.opacity then
278-
win_updated = true
279278
local notif_buf = self.notif_bufs[win]
280279
if notif_buf:is_valid() then
281-
notif_buf.highlights:set_opacity(win_state.opacity.position)
280+
hl_updated = notif_buf.highlights:set_opacity(win_state.opacity.position)
282281
vim.fn.setwinvar(
283282
win,
284283
"&winhl",
@@ -288,6 +287,7 @@ function WindowAnimator:_apply_win_state(win, win_state)
288287
end
289288
local exists, conf = util.get_win_config(win)
290289
local new_conf = {}
290+
local win_updated = false
291291
if not exists then
292292
self:_remove_win(win)
293293
else
@@ -317,7 +317,9 @@ function WindowAnimator:_apply_win_state(win, win_state)
317317
api.nvim_win_set_config(win, new_conf)
318318
end
319319
end
320-
return win_updated
320+
-- The 'flush' key is set to enforce redrawing during blocking event.
321+
vim.api.nvim__redraw({ win = win, valid = false, flush = true })
322+
return hl_updated or win_updated
321323
end
322324

323325
---@return WindowAnimator

0 commit comments

Comments
 (0)