Reputation: 950
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 ?
Upvotes: 2
Views: 3249
Reputation: 1316
This rough approach avoids the use of either a custom or external extension. The only presumption is that Python is already installed on the system. Using the python module json (assuming there are no comments in your task.json
), a "pre-task" is made to modify the options key within the list for the inputs key in task.json
. In this example, the "main task" will use echo in the terminal to say "Hi" to a chosen user from the updated input options after the "pre-task" runs. A directory has a set of folders that follow a naming scheme USER_[insert_username]:
.vscode/
├─ task.json
USER_CindycinErean
USER_Link/
USER_Mario/
USER_Ness/
USER_ShihTzu/
With python, the "pre-task" will scan the directory that matches this schema and update the options key as a list within inputs. The block below is how the code normally looks in a typical python script:
import json, os
base_folder = os.getcwd()
list_of_users = [f.name.split('_')[1] for f in os.scandir(base_folder) if (f.is_dir() and 'USER' in f.name)]
path = base_folder + r'\\.vscode\\tasks.json'
path = r'{}'.format(path)
j = open(path, 'r');ex = json.load(j)
j.close()
j = open(path, 'w');ex['inputs'][0]['options'] = list_of_users
ex['inputs'][0]['default'] = list_of_users[0]
json.dump(ex,j, indent=4);j.close()
And here is the code in a single line:
import json, os;base_folder = os.getcwd();list_of_users = [f.name.split('_')[1] for f in os.scandir(base_folder) if (f.is_dir() and 'USER' in f.name)];path = base_folder + r'\\.vscode\\tasks.json';path = r'{}'.format(path);j = open(path, 'r');ex = json.load(j);j.close();j = open(path, 'w');ex['inputs'][0]['options'] = list_of_users;ex['inputs'][0]['default'] = list_of_users[0];json.dump(ex,j, indent=4);j.close()
The "pre-task" is created using the single line code after double quotes have been escaped and the Python command argument (-c) has been used.
"command": "python3 -c \"import json, os;base_folder = os.getcwd();list_of_users = [f.name.split('_')[1] for f in os.scandir(base_folder) if (f.is_dir() and 'USER' in f.name)];path = base_folder + r'\\.vscode\\tasks.json';path = r'{}'.format(path);j = open(path, 'r');ex = json.load(j);j.close();j = open(path, 'w');ex['inputs'][0]['options'] = list_of_users;ex['inputs'][0]['default'] = list_of_users[0];json.dump(ex,j, indent=4);j.close()\""
Now with that defined, here is the before state of task.json
for Windows, OSX, and Linux:
{
"version": "2.0.0",
"tasks": [
{
"label": "Say Hi to selected user",
"type": "shell",
"dependsOn":["Update for User Selection"],
"command": "echo Hi ${input:userSelect} !!!",
"problemMatcher": []
},
{
"label": "Update for User Selection",
"type": "shell",
"linux": {
"options": {
"cwd": "${workspaceFolder}"
},
"command": "python3 -c \"import json, os;base_folder = os.getcwd();list_of_users = [f.name.split('_')[1] for f in os.scandir(base_folder) if (f.is_dir() and 'USER' in f.name)];path = base_folder + r'\\.vscode\\tasks.json';path = r'{}'.format(path);j = open(path, 'r');ex = json.load(j);j.close();j = open(path, 'w');ex['inputs'][0]['options'] = list_of_users;ex['inputs'][0]['default'] = list_of_users[0];json.dump(ex,j, indent=4);j.close()\""
},
"osx": {
"options": {
"cwd": "${workspaceFolder}"
},
"command": "python3 -c \"import json, os;base_folder = os.getcwd();list_of_users = [f.name.split('_')[1] for f in os.scandir(base_folder) if (f.is_dir() and 'USER' in f.name)];path = base_folder + r'\\.vscode\\tasks.json';path = r'{}'.format(path);j = open(path, 'r');ex = json.load(j);j.close();j = open(path, 'w');ex['inputs'][0]['options'] = list_of_users;ex['inputs'][0]['default'] = list_of_users[0];json.dump(ex,j, indent=4);j.close()\""
},
"windows": {
"options": {
"shell": {
"executable": "C:\\Windows\\system32\\cmd.exe",
"args": [
"/d",
"/c"
]
},
"cwd": "${workspaceFolder}"
},
"command": "python -c \"import json, os;base_folder = os.getcwd();list_of_users = [f.name.split('_')[1] for f in os.scandir(base_folder) if (f.is_dir() and 'USER' in f.name)];path = base_folder + r'\\.vscode\\tasks.json';path = r'{}'.format(path);j = open(path, 'r');ex = json.load(j);j.close();j = open(path, 'w');ex['inputs'][0]['options'] = list_of_users;ex['inputs'][0]['default'] = list_of_users[0];json.dump(ex,j, indent=4);j.close()\""
},
"problemMatcher": []
}
],
"inputs": [
{
"type": "pickString",
"id": "userSelect",
"description": "Choose a user from the directory to say Hi to!",
"options": [
"UserA",
"UserB",
"UserC",
"UserD"
],
"default": "UserA"
}
]
}
And this is the after state:
{
"version": "2.0.0",
"tasks": [
{
"label": "Say Hi to selected user",
"type": "shell",
"dependsOn": [
"Update for User Selection"
],
"command": "echo Hi ${input:userSelect} !!!",
"problemMatcher": []
},
{
"label": "Update for User Selection",
"type": "shell",
"linux": {
"options": {
"cwd": "${workspaceFolder}"
},
"command": "python3 -c \"import json, os;base_folder = os.getcwd();list_of_users = [f.name.split('_')[1] for f in os.scandir(base_folder) if (f.is_dir() and 'USER' in f.name)];path = base_folder + r'\\.vscode\\tasks.json';path = r'{}'.format(path);j = open(path, 'r');ex = json.load(j);j.close();j = open(path, 'w');ex['inputs'][0]['options'] = list_of_users;ex['inputs'][0]['default'] = list_of_users[0];json.dump(ex,j, indent=4);j.close()\""
},
"osx": {
"options": {
"cwd": "${workspaceFolder}"
},
"command": "python3 -c \"import json, os;base_folder = os.getcwd();list_of_users = [f.name.split('_')[1] for f in os.scandir(base_folder) if (f.is_dir() and 'USER' in f.name)];path = base_folder + r'\\.vscode\\tasks.json';path = r'{}'.format(path);j = open(path, 'r');ex = json.load(j);j.close();j = open(path, 'w');ex['inputs'][0]['options'] = list_of_users;ex['inputs'][0]['default'] = list_of_users[0];json.dump(ex,j, indent=4);j.close()\""
},
"windows": {
"options": {
"shell": {
"executable": "C:\\Windows\\system32\\cmd.exe",
"args": [
"/d",
"/c"
]
},
"cwd": "${workspaceFolder}"
},
"command": "python -c \"import json, os;base_folder = os.getcwd();list_of_users = [f.name.split('_')[1] for f in os.scandir(base_folder) if (f.is_dir() and 'USER' in f.name)];path = base_folder + r'\\.vscode\\tasks.json';path = r'{}'.format(path);j = open(path, 'r');ex = json.load(j);j.close();j = open(path, 'w');ex['inputs'][0]['options'] = list_of_users;ex['inputs'][0]['default'] = list_of_users[0];json.dump(ex,j, indent=4);j.close()\""
},
"problemMatcher": []
}
],
"inputs": [
{
"type": "pickString",
"id": "userSelect",
"description": "Choose a user from the directory to say Hi to!",
"options": [
"CindycinErean",
"Link",
"Mario",
"Ness",
"ShihTzu"
],
"default": "CindycinErean"
}
]
}
Below is a demonstration of the task Update for User Selection being executed with the user Mario selected after changes to the task.json
:
Upvotes: 2
Reputation: 28763
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.
Upvotes: 3