fix(tui)!: remove ESC NUL forced escape (#17198)

This make Nvim recognize `ESC NUL` as <M-C-Space>, as many terminal
emulators (including libvterm) send <M-C-Space> as `ESC NUL`.

There is already another unambiguous way to encode a `ESC` key supported
by libtermkey: `ESC [ 2 7 u`, which is a `CSI u` sequence.

If one still wants to use `ESC NUL` as `ESC`, they can just map
<M-C-Space> to <Esc>.
This commit is contained in:
zeertzjq 2022-04-11 10:23:33 +08:00 committed by GitHub
parent 9da0023a66
commit a2f157233f
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
3 changed files with 42 additions and 25 deletions

View File

@ -439,22 +439,6 @@ static HandleState handle_bracketed_paste(TermInput *input)
return kNotApplicable;
}
// ESC NUL => <Esc>
static bool handle_forced_escape(TermInput *input)
{
if (rbuffer_size(input->read_stream.buffer) > 1
&& !rbuffer_cmp(input->read_stream.buffer, "\x1b\x00", 2)) {
// skip the ESC and NUL and push one <esc> to the input buffer
size_t rcnt;
termkey_push_bytes(input->tk, rbuffer_read_ptr(input->read_stream.buffer,
&rcnt), 1);
rbuffer_consumed(input->read_stream.buffer, 2);
tk_getkeys(input, true);
return true;
}
return false;
}
static void set_bg_deferred(void **argv)
{
char *bgvalue = argv[0];
@ -583,7 +567,6 @@ static void handle_raw_buffer(TermInput *input, bool force)
if (!force
&& (handle_focus_event(input)
|| (is_paste = handle_bracketed_paste(input)) != kNotApplicable
|| handle_forced_escape(input)
|| (is_bc = handle_background_color(input)) != kNotApplicable)) {
if (is_paste == kIncomplete || is_bc == kIncomplete) {
// Wait for the next input, leaving it in the raw buffer due to an

View File

@ -7,7 +7,9 @@ local nvim_dir = helpers.nvim_dir
local feed_command, nvim = helpers.feed_command, helpers.nvim
local function feed_data(data)
nvim('set_var', 'term_data', data)
-- A string containing NUL bytes is not converted to a Blob when
-- calling nvim_set_var() API, so convert it using Lua instead.
nvim('exec_lua', 'vim.g.term_data = ...', {data})
nvim('command', 'call jobsend(b:terminal_job_id, term_data)')
end

View File

@ -214,7 +214,7 @@ describe('TUI', function()
]])
end)
it('interprets ESC+key as ALT chord', function()
it('interprets ESC+key as ALT chord in i_CTRL-V', function()
-- Vim represents ALT/META by setting the "high bit" of the modified key:
-- ALT+j inserts "ê". Nvim does not (#3982).
feed_data('i\022\027j')
@ -229,6 +229,38 @@ describe('TUI', function()
]])
end)
it('interprets <Esc>[27u as <Esc>', function()
feed_command('nnoremap <M-;> <Nop>')
feed_command('nnoremap <Esc> AESC<Esc>')
feed_command('nnoremap ; Asemicolon<Esc>')
feed_data('\027[27u;')
screen:expect([[
ESCsemicolo{1:n} |
{4:~ }|
{4:~ }|
{4:~ }|
{5:[No Name] [+] }|
|
{3:-- TERMINAL --} |
]])
-- <Esc>; should be recognized as <M-;> when <M-;> is mapped
feed_data('\027;')
screen:expect_unchanged()
end)
it('interprets <Esc><Nul> as <M-C-Space> #17198', function()
feed_data('i\022\027\000')
screen:expect([[
<M-C-Space>{1: } |
{4:~ }|
{4:~ }|
{4:~ }|
{5:[No Name] [+] }|
{3:-- INSERT --} |
{3:-- TERMINAL --} |
]])
end)
it('accepts ASCII control sequences', function()
feed_data('i')
feed_data('\022\007') -- ctrl+g
@ -271,7 +303,7 @@ describe('TUI', function()
{3:-- TERMINAL --} |
]])
feed_data('\027[201~') -- End paste.
feed_data('\027\000') -- ESC: go to Normal mode.
feed_data('\027[27u') -- ESC: go to Normal mode.
wait_for_mode('n')
screen:expect([[
"pasted from termina{1:l}" |
@ -453,7 +485,7 @@ describe('TUI', function()
{3:-- TERMINAL --} |
]]}
-- Dot-repeat/redo.
feed_data('\027\000')
feed_data('\027[27u')
wait_for_mode('n')
feed_data('.')
screen:expect{grid=[[
@ -499,7 +531,7 @@ describe('TUI', function()
vim.paste = function(lines, phase) error("fake fail") end
]], {})
-- Prepare something for dot-repeat/redo.
feed_data('ifoo\n\027\000')
feed_data('ifoo\n\027[27u')
wait_for_mode('n')
screen:expect{grid=[[
foo |
@ -541,7 +573,7 @@ describe('TUI', function()
{3:-- TERMINAL --} |
]]}
-- Editor should still work after failed/drained paste.
feed_data('ityped input...\027\000')
feed_data('ityped input...\027[27u')
screen:expect{grid=[[
foo |
foo |
@ -575,7 +607,7 @@ describe('TUI', function()
vim.paste = function(lines, phase) return false end
]], {})
feed_data('\027[200~line A\nline B\n\027[201~')
feed_data('ifoo\n\027\000')
feed_data('ifoo\n\027[27u')
expect_child_buf_lines({'foo',''})
end)
@ -669,7 +701,7 @@ describe('TUI', function()
{3:-- INSERT --} |
{3:-- TERMINAL --} |
]])
feed_data('\027\000') -- ESC: go to Normal mode.
feed_data('\027[27u') -- ESC: go to Normal mode.
wait_for_mode('n')
-- Dot-repeat/redo.
feed_data('.')