diff --git a/src/nvim/api/win_config.c b/src/nvim/api/win_config.c index bb1117b3fe..e53e13e2a3 100644 --- a/src/nvim/api/win_config.c +++ b/src/nvim/api/win_config.c @@ -505,7 +505,7 @@ void nvim_win_set_config(Window window, Dict(win_config) *config, Error *err) win->w_pos_changed = true; } - int flags = win_split_flags(fconfig.split, parent == NULL); + int flags = win_split_flags(fconfig.split, parent == NULL) | WSP_NOENTER; if (parent == NULL) { if (!win_split_ins(0, flags, win, 0)) { @@ -514,24 +514,13 @@ void nvim_win_set_config(Window window, Dict(win_config) *config, Error *err) return; } } else { - win_execute_T args; - - tabpage_T *tp = win_find_tabpage(parent); - if (!win_execute_before(&args, parent, tp)) { - // TODO(willothy): how should we handle this / what should the message be? - api_set_error(err, kErrorTypeException, "Failed to switch to tabpage %d", tp->handle); - win_execute_after(&args); - return; - } - // This should return the same ptr to `win`, but we check for - // NULL to detect errors. - win_T *res = win_split_ins(0, flags, win, 0); - win_execute_after(&args); - if (!res) { - // TODO(willothy): What should this error message say? - api_set_error(err, kErrorTypeException, "Failed to split window"); - return; - } + switchwin_T switchwin; + // `parent` is valid in its tabpage, so switch_win should not fail. + const int result = switch_win(&switchwin, parent, win_find_tabpage(parent), true); + (void)result; + assert(result == OK); + win_split_ins(0, flags, win, 0); + restore_win(&switchwin, true); } if (HAS_KEY_X(config, width)) { win_setwidth_win(fconfig.width, win); @@ -539,7 +528,6 @@ void nvim_win_set_config(Window window, Dict(win_config) *config, Error *err) if (HAS_KEY_X(config, height)) { win_setheight_win(fconfig.height, win); } - redraw_later(win, UPD_NOT_VALID); return; } else { win_config_float(win, fconfig); diff --git a/test/functional/api/window_spec.lua b/test/functional/api/window_spec.lua index a812d502eb..3914090814 100644 --- a/test/functional/api/window_spec.lua +++ b/test/functional/api/window_spec.lua @@ -1668,7 +1668,7 @@ describe('API/win', function() command('split | tabnew') local w = api.nvim_get_current_win() local t = api.nvim_get_current_tabpage() - command('tabfirst | autocmd WinEnter * ++once quit') + command('tabfirst | autocmd WinEnter * quit') api.nvim_win_set_config(0, { win = w, split = 'left' }) -- New tabpage is now the only one, as WinEnter closed the new curwin in the original. eq(t, api.nvim_get_current_tabpage()) @@ -1684,6 +1684,38 @@ describe('API/win', function() pcall_err(api.nvim_win_set_config, 0, { win = w, split = 'left' }) ) end) + + it('expected autocmds when moving window to other tabpage', function() + local new_curwin = api.nvim_get_current_win() + command('split') + local win = api.nvim_get_current_win() + command('tabnew') + local parent = api.nvim_get_current_win() + exec([[ + tabfirst + let result = [] + autocmd WinEnter * let result += ["Enter", win_getid()] + autocmd WinLeave * let result += ["Leave", win_getid()] + autocmd WinNew * let result += ["New", win_getid()] + ]]) + api.nvim_win_set_config(0, { win = parent, split = 'left' }) + -- Shouldn't see WinNew, as we're not creating any new windows, just moving existing ones. + eq({ 'Leave', win, 'Enter', new_curwin }, eval('result')) + end) + + it('no autocmds when moving window within same tabpage', function() + local parent = api.nvim_get_current_win() + exec([[ + split + let result = [] + autocmd WinEnter * let result += ["Enter", win_getid()] + autocmd WinLeave * let result += ["Leave", win_getid()] + autocmd WinNew * let result += ["New", win_getid()] + ]]) + api.nvim_win_set_config(0, { win = parent, split = 'left' }) + -- Shouldn't see any of those events, as we remain in the same window. + eq({}, eval('result')) + end) end) describe('get_config', function()