diff options
author | luukvbaal <31730729+luukvbaal@users.noreply.github.com> | 2023-02-14 08:52:22 +0100 |
---|---|---|
committer | GitHub <noreply@github.com> | 2023-02-14 15:52:22 +0800 |
commit | 53968082675cd3b8d1809e53a47c0311b7347ef9 (patch) | |
tree | 21df9c0a71da05b9c6d189ee5a42ebc4267ed1b2 /src | |
parent | 20c9f4b3521fa7ab5c5997c0ec1a3df2b5bd0dbe (diff) | |
download | rneovim-53968082675cd3b8d1809e53a47c0311b7347ef9.tar.gz rneovim-53968082675cd3b8d1809e53a47c0311b7347ef9.tar.bz2 rneovim-53968082675cd3b8d1809e53a47c0311b7347ef9.zip |
fix(folds): cursorline highlight is not always applied on closed folds (#22242)
Problem: The cursorline highlight logic checks for `w_cursor.lnum`
which may be different from the line number passed to
`win_line()` even when the cursor is actually on that line.
Solution: Update cursor line highlight logic to check for the line
number of the start of a closed fold if necessary.
Diffstat (limited to 'src')
-rw-r--r-- | src/nvim/buffer_defs.h | 9 | ||||
-rw-r--r-- | src/nvim/drawline.c | 39 | ||||
-rw-r--r-- | src/nvim/drawscreen.c | 20 |
3 files changed, 39 insertions, 29 deletions
diff --git a/src/nvim/buffer_defs.h b/src/nvim/buffer_defs.h index 3601dc7062..cace4b1364 100644 --- a/src/nvim/buffer_defs.h +++ b/src/nvim/buffer_defs.h @@ -1112,20 +1112,23 @@ struct window_S { win_T *w_prev; ///< link to previous window win_T *w_next; ///< link to next window bool w_closing; ///< window is being closed, don't let - /// autocommands close it too. + ///< autocommands close it too. frame_T *w_frame; ///< frame containing this window pos_T w_cursor; ///< cursor position in buffer colnr_T w_curswant; ///< Column we want to be at. This is - /// used to try to stay in the same column - /// for up/down cursor motions. + ///< used to try to stay in the same column + ///< for up/down cursor motions. int w_set_curswant; // If set, then update w_curswant the next // time through cursupdate() to the // current virtual column + linenr_T w_cursorline; ///< Where 'cursorline' should be drawn, + ///< can be different from w_cursor.lnum + ///< for closed folds. linenr_T w_last_cursorline; ///< where last 'cursorline' was drawn pos_T w_last_cursormoved; ///< for CursorMoved event diff --git a/src/nvim/drawline.c b/src/nvim/drawline.c index e205850314..3bd55dbe09 100644 --- a/src/nvim/drawline.c +++ b/src/nvim/drawline.c @@ -303,7 +303,7 @@ static int draw_virt_text_item(buf_T *buf, int col, VirtText vt, HlMode hl_mode, static bool use_cursor_line_sign(win_T *wp, linenr_T lnum) { return wp->w_p_cul - && lnum == wp->w_cursor.lnum + && lnum == wp->w_cursorline && (wp->w_p_culopt_flags & CULOPT_NBR); } @@ -517,7 +517,7 @@ static void get_statuscol_display_info(statuscol_T *stcp, LineDrawState *draw_st static bool use_cursor_line_nr(win_T *wp, linenr_T lnum, int row, int startrow, int filler_lines) { return wp->w_p_cul - && lnum == wp->w_cursor.lnum + && lnum == wp->w_cursorline && (wp->w_p_culopt_flags & CULOPT_NBR) && (row == startrow + filler_lines || (row > startrow + filler_lines @@ -547,6 +547,12 @@ static inline void get_line_number_str(win_T *wp, linenr_T lnum, char *buf, size static int get_line_number_attr(win_T *wp, linenr_T lnum, int row, int startrow, int filler_lines) { + if (use_cursor_line_nr(wp, lnum, row, startrow, filler_lines)) { + // TODO(vim): Can we use CursorLine instead of CursorLineNr + // when CursorLineNr isn't set? + return win_hl_attr(wp, HLF_CLN); + } + if (wp->w_p_rnu) { if (lnum < wp->w_cursor.lnum) { // Use LineNrAbove @@ -558,12 +564,6 @@ static int get_line_number_attr(win_T *wp, linenr_T lnum, int row, int startrow, } } - if (use_cursor_line_nr(wp, lnum, row, startrow, filler_lines)) { - // TODO(vim): Can we use CursorLine instead of CursorLineNr - // when CursorLineNr isn't set? - return win_hl_attr(wp, HLF_CLN); - } - return win_hl_attr(wp, HLF_N); } @@ -960,20 +960,17 @@ int win_line(win_T *wp, linenr_T lnum, int startrow, int endrow, bool nochange, filler_todo = filler_lines; // Cursor line highlighting for 'cursorline' in the current window. - if (lnum == wp->w_cursor.lnum) { - // Do not show the cursor line in the text when Visual mode is active, - // because it's not clear what is selected then. - if (wp->w_p_cul && !(wp == curwin && VIsual_active) - && wp->w_p_culopt_flags != CULOPT_NBR) { - cul_screenline = (wp->w_p_wrap - && (wp->w_p_culopt_flags & CULOPT_SCRLINE)); - if (!cul_screenline) { - apply_cursorline_highlight(wp, lnum, &line_attr, &cul_attr, &line_attr_lowprio); - } else { - margin_columns_win(wp, &left_curline_col, &right_curline_col); - } - area_highlighting = true; + if (wp->w_p_cul && wp->w_p_culopt_flags != CULOPT_NBR && lnum == wp->w_cursorline + // Do not show the cursor line in the text when Visual mode is active, + // because it's not clear what is selected then. + && !(wp == curwin && VIsual_active)) { + cul_screenline = (wp->w_p_wrap && (wp->w_p_culopt_flags & CULOPT_SCRLINE)); + if (!cul_screenline) { + apply_cursorline_highlight(wp, lnum, &line_attr, &cul_attr, &line_attr_lowprio); + } else { + margin_columns_win(wp, &left_curline_col, &right_curline_col); } + area_highlighting = true; } SignTextAttrs sattrs[SIGN_SHOW_MAX]; // sign attributes for the sign column diff --git a/src/nvim/drawscreen.c b/src/nvim/drawscreen.c index 814d443031..2c0b6ea3b0 100644 --- a/src/nvim/drawscreen.c +++ b/src/nvim/drawscreen.c @@ -1552,7 +1552,15 @@ static void win_update(win_T *wp, DecorProviders *providers) wp->w_old_visual_col = 0; } - bool cursorline_standout = win_cursorline_standout(wp); + foldinfo_T cursorline_fi; + wp->w_cursorline = win_cursorline_standout(wp) ? wp->w_cursor.lnum : 0; + if (wp->w_p_cul) { + // Make sure that the cursorline on a closed fold is redrawn + cursorline_fi = fold_info(wp, wp->w_cursor.lnum); + if (cursorline_fi.fi_level > 0 && cursorline_fi.fi_lines > 0) { + wp->w_cursorline = cursorline_fi.fi_lnum; + } + } win_check_ns_hl(wp); @@ -1608,7 +1616,7 @@ static void win_update(win_T *wp, DecorProviders *providers) // if lines were inserted or deleted || (wp->w_match_head != NULL && buf->b_mod_xlines != 0))))) - || (cursorline_standout && lnum == wp->w_cursor.lnum) + || lnum == wp->w_cursorline || lnum == wp->w_last_cursorline) { if (lnum == mod_top) { top_to_mod = false; @@ -1759,7 +1767,8 @@ static void win_update(win_T *wp, DecorProviders *providers) // When lines are folded, display one line for all of them. // Otherwise, display normally (can be several display lines when // 'wrap' is on). - foldinfo_T foldinfo = fold_info(wp, lnum); + foldinfo_T foldinfo = wp->w_p_cul && lnum == wp->w_cursor.lnum ? + cursorline_fi : fold_info(wp, lnum); if (foldinfo.fi_lines == 0 && idx < wp->w_lines_valid @@ -1818,7 +1827,8 @@ static void win_update(win_T *wp, DecorProviders *providers) if (wp->w_p_rnu && wp->w_last_cursor_lnum_rnu != wp->w_cursor.lnum) { // 'relativenumber' set and cursor moved vertically: The // text doesn't need to be drawn, but the number column does. - foldinfo_T info = fold_info(wp, lnum); + foldinfo_T info = wp->w_p_cul && lnum == wp->w_cursor.lnum ? + cursorline_fi : fold_info(wp, lnum); (void)win_line(wp, lnum, srow, wp->w_grid.rows, true, true, info, &line_providers, &provider_err); } @@ -1853,7 +1863,7 @@ static void win_update(win_T *wp, DecorProviders *providers) // Now that the window has been redrawn with the old and new cursor line, // update w_last_cursorline. - wp->w_last_cursorline = cursorline_standout ? wp->w_cursor.lnum : 0; + wp->w_last_cursorline = wp->w_cursorline; wp->w_last_cursor_lnum_rnu = wp->w_p_rnu ? wp->w_cursor.lnum : 0; |