mirror of
https://github.com/neovim/neovim.git
synced 2025-02-25 18:55:25 -06:00
Merge pull request #9985 from bfredl/shenanigans
Fix aucmd_win issues: crashes and redrawing errors.
This commit is contained in:
commit
9e0982a1a2
@ -11,6 +11,7 @@
|
|||||||
#include <fcntl.h>
|
#include <fcntl.h>
|
||||||
|
|
||||||
#include "nvim/vim.h"
|
#include "nvim/vim.h"
|
||||||
|
#include "nvim/api/private/handle.h"
|
||||||
#include "nvim/ascii.h"
|
#include "nvim/ascii.h"
|
||||||
#include "nvim/fileio.h"
|
#include "nvim/fileio.h"
|
||||||
#include "nvim/buffer.h"
|
#include "nvim/buffer.h"
|
||||||
@ -47,6 +48,7 @@
|
|||||||
#include "nvim/state.h"
|
#include "nvim/state.h"
|
||||||
#include "nvim/strings.h"
|
#include "nvim/strings.h"
|
||||||
#include "nvim/ui.h"
|
#include "nvim/ui.h"
|
||||||
|
#include "nvim/ui_compositor.h"
|
||||||
#include "nvim/types.h"
|
#include "nvim/types.h"
|
||||||
#include "nvim/undo.h"
|
#include "nvim/undo.h"
|
||||||
#include "nvim/window.h"
|
#include "nvim/window.h"
|
||||||
@ -6586,6 +6588,8 @@ void aucmd_prepbuf(aco_save_T *aco, buf_T *buf)
|
|||||||
block_autocmds(); // We don't want BufEnter/WinEnter autocommands.
|
block_autocmds(); // We don't want BufEnter/WinEnter autocommands.
|
||||||
if (need_append) {
|
if (need_append) {
|
||||||
win_append(lastwin, aucmd_win);
|
win_append(lastwin, aucmd_win);
|
||||||
|
handle_register_window(aucmd_win);
|
||||||
|
win_config_float(aucmd_win, aucmd_win->w_float_config);
|
||||||
}
|
}
|
||||||
// Prevent chdir() call in win_enter_ext(), through do_autochdir()
|
// Prevent chdir() call in win_enter_ext(), through do_autochdir()
|
||||||
int save_acd = p_acd;
|
int save_acd = p_acd;
|
||||||
@ -6625,6 +6629,13 @@ void aucmd_restbuf(aco_save_T *aco)
|
|||||||
win_found:
|
win_found:
|
||||||
|
|
||||||
win_remove(curwin, NULL);
|
win_remove(curwin, NULL);
|
||||||
|
handle_unregister_window(curwin);
|
||||||
|
if (curwin->w_grid.chars != NULL) {
|
||||||
|
ui_comp_remove_grid(&curwin->w_grid);
|
||||||
|
ui_call_win_hide(curwin->w_grid.handle);
|
||||||
|
grid_free(&curwin->w_grid);
|
||||||
|
}
|
||||||
|
|
||||||
aucmd_win_used = false;
|
aucmd_win_used = false;
|
||||||
last_status(false); // may need to remove last status line
|
last_status(false); // may need to remove last status line
|
||||||
|
|
||||||
|
@ -3418,8 +3418,8 @@ void win_alloc_aucmd_win(void)
|
|||||||
{
|
{
|
||||||
Error err = ERROR_INIT;
|
Error err = ERROR_INIT;
|
||||||
FloatConfig fconfig = FLOAT_CONFIG_INIT;
|
FloatConfig fconfig = FLOAT_CONFIG_INIT;
|
||||||
fconfig.width = 20;
|
fconfig.width = Columns;
|
||||||
fconfig.height = 20;
|
fconfig.height = 5;
|
||||||
fconfig.focusable = false;
|
fconfig.focusable = false;
|
||||||
aucmd_win = win_new_float(NULL, fconfig, &err);
|
aucmd_win = win_new_float(NULL, fconfig, &err);
|
||||||
aucmd_win->w_buffer->b_nwindows--;
|
aucmd_win->w_buffer->b_nwindows--;
|
||||||
|
@ -1,4 +1,5 @@
|
|||||||
local helpers = require('test.functional.helpers')(after_each)
|
local helpers = require('test.functional.helpers')(after_each)
|
||||||
|
local Screen = require('test.functional.ui.screen')
|
||||||
|
|
||||||
local dedent = helpers.dedent
|
local dedent = helpers.dedent
|
||||||
local eq = helpers.eq
|
local eq = helpers.eq
|
||||||
@ -6,11 +7,13 @@ local eval = helpers.eval
|
|||||||
local feed = helpers.feed
|
local feed = helpers.feed
|
||||||
local clear = helpers.clear
|
local clear = helpers.clear
|
||||||
local meths = helpers.meths
|
local meths = helpers.meths
|
||||||
|
local meth_pcall = helpers.meth_pcall
|
||||||
local funcs = helpers.funcs
|
local funcs = helpers.funcs
|
||||||
local expect = helpers.expect
|
local expect = helpers.expect
|
||||||
local command = helpers.command
|
local command = helpers.command
|
||||||
local exc_exec = helpers.exc_exec
|
local exc_exec = helpers.exc_exec
|
||||||
local curbufmeths = helpers.curbufmeths
|
local curbufmeths = helpers.curbufmeths
|
||||||
|
local source = helpers.source
|
||||||
|
|
||||||
describe('autocmd', function()
|
describe('autocmd', function()
|
||||||
before_each(clear)
|
before_each(clear)
|
||||||
@ -144,4 +147,117 @@ describe('autocmd', function()
|
|||||||
--- Autocommands ---]]),
|
--- Autocommands ---]]),
|
||||||
funcs.execute('autocmd Tabnew'))
|
funcs.execute('autocmd Tabnew'))
|
||||||
end)
|
end)
|
||||||
|
|
||||||
|
it('window works', function()
|
||||||
|
-- Nvim uses a special window to execute certain actions for an invisible buffer,
|
||||||
|
-- internally called autcmd_win and mentioned in the docs at :help E813
|
||||||
|
-- Do some safety checks for redrawing and api accesses to this window.
|
||||||
|
|
||||||
|
local screen = Screen.new(50, 10)
|
||||||
|
screen:attach()
|
||||||
|
screen:set_default_attr_ids({
|
||||||
|
[1] = {bold = true, foreground = Screen.colors.Blue1},
|
||||||
|
[2] = {background = Screen.colors.LightMagenta},
|
||||||
|
[3] = {background = Screen.colors.LightMagenta, bold = true, foreground = Screen.colors.Blue1},
|
||||||
|
})
|
||||||
|
|
||||||
|
source([[
|
||||||
|
function! Doit()
|
||||||
|
let g:winid = nvim_get_current_win()
|
||||||
|
redraw!
|
||||||
|
echo getchar()
|
||||||
|
" API functions work when aucmd_win is in scope
|
||||||
|
let g:had_value = has_key(w:, "testvar")
|
||||||
|
call nvim_win_set_var(g:winid, "testvar", 7)
|
||||||
|
let g:test = w:testvar
|
||||||
|
endfunction
|
||||||
|
set hidden
|
||||||
|
" add dummy text to not discard the buffer
|
||||||
|
call setline(1,"bb")
|
||||||
|
autocmd User <buffer> call Doit()
|
||||||
|
]])
|
||||||
|
screen:expect([[
|
||||||
|
^bb |
|
||||||
|
{1:~ }|
|
||||||
|
{1:~ }|
|
||||||
|
{1:~ }|
|
||||||
|
{1:~ }|
|
||||||
|
{1:~ }|
|
||||||
|
{1:~ }|
|
||||||
|
{1:~ }|
|
||||||
|
{1:~ }|
|
||||||
|
|
|
||||||
|
]])
|
||||||
|
|
||||||
|
feed(":enew | doautoall User<cr>")
|
||||||
|
screen:expect([[
|
||||||
|
{2:bb }|
|
||||||
|
{3:~ }|
|
||||||
|
{3:~ }|
|
||||||
|
{3:~ }|
|
||||||
|
{3:~ }|
|
||||||
|
{1:~ }|
|
||||||
|
{1:~ }|
|
||||||
|
{1:~ }|
|
||||||
|
{1:~ }|
|
||||||
|
^:enew | doautoall User |
|
||||||
|
]])
|
||||||
|
|
||||||
|
feed('<cr>')
|
||||||
|
screen:expect([[
|
||||||
|
^ |
|
||||||
|
{1:~ }|
|
||||||
|
{1:~ }|
|
||||||
|
{1:~ }|
|
||||||
|
{1:~ }|
|
||||||
|
{1:~ }|
|
||||||
|
{1:~ }|
|
||||||
|
{1:~ }|
|
||||||
|
{1:~ }|
|
||||||
|
13 |
|
||||||
|
]])
|
||||||
|
eq(7, eval('g:test'))
|
||||||
|
|
||||||
|
-- API calls are blocked when aucmd_win is not in scope
|
||||||
|
eq({false, 'Vim(call):Invalid window id'},
|
||||||
|
meth_pcall(command, "call nvim_set_current_win(g:winid)"))
|
||||||
|
|
||||||
|
-- second time aucmd_win is needed, a different code path is invoked
|
||||||
|
-- to reuse the same window, so check again
|
||||||
|
command("let g:test = v:null")
|
||||||
|
command("let g:had_value = v:null")
|
||||||
|
feed(":doautoall User<cr>")
|
||||||
|
screen:expect([[
|
||||||
|
{2:bb }|
|
||||||
|
{3:~ }|
|
||||||
|
{3:~ }|
|
||||||
|
{3:~ }|
|
||||||
|
{3:~ }|
|
||||||
|
{1:~ }|
|
||||||
|
{1:~ }|
|
||||||
|
{1:~ }|
|
||||||
|
{1:~ }|
|
||||||
|
^:doautoall User |
|
||||||
|
]])
|
||||||
|
|
||||||
|
feed('<cr>')
|
||||||
|
screen:expect([[
|
||||||
|
^ |
|
||||||
|
{1:~ }|
|
||||||
|
{1:~ }|
|
||||||
|
{1:~ }|
|
||||||
|
{1:~ }|
|
||||||
|
{1:~ }|
|
||||||
|
{1:~ }|
|
||||||
|
{1:~ }|
|
||||||
|
{1:~ }|
|
||||||
|
13 |
|
||||||
|
]])
|
||||||
|
-- win vars in aucmd_win should have been reset
|
||||||
|
eq(0, eval('g:had_value'))
|
||||||
|
eq(7, eval('g:test'))
|
||||||
|
|
||||||
|
eq({false, 'Vim(call):Invalid window id'},
|
||||||
|
meth_pcall(command, "call nvim_set_current_win(g:winid)"))
|
||||||
|
end)
|
||||||
end)
|
end)
|
||||||
|
Loading…
Reference in New Issue
Block a user