命令 API
概述
Trae 命令 API 提供了一套完整的命令系统,允许开发者通过编程方式执行各种 IDE 操作。本文档详细介绍了如何使用命令 API 来自动化工作流程和扩展 IDE 功能。
核心概念
命令系统
命令系统是 Trae 的核心组件之一,提供了统一的接口来执行各种操作:
- 命令注册:注册自定义命令
- 命令执行:执行内置或自定义命令
- 命令参数:传递参数给命令
- 命令结果:获取命令执行结果
命令类型
typescript
interface Command {
id: string;
title: string;
category?: string;
description?: string;
arguments?: any[];
}API 参考
命令注册
registerCommand()
注册一个新的命令:
typescript
import { commands } from '@trae/api';
// 注册简单命令
commands.registerCommand('myExtension.hello', () => {
console.log('Hello from my extension!');
});
// 注册带参数的命令
commands.registerCommand('myExtension.greet', (name: string) => {
console.log(`Hello, ${name}!`);
});
// 注册异步命令
commands.registerCommand('myExtension.fetchData', async (url: string) => {
const response = await fetch(url);
return response.json();
});registerTextEditorCommand()
注册文本编辑器相关的命令:
typescript
commands.registerTextEditorCommand('myExtension.insertText',
(textEditor, edit, text: string) => {
edit.insert(textEditor.selection.active, text);
}
);命令执行
executeCommand()
执行已注册的命令:
typescript
// 执行无参数命令
await commands.executeCommand('workbench.action.files.save');
// 执行带参数命令
await commands.executeCommand('myExtension.greet', 'World');
// 获取命令结果
const result = await commands.executeCommand('myExtension.fetchData',
'https://api.example.com/data'
);
console.log(result);命令查询
getCommands()
获取所有可用命令的列表:
typescript
const allCommands = await commands.getCommands();
console.log('Available commands:', allCommands);
// 过滤特定前缀的命令
const myCommands = allCommands.filter(cmd => cmd.startsWith('myExtension.'));内置命令
文件操作命令
typescript
// 打开文件
await commands.executeCommand('vscode.open', uri);
// 保存文件
await commands.executeCommand('workbench.action.files.save');
// 保存所有文件
await commands.executeCommand('workbench.action.files.saveAll');
// 新建文件
await commands.executeCommand('workbench.action.files.newUntitledFile');编辑器命令
typescript
// 格式化文档
await commands.executeCommand('editor.action.formatDocument');
// 跳转到定义
await commands.executeCommand('editor.action.revealDefinition');
// 查找引用
await commands.executeCommand('editor.action.goToReferences');
// 重命名符号
await commands.executeCommand('editor.action.rename');工作区命令
typescript
// 打开文件夹
await commands.executeCommand('vscode.openFolder', folderUri);
// 重新加载窗口
await commands.executeCommand('workbench.action.reloadWindow');
// 切换侧边栏
await commands.executeCommand('workbench.action.toggleSidebarVisibility');高级用法
命令链
创建命令序列来执行复杂操作:
typescript
commands.registerCommand('myExtension.complexOperation', async () => {
// 保存当前文件
await commands.executeCommand('workbench.action.files.save');
// 格式化文档
await commands.executeCommand('editor.action.formatDocument');
// 运行测试
await commands.executeCommand('workbench.action.tasks.runTask', 'test');
console.log('Complex operation completed!');
});条件命令
根据条件执行不同的命令:
typescript
commands.registerCommand('myExtension.conditionalCommand', async () => {
const activeEditor = window.activeTextEditor;
if (activeEditor) {
const document = activeEditor.document;
if (document.languageId === 'typescript') {
await commands.executeCommand('typescript.organizeImports');
} else if (document.languageId === 'python') {
await commands.executeCommand('python.sortImports');
}
}
});命令参数验证
typescript
commands.registerCommand('myExtension.validateArgs',
(requiredParam: string, optionalParam?: number) => {
if (!requiredParam) {
throw new Error('Required parameter is missing');
}
const value = optionalParam || 0;
console.log(`Processing: ${requiredParam}, value: ${value}`);
}
);错误处理
命令执行错误
typescript
try {
await commands.executeCommand('nonexistent.command');
} catch (error) {
console.error('Command execution failed:', error.message);
}命令注册错误
typescript
try {
commands.registerCommand('duplicate.command', () => {});
commands.registerCommand('duplicate.command', () => {}); // 会抛出错误
} catch (error) {
console.error('Command registration failed:', error.message);
}最佳实践
命名约定
typescript
// 使用扩展名作为前缀
commands.registerCommand('myExtension.action.name', handler);
// 使用描述性名称
commands.registerCommand('myExtension.format.json', handler);
commands.registerCommand('myExtension.generate.component', handler);命令分组
typescript
// 按功能分组命令
const FILE_COMMANDS = {
CREATE: 'myExtension.file.create',
DELETE: 'myExtension.file.delete',
RENAME: 'myExtension.file.rename'
};
// 注册分组命令
Object.values(FILE_COMMANDS).forEach(commandId => {
commands.registerCommand(commandId, getHandlerForCommand(commandId));
});异步处理
typescript
commands.registerCommand('myExtension.asyncOperation', async () => {
try {
const result = await longRunningOperation();
window.showInformationMessage(`Operation completed: ${result}`);
} catch (error) {
window.showErrorMessage(`Operation failed: ${error.message}`);
}
});调试和测试
命令调试
typescript
commands.registerCommand('myExtension.debug', (...args) => {
console.log('Command arguments:', args);
console.log('Active editor:', window.activeTextEditor?.document.fileName);
console.log('Workspace folders:', workspace.workspaceFolders?.map(f => f.uri.path));
});命令测试
typescript
// 测试命令执行
const testCommand = async () => {
const result = await commands.executeCommand('myExtension.testCommand', 'test-arg');
assert.strictEqual(result, 'expected-result');
};性能优化
延迟加载
typescript
// 延迟注册重型命令
commands.registerCommand('myExtension.heavyOperation', async () => {
const { heavyModule } = await import('./heavy-module');
return heavyModule.process();
});命令缓存
typescript
const commandCache = new Map();
commands.registerCommand('myExtension.cachedOperation', async (key: string) => {
if (commandCache.has(key)) {
return commandCache.get(key);
}
const result = await expensiveOperation(key);
commandCache.set(key, result);
return result;
});