fix(api): win_set_config error message for splitting from a float #35650

Problem: after #34287 nvim_win_set_config no longer errors when attempting to
split from a floating window only if "win" is 0.

Solution: fix the regression, reduce the scope of "parent" and similar checks to
only where it's currently used and add test coverage for the errors.

(cherry picked from commit da39966a3a)
This commit is contained in:
Sean Dewar
2025-09-06 21:22:46 +01:00
committed by github-actions[bot]
parent 0f6a180bcc
commit 5aa6257e8c
2 changed files with 81 additions and 24 deletions

View File

@@ -410,25 +410,6 @@ void nvim_win_set_config(Window window, Dict(win_config) *config, Error *err)
if (!parse_win_config(win, config, &fconfig, !was_split || to_split, err)) {
return;
}
win_T *parent = config->win == 0 ? curwin : NULL;
tabpage_T *parent_tp = config->win == 0 ? curtab : NULL;
if (config->win > 0) {
parent = find_window_by_handle(fconfig.window, err);
if (!parent) {
return;
} else if (to_split && parent->w_floating) {
api_set_error(err, kErrorTypeException, "Cannot split a floating window");
return;
}
parent_tp = win_find_tabpage(parent);
// Prevent autocmd window from being moved into another tabpage
if (is_aucmd_win(win) && win_tp != parent_tp) {
api_set_error(err, kErrorTypeException, "Cannot move autocmd win to another tabpage");
return;
}
}
if (was_split && !to_split) {
if (!win_new_float(win, false, fconfig, err)) {
@@ -436,6 +417,34 @@ void nvim_win_set_config(Window window, Dict(win_config) *config, Error *err)
}
redraw_later(win, UPD_NOT_VALID);
} else if (to_split) {
win_T *parent = NULL;
tabpage_T *parent_tp = NULL;
if (config->win == 0) {
parent = curwin;
parent_tp = curtab;
} else if (config->win > 0) {
parent = find_window_by_handle(fconfig.window, err);
if (!parent) {
return;
}
parent_tp = win_find_tabpage(parent);
}
if (parent) {
if (parent->w_floating) {
api_set_error(err, kErrorTypeException, "Cannot split a floating window");
return;
}
if (is_aucmd_win(win) && win_tp != parent_tp) {
api_set_error(err, kErrorTypeException, "Cannot move autocmd window to another tabpage");
return;
}
// Can't move the cmdwin or its old curwin to a different tabpage.
if ((win == cmdwin_win || win == cmdwin_old_curwin) && win_tp != parent_tp) {
api_set_error(err, kErrorTypeException, "%s", e_cmdwin);
return;
}
}
WinSplit old_split = win_split_dir(win);
if (has_vertical && !has_split) {
if (config->vertical) {
@@ -463,11 +472,6 @@ void nvim_win_set_config(Window window, Dict(win_config) *config, Error *err)
if (!check_split_disallowed_err(win, err)) {
return; // error already set
}
// Can't move the cmdwin or its old curwin to a different tabpage.
if ((win == cmdwin_win || win == cmdwin_old_curwin) && parent && parent_tp != win_tp) {
api_set_error(err, kErrorTypeException, "%s", e_cmdwin);
return;
}
bool to_split_ok = false;
// If we are moving curwin to another tabpage, switch windows *before* we remove it from the

View File

@@ -2996,5 +2996,58 @@ describe('API/win', function()
eq({ { 'OLD_FOOTER' } }, api.nvim_win_get_config(win).footer)
end)
end)
it('cannot split from a float', function()
local win = api.nvim_get_current_win()
local float_win = api.nvim_open_win(0, true, {
relative = 'editor',
width = 10,
height = 10,
row = 10,
col = 10,
})
eq(
'Cannot split a floating window',
pcall_err(api.nvim_win_set_config, win, { win = float_win, split = 'right' })
)
eq(
'Cannot split a floating window',
pcall_err(api.nvim_win_set_config, win, { win = 0, split = 'right' })
)
end)
it('cannot move autocmd window between tabpages', function()
local win_type, split_ok, err = exec_lua(function()
local other_tp_win = vim.api.nvim_get_current_win()
vim.cmd.tabnew()
local win_type, split_ok, err
vim.api.nvim_buf_call(vim.api.nvim_create_buf(true, true), function()
win_type = vim.fn.win_gettype()
split_ok, err =
pcall(vim.api.nvim_win_set_config, 0, { win = other_tp_win, split = 'right' })
end)
return win_type, split_ok, err
end)
eq('autocmd', win_type)
eq({ false, 'Cannot move autocmd window to another tabpage' }, { split_ok, err })
end)
it('cannot move cmdwin between tabpages', function()
local other_tp_win = api.nvim_get_current_win()
command('tabnew')
local old_curwin = api.nvim_get_current_win()
feed('q:')
eq('command', fn.win_gettype())
eq(
'E11: Invalid in command-line window; <CR> executes, CTRL-C quits',
pcall_err(api.nvim_win_set_config, 0, { win = other_tp_win, split = 'right' })
)
-- Shouldn't move the old curwin from before we entered the cmdwin either.
eq(
'E11: Invalid in command-line window; <CR> executes, CTRL-C quits',
pcall_err(api.nvim_win_set_config, old_curwin, { win = other_tp_win, split = 'right' })
)
end)
end)
end)