subshell: recognize CSI u encoding for ctrl-o

If a subshell (like fish 4.0) wishes to use "Disambiguate control keys"
from https://sw.kovidgoyal.net/kitty/keyboard-protocol/, ctrl-o sends
a multi-byte sequence.  Let's make sure we can intercept that too so
we can suspend the shell.

Note that the shell already disables "Disambiguate control keys"
while it's suspended, so no other changes should be necessary.

Unfortunately there is one bug left: when I start "SHELL=$(which
fish) mc" and type `ctrl-o`, fish does not recognize CSI u bindings
(such as `bind ctrl-2 'echo hello'`) yet.  It only works after the
second prompt.  I haven't had time to figure that out.

Signed-off-by: Yury V. Zaytsev <yury@shurup.com>
This commit is contained in:
Johannes Altmanninger 2024-10-09 08:03:26 +02:00 committed by Yury V. Zaytsev
parent 0ea77d2ec7
commit 6e4510b558
1 changed files with 7 additions and 1 deletions

View File

@ -180,6 +180,9 @@ static int subshell_pty_slave = -1;
/* The key for switching back to MC from the subshell */ /* The key for switching back to MC from the subshell */
/* *INDENT-OFF* */ /* *INDENT-OFF* */
static const char subshell_switch_key = XCTRL ('o') & 255; static const char subshell_switch_key = XCTRL ('o') & 255;
static const char subshell_switch_key_csi_u[] = "\x1b[111;5u";
static const size_t subshell_switch_key_csi_u_len = sizeof(subshell_switch_key_csi_u) - 1;
/* *INDENT-ON* */ /* *INDENT-ON* */
/* For reading/writing on the subshell's pty */ /* For reading/writing on the subshell's pty */
@ -864,7 +867,10 @@ feed_subshell (int how, gboolean fail_on_error)
} }
for (i = 0; i < bytes; ++i) for (i = 0; i < bytes; ++i)
if (pty_buffer[i] == subshell_switch_key) if (pty_buffer[i] == subshell_switch_key ||
(subshell_switch_key_csi_u_len <= (size_t) bytes - i &&
memcmp (&pty_buffer[i], subshell_switch_key_csi_u,
subshell_switch_key_csi_u_len) == 0))
{ {
write_all (mc_global.tty.subshell_pty, pty_buffer, i); write_all (mc_global.tty.subshell_pty, pty_buffer, i);