必须在package.json中同时声明activationEvents和menus贡献点,注册命令并指定上下文(如editor/context),再通过vscode.commands.registerCommand实现逻辑,否则右键菜单无法触发。

怎么注册命令并绑定到右键菜单
插件要生成代码,第一步是让用户能触发它。最常用的方式就是注册一个命令,再通过 menus 贡献点把它挂到右键菜单上。
常见错误是只注册命令,没配 activationEvents 或 menus,结果命令面板里能看到,但右键点不出来。
-
package.json中必须同时声明:"onCommand:my-extension.generate"(激活事件)和"command": "my-extension.generate"(命令本身) - 右键菜单需指定上下文,比如
"editor/context"表示只在编辑器区域右键时显示;若想限定语言,加"when": "editorTextFocus && editorLangId == 'javascript'" - 命令标题别用空格或特殊字符,VS Code 会截断或报错;推荐用短横线分隔,如
"Generate React Component"
模板插入逻辑怎么写才不破坏光标位置
直接用 editor.edit() 插入文本时,如果没控制好 range,很容易把光标“吞掉”或插到奇怪位置,尤其在多行模板场景下。
关键不是拼字符串,而是算准插入点——得基于当前 selection 或 cursor position 构造 vscode.Range。
- 获取光标位置用
editor.selection.active,不是editor.selection.start,后者在有选区时可能偏移 - 插入多行模板时,用
new vscode.Range(position, position)创建零宽 range,避免覆盖已有内容 - 别用
editor.insertSnippet()处理纯文本模板,它专为带 tabstop 的 snippet 设计;普通文本用edit.insert()更可控 - 插入后手动调用
editor.selection = new vscode.Selection(newPos, newPos)把光标挪到合理位置(比如类名后、函数体首行)
用户自定义模板怎么加载又不重启插件
硬编码模板意味着每次改都要发新版,实际项目里更倾向让用户自己维护 .json 或 .yaml 模板文件。但读取外部文件不能只靠 fs.readFile,得走 VS Code 提供的 vscode.workspace.fs API。
否则在远程开发(SSH/Dev Container)或某些沙箱环境下会失败,且无法监听文件变化。
- 路径必须用
vscode.Uri.file(absolutePath)构造,不能直接传字符串给vscode.workspace.fs.readFile() - 推荐把模板存放在工作区根目录下的
.vscode/templates/,用vscode.workspace.workspaceFolders?.[0].uri拼接,避免跨平台路径问题 - 监听模板变更要用
vscode.workspace.onDidChangeWorkspaceFolders+vscode.workspace.onDidSaveTextDocument组合,单监听后者会漏掉新建文件 - 缓存模板内容,但每次插入前校验文件 mtime,防止用户改完没保存就触发生成
生成逻辑里怎么安全处理用户输入内容
很多代码生成插件会提取当前选区、函数名、参数列表来填充模板,但直接用正则或 substring 解析容易出错,尤其遇到嵌套括号、字符串字面量或注释时。
真正健壮的做法是依赖语言服务器提供的 AST 工具,而不是手写解析器。
- 对 JavaScript/TypeScript,优先用
vscode.languages.setTextDocumentLanguage()确保文档 languageId 正确,再调用vscode.languages.getDocumentSymbolProvider()获取符号结构 - 简单场景可用
vscode.languages.getFoldingRangesProvider()辅助定位函数体范围,比靠大括号计数靠谱 - 涉及变量名提取时,别信
line.match(/\w+/g),它会把字符串里的单词也抓出来;应结合vscode.languages.getDocumentSemanticTokensProvider()过滤 token 类型 - 所有用户输入内容插入模板前,必须做
vscode.workspace.applyEdit()的 range 校验,防止越界或重叠编辑冲突


















