diff options
-rw-r--r-- | src/nvim/window.c | 17 | ||||
-rw-r--r-- | test/functional/legacy/crash_spec.lua | 9 | ||||
-rw-r--r-- | test/old/testdir/crash/poc_win_enter_ext | bin | 0 -> 1958 bytes | |||
-rw-r--r-- | test/old/testdir/test_crash.vim | 8 |
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 Binary files differnew file mode 100644 index 0000000000..73f53b575b --- /dev/null +++ b/test/old/testdir/crash/poc_win_enter_ext 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, '$')) |