Invoking a user defined input in tasks from extension - visual-studio-code

I have created an extension to extend the input features in the tasks configuration. I would like to know if it is possible in my extension that I interpret other inputs and call them.
How could I make inside my extension if I see a string in the arguments like ${input:myInput}, I'd like to fetch/invoke whatever the user configured for that input.
Example:
The first input configuration contains a config from my extension where it will run a cat and theoretically depends on a second input that the user will just choose one of the options. I'd like to know how to parse the ${input:myInput} and invoke it to substitute.
"inputs": [
{
"id": "inputTest",
"type": "command",
"command": "shellCommand.execute",
"args": {
"command": "cat ${input:myInput}",
}
},
{
"id": "myInput",
"description": "Choose a file",
"type": "pickString",
"options": [
"file1.txt",
"file2.txt"
]
}
]

As far as I understand VSC will expand variables if the value is a string or an array of strings.
Make the args property an array of strings.
"inputs": [
{
"id": "inputTest",
"type": "command",
"command": "shellCommand.execute",
"args": ["cat", "${input:myInput}"]
},
{
"id": "myInput",
"description": "Choose a file",
"type": "pickString",
"options": [
"file1.txt",
"file2.txt"
]
}
]
You can add special syntax to the array elements if you want to pass extra options to the command. For example
"args": ["cat", "${input:myInput}", "--XX--", "option1", "option2"]

Related

VsCode : How to generate custom task input options from a command?

Let's say we have the following custom task :
{
"version": "2.0.0",
"tasks": [
{
"label": "do smthg",
"type": "shell",
"command": "echo \"selected option: ${input:option_name}\"",
"problemMatcher": [],
"presentation": {
"panel": "dedicated",
"focus": true
}
}
],
"inputs": [
{
"type": "pickString",
"id": "option_name",
"description": "select an option :",
"options": [
// want possible options to be the output of a command
],
"default": ""
}
]
}
But I want the available options to be the result of a command,
like ls, or a cat smthg.txt | grep -oP '\"value\:\"\K\w*',
how can I do that ? Is it only possible ?
You can use the extension Command Variable v1.34.0
Use the replacement for pickString named extension.commandvariable.pickStringRemember.
This command can read options from a file, you determine the format with a regexp like the problem matcher of tasks.
An example:
"inputs": [
{
"type": "command",
"id": "option_name",
"command": "extension.commandvariable.pickStringRemember",
"args": {
"description": "select an option :",
"options": [
["always 1", "5000"],
["always 2", "5100"]
],
"default": "",
"fileName": "${workspaceFolder}/foo-bar.txt",
"pattern": {
"regexp": "^\\s*(?!#)([^=]+?)\\s*=\\s*(?:(\\{.+\\})|(.+))$",
"label": "$1",
"json": "$2",
"value": "$3"
}
}
}
]
If you don't have label - value lines you can simplify the pattern to
"pattern": {
"regexp": "^\\s*(?!#)(.+)$"
}
If you don't have static options (always 1/2 in example) you can remove the options property from args.
With an additional task you create the file with a command or a shell script if grep-ping and file redirection might be a problem (pass the output file name, using variables, as argument to the script).
You can construct a sequence of tasks, a compound task, see VSC doc.

In tasks.json in vscode, Is it possible to reference single elements in an array defined in settings.json?

When writing an extension in vsCode, is it possible to create a configuration (a field in my settings.json) where I can store multiple values and configure an actively selected one?
Say I have an external dependency, which I need to reference in my tasks.json. Through the configuration contribution point of the extension i can provide the following property:
"myextension.dependencyDir": {
"scope": "resource",
"type": "string",
"description": "Path to the external dependency"
}
I can now reference this path in my tasks.json through ${config:myextension.dependencyDir}
However, lets say my dependency comes in various versions, which I would like to switch from the comfort of my settings(UI)
I know that by using an array I can store multiple versions of the dependency.
"myextension.dependencyDir": {
"scope": "resource",
"type": "array",
"items": {
"type": "string"
},
"description": "Path to the external dependency"
},
However, I cannot seem to reference single elements out of this array from my tasks.json.
By calling ${config:myextension.dependencyDir} now, i get the entire array.
I have tried to call
${config:myextension.dependencyDir[0]}
${config:myextension.dependencyDir(0)}
${config:myextension.dependencyDir:0}
... and many other variations
to query the first item in my array. Neigther of those attempts have worked.
${config:myextension.dependencyDir}[0] just appends '[0]' to the
last element.
I know that I can create custom objects and configure them in my settings.
"myextension.dependencyDir": {
"scope": "resource",
"type": "array",
"items": {
"type": "object",
"properties": {
"name": {
"type": "string",
"description": "Name of your dependency version"
},
"value": {
"type": "string",
"description": "Path to the specific Dependency version"
}
}
},
"description": "Path to the external dependency"
},
However, just like before, I don't know how to access a single entry in my array, let alone adress the specific fields name and value.
Is what I am trying to do possible? Is it even the proper way of doing this? Does anyone have a solution to my problem or suggestions for a different approach?
Thanks in advance
BioZons
You can use the extension Command Variable v1.30.0
It has a command extension.commandvariable.config.expression. It allows to apply a JavaScript expression to the value of a configuration variable.
If the config variable is an array:
{
"version": "2.0.0",
"tasks": [
{
"label": "echo config var",
"type": "shell",
"command": "echo",
"args": [
"ConfigArray: ${input:configArray}",
],
"problemMatcher": []
}
],
"inputs": [
{
"id": "configArray",
"type": "command",
"command": "extension.commandvariable.config.expression",
"args": {
"configVariable": "myextension.dependencyDir",
"expression": "content[1]"
}
}
]
}
If the config variable is an array and you want to pick the array element:
{
"version": "2.0.0",
"tasks": [
{
"label": "echo config var",
"type": "shell",
"command": "echo",
"args": [
"ConfigArrayPick: ${input:configArrayPick}",
],
"problemMatcher": []
}
],
"inputs": [
{
"id": "configArrayPick",
"type": "command",
"command": "extension.commandvariable.config.expression",
"args": {
"configVariable": "myextension.dependencyDir",
"expression": "content[${pickStringRemember:serverNr}]",
"pickStringRemember": {
"serverNr": {
"description": "Which server to use?",
"options": [
["development", "0"],
["live", "1"]
]
}
}
}
}
]
}
If the config variable is an array of objects:
{
"version": "2.0.0",
"tasks": [
{
"label": "echo config var",
"type": "shell",
"command": "echo",
"args": [
"ConfigObject: ${input:configObject}",
],
"problemMatcher": []
}
],
"inputs": [
{
"id": "configObject",
"type": "command",
"command": "extension.commandvariable.config.expression",
"args": {
"configVariable": "myextension.dependencyDir",
"expression": "content[1].name"
}
}
]
}

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.

How to use the same input string across multiple chained tasks in vscode?

I have multiple tasks that depend on each other and that should all operate on the same folder.
My config looks something like this:
{
"version": "2.0.0",
"tasks": [
{
"label": "first task",
"type": "shell",
"command": "bash",
"args": ["do stuff in ${input:pickFolder}"],
"dependsOn": "second task"
},
{
"label": "second task",
"type": "shell",
"command": "bash",
"args": ["also do stuff in ${input:pickFolder}"]
}
],
"inputs": [
{
"type": "pickString",
"id": "pickFolder",
"options": ["path/to/folder", "path/to/other/folder"]
}
]
}
As you might imagine I want both tasks run in the same folder. Also, I don`t want to have to pick the folder twice. How can I do that?
You can use the extension Command Variable v0.9.
Use the commands:
extension.commandvariable.pickStringRemember
extension.commandvariable.rememberPick

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)