How to pass optional selected text to a task - visual-studio-code

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}"
]
}
]
}

Related

How to pass arguments to a task in vscode that executes a snippet linked to a hotkey?

I have this working hotkey:
{
"key": "cmd+t",
"command": "editor.action.insertSnippet",
"args": {
"name": "TryCatch"
}
},
Which wraps the selected text into a tryCatch block, and adds the wanted logs and error reporting.
However, I want to link it with other sequence of either hotkeys or tasks.
I have this task in tasks.json, when when triggered in attempts to perform the above command, it prompts me for user input, because I can't figure out how to pass the name of the snippet as an argument, similar to what is done with hotKey binding configurations in example 1 above.
This is the task:
{
"label": "insertSnippet",
"command": "${command:editor.action.insertSnippet}",
"args": [
// "${name:TryCatch}",
],
},
I've been trying to get tasks to execute without having to wait for user input or pressing enter for example, but dreadfully failed. I couldn't find a wait to intercept the execution of a task and pass data or select an item from a menu.
Any help on setting up a single hotKey which then triggers two or more commands?
Please note that I need to commands/tasks in the editor, not in terminal or shell. All the solutions I came across are for shell. Also inputs or text work in shell or in the editor, but not in the dropdown as in the following images, which are triggered by tasks.
Thanks.
Edit, what worked in the end. Thanks a lot #Mark
{
"version": "2.0.0",
"tasks": [
{
"label": "insertTryCatchSnippet",
"command": [
"workbench.action.tasks.runTask",
"${input:tryCatchInput}"
]
},
{
"label": "save",
"command": "${command:workbench.action.files.save}",
},
{
"label": "TryCatch",
"dependsOrder": "sequence",
"dependsOn": [
"insertTryCatchSnippet",
"save",
],
},
],
"inputs": [
{
"id": "tryCatchInput",
"type": "command",
"command": "editor.action.insertSnippet",
"args": {
"name": "TryCatch"
}
}
]
}
And this hotkey shortcut:
{
"key": "cmd+t",
"command": "workbench.action.tasks.runTask",
"args": "TryCatch"
},
Flawlessly without using macros or extensions. Thanks again.
You can run vscode commands, like editor.action.insertSnippet. But if they take arguments than I believe you have to use the inputs of tasks.json to supply the args. In your tasks.json:
{
"version": "2.0.0",
"tasks": [
{
"label": "insertTryCatchSnippet",
"command": [
"${input:tryCatchInput}"
],
}
],
"inputs": [
{
"id": "tryCatchInput",
"type": "command",
"command": "editor.action.insertSnippet",
"args": {
"name": "tryCatch"
}
}
where your snippet name is defined in some snippets file.
You can then assign this task directly to a keybinding like this (in your keybindings.json):
{
"key": "alt+w",
"command": "workbench.action.tasks.runTask",
"args": "insertTryCatchSnippet",
"when": "editorFocus"
}
If your desired command didn't need any args than you could do something like this in a task:
{
"label": "SplitTerminal",
"command": "${command:workbench.action.terminal.split}",
"type": "shell",
"problemMatcher": []
}
You can use multiple vscode commands in a task too (although some commands may need to wait for the previous command to finish and you should make 2+ tasks that then run from a master task with the dependsOrder property sequence):
{
"label": "open new terminal and then saveAll",
// "type": "shell",
"command": [
"${command:workbench.action.terminal.new}",
"${command:workbench.action.files.saveAll}"
]
}

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 set command argument in vscode task.json?

I would like to automate extension setting with some arguments on task runner in VSCode.
How can I set arguments:
string argument
menu selection
I tried something like :
{
"version": "2.0.0",
"tasks": [
{
"label": "spark setting",
"command": "${command:hdinsight.linkCluster}",
},
}
I tried applying "args" section :
{
"version": "2.0.0",
"tasks": [
{
"label": "spark setting",
"command": "${command:hdinsight.linkCluster}",
"args": ["Generic Livy Endpoint", "htttp://*****"]
},
}
But it seems doesn't work to automate.
The extension command 'linkCluster' requires both menu selection and string argument which is URI.
I haven't found a way to specify the args if you use the command variables directly in the task definition, but inputs (despite the name) allow commands with arguments:
tasks": [
{
"label": "mytask",
"command": "${input:first}",
}
],
"inputs": [
{
"id": "first",
"type": "command",
"command": "hdinsight.linkCluster",
"args": ["Generic Livy Endpoint", "htttp://*****"]
]

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