fix(drawline): initialize linebuf_attr to 0 instead of -1 (#27840)

This also obviates the end-of-line loop when there is virtual text.
This commit is contained in:
zeertzjq
2024-03-13 11:36:41 +08:00
committed by GitHub
parent 93c93a0e36
commit d5488633f6
2 changed files with 23 additions and 14 deletions

View File

@ -288,26 +288,23 @@ static void draw_virt_text(win_T *wp, buf_T *buf, int col_off, int *end_col, int
if (item->draw_col < 0) { if (item->draw_col < 0) {
continue; continue;
} }
int col = 0;
if (item->kind == kDecorKindUIWatched) { if (item->kind == kDecorKindUIWatched) {
// send mark position to UI // send mark position to UI
col = item->draw_col; WinExtmark m = { (NS)item->data.ui.ns_id, item->data.ui.mark_id, win_row, item->draw_col };
WinExtmark m = { (NS)item->data.ui.ns_id, item->data.ui.mark_id, win_row, col };
kv_push(win_extmark_arr, m); kv_push(win_extmark_arr, m);
} }
if (vt) { if (vt) {
int vcol = item->draw_col - col_off; int vcol = item->draw_col - col_off;
col = draw_virt_text_item(buf, item->draw_col, vt->data.virt_text, int col = draw_virt_text_item(buf, item->draw_col, vt->data.virt_text,
vt->hl_mode, max_col, vcol); vt->hl_mode, max_col, vcol);
if (vt->pos == kVPosEndOfLine && do_eol) { if (vt->pos == kVPosEndOfLine && do_eol) {
state->eol_col = col + 1; state->eol_col = col + 1;
} }
*end_col = MAX(*end_col, col);
} }
if (!vt || !(vt->flags & kVTRepeatLinebreak)) { if (!vt || !(vt->flags & kVTRepeatLinebreak)) {
item->draw_col = INT_MIN; // deactivate item->draw_col = INT_MIN; // deactivate
} }
*end_col = MAX(*end_col, col);
} }
} }
@ -898,7 +895,7 @@ static void win_line_start(win_T *wp, winlinevars_T *wlv)
wlv->need_lbr = false; wlv->need_lbr = false;
for (int i = 0; i < wp->w_grid.cols; i++) { for (int i = 0; i < wp->w_grid.cols; i++) {
linebuf_char[i] = schar_from_ascii(' '); linebuf_char[i] = schar_from_ascii(' ');
linebuf_attr[i] = -1; linebuf_attr[i] = 0;
linebuf_vcol[i] = -1; linebuf_vcol[i] = -1;
} }
} }
@ -2569,13 +2566,12 @@ int win_line(win_T *wp, linenr_T lnum, int startrow, int endrow, int col_rows, s
advance_color_col(&wlv, vcol_hlc(wlv)); advance_color_col(&wlv, vcol_hlc(wlv));
bool has_virttext = false;
// Make sure alignment is the same regardless // Make sure alignment is the same regardless
// if listchars=eol:X is used or not. // if listchars=eol:X is used or not.
const int eol_skip = (lcs_eol_todo && eol_hl_off == 0 ? 1 : 0); const int eol_skip = (lcs_eol_todo && eol_hl_off == 0 ? 1 : 0);
if (has_decor) { if (has_decor) {
has_virttext = decor_redraw_eol(wp, &decor_state, &wlv.line_attr, wlv.col + eol_skip); decor_redraw_eol(wp, &decor_state, &wlv.line_attr, wlv.col + eol_skip);
} }
if (((wp->w_p_cuc if (((wp->w_p_cuc
@ -2583,7 +2579,7 @@ int win_line(win_T *wp, linenr_T lnum, int startrow, int endrow, int col_rows, s
&& wp->w_virtcol < grid->cols * (ptrdiff_t)(wlv.row - startrow + 1) + start_col && wp->w_virtcol < grid->cols * (ptrdiff_t)(wlv.row - startrow + 1) + start_col
&& lnum != wp->w_cursor.lnum) && lnum != wp->w_cursor.lnum)
|| wlv.color_cols || wlv.line_attr_lowprio || wlv.line_attr || wlv.color_cols || wlv.line_attr_lowprio || wlv.line_attr
|| wlv.diff_hlf != 0 || has_virttext)) { || wlv.diff_hlf != 0)) {
int rightmost_vcol = get_rightmost_vcol(wp, wlv.color_cols); int rightmost_vcol = get_rightmost_vcol(wp, wlv.color_cols);
const int cuc_attr = win_hl_attr(wp, HLF_CUC); const int cuc_attr = win_hl_attr(wp, HLF_CUC);
const int mc_attr = win_hl_attr(wp, HLF_MC); const int mc_attr = win_hl_attr(wp, HLF_MC);
@ -2597,7 +2593,7 @@ int win_line(win_T *wp, linenr_T lnum, int startrow, int endrow, int col_rows, s
: 0; : 0;
const int base_attr = hl_combine_attr(wlv.line_attr_lowprio, diff_attr); const int base_attr = hl_combine_attr(wlv.line_attr_lowprio, diff_attr);
if (base_attr || wlv.line_attr || has_virttext) { if (base_attr || wlv.line_attr) {
rightmost_vcol = INT_MAX; rightmost_vcol = INT_MAX;
} }
@ -2624,7 +2620,7 @@ int win_line(win_T *wp, linenr_T lnum, int startrow, int endrow, int col_rows, s
break; break;
} }
wlv.vcol += 1; wlv.vcol++;
} }
} }

View File

@ -2301,8 +2301,21 @@ describe('extmark decorations', function()
]]} ]]}
end) end)
it('virtual text does not crash with blend, conceal and wrap #27836', function()
screen:try_resize(50, 3)
insert(('a'):rep(45) .. '|hidden|' .. ('b'):rep(45))
command('syntax match test /|hidden|/ conceal')
command('set conceallevel=2 concealcursor=n')
api.nvim_buf_set_extmark(0, ns, 0, 0, {virt_text = {{'FOO'}}, virt_text_pos='right_align', hl_mode='blend'})
screen:expect{grid=[[
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa FOO|
bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb^b |
|
]]}
end)
it('works with both hl_group and sign_hl_group', function() it('works with both hl_group and sign_hl_group', function()
screen:try_resize(screen._width, 3) screen:try_resize(50, 3)
insert('abcdefghijklmn') insert('abcdefghijklmn')
api.nvim_buf_set_extmark(0, ns, 0, 0, {sign_text='S', sign_hl_group='NonText', hl_group='Error', end_col=14}) api.nvim_buf_set_extmark(0, ns, 0, 0, {sign_text='S', sign_hl_group='NonText', hl_group='Error', end_col=14})
screen:expect{grid=[[ screen:expect{grid=[[