mirror of
https://github.com/neovim/neovim
synced 2025-07-16 09:11:51 +00:00
fix(display): adjust setting winline info for concealed lines (#33717)
Problem: Wrong winline info after partial redraw. Setting
`conceal_cursor_used` is unnecessarily spread out.
Solution: Rather than adjusting `wl_lastlnum` for the previous
winline, adjust it when setting the current winline.
Set `conceal_cursor_used` when the current window is redrawn.
(cherry picked from commit 97a6259442
)
This commit is contained in:
@ -2789,7 +2789,6 @@ int win_line(win_T *wp, linenr_T lnum, int startrow, int endrow, int col_rows, b
|
||||
curwin->w_cline_height = wlv.row - startrow;
|
||||
curwin->w_cline_folded = has_fold;
|
||||
curwin->w_valid |= (VALID_CHEIGHT|VALID_CROW);
|
||||
conceal_cursor_used = conceal_cursor_line(curwin);
|
||||
}
|
||||
|
||||
break;
|
||||
|
@ -19,8 +19,6 @@ typedef struct {
|
||||
} WinExtmark;
|
||||
EXTERN kvec_t(WinExtmark) win_extmark_arr INIT( = KV_INITIAL_VALUE);
|
||||
|
||||
EXTERN bool conceal_cursor_used INIT( = false);
|
||||
|
||||
/// Spell checking variables passed from win_update() to win_line().
|
||||
typedef struct {
|
||||
bool spv_has_spell; ///< drawn window has spell checking
|
||||
|
@ -135,6 +135,7 @@ typedef enum {
|
||||
static bool redraw_popupmenu = false;
|
||||
static bool msg_grid_invalid = false;
|
||||
static bool resizing_autocmd = false;
|
||||
static bool conceal_cursor_used = false;
|
||||
|
||||
/// Check if the cursor line needs to be redrawn because of 'concealcursor'.
|
||||
///
|
||||
@ -2047,6 +2048,9 @@ static void win_update(win_T *wp)
|
||||
|
||||
foldinfo_T cursorline_fi = { 0 };
|
||||
win_update_cursorline(wp, &cursorline_fi);
|
||||
if (wp == curwin) {
|
||||
conceal_cursor_used = conceal_cursor_line(curwin);
|
||||
}
|
||||
|
||||
win_check_ns_hl(wp);
|
||||
|
||||
@ -2123,21 +2127,13 @@ static void win_update(win_T *wp)
|
||||
|
||||
// If the line is concealed and has no filler lines, go to the next line.
|
||||
bool concealed = decor_conceal_line(wp, lnum - 1, false);
|
||||
if (concealed) {
|
||||
if (wp == curwin && lnum == curwin->w_cursor.lnum) {
|
||||
conceal_cursor_used = conceal_cursor_line(curwin);
|
||||
}
|
||||
if (win_get_fill(wp, lnum) == 0) {
|
||||
if (idx > 0) {
|
||||
wp->w_lines[idx - 1].wl_lastlnum = lnum + foldinfo.fi_lines - (foldinfo.fi_lines != 0);
|
||||
}
|
||||
if (lnum == mod_top && lnum < mod_bot) {
|
||||
mod_top += foldinfo.fi_lines ? foldinfo.fi_lines : 1;
|
||||
}
|
||||
lnum += foldinfo.fi_lines ? foldinfo.fi_lines : 1;
|
||||
spv.spv_capcol_lnum = 0;
|
||||
continue;
|
||||
if (concealed && win_get_fill(wp, lnum) == 0) {
|
||||
if (lnum == mod_top && lnum < mod_bot) {
|
||||
mod_top += foldinfo.fi_lines ? foldinfo.fi_lines : 1;
|
||||
}
|
||||
lnum += foldinfo.fi_lines ? foldinfo.fi_lines : 1;
|
||||
spv.spv_capcol_lnum = 0;
|
||||
continue;
|
||||
}
|
||||
|
||||
// When at start of changed lines: May scroll following lines
|
||||
@ -2189,8 +2185,8 @@ static void win_update(win_T *wp)
|
||||
// rows, and may insert/delete lines
|
||||
int j = idx;
|
||||
for (l = lnum; l < mod_bot; l++) {
|
||||
int n = plines_win_full(wp, l, &l, NULL, true, false);
|
||||
n -= (l == wp->w_topline ? adjust_plines_for_skipcol(wp) : 0);
|
||||
int n = (l == wp->w_topline ? -adjust_plines_for_skipcol(wp) : 0);
|
||||
n += plines_win_full(wp, l, &l, NULL, true, false);
|
||||
new_rows += MIN(n, wp->w_height_inner);
|
||||
j += n > 0; // don't count concealed lines
|
||||
if (new_rows > wp->w_grid.rows - row - 2) {
|
||||
@ -2306,23 +2302,19 @@ static void win_update(win_T *wp)
|
||||
spv.spv_capcol_lnum = 0;
|
||||
}
|
||||
|
||||
if (foldinfo.fi_lines == 0) {
|
||||
wp->w_lines[idx].wl_folded = false;
|
||||
wp->w_lines[idx].wl_foldend = lnum;
|
||||
wp->w_lines[idx].wl_lastlnum = lnum;
|
||||
did_update = DID_LINE;
|
||||
} else {
|
||||
foldinfo.fi_lines--;
|
||||
wp->w_lines[idx].wl_folded = true;
|
||||
wp->w_lines[idx].wl_foldend = lnum + foldinfo.fi_lines;
|
||||
wp->w_lines[idx].wl_lastlnum = lnum + foldinfo.fi_lines;
|
||||
did_update = DID_FOLD;
|
||||
}
|
||||
linenr_T lastlnum = lnum + foldinfo.fi_lines - (foldinfo.fi_lines > 0);
|
||||
wp->w_lines[idx].wl_folded = foldinfo.fi_lines > 0;
|
||||
wp->w_lines[idx].wl_foldend = lastlnum;
|
||||
wp->w_lines[idx].wl_lastlnum = lastlnum;
|
||||
did_update = foldinfo.fi_lines > 0 ? DID_FOLD : DID_LINE;
|
||||
|
||||
// Adjust "wl_lastlnum" for concealed lines below the last line in the window.
|
||||
while (row == wp->w_grid.rows
|
||||
&& wp->w_lines[idx].wl_lastlnum < buf->b_ml.ml_line_count
|
||||
// Adjust "wl_lastlnum" for concealed lines below this line, unless it should
|
||||
// still be drawn for below virt_lines attached to the current line. Below
|
||||
// virt_lines attached to a second adjacent concealed line are concealed.
|
||||
bool virt_below = decor_virt_lines(wp, lastlnum, lastlnum + 1, NULL, NULL, true) > 0;
|
||||
while (!virt_below && wp->w_lines[idx].wl_lastlnum < buf->b_ml.ml_line_count
|
||||
&& decor_conceal_line(wp, wp->w_lines[idx].wl_lastlnum, false)) {
|
||||
virt_below = false;
|
||||
wp->w_lines[idx].wl_lastlnum++;
|
||||
hasFolding(wp, wp->w_lines[idx].wl_lastlnum, NULL, &wp->w_lines[idx].wl_lastlnum);
|
||||
}
|
||||
@ -2342,17 +2334,15 @@ static void win_update(win_T *wp)
|
||||
if (dollar_vcol == -1) {
|
||||
wp->w_lines[idx].wl_size = (uint16_t)(row - srow);
|
||||
}
|
||||
idx++;
|
||||
lnum += foldinfo.fi_lines + 1;
|
||||
lnum = wp->w_lines[idx++].wl_lastlnum + 1;
|
||||
} else {
|
||||
// If:
|
||||
// - 'number' is set and below inserted/deleted lines, or
|
||||
// - 'relativenumber' is set and cursor moved vertically,
|
||||
// the text doesn't need to be redrawn, but the number column does.
|
||||
if (((wp->w_p_nu && mod_top != 0 && lnum >= mod_bot
|
||||
&& buf->b_mod_set && buf->b_mod_xlines != 0)
|
||||
|| (wp->w_p_rnu && wp->w_last_cursor_lnum_rnu != wp->w_cursor.lnum))
|
||||
&& !decor_conceal_line(wp, lnum - 1, true)) {
|
||||
if ((wp->w_p_nu && mod_top != 0 && lnum >= mod_bot
|
||||
&& buf->b_mod_set && buf->b_mod_xlines != 0)
|
||||
|| (wp->w_p_rnu && wp->w_last_cursor_lnum_rnu != wp->w_cursor.lnum)) {
|
||||
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, wp->w_lines[idx].wl_size, false, &spv, info);
|
||||
|
@ -2950,6 +2950,22 @@ describe('extmark decorations', function()
|
||||
{1:~ }|*4
|
||||
|
|
||||
]])
|
||||
-- Correct relativenumber for line below concealed line #33694
|
||||
feed('4Gk')
|
||||
screen:expect([[
|
||||
{2: 2 }for _,item in ipairs(items) do |
|
||||
{2:3 } if h^l_id_cell ~= nil then |
|
||||
{2: 1 } hl_id = hl_id_cell |
|
||||
{2: 3 } for _ = 1, (count or 1) do |
|
||||
{2: 4 } local cell = line[colpos] |
|
||||
{2: 5 } cell.text = text |
|
||||
{2: 6 } cell.hl_id = hl_id |
|
||||
{2: 7 } colpos = colpos+1 |
|
||||
{2: 8 } end |
|
||||
{2: 9 }end |
|
||||
{1:~ }|*4
|
||||
|
|
||||
]])
|
||||
-- Also with above virtual line #32744
|
||||
command('set nornu')
|
||||
api.nvim_buf_set_extmark(0, ns, 3, 0, { virt_lines = { { { "virt_below 4" } } } })
|
||||
|
Reference in New Issue
Block a user