diff --git a/lib/util.c b/lib/util.c index fdd758cf8c..ecc219ed8e 100644 --- a/lib/util.c +++ b/lib/util.c @@ -736,7 +736,10 @@ skip_numbers (const char *s) * "control sequence", in a sort of pidgin BNF, as follows: * * control-seq = Esc non-'[' - * | Esc '[' (0 or more digits or ';' or ':' or '?') (any other char) + * | Esc '[' (parameter-byte)* (intermediate-byte)* final-byte + * parameter-byte = [\x30-\x3F] # one of "0-9;:<=>?" + * intermediate-byte = [\x20–\x2F] # one of " !\"#$%&'()*+,-./" + * final-byte = [\x40-\x7e] # one of "@A–Z[\]^_`a–z{|}~" * * The 256-color and true-color escape sequences should allow either ';' or ':' inside as separator, * actually, ':' is the more correct according to ECMA-48. @@ -763,8 +766,10 @@ strip_ctrl_codes (char *s) if (*(++r) == '[' || *r == '(') { /* strchr() matches trailing binary 0 */ - while (*(++r) != '\0' && strchr ("0123456789;:?", *r) != NULL) + while (*(++r) != '\0' && strchr ("0123456789;:<=>?", *r) != NULL) ; + while (*r != '\0' && (*r < 0x40 || *r > 0x7E)) + ++r; } else if (*r == ']') { diff --git a/src/subshell/common.c b/src/subshell/common.c index c196865c00..64e911232c 100644 --- a/src/subshell/common.c +++ b/src/subshell/common.c @@ -180,6 +180,9 @@ 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"; +static const size_t subshell_switch_key_csi_u_len = sizeof(subshell_switch_key_csi_u) - 1; /* *INDENT-ON* */ /* For reading/writing on the subshell's pty */ @@ -427,10 +430,14 @@ init_subshell_child (const char *pty_name) execl (mc_global.shell->path, mc_global.shell->path, "-Z", "-g", (char *) NULL); break; + case SHELL_FISH: + execl (mc_global.shell->path, mc_global.shell->path, + "--init-command", "set --global __mc_csi_u 1", (char *) NULL); + break; + case SHELL_ASH_BUSYBOX: case SHELL_DASH: case SHELL_TCSH: - case SHELL_FISH: execl (mc_global.shell->path, mc_global.shell->path, (char *) NULL); break; @@ -864,7 +871,10 @@ 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 || + (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);