| name | vscode-commands-and-activation |
| description | Guidance for implementing and modifying VS Code commands, menus, when clauses, and activation behavior. |
Skill: Commands and Extension Activation
Overview
Commands are the primary action mechanism in VS Code. Understanding how to register, invoke,
and control the visibility of commands — and how activation events relate to them — is essential
for every extension.
Registering Commands
import * as vscode from 'vscode';
export function activate(context: vscode.ExtensionContext): void {
context.subscriptions.push(
vscode.commands.registerCommand('ext.myCommand', () => {
vscode.window.showInformationMessage('Hello from myCommand!');
})
);
context.subscriptions.push(
vscode.commands.registerCommand('ext.openFile', (uri?: vscode.Uri) => {
const target = uri ?? vscode.window.activeTextEditor?.document.uri;
if (!target) { return; }
})
);
context.subscriptions.push(
vscode.commands.registerTextEditorCommand('ext.formatSelection', (editor, edit) => {
edit.replace(editor.selection, transform(editor.document.getText(editor.selection)));
})
);
}
Executing Commands Programmatically
await vscode.commands.executeCommand('workbench.action.reloadWindow');
await vscode.commands.executeCommand('vscode.open', vscode.Uri.file('/path/to/file'));
const items = await vscode.commands.executeCommand<vscode.SymbolInformation[]>(
'vscode.executeDocumentSymbolProvider',
document.uri
);
Command Palette Visibility
To hide a command from the Command Palette (useful for internal/programmatic commands):
"menus": {
"commandPalette": [
{ "command": "ext.internalCommand", "when": "false" }
]
}
To show a command only in specific contexts:
"commandPalette": [
{ "command": "ext.fxmlCommand", "when": "resourceLangId == fxml" }
]
Activation Events
Best Practices
onLanguage:<id> — Activate when a file of a language is opened. Most common for language feature extensions.
onCommand:<id> — Activate when a specific command is about to run. Useful if the extension does not need to be active before the command is invoked.
workspaceContains:<glob> — Activate when the workspace contains matching files (e.g., "workspaceContains:**/pom.xml").
onStartupFinished — Activate shortly after VS Code starts, without blocking startup. Use for lightweight background tasks.
* — Avoid; activates on every VS Code window open.
"activationEvents": [
"onLanguage:fxml",
"onLanguage:java"
]
VS Code 1.74+: onCommand: events for commands declared in contributes.commands are
automatically inferred — you no longer need to list them explicitly.
Context Keys and when Clauses
Set a custom context key to control command/menu visibility dynamically:
await vscode.commands.executeCommand('setContext', 'ext.myFeatureEnabled', true);
Use it in package.json:
"menus": {
"editor/title": [
{
"command": "ext.myCommand",
"when": "ext.myFeatureEnabled && resourceLangId == fxml"
}
]
}
Progress and Long-Running Commands
await vscode.window.withProgress(
{
location: vscode.ProgressLocation.Notification,
title: 'Processing…',
cancellable: true,
},
async (progress, token) => {
progress.report({ message: 'Step 1', increment: 30 });
if (token.isCancellationRequested) { return; }
await doExpensiveWork();
progress.report({ message: 'Done', increment: 70 });
}
);
Input from Users
const choice = await vscode.window.showQuickPick(['Option A', 'Option B'], {
placeHolder: 'Choose an option',
});
const input = await vscode.window.showInputBox({
prompt: 'Enter the Scene Builder path',
validateInput: (value) => value ? undefined : 'Path cannot be empty',
});
const uris = await vscode.window.showOpenDialog({
canSelectFiles: true,
canSelectMany: false,
filters: { Executables: ['exe', 'app', ''] },
});
Error Handling in Commands
vscode.commands.registerCommand('ext.myCommand', async () => {
try {
await doWork();
} catch (err) {
const message = err instanceof Error ? err.message : String(err);
vscode.window.showErrorMessage(`MyExtension: ${message}`);
}
});
Checklist for New Commands
References