🚀 Get GitHub Copilot Free in VS Code!
Dismiss this update
Visual Studio Code supports variable substitution in Debugging and Task configuration files as well as some select settings. Variable substitution is supported inside some key and value strings in launch.json
and tasks.json
files using ${variableName} syntax.
The following predefined variables are supported:
workspaceFolder
workspaceFolder
Supposing that you have the following requirements:
/home/your-username/your-project/folder/file.ext
opened in your editor;/home/your-username/your-project
opened as your root workspace.So you will have the following values for each variable:
/home/your-username
/home/your-username/your-project
your-project
/home/your-username/your-project/folder/file.ext
/home/your-username/your-project
folder/file.ext
folder
file.ext
file
/home/your-username/your-project/folder
.ext
/
on macOS or linux, \
on WindowsTip: Use IntelliSense inside string values for
tasks.json
andlaunch.json
to get a full list of predefined variables.
By appending the root folder's name to a variable (separated by a colon), it is possible to reach into sibling root folders of a workspace. Without the root folder name, the variable is scoped to the same folder where it is used.
For example, in a multi root workspace with folders Server
and Client
, a ${workspaceFolder:Client}
refers to the path of the Client
root.
You can also reference environment variables through the ${env:Name} syntax (for example, ${env:USERNAME}
).
{
"type": "node",
"request": "launch",
"name": "Launch Program",
"program": "${workspaceFolder}/app.js",
"cwd": "${workspaceFolder}",
"args": ["${env:USERNAME}"]
}
You can reference VS Code settings ("configurations") through ${config:Name} syntax (for example, ${config:editor.fontSize}
).
If the predefined variables from above are not sufficient, you can use any VS Code command as a variable through the ${command:commandID} syntax.
A command variable is replaced with the (string) result from the command evaluation. The implementation of a command can range from a simple calculation with no UI, to some sophisticated functionality based on the UI features available via VS Code's extension API. If the command returns anything other than a string, then the variable replacement will not complete. Command variables must return a string.
An example of this functionality is in VS Code's Node.js debugger extension, which provides an interactive command extension.pickNodeProcess
for selecting a single process from the list of all running Node.js processes. The command returns the process ID of the selected process. This makes it possible to use the extension.pickNodeProcess
command in an Attach by Process ID launch configuration in the following way:
{
"configurations": [
{
"type": "node",
"request": "attach",
"name": "Attach by Process ID",
"processId": "${command:extension.pickNodeProcess}"
}
]
}
When using a command variable in a launch.json
configuration, the enclosing launch.json
configuration is passed as an object to the command via an argument. This allows commands to know the context and parameters of the specific launch.json
configuration when they are called.
Command variables are already powerful but they lack a mechanism to configure the command being run for a specific use case. For example, it is not possible to pass a prompt message or a default value to a generic "user input prompt".
This limitation is solved with input variables which have the syntax: ${input:variableID}
. The variableID
refers to entries in the inputs
section of launch.json
and tasks.json
, where additional configuration attributes are specified. Nesting of input variables is not supported.
The following example shows the overall structure of a tasks.json
that makes use of input variables:
{
"version": "2.0.0",
"tasks": [
{
"label": "task name",
"command": "${input:variableID}"
// ...
}
],
"inputs": [
{
"id": "variableID",
"type": "type of input variable"
// type specific configuration attributes
}
]
}
Currently VS Code supports three types of input variables:
Each type requires additional configuration attributes:
promptString
:
pickString
:
An option can be a string value or an object with both a label and value. The dropdown will display label: value.
command
:
Below is an example of a tasks.json
that illustrates the use of inputs
using Angular CLI:
{
"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"
}
]
}
Running the example:
The following example shows how to use a user input variable of type command
in a debug configuration that lets the user pick a test case from a list of all test cases found in a specific folder. It is assumed that some extension provides an extension.mochaSupport.testPicker
command that locates all test cases in a configurable location and shows a picker UI to pick one of them. The arguments for a command input are defined by the command itself.
{
"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"
}
}
]
}
Command inputs can also be used with tasks. In this example, the built-in Terminate Task command is used. It can accept an argument to terminate all tasks.
{
"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"
}
]
}
Variable substitution in debug configurations or tasks is a two pass process:
A consequence of this is that the evaluation of a variable (for example, a command-based variable implemented in an extension) has no access to other substituted variables in the debug configuration or task. It only sees the original variables. This means that variables cannot depend on each other (which ensures isolation and makes substitution robust against evaluation order).
The predefined variables are supported in a select number of setting keys in settings.json
files such as the terminal cwd
, env
, shell
and shellArgs
values. Some settings like window.title have their own variables:
"window.title": "${dirty}${activeEditorShort}${separator}${rootName}${separator}${appName}"
Refer to the comments in the Settings editor (⌘, (Windows, Linux Ctrl+,)) to learn about setting specific variables.
The variable ${workspaceRoot}
was deprecated in favor of ${workspaceFolder}
to better align with Multi-root Workspace support.
Not all values in tasks.json
support variable substitution. Specifically, only command
, args
, and options
support variable substitution. Input variables in the inputs
section will not be resolved as nesting of input variables is not supported.
One easy way to check a variable's runtime value is to create a VS Code task to output the variable value to the console. For example, to see the resolved value for ${workspaceFolder}
, you can create and run (Terminal > Run Task) the following simple 'echo' task in tasks.json
:
{
"version": "2.0.0",
"tasks": [
{
"label": "echo",
"type": "shell",
"command": "echo ${workspaceFolder}"
}
]
}