mirror of
https://github.com/neovim/neovim.git
synced 2024-12-20 03:05:11 -07:00
fix(aucmd_win): ensure aucmd_win stays floating
Nvim uses a floating window for the autocmd window, but in certain situations, it can be made non-floating (`:wincmd J`), which can cause issues due to the previous setup and cleanup logic for a non-floating aucmd_win being removed from aucmd_prepbuf and aucmd_restbuf. This can cause glitchiness and crashes due to the aucmd_win's frame being invalid after closing its tabpage, for example. Ensure aucmd_win cannot be made non-floating. The only place this happens is in win_split_ins if new_wp != NULL.
This commit is contained in:
parent
30c9c8815b
commit
2deffb5ea8
@ -1147,6 +1147,7 @@ void aucmd_prepbuf(aco_save_T *aco, buf_T *buf)
|
||||
globaldir = NULL;
|
||||
|
||||
block_autocmds(); // We don't want BufEnter/WinEnter autocommands.
|
||||
make_snapshot(SNAP_AUCMD_IDX);
|
||||
if (need_append) {
|
||||
win_append(lastwin, aucmd_win);
|
||||
pmap_put(handle_T)(&window_handles, aucmd_win->handle, aucmd_win);
|
||||
@ -1212,6 +1213,8 @@ win_found:
|
||||
close_tabpage(curtab);
|
||||
}
|
||||
|
||||
restore_snapshot(SNAP_AUCMD_IDX, false);
|
||||
win_comp_pos(); // recompute window positions
|
||||
unblock_autocmds();
|
||||
|
||||
win_T *const save_curwin = win_find_by_handle(aco->save_curwin_handle);
|
||||
|
@ -958,6 +958,11 @@ int win_split_ins(int size, int flags, win_T *new_wp, int dir)
|
||||
int wmh1;
|
||||
bool did_set_fraction = false;
|
||||
|
||||
// aucmd_win should always remain floating
|
||||
if (new_wp != NULL && new_wp == aucmd_win) {
|
||||
return FAIL;
|
||||
}
|
||||
|
||||
if (flags & WSP_TOP) {
|
||||
oldwin = firstwin;
|
||||
} else if (flags & WSP_BOT || curwin->w_floating) {
|
||||
|
@ -2,6 +2,7 @@ local helpers = require('test.functional.helpers')(after_each)
|
||||
local Screen = require('test.functional.ui.screen')
|
||||
|
||||
local assert_visible = helpers.assert_visible
|
||||
local assert_alive = helpers.assert_alive
|
||||
local dedent = helpers.dedent
|
||||
local eq = helpers.eq
|
||||
local eval = helpers.eval
|
||||
@ -13,6 +14,7 @@ local funcs = helpers.funcs
|
||||
local expect = helpers.expect
|
||||
local command = helpers.command
|
||||
local exc_exec = helpers.exc_exec
|
||||
local exec_lua = helpers.exec_lua
|
||||
local curbufmeths = helpers.curbufmeths
|
||||
local source = helpers.source
|
||||
|
||||
@ -333,6 +335,68 @@ describe('autocmd', function()
|
||||
pcall_err(command, "call nvim_set_current_win(g:winid)"))
|
||||
end)
|
||||
|
||||
it("`aucmd_win` cannot be changed into a normal window #13699", function()
|
||||
local screen = Screen.new(50, 10)
|
||||
screen:attach()
|
||||
screen:set_default_attr_ids {
|
||||
[1] = {bold = true, foreground = Screen.colors.Blue1},
|
||||
[2] = {reverse = true},
|
||||
[3] = {bold = true, reverse = true},
|
||||
}
|
||||
|
||||
-- Create specific layout and ensure it's left unchanged.
|
||||
-- Use nvim_buf_call on a hidden buffer so aucmd_win is used.
|
||||
exec_lua [[
|
||||
vim.cmd "wincmd s | wincmd _"
|
||||
_G.buf = vim.api.nvim_create_buf(true, true)
|
||||
vim.api.nvim_buf_call(_G.buf, function() vim.cmd "wincmd J" end)
|
||||
]]
|
||||
screen:expect [[
|
||||
^ |
|
||||
{1:~ }|
|
||||
{1:~ }|
|
||||
{1:~ }|
|
||||
{1:~ }|
|
||||
{1:~ }|
|
||||
{3:[No Name] }|
|
||||
|
|
||||
{2:[No Name] }|
|
||||
|
|
||||
]]
|
||||
-- This used to crash after making aucmd_win a normal window via the above.
|
||||
exec_lua [[
|
||||
vim.cmd "tabnew | tabclose # | wincmd s | wincmd _"
|
||||
vim.api.nvim_buf_call(_G.buf, function() vim.cmd "wincmd K" end)
|
||||
]]
|
||||
assert_alive()
|
||||
screen:expect_unchanged()
|
||||
|
||||
-- Ensure splitting still works from inside the aucmd_win.
|
||||
exec_lua [[vim.api.nvim_buf_call(_G.buf, function() vim.cmd "split" end)]]
|
||||
screen:expect [[
|
||||
^ |
|
||||
{1:~ }|
|
||||
{3:[No Name] }|
|
||||
|
|
||||
{1:~ }|
|
||||
{2:[Scratch] }|
|
||||
|
|
||||
{1:~ }|
|
||||
{2:[No Name] }|
|
||||
|
|
||||
]]
|
||||
|
||||
-- After all of our messing around, aucmd_win should still be floating.
|
||||
-- Use :only to ensure _G.buf is hidden again (so the aucmd_win is used).
|
||||
eq("editor", exec_lua [[
|
||||
vim.cmd "only"
|
||||
vim.api.nvim_buf_call(_G.buf, function()
|
||||
_G.config = vim.api.nvim_win_get_config(0)
|
||||
end)
|
||||
return _G.config.relative
|
||||
]])
|
||||
end)
|
||||
|
||||
it(':doautocmd does not warn "No matching autocommands" #10689', function()
|
||||
local screen = Screen.new(32, 3)
|
||||
screen:attach()
|
||||
|
Loading…
Reference in New Issue
Block a user