fix(api): merge split window config only on success

Problem: nvim_win_set_config may merge configs despite failing to configure a
split, and without applying necessary side-effects (like setting style=minimal
options). Plus, autocommands may apply a different config after the merge,
causing side-effects to apply for an outdated config.

Solution: merge configs last, only on success. Include fields only relevant to
splits. Properly set _cmdline_offset for splits.

Maybe better to disallow _cmdline_offset for splits instead, as the pum is
relative to cmdline_row anyway? (I didn't want to change behaviour too much)

Also use expect_unchanged in an unrelated test to quash a warning.
This commit is contained in:
Sean Dewar
2026-03-07 12:12:02 +00:00
parent 65a1709112
commit 137d5ab01d
5 changed files with 71 additions and 21 deletions

View File

@@ -3553,5 +3553,41 @@ describe('API/win', function()
eq('', api.nvim_get_option_value('colorcolumn', { win = win }))
eq('', api.nvim_get_option_value('statuscolumn', { win = win }))
end)
it('merges configs only after successfully configuring split', function()
local win = api.nvim_open_win(0, true, {
relative = 'editor',
width = 10,
height = 10,
row = 5,
col = 5,
})
local cfg = api.nvim_win_get_config(win)
eq('', cfg.style)
command('set cursorline | tabnew')
local tp2_win = api.nvim_get_current_win()
command('tabfirst | autocmd WinEnter * ++once wincmd p')
eq(
'Failed to switch away from window 1001',
pcall_err(
api.nvim_win_set_config,
win,
{ split = 'below', win = tp2_win, style = 'minimal' }
)
)
eq(cfg, api.nvim_win_get_config(win))
eq(true, api.nvim_get_option_value('cursorline', { win = win }))
exec([[
autocmd WinLeave * ++once let g:style_before = nvim_win_get_config(0).style
\| let g:cul_before = &cursorline
\| call nvim_win_set_config(0, #{style: ""})
]])
api.nvim_win_set_config(win, { split = 'below', win = tp2_win, style = 'minimal' })
eq('', eval('g:style_before'))
eq(1, eval('g:cul_before'))
eq('minimal', api.nvim_win_get_config(win).style)
eq(false, api.nvim_get_option_value('cursorline', { win = win }))
end)
end)
end)