mirror of
https://github.com/neovim/neovim.git
synced 2026-02-20 09:19:43 +10:00
fix(terminal): losing output if BufFile* poll for events (#37580)
Problem: Terminal loses output if a BufFilePre or BufFilePost autocmd
polls for events.
Solution: Rename the buffer after allocating the terminal instance. Also
fix buffer getting wrong name if BufFilePre uses NameBuff.
This commit is contained in:
@@ -801,10 +801,9 @@ describe(':terminal buffer', function()
|
||||
check_term_rep_20000('REPFAST')
|
||||
end)
|
||||
|
||||
-- it('does not drop data when autocommands poll for events #37559', function()
|
||||
it('does not drop data when TermOpen polls for events', function()
|
||||
-- api.nvim_create_autocmd('BufFilePre', { command = 'sleep 50m', nested = true })
|
||||
-- api.nvim_create_autocmd('BufFilePost', { command = 'sleep 50m', nested = true })
|
||||
it('does not drop data when autocommands poll for events #37559', function()
|
||||
api.nvim_create_autocmd('BufFilePre', { command = 'sleep 50m', nested = true })
|
||||
api.nvim_create_autocmd('BufFilePost', { command = 'sleep 50m', nested = true })
|
||||
api.nvim_create_autocmd('TermOpen', { command = 'sleep 50m', nested = true })
|
||||
-- REP pauses 1 ms every 100 lines, so each autocommand processes some output.
|
||||
check_term_rep_20000('REP')
|
||||
@@ -1144,6 +1143,26 @@ describe(':terminal buffer', function()
|
||||
eq('OTHER_TITLE', api.nvim_buf_get_var(0, 'term_title'))
|
||||
matches('^E937: ', api.nvim_get_vvar('errmsg'))
|
||||
end)
|
||||
|
||||
it('using NameBuff in BufFilePre does not interfere with buffer rename', function()
|
||||
local oldbuf = api.nvim_get_current_buf()
|
||||
n.exec([[
|
||||
file Xoldfile
|
||||
new Xotherfile
|
||||
wincmd w
|
||||
let g:BufFilePre_bufs = []
|
||||
let g:BufFilePost_bufs = []
|
||||
autocmd BufFilePre * call add(g:BufFilePre_bufs, [bufnr(), bufname()])
|
||||
autocmd BufFilePost * call add(g:BufFilePost_bufs, [bufnr(), bufname()])
|
||||
autocmd BufFilePre,BufFilePost * call execute('ls')
|
||||
]])
|
||||
fn.jobstart({ testprg('shell-test') }, { term = true })
|
||||
eq({ { oldbuf, 'Xoldfile' } }, api.nvim_get_var('BufFilePre_bufs'))
|
||||
local buffilepost_bufs = api.nvim_get_var('BufFilePost_bufs')
|
||||
eq(1, #buffilepost_bufs)
|
||||
eq(oldbuf, buffilepost_bufs[1][1])
|
||||
matches('^term://', buffilepost_bufs[1][2])
|
||||
end)
|
||||
end)
|
||||
|
||||
describe('on_lines does not emit out-of-bounds line indexes when', function()
|
||||
|
||||
@@ -138,41 +138,53 @@ it('chansend sends lines to terminal channel in proper order', function()
|
||||
end
|
||||
end)
|
||||
|
||||
describe('no crash when TermOpen autocommand', function()
|
||||
local screen
|
||||
--- @param event string
|
||||
--- @param extra_tests fun(table, table)?
|
||||
local function test_autocmd_no_crash(event, extra_tests)
|
||||
local env = {}
|
||||
-- Use REPFAST for immediately output after start.
|
||||
local term_args = { testprg('shell-test'), 'REPFAST', '50', 'TEST' }
|
||||
|
||||
before_each(function()
|
||||
clear()
|
||||
screen = Screen.new(60, 4)
|
||||
command([[call setline(1, 'OLDBUF') | enew]])
|
||||
env.screen = Screen.new(60, 4)
|
||||
command([[file Xoldbuf | call setline(1, 'OLDBUF') | enew]])
|
||||
-- Wait before :bwipe to avoid closing PTY master before the child calls setsid(),
|
||||
-- as that will cause SIGHUP to be also sent to the parent.
|
||||
-- Use vim.uv.sleep() which blocks the event loop.
|
||||
n.exec([[
|
||||
func Wipe()
|
||||
lua vim.uv.sleep(5)
|
||||
bwipe!
|
||||
endfunc
|
||||
]])
|
||||
end)
|
||||
|
||||
it('processes job exit event when using jobstart(…,{term=true})', function()
|
||||
command([[autocmd TermOpen * call input('')]])
|
||||
api.nvim_create_autocmd(event, { command = "call input('')" })
|
||||
async_meths.nvim_call_function('jobstart', { term_args, { term = true } })
|
||||
screen:expect([[
|
||||
env.screen:expect([[
|
||||
|
|
||||
{1:~ }|*2
|
||||
^ |
|
||||
]])
|
||||
vim.uv.sleep(20)
|
||||
feed('<CR>')
|
||||
screen:expect([[
|
||||
env.screen:expect([[
|
||||
^0: TEST |
|
||||
1: TEST |
|
||||
2: TEST |
|
||||
|
|
||||
]])
|
||||
feed('i')
|
||||
screen:expect([[
|
||||
env.screen:expect([[
|
||||
49: TEST |
|
||||
|
|
||||
[Process exited 0]^ |
|
||||
{5:-- TERMINAL --} |
|
||||
]])
|
||||
feed('<CR>')
|
||||
screen:expect([[
|
||||
env.screen:expect([[
|
||||
^OLDBUF |
|
||||
{1:~ }|*2
|
||||
|
|
||||
@@ -181,50 +193,69 @@ describe('no crash when TermOpen autocommand', function()
|
||||
end)
|
||||
|
||||
it('wipes buffer and processes events when using jobstart(…,{term=true})', function()
|
||||
command([[autocmd TermOpen * bwipe! | call input('')]])
|
||||
api.nvim_create_autocmd(event, { command = "call Wipe() | call input('')" })
|
||||
async_meths.nvim_call_function('jobstart', { term_args, { term = true } })
|
||||
screen:expect([[
|
||||
env.screen:expect([[
|
||||
|
|
||||
{1:~ }|*2
|
||||
^ |
|
||||
]])
|
||||
vim.uv.sleep(20)
|
||||
feed('<CR>')
|
||||
screen:expect([[
|
||||
env.screen:expect([[
|
||||
^OLDBUF |
|
||||
{1:~ }|*2
|
||||
|
|
||||
]])
|
||||
assert_alive()
|
||||
eq('Xoldbuf', eval('bufname()'))
|
||||
eq(0, eval([[exists('b:term_title')]]))
|
||||
end)
|
||||
|
||||
it('wipes buffer and processes events when using nvim_open_term()', function()
|
||||
command([[autocmd TermOpen * bwipe! | call input('')]])
|
||||
async_meths.nvim_open_term(0, {})
|
||||
screen:expect([[
|
||||
|
|
||||
{1:~ }|*2
|
||||
^ |
|
||||
]])
|
||||
feed('<CR>')
|
||||
screen:expect([[
|
||||
^OLDBUF |
|
||||
{1:~ }|*2
|
||||
|
|
||||
]])
|
||||
assert_alive()
|
||||
end)
|
||||
if extra_tests then
|
||||
extra_tests(env, term_args)
|
||||
end
|
||||
end
|
||||
|
||||
it('wipes buffer when using jobstart(…,{term=true}) during Nvim exit', function()
|
||||
n.expect_exit(n.exec_lua, function()
|
||||
vim.schedule(function()
|
||||
vim.fn.jobstart(term_args, { term = true })
|
||||
describe('no crash when TermOpen autocommand', function()
|
||||
test_autocmd_no_crash('TermOpen', function(env, term_args)
|
||||
it('wipes buffer and processes events when using nvim_open_term()', function()
|
||||
api.nvim_create_autocmd('TermOpen', { command = "call Wipe() | call input('')" })
|
||||
async_meths.nvim_open_term(0, {})
|
||||
env.screen:expect([[
|
||||
|
|
||||
{1:~ }|*2
|
||||
^ |
|
||||
]])
|
||||
feed('<CR>')
|
||||
env.screen:expect([[
|
||||
^OLDBUF |
|
||||
{1:~ }|*2
|
||||
|
|
||||
]])
|
||||
assert_alive()
|
||||
end)
|
||||
|
||||
it('wipes buffer when using jobstart(…,{term=true}) during Nvim exit', function()
|
||||
n.expect_exit(n.exec_lua, function()
|
||||
vim.schedule(function()
|
||||
vim.fn.jobstart(term_args, { term = true })
|
||||
end)
|
||||
vim.api.nvim_create_autocmd('TermOpen', { command = 'call Wipe()' })
|
||||
vim.cmd('qall!')
|
||||
end)
|
||||
vim.cmd('autocmd TermOpen * bwipe!')
|
||||
vim.cmd('qall!')
|
||||
end)
|
||||
end)
|
||||
end)
|
||||
|
||||
describe('no crash when BufFilePre autocommand', function()
|
||||
test_autocmd_no_crash('BufFilePre')
|
||||
end)
|
||||
|
||||
describe('no crash when BufFilePost autocommand', function()
|
||||
test_autocmd_no_crash('BufFilePost')
|
||||
end)
|
||||
|
||||
describe('nvim_open_term', function()
|
||||
local screen
|
||||
|
||||
|
||||
Reference in New Issue
Block a user