fix(highlight): spurious underline in 'winblend' floating window #34614

Problem: When a floating window with high winblend uses a highlight group
         with underline (but without guisp), the underline appears red.

Solution: Only blend the special color (for underline/undercurl) if the
          foreground highlight actually has underline or undercurl set.
          Otherwise, ignore the special color.
This commit is contained in:
glepnir
2025-06-27 17:52:28 +08:00
committed by GitHub
parent 0b91e9f83b
commit 64753b5c37
2 changed files with 60 additions and 9 deletions

View File

@@ -726,11 +726,10 @@ int hl_blend_attrs(int back_attr, int front_attr, bool *through)
if (*through) { if (*through) {
cattrs = battrs; cattrs = battrs;
cattrs.rgb_fg_color = rgb_blend(ratio, battrs.rgb_fg_color, cattrs.rgb_fg_color = rgb_blend(ratio, battrs.rgb_fg_color, fattrs.rgb_bg_color);
fattrs.rgb_bg_color); // Only apply special colors when the foreground attribute has an underline or undercurl.
if (cattrs.rgb_ae_attr & (HL_UNDERLINE_MASK)) { if (fattrs_raw.rgb_ae_attr & (HL_UNDERLINE | HL_UNDERCURL)) {
cattrs.rgb_sp_color = rgb_blend(ratio, battrs.rgb_sp_color, cattrs.rgb_sp_color = rgb_blend(ratio, battrs.rgb_sp_color, fattrs.rgb_bg_color);
fattrs.rgb_bg_color);
} else { } else {
cattrs.rgb_sp_color = -1; cattrs.rgb_sp_color = -1;
} }
@@ -744,11 +743,9 @@ int hl_blend_attrs(int back_attr, int front_attr, bool *through)
if (ratio >= 50) { if (ratio >= 50) {
cattrs.rgb_ae_attr = hl_combine_ae(battrs.rgb_ae_attr, cattrs.rgb_ae_attr); cattrs.rgb_ae_attr = hl_combine_ae(battrs.rgb_ae_attr, cattrs.rgb_ae_attr);
} }
cattrs.rgb_fg_color = rgb_blend(ratio/2, battrs.rgb_fg_color, cattrs.rgb_fg_color = rgb_blend(ratio/2, battrs.rgb_fg_color, fattrs.rgb_fg_color);
fattrs.rgb_fg_color);
if (cattrs.rgb_ae_attr & (HL_UNDERLINE_MASK)) { if (cattrs.rgb_ae_attr & (HL_UNDERLINE_MASK)) {
cattrs.rgb_sp_color = rgb_blend(ratio/2, battrs.rgb_bg_color, cattrs.rgb_sp_color = rgb_blend(ratio/2, battrs.rgb_bg_color, fattrs.rgb_sp_color);
fattrs.rgb_sp_color);
} else { } else {
cattrs.rgb_sp_color = -1; cattrs.rgb_sp_color = -1;
} }

View File

@@ -8460,6 +8460,8 @@ describe('float window', function()
[30] = { bold = true, foreground = tonumber('0x00007f') }, [30] = { bold = true, foreground = tonumber('0x00007f') },
[31] = { foreground = Screen.colors.Red, blend = 80 }, [31] = { foreground = Screen.colors.Red, blend = 80 },
[32] = { foreground = Screen.colors.Blue1, blend = 100, bold = true }, [32] = { foreground = Screen.colors.Blue1, blend = 100, bold = true },
[33] = { foreground = Screen.colors.Gray0, underline = true },
[34] = { underline = true },
}) })
insert([[ insert([[
Lorem ipsum dolor sit amet, consectetur Lorem ipsum dolor sit amet, consectetur
@@ -8473,6 +8475,7 @@ describe('float window', function()
occaecat cupidatat non proident, sunt in culpa occaecat cupidatat non proident, sunt in culpa
qui officia deserunt mollit anim id est qui officia deserunt mollit anim id est
laborum.]]) laborum.]])
local curbufnr = api.nvim_get_current_buf()
local buf = api.nvim_create_buf(false, false) local buf = api.nvim_create_buf(false, false)
local test_data = { 'test', '', 'popup text' } local test_data = { 'test', '', 'popup text' }
api.nvim_buf_set_lines(buf, 0, -1, true, test_data) api.nvim_buf_set_lines(buf, 0, -1, true, test_data)
@@ -8824,6 +8827,57 @@ describe('float window', function()
| |
]]) ]])
end end
-- winblend highlight with underline (but without guisp) in a floatwin. #14453
command('fclose | hi TestUnderLine gui=underline')
api.nvim_buf_add_highlight(curbufnr, -1, 'TestUnderLine', 3, 0, -1)
api.nvim_buf_add_highlight(curbufnr, -1, 'TestUnderLine', 4, 0, -1)
api.nvim_buf_set_lines(buf, 0, -1, false, {})
api.nvim_open_win(buf, false, { relative = 'win', row = 0, col = 0, width = 50, height = 1 })
if multigrid then
screen:expect({
grid = [[
## grid 1
[2:--------------------------------------------------]|*8
[3:--------------------------------------------------]|
## grid 2
{34:Ut enim ad minim veniam, quis nostrud} |
{34:exercitation ullamco laboris nisi ut aliquip ex} |
ea commodo consequat. Duis aute irure dolor in |
reprehenderit in voluptate velit esse cillum |
dolore eu fugiat nulla pariatur. Excepteur sint |
occaecat cupidatat non proident, sunt in culpa |
{16:^qui officia deserunt mollit anim id est }|
laborum. |
## grid 3
|
## grid 5
{17: }|
]],
win_pos = { [2] = { height = 8, startcol = 0, startrow = 0, width = 50, win = 1000 } },
float_pos = { [5] = { 1002, 'NW', 2, 0, 0, true, 50, 1, 0, 0 } },
win_viewport = {
[2] = { win = 1000, topline = 3, botline = 11, curline = 9, curcol = 0, linecount = 11, sum_scroll_delta = 3 },
[5] = { win = 1002, topline = 0, botline = 1, curline = 0, curcol = 0, linecount = 1, sum_scroll_delta = 0 },
},
win_viewport_margins = {
[2] = { bottom = 0, left = 0, right = 0, top = 0, win = 1000 },
[5] = { bottom = 0, left = 0, right = 0, top = 0, win = 1002 },
},
})
else
screen:expect([[
{33:Ut enim ad minim veniam, quis nostrud}{26: }|
{34:exercitation ullamco laboris nisi ut aliquip ex} |
ea commodo consequat. Duis aute irure dolor in |
reprehenderit in voluptate velit esse cillum |
dolore eu fugiat nulla pariatur. Excepteur sint |
occaecat cupidatat non proident, sunt in culpa |
{16:^qui officia deserunt mollit anim id est }|
laborum. |
|
]])
end
end) end)
it('can overlap doublewidth chars', function() it('can overlap doublewidth chars', function()