mirror of
https://github.com/neovim/neovim.git
synced 2026-01-05 10:57:11 +10:00
Problem: Terminals should respond with the terminator (either BEL or ST) used in the query so that clients can reliably parse the responses. The `TermRequest` autocmd used to handle background color requests in the terminal does not have access to the original sequence terminator, so it always uses BEL. #37018 Solution: Update vterm parsing to include the terminator type, then forward this data into the emitted `TermRequest` events for OSC/DCS/APC sequences. Update the foreground/background `TermRequest` callback to use the same terminator as the original request. Details: I didn't add the terminator to the `TermResponse` event. However, I assume the `TermResponse` event doesn't care about the terminator because the sequence is already parsed. I also didn't update any of the functions in `src/nvim/vterm/state.c` that write out responses. It looked like those all pretty much used ST, and it would be a much larger set of changes. In that same file, there's also logic for 8 bit ST sequences, but from what I can tell, 8 bit doesn't really work (see `:h xterm-8bit`), so I didn't use the 8 bit ST at all.
96 lines
3.3 KiB
Lua
96 lines
3.3 KiB
Lua
local n = require('test.functional.testnvim')()
|
|
|
|
local api = n.api
|
|
local assert_alive = n.assert_alive
|
|
local clear = n.clear
|
|
local exec_lua = n.exec_lua
|
|
|
|
local OSC_PREFIX = string.char(0x1b, 0x5d)
|
|
local BEL = string.char(0x07)
|
|
local ST = string.char(0x1b, 0x5c)
|
|
local NUL = string.char(0x00)
|
|
|
|
describe(':terminal', function()
|
|
before_each(clear)
|
|
|
|
it('handles invalid OSC terminators #30084', function()
|
|
local chan = api.nvim_open_term(0, {})
|
|
api.nvim_chan_send(chan, '\027]8;;https://example.com\027\\Example\027]8;;\027\n')
|
|
assert_alive()
|
|
end)
|
|
|
|
it('handles OSC-2 title setting', function()
|
|
-- OSC-2 should set title.
|
|
local chan = api.nvim_open_term(0, {})
|
|
local input = OSC_PREFIX .. '2;This title set with OSC 2' .. BEL
|
|
api.nvim_chan_send(chan, input)
|
|
--- @type string
|
|
local term_title = api.nvim_buf_get_var(0, 'term_title')
|
|
assert.Equal(term_title, 'This title set with OSC 2')
|
|
assert_alive()
|
|
end)
|
|
|
|
it('handles OSC-0 title and icon setting', function()
|
|
-- OSC-0 should set title and icon name to the same string. We currently ignore the icon name,
|
|
-- but the title should still be reflected.
|
|
local chan = api.nvim_open_term(0, {})
|
|
local input = OSC_PREFIX .. '0;This title set with OSC 0' .. BEL
|
|
api.nvim_chan_send(chan, input)
|
|
--- @type string
|
|
local term_title = api.nvim_buf_get_var(0, 'term_title')
|
|
assert.Equal(term_title, 'This title set with OSC 0')
|
|
assert_alive()
|
|
end)
|
|
|
|
it('handles control character following OSC prefix #34028', function()
|
|
local chan = api.nvim_open_term(0, {})
|
|
-- In order to test for the crash found in #34028 we need a ctrl char following the OSC_PREFIX
|
|
-- which causes `string_fragment()` to be called while in OSC_COMMAND mode, this caused
|
|
-- initial_string to be flipped back to false. At the end we need two more non-BEL control
|
|
-- characters, one to write into the 1 byte buffer, then another to trigger the callback one
|
|
-- more time so that realloc notices that it's internal data has been overwritten.
|
|
local input = OSC_PREFIX .. NUL .. '0;aaaaaaaaaaaaaaaaaaaaaaaaaaa' .. NUL .. NUL
|
|
api.nvim_chan_send(chan, input)
|
|
assert_alive()
|
|
|
|
-- On some platforms such as MacOS we need a longer string to reproduce the crash from #34028.
|
|
input = OSC_PREFIX .. NUL .. '0;'
|
|
for _ = 1, 256 do
|
|
input = input .. 'a'
|
|
end
|
|
input = input .. NUL .. NUL
|
|
api.nvim_chan_send(chan, input)
|
|
assert_alive()
|
|
end)
|
|
|
|
it('uses terminator matching query for OSC TermRequest #37018', function()
|
|
local chan = api.nvim_open_term(0, {})
|
|
exec_lua([[
|
|
vim.api.nvim_create_autocmd("TermRequest", {
|
|
callback = function(args)
|
|
_G.osc10_response = {sequence = args.data.sequence, terminator = args.data.terminator }
|
|
end
|
|
})
|
|
]])
|
|
|
|
local function send_osc_with_terminator(terminator)
|
|
local input = OSC_PREFIX .. '10;?' .. terminator
|
|
api.nvim_chan_send(chan, input)
|
|
end
|
|
|
|
send_osc_with_terminator(BEL)
|
|
--- @type string
|
|
assert.same(
|
|
{ sequence = OSC_PREFIX .. '10;?', terminator = BEL },
|
|
exec_lua([[return _G.osc10_response]])
|
|
)
|
|
|
|
send_osc_with_terminator(ST)
|
|
--- @type string
|
|
assert.same(
|
|
{ sequence = OSC_PREFIX .. '10;?', terminator = ST },
|
|
exec_lua([[return _G.osc10_response]])
|
|
)
|
|
end)
|
|
end)
|