aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/nvim/api/ui.c27
-rw-r--r--src/nvim/tui/input.c26
2 files changed, 53 insertions, 0 deletions
diff --git a/src/nvim/api/ui.c b/src/nvim/api/ui.c
index b508a3ee94..99215f7b4f 100644
--- a/src/nvim/api/ui.c
+++ b/src/nvim/api/ui.c
@@ -16,6 +16,7 @@
#include "nvim/api/ui.h"
#include "nvim/autocmd.h"
#include "nvim/channel.h"
+#include "nvim/eval.h"
#include "nvim/event/loop.h"
#include "nvim/event/wstream.h"
#include "nvim/globals.h"
@@ -524,6 +525,32 @@ void nvim_ui_pum_set_bounds(uint64_t channel_id, Float width, Float height, Floa
ui->pum_pos = true;
}
+/// Tells Nvim when a terminal event has occurred.
+///
+/// The following terminal events are supported:
+///
+/// - "osc_response": The terminal sent a OSC response sequence to Nvim. The
+/// payload is the received OSC sequence.
+///
+/// @param channel_id
+/// @param event Event name
+/// @param payload Event payload
+/// @param[out] err Error details, if any.
+void nvim_ui_term_event(uint64_t channel_id, String event, Object value, Error *err)
+ FUNC_API_SINCE(12) FUNC_API_REMOTE_ONLY
+{
+ if (strequal("osc_response", event.data)) {
+ if (value.type != kObjectTypeString) {
+ api_set_error(err, kErrorTypeValidation, "osc_response must be a string");
+ return;
+ }
+
+ const String osc_response = value.data.string;
+ set_vim_var_string(VV_TERMRESPONSE, osc_response.data, (ptrdiff_t)osc_response.size);
+ apply_autocmds_group(EVENT_TERMRESPONSE, NULL, NULL, false, AUGROUP_ALL, NULL, NULL, &value);
+ }
+}
+
static void flush_event(UIData *data)
{
if (data->cur_event) {
diff --git a/src/nvim/tui/input.c b/src/nvim/tui/input.c
index 487f8b010e..1f659264c5 100644
--- a/src/nvim/tui/input.c
+++ b/src/nvim/tui/input.c
@@ -11,6 +11,7 @@
#include "nvim/api/private/helpers.h"
#include "nvim/ascii.h"
#include "nvim/charset.h"
+#include "nvim/eval.h"
#include "nvim/event/defs.h"
#include "nvim/log.h"
#include "nvim/macros.h"
@@ -479,6 +480,8 @@ static void tk_getkeys(TermInput *input, bool force)
}
}
}
+ } else if (key.type == TERMKEY_TYPE_OSC) {
+ handle_osc_event(input, &key);
}
}
@@ -684,6 +687,29 @@ HandleState handle_background_color(TermInput *input)
return kComplete;
}
+static void handle_osc_event(TermInput *input, const TermKeyKey *key)
+{
+ assert(input);
+
+ const char *str = NULL;
+ if (termkey_interpret_string(input->tk, key, &str) == TERMKEY_RES_KEY) {
+ assert(str != NULL);
+
+ // Send an event to nvim core. This will update the v:termresponse variable and fire the
+ // TermResponse event
+ MAXSIZE_TEMP_ARRAY(args, 2);
+ ADD_C(args, STATIC_CSTR_AS_OBJ("osc_response"));
+
+ // libtermkey strips the OSC bytes from the response. We add it back in so that downstream
+ // consumers of v:termresponse can differentiate between OSC and CSI events.
+ StringBuilder response = KV_INITIAL_VALUE;
+ kv_printf(response, "\x1b]%s", str);
+ ADD_C(args, STRING_OBJ(cbuf_as_string(response.items, response.size)));
+ rpc_send_event(ui_client_channel_id, "nvim_ui_term_event", args);
+ kv_destroy(response);
+ }
+}
+
static void handle_raw_buffer(TermInput *input, bool force)
{
HandleState is_paste = kNotApplicable;