summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/edit.c2
-rw-r--r--src/gui.c2
-rw-r--r--src/main.c2
-rw-r--r--src/proto/window.pro2
-rw-r--r--src/testdir/test_autocmd.vim46
-rw-r--r--src/version.c2
-rw-r--r--src/window.c18
7 files changed, 54 insertions, 20 deletions
diff --git a/src/edit.c b/src/edit.c
index fad2a7b1a..c28c1f98a 100644
--- a/src/edit.c
+++ b/src/edit.c
@@ -1528,7 +1528,7 @@ ins_redraw(int ready) // not busy with something
}
if (ready)
- may_trigger_winscrolled(curwin);
+ may_trigger_winscrolled();
// Trigger SafeState if nothing is pending.
may_trigger_safestate(ready
diff --git a/src/gui.c b/src/gui.c
index 23694d195..f2f541e79 100644
--- a/src/gui.c
+++ b/src/gui.c
@@ -5238,7 +5238,7 @@ gui_update_screen(void)
}
if (!finish_op)
- may_trigger_winscrolled(curwin);
+ may_trigger_winscrolled();
# ifdef FEAT_CONCEAL
if (conceal_update_lines
diff --git a/src/main.c b/src/main.c
index fe3571b92..036ab0a1f 100644
--- a/src/main.c
+++ b/src/main.c
@@ -1342,7 +1342,7 @@ main_loop(
validate_cursor();
if (!finish_op)
- may_trigger_winscrolled(curwin);
+ may_trigger_winscrolled();
// If nothing is pending and we are going to wait for the user to
// type a character, trigger SafeState.
diff --git a/src/proto/window.pro b/src/proto/window.pro
index 589dd0931..9625942fe 100644
--- a/src/proto/window.pro
+++ b/src/proto/window.pro
@@ -17,7 +17,7 @@ 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 may_trigger_winscrolled(void);
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);
diff --git a/src/testdir/test_autocmd.vim b/src/testdir/test_autocmd.vim
index 9af79d8e1..724d0733f 100644
--- a/src/testdir/test_autocmd.vim
+++ b/src/testdir/test_autocmd.vim
@@ -314,17 +314,17 @@ func Test_WinScrolled()
CheckRunVimInTerminal
let lines =<< trim END
- set nowrap scrolloff=0
- for ii in range(1, 18)
- call setline(ii, repeat(nr2char(96 + ii), ii * 2))
- endfor
- let win_id = win_getid()
- let g:matched = v:false
- execute 'au WinScrolled' win_id 'let g:matched = v:true'
- let g:scrolled = 0
- au WinScrolled * let g:scrolled += 1
- au WinScrolled * let g:amatch = str2nr(expand('<amatch>'))
- au WinScrolled * let g:afile = str2nr(expand('<afile>'))
+ set nowrap scrolloff=0
+ for ii in range(1, 18)
+ call setline(ii, repeat(nr2char(96 + ii), ii * 2))
+ endfor
+ let win_id = win_getid()
+ let g:matched = v:false
+ execute 'au WinScrolled' win_id 'let g:matched = v:true'
+ let g:scrolled = 0
+ au WinScrolled * let g:scrolled += 1
+ au WinScrolled * let g:amatch = str2nr(expand('<amatch>'))
+ au WinScrolled * let g:afile = str2nr(expand('<afile>'))
END
call writefile(lines, 'Xtest_winscrolled')
let buf = RunVimInTerminal('-S Xtest_winscrolled', {'rows': 6})
@@ -364,6 +364,30 @@ func Test_WinScrolled()
call delete('Xtest_winscrolled')
endfunc
+func Test_WinScrolled_close_curwin()
+ CheckRunVimInTerminal
+
+ let lines =<< trim END
+ set nowrap scrolloff=0
+ call setline(1, ['aaa', 'bbb'])
+ vsplit
+ au WinScrolled * close
+ au VimLeave * call writefile(['123456'], 'Xtestout')
+ END
+ call writefile(lines, 'Xtest_winscrolled_close_curwin')
+ let buf = RunVimInTerminal('-S Xtest_winscrolled_close_curwin', {'rows': 6})
+
+ " This was using freed memory
+ call term_sendkeys(buf, "\<C-E>")
+ call TermWait(buf)
+ call StopVimInTerminal(buf)
+
+ call assert_equal(['123456'], readfile('Xtestout'))
+
+ call delete('Xtest_winscrolled_close_curwin')
+ call delete('Xtestout')
+endfunc
+
func Test_WinClosed()
" Test that the pattern is matched against the closed window's ID, and both
" <amatch> and <afile> are set to it.
diff --git a/src/version.c b/src/version.c
index 27de4e52f..84c669b18 100644
--- 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 */
/**/
+ 4739,
+/**/
4738,
/**/
4737,
diff --git a/src/window.c b/src/window.c
index 1eab3dcce..c9526a1d6 100644
--- a/src/window.c
+++ b/src/window.c
@@ -2784,9 +2784,13 @@ trigger_winclosed(win_T *win)
recursive = FALSE;
}
+/*
+ * Trigger WinScrolled for "curwin" if needed.
+ */
void
-may_trigger_winscrolled(win_T *wp)
+may_trigger_winscrolled(void)
{
+ win_T *wp = curwin;
static int recursive = FALSE;
char_u winid[NUMBUFLEN];
@@ -2804,10 +2808,14 @@ may_trigger_winscrolled(win_T *wp)
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;
+ // an autocmd may close the window, "wp" may be invalid now
+ if (win_valid_any_tab(wp))
+ {
+ 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;
+ }
}
}