fix(api): improve external window validation

Problem: "win" is allowed in external window configs in some cases. External
window converted to normal float can't move tabpages in one nvim_win_set_config
call. External window can't be turned into a normal split.

Solution: disallow setting "win" for external windows. Allow external window to
move tabpages, which turns it non-external. Allow external window to be turned
into a (non-external) split.

parse_win_config has more validation issues from not considering the window's
existing config enough (not from this PR). For example, zindex can be set for an
existing split if "split"/"vertical" isn't given, despite intending for that to
be an error. Plus the logic is confusing.

It could do with a refactor at some point...
This commit is contained in:
Sean Dewar
2026-03-13 11:52:01 +00:00
parent 853eea859f
commit 3115e3d0d1
3 changed files with 49 additions and 47 deletions

View File

@@ -3354,6 +3354,24 @@ describe('API/win', function()
|
]])
end)
it('can convert external window to non-external', function()
Screen.new(20, 7, { ext_multigrid = true }) -- multigrid needed for external windows
api.nvim_open_win(0, true, { external = true, width = 5, height = 5 })
eq(true, api.nvim_win_get_config(0).external)
api.nvim_win_set_config(0, { split = 'below', win = fn.win_getid(1) })
eq(false, api.nvim_win_get_config(0).external)
api.nvim_win_set_config(0, { external = true, width = 5, height = 5 })
eq(true, api.nvim_win_get_config(0).external)
api.nvim_win_set_config(0, { relative = 'editor', row = 3, col = 3 })
eq(false, api.nvim_win_get_config(0).external)
api.nvim_win_set_config(0, { external = true, width = 5, height = 5 })
eq(true, api.nvim_win_get_config(0).external)
api.nvim_win_set_config(0, { external = false })
eq(false, api.nvim_win_get_config(0).external)
end)
end)
describe('get_config', function()
@@ -3841,35 +3859,6 @@ describe('API/win', function()
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 })
eq(true, api.nvim_win_get_config(float_win).external)
eq(
('Cannot move external window to another tabpage'):format(float_win),
pcall_err(
api.nvim_win_set_config,
float_win,
{ relative = 'win', win = tab3_win, row = 0, col = 0 }
)
)
eq(float_win, api.nvim_get_current_win())
-- Error if made external by autocommand when attempting to move.
api.nvim_win_set_config(
float_win,
{ relative = 'editor', row = 0, col = 0, width = 5, height = 5 }
)
eq(false, api.nvim_win_get_config(float_win).external)
command(
('autocmd WinLeave * ++once call nvim_win_set_config(%d, #{external: 1})'):format(float_win)
)
eq(
('Cannot move external window to another tabpage'):format(float_win),
pcall_err(api.nvim_win_set_config, float_win, { win = tab3_win })
)
eq(float_win, api.nvim_get_current_win())
end)
end)
end)