mirror of
https://github.com/neovim/neovim.git
synced 2025-09-13 14:58:18 +00:00

This is the first installment of a multi-PR series significantly refactoring how highlights are being specified. The end goal is to have a base set of 20 ish most common highlights, and then specific files only need to add more groups to that as needed. As a complicating factor, we also want to migrate to the new default color scheme eventually. But by sharing a base set, that future PR will hopefully be a lot smaller since a lot of tests will be migrated just simply by updating the base set in place. As a first step, fix the anti-pattern than Screen defaults to ignoring highlights. Highlights are integral part of the screen state, not something "extra" which we only test "sometimes". For now, we still allow opt-out via the intentionally ugly screen._default_attr_ids = nil The end goal is to get rid of all of these eventually (which will be easier as part of the color scheme migration)
280 lines
9.2 KiB
Lua
280 lines
9.2 KiB
Lua
local helpers = require('test.functional.helpers')(after_each)
|
|
local Screen = require('test.functional.ui.screen')
|
|
local clear = helpers.clear
|
|
local eq = helpers.eq
|
|
local eval = helpers.eval
|
|
local command = helpers.command
|
|
local pcall_err = helpers.pcall_err
|
|
local feed = helpers.feed
|
|
local poke_eventloop = helpers.poke_eventloop
|
|
local is_os = helpers.is_os
|
|
local api = helpers.api
|
|
local async_meths = helpers.async_meths
|
|
local testprg = helpers.testprg
|
|
local assert_alive = helpers.assert_alive
|
|
|
|
describe('terminal channel is closed and later released if', function()
|
|
local screen
|
|
|
|
before_each(function()
|
|
clear()
|
|
screen = Screen.new()
|
|
screen:attach()
|
|
end)
|
|
|
|
it('opened by nvim_open_term() and deleted by :bdelete!', function()
|
|
command([[let id = nvim_open_term(0, {})]])
|
|
local chans = eval('len(nvim_list_chans())')
|
|
-- channel hasn't been released yet
|
|
eq(
|
|
"Vim(call):Can't send data to closed stream",
|
|
pcall_err(command, [[bdelete! | call chansend(id, 'test')]])
|
|
)
|
|
feed('<Ignore>') -- add input to separate two RPC requests
|
|
-- channel has been released after one main loop iteration
|
|
eq(chans - 1, eval('len(nvim_list_chans())'))
|
|
end)
|
|
|
|
it('opened by nvim_open_term(), closed by chanclose(), and deleted by pressing a key', function()
|
|
command('let id = nvim_open_term(0, {})')
|
|
local chans = eval('len(nvim_list_chans())')
|
|
-- channel has been closed but not released
|
|
eq(
|
|
"Vim(call):Can't send data to closed stream",
|
|
pcall_err(command, [[call chanclose(id) | call chansend(id, 'test')]])
|
|
)
|
|
screen:expect({ any = '%[Terminal closed%]' })
|
|
eq(chans, eval('len(nvim_list_chans())'))
|
|
-- delete terminal
|
|
feed('i<CR>')
|
|
-- need to first process input
|
|
poke_eventloop()
|
|
feed('<Ignore>') -- add input to separate two RPC requests
|
|
-- channel has been released after another main loop iteration
|
|
eq(chans - 1, eval('len(nvim_list_chans())'))
|
|
end)
|
|
|
|
it('opened by nvim_open_term(), closed by chanclose(), and deleted by :bdelete', function()
|
|
command('let id = nvim_open_term(0, {})')
|
|
local chans = eval('len(nvim_list_chans())')
|
|
-- channel has been closed but not released
|
|
eq(
|
|
"Vim(call):Can't send data to closed stream",
|
|
pcall_err(command, [[call chanclose(id) | call chansend(id, 'test')]])
|
|
)
|
|
screen:expect({ any = '%[Terminal closed%]' })
|
|
eq(chans, eval('len(nvim_list_chans())'))
|
|
-- channel still hasn't been released yet
|
|
eq(
|
|
"Vim(call):Can't send data to closed stream",
|
|
pcall_err(command, [[bdelete | call chansend(id, 'test')]])
|
|
)
|
|
feed('<Ignore>') -- add input to separate two RPC requests
|
|
-- channel has been released after one main loop iteration
|
|
eq(chans - 1, eval('len(nvim_list_chans())'))
|
|
end)
|
|
|
|
it('opened by termopen(), exited, and deleted by pressing a key', function()
|
|
command([[let id = termopen('echo')]])
|
|
local chans = eval('len(nvim_list_chans())')
|
|
-- wait for process to exit
|
|
screen:expect({ any = '%[Process exited 0%]' })
|
|
-- process has exited but channel has't been released
|
|
eq(
|
|
"Vim(call):Can't send data to closed stream",
|
|
pcall_err(command, [[call chansend(id, 'test')]])
|
|
)
|
|
eq(chans, eval('len(nvim_list_chans())'))
|
|
-- delete terminal
|
|
feed('i<CR>')
|
|
-- need to first process input
|
|
poke_eventloop()
|
|
feed('<Ignore>') -- add input to separate two RPC requests
|
|
-- channel has been released after another main loop iteration
|
|
eq(chans - 1, eval('len(nvim_list_chans())'))
|
|
end)
|
|
|
|
-- This indirectly covers #16264
|
|
it('opened by termopen(), exited, and deleted by :bdelete', function()
|
|
command([[let id = termopen('echo')]])
|
|
local chans = eval('len(nvim_list_chans())')
|
|
-- wait for process to exit
|
|
screen:expect({ any = '%[Process exited 0%]' })
|
|
-- process has exited but channel hasn't been released
|
|
eq(
|
|
"Vim(call):Can't send data to closed stream",
|
|
pcall_err(command, [[call chansend(id, 'test')]])
|
|
)
|
|
eq(chans, eval('len(nvim_list_chans())'))
|
|
-- channel still hasn't been released yet
|
|
eq(
|
|
"Vim(call):Can't send data to closed stream",
|
|
pcall_err(command, [[bdelete | call chansend(id, 'test')]])
|
|
)
|
|
feed('<Ignore>') -- add input to separate two RPC requests
|
|
-- channel has been released after one main loop iteration
|
|
eq(chans - 1, eval('len(nvim_list_chans())'))
|
|
end)
|
|
end)
|
|
|
|
it('chansend sends lines to terminal channel in proper order', function()
|
|
clear({ args = { '--cmd', 'set laststatus=2' } })
|
|
local screen = Screen.new(100, 20)
|
|
screen:attach()
|
|
screen._default_attr_ids = nil
|
|
local shells = is_os('win') and { 'cmd.exe', 'pwsh.exe -nop', 'powershell.exe -nop' } or { 'sh' }
|
|
for _, sh in ipairs(shells) do
|
|
command([[let id = termopen(']] .. sh .. [[')]])
|
|
command([[call chansend(id, ['echo "hello"', 'echo "world"', ''])]])
|
|
screen:expect {
|
|
any = [[echo "hello".*echo "world"]],
|
|
}
|
|
command('bdelete!')
|
|
screen:expect {
|
|
any = '%[No Name%]',
|
|
}
|
|
end
|
|
end)
|
|
|
|
describe('no crash when TermOpen autocommand', function()
|
|
local screen
|
|
|
|
before_each(function()
|
|
clear()
|
|
api.nvim_set_option_value('shell', testprg('shell-test'), {})
|
|
command('set shellcmdflag=EXE shellredir= shellpipe= shellquote= shellxquote=')
|
|
screen = Screen.new(60, 4)
|
|
screen:set_default_attr_ids({
|
|
[0] = { bold = true, foreground = Screen.colors.Blue },
|
|
})
|
|
screen:attach()
|
|
end)
|
|
|
|
it('processes job exit event when using termopen()', function()
|
|
command([[autocmd TermOpen * call input('')]])
|
|
async_meths.nvim_command('terminal foobar')
|
|
screen:expect {
|
|
grid = [[
|
|
|
|
|
{0:~ }|*2
|
|
^ |
|
|
]],
|
|
}
|
|
feed('<CR>')
|
|
screen:expect {
|
|
grid = [[
|
|
^ready $ foobar |
|
|
|
|
|
[Process exited 0] |
|
|
|
|
|
]],
|
|
}
|
|
feed('i<CR>')
|
|
screen:expect {
|
|
grid = [[
|
|
^ |
|
|
{0:~ }|*2
|
|
|
|
|
]],
|
|
}
|
|
assert_alive()
|
|
end)
|
|
|
|
it('wipes buffer and processes events when using termopen()', function()
|
|
command([[autocmd TermOpen * bwipe! | call input('')]])
|
|
async_meths.nvim_command('terminal foobar')
|
|
screen:expect {
|
|
grid = [[
|
|
|
|
|
{0:~ }|*2
|
|
^ |
|
|
]],
|
|
}
|
|
feed('<CR>')
|
|
screen:expect {
|
|
grid = [[
|
|
^ |
|
|
{0:~ }|*2
|
|
|
|
|
]],
|
|
}
|
|
assert_alive()
|
|
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 {
|
|
grid = [[
|
|
|
|
|
{0:~ }|*2
|
|
^ |
|
|
]],
|
|
}
|
|
feed('<CR>')
|
|
screen:expect {
|
|
grid = [[
|
|
^ |
|
|
{0:~ }|*2
|
|
|
|
|
]],
|
|
}
|
|
assert_alive()
|
|
end)
|
|
end)
|
|
|
|
describe('nvim_open_term', function()
|
|
local screen
|
|
|
|
before_each(function()
|
|
clear()
|
|
screen = Screen.new(8, 10)
|
|
screen:attach()
|
|
end)
|
|
|
|
it('with force_crlf=true converts newlines', function()
|
|
local win = api.nvim_get_current_win()
|
|
local buf = api.nvim_create_buf(false, true)
|
|
local term = api.nvim_open_term(buf, { force_crlf = true })
|
|
api.nvim_win_set_buf(win, buf)
|
|
api.nvim_chan_send(term, 'here\nthere\nfoo\r\nbar\n\ntest')
|
|
screen:expect {
|
|
grid = [[
|
|
^here |
|
|
there |
|
|
foo |
|
|
bar |
|
|
|
|
|
test |
|
|
|*4
|
|
]],
|
|
}
|
|
api.nvim_chan_send(term, '\nfirst')
|
|
screen:expect {
|
|
grid = [[
|
|
^here |
|
|
there |
|
|
foo |
|
|
bar |
|
|
|
|
|
test |
|
|
first |
|
|
|*3
|
|
]],
|
|
}
|
|
end)
|
|
|
|
it('with force_crlf=false does not convert newlines', function()
|
|
local win = api.nvim_get_current_win()
|
|
local buf = api.nvim_create_buf(false, true)
|
|
local term = api.nvim_open_term(buf, { force_crlf = false })
|
|
api.nvim_win_set_buf(win, buf)
|
|
api.nvim_chan_send(term, 'here\nthere')
|
|
screen:expect { grid = [[
|
|
^here |
|
|
there |
|
|
|*8
|
|
]] }
|
|
end)
|
|
end)
|