diff options
Diffstat (limited to 'src')
-rw-r--r-- | src/nvim/auevents.lua | 2 | ||||
-rw-r--r-- | src/nvim/eval.c | 1 | ||||
-rw-r--r-- | src/nvim/eval.h | 1 | ||||
-rw-r--r-- | src/nvim/terminal.c | 49 | ||||
-rw-r--r-- | src/nvim/vvars.lua | 12 |
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()`. |