教程:在 Windows 终端的同一目录中打开选项卡或窗格
通常,无论 startingDirectory
对该配置文件来说内容如何,“新建选项卡”和“拆分窗格”操作总是会打开新的选项卡/窗格。 但是在其他平台上,新选项卡通常会自动使用当前选项卡的工作目录作为新选项卡的起始目录。这样,用户就可在单个目录中快速进行多项操作。
遗憾的是,在 Windows 上,很难确定进程的当前工作目录 (CWD) 是什么。 即使我们能查找它,也并非所有应用程序都在导航时实际设置其 CWD。 特别要注意的是,Windows PowerShell 不会像你围绕文件系统进行 cd
操作一样更改其 CWD! 自动复制 PowerShell 的 CWD 几乎总是错误的。
幸运的是,有一种解决方法。 应用程序可以发出特殊的转义序列(特别是“OSC 9;9 英寸格式)手动告知终端 CWD 应是什么。
本教程介绍如何执行下列操作:
- 配置 shell,告诉终端它是当前工作目录
- 使用
duplicateTab
操作打开具有相同 CWD 的选项卡 - 使用
splitPane
操作打开具有相同 CWD 的窗格 - 使用选项卡上下文菜单打开具有相同 CWD 的选项卡或窗格
配置 shell
若要告诉终端什么是 CWD,需要修改 shell,以便在浏览操作系统时发出转义序列。 幸运的是,大多数 shell 都有一种用于配置“提示符”的机制,该机制在每个命令之后运行。 这是添加此类输出的理想位置。
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 作为命令行 shell。
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 magic,用于确保我们将此命令追加到任何现有命令(如果你已在其他位置设置 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 shell,则将以下行添加到位于 ~/.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`"'
注意
没有在这里看到你喜欢的 shell? 如果你已清楚,可随意打开 PR,为你喜欢的 shell 提供一个解决方案!
使用操作复制路径
配置 shell 来告知终端哪一个是当前目录后,就能轻松打开使用此路径的新选项卡或窗格。
使用 duplicateTab
打开新选项卡
若要打开路径(和配置文件)与当前活跃终端相同的新选项卡,请使用“复制选项卡”操作。 默认情况下,快捷方式为 Ctrl+Shift+D,如下所示:
{ "command": "duplicateTab", "keys": "ctrl+shift+d" },
有关更多详细信息,请参阅 duplicateTab
。
使用 splitPane
打开新窗格
若要打开路径(和配置文件)与当前活跃终端相同的新窗格,请使用“复制窗格”操作。 默认情况下,不限制此操作。 此操作最简单的形式是:
{ "command": { "action": "splitPane", "splitMode": "duplicate" } },
有关更多详细信息,请参阅 splitPane
。
使用菜单复制路径
也可在选项卡上下文菜单上的“复制选项卡”和“拆分窗格”条目下执行上述操作。