vim-patch:9.1.1136: Match highlighting marks a buffer region as changed (#32561)

Problem:  Match highlighting marks a buffer region to be redrawn as if
          its buffer text was changed, unnecessarily invoking syntax code.
Solution: Set the `w_redraw_top/bot` variables instead of the b_mod_* ones
          (Luuk van Baal)

7bbb0f357e
This commit is contained in:
luukvbaal
2025-02-23 09:35:26 +01:00
committed by GitHub
parent 1c81734871
commit 5a41f7e69c
3 changed files with 31 additions and 61 deletions

View File

@@ -2695,18 +2695,36 @@ void redraw_buf_line_later(buf_T *buf, linenr_T line, bool force)
}
}
void redraw_buf_range_later(buf_T *buf, linenr_T firstline, linenr_T lastline)
void redraw_win_range_later(win_T *wp, linenr_T first, linenr_T last)
{
if (last >= wp->w_topline && first < wp->w_botline) {
if (wp->w_redraw_top == 0 || wp->w_redraw_top > first) {
wp->w_redraw_top = first;
}
if (wp->w_redraw_bot == 0 || wp->w_redraw_bot < last) {
wp->w_redraw_bot = last;
}
redraw_later(wp, UPD_VALID);
}
}
/// Changed something in the current window, at buffer line "lnum", that
/// requires that line and possibly other lines to be redrawn.
/// Used when entering/leaving Insert mode with the cursor on a folded line.
/// Used to remove the "$" from a change command.
/// Note that when also inserting/deleting lines w_redraw_top and w_redraw_bot
/// may become invalid and the whole window will have to be redrawn.
void redrawWinline(win_T *wp, linenr_T lnum)
FUNC_ATTR_NONNULL_ALL
{
redraw_win_range_later(wp, lnum, lnum);
}
void redraw_buf_range_later(buf_T *buf, linenr_T first, linenr_T last)
{
FOR_ALL_WINDOWS_IN_TAB(wp, curtab) {
if (wp->w_buffer == buf
&& lastline >= wp->w_topline && firstline < wp->w_botline) {
if (wp->w_redraw_top == 0 || wp->w_redraw_top > firstline) {
wp->w_redraw_top = firstline;
}
if (wp->w_redraw_bot == 0 || wp->w_redraw_bot < lastline) {
wp->w_redraw_bot = lastline;
}
redraw_later(wp, UPD_VALID);
if (wp->w_buffer == buf) {
redraw_win_range_later(wp, first, last);
}
}
}
@@ -2805,27 +2823,6 @@ void win_redraw_last_status(const frame_T *frp)
}
}
/// Changed something in the current window, at buffer line "lnum", that
/// requires that line and possibly other lines to be redrawn.
/// Used when entering/leaving Insert mode with the cursor on a folded line.
/// Used to remove the "$" from a change command.
/// Note that when also inserting/deleting lines w_redraw_top and w_redraw_bot
/// may become invalid and the whole window will have to be redrawn.
void redrawWinline(win_T *wp, linenr_T lnum)
FUNC_ATTR_NONNULL_ALL
{
if (lnum >= wp->w_topline
&& lnum < wp->w_botline) {
if (wp->w_redraw_top == 0 || wp->w_redraw_top > lnum) {
wp->w_redraw_top = lnum;
}
if (wp->w_redraw_bot == 0 || wp->w_redraw_bot < lnum) {
wp->w_redraw_bot = lnum;
}
redraw_later(wp, UPD_VALID);
}
}
/// Return true if the cursor line in window "wp" may be concealed, according
/// to the 'concealcursor' option.
bool conceal_cursor_line(const win_T *wp)

View File

@@ -2098,10 +2098,7 @@ static void foldUpdateIEMS(win_T *const wp, linenr_T top, linenr_T bot)
// this in other situations, the changed lines will be redrawn anyway and
// this method can cause the whole window to be updated.
if (end != bot) {
if (wp->w_redraw_top == 0 || wp->w_redraw_top > top) {
wp->w_redraw_top = top;
}
wp->w_redraw_bot = MAX(wp->w_redraw_bot, end);
redraw_win_range_later(wp, top, end);
}
invalid_top = 0;

View File

@@ -190,19 +190,7 @@ static int match_add(win_T *wp, const char *const grp, const char *const pat, in
// Calculate top and bottom lines for redrawing area
if (toplnum != 0) {
if (wp->w_buffer->b_mod_set) {
if (wp->w_buffer->b_mod_top > toplnum) {
wp->w_buffer->b_mod_top = toplnum;
}
if (wp->w_buffer->b_mod_bot < botlnum) {
wp->w_buffer->b_mod_bot = botlnum;
}
} else {
wp->w_buffer->b_mod_set = true;
wp->w_buffer->b_mod_top = toplnum;
wp->w_buffer->b_mod_bot = botlnum;
wp->w_buffer->b_mod_xlines = 0;
}
redraw_win_range_later(wp, toplnum, botlnum);
m->mit_toplnum = toplnum;
m->mit_botlnum = botlnum;
rtype = UPD_VALID;
@@ -268,19 +256,7 @@ static int match_delete(win_T *wp, int id, bool perr)
vim_regfree(cur->mit_match.regprog);
xfree(cur->mit_pattern);
if (cur->mit_toplnum != 0) {
if (wp->w_buffer->b_mod_set) {
if (wp->w_buffer->b_mod_top > cur->mit_toplnum) {
wp->w_buffer->b_mod_top = cur->mit_toplnum;
}
if (wp->w_buffer->b_mod_bot < cur->mit_botlnum) {
wp->w_buffer->b_mod_bot = cur->mit_botlnum;
}
} else {
wp->w_buffer->b_mod_set = true;
wp->w_buffer->b_mod_top = cur->mit_toplnum;
wp->w_buffer->b_mod_bot = cur->mit_botlnum;
wp->w_buffer->b_mod_xlines = 0;
}
redraw_win_range_later(wp, cur->mit_toplnum, cur->mit_botlnum);
rtype = UPD_VALID;
}
xfree(cur->mit_pos_array);