vim-patch:8.2.3862: crash on exit with EXITFREE and using win_execute()

Problem:    Crash on exit with EXITFREE and using win_execute().
Solution:   Also save and restore tp_topframe. (issue vim/vim#9374)

dab17a0689

Couldn't repro the crash in the test, but I only care about this patch so
switch_win sets topframe properly for win_split_ins in nvim_open_win and
nvim_win_set_config.
Add a test using nvim_win_call and :wincmd, as I couldn't repro the issue via
nvim_open_win or nvim_win_set_config (though it's clear they're affected by this
patch).

That said, at that point, could just use {un}use_tabpage inside switch_win
instead, which also updates tp_curwin (though maybe continue to not set it in
restore_win). That would also fix possible inconsistent behaviour such as:

:call win_execute(w, "let curwin_nr1 = tabpagewinnr(1)")
:let curwin_nr2 = tabpagewinnr(1)

Where it's possible for curwin_nr1 != curwin_nr2 if these commands are run from
the 1st tabpage, but window "w" is in the 2nd (as the 1st tabpage's tp_curwin
may still be invalid). I'll probably PR a fix for that later in Vim.

Co-authored-by: Bram Moolenaar <Bram@vim.org>
This commit is contained in:
Sean Dewar 2024-03-09 20:24:08 +00:00
parent b52d15853e
commit c3d22d32ee
No known key found for this signature in database
GPG Key ID: 08CC2C83AD41B581
3 changed files with 40 additions and 0 deletions

View File

@ -958,9 +958,11 @@ int switch_win_noblock(switchwin_T *switchwin, win_T *win, tabpage_T *tp, bool n
if (no_display) {
curtab->tp_firstwin = firstwin;
curtab->tp_lastwin = lastwin;
curtab->tp_topframe = topframe;
curtab = tp;
firstwin = curtab->tp_firstwin;
lastwin = curtab->tp_lastwin;
topframe = curtab->tp_topframe;
} else {
goto_tabpage_tp(tp, false, false);
}
@ -989,9 +991,11 @@ void restore_win_noblock(switchwin_T *switchwin, bool no_display)
if (no_display) {
curtab->tp_firstwin = firstwin;
curtab->tp_lastwin = lastwin;
curtab->tp_topframe = topframe;
curtab = switchwin->sw_curtab;
firstwin = curtab->tp_firstwin;
lastwin = curtab->tp_lastwin;
topframe = curtab->tp_topframe;
} else {
goto_tabpage_tp(switchwin->sw_curtab, false, false);
}

View File

@ -3664,6 +3664,20 @@ describe('lua stdlib', function()
]]
)
end)
it('layout in current tabpage does not affect windows in others', function()
command('tab split')
local t2_move_win = api.nvim_get_current_win()
command('vsplit')
local t2_other_win = api.nvim_get_current_win()
command('tabprevious')
matches('E36: Not enough room$', pcall_err(command, 'execute "split|"->repeat(&lines)'))
command('vsplit')
-- Without vim-patch:8.2.3862, this gives E36, despite just the 1st tabpage being full.
exec_lua('vim.api.nvim_win_call(..., function() vim.cmd.wincmd "J" end)', t2_move_win)
eq({ 'col', { { 'leaf', t2_other_win }, { 'leaf', t2_move_win } } }, fn.winlayout(2))
end)
end)
describe('vim.iconv', function()

View File

@ -3,6 +3,7 @@
source view_util.vim
source check.vim
source vim9.vim
source term_util.vim
func NestedEval()
let nested = execute('echo "nested\nlines"')
@ -177,6 +178,27 @@ func Test_win_execute_visual_redraw()
bwipe!
endfunc
func Test_win_execute_on_startup()
CheckRunVimInTerminal
let lines =<< trim END
vim9script
[repeat('x', &columns)]->writefile('Xfile1')
silent tabedit Xfile2
var id = win_getid()
silent tabedit Xfile3
autocmd VimEnter * win_execute(id, 'close')
END
call writefile(lines, 'XwinExecute')
let buf = RunVimInTerminal('-p Xfile1 -Nu XwinExecute', {})
" this was crashing on exit with EXITFREE defined
call StopVimInTerminal(buf)
call delete('XwinExecute')
call delete('Xfile1')
endfunc
func Test_execute_cmd_with_null()
call assert_equal("", execute(v:_null_string))
call assert_equal("", execute(v:_null_list))