diff --git a/runtime/doc/api.txt b/runtime/doc/api.txt index afdae1e19a..92c774de2c 100644 --- a/runtime/doc/api.txt +++ b/runtime/doc/api.txt @@ -4028,8 +4028,8 @@ nvim_ui_term_event({event}, {value}) *nvim_ui_term_event()* Tells Nvim when a terminal event has occurred The following terminal events are supported: - • "termresponse": The terminal sent an OSC or DCS response sequence to - Nvim. The payload is the received response. Sets |v:termresponse| and + • "termresponse": The terminal sent an OSC, DCS, or APC response sequence + to Nvim. The payload is the received response. Sets |v:termresponse| and fires |TermResponse|. Attributes: ~ diff --git a/runtime/doc/autocmd.txt b/runtime/doc/autocmd.txt index 2857dedd27..fe57d9ab1c 100644 --- a/runtime/doc/autocmd.txt +++ b/runtime/doc/autocmd.txt @@ -1045,7 +1045,7 @@ TermRequest When a |:terminal| child process emits an OSC, autocommand defined without |autocmd-nested|. *TermResponse* -TermResponse When Nvim receives an OSC or DCS response from +TermResponse When Nvim receives an OSC, DCS, or APC response from the host terminal. Sets |v:termresponse|. The |event-data| is a table with the following fields: diff --git a/runtime/doc/news.txt b/runtime/doc/news.txt index 331a577bcd..c5fbe4bf8a 100644 --- a/runtime/doc/news.txt +++ b/runtime/doc/news.txt @@ -221,7 +221,7 @@ TREESITTER TUI -• todo +• |TermResponse| now supports APC query responses. UI diff --git a/src/nvim/api/ui.c b/src/nvim/api/ui.c index 0e12951575..fa0e23d412 100644 --- a/src/nvim/api/ui.c +++ b/src/nvim/api/ui.c @@ -540,7 +540,7 @@ void nvim_ui_pum_set_bounds(uint64_t channel_id, Float width, Float height, Floa /// /// The following terminal events are supported: /// -/// - "termresponse": The terminal sent an OSC or DCS response sequence to +/// - "termresponse": The terminal sent an OSC, DCS, or APC response sequence to /// Nvim. The payload is the received response. Sets /// |v:termresponse| and fires |TermResponse|. /// diff --git a/src/nvim/tui/input.c b/src/nvim/tui/input.c index e3c7fc6f30..fa5da14f50 100644 --- a/src/nvim/tui/input.c +++ b/src/nvim/tui/input.c @@ -463,7 +463,8 @@ static void tk_getkeys(TermInput *input, bool force) handle_modereport(input, &key); } else if (key.type == TERMKEY_TYPE_UNKNOWN_CSI) { handle_unknown_csi(input, &key); - } else if (key.type == TERMKEY_TYPE_OSC || key.type == TERMKEY_TYPE_DCS) { + } else if (key.type == TERMKEY_TYPE_OSC || key.type == TERMKEY_TYPE_DCS + || key.type == TERMKEY_TYPE_APC) { handle_term_response(input, &key); } } @@ -600,6 +601,9 @@ static void handle_term_response(TermInput *input, const TermKeyKey *key) case TERMKEY_TYPE_DCS: kv_printf(response, "\x1bP%s", str); break; + case TERMKEY_TYPE_APC: + kv_printf(response, "\x1b_%s", str); + break; default: // Key type already checked for OSC/DCS in termkey_interpret_string UNREACHABLE; diff --git a/src/nvim/tui/termkey/driver-csi.c b/src/nvim/tui/termkey/driver-csi.c index f8e503a9d2..89237005b5 100644 --- a/src/nvim/tui/termkey/driver-csi.c +++ b/src/nvim/tui/termkey/driver-csi.c @@ -890,8 +890,22 @@ static TermKeyResult peekkey_ctrlstring(TermKey *tk, TermKeyCsi *csi, size_t int strncpy(csi->saved_string, (char *)tk->buffer + tk->buffstart + introlen, len); // NOLINT(runtime/printf) csi->saved_string[len] = 0; - key->type = (CHARAT(introlen - 1) & 0x1f) == 0x10 - ? TERMKEY_TYPE_DCS : TERMKEY_TYPE_OSC; + char type = CHARAT(introlen - 1) & 0x1f; + switch (type) { + case 0x10: + key->type = TERMKEY_TYPE_DCS; + break; + case 0x1d: + key->type = TERMKEY_TYPE_OSC; + break; + case 0x1f: + key->type = TERMKEY_TYPE_APC; + break; + default: + // Unreachable + abort(); + } + key->code.number = csi->saved_string_id; key->modifiers = 0; @@ -918,6 +932,7 @@ TermKeyResult peekkey_csi(TermKey *tk, void *info, TermKeyKey *key, int force, s case 0x50: // ESC-prefixed DCS case 0x5d: // ESC-prefixed OSC + case 0x5f: // ESC-prefixed APC return peekkey_ctrlstring(tk, csi, 2, key, force, nbytep); case 0x5b: // ESC-prefixed CSI diff --git a/src/nvim/tui/termkey/termkey.c b/src/nvim/tui/termkey/termkey.c index 1f7e498cbf..0bef225033 100644 --- a/src/nvim/tui/termkey/termkey.c +++ b/src/nvim/tui/termkey/termkey.c @@ -182,6 +182,9 @@ static void print_key(TermKey *tk, TermKeyKey *key) case TERMKEY_TYPE_OSC: fprintf(stderr, "Operating System Control"); break; + case TERMKEY_TYPE_APC: + fprintf(stderr, "Application Program Command"); + break; case TERMKEY_TYPE_UNKNOWN_CSI: fprintf(stderr, "unknown CSI\n"); break; @@ -231,7 +234,8 @@ TermKeyResult termkey_interpret_string(TermKey *tk, const TermKeyKey *key, const } if (key->type != TERMKEY_TYPE_DCS - && key->type != TERMKEY_TYPE_OSC) { + && key->type != TERMKEY_TYPE_OSC + && key->type != TERMKEY_TYPE_APC) { return TERMKEY_RES_NONE; } @@ -1270,6 +1274,9 @@ size_t termkey_strfkey(TermKey *tk, char *buffer, size_t len, TermKeyKey *key, T case TERMKEY_TYPE_OSC: l = (size_t)snprintf(buffer + pos, len - pos, "OSC"); break; + case TERMKEY_TYPE_APC: + l = (size_t)snprintf(buffer + pos, len - pos, "APC"); + break; case TERMKEY_TYPE_UNKNOWN_CSI: l = (size_t)snprintf(buffer + pos, len - pos, "CSI %c", key->code.number & 0xff); break; diff --git a/src/nvim/tui/termkey/termkey_defs.h b/src/nvim/tui/termkey/termkey_defs.h index 65c713a22b..a0b3e13439 100644 --- a/src/nvim/tui/termkey/termkey_defs.h +++ b/src/nvim/tui/termkey/termkey_defs.h @@ -111,6 +111,7 @@ typedef enum { TERMKEY_TYPE_MODEREPORT, TERMKEY_TYPE_DCS, TERMKEY_TYPE_OSC, + TERMKEY_TYPE_APC, // add other recognised types here TERMKEY_TYPE_UNKNOWN_CSI = -1,