mirror of
https://github.com/neovim/neovim.git
synced 2025-02-25 18:55:25 -06:00
fix(api): win_set_config autocmds crash when moving win to other tabpage
Problem: win_enter autocommands can close new_curwin, crashing if it was the last window in its tabpage after removing win, or can close parent, crashing when attempting to split it later. Solution: remove win first, check that parent is valid after win_enter. NOTE: This isn't actually quite right, as this means win is not in the window list or even has a frame when triggering enter autocommands (so it's not considered valid in the tabpage). This is addressed in later commits.
This commit is contained in:
parent
a69c720639
commit
bcb70eeac4
@ -478,12 +478,17 @@ void nvim_win_set_config(Window window, Dict(win_config) *config, Error *err)
|
|||||||
int dir;
|
int dir;
|
||||||
new_curwin = winframe_remove(win, &dir, win_tp == curtab ? NULL : win_tp);
|
new_curwin = winframe_remove(win, &dir, win_tp == curtab ? NULL : win_tp);
|
||||||
}
|
}
|
||||||
|
win_remove(win, win_tp == curtab ? NULL : win_tp);
|
||||||
// move to neighboring window if we're moving the current window to a new tabpage
|
// move to neighboring window if we're moving the current window to a new tabpage
|
||||||
if (curwin == win && parent != NULL && new_curwin != NULL
|
if (curwin == win && parent != NULL && new_curwin != NULL
|
||||||
&& win_tp != win_find_tabpage(parent)) {
|
&& win_tp != win_find_tabpage(parent)) {
|
||||||
win_enter(new_curwin, true);
|
win_enter(new_curwin, true);
|
||||||
|
if (!win_valid_any_tab(parent)) {
|
||||||
|
// win_enter autocommands closed the `parent` to split from.
|
||||||
|
api_set_error(err, kErrorTypeException, "Window to split was closed");
|
||||||
|
return;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
win_remove(win, win_tp == curtab ? NULL : win_tp);
|
|
||||||
} else {
|
} else {
|
||||||
win_remove(win, win_tp == curtab ? NULL : win_tp);
|
win_remove(win, win_tp == curtab ? NULL : win_tp);
|
||||||
ui_comp_remove_grid(&win->w_grid_alloc);
|
ui_comp_remove_grid(&win->w_grid_alloc);
|
||||||
|
@ -1663,6 +1663,27 @@ describe('API/win', function()
|
|||||||
},
|
},
|
||||||
}, fn.winlayout())
|
}, fn.winlayout())
|
||||||
end)
|
end)
|
||||||
|
|
||||||
|
it('closing new curwin when moving window to other tabpage works', function()
|
||||||
|
command('split | tabnew')
|
||||||
|
local w = api.nvim_get_current_win()
|
||||||
|
local t = api.nvim_get_current_tabpage()
|
||||||
|
command('tabfirst | autocmd WinEnter * ++once 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())
|
||||||
|
eq({ t }, api.nvim_list_tabpages())
|
||||||
|
end)
|
||||||
|
|
||||||
|
it('closing split parent when moving window to other tabpage aborts', function()
|
||||||
|
command('split | tabnew')
|
||||||
|
local w = api.nvim_get_current_win()
|
||||||
|
command('tabfirst | autocmd WinEnter * call nvim_win_close(' .. w .. ', 1)')
|
||||||
|
eq(
|
||||||
|
'Window to split was closed',
|
||||||
|
pcall_err(api.nvim_win_set_config, 0, { win = w, split = 'left' })
|
||||||
|
)
|
||||||
|
end)
|
||||||
end)
|
end)
|
||||||
|
|
||||||
describe('get_config', function()
|
describe('get_config', function()
|
||||||
|
Loading…
Reference in New Issue
Block a user