aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/nvim/auevents.lua2
-rw-r--r--src/nvim/eval.c1
-rw-r--r--src/nvim/eval.h1
-rw-r--r--src/nvim/terminal.c49
-rw-r--r--src/nvim/vvars.lua12
5 files changed, 64 insertions, 1 deletions
diff --git a/src/nvim/auevents.lua b/src/nvim/auevents.lua
index 11d1597236..b931907fe3 100644
--- a/src/nvim/auevents.lua
+++ b/src/nvim/auevents.lua
@@ -109,6 +109,7 @@ return {
'TermEnter', -- after entering Terminal mode
'TermLeave', -- after leaving Terminal mode
'TermOpen', -- after opening a terminal buffer
+ 'TermRequest', -- after an unhandled OSC sequence is emitted
'TermResponse', -- after setting "v:termresponse"
'TextChanged', -- text was modified
'TextChangedI', -- text was modified in Insert mode(no popup)
@@ -166,6 +167,7 @@ return {
TabNewEntered = true,
TermClose = true,
TermOpen = true,
+ TermRequest = true,
UIEnter = true,
UILeave = true,
},
diff --git a/src/nvim/eval.c b/src/nvim/eval.c
index 5069f00df0..451e258356 100644
--- a/src/nvim/eval.c
+++ b/src/nvim/eval.c
@@ -185,6 +185,7 @@ static struct vimvar {
VV(VV_VERSION, "version", VAR_NUMBER, VV_COMPAT + VV_RO),
VV(VV_LNUM, "lnum", VAR_NUMBER, VV_RO_SBX),
VV(VV_TERMRESPONSE, "termresponse", VAR_STRING, VV_RO),
+ VV(VV_TERMREQUEST, "termrequest", VAR_STRING, VV_RO),
VV(VV_FNAME, "fname", VAR_STRING, VV_RO),
VV(VV_LANG, "lang", VAR_STRING, VV_RO),
VV(VV_LC_TIME, "lc_time", VAR_STRING, VV_RO),
diff --git a/src/nvim/eval.h b/src/nvim/eval.h
index c46a895c06..abe2685424 100644
--- a/src/nvim/eval.h
+++ b/src/nvim/eval.h
@@ -86,6 +86,7 @@ typedef enum {
VV_THIS_SESSION,
VV_VERSION,
VV_LNUM,
+ VV_TERMREQUEST,
VV_TERMRESPONSE,
VV_FNAME,
VV_LANG,
diff --git a/src/nvim/terminal.c b/src/nvim/terminal.c
index c6a2cb3354..ee482f7104 100644
--- a/src/nvim/terminal.c
+++ b/src/nvim/terminal.c
@@ -169,6 +169,54 @@ static VTermScreenCallbacks vterm_screen_callbacks = {
static Set(ptr_t) invalidated_terminals = SET_INIT;
+static void emit_term_request(void **argv)
+{
+ char *payload = argv[0];
+ size_t payload_length = (size_t)argv[1];
+
+ String termrequest = { .data = payload, .size = payload_length };
+ Object data = STRING_OBJ(termrequest);
+ set_vim_var_string(VV_TERMREQUEST, payload, (ptrdiff_t)payload_length);
+ apply_autocmds_group(EVENT_TERMREQUEST, NULL, NULL, false, AUGROUP_ALL, curbuf, NULL, &data);
+ xfree(payload);
+}
+
+static int on_osc(int command, VTermStringFragment frag, void *user)
+{
+ if (frag.str == NULL) {
+ return 0;
+ }
+
+ StringBuilder request = KV_INITIAL_VALUE;
+ kv_printf(request, "\x1b]%d;", command);
+ kv_concat_len(request, frag.str, frag.len);
+ multiqueue_put(main_loop.events, emit_term_request, request.items, (void *)request.size);
+ return 1;
+}
+
+static int on_dcs(const char *command, size_t commandlen, VTermStringFragment frag, void *user)
+{
+ if ((command == NULL) || (frag.str == NULL)) {
+ return 0;
+ }
+
+ StringBuilder request = KV_INITIAL_VALUE;
+ kv_printf(request, "\x1bP%*s", (int)commandlen, command);
+ kv_concat_len(request, frag.str, frag.len);
+ multiqueue_put(main_loop.events, emit_term_request, request.items, (void *)request.size);
+ return 1;
+}
+
+static VTermStateFallbacks vterm_fallbacks = {
+ .control = NULL,
+ .csi = NULL,
+ .osc = on_osc,
+ .dcs = on_dcs,
+ .apc = NULL,
+ .pm = NULL,
+ .sos = NULL,
+};
+
void terminal_init(void)
{
time_watcher_init(&main_loop, &refresh_timer, NULL);
@@ -222,6 +270,7 @@ void terminal_open(Terminal **termpp, buf_T *buf, TerminalOptions opts)
vterm_screen_enable_reflow(rv->vts, true);
// delete empty lines at the end of the buffer
vterm_screen_set_callbacks(rv->vts, &vterm_screen_callbacks, rv);
+ vterm_screen_set_unrecognised_fallbacks(rv->vts, &vterm_fallbacks, rv);
vterm_screen_set_damage_merge(rv->vts, VTERM_DAMAGE_SCROLL);
vterm_screen_reset(rv->vts, 1);
vterm_output_set_callback(rv->vt, term_output_callback, rv);
diff --git a/src/nvim/vvars.lua b/src/nvim/vvars.lua
index d1b5e13401..6410df1a57 100644
--- a/src/nvim/vvars.lua
+++ b/src/nvim/vvars.lua
@@ -770,13 +770,23 @@ M.vars = {
desc = 'Value of |String| type. Read-only. See: |type()|',
},
termresponse = {
+ type = 'string',
desc = [=[
- The value of the most recent OSC or DCS escape sequence
+ The value of the most recent OSC or DCS control sequence
received by Nvim from the terminal. This can be read in a
|TermResponse| event handler after querying the terminal using
another escape sequence.
]=],
},
+ termrequest = {
+ type = 'string',
+ desc = [=[
+ The value of the most recent OSC or DCS 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.
+ ]=],
+ },
testing = {
desc = [=[
Must be set before using `test_garbagecollect_now()`.