Is there a way to get a pickString dynamically populated in a VS Code task?
Asked Answered
C

4

22

I'd like to provide a list of strings as a pickString for a task. The list of strings will be a list of folder names, which I can get from PowerShell, but I'm not sure how to display this list in a task.

How can I set up my task and input so this list can be populated?

{
  "version": "2.0.0", 
  "tasks": [
    {
      "label": "Test Task", 
      "type":  "shell", 
      "windows": {
        "command":  "echo",
          "args": [
            "-opt",
            "${input:optionsList}"
          ]
      }
    }
  ], 
  "inputs": [
    "id": "optionsList", 
    "type": "pickString", 
    "options": [<insert something here>]
  ]
}

I want the user to see the list of folders while the task is running.

Conias answered 17/9, 2019 at 15:47 Comment(2)
Did you find an answer for this?Sloop
An enhancement request for this feature in VSCode has been requested. github.com/microsoft/vscode/issues/109789 Please do vote for this feature through the above link. If there is more than 20 votes, then this feature would get implemented in VSCode.Sloop
C
7

Task/Launch Input Variables shows a way to do this with a command input variable. That command can come from vscode's built-in commands or from an extension. In your case, there is no built-in command which returns a list of folders in a given workspace. But it is fairly straightforward to do it in an extension. The documentation does not give a full example of how to do this so I'll show one here. First the demo of it working to ls a chosen folder in a task:

Using an extension command to populate a pickString variable.

Here is the entire tasks.json file:


    {
      "version": "2.0.0",
      "tasks": [
    
        {
          "label": "List Folder Choice files",
          "type": "shell",
          "command": "ls",            // your command here
          "args": [
            "${input:pickTestDemo}"  // wait for the input by "id" below
          ],
          "problemMatcher": []
        }
      ],
      
      "inputs": [
        {
          "id": "pickTestDemo",
          "type": "command",
          "command": "folder-operations.getFoldersInWorkspace"  // returns a QuickPick element
        },
      ]
    } 

You can see in the input variables that a command is called from the folder-operations extension. Since that command returns a QuickPick element that is what you'll see when you run the task.

Here is the guts of the extension:

    const vscode = require('vscode');
    const fs = require('fs');
    const path = require('path');
    
    /**
     * @param {vscode.ExtensionContext} context
     */
    function activate(context) {
    
        let disposable = vscode.commands.registerCommand('folder-operations.getFoldersInWorkspace', async function () {
    
        // get the workspaceFolder of the current file, check if multiple workspaceFolders
        // a file must be opened
        const wsFolders = await vscode.workspace.workspaceFolders;
        if (!wsFolders)  vscode.window.showErrorMessage('There is no workspacefolder open.')
        const currentWorkSpace = await vscode.workspace.getWorkspaceFolder(vscode.window.activeTextEditor.document.uri);
    
        // filter out files, keep folder names.  Returns an array of string.
        // no attempt made here to handle symbolic links for example - look at lstatSync if necessary
    
        const allFilesFolders = fs.readdirSync(currentWorkSpace.uri.fsPath);
        const onlyFolders = allFilesFolders.filter(f => fs.statSync(path.join(currentWorkSpace.uri.fsPath, f)).isDirectory());
    
        // showQuickPick() takes an array of strings
        return vscode.window.showQuickPick(onlyFolders);
        });
    
        context.subscriptions.push(disposable);
    }
    
    exports.activate = activate;
    
    // this method is called when your extension is deactivated
    function deactivate() {}
    
    module.exports = {
        activate,
        deactivate
    }

Here is a link to the folder-operations demo extension so you can look at the full extension code and its package.json. Once you get your extension publishing credentials set up it is really pretty easy to publish more.

Chaussure answered 1/11, 2020 at 21:46 Comment(1)
but but but... when you add a new terminal in the console, it gives you exactly this list; so where's the commandCulminate
D
7

Problem

Actually VSCode tasks doesn't have this functionality built-in. The enhancement request was closed probably because there is no plans to develop it in the near future.

Alternative Solution

You can install the augustocdias.tasks-shell-input and configure an input variable with type command calling this extension for populating the pick list.

Follow the following steps:

  1. Install the extension with:
    1. Search in the Extensions Sidebar (Ctrl+Shift+X) for augustocdias.tasks-shell-input and install or
    2. Launch VS Code Quick Open (Ctrl+P), paste the following command, and press enter:
    • ext install augustocdias.tasks-shell-input
  2. Configure your task.json with:
    1. A task with the command you want to execute
    2. Add to the task args configuration entry one or more references to input variables like ${input:my_variable}.
    3. Configure an entry in the inputs section with:
      • id: use the same variable name defined in task args like my_variable for ${input:my_variable}
      • type: command
      • command: shellCommand.execute
      • args: add an config with the properties: command, cwd, env
  3. See the example task.json file bellow.

Example

Example task.json file using augustocdias.tasks-shell-input extension:

{
    "version": "2.0.0",
    "tasks": [
        {
            "label": "Dynamically Populated Task",
            "type": "shell",
            "command": "echo",
            "args": [
                "'${input:my_dynamic_input_variable}'"
            ],
            "problemMatcher": []
        }
    ],
    "inputs": [
        {
            "id": "my_dynamic_input_variable",
            "type": "command",
            "command": "shellCommand.execute",
            "args": {
                "command": "ls -1 *.*",
                "cwd": "${workspaceFolder}",
                "env": {
                    "WORKSPACE": "${workspaceFolder[0]}",
                    "FILE": "${file}",
                    "PROJECT": "${workspaceFolderBasename}"
                }
            },
        }
    ]
}

Dubitable answered 24/11, 2020 at 16:33 Comment(0)
C
0

Short of installing an extension or writing your own, you should first determine your workspace folder structure.

You could have

  1. Single-root workspace (workspace=folder)
  2. Multi-root workspace with main folder (workspace=folder)
  3. Multi-root workspace with no main folder (workspace=folder/../)

There are built-in vars that allow you to access, for example

  • folder path (=workspace if 1,2,3) ${workspaceFolder}
  • current file path relative to ${workspaceFolder} ${relativeFileDirname}

Say you want to run git gui for the repo of the current open file - with "cwd" : "${relativeFileDirname}" in tasks.json config, git should pick up the current repo, and you don't need to ask for the folder path.

Culminate answered 12/11, 2021 at 8:40 Comment(0)
G
0

I had a similar issue with a custom task. I wanted to make use of the extension idea from @Mark and created one that could be applied more generally. Populate-quickpick creates options from a list provided via a text file. I am using it as a simple input for python scripts that receive the chosen option as an argument.

This is how it can be used:

    "tasks": {
        "version": "2.0.0",
        "tasks": [
            {
                "label": "My Task",
                "type": "shell",
                "command": "echo", // your command here
                "args": [
                    "${input:pickDemo}"
                ],
                "problemMatcher": []
            }
        ],
        "inputs": [
            {
                "id": "pickDemo",
                "type": "command",
                "command": "populate-quickpick.quickPickFromFile"
            }
        ]
Gravity answered 6/6, 2023 at 17:1 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.