skip to Main Content

I’m using a VSCode multi-root workspace. I want to define some tasks in myprojects.code-workspace using a variable for the root directory.

In a regular .vscode/tasks.json I could use ${workspaceFolder}.

However when I create this simple task in .project.code-workspace:

{
  "label":   "foo",
  "type":    "shell",
  "command": "echo ${workspaceFolder}"
}

…it prints the first workspace path:

/home/username/myprojects/project1

instead of:

/home/username/myprojects

So the ${workspaceFolder} variable is obviously unsuitable.

Is there a variable that refers to the multiroot workspace’s root?


UPDATE

To address the "why do you want that" query. It’s a very common developer setup: similar to a monorepo as all projects are open simultaneously (for convenience), but not really a monorepo:

myprojects/           # multi-root workspace's root
  .code-workspace     # has tasks which target all projects (so needs multiroot's root directory)
  project1/
    .git/
    src/
  project2/
    .git/
    src/
  project3/
    .git/
    src/

2

Answers


  1. Chosen as BEST ANSWER

    I don't think this is currently possible - variables defined here lack a suitable option.

    If you need this functionality, please upvote this issue on the repo, and add your use case!

    In the meantime, one could use a workaround:

    {
      "label":   "foo",
      "type":    "shell",
      "command": "echo $(dirname ${workspaceFolder})"
    }
    

  2. If the location of the .code-workspace file is always 1 up of the workspaces it refers to you can use an extension I wrote: Command Variable

    {
      "version": "2.0.0",
      "tasks": [
        {
          "label":   "foo",
          "type":    "shell",
          "command": "echo ${input:codeWorkspaceDir}"
        }
      ],
      "inputs": [
        {
          "id": "codeWorkspaceDir",
          "type": "command",
          "command": "extension.commandvariable.workspace.folder1Up"
        }
      ]
    }
    

    This works if the current open file is in one of the workspaces.


    If you have a task that should also work when you have no files open you can use

    {
      "version": "2.0.0",
      "tasks": [
        {
          "label":   "foo",
          "type":    "shell",
          "command": "echo ${input:codeWorkspaceDir}"
        }
      ],
      "inputs": [
        {
          "id": "codeWorkspaceDir",
          "type": "command",
          "command": "extension.commandvariable.transform",
          "args": {
            "text": "${workspaceFolder:NAME}",
            "find": "${pathSeparator}\w+$",
            "replace": ""
          }
        }
      ]
    }
    

    You have to fill in a NAME of one of the workspaces.

    What it does is remove the last part of the directory of the text for ${workspaceFolder:NAME}. Depending on the kind of workspace names you have to modify the regular expression or you can hard code the folder name.

    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search