floatwin: show error if window is closed immediately #11476

Autocmds may close window while it is being entered, then
win_set_minimal_style(wp) operates on an invalid pointer.

We could silently ignore this instead, but it is unlikely to be
intentional, so it is more useful to show an error.

fix #11383
This commit is contained in:
Justin M. Keyes
2019-11-29 23:48:14 -08:00
committed by GitHub
parent 1f684cf80a
commit f6e7857c54
4 changed files with 38 additions and 6 deletions

View File

@@ -1096,6 +1096,10 @@ Window nvim_open_win(Buffer buffer, Boolean enter, Dictionary config,
if (enter) {
win_enter(wp, false);
}
if (!win_valid(wp)) {
api_set_error(err, kErrorTypeException, "Window was closed immediately");
return 0;
}
if (buffer > 0) {
nvim_win_set_buf(wp->handle, buffer, err);
}

View File

@@ -4372,9 +4372,10 @@ static void win_goto_hor(bool left, long count)
}
}
/*
* Make window "wp" the current window.
*/
/// Make window `wp` the current window.
///
/// @warning Autocmds may close the window immediately, so caller must check
/// win_valid(wp).
void win_enter(win_T *wp, bool undo_sync)
{
win_enter_ext(wp, undo_sync, false, false, true, true);

View File

@@ -2,9 +2,11 @@ local helpers = require('test.functional.helpers')(after_each)
local Screen = require('test.functional.ui.screen')
local os = require('os')
local clear, feed = helpers.clear, helpers.feed
local assert_alive = helpers.assert_alive
local command, feed_command = helpers.command, helpers.feed_command
local eval = helpers.eval
local eq = helpers.eq
local exec_lua = helpers.exec_lua
local insert = helpers.insert
local meths = helpers.meths
local curbufmeths = helpers.curbufmeths
@@ -12,7 +14,7 @@ local funcs = helpers.funcs
local run = helpers.run
local pcall_err = helpers.pcall_err
describe('floating windows', function()
describe('floatwin', function()
before_each(function()
clear()
end)
@@ -56,6 +58,31 @@ describe('floating windows', function()
eq(1000, funcs.win_getid())
end)
it('closed immediately by autocmd #11383', function()
eq('Error executing lua: [string "<nvim>"]:4: Window was closed immediately',
pcall_err(exec_lua, [[
local a = vim.api
local function crashes(contents)
local buf = a.nvim_create_buf(false, true)
local floatwin = a.nvim_open_win(buf, true, {
relative = 'cursor';
style = 'minimal';
row = 0; col = 0;
height = #contents;
width = 10;
})
a.nvim_buf_set_lines(buf, 0, -1, true, contents)
local winnr = vim.fn.win_id2win(floatwin)
a.nvim_command('wincmd p')
a.nvim_command('autocmd CursorMoved * ++once '..winnr..'wincmd c')
return buf, floatwin
end
crashes{'foo'}
crashes{'bar'}
]]))
assert_alive()
end)
local function with_ext_multigrid(multigrid)
local screen
before_each(function()

View File

@@ -52,10 +52,10 @@ describe('UI receives option updates', function()
local evs = {}
screen = Screen.new(20,5)
-- Override mouse_on/mouse_off handlers.
function screen._handle_mouse_on()
function screen:_handle_mouse_on()
table.insert(evs, 'mouse_on')
end
function screen._handle_mouse_off()
function screen:_handle_mouse_off()
table.insert(evs, 'mouse_off')
end
screen:attach()