handle multiple values from inputs user in vscode tasks - visual-studio-code

What are the best solutions to receive input from user in inputs vscode on tasks.json then according chosen option to handle multiple values?
Is there any solution like this bellow?
{
"version": "2.0.0",
"inputs": [
{
"id": "selectProject",
"type": "pickString",
"description": "Some decription",
"options":
[
{
"label": "project1",
"value" : {"path":"","name":"","link":"","anyOther":""} // something like this
} ,
{
"label": "project2",
"value" : {"path":"","name":"","link":"","anyOther":""} // something like this
}
]
}
],
"tasks": [
{
"label": "test on projects",
"type": "process",
"command": "echo",
"args": [
"${input:selectProject.path}", // handle many info from one chosen option
"${input:selectProject.name}",
"${input:selectProject.link}",
"${input:selectProject.anyOther}"
]
}
]
}
currently options can receive only one value :(
"options":
[
{ "label": "project1", "value" : "value" } ,
{ "label": "project2", "value" : "value" }
]

You can use extension Command Variable v1.22.0.
The command extension.commandvariable.pickStringRemember can remember multiple values for 1 pick.
The syntax of the label-value is a bit different because I did not know pickString supported that.
{
"version": "2.0.0",
"tasks": [
{
"label": "Do some project",
"type": "process",
"command": "echo",
"args": [
"${input:selectProject.path}",
"${input:selectProject.name}",
"${input:selectProject.link}",
"${input:selectProject.anyOther}"
],
"problemMatcher": []
}
],
"inputs": [
{
"id": "selectProject.path",
"type": "command",
"command": "extension.commandvariable.pickStringRemember",
"args": {
"key": "path",
"options": [
["project1", {"path":"p1","name":"n1","link":"lnk1","anyOther":"any1"}],
["project2", {"path":"p2","name":"n2","link":"lnk2","anyOther":"any2"}]
],
"description": "Pick a project"
}
},
{
"id": "selectProject.name",
"type": "command",
"command": "extension.commandvariable.rememberPick",
"args": { "key": "name" }
},
{
"id": "selectProject.link",
"type": "command",
"command": "extension.commandvariable.rememberPick",
"args": { "key": "link" }
},
{
"id": "selectProject.anyOther",
"type": "command",
"command": "extension.commandvariable.rememberPick",
"args": { "key": "anyOther" }
}
]
}

Related

vscode tasks.json transform pickfile

I have next vscode tasks.json
{
"version": "2.0.0",
"tasks": [
{
"label": "build",
"type": "shell",
"command": "${userHome}/build.py",
"args": ["param_def=${input:pickBuild}"]
}
],
"inputs": [
{
"id": "pickBuild",
"type": "command",
"command": "extension.commandvariable.file.pickFile",
"args": {
"include": "**/default_*.py",
"description": "Select build",
"display": "fileName",
}
}
]}
when run:
actual: /home/user/build.py param_def=/home/user/default_android.py
expected: /home/user/build.py param_def=default_android
P.S: I have tried use extension.commandvariable.transform, but did not success
You can use the following config in your tasks.json
{
"version": "2.0.0",
"tasks": [
{
"label": "build",
"type": "shell",
"command": "${userHome}/build.py",
"args": ["param_def=${input:pickBuild}"]
}
],
"inputs": [
{
"id": "pickBuild",
"type": "command",
"command": "extension.commandvariable.transform",
"args": {
"text": "${pickFile:build}",
"find": "^.*/(.*).py",
"replace": "$1",
"pickFile": {
"build": {
"include": "**/default_*.py",
"description": "Select build",
"display": "fileName",
}
}
}
}
]}

How to pass input variable from launch.json to tasks.json in vscode

I can use input variables from launch.json in launch.json.
"configurations": [
{
...
"args": [${input:file_no}]
"preLanuchTask": "runPreTasks"
...
}
],
"inputs": [
{
"id": "file_no",
"type": "promptString"
}
]
Now, I want to get access to the same variable without entering input a second time in tasks.json.
{
"version": "2.0.0",
"tasks":[
{
"label": "runPreTasks",
"type": "shell",
"command": sh,
"args": [
"/path2script/scriptName.sh",
"${input:file_no}" // This does not work, without defining input again
]
}
]
}
Is there a way to pass input variables from launch.json to tasks.json in vscode?
You can use the extension Command Variable v1.21.0
It has a command extension.commandvariable.promptStringRemember that behaves the same as an ${input:name} promptString variable. By adding a key property the result is saved under this key and you can retreive it with the extension.commandvariable.rememberPick command.
The extension.commandvariable.rememberPick command can be used in a different task/launch than the extension.commandvariable.promptStringRemember command
{
"version": "2.0.0",
"tasks": [
{
"label": "Task 1",
"type": "shell",
"command": "dostuff1",
"args": ["-p", "${input:promptPath}"]
},
{
"label": "Task 2",
"type": "shell",
"command": "dostuff2",
"args": ["-p", "${input:rememberPath}"]
},
{
"label": "Do Task 1 and 2",
"dependsOrder": "sequence",
"dependsOn": ["Task 1", "Task 2"],
"problemMatcher": []
}
],
"inputs": [
{
"id": "promptPath",
"type": "command",
"command": "extension.commandvariable.promptStringRemember",
"args": {
"key": "path",
"description": "Enter a path"
}
},
{
"id": "rememberPath",
"type": "command",
"command": "extension.commandvariable.rememberPick",
"args": { "key": "path" }
}
]
}
Following #rioV8 answer, I edited my json files as shown below:
launch.json:
"configurations": [
{
...
"args": [${input:file_no}]
"preLanuchTask": "runPreTasks"
...
}
],
"inputs": [
{
"id": "file_no",
"type": "command",
"command": "extension.commandvariable.promptStringRemember",
"args": {
"key": "lastnumber",
"description": "Enter the number"
}
}
]
tasks.json:
{
"version": "2.0.0",
"tasks":[
{
"label": "runPreTasks",
"type": "shell",
"command": sh,
"args": [
"/path2script/scriptName.sh",
"${input:file_no}"
]
}
]
"inputs": [
{
"id": "file_no",
"type": "command",
"command": "extension.commandvariable.rememberPick",
"args": { "key": "lastnumber" }
}
]
}

Add a folder into a workspace by tasks in Visual Studio Code

Is there a way to add a folder into a workspace by tasks?
Is it possible to add and remove (or hide) folders in a workspace on selecting options from input in tasks.json?
{
"version": "2.0.0",
"inputs": [
{
"id": "selectProject",
"type": "pickString",
"description": "Some decription",
"options":
[
"PROJECT1",
"PROJECT2"
]
}
],
"tasks": [
{
"label": "add into workspace",
"type": "process",
"command": "command-to-add-folder-into-workspace", // what do I need to put here?
"args": [
"${input:selectProject}"
]
}
]
}
I've found a solution using code --add folder in tasks.
File .code-workspace
{
"folders": [
{
"name": "wp",
"path": "../wp" // folder has .code-workspace file
}
],
"settings": { /*...*/ },
"tasks": {
"inputs":[
{
"id": "selectProject",
"type": "pickString",
"description": "select project",
"options":
[
"PROJECT1",
"PROJECT2"
]
}
],
"version": "2.0.0",
"tasks": [
{
"label": "Add project",
"type": "shell",
"command": "code", // usind command code --add folder
"options": {
"cwd": "${workspaceFolder}"
},
"args": [
"--add",
"../${input:selectTest}"
],
"presentation": {
"echo": false,
"reveal": "always",
"clear": false,
"showReuseMessage": false
}
}
]
}
}

VSCode, Define custom variables to use in tasks, lauch and cpp properties

I am setting up VSCode for Embedded development with Nordic NRF52.
I have noticed that in the nrf_sdk there are examples for several boards and several soft devices.
I have seen that it is possible to reference env variables that have been previously defined both in tasks, launch and extension properties, such as: c_cpp, stm32-for-vscode. But what about having a section in the workspace file defined as my_vars so the workspace file looks like this?
{
"my_vars": {
"BOARD_NAME": "NRF52840_MDK_USB_DONGLE",
"MCU_NAME": "NRF52840",
"SOFT_DEVICE": "S140",
"BOARD_VARIANT_PATH": "/pca10059/mbr"
},
"launch": {
"version": "0.2.0",
"configurations": [
{
"name": "Cortex Debug",
"cwd": "${workspaceRoot}",
"executable": "${workspaceFolder}${my_vars:BOARD_VARIANT_PATH}/armgcc/_build/${my_vars:MCU_NAME}_xxaa.out",
"request": "launch",
"type": "cortex-debug",
"servertype": "jlink",
"device": "nrf52",
"interface": "swd",
"ipAddress": null,
"serialNumber": null,
"armToolchainPath": "${env:VSARM}/armcc/bin/"
},
]
},
"folders": [
{
"path": "."
}
],
"settings":{
// "C_Cpp.name": "nRF52840 DK",
"C_Cpp.default.includePath": [
"${workspaceFolder}/**",
"${env:GNU_GCC}/arm-none-eabi/include",
"${env:NRF_SDK}/modules/**",
"${env:NRF_SDK}/components/**"
],
"C_Cpp.default.defines": [
"${my_vars:BOARD_NAME}",
"CONFIG_GPIO_AS_PINRESET",
"INITIALIZE_USER_SECTIONS",
"FLOAT_ABI_HARD",
"NRF52",
"${my_vars:MCU_NAME}_XXAA",
"NRF_SD_BLE_API_VERSION=6",
"${my_vars:SOFT_DEVICE}",
"SOFTDEVICE_PRESENT",
"SWI_DISABLE0"
],
"C_Cpp.default.compilerPath": "${env:GNU_GCC}/bin/arm-none-eabi-gcc",
"C_Cpp.default.cStandard": "c11",
"C_Cpp.default.cppStandard": "c++17",
"C_Cpp.default.intelliSenseMode": "clang-x64"
},
"tasks": {
"version": "2.0.0",
// See https://go.microsoft.com/fwlink/?LinkId=733558
// for the documentation about the tasks.json format
"tasks": [
{
"label": "nRF52 build",
"type": "shell",
"command": "make",
"options": {
"cwd": "${workspaceFolder}${my_vars:BOARD_VARIANT_PATH}/armgcc"
},
"problemMatcher": [],
"group": {
"kind": "build",
"isDefault": true
}
},
{
"label": "nRF52 build clean",
"type": "shell",
"command": "make clean",
"options": {
"cwd": "${workspaceFolder}${my_vars:BOARD_VARIANT_PATH}/armgcc"
},
"problemMatcher": [],
"group": {
"kind": "build",
"isDefault": true
}
},
{
"label": "nRF52 flash",
"type": "shell",
"command": "make flash",
"options": {
"cwd": "${workspaceFolder}${my_vars:BOARD_VARIANT_PATH}/armgcc"
},
"group": {
"kind": "build",
"isDefault": true
},
"problemMatcher": []
},
{
"label": "nRF52 dfu upload",
"type": "shell",
"command": "make bootload",
"options": {
"cwd": "${workspaceFolder}${my_vars:BOARD_VARIANT_PATH}/armgcc"
},
"group": {
"kind": "build",
"isDefault": true
},
"problemMatcher": []
},
{
"label": "nRF52 flash_softdevice",
"type": "shell",
"command": "make flash_softdevice",
"options": {
"cwd": "${workspaceFolder}${my_vars:BOARD_VARIANT_PATH}/armgcc"
},
"problemMatcher": [],
"group": {
"kind": "build",
"isDefault": true
},
},
{
"label": "nRF52 sdk_config",
"type": "shell",
"command": "make sdk_config",
"options": {
"cwd": "${workspaceFolder}${my_vars:BOARD_VARIANT_PATH}/armgcc"
},
"problemMatcher": []
},
{
"label": "nRF52 erase",
"type": "shell",
"command": "make erase",
"options": {
"cwd": "${workspaceFolder}${my_vars:BOARD_VARIANT_PATH}/armgcc"
},
"problemMatcher": [],
"group": {
"kind": "build",
"isDefault": true
},
}
]
}
}
I tried having a task which is set_env, which in my case, since I am in Windows, run a batch script that does:
set BOARD_NAME=NRF52840_MDK_USB_DONGLE
set MCU_NAME=NRF52840
set SOFT_DEVICE=S140
set BOARD_VARIANT_PATH=/pca10059/mbr
This will ease a lot playing around with the SDK examples and could be potential work for a NRF52 VSCode extension, as https://marketplace.visualstudio.com/items?itemName=bmd.stm32-for-vscode does.
You've undoubtedly solved this problem by now, but hopefully I can save someone else some searching.
There is a top-level section called env that holds global variables that you can reference in your configs.
Here's an example from MSDN.
{
"env": {
"myDefaultIncludePath": ["${workspaceFolder}", "${workspaceFolder}/include"],
"myCompilerPath": "/usr/local/bin/gcc-7"
},
"configurations": [
{
"name": "Mac",
"intelliSenseMode": "clang-x64",
"includePath": ["${myDefaultIncludePath}", "/another/path"],
"macFrameworkPath": ["/System/Library/Frameworks"],
"defines": ["FOO", "BAR=100"],
"forcedInclude": ["${workspaceFolder}/include/config.h"],
"compilerPath": "/usr/bin/clang",
"cStandard": "c11",
"cppStandard": "c++17",
"compileCommands": "/path/to/compile_commands.json",
"browse": {
"path": ["${workspaceFolder}"],
"limitSymbolsToIncludedHeaders": true,
"databaseFilename": ""
}
}
],
"version": 4
}
Have a look at the extension Command Variable.
It can use the content of a file as key-value pairs.

How to create a "terminal configuration macro" in VS Code? Open and split multiple terminals easily

~400 times by year 1 :
open VS Code
open one terminal
divide the terminal into 2 parts
run "npm run hot" (first split)
leave the other split terminal empty
open a second terminal (with "+" button)
split it into 3 parts
run "php artisan websockets:serve" (first part)
run "php artisan queue:words" (second part)
run "maidev --ip=localhost" (third part)
and finally I can start to work
I'm sure I am not alone with this problem.
Would anyone have a method to optimize that with one command or configuration ?
Thanks for your help !
Use this setting:
"terminal.integrated.windowsEnableConpty": false // true is the default
In tasks.json:
{
"label": "Run 2 terminals from tasks",
"dependsOrder": "sequence", // or parallel
"dependsOn": [
"OpenTerminal1",
"RunInTerminal1",
"RenameTerminal1", // if you care to rename each terminal
"SplitTerminal1",
"OpenTerminal2",
"RunInTerminal2a",
"RenameTerminal2a", // if you care to rename each terminal
"SplitTerminal2",
"RunInTerminal2b",
"RenameTerminal2b", // if you care to rename each terminal
"SplitTerminal2",
"RunInTerminal2c",
"RenameTerminal2c", // if you care to rename each terminal
],
// "runOptions": { "runOn": "folderOpen" } // or trigger with keybinding
},
That is the "master" task which calls all the constituent tasks, which are:
{
"label": "OpenTerminal1",
"command": "${command:workbench.action.terminal.new}",
"type": "shell",
"problemMatcher": []
},
{
"label": "RunInTerminal1",
"command": "${input:runTerminal1}",
"type": "shell",
"problemMatcher": []
},
{
"label": "RenameTerminal1",
"command": "${input:renameTerminal1}",
"type": "shell",
"problemMatcher": []
},
{
"label": "SplitTerminal1",
"command": "${command:workbench.action.terminal.split}",
"type": "shell",
"problemMatcher": []
},
// ------------------------------------------------------------------
{
"label": "OpenTerminal2",
"command": "${command:workbench.action.terminal.new}",
"type": "shell",
"problemMatcher": []
},
{
"label": "RunInTerminal2a",
"command": "${input:runTerminal2a}",
"type": "shell",
"problemMatcher": []
},
{
"label": "RenameTerminal2a",
"command": "${input:renameTerminal2a}",
"type": "shell",
"problemMatcher": []
},
// ------------------------------------------------------------------
{
"label": "SplitTerminal2",
"command": "${command:workbench.action.terminal.split}",
"type": "shell",
"problemMatcher": []
},
{
"label": "RunInTerminal2b",
"command": "${input:runTerminal2b}",
"type": "shell",
"problemMatcher": []
},
{
"label": "RenameTerminal2b",
"command": "${input:renameTerminal2b}",
"type": "shell",
"problemMatcher": []
},
// ------------------------------------------------------------------
{
"label": "RunInTerminal2c",
"command": "${input:runTerminal2c}",
"type": "shell",
"problemMatcher": []
},
{
"label": "RenameTerminal2c",
"command": "${input:renameTerminal2c}",
"type": "shell",
"problemMatcher": []
},
You might think that is enough but you can see that task require args (what to send to the terminals) so that I had to use this form:
"command": "${input:runTerminal2c}",
so that that input can provide the needed arguments and commands. Those go into the inputs section of your tasks file like so:
"inputs": [
{
"id": "openTerminal1",
"type": "command",
"command": "workbench.action.terminal.new",
},
{
"id": "runTerminal1",
"type": "command",
"command": "workbench.action.terminal.sendSequence",
"args": {
"text": "npm run test\u000D"
}
},
{
"id": "renameTerminal1",
"type": "command",
"command": "workbench.action.terminal.renameWithArg",
"args": {
"name": "npm run hot"
}
},
{
"id": "openTerminal2",
"type": "command",
"command": "workbench.action.terminal.new",
},
{
"id": "runTerminal2a",
"type": "command",
"command": "workbench.action.terminal.sendSequence",
"args": {
"text": "php artisan websockets:serve"
}
},
{
"id": "renameTerminal2a",
"type": "command",
"command": "workbench.action.terminal.renameWithArg",
"args": {
"name": "websockets:serve"
}
},
{
"id": "runTerminal2b",
"type": "command",
"command": "workbench.action.terminal.sendSequence",
"args": {
"text": "php artisan queue:words"
}
},
{
"id": "renameTerminal2b",
"type": "command",
"command": "workbench.action.terminal.renameWithArg",
"args": {
"name": "queue:words"
}
},
{
"id": "runTerminal2c",
"type": "command",
"command": "workbench.action.terminal.sendSequence",
"args": {
"text": "maidev"
}
},
{
"id": "renameTerminal2c",
"type": "command",
"command": "workbench.action.terminal.renameWithArg",
"args": {
"name": "maidev"
}
}
Again maybe you don't care about all the renaming the terminal commands and can eliminate those. Here, I just sent your command to the terminal:
{
"id": "runTerminal2c",
"type": "command",
"command": "workbench.action.terminal.sendSequence",
"args": {
"text": "maidev"
}
},
but did not automatically start them. To have them start immediately, add the return unicode to the text that is sent to the terminal like:
{
"id": "runTerminal2c",
"type": "command",
"command": "workbench.action.terminal.sendSequence",
"args": {
"text": "maidev --ip=localhost"
}
},
And finally a keybinding to trigger the master task (if you don't use the run on folder open option):
{
"key": "alt+z",
"command": "workbench.action.tasks.runTask",
"args": "Run 2 terminals from tasks"
},
I prefer the macro version - it is much shorter and less prone to set-up error. Both are very fast.
Okay, a day after answering this with other two answers, I saw this extension: Restore Terminals at this other question https://stackoverflow.com/a/62595681/836330
This extension seems to work quite well. Put this into your settings.json:
"restoreTerminals.runOnStartup": false, // true is the default
// set to false if using a keybinding or the command palette
"restoreTerminals.terminals": [
{
"splitTerminals": [
{
"name": "server",
"commands": [
"npm run test"
]
},
{
"name": "empty",
}
]
},
{
"splitTerminals": [
{
"name": "websockets",
"commands": [
"ls -l"
]
},
{
"name": "queue",
"commands": [
"cd zip",
"gulp sass"
]
},
{
"name": "maidev",
"commands": [
"cd zip-multiple",
"gulp"
]
}
]
}
],
And a keybinding:
{
"key": "shift+alt+t", // whatever keybinding if you wish
"command": "restore-terminals.restoreTerminals",
},
If on Windows, I would still use the setting:
"terminal.integrated.windowsEnableConpty": false
as the same issue occurs when using this extension as any other method to open and write to terminals quickly - if you then try to close the terminals vscode will hang and eventually timeout and need to be reopened.
I'll make this two answers as one version is particularly long. One answer uses a macro extension to help solve this and the other uses only tasks.
For both solutions, use this setting:
"terminal.integrated.windowsEnableConpty": false // true is the default
There is a nasty unsolved bug affecting Winpty and vscode when you try to delete a terminal opened by these methods.
Using the macro extension multi-command. This goes into your tasks.json:
{
"label": "Run 2 terminals with macro",
"dependsOrder": "sequence", // or parallel
"dependsOn": [
"terminal1",
"terminal2"
],
// "runOptions": { "runOn": "folderOpen" }
},
{
"label": "terminal1",
"command": "${command:multiCommand.startFirstTerminal}"
},
{
"label": "terminal2",
"command": "${command:multiCommand.startSecondTerminal}"
},
The two tasks are run by the macro. This goes into your settings.json:
"multiCommand.commands": [
{
"command": "multiCommand.startFirstTerminal",
"sequence": [
"workbench.action.terminal.newInActiveWorkspace",
{
"command": "workbench.action.terminal.sendSequence",
"args": {
"text": "npm run test\u000D"
}
},
{
"command": "workbench.action.terminal.renameWithArg",
"args": {
"name": "npm run hot"
}
},
"workbench.action.terminal.split",
]
},
{
"command": "multiCommand.startSecondTerminal",
"sequence": [
"workbench.action.terminal.newInActiveWorkspace",
{
"command": "workbench.action.terminal.renameWithArg",
"args": {
"name": "websockets:serve"
}
},
{
"command": "workbench.action.terminal.sendSequence",
"args": {
"text": "ls -lrt\u000D"
}
},
"workbench.action.terminal.split",
{
"command": "workbench.action.terminal.renameWithArg",
"args": {
"name": "queue:words"
}
},
{
"command": "workbench.action.terminal.sendSequence",
"args": {
"text": "ls -lrt\u000D"
}
},
"workbench.action.terminal.split",
{
"command": "workbench.action.terminal.renameWithArg",
"args": {
"name": "maidev"
}
},
{
"command": "workbench.action.terminal.sendSequence",
"args": {
"text": "ls -lrt\u000D"
}
},
]
}
]
I renamed the terminals to match your commands - perhaps you don't care about that and can eliminate the renameWithArg sections to shorten the whole thing.
I couldn't test with your php setup, so I substituted ls -lrt\u000D running in each terminal. Just substitute your
{
"command": "workbench.action.terminal.sendSequence",
"args": {
"text": "php artisan websockets:serve\u000D"
}
},
for example. The \u000D is a return so the command runs immediately. Now you can either use the "runOptions": { "runOn": "folderOpen" } option so the master task runs when the workspace opens or assign a keybinding to the master task like
{
"key": "alt+z", // or watever you want
"command": "workbench.action.tasks.runTask",
"args": "Run 2 terminals with macro"
},