mirror of
https://github.com/neovim/neovim.git
synced 2026-11-02 09:49:02 -06:00
fix(decor): highlight without 'hl_eol' bleeds into wrap gaps #41160
Problem: 'linebreak' filler and 'breakindent'/'showbreak' padding are screen cells with no buffer character behind them, yet a decoration draws over them whether or not it asked to cover such cells. A highlight bounded to its text then paints a tail out to the edge of the row, most visible on inline code spans from plugins. That same highlight already leaves the cells past the end of a line alone, so it treats identical cells two different ways. Solution: Only a decoration with 'hl_eol' draws the gaps, which is what the flag already means at the end of a line. A full-width background such as a fenced code block sets it and still covers them. Classic :syntax has no such flag and is unchanged.
This commit is contained in:
1 parent
a4a544032a
commit
a8da01f8e6
5 files changed
+46
-17
No files matched your search
@@ -330,22 +330,36 @@ describe('listlbr', function()
|
||||
]])
|
||||
end)
|
||||
|
||||
it('extends a background highlight into the filler for the last word on a line', function()
|
||||
it('extends a background highlight into the filler only with hl_eol', function()
|
||||
local screen = Screen.new(20, 5)
|
||||
screen:add_extra_attr_ids({ [100] = { background = Screen.colors.Red } })
|
||||
source([[
|
||||
set wrap linebreak
|
||||
call setline(1, 'word1.word2verylongwordthatpushesdown')
|
||||
highlight TestBg guibg=Red ctermbg=Red
|
||||
let g:ns = nvim_create_namespace('')
|
||||
]])
|
||||
|
||||
-- The pushed-down word is the last thing on the line, so nothing absorbs the width overflow: a
|
||||
-- background highlight must still extend into the filler, since a solid color looks fine over
|
||||
-- blank cells (unlike underline/strikethrough, see tests above).
|
||||
command([[call nvim_buf_add_highlight(0, -1, 'TestBg', 0, 0, -1)]])
|
||||
-- 'hl_eol' covers cells with no text behind them, so the filler is covered too.
|
||||
command(
|
||||
'call nvim_buf_set_extmark(0, g:ns, 0, 0, '
|
||||
.. "{'end_row': 1, 'hl_group': 'TestBg', 'hl_eol': v:true})"
|
||||
)
|
||||
screen:expect([[
|
||||
{100:^word1. }|
|
||||
{100:word2verylongwordtha}|
|
||||
{100:tpushesdown }|
|
||||
{1:~ }|
|
||||
|
|
||||
]])
|
||||
|
||||
-- Without it the highlight decorates characters, so it stops where they do, just as an
|
||||
-- underline already does (see tests above).
|
||||
command('call nvim_buf_clear_namespace(0, -1, 0, -1)')
|
||||
command([[call nvim_buf_add_highlight(0, -1, 'TestBg', 0, 0, -1)]])
|
||||
screen:expect([[
|
||||
{100:^word1.} |
|
||||
{100:word2verylongwordtha}|
|
||||
{100:tpushesdown} |
|
||||
{1:~ }|
|
||||
|
|
||||
|
||||
@@ -767,7 +767,7 @@ describe('decorations providers', function()
|
||||
}
|
||||
end)
|
||||
|
||||
it("'hl_eol' and plain highlights extend into 'linebreak'/'breakindent'/'showbreak' gaps", function()
|
||||
it("'hl_eol' extends into 'linebreak'/'breakindent'/'showbreak' gaps", function()
|
||||
command('set wrap linebreak breakindent breakindentopt=shift:2')
|
||||
api.nvim_buf_set_lines(0, 0, -1, false, {
|
||||
' if vim.g.colors_name == "ferricferric" then',
|
||||
@@ -794,31 +794,31 @@ describe('decorations providers', function()
|
||||
|
|
||||
]])
|
||||
|
||||
-- No hl_eol here: these gaps have no real text, but the highlight is still active, not
|
||||
-- ending, so it must show through regardless.
|
||||
-- Without 'hl_eol' the highlight decorates characters, so it leaves the gaps alone, the same
|
||||
-- way it already leaves the cells past the end of the line alone.
|
||||
api.nvim_buf_set_extmark(0, ns, 0, 0, { id = id, end_row = 1, hl_group = 'DiffAdd' })
|
||||
screen:expect([[
|
||||
{100:^ if vim.g.colors_name == }|
|
||||
{100: }{101:>}{100:"ferricferric" then} |
|
||||
{100:^ if vim.g.colors_name == } |
|
||||
{1:>}{100:"ferricferric" then} |
|
||||
{1:~ }|*5
|
||||
|
|
||||
]])
|
||||
end)
|
||||
|
||||
it('breakindent keeps the highlight after a real linebreak word-push', function()
|
||||
-- The word pushed down by 'linebreak' resets decor_attr (it hides real word text, see listlbr_spec.lua), which must not then leak into
|
||||
-- 'breakindent's own gap on the row the word lands on.
|
||||
-- The word pushed down by 'linebreak' resets decor_attr (see listlbr_spec.lua), which must not
|
||||
-- then leak into 'breakindent's own gap on the row the word lands on.
|
||||
screen:try_resize(30, 5)
|
||||
screen:add_extra_attr_ids({ [100] = { background = Screen.colors.LightBlue } })
|
||||
command('set wrap linebreak breakindent')
|
||||
local line = ' This is a long indented line of plain text that will wrap nicely.'
|
||||
api.nvim_buf_set_lines(0, 0, -1, false, { line })
|
||||
local ns = api.nvim_create_namespace('code_bg2')
|
||||
api.nvim_buf_set_extmark(0, ns, 0, 0, { end_row = 0, end_col = #line, hl_group = 'DiffAdd' })
|
||||
api.nvim_buf_set_extmark(0, ns, 0, 0, { end_row = 1, hl_group = 'DiffAdd', hl_eol = true })
|
||||
screen:expect([[
|
||||
{100:^ This is a long indented }|
|
||||
{100: line of plain text that }|
|
||||
{100: will wrap nicely.} |
|
||||
{100: will wrap nicely. }|
|
||||
{1:~ }|
|
||||
|
|
||||
]])
|
||||
|
||||
Reference in new issue
Block a user