终端高级功能
Visual Studio Code 的集成终端具有许多高级功能和设置,例如 Unicode 和表情符号支持、自定义键盘快捷方式以及自动回复。本主题详细解释了这些高级功能。如果你是 VS Code 或集成终端的新手,可能需要先回顾终端基础知识主题。
持久会话
终端支持两种不同类型的持久会话:
- 进程重连:当重新加载窗口时(例如,在安装扩展后),会重连到之前的进程并恢复其内容。
- 进程恢复:当重启 VS Code 时,终端的内容会被恢复,并且进程会使用其原始环境被重新启动。
通过将 terminal.integrated.enablePersistentSessions 设置为 false
,可以禁用这两种持久会话。恢复的回滚行数由 terminal.integrated.persistentSessionScrollback 设置控制。进程恢复可以通过 terminal.integrated.persistentSessionReviveProcess 进行独立配置。
在窗口间移动终端
终端标签页可以在 VS Code 窗口之间拖放。也可以通过命令面板以及 终端:分离会话 (Terminal: Detach Session) 和 终端:附加到会话 (Terminal: Attach to Session) 命令手动完成此操作。
配置终端可见性
打开窗口时,如果终端视图是可见的,它将使用持久会话重连到终端,或创建一个新的 shell。此行为可以通过 terminal.integrated.hideOnStartup 设置进行微调。
never
(默认值): 启动时从不隐藏终端视图。whenEmpty
: 仅在没有恢复持久会话时隐藏终端。always
: 总是隐藏终端,即使有恢复的持久会话。
terminal.integrated.hideOnLastClosed 设置也可用于覆盖在关闭最后一个终端时关闭终端视图的默认行为。
键盘快捷方式和 shell
作为一个嵌入式应用程序,集成终端应该拦截部分(但不是全部)在 VS Code 内部派发的键盘快捷方式。
可配置的 terminal.integrated.commandsToSkipShell 设置决定了哪些命令的键盘快捷方式应始终“跳过 shell”,转而由 VS Code 的键盘快捷方式系统处理。默认情况下,它包含一个硬编码的命令列表,这些命令对 VS Code 的体验至关重要,但你可以添加或删除特定的命令。
{
"terminal.integrated.commandsToSkipShell": [
// Ensure the toggle sidebar visibility keyboard shortcut skips the shell
"workbench.action.toggleSidebarVisibility",
// Send quick open's keyboard shortcut to the shell
"-workbench.action.quickOpen",
]
}
查看 terminal.integrated.commandsToSkipShell 设置的详细信息,以查看完整的默认命令列表。
提示: terminal.integrated.sendKeybindingsToShell 可以配置为覆盖 terminal.integrated.commandsToSkipShell 并将大多数键盘快捷方式分派给 shell。请注意,这会禁用诸如 Ctrl+F 打开查找等键盘快捷方式。
组合键
组合键快捷方式由两个键盘快捷方式组成,例如 Ctrl+K 后跟 Ctrl+C 将行更改为注释。组合键默认情况下总是跳过 shell,但可以通过 terminal.integrated.allowChords 禁用。
macOS 清屏
在 macOS 上,Cmd+K 是终端中清屏的常用键盘快捷方式,因此 VS Code 也遵循此规则,这意味着 Cmd+K 组合键将无法工作。可以通过删除清屏键盘快捷方式来启用 Cmd+K 组合键。
{
"key": "cmd+k",
"command": "-workbench.action.terminal.clear"
}
此外,由于键盘快捷方式优先级的工作方式,如果任何扩展贡献了 Cmd+K 键盘快捷方式,此快捷方式将被自动覆盖。要在这种情况下重新启用 Cmd+K 清屏快捷方式,你可以在用户键盘快捷方式中重新定义它,因为用户快捷方式的优先级高于扩展快捷方式。
{
"key": "cmd+k",
"command": "workbench.action.terminal.clear",
"when": "terminalFocus && terminalHasBeenCreated || terminalFocus && terminalProcessSupported"
}
助记符
在终端中,默认禁用使用助记符访问 VS Code 菜单(例如,Alt+F 打开文件菜单),因为这些按键事件通常是 shell 中的重要热键。设置 terminal.integrated.allowMnemonics 以启用助记符,但请注意,这将禁止任何 Alt 键事件传递给 shell。此设置在 macOS 上无效。
自定义序列键盘快捷方式
workbench.action.terminal.sendSequence
命令可用于向终端发送特定的文本序列,包括由 shell 特殊解释的转义序列。该命令使你能够发送方向键、Enter、光标移动等。通过命令面板运行此命令允许手动输入,但当您分配带有参数的自定义键盘快捷方式时,它最为有用。
例如,下面的序列会跳过光标左侧的单词(Ctrl+Left),然后按下Backspace:
{
"key": "ctrl+u",
"command": "workbench.action.terminal.sendSequence",
"args": {
"text": "\u001b[1;5D\u007f"
}
}
此功能支持变量替换。
sendSequence
命令仅支持使用 \u0000
格式通过字符代码来表示字符(不支持 \x00
)。在以下资源中阅读有关这些十六进制代码和终端序列的更多信息:
发送自定义信号
workbench.action.terminal.sendSignal
命令可用于向活动终端中的前台进程发送任意信号。
例如,下面的键绑定将发送 SIGTERM
,使其正常终止。
{
"key": "ctrl+shift+/",
"command": "workbench.action.terminal.sendSignal",
"args": {
"signal": "SIGTERM"
}
}
确认对话框
为了避免不必要的输出和用户提示,当进程退出时,终端不会显示警告对话框。如果需要警告,可以通过以下设置进行配置:
- terminal.integrated.confirmOnExit - 控制当有活动的调试会话时,关闭窗口是否需要确认。
- terminal.integrated.confirmOnKill - 控制当终端有子进程时,终止终端是否需要确认。
- terminal.integrated.showExitAlert - 控制当退出代码非零时,是否显示“终端进程已终止,退出代码为...”的警报。
自动回复
如果接收到精确的输出序列,终端可以自动向 shell 提供可配置的输入响应。最常见的用例是在批处理脚本中按 Ctrl+C 时,当脚本询问用户是否要终止批处理作业时,自动回复提示。要自动忽略此消息,请添加此设置:
{
"terminal.integrated.autoReplies": {
"Terminate batch job (Y/N)": "Y\r"
}
}
请注意,这里使用的 \r
字符表示 Enter,与自定义序列键盘快捷方式非常相似,此功能支持向 shell 发送转义序列。
默认情况下没有配置自动回复,因为提供 shell 输入应该是用户的明确操作或配置。
更改制表符宽度
terminal.integrated.tabStopWidth 设置允许在终端中运行的程序输出 \t
时配置制表符的宽度。这通常不是必需的,因为程序通常会移动光标而不是使用 Tab 字符,但在某些情况下可能很有用。
Unicode 和表情符号支持
终端同时支持 Unicode 和表情符号。当这些字符在终端中使用时,该支持存在一些注意事项:
- 一些 Unicode 符号具有不明确的宽度,可能会在不同 Unicode 版本之间发生变化。目前我们支持 Unicode 版本 6 和 11 的宽度,可以通过 terminal.integrated.unicodeVersion 设置进行配置。指定的版本应与 shell/操作系统使用的 Unicode 版本匹配,否则可能会出现渲染问题。请注意,shell/操作系统的 Unicode 版本可能与字体的实际宽度不匹配。
- 一些由多个字符组成的表情符号可能无法正确渲染,例如肤色修饰符。
- 在 Windows 上,表情符号支持有限。
图像支持
只要使用 Sixel 或 iTerm 内联图像协议,终端中的图像就可以工作。此功能默认禁用,可以通过 terminal.integrated.enableImages 设置启用。
当前限制
- 序列化不起作用,因此重新加载终端不会保留任何图像 (jerch/xterm-addon-image#47)。
- 将选择内容复制为 HTML 不包括所选图像 (jerch/xterm-addon-image#50)。
- 动画 gif 不起作用 (jerch/xterm-addon-image#51)。
- 比单元格短的图像将无法正常工作,这是序列的设计缺陷,在 XTerm 中也会出现。
进程环境
在终端内运行的应用程序的进程环境受到各种设置和扩展的影响,可能导致 VS Code 终端中的输出与其他终端中的输出看起来不同。
环境继承
当 VS Code 打开时,它会启动一个登录 shell 环境以获取 shell 环境。这样做是因为开发工具通常被添加到像 ~/.bash_profile
这样的 shell 启动脚本的 $PATH
中。默认情况下,终端会继承此环境,这取决于你的配置文件 shell 参数,这意味着可能已经运行了多个配置文件脚本,这可能会导致意外行为。
在 macOS 和 Linux 上,可以通过 terminal.integrated.inheritEnv 设置禁用此环境继承。
与 $LANG
的交互
与 $LANG
环境变量有一些特殊的交互,它决定了字符在终端中的显示方式。此功能通过 terminal.integrated.detectLocale 设置进行配置:
值 | 行为 |
---|---|
on |
始终将 $LANG 设置为最常用的期望值。所选值基于操作系统的区域设置(回退到 en-US ),并使用 UTF-8 编码。 |
auto (默认值) |
如果 $LANG 未正确配置(未设置为 UTF 或 EUC 编码),则其行为类似于 on 。 |
off |
不修改 $LANG 。 |
扩展环境贡献
扩展能够为终端环境做出贡献,允许它们提供与终端的一些集成。例如,内置的 Git 扩展会注入 GIT_ASKPASS
环境变量,以允许 VS Code 处理对 Git 远程仓库的身份验证。
如果扩展更改了终端环境,任何现有的终端将在安全的情况下被重新启动,否则将在终端状态栏中显示警告。有关更改的更多信息可以在悬停提示中查看,其中还包括一个重新启动按钮。
Windows 和 ConPTY
VS Code 的终端基于 xterm.js 项目构建,以实现一个 Unix 风格的终端,该终端将所有数据序列化为字符串并通过“伪终端”进行管道传输。从历史上看,这并不是 Windows 上终端的工作方式,Windows 使用 控制台 API 来实现其名为“conhost”的控制台。
一个名为 winpty 的开源项目被创建出来,试图通过在 Unix 风格终端和 Windows 控制台之间提供一个模拟/转换层来解决这个问题。VS Code 的终端最初仅使用 winpty 实现。这在当时很好,但在 2018 年,Windows 10 获得了 ConPTY API,它借鉴了 winpty 的开创性思想并将其融入 Windows,为在 Windows 上利用 Unix 风格的终端和应用程序提供了一个更可靠和受支持的系统。
VS Code 在 Windows 10+(从构建号 18309 开始)上默认使用 ConPTY,并对旧版 Windows 回退到 winpty 作为旧版选项。ConPTY 可以通过 terminal.integrated.windowsEnableConpty 设置明确禁用,但通常应避免这样做。
由于 ConPTY 是一个模拟层,它确实带有一些怪癖。最常见的是 ConPTY 认为自己是视口的拥有者,因此有时会重绘屏幕。这种重绘可能导致意外行为,例如在运行 终端:清除 (Terminal: Clear) 命令后显示旧内容。
远程开发
本节概述了当 VS Code 使用 VS Code 远程开发扩展连接到远程计算机时的特定主题。
远程窗口中的本地终端
默认的本地终端配置文件可以通过命令面板中的 终端:创建新的集成终端 (本地) (Terminal: Create New Integrated Terminal (Local)) 命令在远程窗口中启动。目前,非默认配置文件无法从远程窗口启动。
减少远程输入延迟(预览)
本地回显是一项有助于减轻远程窗口输入延迟的功能。它会在远程确认结果之前,以暗淡的颜色在终端中写入按键。默认情况下,当检测到延迟超过 30 毫秒时,该功能开始运行,并且时间可以通过 terminal.integrated.localEchoLatencyThreshold 进行配置。未确认字符的颜色由 terminal.integrated.localEchoStyle 定义。
本地回显会根据终端中活动的程序动态禁用自身。这由 terminal.integrated.localEchoExcludePrograms 控制,默认为 ['vim', 'vi', 'nano', 'tmux']
。建议您为任何高度动态和/或在键入时进行大量屏幕重绘的应用程序或 shell 禁用该功能。
要完全禁用该功能,请使用:
{
"terminal.integrated.localEchoEnabled": false
}