Search code examples
visual-studio-codemenuvscode-extensions

Why doesn't my when clause in a VS Code extension work?


In my extension I want to programmatically set the visibility of a command in the Command Palette of VS Code.

Following the VS Code documentation and some examples, my extension looks like this (redacted):


package.json

    "contributes": {
        "commands": [
            {
                "command": "gitHome.goHome",
                "title": "Open repository's origin URL",
                "category": "Git Home"
            }
        ]
    },
    "menus": {
        "commandPalette": [
            {
                "command": "gitHome.goHome",
                "when": "gitHome.isGit"
            }
        ]
    }

and

extension.mts

export async function activate(context: vscode.ExtensionContext) {
  const cwd: string = getCwd()

  const cmdGoHome: vscode.Disposable = vscode.commands.registerCommand(
    'gitHome.goHome',
    () => goHome(cwd)
  )
  context.subscriptions.push(cmdGoHome)

  await vscode.commands.executeCommand('setContext', 'gitHome.isGit', false)

  // more functionality-related code below
}

Tried moving vscode.commands.executeCommand('setContext', 'gitHome.isGit', false) to the top of the activate() method and out of it, using await and not using it, etc.

My command is always visible in the Command Palette, upon inspecting Context keys I saw that gitHome.isGit was indeed set to false.


Solution

  • I don't see anything wrong with your code but try adding the enablement option to your command:

    {
      "command": "gitHome.goHome",
      "title": "Open repository's origin URL",
      "category": "Git Home",
      "enablement": "gitHome.isGit"
    }
    

    Command enablement is broader than a menu when clause. From api: contribute menus

    Note that when clauses apply to menus and enablement clauses to commands. The enablement applies to all menus and even keybindings while the when only applies to a single menu.

    So, using the enablement clause will prevent the command from being shown in the Command Palette and from being triggered by a keybinding. So assuming you are good with both enablement is the way to go.