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 "nvim/vim.h"
|
||||
#include "nvim/api/private/handle.h"
|
||||
#include "nvim/ascii.h"
|
||||
#include "nvim/fileio.h"
|
||||
#include "nvim/buffer.h"
|
||||
@ -47,6 +48,7 @@
|
||||
#include "nvim/state.h"
|
||||
#include "nvim/strings.h"
|
||||
#include "nvim/ui.h"
|
||||
#include "nvim/ui_compositor.h"
|
||||
#include "nvim/types.h"
|
||||
#include "nvim/undo.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.
|
||||
if (need_append) {
|
||||
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()
|
||||
int save_acd = p_acd;
|
||||
@ -6625,6 +6629,13 @@ void aucmd_restbuf(aco_save_T *aco)
|
||||
win_found:
|
||||
|
||||
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;
|
||||
last_status(false); // may need to remove last status line
|
||||
|
||||
|
@ -3418,8 +3418,8 @@ void win_alloc_aucmd_win(void)
|
||||
{
|
||||
Error err = ERROR_INIT;
|
||||
FloatConfig fconfig = FLOAT_CONFIG_INIT;
|
||||
fconfig.width = 20;
|
||||
fconfig.height = 20;
|
||||
fconfig.width = Columns;
|
||||
fconfig.height = 5;
|
||||
fconfig.focusable = false;
|
||||
aucmd_win = win_new_float(NULL, fconfig, &err);
|
||||
aucmd_win->w_buffer->b_nwindows--;
|
||||
|
@ -1,4 +1,5 @@
|
||||
local helpers = require('test.functional.helpers')(after_each)
|
||||
local Screen = require('test.functional.ui.screen')
|
||||
|
||||
local dedent = helpers.dedent
|
||||
local eq = helpers.eq
|
||||
@ -6,11 +7,13 @@ local eval = helpers.eval
|
||||
local feed = helpers.feed
|
||||
local clear = helpers.clear
|
||||
local meths = helpers.meths
|
||||
local meth_pcall = helpers.meth_pcall
|
||||
local funcs = helpers.funcs
|
||||
local expect = helpers.expect
|
||||
local command = helpers.command
|
||||
local exc_exec = helpers.exc_exec
|
||||
local curbufmeths = helpers.curbufmeths
|
||||
local source = helpers.source
|
||||
|
||||
describe('autocmd', function()
|
||||
before_each(clear)
|
||||
@ -144,4 +147,117 @@ describe('autocmd', function()
|
||||
--- Autocommands ---]]),
|
||||
funcs.execute('autocmd Tabnew'))
|
||||
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)
|
||||
|
Loading…
Reference in New Issue
Block a user