mirror of
https://github.com/neovim/neovim.git
synced 2025-02-25 18:55:25 -06:00
feat(term): trigger TermRequest for APC (#32407)
Co-authored-by: Gregory Anders <greg@gpanders.com> Co-authored-by: zeertzjq <zeertzjq@outlook.com>
This commit is contained in:
parent
e4c6e732fd
commit
93480f7fba
@ -1004,8 +1004,8 @@ TermClose When a |terminal| job ends.
|
||||
Sets these |v:event| keys:
|
||||
status
|
||||
*TermRequest*
|
||||
TermRequest When a |:terminal| child process emits an OSC
|
||||
or DCS sequence. Sets |v:termrequest|. The
|
||||
TermRequest When a |:terminal| child process emits an OSC,
|
||||
DCS or APC sequence. Sets |v:termrequest|. The
|
||||
|event-data| is the request string.
|
||||
*TermResponse*
|
||||
TermResponse When Nvim receives an OSC or DCS response from
|
||||
|
@ -372,6 +372,8 @@ TERMINAL
|
||||
• The |terminal| has experimental support for the Kitty keyboard protocol
|
||||
(sometimes called "CSI u" key encoding). Only the "Disambiguate escape
|
||||
codes" mode is currently supported.
|
||||
• The |terminal| emits a |TermRequest| autocommand event when the child process
|
||||
emits an APC control sequence.
|
||||
|
||||
TREESITTER
|
||||
|
||||
|
@ -663,7 +663,7 @@ v:t_string Value of |String| type. Read-only. See: |type()|
|
||||
|
||||
*v:termrequest* *termrequest-variable*
|
||||
v:termrequest
|
||||
The value of the most recent OSC or DCS control sequence
|
||||
The value of the most recent OSC, DCS or APC control sequence
|
||||
sent from a process running in the embedded |terminal|.
|
||||
This can be read in a |TermRequest| event handler to respond
|
||||
to queries from embedded applications.
|
||||
|
2
runtime/lua/vim/_meta/vvars.lua
generated
2
runtime/lua/vim/_meta/vvars.lua
generated
@ -700,7 +700,7 @@ vim.v.t_number = ...
|
||||
--- @type integer
|
||||
vim.v.t_string = ...
|
||||
|
||||
--- The value of the most recent OSC or DCS control sequence
|
||||
--- The value of the most recent OSC, DCS or APC control sequence
|
||||
--- sent from a process running in the embedded `terminal`.
|
||||
--- This can be read in a `TermRequest` event handler to respond
|
||||
--- to queries from embedded applications.
|
||||
|
@ -183,8 +183,10 @@ struct terminal {
|
||||
|
||||
bool color_set[16];
|
||||
|
||||
char *selection_buffer; /// libvterm selection buffer
|
||||
StringBuilder selection; /// Growable array containing full selection data
|
||||
char *selection_buffer; ///< libvterm selection buffer
|
||||
StringBuilder selection; ///< Growable array containing full selection data
|
||||
|
||||
StringBuilder termrequest_buffer; ///< Growable array containing unfinished request payload
|
||||
|
||||
size_t refcount; // reference count
|
||||
};
|
||||
@ -307,15 +309,22 @@ static int on_osc(int command, VTermStringFragment frag, void *user)
|
||||
return 1;
|
||||
}
|
||||
|
||||
StringBuilder request = KV_INITIAL_VALUE;
|
||||
kv_printf(request, "\x1b]%d;", command);
|
||||
kv_concat_len(request, frag.str, frag.len);
|
||||
schedule_termrequest(term, request.items, request.size);
|
||||
if (frag.initial) {
|
||||
kv_size(term->termrequest_buffer) = 0;
|
||||
kv_printf(term->termrequest_buffer, "\x1b]%d;", command);
|
||||
}
|
||||
kv_concat_len(term->termrequest_buffer, frag.str, frag.len);
|
||||
if (frag.final) {
|
||||
char *payload = xmemdup(term->termrequest_buffer.items, term->termrequest_buffer.size);
|
||||
schedule_termrequest(user, payload, term->termrequest_buffer.size);
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
|
||||
static int on_dcs(const char *command, size_t commandlen, VTermStringFragment frag, void *user)
|
||||
{
|
||||
Terminal *term = user;
|
||||
|
||||
if (command == NULL || frag.str == NULL) {
|
||||
return 0;
|
||||
}
|
||||
@ -323,10 +332,38 @@ static int on_dcs(const char *command, size_t commandlen, VTermStringFragment fr
|
||||
return 1;
|
||||
}
|
||||
|
||||
StringBuilder request = KV_INITIAL_VALUE;
|
||||
kv_printf(request, "\x1bP%*s", (int)commandlen, command);
|
||||
kv_concat_len(request, frag.str, frag.len);
|
||||
schedule_termrequest(user, request.items, request.size);
|
||||
if (frag.initial) {
|
||||
kv_size(term->termrequest_buffer) = 0;
|
||||
kv_printf(term->termrequest_buffer, "\x1bP%*s", (int)commandlen, command);
|
||||
}
|
||||
kv_concat_len(term->termrequest_buffer, frag.str, frag.len);
|
||||
if (frag.final) {
|
||||
char *payload = xmemdup(term->termrequest_buffer.items, term->termrequest_buffer.size);
|
||||
schedule_termrequest(user, payload, term->termrequest_buffer.size);
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
|
||||
static int on_apc(VTermStringFragment frag, void *user)
|
||||
{
|
||||
Terminal *term = user;
|
||||
if (frag.str == NULL || frag.len == 0) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (!has_event(EVENT_TERMREQUEST)) {
|
||||
return 1;
|
||||
}
|
||||
|
||||
if (frag.initial) {
|
||||
kv_size(term->termrequest_buffer) = 0;
|
||||
kv_printf(term->termrequest_buffer, "\x1b_");
|
||||
}
|
||||
kv_concat_len(term->termrequest_buffer, frag.str, frag.len);
|
||||
if (frag.final) {
|
||||
char *payload = xmemdup(term->termrequest_buffer.items, term->termrequest_buffer.size);
|
||||
schedule_termrequest(user, payload, term->termrequest_buffer.size);
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
|
||||
@ -335,7 +372,7 @@ static VTermStateFallbacks vterm_fallbacks = {
|
||||
.csi = NULL,
|
||||
.osc = on_osc,
|
||||
.dcs = on_dcs,
|
||||
.apc = NULL,
|
||||
.apc = on_apc,
|
||||
.pm = NULL,
|
||||
.sos = NULL,
|
||||
};
|
||||
@ -924,6 +961,7 @@ void terminal_destroy(Terminal **termpp)
|
||||
xfree(term->title);
|
||||
xfree(term->selection_buffer);
|
||||
kv_destroy(term->selection);
|
||||
kv_destroy(term->termrequest_buffer);
|
||||
vterm_free(term->vt);
|
||||
xfree(term);
|
||||
*termpp = NULL; // coverity[dead-store]
|
||||
|
@ -799,7 +799,7 @@ M.vars = {
|
||||
termrequest = {
|
||||
type = 'string',
|
||||
desc = [=[
|
||||
The value of the most recent OSC or DCS control sequence
|
||||
The value of the most recent OSC, DCS or APC control sequence
|
||||
sent from a process running in the embedded |terminal|.
|
||||
This can be read in a |TermRequest| event handler to respond
|
||||
to queries from embedded applications.
|
||||
|
@ -350,6 +350,17 @@ describe(':terminal buffer', function()
|
||||
eq(termbuf, eval('g:termbuf'))
|
||||
end)
|
||||
|
||||
it('emits TermRequest events for APC', function()
|
||||
local term = api.nvim_open_term(0, {})
|
||||
|
||||
-- cwd will be inserted in a file URI, which cannot contain backs
|
||||
local cwd = t.fix_slashes(fn.getcwd())
|
||||
local parent = cwd:match('^(.+/)')
|
||||
local expected = '\027_Gfile://host' .. parent
|
||||
api.nvim_chan_send(term, string.format('%s\027\\', expected))
|
||||
eq(expected, eval('v:termrequest'))
|
||||
end)
|
||||
|
||||
it('TermRequest synchronization #27572', function()
|
||||
command('autocmd! nvim.terminal TermRequest')
|
||||
local term = exec_lua([[
|
||||
|
Loading…
Reference in New Issue
Block a user