feat(tui): support APC queries in TermResponse (#34426)

Add support for APC sequences to libtermkey and the TermResponse
autocommand event.
This commit is contained in:
Gregory Anders
2025-06-11 08:26:58 -05:00
committed by GitHub
parent 966b1da183
commit de87ceb3be
8 changed files with 36 additions and 9 deletions

View File

@ -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|.
///

View File

@ -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;

View File

@ -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

View File

@ -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;

View File

@ -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,