diff --git a/src/nvim/api/win_config.c b/src/nvim/api/win_config.c index e8e184f10e..f5165c8da6 100644 --- a/src/nvim/api/win_config.c +++ b/src/nvim/api/win_config.c @@ -415,25 +415,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)) { @@ -441,6 +422,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) { @@ -468,11 +477,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 diff --git a/test/functional/api/window_spec.lua b/test/functional/api/window_spec.lua index 192336e2d6..c40a5037e2 100644 --- a/test/functional/api/window_spec.lua +++ b/test/functional/api/window_spec.lua @@ -3325,5 +3325,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; 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; executes, CTRL-C quits', + pcall_err(api.nvim_win_set_config, old_curwin, { win = other_tp_win, split = 'right' }) + ) + end) end) end)