mirror of
https://github.com/neovim/neovim.git
synced 2025-10-14 22:06:07 +00:00
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.
This commit is contained in:
@@ -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
|
||||
|
||||
|
@@ -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
|
||||
|
@@ -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;
|
||||
|
||||
|
Reference in New Issue
Block a user