fix(api): crash when moving curwin to other tabpage #35679

Problem: nvim_win_set_config may crash when attempting to move curwin to a
different tabpage if there is no other non-float available to switch to.

Solution: fix the crash. Fix ONE_WINDOW checks in winframe_find_altwin and
win_altframe to consider floating windows by instead using one_window. Allow
one_window to consider non-current tabpages. We can use one_window in
win_close_othertab now to also better reflect its use in win_close.

Co-authored-by: Sean Dewar <6256228+seandewar@users.noreply.github.com>
This commit is contained in:
glepnir
2025-09-09 09:30:20 +08:00
committed by GitHub
parent c951fa9eeb
commit c553008e74
5 changed files with 69 additions and 28 deletions

View File

@@ -2309,11 +2309,42 @@ describe('API/win', function()
eq('editor', api.nvim_win_get_config(win).relative)
end)
it('throws error when attempting to move the last window', function()
it('throws error when attempting to move the last non-floating window', function()
local err = pcall_err(api.nvim_win_set_config, 0, {
vertical = false,
})
eq('Cannot move last window', err)
eq('Cannot move last non-floating window', err)
local win1 = api.nvim_get_current_win()
command('tabnew')
eq(
'Cannot move last non-floating window',
pcall_err(api.nvim_win_set_config, 0, { win = win1, split = 'left' })
)
api.nvim_open_win(0, false, { relative = 'editor', width = 5, height = 5, row = 1, col = 1 })
eq(
'Cannot move last non-floating window',
pcall_err(api.nvim_win_set_config, 0, { win = win1, split = 'left' })
)
-- If it's no longer the last non-float, still an error if autocommands make it the last
-- non-float again before it's moved.
command('vsplit')
exec_lua(function()
vim.api.nvim_create_autocmd('WinEnter', {
once = true,
callback = function()
vim.api.nvim_win_set_config(
0,
{ relative = 'editor', width = 5, height = 5, row = 1, col = 1 }
)
end,
})
end)
eq(
'Cannot move last non-floating window',
pcall_err(api.nvim_win_set_config, 0, { win = win1, split = 'left' })
)
end)
it('passing retval of get_config results in no-op', function()