diff options
-rw-r--r-- | runtime/doc/news.txt | 3 | ||||
-rw-r--r-- | src/nvim/api/win_config.c | 53 | ||||
-rw-r--r-- | src/nvim/window.c | 9 | ||||
-rw-r--r-- | src/nvim/winfloat.c | 19 | ||||
-rw-r--r-- | test/functional/api/window_spec.lua | 34 | ||||
-rw-r--r-- | test/functional/ui/float_spec.lua | 5 |
6 files changed, 95 insertions, 28 deletions
diff --git a/runtime/doc/news.txt b/runtime/doc/news.txt index 7d189d7df0..5e2a48701e 100644 --- a/runtime/doc/news.txt +++ b/runtime/doc/news.txt @@ -478,7 +478,8 @@ The following changes to existing APIs or features add new behavior. |:vertical|, |:horizontal| and |:botright|. • |nvim_open_win()| and |nvim_win_set_config()| now support opening normal (split) - windows, and moving floating windows into split windows. + windows, moving floating windows into split windows, and opening windows in + non-current tabpages. • 'errorfile' (|-q|) accepts `-` as an alias for stdin. diff --git a/src/nvim/api/win_config.c b/src/nvim/api/win_config.c index 3bc9cd816f..3a9986a7d1 100644 --- a/src/nvim/api/win_config.c +++ b/src/nvim/api/win_config.c @@ -236,19 +236,19 @@ Window nvim_open_win(Buffer buffer, Boolean enter, Dict(win_config) *config, Err win_T *wp = NULL; tabpage_T *tp = curtab; + win_T *parent = NULL; + if (config->win != -1) { + parent = find_window_by_handle(fconfig.window, err); + if (!parent) { + // find_window_by_handle has already set the error + goto cleanup; + } else if (is_split && parent->w_floating) { + api_set_error(err, kErrorTypeException, "Cannot split a floating window"); + goto cleanup; + } + tp = win_find_tabpage(parent); + } if (is_split) { - win_T *parent = NULL; - if (config->win != -1) { - parent = find_window_by_handle(fconfig.window, err); - if (!parent) { - // find_window_by_handle has already set the error - goto cleanup; - } else if (parent->w_floating) { - api_set_error(err, kErrorTypeException, "Cannot split a floating window"); - goto cleanup; - } - } - if (!check_split_disallowed_err(parent ? parent : curwin, err)) { goto cleanup; // error already set } @@ -267,7 +267,6 @@ Window nvim_open_win(Buffer buffer, Boolean enter, Dict(win_config) *config, Err if (parent == NULL || parent == curwin) { wp = win_split_ins(size, flags, NULL, 0, NULL); } else { - tp = win_find_tabpage(parent); switchwin_T switchwin; // `parent` is valid in `tp`, so switch_win should not fail. const int result = switch_win(&switchwin, parent, tp, true); @@ -395,6 +394,7 @@ void nvim_win_set_config(Window window, Dict(win_config) *config, Error *err) if (!win) { return; } + tabpage_T *win_tp = win_find_tabpage(win); bool was_split = !win->w_floating; bool has_split = HAS_KEY_X(config, split); @@ -409,23 +409,28 @@ 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 = NULL; + if (config->win != -1) { + 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; + } + + // Prevent autocmd window from being moved into another tabpage + if (is_aucmd_win(win) && win_find_tabpage(win) != win_find_tabpage(parent)) { + 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)) { return; } redraw_later(win, UPD_NOT_VALID); } else if (to_split) { - win_T *parent = NULL; - if (config->win != -1) { - parent = find_window_by_handle(fconfig.window, err); - if (!parent) { - return; - } else if (parent->w_floating) { - api_set_error(err, kErrorTypeException, "Cannot split a floating window"); - return; - } - } - WinSplit old_split = win_split_dir(win); if (has_vertical && !has_split) { if (config->vertical) { diff --git a/src/nvim/window.c b/src/nvim/window.c index 4c3fb5770c..8232767e20 100644 --- a/src/nvim/window.c +++ b/src/nvim/window.c @@ -5127,7 +5127,14 @@ win_T *win_alloc(win_T *after, bool hidden) block_autocmds(); // link the window in the window list if (!hidden) { - win_append(after, new_wp, NULL); + tabpage_T *tp = NULL; + if (after) { + tp = win_find_tabpage(after); + if (tp == curtab) { + tp = NULL; + } + } + win_append(after, new_wp, tp); } new_wp->w_wincol = 0; diff --git a/src/nvim/winfloat.c b/src/nvim/winfloat.c index f271f7d055..a0f426e30d 100644 --- a/src/nvim/winfloat.c +++ b/src/nvim/winfloat.c @@ -41,7 +41,24 @@ win_T *win_new_float(win_T *wp, bool last, WinConfig fconfig, Error *err) { if (wp == NULL) { - wp = win_alloc(last ? lastwin : lastwin_nofloating(), false); + tabpage_T *tp = NULL; + win_T *tp_last = last ? lastwin : lastwin_nofloating(); + if (fconfig.window != 0) { + assert(!last); + win_T *parent_wp = find_window_by_handle(fconfig.window, err); + if (!parent_wp) { + return NULL; + } + tp = win_find_tabpage(parent_wp); + if (!tp) { + return NULL; + } + tp_last = tp->tp_lastwin; + while (tp_last->w_floating && tp_last->w_prev) { + tp_last = tp_last->w_prev; + } + } + wp = win_alloc(tp_last, false); win_init(wp, curwin, 0); } else { assert(!last); diff --git a/test/functional/api/window_spec.lua b/test/functional/api/window_spec.lua index 636338cb2e..15b9b0945c 100644 --- a/test/functional/api/window_spec.lua +++ b/test/functional/api/window_spec.lua @@ -1454,6 +1454,40 @@ describe('API/win', function() }, layout) end) + it('opens floating windows in other tabpages', function() + local first_win = api.nvim_get_current_win() + local first_tab = api.nvim_get_current_tabpage() + + command('tabnew') + local new_tab = api.nvim_get_current_tabpage() + local win = api.nvim_open_win(0, false, { + relative = 'win', + win = first_win, + width = 5, + height = 5, + row = 1, + col = 1, + }) + eq(api.nvim_win_get_tabpage(win), first_tab) + eq(api.nvim_get_current_tabpage(), new_tab) + end) + + it('switches to new windows in non-current tabpages when enter=true', function() + local first_win = api.nvim_get_current_win() + local first_tab = api.nvim_get_current_tabpage() + command('tabnew') + local win = api.nvim_open_win(0, true, { + relative = 'win', + win = first_win, + width = 5, + height = 5, + row = 1, + col = 1, + }) + eq(api.nvim_win_get_tabpage(win), first_tab) + eq(api.nvim_get_current_tabpage(), first_tab) + end) + local function setup_tabbed_autocmd_test() local info = {} info.orig_buf = api.nvim_get_current_buf() diff --git a/test/functional/ui/float_spec.lua b/test/functional/ui/float_spec.lua index b7fb9dbd32..131cc15bfb 100644 --- a/test/functional/ui/float_spec.lua +++ b/test/functional/ui/float_spec.lua @@ -532,7 +532,10 @@ describe('float window', function() local closed_win = api.nvim_get_current_win() command('close') local buf = api.nvim_create_buf(false,false) - api.nvim_open_win(buf, true, {relative='win', win=closed_win, width=1, height=1, bufpos={0,0}}) + eq( + 'Invalid window id: ' .. closed_win, + pcall_err(api.nvim_open_win, buf, true, {relative='win', win=closed_win, width=1, height=1, bufpos={0,0}}) + ) assert_alive() end) |