Skip to content

Commands API

Commands APIを使用すると、Trae IDEでカスタムコマンドの登録、既存コマンドの実行、キーボードショートカットの管理ができます。

概要

Commands APIでは以下のことができます:

  • カスタムコマンドの登録
  • 組み込みコマンドとカスタムコマンドの実行
  • コマンドパラメータの処理
  • キーボードショートカットの作成
  • コマンドライフサイクルの管理

基本的な使用方法

コマンドの登録

typescript
import { TraeAPI } from '@trae/api';

// シンプルなコマンドを登録
const disposable = TraeAPI.commands.registerCommand('myExtension.helloWorld', () => {
  TraeAPI.window.showInformationMessage('Hello World!');
});

// パラメータ付きコマンドを登録
TraeAPI.commands.registerCommand('myExtension.greet', (name: string) => {
  TraeAPI.window.showInformationMessage(`Hello, ${name}!`);
});

// 非同期コマンドを登録
TraeAPI.commands.registerCommand('myExtension.asyncOperation', async () => {
  try {
    const result = await performAsyncOperation();
    TraeAPI.window.showInformationMessage(`Result: ${result}`);
  } catch (error) {
    TraeAPI.window.showErrorMessage(`Error: ${error.message}`);
  }
});

コマンドの実行

typescript
// コマンドを実行
await TraeAPI.commands.executeCommand('workbench.action.files.save');

// パラメータ付きでコマンドを実行
await TraeAPI.commands.executeCommand('myExtension.greet', 'Alice');

// コマンドを実行して結果を取得
const result = await TraeAPI.commands.executeCommand<string>('myExtension.getData');
console.log('Command result:', result);

利用可能なコマンドの取得

typescript
// すべての利用可能なコマンドを取得
const commands = await TraeAPI.commands.getCommands();
console.log('Available commands:', commands);

// コマンドをフィルタリング
const myCommands = commands.filter(cmd => cmd.startsWith('myExtension.'));

コマンドの登録

コンテキスト付きコマンド

typescript
class MyExtension {
  private context: TraeAPI.ExtensionContext;

  constructor(context: TraeAPI.ExtensionContext) {
    this.context = context;
    this.registerCommands();
  }

  private registerCommands() {
    // クラスメソッドでコマンドを登録
    const disposable = TraeAPI.commands.registerCommand(
      'myExtension.processFile',
      this.processFile.bind(this)
    );

    this.context.subscriptions.push(disposable);
  }

  private async processFile(uri?: TraeAPI.Uri) {
    const fileUri = uri || TraeAPI.window.activeTextEditor?.document.uri;
    if (!fileUri) {
      TraeAPI.window.showErrorMessage('No file selected');
      return;
    }

    // ファイルを処理
    const document = await TraeAPI.workspace.openTextDocument(fileUri);
    console.log(`Processing file: ${document.fileName}`);
  }
}

Command with Validation

typescript
TraeAPI.commands.registerCommand('myExtension.validateAndRun', async (...args) => {
  // Validate arguments
  if (args.length === 0) {
    TraeAPI.window.showErrorMessage('Command requires at least one argument');
    return;
  }

  const [firstArg] = args;
  if (typeof firstArg !== 'string') {
    TraeAPI.window.showErrorMessage('First argument must be a string');
    return;
  }

  // Execute command logic
  console.log('Executing with argument:', firstArg);
});

Built-in Commands

File Operations

typescript
// Save current file
await TraeAPI.commands.executeCommand('workbench.action.files.save');

// Save all files
await TraeAPI.commands.executeCommand('workbench.action.files.saveAll');

// Open file
await TraeAPI.commands.executeCommand('workbench.action.files.openFile');

// New file
await TraeAPI.commands.executeCommand('workbench.action.files.newUntitledFile');

Editor Operations

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

// Go to definition
await TraeAPI.commands.executeCommand('editor.action.revealDefinition');

// Find and replace
await TraeAPI.commands.executeCommand('editor.action.startFindReplaceAction');

// Comment/uncomment lines
await TraeAPI.commands.executeCommand('editor.action.commentLine');

Workspace Operations

typescript
// Open folder
await TraeAPI.commands.executeCommand('workbench.action.files.openFolder');

// Close workspace
await TraeAPI.commands.executeCommand('workbench.action.closeFolder');

// Reload window
await TraeAPI.commands.executeCommand('workbench.action.reloadWindow');

Keyboard Shortcuts

Defining Shortcuts in package.json

json
{
  "contributes": {
    "commands": [
      {
        "command": "myExtension.quickAction",
        "title": "Quick Action",
        "category": "My Extension"
      }
    ],
    "keybindings": [
      {
        "command": "myExtension.quickAction",
        "key": "ctrl+shift+q",
        "mac": "cmd+shift+q",
        "when": "editorTextFocus"
      }
    ]
  }
}

Conditional Keybindings

json
{
  "keybindings": [
    {
      "command": "myExtension.debugAction",
      "key": "f5",
      "when": "debuggersAvailable && !inDebugMode"
    },
    {
      "command": "myExtension.testAction",
      "key": "ctrl+t",
      "when": "resourceExtname == .test.js"
    }
  ]
}

Command Palette Integration

Adding Commands to Palette

json
{
  "contributes": {
    "commands": [
      {
        "command": "myExtension.analyze",
        "title": "Analyze Code",
        "category": "Code Analysis",
        "icon": "$(search)"
      }
    ]
  }
}

Context Menu Integration

json
{
  "contributes": {
    "menus": {
      "editor/context": [
        {
          "command": "myExtension.refactor",
          "when": "editorHasSelection",
          "group": "1_modification"
        }
      ],
      "explorer/context": [
        {
          "command": "myExtension.processFile",
          "when": "resourceExtname == .js"
        }
      ]
    }
  }
}

Advanced Usage

Command Chaining

typescript
TraeAPI.commands.registerCommand('myExtension.complexOperation', async () => {
  // Chain multiple commands
  await TraeAPI.commands.executeCommand('editor.action.selectAll');
  await TraeAPI.commands.executeCommand('editor.action.formatSelection');
  await TraeAPI.commands.executeCommand('workbench.action.files.save');
  
  TraeAPI.window.showInformationMessage('Complex operation completed');
});

Command with Progress

typescript
TraeAPI.commands.registerCommand('myExtension.longRunningTask', async () => {
  await TraeAPI.window.withProgress({
    location: TraeAPI.ProgressLocation.Notification,
    title: 'Processing...',
    cancellable: true
  }, async (progress, token) => {
    for (let i = 0; i < 100; i++) {
      if (token.isCancellationRequested) {
        break;
      }
      
      progress.report({ increment: 1, message: `Step ${i + 1}/100` });
      await new Promise(resolve => setTimeout(resolve, 50));
    }
  });
});

Command with User Input

typescript
TraeAPI.commands.registerCommand('myExtension.createFile', async () => {
  const fileName = await TraeAPI.window.showInputBox({
    prompt: 'Enter file name',
    placeHolder: 'example.txt'
  });
  
  if (!fileName) {
    return;
  }
  
  const fileType = await TraeAPI.window.showQuickPick(
    ['JavaScript', 'TypeScript', 'JSON', 'Markdown'],
    { placeHolder: 'Select file type' }
  );
  
  if (fileType) {
    // Create file based on user input
    await createFileWithType(fileName, fileType);
  }
});

API Reference

registerCommand()

typescript
registerCommand(
  command: string,
  callback: (...args: any[]) => any,
  thisArg?: any
): Disposable;

executeCommand()

typescript
executeCommand<T = unknown>(
  command: string,
  ...rest: any[]
): Thenable<T | undefined>;

getCommands()

typescript
getCommands(filterInternal?: boolean): Thenable<string[]>;

Best Practices

  1. Use descriptive command names with extension prefix
  2. Handle errors gracefully in command handlers
  3. Provide user feedback for long-running operations
  4. Validate command parameters before execution
  5. Dispose of command registrations properly
  6. Use appropriate keyboard shortcuts that don't conflict
  7. Add commands to appropriate menus for discoverability

Error Handling

typescript
TraeAPI.commands.registerCommand('myExtension.safeCommand', async () => {
  try {
    const result = await riskyOperation();
    TraeAPI.window.showInformationMessage(`Success: ${result}`);
  } catch (error) {
    console.error('Command failed:', error);
    TraeAPI.window.showErrorMessage(`Failed: ${error.message}`);
  }
});

Testing Commands

typescript
// In test file
import * as assert from 'assert';
import { TraeAPI } from '@trae/api';

suite('Command Tests', () => {
  test('should execute custom command', async () => {
    const result = await TraeAPI.commands.executeCommand('myExtension.testCommand');
    assert.strictEqual(result, 'expected result');
  });
});

究極の AI 駆動 IDE 学習ガイド