diff --git a/src/nvim/drawline.c b/src/nvim/drawline.c index 6853e545e4..a469ea8b7f 100644 --- a/src/nvim/drawline.c +++ b/src/nvim/drawline.c @@ -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; diff --git a/src/nvim/drawline.h b/src/nvim/drawline.h index 9112deddb3..0b2e010d02 100644 --- a/src/nvim/drawline.h +++ b/src/nvim/drawline.h @@ -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 diff --git a/src/nvim/drawscreen.c b/src/nvim/drawscreen.c index 5201923a96..097733275f 100644 --- a/src/nvim/drawscreen.c +++ b/src/nvim/drawscreen.c @@ -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); diff --git a/test/functional/ui/decorations_spec.lua b/test/functional/ui/decorations_spec.lua index 8510e1edd9..f222f115f3 100644 --- a/test/functional/ui/decorations_spec.lua +++ b/test/functional/ui/decorations_spec.lua @@ -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" } } } })