mirror of
https://github.com/neovim/neovim.git
synced 2026-03-28 11:22:03 +00:00
feat(api): nvim_win_set_config can move split to other tp as floatwin
Problem: not possible for nvim_win_set_config to convert a split to a floatwin, then move it to another tabpage in one call. Solution: allow it.
This commit is contained in:
@@ -167,7 +167,7 @@ API
|
||||
they were so specified in `nvim_create_user_command()`.
|
||||
• |nvim_open_win()| floating windows can show a 'statusline'. Plugins can use
|
||||
`style='minimal'` or `:setlocal statusline=` to hide the statusline.
|
||||
• |nvim_win_set_config()| can move floating windows to other tab pages.
|
||||
• |nvim_win_set_config()| can move windows to other tab pages as floats.
|
||||
• Added experimental |nvim__exec_lua_fast()| to allow remote API clients to
|
||||
execute code while nvim is blocking for input.
|
||||
• |vim.secure.trust()| accepts `path` for the `allow` action.
|
||||
|
||||
@@ -384,9 +384,13 @@ static int win_split_flags(WinSplit split, bool toplevel)
|
||||
}
|
||||
|
||||
/// Checks if window `wp` can be moved to tabpage `tp`.
|
||||
static bool win_can_move_tp(win_T *wp, Error *err)
|
||||
static bool win_can_move_tp(win_T *wp, tabpage_T *tp, Error *err)
|
||||
FUNC_ATTR_NONNULL_ALL
|
||||
{
|
||||
if (one_window(wp, tp == curtab ? NULL : tp)) {
|
||||
api_set_error(err, kErrorTypeException, "Cannot move last non-floating window");
|
||||
return false;
|
||||
}
|
||||
if (is_aucmd_win(wp)) {
|
||||
api_set_error(err, kErrorTypeException, "Cannot move autocmd window to another tabpage");
|
||||
return false;
|
||||
@@ -403,6 +407,17 @@ static bool win_can_move_tp(win_T *wp, Error *err)
|
||||
return true;
|
||||
}
|
||||
|
||||
static win_T *win_find_altwin(win_T *win, tabpage_T *tp)
|
||||
FUNC_ATTR_NONNULL_ALL
|
||||
{
|
||||
if (win->w_floating) {
|
||||
return win_float_find_altwin(win, tp == curtab ? NULL : tp);
|
||||
} else {
|
||||
int dir;
|
||||
return winframe_find_altwin(win, &dir, tp == curtab ? NULL : tp, NULL);
|
||||
}
|
||||
}
|
||||
|
||||
/// Configures `win` into a split, also moving it to another tabpage if requested.
|
||||
static bool win_config_split(win_T *win, const Dict(win_config) *config, WinConfig *fconfig,
|
||||
Error *err)
|
||||
@@ -446,7 +461,7 @@ static bool win_config_split(win_T *win, const Dict(win_config) *config, WinConf
|
||||
api_set_error(err, kErrorTypeException, "Cannot split a floating window");
|
||||
return false;
|
||||
}
|
||||
if (win_tp != parent_tp && !win_can_move_tp(win, err)) {
|
||||
if (win_tp != parent_tp && !win_can_move_tp(win, win_tp, err)) {
|
||||
return false; // error already set
|
||||
}
|
||||
}
|
||||
@@ -460,19 +475,9 @@ static bool win_config_split(win_T *win, const Dict(win_config) *config, WinConf
|
||||
// window list or remove its frame (if non-floating), so it's valid for autocommands.
|
||||
const bool curwin_moving_tp = win == curwin && parent && win_tp != parent_tp;
|
||||
if (curwin_moving_tp) {
|
||||
if (was_split) {
|
||||
int dir;
|
||||
win_T *altwin = winframe_find_altwin(win, &dir, NULL, NULL);
|
||||
// Autocommands may still make this the last non-float after this check.
|
||||
// That case will be caught later when trying to move the window.
|
||||
if (!altwin) {
|
||||
api_set_error(err, kErrorTypeException, "Cannot move last non-floating window");
|
||||
return false;
|
||||
}
|
||||
win_goto(altwin);
|
||||
} else {
|
||||
win_goto(win_float_find_altwin(win, NULL));
|
||||
}
|
||||
win_T *altwin = win_find_altwin(win, win_tp);
|
||||
assert(altwin); // win_can_move_tp ensures `win` is not the only window
|
||||
win_goto(altwin);
|
||||
|
||||
// Autocommands may have been a real nuisance and messed things up...
|
||||
if (curwin == win) {
|
||||
@@ -642,12 +647,21 @@ static bool win_config_float_tp(win_T *win, const Dict(win_config) *config,
|
||||
parent_tp = win_find_tabpage(parent);
|
||||
}
|
||||
|
||||
bool curwin_moving_tp = false;
|
||||
win_T *altwin = NULL;
|
||||
|
||||
if (win_tp != parent_tp) {
|
||||
if (!win_can_move_tp(win, err)) {
|
||||
if (!win_can_move_tp(win, win_tp, err)) {
|
||||
return false; // error already set
|
||||
}
|
||||
altwin = win_find_altwin(win, win_tp);
|
||||
assert(altwin); // win_can_move_tp ensures `win` is not the only window
|
||||
|
||||
// If we are moving curwin to another tabpage, switch windows *before* we remove it from the
|
||||
// window list or remove its frame (if non-floating), so it's valid for autocommands.
|
||||
if (curwin == win) {
|
||||
win_goto(win_float_find_altwin(win, NULL));
|
||||
curwin_moving_tp = true;
|
||||
win_goto(altwin);
|
||||
|
||||
// Autocommands may have been a real nuisance and messed things up...
|
||||
if (curwin == win) {
|
||||
@@ -658,47 +672,51 @@ static bool win_config_float_tp(win_T *win, const Dict(win_config) *config,
|
||||
win_tp = win_find_tabpage(win);
|
||||
parent_tp = win_find_tabpage(parent);
|
||||
|
||||
bool restore_curwin = false;
|
||||
if (!win_tp || !parent_tp) {
|
||||
api_set_error(err, kErrorTypeException, "Target windows were closed");
|
||||
restore_curwin = true;
|
||||
} else if (!win->w_floating) {
|
||||
api_set_error(err, kErrorTypeException, "Window %d was made non-floating", win->handle);
|
||||
restore_curwin = true;
|
||||
} else if (win_tp != parent_tp && !win_can_move_tp(win, err)) {
|
||||
restore_curwin = true; // error already set
|
||||
goto restore_curwin;
|
||||
}
|
||||
if (restore_curwin) {
|
||||
// As `win` was the original curwin, and autocommands didn't move it outside of curtab, be
|
||||
// a good citizen and try to return to it.
|
||||
if (win_valid(win)) {
|
||||
win_goto(win);
|
||||
}
|
||||
return false;
|
||||
if (win_tp != parent_tp && !win_can_move_tp(win, win_tp, err)) {
|
||||
goto restore_curwin; // error already set
|
||||
}
|
||||
altwin = win_find_altwin(win, win_tp);
|
||||
assert(altwin); // win_can_move_tp ensures `win` is not the only window
|
||||
}
|
||||
}
|
||||
|
||||
// Convert the window to a float if needed.
|
||||
if (!win->w_floating) {
|
||||
if (!win_new_float(win, false, *fconfig, err)) {
|
||||
restore_curwin:
|
||||
// If `win` was the original curwin, and autocommands didn't move it outside of curtab, be a
|
||||
// good citizen and try to return to it.
|
||||
if (curwin_moving_tp && win_valid(win)) {
|
||||
win_goto(win);
|
||||
}
|
||||
return false;
|
||||
}
|
||||
redraw_later(win, UPD_NOT_VALID);
|
||||
}
|
||||
|
||||
if (win_tp != parent_tp) {
|
||||
win_remove(win, win_tp == curtab ? NULL : win_tp);
|
||||
tabpage_T *append_tp = parent_tp == curtab ? NULL : parent_tp;
|
||||
win_append(lastwin_nofloating(append_tp), win, append_tp);
|
||||
|
||||
// If `win` was the curwin of its old tabpage, select a new curwin for it.
|
||||
if (win_tp != curtab && win_tp->tp_curwin == win) {
|
||||
win_tp->tp_curwin = altwin;
|
||||
}
|
||||
|
||||
// Check again, in case autocommands above moved windows to the same tabpage.
|
||||
if (win_tp != parent_tp) {
|
||||
win_remove(win, win_tp == curtab ? NULL : win_tp);
|
||||
tabpage_T *append_tp = parent_tp == curtab ? NULL : parent_tp;
|
||||
win_append(lastwin_nofloating(append_tp), win, append_tp);
|
||||
// Remove grid if present. More reliable than checking curtab, as tabpage_check_windows may not
|
||||
// run when temporarily switching tabpages, meaning grids may be stale from another tabpage!
|
||||
// (e.g: switch_win_noblock with no_display=true)
|
||||
ui_comp_remove_grid(&win->w_grid_alloc);
|
||||
|
||||
// If `win` was the curwin of its old tabpage, select a new curwin for it.
|
||||
if (win_tp != curtab && win_tp->tp_curwin == win) {
|
||||
win_tp->tp_curwin = win_float_find_altwin(win, win_tp);
|
||||
}
|
||||
|
||||
// Remove grid if present. More reliable than checking curtab, as tabpage_check_windows may
|
||||
// not run when temporarily switching tabpages, meaning grids may be stale from another
|
||||
// tabpage! (e.g: switch_win_noblock with no_display=true)
|
||||
ui_comp_remove_grid(&win->w_grid_alloc);
|
||||
|
||||
// Redraw tabline, update window's hl attribs, etc. Set must_redraw here, as redraw_later
|
||||
// might not if w_redr_type >= UPD_NOT_VALID was set in the old tabpage.
|
||||
redraw_later(win, UPD_NOT_VALID);
|
||||
set_must_redraw(UPD_NOT_VALID);
|
||||
}
|
||||
// Redraw tabline, update window's hl attribs, etc. Set must_redraw here, as redraw_later might
|
||||
// not if w_redr_type >= UPD_NOT_VALID was set in the old tabpage.
|
||||
redraw_later(win, UPD_NOT_VALID);
|
||||
set_must_redraw(UPD_NOT_VALID);
|
||||
}
|
||||
|
||||
win_config_float(win, *fconfig);
|
||||
@@ -745,27 +763,11 @@ void nvim_win_set_config(Window window, Dict(win_config) *config, Error *err)
|
||||
return;
|
||||
}
|
||||
|
||||
if (was_split && !to_split) {
|
||||
win_T *parent = find_window_by_handle(fconfig.window, err);
|
||||
if (!parent) {
|
||||
return;
|
||||
}
|
||||
// TODO(seandewar): support this, preferably via win_config_float_tp.
|
||||
if (!win_valid(parent)) {
|
||||
api_set_error(err, kErrorTypeValidation,
|
||||
"Cannot configure split into float in another tabpage");
|
||||
return;
|
||||
}
|
||||
if (!win_new_float(win, false, fconfig, err)) {
|
||||
return;
|
||||
}
|
||||
redraw_later(win, UPD_NOT_VALID);
|
||||
} else if (to_split) {
|
||||
if (to_split) {
|
||||
if (!win_config_split(win, config, &fconfig, err)) {
|
||||
return;
|
||||
}
|
||||
} else {
|
||||
assert(!was_split);
|
||||
if (!win_config_float_tp(win, config, &fconfig, err)) {
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -35,10 +35,9 @@
|
||||
|
||||
#include "winfloat.c.generated.h"
|
||||
|
||||
/// Create a new float.
|
||||
/// Creates a new float, or transforms an existing window to a float.
|
||||
///
|
||||
/// @param wp if NULL, allocate a new window, otherwise turn existing window into a float.
|
||||
/// It must then already belong to the current tabpage!
|
||||
/// @param last make the window the last one in the window list.
|
||||
/// Only used when allocating the autocommand window.
|
||||
/// @param config must already have been validated!
|
||||
@@ -74,19 +73,19 @@ win_T *win_new_float(win_T *wp, bool last, WinConfig fconfig, Error *err)
|
||||
} else {
|
||||
assert(!last);
|
||||
assert(!wp->w_floating);
|
||||
if (firstwin == wp && lastwin_nofloating(NULL) == wp) {
|
||||
// last non-float
|
||||
api_set_error(err, kErrorTypeException,
|
||||
"Cannot change last window into float");
|
||||
return NULL;
|
||||
} else if (!win_valid(wp)) {
|
||||
api_set_error(err, kErrorTypeException,
|
||||
"Cannot change window from different tabpage into float");
|
||||
tabpage_T *win_tp = win_find_tabpage(wp);
|
||||
assert(win_tp);
|
||||
if ((win_tp == curtab && firstwin == wp && lastwin_nofloating(NULL) == wp)
|
||||
|| (win_tp != curtab && win_tp->tp_firstwin == wp && lastwin_nofloating(win_tp) == wp)) {
|
||||
api_set_error(err, kErrorTypeException, "Cannot change last window into float");
|
||||
return NULL;
|
||||
} else if (cmdwin_win != NULL && !cmdwin_win->w_floating) {
|
||||
// cmdwin can't become the only non-float. Check for others.
|
||||
bool other_nonfloat = false;
|
||||
for (win_T *wp2 = firstwin; wp2 != NULL && !wp2->w_floating; wp2 = wp2->w_next) {
|
||||
FOR_ALL_WINDOWS_IN_TAB(wp2, win_tp) {
|
||||
if (wp2->w_floating) {
|
||||
break;
|
||||
}
|
||||
if (wp2 != wp && wp2 != cmdwin_win) {
|
||||
other_nonfloat = true;
|
||||
break;
|
||||
@@ -97,13 +96,16 @@ win_T *win_new_float(win_T *wp, bool last, WinConfig fconfig, Error *err)
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
tabpage_T *tp = win_tp == curtab ? NULL : win_tp;
|
||||
int dir;
|
||||
winframe_remove(wp, &dir, NULL, NULL);
|
||||
winframe_remove(wp, &dir, tp, NULL);
|
||||
XFREE_CLEAR(wp->w_frame);
|
||||
win_remove(wp, NULL);
|
||||
last_status(false); // may need to remove last status line
|
||||
win_comp_pos(); // recompute window positions
|
||||
win_append(lastwin_nofloating(NULL), wp, NULL);
|
||||
win_remove(wp, tp);
|
||||
if (win_tp == curtab) {
|
||||
last_status(false); // may need to remove last status line
|
||||
win_comp_pos(); // recompute window positions
|
||||
}
|
||||
win_append(lastwin_nofloating(tp), wp, tp);
|
||||
}
|
||||
wp->w_floating = true;
|
||||
wp->w_status_height = wp->w_p_stl && *wp->w_p_stl != NUL
|
||||
|
||||
@@ -2585,15 +2585,17 @@ describe('API/win', function()
|
||||
},
|
||||
}, layout)
|
||||
|
||||
-- converting split into a float for a different tabpage is not yet supported
|
||||
eq(
|
||||
'Cannot configure split into float in another tabpage',
|
||||
pcall_err(
|
||||
api.nvim_win_set_config,
|
||||
win,
|
||||
{ relative = 'editor', row = 0, col = 0, width = 1, height = 1, win = first_win }
|
||||
)
|
||||
-- directly convert split into a float for a different tabpage
|
||||
local win2 = api.nvim_open_win(0, true, { split = 'below' })
|
||||
eq('', api.nvim_win_get_config(win2).relative)
|
||||
api.nvim_win_set_config(
|
||||
win2,
|
||||
{ relative = 'editor', row = 0, col = 0, width = 1, height = 1, win = first_win }
|
||||
)
|
||||
eq(first_tab, api.nvim_win_get_tabpage(win2))
|
||||
eq('editor', api.nvim_win_get_config(win2).relative)
|
||||
eq({ first_win, win2 }, api.nvim_tabpage_list_wins(first_tab))
|
||||
eq({ tab2_win, win }, api.nvim_tabpage_list_wins(new_tab))
|
||||
|
||||
-- convert new win to float in new tabpage
|
||||
api.nvim_win_set_config(win, { relative = 'editor', row = 2, col = 2, height = 2, width = 2 })
|
||||
@@ -2601,10 +2603,23 @@ describe('API/win', function()
|
||||
-- move to other tabpage
|
||||
api.nvim_win_set_config(win, { win = first_win })
|
||||
eq(first_tab, api.nvim_win_get_tabpage(win))
|
||||
eq({ first_win, win }, api.nvim_tabpage_list_wins(first_tab))
|
||||
eq({ first_win, win, win2 }, api.nvim_tabpage_list_wins(first_tab))
|
||||
eq({ tab2_win }, api.nvim_tabpage_list_wins(new_tab))
|
||||
-- unlike splits, negative win is invalid
|
||||
eq('Invalid window id: -1', pcall_err(api.nvim_win_set_config, win, { win = -1 }))
|
||||
|
||||
-- can't convert only window in other tabpage to float
|
||||
command('tabnew')
|
||||
local only_win = api.nvim_get_current_win()
|
||||
command('tabprevious')
|
||||
eq(
|
||||
'Cannot change last window into float',
|
||||
pcall_err(
|
||||
api.nvim_win_set_config,
|
||||
only_win,
|
||||
{ relative = 'editor', width = 5, height = 5, row = 0, col = 0 }
|
||||
)
|
||||
)
|
||||
end)
|
||||
|
||||
it('correctly moves curwin when moving curwin to a different tabpage', function()
|
||||
@@ -2773,7 +2788,6 @@ describe('API/win', function()
|
||||
|
||||
it('messing with "win" or "parent" when moving "win" to other tabpage', function()
|
||||
command('split | tabnew')
|
||||
local t2 = api.nvim_get_current_tabpage()
|
||||
local t2_win1 = api.nvim_get_current_win()
|
||||
command('split')
|
||||
local t2_win2 = api.nvim_get_current_win()
|
||||
@@ -2818,23 +2832,19 @@ describe('API/win', function()
|
||||
eq('', api.nvim_win_get_config(0).relative)
|
||||
eq(cur_win, api.nvim_get_current_win())
|
||||
|
||||
-- Try to make "parent" floating. This should give the same error as before, but because
|
||||
-- changing a split from another tabpage into a float isn't supported yet, check for that
|
||||
-- error instead for now.
|
||||
-- Use ":silent!" to avoid the one second delay from printing the error message.
|
||||
-- Try to make "parent" floating. This should give the same error as before.
|
||||
exec(([[
|
||||
autocmd WinLeave * ++once silent!
|
||||
autocmd WinLeave * ++once
|
||||
\ call nvim_win_set_config(%d, #{relative:'editor', row:0, col:0, width:5, height:5})
|
||||
]]):format(t2_win3))
|
||||
cur_win = api.nvim_get_current_win()
|
||||
api.nvim_win_set_config(0, { win = t2_win3, split = 'left' })
|
||||
matches(
|
||||
'Cannot change window from different tabpage into float$',
|
||||
api.nvim_get_vvar('errmsg')
|
||||
eq(
|
||||
'Floating state of windows to split changed',
|
||||
pcall_err(api.nvim_win_set_config, 0, { win = t2_win3, split = 'left' })
|
||||
)
|
||||
-- The error doesn't abort moving the window (or maybe it should, if that's wanted?)
|
||||
neq(cur_win, api.nvim_get_current_win())
|
||||
eq(t2, api.nvim_win_get_tabpage(cur_win))
|
||||
eq('editor', api.nvim_win_get_config(t2_win3).relative)
|
||||
eq('', api.nvim_win_get_config(0).relative)
|
||||
eq(cur_win, api.nvim_get_current_win())
|
||||
end)
|
||||
|
||||
it('expected autocmds when moving window to other tabpage', function()
|
||||
@@ -3228,6 +3238,35 @@ describe('API/win', function()
|
||||
api.nvim_win_set_config(t2_cur_win, { split = 'left', win = 0 })
|
||||
eq(t2_alt_win, api.nvim_tabpage_get_win(t2))
|
||||
eq(t1, api.nvim_win_get_tabpage(t2_cur_win))
|
||||
|
||||
-- Very fun: move curwin between tabpages, converting from split to float, but with an autocmd
|
||||
-- that deletes altwin after we're bumped to it, re-enters curwin, then switches to a 3rd
|
||||
-- tabpage. tp_curwin of the window's old tabpage shouldn't be set to the freed altwin!
|
||||
command('tablast | tab split | tabprevious | split')
|
||||
command('autocmd WinEnter * ++once quit | let expect_alt = win_getid() | wincmd p | tabnext')
|
||||
api.nvim_win_set_config(0, {
|
||||
relative = 'editor',
|
||||
win = api.nvim_tabpage_get_win(t1),
|
||||
row = 0,
|
||||
col = 0,
|
||||
width = 5,
|
||||
height = 5,
|
||||
})
|
||||
eq(eval('g:expect_alt'), api.nvim_tabpage_get_win(t2))
|
||||
|
||||
-- Same, but for float -> float.
|
||||
command('tabprevious | split')
|
||||
api.nvim_open_win(0, true, { relative = 'editor', row = 0, col = 0, width = 1, height = 1 })
|
||||
command('autocmd WinEnter * ++once quit | let expect_alt = win_getid() | wincmd p | tabnext')
|
||||
api.nvim_win_set_config(0, {
|
||||
relative = 'editor',
|
||||
win = api.nvim_tabpage_get_win(t1),
|
||||
row = 0,
|
||||
col = 0,
|
||||
width = 5,
|
||||
height = 5,
|
||||
})
|
||||
eq(eval('g:expect_alt'), api.nvim_tabpage_get_win(t2))
|
||||
end)
|
||||
|
||||
it('set_config cannot change "noautocmd" #36409', function()
|
||||
@@ -3742,7 +3781,6 @@ describe('API/win', function()
|
||||
|
||||
it('preserve current floating window when moving fails', function()
|
||||
local buf = api.nvim_create_buf(false, true)
|
||||
local tab1_win = api.nvim_get_current_win()
|
||||
local float_win = api.nvim_open_win(buf, true, {
|
||||
relative = 'editor',
|
||||
row = 1,
|
||||
@@ -3770,18 +3808,6 @@ describe('API/win', function()
|
||||
)
|
||||
eq(float_win, api.nvim_get_current_win())
|
||||
|
||||
command(
|
||||
('autocmd WinLeave * ++once call nvim_win_set_config(%d, #{split: "left", win: %d})'):format(
|
||||
float_win,
|
||||
tab1_win
|
||||
)
|
||||
)
|
||||
eq(
|
||||
('Window %d was made non-floating'):format(float_win),
|
||||
pcall_err(api.nvim_win_set_config, float_win, { win = tab3_win })
|
||||
)
|
||||
eq(float_win, api.nvim_get_current_win())
|
||||
|
||||
-- Need multigrid for external windows.
|
||||
Screen.new(20, 9, { ext_multigrid = true })
|
||||
api.nvim_win_set_config(float_win, { external = true, width = 5, height = 5 })
|
||||
|
||||
@@ -3782,10 +3782,7 @@ describe('float window', function()
|
||||
it('API has proper error messages', function()
|
||||
local buf = api.nvim_create_buf(false, false)
|
||||
eq("Invalid key: 'bork'", pcall_err(api.nvim_open_win, buf, false, { width = 20, height = 2, bork = true }))
|
||||
eq(
|
||||
"Must specify 'relative' or 'external' when creating a float",
|
||||
pcall_err(api.nvim_open_win, buf, false, { win = 0 })
|
||||
)
|
||||
eq("Must specify 'relative' or 'external' when creating a float", pcall_err(api.nvim_open_win, buf, false, { win = 0 }))
|
||||
eq(
|
||||
"floating windows cannot have 'vertical'",
|
||||
pcall_err(api.nvim_open_win, buf, false, { width = 20, height = 2, relative = 'editor', row = 0, col = 0, vertical = true })
|
||||
@@ -12030,6 +12027,7 @@ describe('float window', function()
|
||||
|
||||
-- Check tablines are redrawn even when moving floats between two non-current tabpages.
|
||||
command('tabnew')
|
||||
local tab3_win = api.nvim_get_current_win()
|
||||
if multigrid then
|
||||
screen:expect({
|
||||
grid = [[
|
||||
@@ -12094,6 +12092,270 @@ describe('float window', function()
|
||||
|
|
||||
]])
|
||||
end
|
||||
|
||||
-- Try converting a split to a float, then moving it to another tabpage in one call.
|
||||
command('set norightleft | new')
|
||||
fn.setline(1, 'floaty mcfloatface')
|
||||
api.nvim_win_set_config(0, { relative = 'editor', win = tab1_win, row = 3, col = 3, width = 15, height = 5 })
|
||||
if multigrid then
|
||||
screen:expect({
|
||||
grid = [[
|
||||
## grid 1
|
||||
{9: }{10:2}{9:+ No Name] }{3: [No Name] }{9: }{10:2}{9:+ No Name] }{5: }{9:X}|
|
||||
[6:----------------------------------------]|*5
|
||||
[3:----------------------------------------]|
|
||||
## grid 2 (hidden)
|
||||
olleh|
|
||||
{0: ~}|*4
|
||||
## grid 3
|
||||
|
|
||||
## grid 4 (hidden)
|
||||
hello |
|
||||
{0:~ }|*4
|
||||
## grid 5 (hidden)
|
||||
{1:hello }|
|
||||
{2:~ }|*4
|
||||
## grid 6
|
||||
^ |
|
||||
{0:~ }|*4
|
||||
## grid 7 (hidden)
|
||||
floaty mcfloatface |
|
||||
{0:~ }|
|
||||
]],
|
||||
})
|
||||
else
|
||||
screen:expect([[
|
||||
{9: }{10:2}{9:+ No Name] }{3: [No Name] }{9: }{10:2}{9:+ No Name] }{5: }{9:X}|
|
||||
^ |
|
||||
{0:~ }|*4
|
||||
|
|
||||
]])
|
||||
end
|
||||
|
||||
command('tabfirst')
|
||||
if multigrid then
|
||||
screen:expect({
|
||||
grid = [[
|
||||
## grid 1
|
||||
{3: }{11:2}{3:+ No Name] }{9: [No Name] }{10:2}{9:+ No Name] }{5: }{9:X}|
|
||||
[2:----------------------------------------]|*5
|
||||
[3:----------------------------------------]|
|
||||
## grid 2
|
||||
olle^h|
|
||||
{0: ~}|*4
|
||||
## grid 3
|
||||
|
|
||||
## grid 4 (hidden)
|
||||
hello |
|
||||
{0:~ }|*4
|
||||
## grid 5 (hidden)
|
||||
{1:hello }|
|
||||
{2:~ }|*4
|
||||
## grid 6 (hidden)
|
||||
|
|
||||
{0:~ }|*4
|
||||
## grid 7
|
||||
{1:floaty mcfloatf}|
|
||||
{1:ace }|
|
||||
{2:~ }|*3
|
||||
]],
|
||||
float_pos = {
|
||||
[7] = { 1004, 'NW', 1, 3, 3, true, 50, 1, 1, 3 },
|
||||
},
|
||||
})
|
||||
else
|
||||
screen:expect([[
|
||||
{3: }{11:2}{3:+ No Name] }{9: [No Name] }{10:2}{9:+ No Name] }{5: }{9:X}|
|
||||
{1:floaty mcfloatf} olle^h|
|
||||
{0: }{1:ace }{0: ~}|
|
||||
{0: }{2:~ }{0: ~}|*3
|
||||
|
|
||||
]])
|
||||
end
|
||||
|
||||
-- Works when doing the same between two non-current tabpages.
|
||||
local float2 = api.nvim_open_win(0, false, { split = 'below', win = tab3_win })
|
||||
api.nvim_win_set_config(float2, { relative = 'win', win = tab2_win, row = 2, col = 7, width = 4, height = 4, border = 'single' })
|
||||
if multigrid then
|
||||
screen:expect({
|
||||
grid = [[
|
||||
## grid 1
|
||||
{3: }{11:2}{3:+ No Name] }{9: [No Name] }{10:3}{9:+ No Name] }{5: }{9:X}|
|
||||
[2:----------------------------------------]|*5
|
||||
[3:----------------------------------------]|
|
||||
## grid 2
|
||||
olle^h|
|
||||
{0: ~}|*4
|
||||
## grid 3
|
||||
|
|
||||
## grid 4 (hidden)
|
||||
hello |
|
||||
{0:~ }|*4
|
||||
## grid 5 (hidden)
|
||||
{1:hello }|
|
||||
{2:~ }|*4
|
||||
## grid 6 (hidden)
|
||||
|
|
||||
{0:~ }|*4
|
||||
## grid 7
|
||||
{1:floaty mcfloatf}|
|
||||
{1:ace }|
|
||||
{2:~ }|*3
|
||||
]],
|
||||
float_pos = {
|
||||
[7] = { 1004, 'NW', 1, 3, 3, true, 50, 1, 1, 3 },
|
||||
},
|
||||
})
|
||||
else
|
||||
screen:expect([[
|
||||
{3: }{11:2}{3:+ No Name] }{9: [No Name] }{10:3}{9:+ No Name] }{5: }{9:X}|
|
||||
{1:floaty mcfloatf} olle^h|
|
||||
{0: }{1:ace }{0: ~}|
|
||||
{0: }{2:~ }{0: ~}|*3
|
||||
|
|
||||
]])
|
||||
end
|
||||
|
||||
command('tabnext')
|
||||
if multigrid then
|
||||
screen:expect({
|
||||
grid = [[
|
||||
## grid 1
|
||||
{9: }{10:2}{9:+ No Name] }{3: [No Name] }{9: }{10:3}{9:+ No Name] }{5: }{9:X}|
|
||||
[6:----------------------------------------]|*5
|
||||
[3:----------------------------------------]|
|
||||
## grid 2 (hidden)
|
||||
olleh|
|
||||
{0: ~}|*4
|
||||
## grid 3
|
||||
|
|
||||
## grid 4 (hidden)
|
||||
hello |
|
||||
{0:~ }|*4
|
||||
## grid 5 (hidden)
|
||||
{1:hello }|
|
||||
{2:~ }|*4
|
||||
## grid 6
|
||||
^ |
|
||||
{0:~ }|*4
|
||||
## grid 7 (hidden)
|
||||
{1:floaty mcfloatf}|
|
||||
{1:ace }|
|
||||
{2:~ }|*3
|
||||
]],
|
||||
})
|
||||
else
|
||||
screen:expect([[
|
||||
{9: }{10:2}{9:+ No Name] }{3: [No Name] }{9: }{10:3}{9:+ No Name] }{5: }{9:X}|
|
||||
^ |
|
||||
{0:~ }|*4
|
||||
|
|
||||
]])
|
||||
end
|
||||
|
||||
command('tabnext')
|
||||
if multigrid then
|
||||
screen:expect({
|
||||
grid = [[
|
||||
## grid 1
|
||||
{9: }{10:2}{9:+ No Name] [No Name] }{3: }{11:3}{3:+ No Name] }{5: }{9:X}|
|
||||
[4:----------------------------------------]|*5
|
||||
[3:----------------------------------------]|
|
||||
## grid 2 (hidden)
|
||||
olleh|
|
||||
{0: ~}|*4
|
||||
## grid 3
|
||||
|
|
||||
## grid 4
|
||||
^hello |
|
||||
{0:~ }|*4
|
||||
## grid 5
|
||||
{1:hello }|
|
||||
{2:~ }|*4
|
||||
## grid 6 (hidden)
|
||||
|
|
||||
{0:~ }|*4
|
||||
## grid 7 (hidden)
|
||||
{1:floaty mcfloatf}|
|
||||
{1:ace }|
|
||||
{2:~ }|*3
|
||||
## grid 8
|
||||
{5:┌────┐}|
|
||||
{5:│}{1:lleh}{5:│}|
|
||||
{5:│}{1: o}{5:│}|
|
||||
{5:│}{2: ~}{5:│}|*2
|
||||
{5:└────┘}|
|
||||
]],
|
||||
float_pos = {
|
||||
[5] = { 1002, 'NW', 4, 0, 0, true, 50, 1, 1, 0 },
|
||||
[8] = { 1005, 'NW', 4, 2, 7, true, 50, 2, 0, 7 },
|
||||
},
|
||||
})
|
||||
else
|
||||
screen:expect([[
|
||||
{9: }{10:2}{9:+ No }{5:┌────┐}{9: [No Name] }{3: }{11:3}{3:+ No Name] }{5: }{9:X}|
|
||||
{1:^hello }{5:│}{1:lleh}{5:│} |
|
||||
{2:~ }{5:│}{1: o}{5:│}{0: }|
|
||||
{2:~ }{5:│}{2: ~}{5:│}{0: }|*2
|
||||
{2:~ }{5:└────┘}{0: }|
|
||||
|
|
||||
]])
|
||||
end
|
||||
|
||||
-- Used relative=win on two floats relative to this window.
|
||||
-- Split it to the right to ensure both follow.
|
||||
command('topleft vsplit')
|
||||
if multigrid then
|
||||
screen:expect({
|
||||
grid = [[
|
||||
## grid 1
|
||||
{9: }{10:2}{9:+ No Name] [No Name] }{3: }{11:4}{3:+ No Name] }{5: }{9:X}|
|
||||
[9:--------------------]{5:│}[4:-------------------]|*4
|
||||
{4:[No Name] [+] }{5:[No Name] [+] }|
|
||||
[3:----------------------------------------]|
|
||||
## grid 2 (hidden)
|
||||
olleh|
|
||||
{0: ~}|*4
|
||||
## grid 3
|
||||
|
|
||||
## grid 4
|
||||
hello |
|
||||
{0:~ }|*3
|
||||
## grid 5
|
||||
{1:hello }|
|
||||
{2:~ }|*4
|
||||
## grid 6 (hidden)
|
||||
|
|
||||
{0:~ }|*4
|
||||
## grid 7 (hidden)
|
||||
{1:floaty mcfloatf}|
|
||||
{1:ace }|
|
||||
{2:~ }|*3
|
||||
## grid 8
|
||||
{5:┌────┐}|
|
||||
{5:│}{1:lleh}{5:│}|
|
||||
{5:│}{1: o}{5:│}|
|
||||
{5:│}{2: ~}{5:│}|*2
|
||||
{5:└────┘}|
|
||||
## grid 9
|
||||
^hello |
|
||||
{0:~ }|*3
|
||||
]],
|
||||
float_pos = {
|
||||
[5] = { 1002, 'NW', 4, 0, 0, true, 50, 1, 1, 21 },
|
||||
[8] = { 1005, 'NW', 4, 2, 7, true, 50, 2, 0, 28 },
|
||||
},
|
||||
})
|
||||
else
|
||||
screen:expect([[
|
||||
{9: }{10:2}{9:+ No Name] [No Name] }{3: }{11:4}{3:+ }{5:┌────┐}{3:e] }{5: }{9:X}|
|
||||
^hello {5:│}{1:hello }{5:│}{1:lleh}{5:│} |
|
||||
{0:~ }{5:│}{2:~ }{5:│}{1: o}{5:│}{0: }|
|
||||
{0:~ }{5:│}{2:~ }{5:│}{2: ~}{5:│}{0: }|*2
|
||||
{4:[No Name] [+] }{2:~ }{5:└────┘ }|
|
||||
|
|
||||
]])
|
||||
end
|
||||
end)
|
||||
end
|
||||
|
||||
|
||||
Reference in New Issue
Block a user