fix(highlight): retry highlight computation when Normal has no background

Problem: if `Normal.bg` is nil when `compute_highlight_groups` first runs
(colorscheme not yet loaded), the neutral fallbacks are baked in and never
corrected — the `ColorScheme` autocmd only fires for explicit `:colorscheme`
calls, which may come too late for some plugin manager configurations.

Solution: when `Normal.bg` is absent, schedule a single deferred retry via
`vim.schedule` that recomputes all highlight groups and invalidates attached
buffer caches once the event loop settles. Also document the load-order
requirement and the retry behaviour in the highlight groups section of the
vimdoc.
This commit is contained in:
Barrett Ruth 2026-03-05 19:40:48 -05:00
parent 904f141366
commit d1f7acde8e
Signed by: barrett
GPG key ID: A6C96C9349D2FC81
2 changed files with 19 additions and 0 deletions

View file

@ -758,6 +758,13 @@ character-level groups blend at 60% for more contrast. Line-number groups
combine both: background from the line-level blend, foreground from the combine both: background from the line-level blend, foreground from the
character-level blend. character-level blend.
Note: highlight groups are computed when the first diff buffer is attached,
so your colorscheme must be loaded before any diff buffer opens. If `Normal`
has no background at that point (colorscheme loaded too late, or transparent
terminal), diffs.nvim schedules one deferred retry via |vim.schedule()| to
recompute once the event loop settles. To avoid relying on this, ensure your
colorscheme plugin has `priority = 1000` and `lazy = false`.
Fugitive unified diff highlights: ~ Fugitive unified diff highlights: ~
*DiffsAdd* *DiffsAdd*
DiffsAdd Background for `+` lines. Derived by blending DiffsAdd Background for `+` lines. Derived by blending

View file

@ -162,6 +162,7 @@ local default_config = {
local config = vim.deepcopy(default_config) local config = vim.deepcopy(default_config)
local initialized = false local initialized = false
local hl_retry_pending = false
---@diagnostic disable-next-line: missing-fields ---@diagnostic disable-next-line: missing-fields
local fast_hl_opts = {} ---@type diffs.HunkOpts local fast_hl_opts = {} ---@type diffs.HunkOpts
@ -477,6 +478,17 @@ local function compute_highlight_groups()
local add_fg = diff_added.fg or diff_add.fg or (dark and 0x80d080 or 0x206020) local add_fg = diff_added.fg or diff_add.fg or (dark and 0x80d080 or 0x206020)
local del_fg = diff_removed.fg or diff_delete.fg or (dark and 0xd08080 or 0x802020) local del_fg = diff_removed.fg or diff_delete.fg or (dark and 0xd08080 or 0x802020)
if not normal.bg and not hl_retry_pending then
hl_retry_pending = true
vim.schedule(function()
hl_retry_pending = false
compute_highlight_groups()
for bufnr, _ in pairs(attached_buffers) do
invalidate_cache(bufnr)
end
end)
end
local blended_add = blend_color(add_bg, bg, 0.4) local blended_add = blend_color(add_bg, bg, 0.4)
local blended_del = blend_color(del_bg, bg, 0.4) local blended_del = blend_color(del_bg, bg, 0.4)