aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/nvim/window.c17
-rw-r--r--test/functional/legacy/crash_spec.lua9
-rw-r--r--test/old/testdir/crash/poc_win_enter_extbin0 -> 1958 bytes
-rw-r--r--test/old/testdir/test_crash.vim8
4 files changed, 28 insertions, 6 deletions
diff --git a/src/nvim/window.c b/src/nvim/window.c
index 7728efde33..ef1ef89d95 100644
--- a/src/nvim/window.c
+++ b/src/nvim/window.c
@@ -4470,11 +4470,12 @@ void tabpage_move(int nr)
redraw_tabline = true;
}
-// Go to another window.
-// When jumping to another buffer, stop Visual mode. Do this before
-// changing windows so we can yank the selection into the '*' register.
-// When jumping to another window on the same buffer, adjust its cursor
-// position to keep the same Visual area.
+/// Go to another window.
+/// When jumping to another buffer, stop Visual mode. Do this before
+/// changing windows so we can yank the selection into the '*' register.
+/// (note: this may trigger ModeChanged autocommand!)
+/// When jumping to another window on the same buffer, adjust its cursor
+/// position to keep the same Visual area.
void win_goto(win_T *wp)
{
win_T *owp = curwin;
@@ -4485,11 +4486,17 @@ void win_goto(win_T *wp)
}
if (wp->w_buffer != curbuf) {
+ // careful: triggers ModeChanged autocommand
reset_VIsual_and_resel();
} else if (VIsual_active) {
wp->w_cursor = curwin->w_cursor;
}
+ // autocommand may have made wp invalid
+ if (!win_valid(wp)) {
+ return;
+ }
+
win_enter(wp, true);
// Conceal cursor line in previous window, unconceal in current window.
diff --git a/test/functional/legacy/crash_spec.lua b/test/functional/legacy/crash_spec.lua
index 5094f81847..979ebd9e33 100644
--- a/test/functional/legacy/crash_spec.lua
+++ b/test/functional/legacy/crash_spec.lua
@@ -6,7 +6,6 @@ local feed = helpers.feed
before_each(clear)
--- oldtest: Test_crash1()
it('no crash when ending Visual mode while editing buffer closes window', function()
command('new')
command('autocmd ModeChanged v:n ++once close')
@@ -14,3 +13,11 @@ it('no crash when ending Visual mode while editing buffer closes window', functi
command('enew')
assert_alive()
end)
+
+it('no crash when ending Visual mode close the window to switch to', function()
+ command('new')
+ command('autocmd ModeChanged v:n ++once only')
+ feed('v')
+ command('wincmd p')
+ assert_alive()
+end)
diff --git a/test/old/testdir/crash/poc_win_enter_ext b/test/old/testdir/crash/poc_win_enter_ext
new file mode 100644
index 0000000000..73f53b575b
--- /dev/null
+++ b/test/old/testdir/crash/poc_win_enter_ext
Binary files differ
diff --git a/test/old/testdir/test_crash.vim b/test/old/testdir/test_crash.vim
index b093b053c5..11c5f4e014 100644
--- a/test/old/testdir/test_crash.vim
+++ b/test/old/testdir/test_crash.vim
@@ -128,6 +128,13 @@ func Test_crash1_2()
\ ' && echo "crash 1: [OK]" > '.. result .. "\<cr>")
call TermWait(buf, 150)
+ let file = 'crash/poc_win_enter_ext'
+ let cmn_args = "%s -u NONE -i NONE -n -e -s -S %s -c ':qa!'"
+ let args = printf(cmn_args, vim, file)
+ call term_sendkeys(buf, args ..
+ \ ' && echo "crash 2: [OK]" >> '.. result .. "\<cr>")
+ call TermWait(buf, 350)
+
" clean up
exe buf .. "bw!"
@@ -135,6 +142,7 @@ func Test_crash1_2()
let expected = [
\ 'crash 1: [OK]',
+ \ 'crash 2: [OK]',
\ ]
call assert_equal(expected, getline(1, '$'))