CodeHooker
一个强大的 VS Code 扩展,允许你在编辑器事件发生时执行自定义操作。
功能特性
支持的 Hook 事件
- 保存文件 (
onSave
) - 当文件被保存时触发
- 文件切换 (
onFileSwitch
) - 当切换到不同文件时触发
- 窗口切换 (
onWindowSwitch
) - 当窗口获得焦点时触发
内置操作类型
- 执行命令 (
executeCommand
) - 执行任何 VS Code 命令,支持实时验证和命令建议
- 执行快捷键 (
executeKeybinding
) - 通过实际按键录制快捷键组合
扩展性架构
- 支持自定义 Hook 触发器
- 支持自定义操作类型
- 插件系统允许第三方扩展
快速开始
安装
- 打开 VS Code
- 按
F1
打开命令面板
- 输入 "CodeHooker: Open Manager" 打开管理界面
创建第一个 Hook
- 在管理界面中点击 "Add New Hook"
- 填写 Hook 名称,例如 "Auto Save All on File Switch"
- 选择触发事件,例如 "On File Switch"
- 添加操作:
- 类型:Execute Command
- 命令:输入
workbench.action.files.saveAll
(会实时验证命令有效性)
- 延迟:100ms
- 点击 "Add Hook" 保存
使用快捷键录制功能
- 添加操作时选择 "Execute Keybinding"
- 点击 "Click to record keybinding" 按钮
- 按下你想要的快捷键组合(如 Ctrl+S)
- 系统会自动录制并显示快捷键组合
常用配置示例
保存时重启 TypeScript 服务器
{
"name": "Restart TypeScript Server on Save",
"trigger": "onSave",
"actions": [
{
"type": "executeCommand",
"command": "typescript.restartTsServer",
"delay": 500
}
],
"executeAfter": true
}
文件切换时自动保存
{
"name": "Auto Save on File Switch",
"trigger": "onFileSwitch",
"actions": [
{
"type": "executeKeybinding",
"command": "ctrl+s"
}
],
"executeAfter": false
}
窗口激活时显示通知(通过自定义插件)
{
"name": "Welcome Message",
"trigger": "onWindowSwitch",
"actions": [
{
"type": "showNotification",
"params": {
"message": "欢迎回来!"
}
}
]
}
管理界面功能
Hook 管理
- 添加 Hook: 通过表单创建新的 Hook 配置
- 编辑 Hook: 点击编辑按钮修改 Hook 名称和执行时机
- 删除 Hook: 确认删除对话框防止误操作
- 启用/禁用: 快速切换单个 Hook 的状态
- 全局开关: 一键启用或禁用所有 Hook
智能输入功能
- 命令验证: 输入命令时实时验证有效性
- 命令建议: 对无效命令提供相似命令建议
- 快捷键录制: 通过实际按键录制快捷键组合
- 输入验证: 确保所有必需字段都已填写
扩展开发指南
1. 插件系统架构
CodeHooker 采用插件化架构,允许开发者扩展功能:
// 插件接口定义
export interface ExtensionPlugin {
id: string; // 插件唯一标识
name: string; // 插件显示名称
version: string; // 版本号
author: string; // 作者
description: string; // 描述
triggers?: CustomTrigger[]; // 自定义触发器
actions?: CustomAction[]; // 自定义操作
initialize?: (context: vscode.ExtensionContext) => Promise<void>;
dispose?: () => Promise<void>;
}
2. 创建自定义触发器
const customTrigger: CustomTrigger = {
id: 'onGitCommit',
name: 'Git Commit',
description: '在 Git 提交时触发',
handler: async (context) => {
// 监听 git 事件的逻辑
const gitExtension = vscode.extensions.getExtension('vscode.git');
if (gitExtension) {
const git = gitExtension.exports.getAPI(1);
// 实现 git 事件监听
}
}
};
3. 创建自定义操作
const customAction: CustomAction = {
id: 'runTests',
name: 'Run Tests',
description: '运行测试套件',
requiredParams: ['testType'],
executor: async (params) => {
const terminal = vscode.window.createTerminal('Test Runner');
terminal.show();
switch (params.testType) {
case 'unit':
terminal.sendText('npm test');
break;
case 'e2e':
terminal.sendText('npm run test:e2e');
break;
default:
terminal.sendText('npm run test:all');
}
}
};
4. 完整插件示例
import * as vscode from 'vscode';
import { ExtensionPlugin } from './extensionSystem';
const myPlugin: ExtensionPlugin = {
id: 'development-helper',
name: 'Development Helper',
version: '1.0.0',
author: 'Your Name',
description: '开发辅助插件',
triggers: [
{
id: 'onTerminalCommand',
name: 'Terminal Command',
description: '在终端执行命令时触发',
handler: async (context) => {
// 监听终端命令执行
vscode.window.onDidChangeTerminalState(terminal => {
console.log('Terminal state changed:', terminal.name);
});
}
}
],
actions: [
{
id: 'openBrowser',
name: 'Open Browser',
description: '打开浏览器到指定 URL',
requiredParams: ['url'],
executor: async (params) => {
const url = params.url || 'http://localhost:3000';
await vscode.env.openExternal(vscode.Uri.parse(url));
}
},
{
id: 'formatCode',
name: 'Format Code',
description: '格式化当前文件',
executor: async (params) => {
await vscode.commands.executeCommand('editor.action.formatDocument');
vscode.window.showInformationMessage('Code formatted successfully');
}
}
],
initialize: async (context) => {
console.log('Development Helper plugin initialized');
// 注册插件特定的命令
const command = vscode.commands.registerCommand('dev-helper.hello', () => {
vscode.window.showInformationMessage('Hello from Development Helper!');
});
context.subscriptions.push(command);
},
dispose: async () => {
console.log('Development Helper plugin disposed');
}
};
export default myPlugin;
5. 插件注册
// 在 hookManager.ts 中注册插件
import myPlugin from './plugins/myPlugin';
async function loadCustomPlugins() {
try {
await this.extensionSystem.registerPlugin(myPlugin);
console.log('Custom plugin loaded successfully');
} catch (error) {
console.error('Failed to load custom plugin:', error);
}
}
6. 最佳实践
错误处理
executor: async (params) => {
try {
// 执行操作逻辑
await someAsyncOperation();
} catch (error) {
vscode.window.showErrorMessage(`操作失败: ${error.message}`);
throw error;
}
}
参数验证
executor: async (params) => {
if (!params.requiredParam) {
throw new Error('Required parameter is missing');
}
// 继续执行
}
异步操作处理
handler: async (context) => {
// 使用防抖避免频繁触发
let timeout: NodeJS.Timeout;
return new Promise((resolve) => {
clearTimeout(timeout);
timeout = setTimeout(() => {
resolve(actualHandler(context));
}, 300);
});
}
配置文件
所有的 Hook 配置都存储在 VS Code 的设置中:
{
"codehooker.globalEnabled": true,
"codehooker.hooks": [
{
"id": "unique-id",
"name": "Hook Name",
"trigger": "onSave",
"actions": [
{
"id": "action-id",
"type": "refreshLanguageServer",
"delay": 0,
"enabled": true
}
],
"enabled": true,
"executeAfter": true
}
]
}
命令
CodeHooker: Open Manager
- 打开管理界面
CodeHooker: Toggle Hook
- 全局启用/禁用 CodeHooker
快捷键录制系统
CodeHooker 支持实时快捷键录制:
录制方式
- 选择 "Execute Keybinding" 操作类型
- 点击 "Click to record keybinding" 按钮
- 直接按下目标快捷键组合
- 系统自动识别并保存快捷键
支持的快捷键组合
- 修饰键: Ctrl, Cmd, Shift, Alt
- 功能键: F1-F12
- 常用键: 字母、数字、符号键
- 组合示例:
ctrl+s
- 保存文件
cmd+shift+p
- 打开命令面板
alt+f4
- 关闭窗口
注意事项
- 录制过程中按任意键会立即完成录制
- 支持多级修饰键组合
- 自动处理平台差异(Ctrl vs Cmd)
故障排除
Hook 没有被触发
- 检查全局开关是否启用
- 确认具体的 Hook 是否启用
- 查看 VS Code 开发者控制台的错误信息
命令验证失败
- 检查命令名称是否正确拼写
- 查看建议的相似命令
- 使用 VS Code 命令面板确认命令存在
性能问题
如果发现性能问题,可以:
- 增加操作的延迟时间
- 禁用不必要的 Hook
- 检查自定义操作是否有性能问题
贡献
欢迎提交 Issue 和 Pull Request 来改进 CodeHooker。
许可证
MIT License