vscode: command for user input in debug launch config - visual-studio-code

I want to do something similar to whats outlined in this documentation for selecting a process, except I want to just be able to input any string:
{
"name": "Attach to Process",
"type": "node",
"request": "attach",
"processId": "${command:PickProcess}",
"port": 9229
}
Is there a command that I can use to get any user input? Ideally I could do something like this:
{
"name": "Launch Chrome Debug",
"type": "chrome",
"request": "launch",
"url": "http://localhost:8080/?id=${command:UserInput}",
"webRoot": "${workspaceRoot}",
}
That way I could specify the "id" param when I launch the debugger.

v1.30 has added this functionality: input variables during tasks and debug.
For user input variables, we introduced a new variable category input,
which results in this syntax: ${input:variableName}. This simple
syntax is not sufficient to present meaningful UI to the end user, so
we've introduced a new inputs section in launch.json and tasks.json,
where additional configuration attributes are specified.
Here is the list of supported attributes:
id - The corresponding variable name for which these attributes are
used.
type - The type of user input widget. In this release, promptString
(for a string InputBox) and pickString (for a string Quick Pick) are
supported.
description - Descriptive text shown to the user.
default - The default value to use if the user just presses Enter.
A first example shows how to use a user input variable in a task
configuration (tasks.json):
{
"tasks": [
{
"label": "Echo input",
"type": "shell",
"command": "echo ${input:echoPrompt}"
}
],
"inputs": [
{
"id": "echoPrompt",
"description": "Please enter a value",
"default": "default echo text",
"type": "promptString"
}
]
}
Another example shows a user input variable for selecting between two
options in a debug configuration (launch.json):
{
"configurations": [
{
"type": "node",
"request": "launch",
"name": "Launch Program",
"program": "${workspaceFolder}/${input:pickProgram}"
}
],
"inputs": [
{
"id": "pickProgram",
"description": "Select client or server",
"type": "pickString",
"options": ["client.js", "server.js"],
"default": "client.js"
}
]
}
We plan to combine user input variables with the existing
command-based variables so that user input variables can be
contributed by extensions.

Related

How to perform operations on VSCode macros?

My launch.json specifies a list of arguments for a given debug session (For airflow debugging in this case):
{
"version": "0.2.0",
"configurations": [
{
"name": "airflow_debug",
"type": "python",
"request": "launch",
"program": "${workspaceFolder}/.venv/bin/airflow",
"preLaunchTask": "activate-python-venv",
"console": "integratedTerminal",
"env": {
"AIRFLOW_HOME": "${workspaceFolder}",
"AIRFLOW__CORE__LOAD_EXAMPLES": "False",
"AIRFLOW__CORE__DAGS_FOLDER": "${workspaceFolder}/dags",
"AIRFLOW__CORE__EXECUTOR": "SequentialExecutor",
"PYTHONPATH": "${workspaceFolder}/plugins:${workspaceFolder}/dags:${env:PYTHONPATH}"
},
"args": [
"dags",
"test",
"migrate_dtm",
"2022-11-24"
]
}
]
}
In order to be able to debug my dags, I must specify the dag name in the args, here it is migrate_dtm. A more sophisticated way, would be to deduce the name of the dag from the name of the file My file's name is migrate_dtm_dag.py.
The goal here is not to change the launch.json and manually specify the dag name within every different debug launch; but only set a nomenclature rule for the devs to follow.
Something like this would help
"args":[
...
"${file.split('/')[-1].split('_dag')'}", // First split to get only the file name without the path, second split to extract the dag name.
...
]
Is there a way to achieve something like this in a VSCode macro? Or to perform operations on macros at all?
you can use the extension Command Variable
{
"version": "0.2.0",
"configurations": [
{
"name": "airflow_debug",
"type": "python",
"request": "launch",
"program": "${workspaceFolder}/.venv/bin/airflow",
"preLaunchTask": "activate-python-venv",
"console": "integratedTerminal",
"env": {
"AIRFLOW_HOME": "${workspaceFolder}",
"AIRFLOW__CORE__LOAD_EXAMPLES": "False",
"AIRFLOW__CORE__DAGS_FOLDER": "${workspaceFolder}/dags",
"AIRFLOW__CORE__EXECUTOR": "SequentialExecutor",
"PYTHONPATH": "${workspaceFolder}/plugins:${workspaceFolder}/dags:${env:PYTHONPATH}"
},
"args": [
"dags",
"test",
"${input:getdag}",
"2022-11-24"
]
}
],
"inputs": [
{
"id": "getdag",
"type": "command",
"command": "extension.commandvariable.transform",
"args": {
"text": "${fileBasenameNoExtension}",
"find": "_dag"
}
}
]
}
The default replace is "", so it removed the text _dag.
With the command extension.commandvariable.dateTime you can create a date string for today.

Nesting/joining a workspace input variable inside multi folder workspaceFolder variable?

Is there a way to nest an input variable inside other variables, particularly ${workspaceFolder}? As an example .code-workspace file:
{
"folders": [
{
"name": "Client",
"path": "path/to/client/code"
},
{
"name": "Server",
"path": "path/to/server/code"
},
{
"name": "Shared",
"path": "path/to/shared/code"
}
],
"launch": {
"version": "0.2.0",
"configurations": [
{
"name": "(gdb) Launch",
"type": "cppdbg",
"request": "launch",
"cwd": "${workspaceFolder}",
"program": "apphere"
}
],
"inputs": [
{
"id": "pickProject",
"type": "pickString",
"description": "Select a project:",
"options": [
"Client",
"Server"
]
}
]
}
}
All projects (Client and Server in this example) would share the same launch configurations, the only thing that would need to change is the cwd value. Unfortunately you cannot use ${workspaceFolder} directly in a multi folder workspace as you receive this error:
Variable ${workspaceFolder} can not be resolved in a multi folder workspace. Scope this variable using ':' and a workspace folder name.
What would be perfect is being able to do something like this:
"cwd": "${workspaceFolder:${input:pickProject}}"
Unfortunately this does not work. Is there another way to provide a dynamic scope for the workspaceFolder variable?
I did figure out one rather hacky way to handle this although it feels like there should be a better way: If you change the pickString input options to the folder paths and then change the debug cwd to "cwd": "${workspaceFolder:Shared}/../../../${input:pickProject}" you can arbitrarily pick one of the folders, traverse back out to the root workspace directory, and then append the ${input:pickProject} variable onto the end. In addition to the directory traversals, the debug choices you see will be "path/to/client/code" and "path/to/server/code" instead of the more clean "Client" and "Server". But at least it does seem to work, albeit not overly ideal.
With the extension Command Variable you have possible solutions
extension.commandvariable.file.fileAsKey
When you have a file open and current for Client or Server the F5 will select the correct cwd based on the path of the current file.
"launch": {
"version": "0.2.0",
"configurations": [
{
"name": "(gdb) Launch",
"type": "cppdbg",
"request": "launch",
"cwd": "${input:getCWD}",
"program": "apphere"
}
],
"inputs": [
{
"id": "getCWD",
"type": "command",
"command": "extension.commandvariable.file.fileAsKey",
"args": {
"/client/": "/path/to/client/code",
"/server/": "/path/to/server/code"
}
}
]
}
extension.commandvariable.pickStringRemember
If you want a pick list that shows Client and Server but returns the corresponding paths use:
"launch": {
"version": "0.2.0",
"configurations": [
{
"name": "(gdb) Launch",
"type": "cppdbg",
"request": "launch",
"cwd": "${input:pickPath}",
"program": "apphere"
}
],
"inputs": [
{
"id": "pickPath",
"type": "command",
"command": "extension.commandvariable.pickStringRemember",
"args": {
"description": "Select a project:",
"options": [
["Client", "/path/to/client/code"],
["Server", "/path/to/server/code"]
]
}
}
]
}

Predefined variable substitution in VSCode tasks user input

Looking at the documentation for VSCode variable substitution, I was expecting the following tasks.json to perform variable substitution in the pick list when using the chooseDirectory code, but it just selects the literal string ${fileDirname} instead.
Can I get the substituted text to appear in the user selection menu?
{
"version": "2.0.0",
"command": "cmd",
"args": ["/c"],
"tasks": [
{
"label": "The task",
"command": "my_batch_file.bat",
"type": "shell",
"args": [
"${workspaceFolder}",
"${input:chooseDirectory}"
],
"problemMatcher": []
}
],
"inputs": [
{
"id": "chooseDirectory",
"description": "Select the Directory",
"type": "pickString",
"options": ["option1", "${fileDirname}"],
"default": "option1"
}
]
}
When the task executes, this is what gets executed:
> Executing task: my_batch_file.bat C:\My\Workspace\Directory ${fileDirname} <
This issue suggests that variable substitution is currently not supported for inputs, but might be added sometime in the future:
consider to allow for variable substitution in the inputs section (#64358)

Is it possible to launch a vscode extension with a set of custom settings?

I'm developing a vscode extension, and while testing it out I've hit a bit of a snag. Some functionality depends on custom settings that I define in the configuration of package.json. I would like to be able to launch a new VSCode window with the settings set to particular values, but I can't find how to do that.
What I have in launch.json:
{
"version": "0.2.0",
"configurations": [
{
"name": "Extension",
"type": "extensionHost",
"request": "launch",
"runtimeExecutable": "${execPath}",
"args": [
"--disable-extensions",
"--extensionDevelopmentPath=${workspaceRoot}"
],
"ns.customSetting": "customValue"
},
{
"name": "Extension with another value",
"type": "extensionHost",
"request": "launch",
"runtimeExecutable": "${execPath}",
"args": [
"--disable-extensions",
"--extensionDevelopmentPath=${workspaceRoot}"
],
"ns.customSetting": "anotherValue"
}
]
}
That hasn't been working, but hopefully the idea is clear. I want that new window to open with the custom setting already set to the value I want. How do I do that?

VSCode Custom Variables in Launch Settings?

Is there a way to add custom variables that I can use in my launch.json settings for debugging in VSCode? Currently, the only way I have found is to add them to my workspace settings and refer to the from the ${config} predefined variable.
I'd like to define variables/properties in the launch.json and use them. Here's an example of what that might look like if I wanted to add myCustomVar to all my URLs:
{
"version": "0.2.0",
"myCustomVar": "my_value",
"configurations": [
{
"name": "Page 1",
"type": "chrome",
"request": "launch",
"url": "http://localhost/page1.html?customVar=${myCustomVar}",
"sourceMaps": true,
"webRoot": "${workspaceFolder}/dev"
},
{
"name": "Page 2",
"type": "chrome",
"request": "launch",
"url": "http://localhost/page2.html?customVar=${myCustomVar}",
"sourceMaps": true,
"webRoot": "${workspaceFolder}/dev"
}
}
Input variables might work?
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
}
]
}
Otherwise, you should be able to add custom settings to your VS Code settings.json file (it will warn you about "Unknown Configuration Setting") and insert them using ${config:myCustomVar}.