fix(column): redraw 'statuscolumn' on wrapped lines with 'relativenumber'

Problem:  The 'statuscolumn' is not redrawn on the wrapped part of a
          line when moving the cursor with 'relativenumber' set.
Solution: Redraw the 'statuscolumn' for the entire line height in the
          "col_rows" win_line() code path.
This commit is contained in:
Luuk van Baal 2024-01-07 09:59:10 +01:00
parent 50284d07b6
commit c6864b0d14
3 changed files with 40 additions and 14 deletions

View File

@ -907,7 +907,7 @@ static void fix_for_boguscols(winlinevars_T *wlv)
/// @param lnum line to display
/// @param startrow first row relative to window grid
/// @param endrow last grid row to be redrawn
/// @param number_only only update the number column
/// @param col_rows only update the columns for this amount of rows
/// @param spv 'spell' related variables kept between calls for "wp"
/// @param foldinfo fold info for this line
/// @param[in, out] providers decoration providers active this line
@ -915,7 +915,7 @@ static void fix_for_boguscols(winlinevars_T *wlv)
/// or explicitly return `false`.
///
/// @return the number of last row the line occupies.
int win_line(win_T *wp, linenr_T lnum, int startrow, int endrow, bool number_only, spellvars_T *spv,
int win_line(win_T *wp, linenr_T lnum, int startrow, int endrow, int col_rows, spellvars_T *spv,
foldinfo_T foldinfo)
{
winlinevars_T wlv; // variables passed between functions
@ -1019,7 +1019,7 @@ int win_line(win_T *wp, linenr_T lnum, int startrow, int endrow, bool number_onl
buf_T *buf = wp->w_buffer;
const bool end_fill = (lnum == buf->b_ml.ml_line_count + 1);
if (!number_only) {
if (col_rows == 0) {
// To speed up the loop below, set extra_check when there is linebreak,
// trailing white space and/or syntax processing to be done.
extra_check = wp->w_p_lbr;
@ -1229,7 +1229,7 @@ int win_line(win_T *wp, linenr_T lnum, int startrow, int endrow, bool number_onl
line_attr_lowprio_save = wlv.line_attr_lowprio;
}
if (spv->spv_has_spell && !number_only) {
if (spv->spv_has_spell && col_rows == 0) {
// Prepare for spell checking.
extra_check = true;
@ -1321,7 +1321,7 @@ int win_line(win_T *wp, linenr_T lnum, int startrow, int endrow, bool number_onl
} else {
v = wp->w_leftcol;
}
if (v > 0 && !number_only) {
if (v > 0 && col_rows == 0) {
char *prev_ptr = ptr;
chartabsize_T cts;
int charsize = 0;
@ -1454,7 +1454,7 @@ int win_line(win_T *wp, linenr_T lnum, int startrow, int endrow, bool number_onl
}
}
if (!number_only && !has_fold && !end_fill) {
if (col_rows == 0 && !has_fold && !end_fill) {
v = ptr - line;
area_highlighting |= prepare_search_hl_line(wp, lnum, (colnr_T)v,
&line, &screen_search_hl, &search_attr,
@ -1566,13 +1566,19 @@ int win_line(win_T *wp, linenr_T lnum, int startrow, int endrow, bool number_onl
&& wp == curwin
&& lnum == wp->w_cursor.lnum
&& wlv.vcol >= wp->w_virtcol)
|| number_only)
|| col_rows > 0)
&& wlv.filler_todo <= 0) {
if (!number_only) {
if (col_rows == 0) {
draw_virt_text(wp, buf, win_col_offset, &wlv.col, wlv.row);
}
// don't clear anything after wlv.col
win_put_linebuf(wp, wlv.row, 0, wlv.col, wlv.col, bg_attr, false);
// update the 'statuscolumn' for the entire line size
if (col_rows > 0 && statuscol.draw && ++wlv.row - wlv.startrow < col_rows) {
draw_cols = true;
wlv.off = 0;
continue;
}
// Pretend we have finished updating the window. Except when
// 'cursorcolumn' is set.
if (wp->w_p_cuc) {

View File

@ -2285,9 +2285,8 @@ static void win_update(win_T *wp)
// Display one line
spellvars_T zero_spv = { 0 };
row = win_line(wp, lnum, srow, wp->w_grid.rows, false,
foldinfo.fi_lines > 0 ? &zero_spv : &spv,
foldinfo);
row = win_line(wp, lnum, srow, wp->w_grid.rows, 0,
foldinfo.fi_lines > 0 ? &zero_spv : &spv, foldinfo);
if (foldinfo.fi_lines == 0) {
wp->w_lines[idx].wl_folded = false;
@ -2325,7 +2324,7 @@ static void win_update(win_T *wp)
// text doesn't need to be drawn, but the number column does.
foldinfo_T info = wp->w_p_cul && lnum == wp->w_cursor.lnum
? cursorline_fi : fold_info(wp, lnum);
win_line(wp, lnum, srow, wp->w_grid.rows, true, &spv, info);
win_line(wp, lnum, srow, wp->w_grid.rows, wp->w_lines[idx].wl_size, &spv, info);
}
// This line does not need to be drawn, advance to the next one.
@ -2422,8 +2421,7 @@ static void win_update(win_T *wp)
// for ml_line_count+1 and only draw filler lines
spellvars_T zero_spv = { 0 };
foldinfo_T zero_foldinfo = { 0 };
row = win_line(wp, wp->w_botline, row, wp->w_grid.rows, false, &zero_spv,
zero_foldinfo);
row = win_line(wp, wp->w_botline, row, wp->w_grid.rows, 0, &zero_spv, zero_foldinfo);
}
} else if (dollar_vcol == -1) {
wp->w_botline = lnum;

View File

@ -510,6 +510,28 @@ describe('statuscolumn', function()
{0:~ }|
|
]])
-- Also test "col_rows" code path for 'relativenumber' cursor movement
command([[
set cpoptions-=n nocursorline relativenumber
set stc=%{v:virtnum<0?'virtual':(!v:virtnum?'buffer':'wrapped')}%=%{'\ '.v:virtnum.'\ '.v:lnum.'\ '.v:relnum}
]])
feed('kk')
screen:expect([[
{1:buffer 0 12 1}aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa|
{1:wrapped 1 12 1}aaaaaaaaaaa |
{1:buffer 0 13 0}aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa|
{1:wrapped 1 13 0}aaaaaaaaaa^a |
{1:buffer 0 14 1}aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa|
{1:wrapped 1 14 1}aaaaaaaaaaa |
{1:buffer 0 15 2}aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa|
{1:wrapped 1 15 2}aaaaaaaaaaa aaaaaaaaaaaaaaaaaaaaaaaaaaa|
{1:wrapped 2 15 2}aaaaaaaaaaaaaaaaaaaaaaa |
{1:virtual-3 15 2}virt_line1 |
{1:virtual-2 15 2}virt_line2 |
{1:virtual-1 15 2}END |
{0:~ }|
|
]])
end)
it('does not corrupt the screen with minwid sign item', function()