Predefined variable substitution in VSCode tasks user input - visual-studio-code

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)

Related

${relativeFileDirname} doesn't resolve in tasks.json

Here's my tasks.json for reference:
{
"version": "2.0.0",
"tasks": [
{
"type": "cppbuild",
"label": "build active file with debug",
"command": "/usr/bin/g++",
"args": [
"${file}",
"-o",
"${workspaceFolder}/out/${relativeFileDirname}.out",
"-g"
],
"problemMatcher": ["$gcc"],
"group": "build",
"detail": "compiler: /usr/bin/g++"
},
]
}
Here's a video to demonstrate the output: https://imgur.com/a/tvurtX1
In the video I am compiling a file 12-how-to-debug-effectively/main.cpp, and according to my tasks.json, the output file should be out/12-how-to-debug-effectively.out, but for some reason the variable substitution doesn't work and I instead get out/.out.
Any pointers where I might be going wrong?
cppbuild is not a valid value for the type argument.
All the examples on the VSC doc site use "type": "shell"
When using "type": "shell" I can see the command to be executed and the variables are filled in correct. (I used a 1 word subdirectory mysite)
Using "type": "cppbuild" I can't see which command is executed.

how can I change the Predefined variables in vscode json file

for example:
when I run the tasks.json:
{
"tasks": [
{
"label": "echo",
"type": "shell",
"command": "echo ${workspaceFolder}\\bulid\\${relativeFileDirname}\\${fileBasenameNoExtension}.exe"
}
],
"version": "2.0.0"
}
it print
C:\Users\***\OneDrive\***\CLion\bulid\CourseBook\0201_SqList\SqList-main.exe
because my filename was SqList-main.c.
But what I want is Sqlist.exe.
Can I do something to let it print?
C:\Users\***\OneDrive\***\CLion\bulid\CourseBook\0201_SqList\SqList.exe
I want a smart or auto method because I have many files to change.
tips: the .c file can not rename for some reason.
Using extension Command Variable v1.6.0 there is a command that can transform a number of variables.
For this case you have to modify task.json
{
"version": "2.0.0",
"tasks": [
{
"label": "echo",
"type": "shell",
"command": "echo ${workspaceFolder}\\build\\${relativeFileDirname}\\${input:noMain}.exe"
}
],
"inputs": [
{
"id": "noMain",
"type": "command",
"command": "extension.commandvariable.transform",
"args": {
"text": "${fileBasenameNoExtension}",
"find": "-main"
}
}
]
}
You can use any regular expression as find and define a replace string with capture group references ($1), and the flags to use to construct the regular expression.

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.

How to pass optional selected text to a task

I would like to be able to run a task and optionally pass in any currently selected text, ignoring the argument if there is no selection.
For example:
{
"label": "echo",
"type": "shell",
"command": "echo",
"args": [
"${selectedText}"
],
}
The above task will run fine if there is a selection, but VS Code gives an error and refuses to run the task if there is no selection. I've tried using an input:
"inputs": [
{
"type": "promptString",
"id": "selection",
"description": "Selection:",
"default": "${selectedText}"
},
]
I then pass "${input:selection}" to the task. This prevents the error message from VS Code if there is no selection, but then Terminal hangs and the task does not complete.
v0.3.0 of the extension Command Variable has a version of selectedText that returns an empty string when nothing selected.
{
"version": "2.0.0",
"tasks": [
{
"label": "echo",
"type": "shell",
"command": "echo",
"args": [
"${command:extension.commandvariable.selectedText}"
]
}
]
}

Is it possible to pass arguments to a task in Visual Studio Code

Here's an example of my tasks.json:
{
"version": "0.1.0",
"tasks": [
{
"taskName": "test",
"suppressTaskName": true,
"command": "python",
"args": [
"tests/brewer_tests.py"
],
"isTestCommand": true
}
]
}
I can run this with shift+cmd+alt+b. I can also run it with alt+t, and choose it from the menu. Is it possible to pass additional arguments in that menu? e.g.
And you could build it into your task like so:
{
"version": "0.1.0",
"tasks": [
{
"taskName": "test",
"suppressTaskName": true,
"command": "python",
"args": [
"tests/brewer_tests.py",
$arg1 # would resolve to "ARG1"
],
"isTestCommand": true
}
]
}
Or something similar?
I used the solution from this answer until now, but since Visual Studio Code has now an official support for task prompts I will add it as an answer here.
In your tasks.json file, you add the key inputs next to your tasks. This key contains an array with all possible parameters. Note that not every task has to use all of these inputs.
All of these inputs have an id, which you will use to reference the input in your task.
Now, in the task you only need to add ${input:myInputId} whereever you need the parameter.
Example:
{
"version": "2.0.0",
"tasks": [
{
"label": "Echo param",
"type": "shell",
"command": "echo ${input:param1}",
"problemMatcher": []
},
{
"label": "Echo without param",
"type": "shell",
"command": "echo Hello",
"problemMatcher": []
},
],
"inputs": [
{
"id": "param1",
"description": "Param1:",
"default": "Hello",
"type": "promptString"
},
]
}
The task Echo param will open a prompt, which lets you input a string value and it will then print this value. The task Echo without param will simply print "Hello".
Here's what is working for me for now - using this to run a golang snippet with custom arguments.
If you add a keyboard mapping to this, the process is very straightforward.
So far tested this only under Windows - linux version is commented out for that reason
{
"label": "runwithargs",
"type": "shell",
"windows": {
"options": {
"shell": {
"executable": "powershell.exe",
"args": [
"-NoProfile",
"-ExecutionPolicy",
"Bypass",
"-Command"
]
}
},
"command": "",
"args": [
{ "value": "$cmdargs = read-host 'Enter command line arguments';", "quoting": "weak"},
{ "value": "go run ${file} $cmdargs", "quoting": "weak"}
]
},
/*"linux": {
"command": "echo 'Enter command line arguments: '; read cmdargs;",
"args": [ "go run ${file} $cmdargs" ]
},*/
"presentation": {
"panel": "dedicated",
"focus": true
}
}
Regarding Input variables, VSCode 1.43 (Feb. 2020) adds a new feature:
promptString Password Input
The "promptString" "input" type can have "password": true, which will cause the quick input that shows to obscure the typed content like a password.