Skip to main content

Commands API

The Commands API allows you to register and execute commands in VS Code. Commands are functions with unique identifiers that can be invoked from the Command Palette, keyboard shortcuts, menus, or programmatically.

Namespace

vscode.commands
All command-related functionality is available through the commands namespace.

Core Functions

registerCommand

Register a command that can be invoked via keyboard shortcuts, menu items, or directly.
function registerCommand(
    command: string,
    callback: (...args: any[]) => any,
    thisArg?: any
): Disposable
command
string
required
A unique identifier for the command
callback
function
required
The command handler function that will be executed
thisArg
any
The this context used when invoking the handler
return
Disposable
Disposable that unregisters the command when disposed

Example

import * as vscode from 'vscode';

export function activate(context: vscode.ExtensionContext) {
    // Register a simple command
    let disposable = vscode.commands.registerCommand('extension.sayHello', () => {
        vscode.window.showInformationMessage('Hello World!');
    });
    
    context.subscriptions.push(disposable);
    
    // Register command with arguments
    let greetCommand = vscode.commands.registerCommand(
        'extension.greet',
        (name: string) => {
            vscode.window.showInformationMessage(`Hello, ${name}!`);
        }
    );
    
    context.subscriptions.push(greetCommand);
}
Registering a command with an existing identifier will cause an error. Ensure your command IDs are unique.

registerTextEditorCommand

Register a text editor command that executes only when an active editor is present.
function registerTextEditorCommand(
    command: string,
    callback: (textEditor: TextEditor, edit: TextEditorEdit, ...args: any[]) => void,
    thisArg?: any
): Disposable
command
string
required
Unique identifier for the command
callback
function
required
Handler with access to the active TextEditor and TextEditorEdit builder
thisArg
any
The this context for the handler

Example

const command = vscode.commands.registerTextEditorCommand(
    'extension.transformText',
    (textEditor: vscode.TextEditor, edit: vscode.TextEditorEdit) => {
        const document = textEditor.document;
        const selection = textEditor.selection;
        
        // Get selected text
        const text = document.getText(selection);
        
        // Transform and replace
        edit.replace(selection, text.toUpperCase());
    }
);

context.subscriptions.push(command);
The edit builder is only valid during callback execution. Changes are applied atomically when the callback completes.

executeCommand

Execute a command programmatically.
function executeCommand<T = unknown>(
    command: string,
    ...rest: any[]
): Thenable<T>
command
string
required
Identifier of the command to execute
rest
any[]
Parameters passed to the command handler
return
Thenable<T>
A thenable that resolves to the command’s return value

Example

// Execute a built-in command
await vscode.commands.executeCommand('workbench.action.files.save');

// Execute your own command with arguments
const result = await vscode.commands.executeCommand(
    'extension.calculate',
    10,
    20
);
console.log('Result:', result);

// Open a file
await vscode.commands.executeCommand(
    'vscode.open',
    vscode.Uri.file('/path/to/file.txt')
);
// Only primitive types are allowed for built-in commands
await vscode.commands.executeCommand(
    'editor.action.insertSnippet',
    { snippet: 'console.log($1);' }
);

getCommands

Retrieve the list of all available commands.
function getCommands(filterInternal?: boolean): Thenable<string[]>
filterInternal
boolean
default:"false"
Set to true to exclude internal commands (those starting with underscore)
return
Thenable<string[]>
List of command identifiers

Example

// Get all commands including internal
const allCommands = await vscode.commands.getCommands();
console.log(`Total commands: ${allCommands.length}`);

// Get only public commands
const publicCommands = await vscode.commands.getCommands(true);
const extensionCommands = publicCommands.filter(cmd => 
    cmd.startsWith('extension.')
);
console.log('Extension commands:', extensionCommands);

Command Interface

Commands are referenced using the Command interface:
interface Command {
    title: string;
    command: string;
    tooltip?: string;
    arguments?: any[];
}
title
string
required
Human-readable title displayed in the UI
command
string
required
The identifier of the command handler
tooltip
string
Optional tooltip shown when hovering over the command
arguments
any[]
Arguments passed to the command handler when invoked

Usage Example

// In a CodeLens
const codeLens = new vscode.CodeLens(range, {
    title: 'Run Test',
    command: 'extension.runTest',
    arguments: [testId, testFile]
});

// In a tree item
const treeItem = new vscode.TreeItem('Item');
treeItem.command = {
    title: 'Open File',
    command: 'vscode.open',
    arguments: [uri]
};

Package.json Contributions

Declare commands in your package.json to make them available in the Command Palette:
package.json
{
  "contributes": {
    "commands": [
      {
        "command": "extension.helloWorld",
        "title": "Hello World",
        "category": "My Extension",
        "icon": "$(rocket)"
      },
      {
        "command": "extension.openSettings",
        "title": "Open Settings",
        "category": "My Extension",
        "enablement": "workspaceFolderCount > 0"
      }
    ],
    "keybindings": [
      {
        "command": "extension.helloWorld",
        "key": "ctrl+shift+h",
        "mac": "cmd+shift+h",
        "when": "editorTextFocus"
      }
    ],
    "menus": {
      "editor/context": [
        {
          "command": "extension.transform",
          "when": "editorHasSelection",
          "group": "1_modification"
        }
      ]
    }
  }
}

Built-in Commands

VS Code provides many built-in commands you can execute:
// Save the active file
await vscode.commands.executeCommand('workbench.action.files.save');

// Format document
await vscode.commands.executeCommand('editor.action.formatDocument');

// Toggle sidebar
await vscode.commands.executeCommand('workbench.action.toggleSidebarVisibility');

Advanced Patterns

Conditional Command Registration

if (someCondition) {
    const disposable = vscode.commands.registerCommand(
        'extension.conditionalCommand',
        () => {
            // Command implementation
        }
    );
    context.subscriptions.push(disposable);
}

Command Chaining

vscode.commands.registerCommand('extension.workflow', async () => {
    // Execute multiple commands in sequence
    await vscode.commands.executeCommand('workbench.action.files.save');
    await vscode.commands.executeCommand('editor.action.formatDocument');
    await vscode.commands.executeCommand('workbench.action.files.saveAll');
    
    vscode.window.showInformationMessage('Workflow completed!');
});

Error Handling

vscode.commands.registerCommand('extension.safeCommand', async () => {
    try {
        const result = await vscode.commands.executeCommand('some.command');
        return result;
    } catch (error) {
        vscode.window.showErrorMessage(`Command failed: ${error.message}`);
        return null;
    }
});

Best Practices

  • Use a consistent prefix (e.g., myExtension.commandName)
  • Choose descriptive, action-oriented names
  • Avoid generic names that might conflict
  • Document all public commands
  • Keep command handlers lightweight
  • Use async/await for long-running operations
  • Show progress indicators for slow operations
  • Don’t block the UI thread
  • Provide clear feedback when commands execute
  • Handle errors gracefully with user-friendly messages
  • Support undo/redo when modifying text
  • Use appropriate keyboard shortcuts

Common Use Cases

Transform Selected Text

vscode.commands.registerTextEditorCommand(
    'extension.uppercase',
    (editor, edit) => {
        const selections = editor.selections;
        
        for (const selection of selections) {
            const text = editor.document.getText(selection);
            edit.replace(selection, text.toUpperCase());
        }
    }
);

Open External URL

vscode.commands.registerCommand('extension.openDocs', () => {
    vscode.env.openExternal(
        vscode.Uri.parse('https://example.com/docs')
    );
});

Create New File with Content

vscode.commands.registerCommand('extension.newTemplate', async () => {
    const doc = await vscode.workspace.openTextDocument({
        content: '// Template\n',
        language: 'javascript'
    });
    await vscode.window.showTextDocument(doc);
});