From 94085cfce82153e79eba5a1d277fe5799d973ffd Mon Sep 17 00:00:00 2001 From: zeertzjq Date: Tue, 13 Feb 2024 06:56:19 +0800 Subject: [PATCH] perf(redraw): reduce redraw with undo and extmarks or 'spell' (#27442) vim-patch:9.1.0100: Redrawing can be improved with undo and 'spell' Problem: When undoing with 'spell', redrawWinline() is called after changed_lines(), while later win_update() sets redraw type to UPD_NOT_VALID, even though w_redraw_top and w_redraw_bot are still valid. Solution: Only set redraw type to UPD_NOT_VALID when inserting/deleting lines after parts of window has pending redraw, i.e., when changed_lines() is called after redrawWinline(). (zeertzjq) closes: vim/vim#14019 https://github.com/vim/vim/commit/f2d90a351159fd6843f450850f52004f42e00183 --- src/nvim/change.c | 7 +++++++ src/nvim/drawscreen.c | 9 +-------- 2 files changed, 8 insertions(+), 8 deletions(-) diff --git a/src/nvim/change.c b/src/nvim/change.c index a7c885bf4d..1c7724f010 100644 --- a/src/nvim/change.c +++ b/src/nvim/change.c @@ -326,6 +326,13 @@ static void changed_common(buf_T *buf, linenr_T lnum, colnr_T col, linenr_T lnum wp->w_redr_type = UPD_VALID; } + // When inserting/deleting lines and the window has specific lines + // to be redrawn, w_redraw_top and w_redraw_bot may now be invalid, + // so just redraw everything. + if (xtra != 0 && wp->w_redraw_top != 0) { + redraw_later(wp, UPD_NOT_VALID); + } + linenr_T last = lnume + xtra - 1; // last line after the change // Reset "w_skipcol" if the topline length has become smaller to diff --git a/src/nvim/drawscreen.c b/src/nvim/drawscreen.c index 7e1a453497..ea6be5d6d3 100644 --- a/src/nvim/drawscreen.c +++ b/src/nvim/drawscreen.c @@ -1427,7 +1427,7 @@ static void draw_sep_connectors_win(win_T *wp) /// - if wp->w_buffer->b_mod_set set, update lines between /// b_mod_top and b_mod_bot. /// - if wp->w_redraw_top non-zero, redraw lines between -/// wp->w_redraw_top and wp->w_redr_bot. +/// wp->w_redraw_top and wp->w_redraw_bot. /// - continue redrawing when syntax status is invalid. /// 4. if scrolled up, update lines at the bottom. /// This results in three areas that may need updating: @@ -1537,13 +1537,6 @@ static void win_update(win_T *wp) if (wp->w_nrwidth != nrwidth_new) { type = UPD_NOT_VALID; wp->w_nrwidth = nrwidth_new; - } else if (buf->b_mod_set - && buf->b_mod_xlines != 0 - && wp->w_redraw_top != 0) { - // When there are both inserted/deleted lines and specific lines to be - // redrawn, w_redraw_top and w_redraw_bot may be invalid, just redraw - // everything (only happens when redrawing is off for while). - type = UPD_NOT_VALID; } else { // Set mod_top to the first line that needs displaying because of // changes. Set mod_bot to the first line after the changes.