Tutorial: Como abrir uma guia ou um painel no mesmo diretório no Terminal do Windows

Normalmente, as ações "nova guia" e "dividir painel" sempre abrirão uma nova guia/painel em qualquer que seja o startingDirectory deste perfil. No entanto, em outras plataformas, é comum que novas guias usem automaticamente o diretório de trabalho da guia atual como o diretório inicial de uma nova guia. Isso permite que o usuário realize várias tarefas ao mesmo tempo rapidamente em um diretório.

Infelizmente, no Windows, é difícil determinar qual é o CWD (diretório de trabalho atual) de um processo. Mesmo que seja possível procurá-lo, nem todos os aplicativos realmente definem o CWD durante a navegação. Em especial, o Windows PowerShell não altera o CWD como o seu cd no sistema de arquivos. Duplicar o CWD do PowerShell automaticamente quase sempre seria errado.

Felizmente, há uma solução alternativa. Os aplicativos podem emitir uma sequência de escape especial para informar manualmente ao terminal qual deve ser o CWD.

Neste tutorial, você aprenderá como:

  • Configurar o shell para informar ao terminal o diretório de trabalho atual
  • Use a ação duplicateTab para abrir uma guia com o mesmo CWD
  • Use a ação splitPane para abrir um painel com o mesmo CWD
  • Como usar o menu de contexto de guia para abrir guias ou painéis com o mesmo CWD

Configurar seu shell

Para informar ao terminal o que é o CWD, você precisará modificar o shell para emitir uma sequência de escape enquanto navega pelo sistema operacional. Felizmente, a maioria dos shells tem um mecanismo para configurar o prompt, que é executado após cada comando. Esse é o lugar perfeito para adicionar essa saída.

Windows

Prompt de comando: cmd.exe

O cmd usa a variável de ambiente %PROMPT% para configurar o prompt. Você pode preceder o prompt com o comando com facilidade para definir o CWD com o seguinte comando:

set PROMPT=$e]9;9;$P$e\%PROMPT%

Isso acrescenta $e]9;9;$P$e\ ao prompt atual. Quando o cmd avaliar esse prompt, ele substituirá

  • o $e pelo caractere de escape
  • o $p pelo diretório de trabalho atual

Observe que o comando acima só funcionará na sessão cmd.exe atual. Para definir o valor de modo permanente, DEPOIS de executar o comando acima, execute

setx PROMPT "%PROMPT%"

PowerShell: powershell.exe ou pwsh.exe

Se você nunca alterou o prompt do PowerShell antes, confira primeiro about_Prompts.

Adicione o seguinte ao seu perfil do PowerShell:

function prompt {
  $loc = $executionContext.SessionState.Path.CurrentLocation;

  $out = ""
  if ($loc.Provider.Name -eq "FileSystem") {
    $out += "$([char]27)]9;9;`"$($loc.ProviderPath)`"$([char]27)\"
  }
  $out += "PS $loc$('>' * ($nestedPromptLevel + 1)) ";
  return $out
}

PowerShell com posh-git

Se você estiver usando posh-git, isso já modificará seu prompt. Nesse caso, você só deseja adicionar a saída necessária ao prompt já modificado. O seguinte exemplo é uma versão levemente modificada deste exemplo na documentação do ConEmu:

function prompt
{
  $loc = Get-Location

  $prompt = & $GitPromptScriptBlock

  $prompt += "$([char]27)]9;12$([char]7)"
  if ($loc.Provider.Name -eq "FileSystem")
  {
    $prompt += "$([char]27)]9;9;`"$($loc.ProviderPath)`"$([char]27)\"
  }

  $prompt
}

PowerShell com Starship

Se você estiver usando Starship, isso já modificará seu prompt. Nesse caso, você só deseja adicionar a saída necessária ao prompt já modificado.

function Invoke-Starship-PreCommand {
  $loc = $executionContext.SessionState.Path.CurrentLocation;
  $prompt = "$([char]27)]9;12$([char]7)"
  if ($loc.Provider.Name -eq "FileSystem")
  {
    $prompt += "$([char]27)]9;9;`"$($loc.ProviderPath)`"$([char]27)\"
  }
  $host.ui.Write($prompt)
}

WSL

As distribuições do Subsistema do Windows para Linux usam principalmente o BASH como o shell da linha de comando.

bash

Adicione a seguinte linha ao final do arquivo de configuração .bash_profile:

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

A variável PROMPT_COMMAND no bash informa ao bash qual comando executar antes de exibir o prompt. A instrução printf é o que estamos usando para acrescentar a sequência para definir o diretório de trabalho com o terminal. O bit $(wslpath -w "$PWD") invocará o executável wslpath para converter o diretório atual em um caminho semelhante ao Windows. O bit ${PROMPT_COMMAND:+"$PROMPT_COMMAND; "} usa um pouco de bash magic para garantir que esse comando seja acrescentado a qualquer comando existente (se você já tiver definido PROMPT_COMMAND em outro lugar).

zsh

Adicione as seguintes linhas ao final do arquivo .zshrc:

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

O gancho precmd_functions informa ao zsh quais comandos executar antes de exibir o prompt. A instrução printf é o que estamos usando para acrescentar a sequência para definir o diretório de trabalho com o terminal. O bit $(wslpath -w "$PWD") invocará o executável wslpath para converter o diretório atual em um caminho semelhante ao Windows. Usando precmd_functions+= verifique se acrescentamos a função keep_current_path a qualquer função existente já definida para esse gancho.

Fish

Se você estiver usando o shell do Fish, adicione as seguintes linhas ao final do arquivo de configuração localizado em ~/.config/fish/config.fish:

function storePathForWindowsTerminal --on-variable PWD
    if test -n "$WT_SESSION"
      printf "\e]9;9;%s\e\\" (wslpath -w "$PWD")
    end
end

Essa função será chamada sempre que o caminho atual for alterado para confirmar se a sessão atual é aberta por Terminal do Windows (verificando $WT_SESSION) e enviando o Comando do Sistema Operacional (OSC 9;9;), com o caminho equivalente do Windows (wslpath -w) do caminho atual.

MINGW

Para MINGW, Git Bash e Cygwin, você precisa modificar o PROMPT_COMMAND para WSL: substitua wslpath por cygpath.

Adicione a seguinte linha ao final do arquivo .bashrc:

PROMPT_COMMAND=${PROMPT_COMMAND:+"$PROMPT_COMMAND; "}'printf "\e]9;9;%s\e\\" "`cygpath -w "$PWD" -C ANSI`"'

Observação

Não encontrou seu shell favorito aqui? Se você descobrir, sinta-se à vontade para abrir uma PR para contribuir com uma solução para seu shell preferido.

Como usar ações para duplicar o caminho

Depois de configurar o shell para informar ao terminal qual é o diretório atual, é fácil abrir uma nova guia ou painel com esse caminho.

Abrir uma nova guia com duplicateTab

Para abrir uma nova guia com o mesmo caminho (e perfil) que o terminal ativo no momento, use a ação "Duplicar Guia". Isso é associado por padrão a Ctrl+Shift+D, da seguinte maneira:

        { "command": "duplicateTab", "keys": "ctrl+shift+d" },

Confira duplicateTab para obter mais detalhes.

Abrir um novo painel com splitPane

Para abrir um novo painel com o mesmo caminho (e perfil) que o terminal ativo no momento, use a ação "Duplicar Guia". Isso NÃO está associado por padrão. A forma mais simples de realizar essa ação é:

        { "command": { "action": "splitPane", "splitMode": "duplicate" } },

Confira splitPane para obter mais detalhes.

Como usar o menu para duplicar o caminho

as ações acima também estão disponíveis no menu de contexto da guia, nas entradas "Duplicar Guia" e "Dividir Painel".

Image duplicate-tab-same-cwdImage split-pane-same-cwd