microsoft / vscode

Visual Studio Code
https://code.visualstudio.com
MIT License
164.83k stars 29.5k forks source link

Feature Request: Support shell interation for terminal inside tmux #233074

Open hehaoqian opened 3 weeks ago

hehaoqian commented 3 weeks ago

Current, shell integration does not fully work, for bash shell running inside tmux, that current working directory detection not working, because \e]633;P; \a terminal escape sequence is not recognized by tmux.

Note that terminal inside tmux, need to enable VSCode shell integration manually by (The method currently I am using):

# Inside ~/.bashrc
if [[ -n "${VSCODE_IPC_HOOK_CLI}" ]]; then
  . "$(~/.vscode-server/cli/servers/*/server/bin/remote-cli/code --locate-shell-integration-path bash)"
fi

According to https://github.com/tmux/tmux/wiki/FAQ

What is the passthrough escape sequence and how do I use it? tmux takes care not to send escape sequences to a terminal that it isn't going to understand because it can't predict how it will react. However, it can be forced to pass an escape sequence through by wrapping it in a special form of the DCS sequence with the content prefixed by tmux;. Any \033 characters in the wrapped sequence must be doubled, for example: \033Ptmux;\033\033]1337;SetProfile=NewProfileName\007\033\ Will pass this iTerm2 special escape sequence \033]1337;SetProfile=NewProfileName\007 through to the terminal without tmux discarding it.

To make it works, the current <src/vs/workbench/contrib/terminal/common/scripts/shellIntegration-bash.sh> needed to be updated to add tmux specific escape sequence.

Example change:

Before:

__vsc_update_cwd ()
{
    if [ "$__vsc_is_windows" = "1" ]; then
        __vsc_cwd="$(cygpath -m "$PWD")";
    else
        __vsc_cwd="$PWD";
    fi;
    builtin printf '\e]633;P;Cwd=%s\a' "$(__vsc_escape_value "$__vsc_cwd")"
}

After:

__vsc_printf () {
    if [ -n "$TMUX" ]; then
        builtin local format_str
        format_str="\033Ptmux;\033${1}\033\\"
        shift 1
        builtin printf "${format_str}"  "$@"
    else
        builtin printf "$@"
    fi
}

__vsc_update_cwd ()
{
    if [ "$__vsc_is_windows" = "1" ]; then
        __vsc_cwd="$(cygpath -m "$PWD")";
    else
        __vsc_cwd="$PWD";
    fi;
    __vsc_printf '\e]633;P;Cwd=%s\a' "$(__vsc_escape_value "$__vsc_cwd")"
}

I can submit a PR later, if such request to okay to accept.

Tyriar commented 3 weeks ago

If that's all we need to do to get it to mostly work, a PR would be helpful. Extra points if zsh/fish scripts also include the change to get it to work.