[mc-devel] [PATCH 2/2] Recognize CSI u encoding for ctrl-o

Johannes Altmanninger aclopte at gmail.com
Wed Oct 9 08:08:10 UTC 2024


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.

Also export an environment variable so fish knows that enabling this
keyboard protocol no longer breaks mc. Maybe there is a better way,
like checking the mc version?

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.
---
 src/subshell/common.c | 8 +++++++-
 1 file changed, 7 insertions(+), 1 deletion(-)

diff --git a/src/subshell/common.c b/src/subshell/common.c
index 72f001569..16435d26f 100644
--- a/src/subshell/common.c
+++ b/src/subshell/common.c
@@ -180,6 +180,7 @@ static int subshell_pty_slave = -1;
 /* The key for switching back to MC from the subshell */
 /* *INDENT-OFF* */
 static const char subshell_switch_key = XCTRL ('o') & 255;
+static const char subshell_switch_key_csi_u[] = "\x1b[111;5u";
 /* *INDENT-ON* */
 
 /* For reading/writing on the subshell's pty */
@@ -315,6 +316,7 @@ init_subshell_child (const char *pty_name)
         g_snprintf (sid_str, sizeof (sid_str), "MC_SID=%ld", (long) mc_sid);
         putenv (g_strdup (sid_str));
     }
+    putenv ((char *)"MC_CSI_U=1");
 
     switch (mc_global.shell->type)
     {
@@ -864,7 +866,11 @@ feed_subshell (int how, gboolean fail_on_error)
             }
 
             for (i = 0; i < bytes; ++i)
-                if (pty_buffer[i] == subshell_switch_key)
+                if (pty_buffer[i] == subshell_switch_key ||
+                    (strlen(subshell_switch_key_csi_u) <= (size_t)bytes - i &&
+                     !memcmp(
+                         &pty_buffer[i], subshell_switch_key_csi_u,
+                         strlen(subshell_switch_key_csi_u))))
                 {
                     write_all (mc_global.tty.subshell_pty, pty_buffer, i);
 
-- 
2.47.0.rc0



More information about the mc-devel mailing list