Use command inside a VSCode configuration - visual-studio-code

As per the documentation given here, I wish to add a text prompt box when I start my debug configuration. My launch.json file is as follows -
{ "version": "2.0.0",
"configurations": [
{
"name": "Docker Attach my container",
"type": "coreclr",
"request": "attach",
"processId": "${command:pickRemoteProcess}",
"pipeTransport": {
"pipeProgram": "docker",
"pipeArgs": [ "exec", "-i", "${input:containerName}" ],
"debuggerPath": "/vsdbg/vsdbg",
"pipeCwd": "${workspaceRoot}",
"quoteArgs": false
}
}
],
"inputs": [
{
"id": "containerName",
"type": "promptString",
"description": "Please enter container name",
"default": "my-container"
}
]
}
However with this VSCode does not give the prompt for me to enter container name. Any ideas why this would be the case?
Also further question, ideally I wish to execute a shell script that can run docker ps + some grep to filter out the correct container name automatically. So if that can be done and then passed to this configuration as an argument, that would be even ideal.

For the second part you can use the extension Command Variable to use the content of a file as a variable of via a Key-Value pair.
Write a shell script that does your docker ps and grep that produces the result in a file in a preLaunchTask.
Use the command extension.commandvariable.file.content in an ${input:xxxx} variable and use the extension to read the content of the file to be used in the launch command.

Related

Is it possible to specify user specific pre commands in VS Code?

We have a slew of folks doing development through the same GitLab repo. We are using VS Code tasks to execute internal commands. The main command is the same for everyone: internal_command on Windows and internalCommand on Linux.
{
// See https://go.microsoft.com/fwlink/?LinkId=733558
// for the documentation about the tasks.json format
"version": "2.0.0",
"tasks": [
{
"label" : "do it",
"type" : "shell",
"windows": {
"command": "internal_command"
},
"linux": {
"command": "internalCommand"
}
}
]
}
This works as expected.
Some users need/want to run a specific command before the main command. For example, one use wants to rename a file, another user wants to change an environment variable, etc...
We don't want to have multiple versions of .vscode/tasks.json cause that is a mess when pushing things to GitLab.
So I am wondering if there is a way to specify user specific tasks in the project's .vscode/tasks.json file?
You can with the help of the extension Command Variable it allows you to use the content of a file as a command in the terminal. The file can also contain Key-Value pairs or be a JSON file.
Say you store this userTask.txt or userTask.json file in the .vscode folder and add the file to the .gitignore file.
With the current version of the extension the file userTask.txt has to exist, I will add an option to supply alternative text in case the file does not exist. You can fill the file with a dummy command like echo No User Task
Set up your task.json like
{
"version": "2.0.0",
"tasks": [
{
"label" : "do it",
"type" : "shell",
"windows": {
"command": "internal_command"
},
"linux": {
"command": "internalCommand"
},
"dependsOrder": "sequence",
"dependsOn": ["userTask"]
},
{
"label" : "userTask",
"type" : "shell",
"command": "${input:getUserTask}"
}
],
"inputs": [
{
"id": "getUserTask",
"type": "command",
"command": "extension.commandvariable.file.content",
"args": {
"fileName": "${workspaceFolder}/.vscode/userTask.txt"
}
}
]
}

How can I start debugging R or Python code using the same key in Visual Studio Code?

Trying to avoid the XY problem, my problem at the very high level: I work in a VS Code workspace with R and Python code files, and I often need to debug one or the other. Currently I have different debug launch configurations saved, and I need to switch between them manually - that is a pain. I would like to use F5 to
launch the Python debugger when the editor is active in a .py file
launch the R debugger when the editor is active in a .R file
I see many technical ways of doing that, but all have their roadblocks (some of which may just poor documentation):
Create my own extension with a dynamic debug configuration that determines the type of the active editor and starts the correct debug configuration. (A lot of effort required.)
Use a "compound" launch configuration, starting both R and Python launch configurations, and stopping all but one. This can be done using a "prelaunchTask" for each, but non-zero return codes create error message that I don't like.
Use editor-dependent key mappings ("when": "editorLangId == 'python'"), but which command for debugging to start and how to pass the launch configuration? There is vscode.startDebug which takes arguments (https://github.com/microsoft/vscode/issues/4615), but I cannot keybind to that. And then there is workbench.action.debug.start which seems to ignore arguments. And then there is vscode.commands.executeCommand to which I cannot keybind, either.
Use a multi-command extension to bind a key to something like "set debug configuration, then press F5". But how to do that?
Etc. etc.
After much fiddling, here is one solution following idea 2:
settings.json (launch configs could be put into launch.json):
{
"debug.onTaskErrors": "abort",
"launch": {
"compounds": [
{
"name": "Python/R: Current File",
"configurations": [
"Python: Current File",
"R: Current File",
],
},
],
"configurations": [
{
"name": "Python: Current File",
"type": "python",
"preLaunchTask": "check_ext py",
"request": "launch",
// ...
},
{
"name": "R: Current File",
"type": "R-Debugger",
"preLaunchTask": "check_ext R",
"request": "launch",
// ...
}
],
},
}
tasks.json:
{
"version": "2.0.0",
"tasks": [
{
"label": "check_ext py",
"type": "shell",
"command": "echo ${fileExtname} | grep -i ^.py$",
},
{
"label": "check_ext R",
"type": "shell",
"command": "echo ${fileExtname} | grep -i '^.R$'",
},
],
}

Using a shell command as VSCode task variable value

I am trying to define a VSCode task in tasks.json that would adapt to the specific architecture where VSCode runs. To do this, I want to get the architecture as uname --m (e.g. "aarch64" or "amd64"). My goal is to interpolate the output of uname into an environment variable like so
"version": "2.0.0",
"tasks": [
{
"label": "build",
"type": "shell",
"command": "cmake",
"args": [
"-DMYLIB_INCLUDE_DIR=$MYLIB/include",
"-DMYLIB_LIBRARY=$MYLIB/lib"
],
"options": {
"env": {
"MYLIB": "${workspaceFolder}/mylib/${command:get_arch}"
}
},
}
]
In my case, I will have architecture-specific versions of mylib under mylib/aarch64, mylib/amd64, etc.
My attempt so far as been to define a second get_arch task used in the environment definition of MYLIB, that simply runs uname.
{
"label": "get_arch",
"type": "shell",
"command": "uname --m"
}
Of course, this task is not a proper command and so it isn't detected by VSCode and my build task fails. I checked out the documentation on variable substition, but they don't mention if it's possible to substitute a shell command. I guess this would be possible from within an extension, but I want to keep things as simple as possible.
This extension provides a way to launch arbitrary shell commands as a VS Code command:
"tasks": [
{
"label": "test_arch",
"type": "shell",
"command": "echo",
"args": [
"${MYARCH}"
],
"options": {
"env": {
"MYARCH": "${input:get_arch}"
}
},
"problemMatcher": []
},
],
"inputs": [
{
"id": "get_arch",
"type": "command",
"command": "shellCommand.execute",
"args": {
"command": "uname -m"
}
}
]
One disadvantage I discovered is that you have to press Enter once more when the result of the command is prompted in picker. Aside of this, this is the straightest way to implement what you want, and yet it can be utilized in many similar situations.
Alternatively, you can add pickString input with arch picker or create an extension that adds only single command GetArch.
If you don't want to press enter every time, you can add the option useFirstResult: true in the args section.

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}.

vscode: command for user input in debug launch config

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.