perf(screen): reduce cursorline redrawing when jumping around

vim-patch:8.2.4614: redrawing too much when 'cursorline' is set

Problem:    Redrawing too much when 'cursorline' is set and jumping around.
Solution:   Rely on win_update() to redraw the current and previous cursor
            line, do not mark lines as modified. (closes vim/vim#9996)
c20e46a4e3

This doesn't match the patch exactly, because I missed some lines when
porting patch 8.1.2029, and these lines were removed in this patch.

This also makes win_update() always update for 'concealcursor' like how
it always updates for 'cursorline', as 'cursorline' and 'concealcursor'
redrawing logic has been unified in Nvim.

As redrawing for 'cursorline' now always only requires VALID redraw
type, it is no longer necessary to call redraw_for_cursorline() in
nvim_win_set_cursor().
This commit is contained in:
zeertzjq
2022-03-23 11:28:32 +08:00
parent 3e9b4e917d
commit c29a14d1fa
4 changed files with 10 additions and 32 deletions

View File

@@ -119,7 +119,6 @@ void nvim_win_set_cursor(Window window, ArrayOf(Integer, 2) pos, Error *err)
update_topline_win(win); update_topline_win(win);
redraw_later(win, VALID); redraw_later(win, VALID);
redraw_for_cursorline(win);
win->w_redr_status = true; win->w_redr_status = true;
} }

View File

@@ -95,11 +95,6 @@ static void comp_botline(win_T *wp)
win_check_anchored_floats(wp); win_check_anchored_floats(wp);
} }
void reset_cursorline(void)
{
curwin->w_last_cursorline = 0;
}
// Redraw when w_cline_row changes and 'relativenumber' or 'cursorline' is set. // Redraw when w_cline_row changes and 'relativenumber' or 'cursorline' is set.
void redraw_for_cursorline(win_T *wp) void redraw_for_cursorline(win_T *wp)
FUNC_ATTR_NONNULL_ALL FUNC_ATTR_NONNULL_ALL
@@ -107,22 +102,9 @@ void redraw_for_cursorline(win_T *wp)
if ((wp->w_p_rnu || win_cursorline_standout(wp)) if ((wp->w_p_rnu || win_cursorline_standout(wp))
&& (wp->w_valid & VALID_CROW) == 0 && (wp->w_valid & VALID_CROW) == 0
&& !pum_visible()) { && !pum_visible()) {
if (wp->w_p_rnu) { // win_line() will redraw the number column and cursorline only.
// win_line() will redraw the number column only.
redraw_later(wp, VALID); redraw_later(wp, VALID);
} }
if (win_cursorline_standout(wp)) {
if (wp->w_redr_type <= VALID && wp->w_last_cursorline != 0) {
// "w_last_cursorline" may be outdated, worst case we redraw
// too much. This is optimized for moving the cursor around in
// the current window.
redrawWinline(wp, wp->w_last_cursorline);
redrawWinline(wp, wp->w_cursor.lnum);
} else {
redraw_later(wp, SOME_VALID);
}
}
}
} }
/* /*

View File

@@ -3962,11 +3962,8 @@ static char *set_bool_option(const int opt_idx, char_u *const varp, const int va
} else if ((int *)varp == &p_lnr) { } else if ((int *)varp == &p_lnr) {
// 'langnoremap' -> !'langremap' // 'langnoremap' -> !'langremap'
p_lrm = !p_lnr; p_lrm = !p_lnr;
} else if ((int *)varp == &curwin->w_p_cul && !value && old_value) {
// 'cursorline'
reset_cursorline();
// 'undofile'
} else if ((int *)varp == &curbuf->b_p_udf || (int *)varp == &p_udf) { } else if ((int *)varp == &curbuf->b_p_udf || (int *)varp == &p_udf) {
// 'undofile'
// Only take action when the option was set. When reset we do not // Only take action when the option was set. When reset we do not
// delete the undo file, the option may be set again without making // delete the undo file, the option may be set again without making
// any changes in between. // any changes in between.

View File

@@ -737,9 +737,6 @@ static void win_update(win_T *wp, DecorProviders *providers)
#define DID_FOLD 3 // updated a folded line #define DID_FOLD 3 // updated a folded line
int did_update = DID_NONE; int did_update = DID_NONE;
linenr_T syntax_last_parsed = 0; // last parsed text line linenr_T syntax_last_parsed = 0; // last parsed text line
// remember the current w_last_cursorline, it changes when drawing the new
// cursor line
linenr_T last_cursorline = wp->w_last_cursorline;
linenr_T mod_top = 0; linenr_T mod_top = 0;
linenr_T mod_bot = 0; linenr_T mod_bot = 0;
int save_got_int; int save_got_int;
@@ -1326,6 +1323,8 @@ static void win_update(win_T *wp, DecorProviders *providers)
DecorProviders line_providers; DecorProviders line_providers;
decor_providers_invoke_win(wp, providers, &line_providers, &provider_err); decor_providers_invoke_win(wp, providers, &line_providers, &provider_err);
bool cursorline_standout = win_cursorline_standout(wp);
for (;;) { for (;;) {
/* stop updating when reached the end of the window (check for _past_ /* stop updating when reached the end of the window (check for _past_
* the end of the window is at the end of the loop) */ * the end of the window is at the end of the loop) */
@@ -1370,8 +1369,8 @@ static void win_update(win_T *wp, DecorProviders *providers)
// if lines were inserted or deleted // if lines were inserted or deleted
|| (wp->w_match_head != NULL || (wp->w_match_head != NULL
&& buf->b_mod_xlines != 0))))) && buf->b_mod_xlines != 0)))))
|| (wp->w_p_cul && (lnum == wp->w_cursor.lnum || (cursorline_standout && lnum == wp->w_cursor.lnum)
|| lnum == last_cursorline))) { || lnum == wp->w_last_cursorline) {
if (lnum == mod_top) { if (lnum == mod_top) {
top_to_mod = false; top_to_mod = false;
} }
@@ -1604,6 +1603,9 @@ static void win_update(win_T *wp, DecorProviders *providers)
* End of loop over all window lines. * End of loop over all window lines.
*/ */
// 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;
if (idx > wp->w_lines_valid) { if (idx > wp->w_lines_valid) {
wp->w_lines_valid = idx; wp->w_lines_valid = idx;
@@ -2383,8 +2385,6 @@ static int win_line(win_T *wp, linenr_T lnum, int startrow, int endrow, bool noc
} }
area_highlighting = true; area_highlighting = true;
} }
// Update w_last_cursorline even if Visual mode is active.
wp->w_last_cursorline = wp->w_cursor.lnum;
} }
memset(sattrs, 0, sizeof(sattrs)); memset(sattrs, 0, sizeof(sattrs));