fix(highlight): preserve inherited colors when update=true breaks links #38750

Problem: Breaking a link with update=true loses colors inherited from
the linked group.

Solution: Copy color indices from the linked group so inherited colors
remain visible in :hi output.
This commit is contained in:
glepnir
2026-04-11 22:14:27 +08:00
committed by GitHub
parent 0cb6dde5ee
commit 01567ad4f6
2 changed files with 20 additions and 2 deletions

View File

@@ -919,6 +919,7 @@ void set_hl_group(int id, HlAttrs attrs, Dict(highlight) *dict, int link_id)
HlGroup *g = &hl_table[idx];
g->sg_cleared = false;
int old_link = g->sg_link;
if (link_id > 0) {
g->sg_link = link_id;
@@ -965,6 +966,13 @@ void set_hl_group(int id, HlAttrs attrs, Dict(highlight) *dict, int link_id)
}
} else if (!update) {
*cattrs[j].dest = kColorIdxNone;
} else if (old_link > 0 && cattrs[j].val >= 0) {
// Copy color indices from the linked group so inherited colors remain visible in :hi output.
HlGroup *linked = &hl_table[old_link - 1];
int linked_idx = (j == 0) ? linked->sg_rgb_fg_idx
: (j == 1) ? linked->sg_rgb_bg_idx
: linked->sg_rgb_sp_idx;
*cattrs[j].dest = (linked_idx != kColorIdxNone) ? linked_idx : kColorIdxHex;
}
}

View File

@@ -285,11 +285,21 @@ describe('API: set highlight', function()
eq(tonumber('0x00ff00'), hl.fg)
eq(true, hl.italic)
api.nvim_set_hl(0, 'LinkedGroup', { link = 'Normal' })
api.nvim_set_hl(0, 'LinkedGroup', { bold = true, update = true })
api.nvim_set_hl(0, 'NamedColor', { fg = 'red', bg = 'blue' })
api.nvim_set_hl(0, 'LinkedGroup', { link = 'NamedColor' })
api.nvim_set_hl(0, 'LinkedGroup', { bold = true, fg = 'green', update = true })
hl = api.nvim_get_hl(0, { name = 'LinkedGroup' })
eq(nil, hl.link)
eq(true, hl.bold)
eq(
'LinkedGroup xxx cterm=bold gui=bold guifg=Green guibg=Blue',
n.exec_capture('hi LinkedGroup')
)
api.nvim_set_hl(0, 'LinkedGroup', { bg = '#121314', update = true })
eq(
'LinkedGroup xxx cterm=bold gui=bold guifg=Green guibg=#121314',
n.exec_capture('hi LinkedGroup')
)
-- underline style flags: false must not corrupt other styles
local unders = { 'underline', 'undercurl', 'underdouble', 'underdotted', 'underdashed' }