fix(drawline): correct highlight priority with Visual selection (#30706)

This commit is contained in:
zeertzjq 2024-10-08 06:24:36 +08:00 committed by GitHub
parent 88085c2e80
commit 376de1483e
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
4 changed files with 55 additions and 44 deletions

View File

@ -927,7 +927,8 @@ int win_line(win_T *wp, linenr_T lnum, int startrow, int endrow, int col_rows, s
bool noinvcur = false; // don't invert the cursor bool noinvcur = false; // don't invert the cursor
bool lnum_in_visual_area = false; bool lnum_in_visual_area = false;
bool attr_pri = false; // char_attr has priority int char_attr_pri = 0; // attributes with high priority
int char_attr_base = 0; // attributes with low priority
bool area_highlighting = false; // Visual or incsearch highlighting in this line bool area_highlighting = false; // Visual or incsearch highlighting in this line
int vi_attr = 0; // attributes for Visual and incsearch highlighting int vi_attr = 0; // attributes for Visual and incsearch highlighting
int area_attr = 0; // attributes desired by highlighting int area_attr = 0; // attributes desired by highlighting
@ -1741,16 +1742,14 @@ int win_line(win_T *wp, linenr_T lnum, int startrow, int endrow, int col_rows, s
} }
// Decide which of the highlight attributes to use. // Decide which of the highlight attributes to use.
attr_pri = true;
if (area_attr != 0) { if (area_attr != 0) {
wlv.char_attr = hl_combine_attr(wlv.line_attr, area_attr); char_attr_pri = hl_combine_attr(wlv.line_attr, area_attr);
if (!highlight_match) { if (!highlight_match) {
// let search highlight show in Visual area if possible // let search highlight show in Visual area if possible
wlv.char_attr = hl_combine_attr(search_attr, wlv.char_attr); char_attr_pri = hl_combine_attr(search_attr, char_attr_pri);
} }
} else if (search_attr != 0) { } else if (search_attr != 0) {
wlv.char_attr = hl_combine_attr(wlv.line_attr, search_attr); char_attr_pri = hl_combine_attr(wlv.line_attr, search_attr);
} else if (wlv.line_attr != 0 } else if (wlv.line_attr != 0
&& ((wlv.fromcol == -10 && wlv.tocol == MAXCOL) && ((wlv.fromcol == -10 && wlv.tocol == MAXCOL)
|| wlv.vcol < wlv.fromcol || wlv.vcol < wlv.fromcol
@ -1758,15 +1757,12 @@ int win_line(win_T *wp, linenr_T lnum, int startrow, int endrow, int col_rows, s
|| wlv.vcol >= wlv.tocol)) { || wlv.vcol >= wlv.tocol)) {
// Use wlv.line_attr when not in the Visual or 'incsearch' area // Use wlv.line_attr when not in the Visual or 'incsearch' area
// (area_attr may be 0 when "noinvcur" is set). // (area_attr may be 0 when "noinvcur" is set).
wlv.char_attr = wlv.line_attr; char_attr_pri = wlv.line_attr;
} else { } else {
attr_pri = false; char_attr_pri = 0;
wlv.char_attr = decor_attr;
}
if (folded_attr != 0) {
wlv.char_attr = hl_combine_attr(folded_attr, wlv.char_attr);
} }
char_attr_base = hl_combine_attr(folded_attr, decor_attr);
wlv.char_attr = hl_combine_attr(char_attr_base, char_attr_pri);
} }
if (draw_folded && has_foldtext && wlv.n_extra == 0 && wlv.col == win_col_offset) { if (draw_folded && has_foldtext && wlv.n_extra == 0 && wlv.col == win_col_offset) {
@ -1997,25 +1993,8 @@ int win_line(win_T *wp, linenr_T lnum, int startrow, int endrow, int col_rows, s
can_spell = TRISTATE_TO_BOOL(decor_state.spell, can_spell); can_spell = TRISTATE_TO_BOOL(decor_state.spell, can_spell);
} }
if (folded_attr) { char_attr_base = hl_combine_attr(folded_attr, decor_attr);
decor_attr = hl_combine_attr(folded_attr, decor_attr); wlv.char_attr = hl_combine_attr(char_attr_base, char_attr_pri);
}
if (decor_attr) {
if (!attr_pri) {
if (wlv.cul_attr) {
wlv.char_attr = 0 != wlv.line_attr_lowprio
? hl_combine_attr(wlv.cul_attr, decor_attr)
: hl_combine_attr(decor_attr, wlv.cul_attr);
} else {
wlv.char_attr = decor_attr;
}
} else {
wlv.char_attr = hl_combine_attr(decor_attr, wlv.char_attr);
}
} else if (!attr_pri) {
wlv.char_attr = 0;
}
// Check spelling (unless at the end of the line). // Check spelling (unless at the end of the line).
// Only do this when there is no syntax highlighting, the // Only do this when there is no syntax highlighting, the
@ -2083,11 +2062,8 @@ int win_line(win_T *wp, linenr_T lnum, int startrow, int endrow, int col_rows, s
} }
} }
if (spell_attr != 0) { if (spell_attr != 0) {
if (!attr_pri) { char_attr_base = hl_combine_attr(char_attr_base, spell_attr);
wlv.char_attr = hl_combine_attr(wlv.char_attr, spell_attr); wlv.char_attr = hl_combine_attr(char_attr_base, char_attr_pri);
} else {
wlv.char_attr = hl_combine_attr(spell_attr, wlv.char_attr);
}
} }
if (wp->w_buffer->terminal) { if (wp->w_buffer->terminal) {

View File

@ -1964,7 +1964,7 @@ describe('extmark decorations', function()
]]} ]]}
end) end)
pending('highlight applies to a full TAB in visual block mode', function() it('highlight applies to a full TAB in visual block mode', function()
screen:try_resize(50, 8) screen:try_resize(50, 8)
command('hi! Visual guifg=NONE guibg=LightGrey') command('hi! Visual guifg=NONE guibg=LightGrey')
api.nvim_buf_set_lines(0, 0, -1, true, {'asdf', '\tasdf', '\tasdf', '\tasdf', 'asdf'}) api.nvim_buf_set_lines(0, 0, -1, true, {'asdf', '\tasdf', '\tasdf', '\tasdf', 'asdf'})

View File

@ -55,6 +55,8 @@ describe('folded lines', function()
}, },
[19] = { background = Screen.colors.Yellow, foreground = Screen.colors.DarkBlue }, [19] = { background = Screen.colors.Yellow, foreground = Screen.colors.DarkBlue },
[20] = { background = Screen.colors.Red, bold = true, foreground = Screen.colors.Blue }, [20] = { background = Screen.colors.Red, bold = true, foreground = Screen.colors.Blue },
[21] = { background = Screen.colors.LightGrey, foreground = Screen.colors.Green },
[22] = { background = Screen.colors.Red, foreground = Screen.colors.Green },
}) })
end) end)
@ -2625,6 +2627,8 @@ describe('folded lines', function()
command('hi! CursorLine guibg=NONE guifg=Red gui=NONE') command('hi! CursorLine guibg=NONE guifg=Red gui=NONE')
command('hi F0 guibg=Red guifg=Black') command('hi F0 guibg=Red guifg=Black')
command('hi F1 guifg=White') command('hi F1 guifg=White')
command([[syn match Keyword /\<sentence\>/]])
command('hi! Keyword guibg=NONE guifg=Green')
api.nvim_set_option_value('cursorline', true, {}) api.nvim_set_option_value('cursorline', true, {})
api.nvim_set_option_value('foldcolumn', '4', {}) api.nvim_set_option_value('foldcolumn', '4', {})
api.nvim_set_option_value('foldtext', '', {}) api.nvim_set_option_value('foldtext', '', {})
@ -2662,7 +2666,7 @@ describe('folded lines', function()
## grid 2 ## grid 2
{7: }This is a | {7: }This is a |
{7:- }valid English | {7:- }valid English |
{7:+ }{5:sentence composed by······}| {7:+ }{21:sentence}{5: composed by······}|
{7:+ }{13:^in his cave.··············}| {7:+ }{13:^in his cave.··············}|
{1:~ }|*2 {1:~ }|*2
## grid 3 ## grid 3
@ -2672,7 +2676,7 @@ describe('folded lines', function()
screen:expect([[ screen:expect([[
{7: }This is a | {7: }This is a |
{7:- }valid English | {7:- }valid English |
{7:+ }{5:sentence composed by······}| {7:+ }{21:sentence}{5: composed by······}|
{7:+ }{13:^in his cave.··············}| {7:+ }{13:^in his cave.··············}|
{1:~ }|*2 {1:~ }|*2
| |
@ -2689,7 +2693,7 @@ describe('folded lines', function()
## grid 2 ## grid 2
{7: }This is a | {7: }This is a |
{7:- }^v{14:alid English} | {7:- }^v{14:alid English} |
{7:+ }{15:sentence composed by······}| {7:+ }{22:sentence}{15: composed by······}|
{7:+ }{15:in his cave.··············}| {7:+ }{15:in his cave.··············}|
{1:~ }|*2 {1:~ }|*2
## grid 3 ## grid 3
@ -2699,7 +2703,7 @@ describe('folded lines', function()
screen:expect([[ screen:expect([[
{7: }This is a | {7: }This is a |
{7:- }^v{14:alid English} | {7:- }^v{14:alid English} |
{7:+ }{15:sentence composed by······}| {7:+ }{22:sentence}{15: composed by······}|
{7:+ }{15:in his cave.··············}| {7:+ }{15:in his cave.··············}|
{1:~ }|*2 {1:~ }|*2
{11:-- VISUAL LINE --} | {11:-- VISUAL LINE --} |
@ -2715,7 +2719,7 @@ describe('folded lines', function()
## grid 2 ## grid 2
a si sihT{7: }| a si sihT{7: }|
{14:hsilgnE dila}^v{7: -}| {14:hsilgnE dila}^v{7: -}|
{15:······yb desopmoc ecnetnes}{7: +}| {15:······yb desopmoc }{22:ecnetnes}{7: +}|
{15:··············.evac sih ni}{7: +}| {15:··············.evac sih ni}{7: +}|
{1: ~}|*2 {1: ~}|*2
## grid 3 ## grid 3
@ -2725,7 +2729,7 @@ describe('folded lines', function()
screen:expect([[ screen:expect([[
a si sihT{7: }| a si sihT{7: }|
{14:hsilgnE dila}^v{7: -}| {14:hsilgnE dila}^v{7: -}|
{15:······yb desopmoc ecnetnes}{7: +}| {15:······yb desopmoc }{22:ecnetnes}{7: +}|
{15:··············.evac sih ni}{7: +}| {15:··············.evac sih ni}{7: +}|
{1: ~}|*2 {1: ~}|*2
{11:-- VISUAL LINE --} | {11:-- VISUAL LINE --} |

View File

@ -377,4 +377,35 @@ describe("'spell'", function()
| |
]]) ]])
end) end)
it('overrides syntax when Visual selection is active', function()
screen:try_resize(43, 3)
screen:set_default_attr_ids({
[0] = { bold = true, foreground = Screen.colors.Blue },
[1] = { foreground = Screen.colors.Blue },
[2] = { foreground = Screen.colors.Red },
[3] = { foreground = Screen.colors.Blue, underline = true },
[4] = { foreground = Screen.colors.Red, underline = true },
[5] = { bold = true },
})
exec([[
hi! Comment guibg=NONE guifg=Blue gui=NONE guisp=NONE
hi! SpellBad guibg=NONE guifg=Red gui=NONE guisp=NONE
hi! Visual guibg=NONE guifg=NONE gui=underline guisp=NONE
syn match Comment "//.*"
call setline(1, '// Here is a misspeld word.')
set spell
]])
screen:expect([[
{1:^// Here is a }{2:misspeld}{1: word.} |
{0:~ }|
|
]])
feed('V')
screen:expect([[
{1:^/}{3:/ Here is a }{4:misspeld}{3: word.} |
{0:~ }|
{5:-- VISUAL LINE --} |
]])
end)
end) end)