教學課程:在 Windows 終端機的相同目錄中開啟索引標籤或窗格
一般而言,「新索引標籤」和「分割窗格」動作一律會在該設定檔的任何 startingDirectory
中開啟新的索引標籤/窗格。 不過,在其他平台上,新的索引標籤通常會自動使用目前索引標籤的工作目錄,作為新索引標籤的起始目錄。這讓使用者可以迅速在單一目錄中多工處理。
可惜的是,在 Windows 上很難判斷程序目前的工作目錄 (「CWD」) 是什麼。 即使我們能夠查閱,也並非所有應用程式都會在瀏覽時實際設定其 CWD。 需要注意的是,Windows PowerShell 不會在您 cd
檔案系統時變更其 CWD! 自動複製 PowerShell 的 CWD 幾乎總是會出錯。
所幸,還有一種因應措施。 應用程式可以發出特殊的逸出序列(特別是“OSC 9;9 吋格式)手動告訴終端機 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
}
搭配 posh-git 的 PowerShell
如果您使用的是 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
}
搭配 Starship 的 PowerShell
如果您使用的是 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
Windows 子系統 Linux 發行版本主要使用 BASH 作為命令列殼層。
bash
將以下這一行新增至 .bash_profile
設定檔結尾:
PROMPT_COMMAND=${PROMPT_COMMAND:+"$PROMPT_COMMAND "}'printf "\e]9;9;%s\e\\" "$(wslpath -w "$PWD")"'
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 終端機開啟 (驗證 $WT_SESSION) 並傳送作業系統命令 (OSC 9;9;),就會呼叫此函式,且目前路徑相當於 Windows 路徑 (wslpath -w
)。
MINGW
針對 MINGW、Git Bash 和 Cygwin,您必須修改 WSL 的 PROMPT_COMMAND
:將 wslpath
取代為 cygpath
。
將以下這一行新增至 .bashrc
檔案結尾:
PROMPT_COMMAND=${PROMPT_COMMAND:+"$PROMPT_COMMAND; "}'printf "\e]9;9;%s\e\\" "`cygpath -w "$PWD" -C ANSI`"'
注意
這裡找不到您最愛的殼層嗎? 如果您已經找到解答,歡迎開啟 PR,為慣用的殼層貢獻解決方案!
使用動作複製路徑
設定殼層來告知終端機目前目錄是什麼之後,開啟具有該路徑的新索引標籤或窗格就很簡單了。
使用 duplicateTab
開啟新的索引標籤
若要開啟與目前使用中的終端機具有相同路徑 (和設定檔) 的新索引標籤,請使用 [複製索引標籤] 動作。 這預設會系結至 Ctrl+Shift+D,如下所示:
{ "command": "duplicateTab", "keys": "ctrl+shift+d" },
(如需詳細資訊,請參閱 duplicateTab
)。
使用 splitPane
開啟新窗格
若要開啟與目前使用中的終端機具有相同路徑 (和設定檔) 的新窗格,請使用 [複製窗格] 動作。 根據預設,這沒有建立繫結。 此動作最簡單的形式為:
{ "command": { "action": "splitPane", "splitMode": "duplicate" } },
(如需詳細資訊,請參閱 splitPane
)。
使用功能表複製路徑
上述動作也可在索引標籤操作功能表的 [複製索引標籤] 和 [分割窗格] 項目下找到。