チュートリアル: Windows ターミナルで同じディレクトリ内のタブまたはペインを開く

通常、"新しいタブ" と "ペインを分割" アクションでは、そのプロファイルの startingDirectory が何であれ、常に新しいタブまたはペインが開かれます。 ただし、他のプラットフォームでは、新しいタブの開始ディレクトリとして、新しいタブで現在のタブの作業ディレクトリを自動的に使用することが一般的です。これにより、ユーザーは 1 つのディレクトリですばやくマルチタスクを実行できます。

残念ながら、Windows では、あるプロセスの現在の作業ディレクトリ ("CWD") が何であるかを判断するのが難しい場合があります。 仮に調べることができたとしても、実際にすべてのアプリケーションがナビゲートしながら CWD を設定するわけではありません。 特に、Windows PowerShell では、ファイル システムで cd を実行しても CWD は変更されません。 PowerShell の CWD を自動的に複製することは、ほとんどの場合、間違った結果になります。

さいわいなことに、回避策があります。 アプリケーションは、特別なエスケープ シーケンスを発行して、CWD が何であるかをターミナルに手動で伝えることができます。

このチュートリアルでは、以下の内容を学習します。

  • 現在の作業ディレクトリをターミナルに伝えるようにシェルを構成する
  • duplicateTab アクションを使用して、同じ CWD でタブを開く
  • splitPane アクションを使用して、同じ CWD でペインを開く
  • タブ コンテキスト メニューを使用して、同じ CWD でタブまたはペインを開く

シェルを構成する

CWD が何であるかをターミナルに伝えるには、OS をナビゲートするときにエスケープ シーケンスを発行するようにシェルを変更する必要があります。 さいわいなことに、ほとんどのシェルには、すべてのコマンドの後に実行される "プロンプト" を構成するためのメカニズムがあります。 これは、そのような出力を追加するための最適な場所です。

Windows

コマンド プロンプト: cmd.exe

cmd は、環境変数 %PROMPT% を使用してプロンプトを構成します。 次のコマンドで、CWD を設定するコマンドをプロンプトの前に簡単に記述できます。

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

これにより、現在のプロンプトに $e]9;9;$P$e\ が追加されます。 cmd がこのプロンプトを評価するときに、次のように置き換わります。

  • $e はエスケープ文字に
  • $p は現在の作業ディレクトリに

上記のコマンドは、現在の cmd.exe セッションに対してのみ機能することに注意してください。 値を永続的に設定するには、上記のコマンドを実行した後に、次を実行します。

setx PROMPT "%PROMPT%"

PowerShell: powershell.exe または pwsh.exe

PowerShell プロンプトを以前に変更したことがない場合は、最初に about_Prompts を確認する必要があります。

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 と posh-git

posh-git を使用している場合、プロンプトは既に変更された状態になります。 その場合は、既に変更されているプロンプトに必要な出力を追加するのみです。 次の例は、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 と Starship

Starship を使用している場合、プロンプトは既に変更された状態になります。 その場合は、既に変更されているプロンプトに必要な出力を追加するのみです。

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

Linux 用 Windows サブシステム ディストリビューションには、コマンドライン シェルとして主に BASH が使われます。

bash

次の行を .bash_profile 構成ファイルの末尾に追加します。

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

bash の PROMPT_COMMAND 変数は、プロンプトを表示する前に実行するコマンドを bash に指示します。 printf ステートメントは、作業ディレクトリをターミナルに設定するシーケンスを追加するために使用しているものです。 $(wslpath -w "$PWD") ビットは、wslpath 実行可能ファイルを呼び出して、現在のディレクトリをその Windows のようなパスに変換します。 ${PROMPT_COMMAND:+"$PROMPT_COMMAND; "} ビットは何らかの bash マジックで、このコマンドが既存のコマンドに確実に追加されるようにします (他の場所で既に PROMPT_COMMAND を設定している場合)。

zsh

次の行を .zshrc ファイルの末尾に追加します。

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

precmd_functions フックは、プロンプトを表示する前に実行するコマンドを zsh に指示します。 printf ステートメントは、作業ディレクトリをターミナルに設定するシーケンスを追加するために使用しているものです。 $(wslpath -w "$PWD") ビットは、wslpath 実行可能ファイルを呼び出して、現在のディレクトリをその Windows のようなパスに変換します。 precmd_functions+= を使用して、このフックに対して既に定義されている既存の関数に keep_current_path 関数が確実に追加されるようにします。

Fish

Fish シェルを使用している場合は、次の行を ~/.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

この関数は、現在のパスが変更されるたびに呼び出され、現在のセッションが Windows ターミナルで開かれ、現在のパスの Windows と同等のパス (wslpath -w) を使用してオペレーティング システム コマンド (OSC 9;9;) を送信していることを確認します。

MINGW

MINGW、Git Bash、Cygwin の場合、WSL 用に PROMPT_COMMAND を変更する必要があります。wslpathcygpath で置き換えます。

次の行を .bashrc ファイルの末尾に追加します。

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

Note

お気に入りのシェルがここに表示されていない場合 解決方法が判明した場合は、PR を開き、お気に入りのシェルでの解決策をご自由にお寄せください。

アクションを使用してパスを複製する

現在のディレクトリが何であるかをターミナルに伝えるようにシェルを構成したら、そのパスで新しいタブまたはペインを開くのは簡単です。

duplicateTab で新しいタブを開く

現在アクティブなターミナルと同じパス (およびプロファイル) で新しいタブを開くには、[タブを複製] アクションを使用します。 これは、次のように既定では Ctrl+Shift+D にバインドされています。

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

詳細については、duplicateTab を参照してください。

splitPane で新しいペインを開く

現在アクティブなターミナルと同じパス (およびプロファイル) で新しいペインを開くには、[ペインを複製] アクションを使用します。 これは既定では、バインドされていません。 このアクションの最も単純な形式は次のとおりです。

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

詳細については、splitPane を参照してください。

メニューを使用してパスを複製する

上記のアクションは、タブ コンテキスト メニューの [タブを複製] と [Split Pane](ペインを分割) のエントリでも使用できます。

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