mirror of
				https://github.com/neovim/neovim.git
				synced 2025-11-04 09:44:31 +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_height = wlv.row - startrow;
 | 
				
			||||||
        curwin->w_cline_folded = has_fold;
 | 
					        curwin->w_cline_folded = has_fold;
 | 
				
			||||||
        curwin->w_valid |= (VALID_CHEIGHT|VALID_CROW);
 | 
					        curwin->w_valid |= (VALID_CHEIGHT|VALID_CROW);
 | 
				
			||||||
        conceal_cursor_used = conceal_cursor_line(curwin);
 | 
					 | 
				
			||||||
      }
 | 
					      }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
      break;
 | 
					      break;
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -19,8 +19,6 @@ typedef struct {
 | 
				
			|||||||
} WinExtmark;
 | 
					} WinExtmark;
 | 
				
			||||||
EXTERN kvec_t(WinExtmark) win_extmark_arr INIT( = KV_INITIAL_VALUE);
 | 
					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().
 | 
					/// Spell checking variables passed from win_update() to win_line().
 | 
				
			||||||
typedef struct {
 | 
					typedef struct {
 | 
				
			||||||
  bool spv_has_spell;         ///< drawn window has spell checking
 | 
					  bool spv_has_spell;         ///< drawn window has spell checking
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -135,6 +135,7 @@ typedef enum {
 | 
				
			|||||||
static bool redraw_popupmenu = false;
 | 
					static bool redraw_popupmenu = false;
 | 
				
			||||||
static bool msg_grid_invalid = false;
 | 
					static bool msg_grid_invalid = false;
 | 
				
			||||||
static bool resizing_autocmd = false;
 | 
					static bool resizing_autocmd = false;
 | 
				
			||||||
 | 
					static bool conceal_cursor_used = false;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
/// Check if the cursor line needs to be redrawn because of 'concealcursor'.
 | 
					/// 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 };
 | 
					  foldinfo_T cursorline_fi = { 0 };
 | 
				
			||||||
  win_update_cursorline(wp, &cursorline_fi);
 | 
					  win_update_cursorline(wp, &cursorline_fi);
 | 
				
			||||||
 | 
					  if (wp == curwin) {
 | 
				
			||||||
 | 
					    conceal_cursor_used = conceal_cursor_line(curwin);
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  win_check_ns_hl(wp);
 | 
					  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.
 | 
					      // If the line is concealed and has no filler lines, go to the next line.
 | 
				
			||||||
      bool concealed = decor_conceal_line(wp, lnum - 1, false);
 | 
					      bool concealed = decor_conceal_line(wp, lnum - 1, false);
 | 
				
			||||||
      if (concealed) {
 | 
					      if (concealed && win_get_fill(wp, lnum) == 0) {
 | 
				
			||||||
        if (wp == curwin && lnum == curwin->w_cursor.lnum) {
 | 
					        if (lnum == mod_top && lnum < mod_bot) {
 | 
				
			||||||
          conceal_cursor_used = conceal_cursor_line(curwin);
 | 
					          mod_top += foldinfo.fi_lines ? foldinfo.fi_lines : 1;
 | 
				
			||||||
        }
 | 
					 | 
				
			||||||
        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;
 | 
					 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
 | 
					        lnum += foldinfo.fi_lines ? foldinfo.fi_lines : 1;
 | 
				
			||||||
 | 
					        spv.spv_capcol_lnum = 0;
 | 
				
			||||||
 | 
					        continue;
 | 
				
			||||||
      }
 | 
					      }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
      // When at start of changed lines: May scroll following lines
 | 
					      // 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
 | 
					          // rows, and may insert/delete lines
 | 
				
			||||||
          int j = idx;
 | 
					          int j = idx;
 | 
				
			||||||
          for (l = lnum; l < mod_bot; l++) {
 | 
					          for (l = lnum; l < mod_bot; l++) {
 | 
				
			||||||
            int n = plines_win_full(wp, l, &l, NULL, true, false);
 | 
					            int n = (l == wp->w_topline ? -adjust_plines_for_skipcol(wp) : 0);
 | 
				
			||||||
            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);
 | 
					            new_rows += MIN(n, wp->w_height_inner);
 | 
				
			||||||
            j += n > 0;  // don't count concealed lines
 | 
					            j += n > 0;  // don't count concealed lines
 | 
				
			||||||
            if (new_rows > wp->w_grid.rows - row - 2) {
 | 
					            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;
 | 
					          spv.spv_capcol_lnum = 0;
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        if (foldinfo.fi_lines == 0) {
 | 
					        linenr_T lastlnum = lnum + foldinfo.fi_lines - (foldinfo.fi_lines > 0);
 | 
				
			||||||
          wp->w_lines[idx].wl_folded = false;
 | 
					        wp->w_lines[idx].wl_folded = foldinfo.fi_lines > 0;
 | 
				
			||||||
          wp->w_lines[idx].wl_foldend = lnum;
 | 
					        wp->w_lines[idx].wl_foldend = lastlnum;
 | 
				
			||||||
          wp->w_lines[idx].wl_lastlnum = lnum;
 | 
					        wp->w_lines[idx].wl_lastlnum = lastlnum;
 | 
				
			||||||
          did_update = DID_LINE;
 | 
					        did_update = foldinfo.fi_lines > 0 ? DID_FOLD : 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;
 | 
					 | 
				
			||||||
        }
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
        // Adjust "wl_lastlnum" for concealed lines below the last line in the window.
 | 
					        // Adjust "wl_lastlnum" for concealed lines below this line, unless it should
 | 
				
			||||||
        while (row == wp->w_grid.rows
 | 
					        // still be drawn for below virt_lines attached to the current line. Below
 | 
				
			||||||
               && wp->w_lines[idx].wl_lastlnum < buf->b_ml.ml_line_count
 | 
					        // 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)) {
 | 
					               && decor_conceal_line(wp, wp->w_lines[idx].wl_lastlnum, false)) {
 | 
				
			||||||
 | 
					          virt_below = false;
 | 
				
			||||||
          wp->w_lines[idx].wl_lastlnum++;
 | 
					          wp->w_lines[idx].wl_lastlnum++;
 | 
				
			||||||
          hasFolding(wp, wp->w_lines[idx].wl_lastlnum, NULL, &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) {
 | 
					      if (dollar_vcol == -1) {
 | 
				
			||||||
        wp->w_lines[idx].wl_size = (uint16_t)(row - srow);
 | 
					        wp->w_lines[idx].wl_size = (uint16_t)(row - srow);
 | 
				
			||||||
      }
 | 
					      }
 | 
				
			||||||
      idx++;
 | 
					      lnum = wp->w_lines[idx++].wl_lastlnum + 1;
 | 
				
			||||||
      lnum += foldinfo.fi_lines + 1;
 | 
					 | 
				
			||||||
    } else {
 | 
					    } else {
 | 
				
			||||||
      // If:
 | 
					      // If:
 | 
				
			||||||
      // - 'number' is set and below inserted/deleted lines, or
 | 
					      // - 'number' is set and below inserted/deleted lines, or
 | 
				
			||||||
      // - 'relativenumber' is set and cursor moved vertically,
 | 
					      // - 'relativenumber' is set and cursor moved vertically,
 | 
				
			||||||
      // the text doesn't need to be redrawn, but the number column does.
 | 
					      // the text doesn't need to be redrawn, but the number column does.
 | 
				
			||||||
      if (((wp->w_p_nu && mod_top != 0 && lnum >= mod_bot
 | 
					      if ((wp->w_p_nu && mod_top != 0 && lnum >= mod_bot
 | 
				
			||||||
            && buf->b_mod_set && buf->b_mod_xlines != 0)
 | 
					           && buf->b_mod_set && buf->b_mod_xlines != 0)
 | 
				
			||||||
           || (wp->w_p_rnu && wp->w_last_cursor_lnum_rnu != wp->w_cursor.lnum))
 | 
					          || (wp->w_p_rnu && wp->w_last_cursor_lnum_rnu != wp->w_cursor.lnum)) {
 | 
				
			||||||
          && !decor_conceal_line(wp, lnum - 1, true)) {
 | 
					 | 
				
			||||||
        foldinfo_T info = wp->w_p_cul && lnum == wp->w_cursor.lnum
 | 
					        foldinfo_T info = wp->w_p_cul && lnum == wp->w_cursor.lnum
 | 
				
			||||||
                          ? cursorline_fi : fold_info(wp, 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);
 | 
					        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
 | 
					      {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
 | 
					    -- Also with above virtual line #32744
 | 
				
			||||||
    command('set nornu')
 | 
					    command('set nornu')
 | 
				
			||||||
    api.nvim_buf_set_extmark(0, ns, 3, 0, { virt_lines = { { { "virt_below 4" } } } })
 | 
					    api.nvim_buf_set_extmark(0, ns, 3, 0, { virt_lines = { { { "virt_below 4" } } } })
 | 
				
			||||||
 
 | 
				
			|||||||
		Reference in New Issue
	
	Block a user