Charlie Wang

Open new WSL tab in Windows Terminal in current directory

Microsoft has helpful instructions for how to make new tabs open in the current directory of the current tab. Basically, you have to emit a special escape sequence every time you change directory so that Windows Terminal can keep track and use that to open new tabs in the desired directory. This works even across multiple tabs.

There are two things missing from these instructions. The first is that this doesn't work with the "New tab" action, which is bound to Ctrl+Shift+T. To replicate the behaviour of other terminal programs, you need to bind Ctrl+Shift+T to "Duplicate tab" as mentioned in the article.

The other issue is that the PROMPT_COMMAND they give you doesn't work if your PROMPT_COMMAND already ends with a semicolon, which is the case if you follow the installation instructions for pyenv-virtualenv.

Microsoft gives us:

PROMPT_COMMAND=${PROMPT_COMMAND:+"$PROMPT_COMMAND ; "}'printf "\e]9;9;%s\e\\" "$(wslpath -w "$PWD")"'

Let's break that down.

  1. PROMPT_COMMAND=${PROMPT_COMMAND:+"$PROMPT_COMMAND ; "} is fancy parameter expansion that evaluates to nothing if PROMPT_COMMAND is unset, otherwise it expands to the second part. This prevents it from prepending a semicolon if PROMPT_COMMAND doesn't exist, because a semicolon that follows nothing is a syntax error in bash.

  2. printf "\e]9;9;%s\e\\" "$(wslpath -w "$PWD")" prints out the fancy escape sequence and the current directory in a format Windows Terminal understands. This is the part that's doing the work. You can run this manually and duplicate the current tab to see Windows Terminal pick up your current directory.

Although they've taken care to not insert a semicolon when you don't have an existing PROMPT_COMMAND, this doesn't work if there's already a semicolon at the end of your PROMPT_COMMAND. The installation instructions for pyenv-virtualenv tell you to add eval "$(pyenv virtualenv-init -)" into your .bashrc. Eventually that executes

if ! [[ "${PROMPT_COMMAND-}" =~ _pyenv_virtualenv_hook ]]; then
  PROMPT_COMMAND="_pyenv_virtualenv_hook;${PROMPT_COMMAND-}"
fi

If there is no PROMPT_COMMAND already, then it will be set to _pyenv_virtualenv_hook; with a trailing semicolon.

Then, if you use the snippet from Microsoft and put it after pyenv-virtualenv's snippet, it will expand it into

_pyenv_virtualenv_hook; ; printf "\e]9;9;%s\e\\" "$(wslpath -w "$PWD")"

The empty semicolon is a syntax error:

-bash: PROMPT_COMMAND: line 1: syntax error near unexpected token `;'

which you can also see by trying to run just a semicolon as a command.

The quickest way to fix this, if you are already getting this error, is to remove the parameter expansion in order to remove the extra semicolon:

PROMPT_COMMAND=${PROMPT_COMMAND}'printf "\e]9;9;%s\e\\" "$(wslpath -w "$PWD")"'

If you change your PROMPT_COMMAND again this could break, because it assumes it ends with a semicolon, but the underlying concept was never robust to begin with, so that's a problem you can deal with if it ever happens again, several years later.

More posts