mirror of
https://github.com/neovim/neovim.git
synced 2026-05-05 21:45:05 +00:00
fix(api): nvim_set_hl boolean false corrupts underline styles (#38504)
Problem: setting one underline style to false clears bits belonging
to another style. `{underdouble = true, underdashed = false}` results
in undercurl because CHECK_FLAG_WITH_KEY does `m &= ~flag` which
doesn't work for multi-bit encoded values sharing HL_UNDERLINE_MASK.
Solution: use a local variable to derive the correct clear mask from
the flag. Clear the whole HL_UNDERLINE_MASK field instead of individual
bits, and only clear on false when the current style actually matches.
This commit is contained in:
@@ -1039,13 +1039,12 @@ HlAttrs dict2hlattrs(Dict(highlight) *dict, bool use_rgb, int *link_id, HlAttrs
|
|||||||
|
|
||||||
#define CHECK_FLAG_WITH_KEY(d, m, name, extra, flag) \
|
#define CHECK_FLAG_WITH_KEY(d, m, name, extra, flag) \
|
||||||
if (HAS_KEY_X(d, name)) { \
|
if (HAS_KEY_X(d, name)) { \
|
||||||
|
int32_t flag_ = (flag); \
|
||||||
|
int32_t cmask_ = (flag_ & HL_UNDERLINE_MASK) ? HL_UNDERLINE_MASK : flag_; \
|
||||||
if (d->name##extra) { \
|
if (d->name##extra) { \
|
||||||
if (flag & HL_UNDERLINE_MASK) { \
|
m = (m & ~cmask_) | flag_; \
|
||||||
m &= ~HL_UNDERLINE_MASK; \
|
} else if ((m & cmask_) == flag_) { \
|
||||||
} \
|
m &= ~cmask_; \
|
||||||
m |= flag; \
|
|
||||||
} else { \
|
|
||||||
m &= ~flag; \
|
|
||||||
} \
|
} \
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -290,6 +290,39 @@ describe('API: set highlight', function()
|
|||||||
hl = api.nvim_get_hl(0, { name = 'LinkedGroup' })
|
hl = api.nvim_get_hl(0, { name = 'LinkedGroup' })
|
||||||
eq(nil, hl.link)
|
eq(nil, hl.link)
|
||||||
eq(true, hl.bold)
|
eq(true, hl.bold)
|
||||||
|
|
||||||
|
-- underline style flags: false must not corrupt other styles
|
||||||
|
local unders = { 'underline', 'undercurl', 'underdouble', 'underdotted', 'underdashed' }
|
||||||
|
for _, a in ipairs(unders) do
|
||||||
|
for _, b in ipairs(unders) do
|
||||||
|
if a ~= b then
|
||||||
|
api.nvim_set_hl(0, 'TestGroup', { [a] = true, [b] = false })
|
||||||
|
hl = api.nvim_get_hl(0, { name = 'TestGroup' })
|
||||||
|
eq(true, hl[a])
|
||||||
|
eq(nil, hl[b])
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
api.nvim_set_hl(0, 'TestGroup', { underdouble = true, fg = '#ff0000', bold = true })
|
||||||
|
api.nvim_set_hl(0, 'TestGroup', { fg = '#00ff00', update = true })
|
||||||
|
hl = api.nvim_get_hl(0, { name = 'TestGroup' })
|
||||||
|
eq(true, hl.underdouble)
|
||||||
|
eq(true, hl.bold)
|
||||||
|
eq(65280, hl.fg)
|
||||||
|
|
||||||
|
api.nvim_set_hl(0, 'TestGroup', { underdashed = true, update = true })
|
||||||
|
hl = api.nvim_get_hl(0, { name = 'TestGroup' })
|
||||||
|
eq(true, hl.underdashed)
|
||||||
|
eq(nil, hl.underdouble)
|
||||||
|
|
||||||
|
api.nvim_set_hl(0, 'TestGroup', { underdouble = true, bold = true })
|
||||||
|
api.nvim_set_hl(0, 'TestGroup', { underdashed = false, update = true })
|
||||||
|
hl = api.nvim_get_hl(0, { name = 'TestGroup' })
|
||||||
|
eq(true, hl.underdouble)
|
||||||
|
api.nvim_set_hl(0, 'TestGroup', { underdouble = false, update = true })
|
||||||
|
hl = api.nvim_get_hl(0, { name = 'TestGroup' })
|
||||||
|
eq(nil, hl.underdouble)
|
||||||
|
eq(true, hl.bold)
|
||||||
end)
|
end)
|
||||||
end)
|
end)
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user