变量参考
Visual Studio Code 支持在调试和任务配置文件以及某些选定设置中进行变量替换。在 launch.json
和 tasks.json
文件中的某些键和值字符串内部,通过使用 ${variableName} 语法支持变量替换。
预定义变量
支持以下预定义变量
变量 | 描述 |
---|---|
${userHome} | 用户主文件夹的路径 |
${workspaceFolder} | 在 VS Code 中打开的文件夹的路径 |
${workspaceFolderBasename} | 在 VS Code 中打开的文件夹的名称,不带任何斜杠 (/) |
${file} | 当前打开的文件 |
${fileWorkspaceFolder} | 当前打开文件的工作区文件夹 |
${relativeFile} | 当前打开的文件相对于 workspaceFolder 的路径 |
${relativeFileDirname} | 当前打开文件的目录名相对于 workspaceFolder 的路径 |
${fileBasename} | 当前打开文件的基本名称 |
${fileBasenameNoExtension} | 当前打开文件的基本名称,不带文件扩展名 |
${fileExtname} | 当前打开文件的扩展名 |
${fileDirname} | 当前打开文件的文件夹路径 |
${fileDirnameBasename} | 当前打开文件的文件夹名称 |
${cwd} | VS Code 启动时任务运行器的当前工作目录 |
${lineNumber} | 活动文件中当前选定的行号 |
${columnNumber} | 活动文件中当前选定的列号 |
${selectedText} | 活动文件中当前选定的文本 |
${execPath} | 运行中的 VS Code 可执行文件的路径 |
${defaultBuildTask} | 默认生成任务的名称 |
${pathSeparator} | 操作系统用于分隔文件路径组件的字符 |
${/} | ${pathSeparator} 的简写形式 |
预定义变量示例
假设您有以下情况
- 编辑器中打开的文件位于
/home/your-username/your-project/folder/file.ext
; - 目录
/home/your-username/your-project
作为您的根工作区打开。
这会使每个变量具有以下值
- ${userHome}:
/home/your-username
- ${workspaceFolder}:
/home/your-username/your-project
- ${workspaceFolderBasename}:
your-project
- ${file}:
/home/your-username/your-project/folder/file.ext
- ${fileWorkspaceFolder}:
/home/your-username/your-project
- ${relativeFile}:
folder/file.ext
- ${relativeFileDirname}:
folder
- ${fileBasename}:
file.ext
- ${fileBasenameNoExtension}:
file
- ${fileExtname}:
.ext
- ${fileDirname}:
/home/your-username/your-project/folder
- ${fileDirnameBasename}:
folder
- ${lineNumber}: 光标所在行号
- ${columnNumber}: 光标所在列号
- ${selectedText}: 代码编辑器中选定的文本
- ${execPath}: Code.exe 的位置
- ${pathSeparator}: 在 macOS 或 Linux 上为
/
,在 Windows 上为\
在 tasks.json
和 launch.json
的字符串值中使用 IntelliSense 以获取预定义变量的完整列表。
按工作区文件夹范围划分的变量
通过将根文件夹的名称附加到变量(用冒号分隔),可以访问工作区的同级根文件夹。如果没有根文件夹名称,变量的作用域将限定在使用它的同一文件夹中。
例如,在包含 Server
和 Client
文件夹的多根工作区中,${workspaceFolder:Client}
指的是 Client
根的路径。
环境变量
您可以使用 ${env:Name} 语法引用环境变量。例如,${env:USERNAME} 引用 USERNAME
环境变量。
{
"type": "node",
"request": "launch",
"name": "Launch Program",
"program": "${workspaceFolder}/app.js",
"cwd": "${workspaceFolder}",
"args": ["${env:USERNAME}"]
}
配置变量
要引用 VS Code 设置(配置),请使用 ${config:Name} 语法。例如,${config:editor.fontSize} 引用 editor.fontSize
设置。
命令变量
您可以使用 ${command:commandID} 语法将任何 VS Code 命令用作变量。
命令变量会被替换为命令评估的结果(字符串)。命令的实现可以是从没有 UI 的简单计算,到基于通过 VS Code 扩展 API 提供的 UI 功能的一些复杂功能。如果命令返回的不是字符串,则变量替换将不会完成。命令变量必须返回一个字符串。
此功能的一个示例是 VS Code 的 Node.js 调试器扩展,它提供了一个交互式命令 extension.pickNodeProcess
,用于从所有正在运行的 Node.js 进程列表中选择单个进程。该命令返回所选进程的进程 ID。这使得可以在**按进程 ID 附加**启动配置中按以下方式使用 extension.pickNodeProcess
命令
{
"configurations": [
{
"type": "node",
"request": "attach",
"name": "Attach by Process ID",
"processId": "${command:extension.pickNodeProcess}"
}
]
}
在 launch.json
配置中使用命令变量时,包含该命令变量的 launch.json
配置会通过参数作为对象传递给该命令。这使得命令在被调用时能够了解特定 launch.json
配置的上下文和参数。
输入变量
命令变量已经很强大,但它们缺少一种机制来为特定用例配置正在运行的命令。例如,无法将**提示消息**或**默认值**传递给通用的“用户输入提示”。
此限制通过**输入变量**解决,其语法为 ${input:variableID}。variableID
指的是 launch.json
和 tasks.json
的 inputs
部分中的条目,其中指定了其他配置属性。不支持输入变量的嵌套。
以下示例展示了使用输入变量的 tasks.json
的整体结构
{
"version": "2.0.0",
"tasks": [
{
"label": "task name",
"command": "${input:variableID}"
// ...
}
],
"inputs": [
{
"id": "variableID",
"type": "type of input variable"
// type specific configuration attributes
}
]
}
目前 VS Code 支持三种类型的输入变量
- promptString: 显示一个输入框以从用户获取字符串。
- pickString: 显示一个快速选择下拉列表,让用户从多个选项中进行选择。
- command: 运行任意命令。
每种类型都需要额外的配置属性
promptString
:
- description: 显示在快速输入中,为输入提供上下文。
- default: 如果用户不输入其他内容,将使用的默认值。
- password: 设置为 true 以使用密码提示进行输入,该提示不会显示输入的值。
pickString
:
- description: 显示在快速选择中,为输入提供上下文。
- options: 供用户选择的选项数组。
- default: 如果用户不输入其他内容,将使用的默认值。它必须是选项值之一。
选项可以是字符串值,也可以是同时包含标签和值的对象。下拉列表将显示 label: value。
command
:
- command: 在变量插值时运行命令。
- args: 传递给命令实现的(可选)选项包。
以下是 tasks.json
的一个示例,它演示了使用 Angular CLI 的 inputs
。
{
"version": "2.0.0",
"tasks": [
{
"label": "ng g",
"type": "shell",
"command": "ng",
"args": ["g", "${input:componentType}", "${input:componentName}"]
}
],
"inputs": [
{
"type": "pickString",
"id": "componentType",
"description": "What type of component do you want to create?",
"options": [
"component",
"directive",
"pipe",
"service",
"class",
"guard",
"interface",
"enum"
],
"default": "component"
},
{
"type": "promptString",
"id": "componentName",
"description": "Name your component.",
"default": "my-new-component"
}
]
}
运行示例
以下示例展示了如何在调试配置中使用 command
类型的用户输入变量,该变量允许用户从特定文件夹中找到的所有测试用例列表中选择一个测试用例。假设某个扩展提供了 extension.mochaSupport.testPicker
命令,该命令可在可配置位置查找所有测试用例并显示选择器 UI 以选择其中一个。命令输入的参数由命令本身定义。
{
"configurations": [
{
"type": "node",
"request": "launch",
"name": "Run specific test",
"program": "${workspaceFolder}/${input:pickTest}"
}
],
"inputs": [
{
"id": "pickTest",
"type": "command",
"command": "extension.mochaSupport.testPicker",
"args": {
"testFolder": "/out/tests"
}
}
]
}
命令输入也可以与任务一起使用。在此示例中,使用了内置的“终止任务”命令。它可以接受一个参数来终止所有任务。
{
"version": "2.0.0",
"tasks": [
{
"label": "Terminate All Tasks",
"command": "echo ${input:terminate}",
"type": "shell",
"problemMatcher": []
}
],
"inputs": [
{
"id": "terminate",
"type": "command",
"command": "workbench.action.tasks.terminate",
"args": "terminateAll"
}
]
}
常见问题
调试配置或任务中变量替换的详细信息
调试配置或任务中的变量替换是一个两遍过程
- 在第一遍中,所有变量都被评估为字符串结果。如果一个变量出现多次,它只会被评估一次。
- 在第二遍中,所有变量都将被替换为第一遍的结果。
这样做的结果是,变量的评估(例如,在扩展中实现的基于命令的变量)**无法访问**调试配置或任务中的其他已替换变量。它只看到原始变量。这意味着变量不能相互依赖(这确保了隔离,并使替换对评估顺序具有鲁棒性)。
用户和工作区设置中是否支持变量替换?
预定义变量在 settings.json
文件中的少数设置键中受支持,例如终端的 cwd
、env
、shell
和 shellArgs
值。某些设置,如 window.title,有自己的变量
"window.title": "${dirty}${activeEditorShort}${separator}${rootName}${separator}${appName}"
请参阅“设置”编辑器中的注释(⌘, (Windows、Linux Ctrl+,))以了解特定于设置的变量。
为什么没有记录 ${workspaceRoot}?
变量 ${workspaceRoot}
已被弃用,转而使用 ${workspaceFolder}
,以便更好地与多根工作区支持保持一致。
为什么 tasks.json 中的变量未解析?
tasks.json
中的并非所有值都支持变量替换。具体来说,只有 command
、args
和 options
支持变量替换。inputs
部分中的输入变量将不会被解析,因为不支持输入变量的嵌套。
如何知道变量的实际值?
检查变量运行时值的一种简单方法是创建一个 VS Code 任务,将变量值输出到控制台。例如,要查看 ${workspaceFolder}
的解析值,您可以在 tasks.json
中创建并运行(终端 > 运行任务)以下简单的 'echo' 任务
{
"version": "2.0.0",
"tasks": [
{
"label": "echo",
"type": "shell",
"command": "echo ${workspaceFolder}"
}
]
}