changeset 28375:e466fdbe0699 v8.2.4713

patch 8.2.4713: plugins cannot track text scrolling Commit: https://github.com/vim/vim/commit/0937182d49fa8db50cec42785f22f1031760a0bd Author: LemonBoy <thatlemon@gmail.com> Date: Fri Apr 8 15:18:45 2022 +0100 patch 8.2.4713: plugins cannot track text scrolling Problem: Plugins cannot track text scrolling. Solution: Add the WinScrolled event. (closes https://github.com/vim/vim/issues/10102)
author Bram Moolenaar <Bram@vim.org>
date Fri, 08 Apr 2022 16:30:03 +0200
parents 14d6f5ebf810
children a85946ba5cd4
files runtime/doc/autocmd.txt src/autocmd.c src/edit.c src/gui.c src/main.c src/proto/autocmd.pro src/proto/window.pro src/structs.h src/testdir/test_autocmd.vim src/version.c src/vim.h src/window.c
diffstat 12 files changed, 98 insertions(+), 5 deletions(-) [+]
line wrap: on
line diff
--- a/runtime/doc/autocmd.txt
+++ b/runtime/doc/autocmd.txt
@@ -402,6 +402,8 @@ Name			triggered by ~
 |User|			to be used in combination with ":doautocmd"
 |SigUSR1|		after the SIGUSR1 signal has been detected
 
+|WinScrolled|		after scrolling or resizing a window
+
 
 The alphabetical list of autocommand events:		*autocmd-events-abc*
 
@@ -1228,7 +1230,13 @@ User				Never executed automatically.  T
 				Note that when `:doautocmd User MyEvent` is
 				used while there are no matching autocommands,
 				you will get an error.  If you don't want
-				that, define a dummy autocommand yourself.
+				that, either check whether an autocommand is
+				defined using `exists('#User#MyEvent')` or
+				define a dummy autocommand yourself.
+				Example: >
+				    if exists('#User#MyEvent')
+					doautocmd User MyEvent
+				    endif
 
 							*SigUSR1*
 SigUSR1				After the SIGUSR1 signal has been detected.
@@ -1317,10 +1325,23 @@ WinNew				When a new window was created.
 				the first window, when Vim has just started.
 				Before a WinEnter event.
 
+							*WinScrolled*
+WinScrolled			After scrolling the content of a window or
+				resizing a window.
+				The pattern is matched against the
+				|window-ID|.  Both <amatch> and <afile> are
+				set to the |window-ID|.
+				Non-recursive (the event cannot trigger
+				itself).  However, if the command causes the
+				window to scroll or change size another
+				WinScrolled event will be triggered later.
+				Does not trigger when the command is added,
+				only after the first scroll or resize.
+
 ==============================================================================
 6. Patterns					*autocmd-patterns* *{aupat}*
 
-The {aupat} argument of `:autocmd` can be a comma separated list.  This works as
+The {aupat} argument of `:autocmd` can be a comma-separated list.  This works as
 if the command was given with each pattern separately.  Thus this command: >
 	:autocmd BufRead *.txt,*.info set et
 Is equivalent to: >
--- a/src/autocmd.c
+++ b/src/autocmd.c
@@ -190,6 +190,7 @@ static struct event_name
     {"WinClosed",	EVENT_WINCLOSED},
     {"WinEnter",	EVENT_WINENTER},
     {"WinLeave",	EVENT_WINLEAVE},
+    {"WinScrolled",	EVENT_WINSCROLLED},
     {"VimResized",	EVENT_VIMRESIZED},
     {"TextYankPost",	EVENT_TEXTYANKPOST},
     {"VimSuspend",	EVENT_VIMSUSPEND},
@@ -1251,6 +1252,15 @@ do_autocmd_event(
 		    vim_free(rettv.vval.v_string);
 		}
 #endif
+		// Initialize the fields checked by the WinScrolled trigger to
+		// stop it from firing right after the first autocmd is defined.
+		if (event == EVENT_WINSCROLLED && !has_winscrolled())
+		{
+		    curwin->w_last_topline = curwin->w_topline;
+		    curwin->w_last_leftcol = curwin->w_leftcol;
+		    curwin->w_last_width = curwin->w_width;
+		    curwin->w_last_height = curwin->w_height;
+		}
 
 		if (is_buflocal)
 		{
@@ -1783,6 +1793,15 @@ trigger_cursorhold(void)
 }
 
 /*
+ * Return TRUE when there is a WinScrolled autocommand defined.
+ */
+    int
+has_winscrolled(void)
+{
+    return (first_autopat[(int)EVENT_WINSCROLLED] != NULL);
+}
+
+/*
  * Return TRUE when there is a CursorMoved autocommand defined.
  */
     int
@@ -2078,7 +2097,8 @@ apply_autocmds_group(
 		|| event == EVENT_DIRCHANGEDPRE
 		|| event == EVENT_MODECHANGED
 		|| event == EVENT_USER
-		|| event == EVENT_WINCLOSED)
+		|| event == EVENT_WINCLOSED
+		|| event == EVENT_WINSCROLLED)
 	{
 	    fname = vim_strsave(fname);
 	    autocmd_fname_full = TRUE; // don't expand it later
--- a/src/edit.c
+++ b/src/edit.c
@@ -1527,6 +1527,9 @@ ins_redraw(int ready)	    // not busy wi
 					(linenr_T)(curwin->w_cursor.lnum + 1));
     }
 
+    if (ready)
+	may_trigger_winscrolled(curwin);
+
     // Trigger SafeState if nothing is pending.
     may_trigger_safestate(ready
 	    && !ins_compl_active()
--- a/src/gui.c
+++ b/src/gui.c
@@ -5237,6 +5237,9 @@ gui_update_screen(void)
 	last_cursormoved = curwin->w_cursor;
     }
 
+    if (!finish_op)
+	may_trigger_winscrolled(curwin);
+
 # ifdef FEAT_CONCEAL
     if (conceal_update_lines
 	    && (conceal_old_cursor_line != conceal_new_cursor_line
--- a/src/main.c
+++ b/src/main.c
@@ -1336,6 +1336,14 @@ main_loop(
 		curbuf->b_last_changedtick = CHANGEDTICK(curbuf);
 	    }
 
+	    // Ensure curwin->w_topline and curwin->w_leftcol are up to date
+	    // before triggering a WinScrolled autocommand.
+	    update_topline();
+	    validate_cursor();
+
+	    if (!finish_op)
+		may_trigger_winscrolled(curwin);
+
 	    // If nothing is pending and we are going to wait for the user to
 	    // type a character, trigger SafeState.
 	    may_trigger_safestate(!op_pending() && restart_edit == 0);
--- a/src/proto/autocmd.pro
+++ b/src/proto/autocmd.pro
@@ -26,6 +26,7 @@ int has_cmdundefined(void);
 int has_textyankpost(void);
 int has_completechanged(void);
 int has_modechanged(void);
+int has_winscrolled(void);
 void block_autocmds(void);
 void unblock_autocmds(void);
 int is_autocmd_blocked(void);
--- a/src/proto/window.pro
+++ b/src/proto/window.pro
@@ -13,14 +13,15 @@ int make_windows(int count, int vertical
 void win_move_after(win_T *win1, win_T *win2);
 void win_equal(win_T *next_curwin, int current, int dir);
 void entering_window(win_T *win);
+void curwin_init(void);
 void close_windows(buf_T *buf, int keep_curwin);
 int one_window(void);
 int win_close(win_T *win, int free_buf);
+void may_trigger_winscrolled(win_T *wp);
 void win_close_othertab(win_T *win, int free_buf, tabpage_T *tp);
 void win_free_all(void);
 win_T *winframe_remove(win_T *win, int *dirp, tabpage_T *tp);
 void close_others(int message, int forceit);
-void curwin_init(void);
 int win_alloc_first(void);
 win_T *win_alloc_popup_win(void);
 void win_init_popup_win(win_T *wp, buf_T *buf);
--- a/src/structs.h
+++ b/src/structs.h
@@ -3510,6 +3510,12 @@ struct window_S
 				    // window
 #endif
 
+    // four fields that are only used when there is a WinScrolled autocommand
+    linenr_T	w_last_topline;	    // last known value for w_topline
+    colnr_T	w_last_leftcol;	    // last known value for w_leftcol
+    int		w_last_width;	    // last known value for w_width
+    int		w_last_height;	    // last known value for w_height
+
     /*
      * Layout of the window in the screen.
      * May need to add "msg_scrolled" to "w_winrow" in rare situations.
index eb1fa046c59575b5130d4d7f037e13a72a073810..3ff9d0b340fa85b8fd228345750b9b6aaec34582
GIT binary patch
literal 91873
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
--- a/src/version.c
+++ b/src/version.c
@@ -747,6 +747,8 @@ static char *(features[]) =
 static int included_patches[] =
 {   /* Add new patch number below this line */
 /**/
+    4713,
+/**/
     4712,
 /**/
     4711,
--- a/src/vim.h
+++ b/src/vim.h
@@ -1386,6 +1386,7 @@ enum auto_event
     EVENT_WINCLOSED,		// after closing a window
     EVENT_VIMSUSPEND,		// before Vim is suspended
     EVENT_VIMRESUME,		// after Vim is resumed
+    EVENT_WINSCROLLED,		// after Vim window was scrolled
 
     NUM_EVENTS			// MUST be the last one
 };
--- a/src/window.c
+++ b/src/window.c
@@ -2779,11 +2779,38 @@ trigger_winclosed(win_T *win)
     if (recursive)
 	return;
     recursive = TRUE;
-    vim_snprintf((char *)winid, sizeof(winid), "%i", win->w_id);
+    vim_snprintf((char *)winid, sizeof(winid), "%d", win->w_id);
     apply_autocmds(EVENT_WINCLOSED, winid, winid, FALSE, win->w_buffer);
     recursive = FALSE;
 }
 
+    void
+may_trigger_winscrolled(win_T *wp)
+{
+    static int	    recursive = FALSE;
+    char_u	    winid[NUMBUFLEN];
+
+    if (recursive || !has_winscrolled())
+	return;
+
+    if (wp->w_last_topline != wp->w_topline
+	    || wp->w_last_leftcol != wp->w_leftcol
+	    || wp->w_last_width != wp->w_width
+	    || wp->w_last_height != wp->w_height)
+    {
+	vim_snprintf((char *)winid, sizeof(winid), "%d", wp->w_id);
+
+	recursive = TRUE;
+	apply_autocmds(EVENT_WINSCROLLED, winid, winid, FALSE, wp->w_buffer);
+	recursive = FALSE;
+
+	wp->w_last_topline = wp->w_topline;
+	wp->w_last_leftcol = wp->w_leftcol;
+	wp->w_last_width = wp->w_width;
+	wp->w_last_height = wp->w_height;
+    }
+}
+
 /*
  * Close window "win" in tab page "tp", which is not the current tab page.
  * This may be the last window in that tab page and result in closing the tab,