现已发布!阅读有关 11 月份新功能和修复的信息。

终端 Shell 集成

Visual Studio Code 具有与常见 shell 集成的能力,允许终端了解更多关于 shell 内部实际发生的事情。此附加信息启用了一些有用的功能,如工作目录检测和命令检测、装饰导航

支持的 shell

  • Linux/macOS:bash、fish、pwsh、zsh
  • Windows:pwsh

安装

自动脚本注入

默认情况下,shell 集成脚本应在从 VS Code 启动的受支持 shell 上自动激活。这是通过在 shell 会话启动时注入参数和/或环境变量来实现的。可以通过将terminal.integrated.shellIntegration.enabled设置为 false来禁用此自动注入。

这种标准的、简单的方式不适用于一些高级用例,如子 shell、通过常规 ssh 会话(当不使用Remote - SSH 扩展时)或对于一些复杂的 shell 设置。对于这些情况,启用 shell 集成的推荐方法是手动安装

注意:自动注入可能在旧版本的 shell 上不起作用,例如,旧版本的 fish 不支持 $XDG_DATA_DIRS 环境变量,这是注入的工作方式。您可能仍然可以通过手动安装使其正常工作。

手动安装

要手动安装 shell 集成,需要在 shell 的初始化期间运行 VS Code shell 集成脚本。具体在何处以及如何执行此操作取决于您正在使用的 shell 和操作系统。使用手动安装时,建议将terminal.integrated.shellIntegration.enabled设置为 false,但不是强制性的。

提示: 使用Insiders 构建时,请将下面的 code 替换为 code-insiders

bash

将以下内容添加到您的 ~/.bashrc 文件中。在 bash 中运行 code ~/.bashrc 以在 VS Code 中打开该文件。

[[ "$TERM_PROGRAM" == "vscode" ]] && . "$(code --locate-shell-integration-path bash)"

fish

将以下内容添加到您的 config.fish 中。在 fish 中运行 code $__fish_config_dir/config.fish 以在 VS Code 中打开该文件。

string match -q "$TERM_PROGRAM" "vscode"
and . (code --locate-shell-integration-path fish)

pwsh

将以下内容添加到您的PowerShell 配置文件中。在 pwsh 中运行 code $Profile 以在 VS Code 中打开该文件。

if ($env:TERM_PROGRAM -eq "vscode") { . "$(code --locate-shell-integration-path pwsh)" }

zsh

将以下内容添加到您的 ~/.zshrc 文件中。在 bash 中运行 code ~/.zshrc 以在 VS Code 中打开该文件。

[[ "$TERM_PROGRAM" == "vscode" ]] && . "$(code --locate-shell-integration-path zsh)"

Git Bash

将以下内容添加到您的 ~/.bashrc 文件中。在 Git Bash 中运行 code ~/.bashrc 以在 VS Code 中打开该文件。

[[ "$TERM_PROGRAM" == "vscode" ]] && . "$(code --locate-shell-integration-path bash)"

可移植性与性能

如果 code$PATH 中,则上述 shell 集成安装是跨平台的,并且与任何安装类型兼容。但是,这种推荐的方法会启动 Node.js 来获取脚本路径,从而导致 shell 启动时出现轻微延迟。为了缓解此延迟,请通过提前解析路径并将其直接添加到初始化脚本中来内联上面的脚本。

# Output the executable's path first:
code --locate-shell-integration-path bash

# Add the result of the above to the source statement:
[[ "$TERM_PROGRAM" == "vscode" ]] && . "/path/to/shell/integration/script.sh"

命令装饰和概览标尺

shell 集成启用的一项功能是获取在终端中运行的命令的退出代码的能力。使用此信息,会在行的左侧添加装饰,以指示命令是否成功或失败。这些装饰也会像在编辑器中一样,显示在滚动条中相对较新的概览标尺中。

Blue circles appear next to successful commands, red circles with crosses appear next to failed commands. The color of the circles appears in the scroll bar

可以与装饰进行交互,以提供一些上下文操作,例如重新运行命令

Clicking a successful command decoration shows a context menu containing items: Copy Output, Copy Output as HTML, Rerun Command and How does this work?

可以使用terminal.integrated.shellIntegration.decorationsEnabled设置来配置命令和概览标尺装饰。

命令导航

shell 集成检测到的命令会馈送到命令导航功能(Ctrl/Cmd+向上Ctrl/Cmd+向下),以便为其提供更可靠的命令位置。此功能允许在命令之间快速导航和选择其输出。要从当前位置选择到命令,您还可以按住 Shift,按 Shift+Ctrl/Cmd+向上Shift+Ctrl/Cmd+向下

命令指南

命令指南是一个条,当鼠标悬停在其上时会显示在命令及其输出旁边。这有助于更快地识别命令,并且也是验证 shell 集成是否正常工作的一种方式。

Screenshot of the terminal, highlighting the command guide vertical bar on the left-hand side to indicate the boundary of a command.

您可以使用颜色主题自定义命令指南的颜色。要切换命令指南,请配置terminal.integrated.shellIntegration.showCommandGuide设置。

粘性滚动

粘性滚动功能会将部分显示在终端顶部的命令“粘住”,从而更容易查看该输出所属的命令。单击粘性滚动组件会将滚动条滚动到终端缓冲区中命令的位置。

Sticky scroll will show the command at the top of the terminal viewport

可以使用terminal.integrated.stickyScroll.enabled设置启用此功能。

快速修复

VS Code 会扫描命令的输出,并显示一个快速修复,其中包含用户接下来可能想要执行的操作。

Running 'git push --set-upstream' will present a lightbulb that opens a dropdown with an option to open a new PR on github.com

以下是一些内置的快速修复

  • 当检测到端口已被侦听时,建议杀死该进程并重新运行上一个命令。
  • 当由于未设置上游而导致 git push 失败时,建议使用设置的上游进行推送。
  • git 子命令因类似的命令错误而失败时,建议使用类似的命令。
  • git push 导致创建 GitHub PR 的建议时,建议打开该链接。
  • Generalcmd-not-found PowerShell 反馈提供程序触发时,建议每个建议。

当快速修复可用时,快速修复功能还支持辅助功能信号以获得额外的反馈。

运行最近的命令

终端:运行最近的命令命令在快速选择中显示来自各种来源的历史记录,提供类似于 shell 反向搜索(Ctrl+R)的功能。这些来源是当前会话的历史记录、此 shell 类型的先前会话历史记录和常见的 shell 历史记录文件。

The "run recent command" command shows a quick pick with previously run commands that can be filtered similar to the go to file command

该命令的其他一些功能

  • 默认情况下,搜索模式为“连续搜索”,这意味着搜索词必须完全匹配。搜索输入框右侧的按钮允许切换到模糊搜索。
  • 在当前会话部分,快速选择右侧有一个剪贴板图标,点击它将在编辑器中打开命令输出。
  • 快速选择右侧的固定操作可以将命令固定到列表顶部。
  • 按住 Alt 键可以将文本写入终端而不执行它。
  • 存储在上一会话部分的历史记录数量由 terminal.integrated.shellIntegration.history 设置决定。

此命令的默认快捷键是 Ctrl+Alt+R。但是,当开启辅助功能模式时,这些快捷键会反转;Ctrl+R 运行最近的命令,而 Ctrl+Alt+R 将 Ctrl+R 发送到 shell。

当关闭辅助功能模式时,可以使用以下快捷键翻转快捷键

{
    "key": "ctrl+r",
    "command": "workbench.action.terminal.runRecentCommand",
    "when": "terminalFocus"
},
{
  "key": "ctrl+alt+r",
  "command": "workbench.action.terminal.sendSequence",
  "args": { "text": "\u0012"/*^R*/ },
  "when": "terminalFocus"
}

转到最近的目录

与运行最近的命令功能类似,**终端:转到最近的目录** 命令会跟踪已访问的目录,并允许快速过滤和导航 (cd) 到这些目录。按住 Alt 键可以将文本写入终端而不执行它。

此命令的默认快捷键是 ⌘G (Windows, Linux Ctrl+G),因为它与编辑器中的 **转到行/列** 命令类似。可以使用 Ctrl+Alt+G 将 Ctrl+G 发送到 shell。

当前工作目录检测

Shell 集成会告诉 VS Code shell 的当前工作目录。如果没有通过正则表达式尝试检测提示符,则在 Windows 上无法获取此信息,并且在 macOS 和 Linux 上需要轮询,这不利于性能。

它实现的最大功能之一是增强了终端中链接的解析。例如,以链接 package.json 为例,当禁用 shell 集成时激活该链接时,如果工作区中有多个 package.json 文件,则会打开一个以 package.json 为过滤器的搜索快速选择。但是,当启用 shell 集成时,它将直接在当前文件夹中打开 package.json 文件,因为已知当前位置。这允许 ls 的输出可靠地打开正确的文件。

当前工作目录也用于在终端选项卡、运行最近的命令快速选择中以及 "terminal.integrated.splitCwd": "inherited" 功能中显示目录。

扩展的 PowerShell 键绑定

Windows 的控制台 API 允许比 Linux/macOS 终端更多的快捷键,由于 VS Code 的终端即使在 Windows 上也模拟后者,因此由于缺少 VT 编码,某些 PowerShell 快捷键无法使用标准方法实现,例如 Ctrl+Space。Shell 集成允许 VS Code 附加自定义快捷键以向 PowerShell 发送特殊序列,然后该序列在 shell 集成脚本中处理并转发到正确的按键处理程序。

启用 shell 集成后,以下快捷键应在 PowerShell 中工作

  • Ctrl+Space:仅在 Windows 上默认为 MenuComplete
  • Alt+Space:在所有平台上默认为 SetMark
  • Shift+Enter:在所有平台上默认为 AddLine
  • Shift+End:在所有平台上默认为 SelectLine
  • Shift+Home:在所有平台上默认为 SelectBackwardsLine

PowerShell 的实验性 IntelliSense

PowerShell 的实验性 IntelliSense 在 PowerShell 中键入时会显示一个完成列表,类似于编辑器的体验。在后台,此功能由 PowerShell 会话的本机完成 API 提供支持,因此可以使用上下文相关的完成,例如变量。

PowerShell IntelliSense shows completions like Get-Alias, Get-ChildItem, for example when typing Get-

可以使用 terminal.integrated.suggest.enabled 设置启用 PowerShell 的实验性 IntelliSense。

"terminal.integrated.suggest.enabled": true

注意:此功能目前仅在 Windows 和 macOS 上可用。

Git 和 VS Code 完成

启用实验性 IntelliSense 后,默认情况下会启用 CLI gitcodecode-insiders 的完成。如果你的 PowerShell 配置文件已经有完成项,你可能想使用 terminal.integrated.suggest.builtinCompletions 设置关闭这些完成项。

增强的辅助功能

Shell 集成为 VS Code 提供的信息用于改进终端中的辅助功能。一些增强功能的示例包括

  • 在可访问缓冲区中导航检测到的命令 (⌥F2 (Windows Alt+F2, Linux Shift+Alt+F2))
  • 当命令失败时,会播放音频提示
  • 底层文本框同步,以便使用箭头键和退格键的行为更正确。

支持的转义序列

VS Code 支持多个自定义转义序列

VS Code 自定义序列 'OSC 633 ; ... ST'

VS Code 有一组自定义转义序列,旨在在 VS Code 的终端中运行时启用 shell 集成功能。这些转义序列由内置脚本使用,但也可以由任何能够向终端发送序列的应用程序使用,例如,Julia 扩展 使用这些转义序列来支持 Julia REPL 中的 shell 集成。

其他终端应忽略这些序列,但除非其他终端最终更广泛地采用这些序列,否则建议在写入这些序列之前检查 $TERM_PROGRAM 是否为 vscode

  • OSC 633 ; A ST - 标记提示符开始。

  • OSC 633 ; B ST - 标记提示符结束。

  • OSC 633 ; C ST - 标记预执行。

  • OSC 633 ; D [; <exitcode>] ST - 标记执行完成,带有可选的退出代码。

  • OSC 633 ; E ; <commandline> [; <nonce] ST - 使用可选的 nonce 显式设置命令行。

    E 序列允许终端可靠地获取 shell 解释的准确命令行。如果未指定此项,则终端可能会退回到使用 A、B 和 C 序列来获取命令,或者如果不可靠,则完全禁用检测。

    可选的 nonce 可用于验证该序列是否来自 shell 集成脚本,以防止命令欺骗。当 nonce 验证成功时,将删除使用命令之前的一些保护措施,以改善用户体验。

    命令行可以使用 \xAB 格式转义 ASCII 字符,其中 AB 是字符代码的十六进制表示形式(不区分大小写),并使用 \\ 转义 \ 字符。需要转义分号 (0x3b) 和字符 0x20 及以下,这对于换行符和分号尤其重要。

    一些示例

    "\"  -> "\\"
    "\n" -> "\x0a"
    ";"  -> "\x3b"
    
  • OSC 633 ; P ; <Property>=<Value> ST - 在终端上设置属性,仅处理已知的属性。

    已知属性

    • Cwd - 将当前工作目录报告给终端。
    • IsWindows - 指示终端是否正在使用 Windows 后端(如 winpty 或 conpty)。这可用于启用其他启发式方法,因为 shell 集成序列的位置不能保证正确。有效值为 TrueFalse

Final Term shell 集成

VS Code 支持 Final Term 的 shell 集成序列,允许非 VS Code shell 集成脚本在 VS Code 中工作。这会导致一些降级体验,因为它不支持 OSC 633 的许多功能。以下是支持的特定序列

  • OSC 133 ; A ST - 标记提示符开始。
  • OSC 133 ; B ST - 标记提示符结束。
  • OSC 133 ; C ST - 标记预执行。
  • OSC 133 ; D [; <exitcode>] ST - 标记执行完成,带有可选的退出代码。

iTerm2 shell 集成

支持 iTerm2 开创的以下序列

  • OSC 1337 ; CurrentDir=<Cwd> S - 设置终端的当前工作目录,类似于 OSC 633 ; P ; Cwd=<Cwd> ST

  • OSC 1337 ; SetMark ST - 在触发该行的左侧添加一个标记,并在滚动条中添加一个注释

    When the sequence is written to the terminal a small grey circle will appear to the left of the command, with a matching annotation in the scroll bar

    这些标记与命令导航集成,以便通过 ⌘↑ (Windows, Linux Ctrl+Up)⌘↓ (Windows, Linux Ctrl+Down) 轻松导航到它们。

常见问题

自动注入何时不起作用?

在某些情况下,自动注入不起作用,以下是一些常见情况

  • $PROMPT_COMMAND 的格式不受支持,将其更改为指向单个函数是一种简单的解决方法。例如

    prompt() {
      printf "\033]0;%s@%s:%s\007" "${USER}" "${HOSTNAME%%.*}" "${PWD/#$HOME/\~}"
    }
    PROMPT_COMMAND=prompt
    
  • 某些 shell 插件可能会在初始化时取消设置 $VSCODE_SHELL_INTEGRATION 来显式禁用 VS Code 的 shell 集成。

为什么在禁用该功能时仍显示命令装饰?

造成这种情况的可能原因是你的系统安装了另一个终端的 shell 集成,而VS Code 可以理解。如果你不想要任何装饰,可以使用以下设置隐藏它们

"terminal.integrated.shellIntegration.decorationsEnabled": never

或者,你可以从你的 shell rc/启动脚本中删除 shell 集成脚本,但你将失去对命令感知功能(如 命令导航)的访问权限。

为什么 Windows 上的命令装饰会跳来跳去?

Windows 使用名为 ConPTY 的模拟伪终端 (pty) 后端。它的工作方式与常规 pty 略有不同,因为它需要保持与 Windows 控制台 API 的兼容性。其中一个影响是,pty 句柄的渲染方式很特殊,会导致识别终端缓冲区中命令的 shell 集成序列错位。当命令跳动时,通常是在命令运行后,VS Code 的启发式方法开始发挥作用,以改进命令装饰的位置。