aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/nvim/autocmd.c16
-rw-r--r--src/nvim/testdir/test_autocmd.vim26
-rw-r--r--src/nvim/window.c33
-rw-r--r--test/functional/autocmd/winscrolled_spec.lua1
4 files changed, 61 insertions, 15 deletions
diff --git a/src/nvim/autocmd.c b/src/nvim/autocmd.c
index 4df14411c5..54fa57c7a0 100644
--- a/src/nvim/autocmd.c
+++ b/src/nvim/autocmd.c
@@ -1142,13 +1142,17 @@ int autocmd_register(int64_t id, event_T event, char *pat, int patlen, int group
}
// Initialize the fields checked by the WinScrolled trigger to
- // stop it from firing right after the first autocmd is defined.
+ // prevent it from firing right after the first autocmd is
+ // defined.
if (event == EVENT_WINSCROLLED && !has_event(EVENT_WINSCROLLED)) {
- curwin->w_last_topline = curwin->w_topline;
- curwin->w_last_leftcol = curwin->w_leftcol;
- curwin->w_last_skipcol = curwin->w_skipcol;
- curwin->w_last_width = curwin->w_width;
- curwin->w_last_height = curwin->w_height;
+ tabpage_T *save_curtab = curtab;
+ FOR_ALL_TABS(tp) {
+ unuse_tabpage(curtab);
+ use_tabpage(tp);
+ snapshot_windows_scroll_size();
+ }
+ unuse_tabpage(curtab);
+ use_tabpage(save_curtab);
}
ap->cmds = NULL;
diff --git a/src/nvim/testdir/test_autocmd.vim b/src/nvim/testdir/test_autocmd.vim
index bfb4a23f42..3030ecdfa9 100644
--- a/src/nvim/testdir/test_autocmd.vim
+++ b/src/nvim/testdir/test_autocmd.vim
@@ -428,6 +428,32 @@ func Test_WinScrolled_once_only()
call StopVimInTerminal(buf)
endfunc
+" Check that WinScrolled is not triggered immediately when defined and there
+" are split windows.
+func Test_WinScrolled_not_when_defined()
+ CheckRunVimInTerminal
+
+ let lines =<< trim END
+ call setline(1, ['aaa', 'bbb'])
+ echo 'nothing happened'
+ func ShowTriggered(id)
+ echo 'triggered'
+ endfunc
+ END
+ call writefile(lines, 'Xtest_winscrolled_not', 'D')
+ let buf = RunVimInTerminal('-S Xtest_winscrolled_not', #{rows: 10, cols: 60, statusoff: 2})
+ call term_sendkeys(buf, ":split\<CR>")
+ call TermWait(buf)
+ " use a timer to show the message after redrawing
+ call term_sendkeys(buf, ":au WinScrolled * call timer_start(100, 'ShowTriggered')\<CR>")
+ call VerifyScreenDump(buf, 'Test_winscrolled_not_when_defined_1', {})
+
+ call term_sendkeys(buf, "\<C-E>")
+ call VerifyScreenDump(buf, 'Test_winscrolled_not_when_defined_2', {})
+
+ call StopVimInTerminal(buf)
+endfunc
+
func Test_WinScrolled_long_wrapped()
CheckRunVimInTerminal
diff --git a/src/nvim/window.c b/src/nvim/window.c
index 4a451975a4..f25e25e905 100644
--- a/src/nvim/window.c
+++ b/src/nvim/window.c
@@ -3868,6 +3868,27 @@ void close_others(int message, int forceit)
}
}
+/// Store the relevant window pointers for tab page "tp". To be used before
+/// use_tabpage().
+void unuse_tabpage(tabpage_T *tp)
+{
+ tp->tp_topframe = topframe;
+ tp->tp_firstwin = firstwin;
+ tp->tp_lastwin = lastwin;
+ tp->tp_curwin = curwin;
+}
+
+/// Set the relevant pointers to use tab page "tp". May want to call
+/// unuse_tabpage() first.
+void use_tabpage(tabpage_T *tp)
+{
+ curtab = tp;
+ topframe = curtab->tp_topframe;
+ firstwin = curtab->tp_firstwin;
+ lastwin = curtab->tp_lastwin;
+ curwin = curtab->tp_curwin;
+}
+
// Allocate the first window and put an empty buffer in it.
// Only called from main().
void win_alloc_first(void)
@@ -3878,11 +3899,8 @@ void win_alloc_first(void)
}
first_tabpage = alloc_tabpage();
- first_tabpage->tp_topframe = topframe;
curtab = first_tabpage;
- curtab->tp_firstwin = firstwin;
- curtab->tp_lastwin = lastwin;
- curtab->tp_curwin = curwin;
+ unuse_tabpage(first_tabpage);
}
// Init `aucmd_win`. This can only be done after the first window
@@ -4253,10 +4271,7 @@ static void enter_tabpage(tabpage_T *tp, buf_T *old_curbuf, bool trigger_enter_a
win_T *next_prevwin = tp->tp_prevwin;
tabpage_T *old_curtab = curtab;
- curtab = tp;
- firstwin = tp->tp_firstwin;
- lastwin = tp->tp_lastwin;
- topframe = tp->tp_topframe;
+ use_tabpage(tp);
if (old_curtab != curtab) {
tabpage_check_windows(old_curtab);
@@ -5265,7 +5280,7 @@ void win_new_screen_cols(void)
/// Make a snapshot of all the window scroll positions and sizes of the current
/// tab page.
-static void snapshot_windows_scroll_size(void)
+void snapshot_windows_scroll_size(void)
{
FOR_ALL_WINDOWS_IN_TAB(wp, curtab) {
wp->w_last_topline = wp->w_topline;
diff --git a/test/functional/autocmd/winscrolled_spec.lua b/test/functional/autocmd/winscrolled_spec.lua
index 6db2d53bbf..cd9c6dd168 100644
--- a/test/functional/autocmd/winscrolled_spec.lua
+++ b/test/functional/autocmd/winscrolled_spec.lua
@@ -104,6 +104,7 @@ describe('WinScrolled', function()
let g:scrolled = 0
au WinScrolled * let g:scrolled += 1
]])
+ eq(0, eval('g:scrolled'))
-- With the upper split focused, send a scroll-down event to the unfocused one.
meths.input_mouse('wheel', 'down', '', 0, 6, 0)