fix(events): avoid unnecessary CursorMoved (#24675)

Problem:    Temporarily changing current window in a script causes
            CursorMoved to be triggerd.
Solution:   Don't trigger CursorMoved if neither curwin nor cursor
            changed between two checks.
This commit is contained in:
zeertzjq
2023-08-12 09:50:17 +08:00
committed by GitHub
parent 6c07a189f2
commit 58a1ef8e6a
9 changed files with 44 additions and 24 deletions

View File

@@ -1030,7 +1030,8 @@ int autocmd_register(int64_t id, event_T event, const char *pat, int patlen, int
// If the event is CursorMoved, update the last cursor position
// position to avoid immediately triggering the autocommand
if (event == EVENT_CURSORMOVED && !has_event(EVENT_CURSORMOVED)) {
curwin->w_last_cursormoved = curwin->w_cursor;
last_cursormoved_win = curwin;
last_cursormoved = curwin->w_cursor;
}
// Initialize the fields checked by the WinScrolled and

View File

@@ -80,6 +80,11 @@ typedef kvec_t(AutoCmd) AutoCmdVec;
// apply_autocmds_group.
EXTERN bool au_did_filetype INIT(= false);
/// For CursorMoved event
EXTERN win_T *last_cursormoved_win INIT(= NULL);
/// For CursorMoved event, only used when last_cursormoved_win == curwin
EXTERN pos_T last_cursormoved INIT(= { 0, 0, 0 });
#ifdef INCLUDE_GENERATED_DECLARATIONS
# include "autocmd.h.generated.h"
#endif

View File

@@ -1101,7 +1101,6 @@ struct window_S {
///< 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
// the next seven are used to update the visual part
char w_old_visual_mode; ///< last known VIsual_mode

View File

@@ -361,9 +361,10 @@ static void changed_common(linenr_T lnum, colnr_T col, linenr_T lnume, linenr_T
}
// when the cursor line is changed always trigger CursorMoved
if (lnum <= curwin->w_cursor.lnum
if (last_cursormoved_win == curwin
&& lnum <= curwin->w_cursor.lnum
&& lnume + (xtra < 0 ? -xtra : xtra) > curwin->w_cursor.lnum) {
curwin->w_last_cursormoved.lnum = 0;
last_cursormoved.lnum = 0;
}
}

View File

@@ -1287,7 +1287,8 @@ void ins_redraw(bool ready)
// Trigger CursorMoved if the cursor moved. Not when the popup menu is
// visible, the command might delete it.
if (ready && has_event(EVENT_CURSORMOVEDI)
&& !equalpos(curwin->w_last_cursormoved, curwin->w_cursor)
&& (last_cursormoved_win != curwin
|| !equalpos(last_cursormoved, curwin->w_cursor))
&& !pum_visible()) {
// Need to update the screen first, to make sure syntax
// highlighting is correct after making a change (e.g., inserting
@@ -1300,7 +1301,8 @@ void ins_redraw(bool ready)
// getcurpos()
update_curswant();
ins_apply_autocmds(EVENT_CURSORMOVEDI);
curwin->w_last_cursormoved = curwin->w_cursor;
last_cursormoved_win = curwin;
last_cursormoved = curwin->w_cursor;
}
// Trigger TextChangedI if changedtick differs.

View File

@@ -1267,9 +1267,11 @@ static void normal_check_cursor_moved(NormalState *s)
{
// Trigger CursorMoved if the cursor moved.
if (!finish_op && has_event(EVENT_CURSORMOVED)
&& !equalpos(curwin->w_last_cursormoved, curwin->w_cursor)) {
&& (last_cursormoved_win != curwin
|| !equalpos(last_cursormoved, curwin->w_cursor))) {
apply_autocmds(EVENT_CURSORMOVED, NULL, NULL, false, curbuf);
curwin->w_last_cursormoved = curwin->w_cursor;
last_cursormoved_win = curwin;
last_cursormoved = curwin->w_cursor;
}
}

View File

@@ -4943,7 +4943,6 @@ static void win_enter_ext(win_T *const wp, const int flags)
if (other_buffer) {
apply_autocmds(EVENT_BUFENTER, NULL, NULL, false, curbuf);
}
curwin->w_last_cursormoved.lnum = 0;
}
maketitle();