如何开发VS Code非侵入式行级动态标注扩展?
实现VS Code行级标注(无需修改源文件)
你选的方向完全没错——CodeLens API就是实现这种行旁标注的核心工具,只是你的代码还没用到它的关键功能。我帮你调整一下代码,不仅能实现每行添加标注,还支持动态修改内容:
首先,我们需要一个全局存储来保存不同文件每行的标注内容,这样才能实现动态更新:
// 全局存储结构:文件URI字符串 -> 行号 -> 标注文本 const lineAnnotations = new Map<string, Map<number, string>>();
接下来修正你的CodeLens提供者实现:
class TestCodeLensProvider implements vscode.CodeLensProvider { // 为文档的每一行生成CodeLens对象 public provideCodeLenses(document: vscode.TextDocument, token: vscode.CancellationToken): vscode.CodeLens[] { const lenses: vscode.CodeLens[] = []; const fileUri = document.uri.toString(); // 遍历文档的每一行,为每行创建CodeLens for (let lineNum = 0; lineNum < document.lineCount; lineNum++) { // 绑定整行范围,确保CodeLens和当前行关联 const lineRange = new vscode.Range(lineNum, 0, lineNum, document.lineAt(lineNum).text.length); // 附加行号和文件URI,方便后续解析时获取上下文 const lens = new vscode.CodeLens(lineRange, { line: lineNum, uri: fileUri }); lenses.push(lens); } return lenses; } // 解析CodeLens,设置显示文本和交互命令 public resolveCodeLens(codeLens: vscode.CodeLens, token: vscode.CancellationToken): vscode.CodeLens { const { line, uri } = codeLens.command?.arguments?.[0] || {}; if (!uri || line === undefined) return codeLens; // 获取当前行的标注文本,默认显示"无标注" const fileAnnotations = lineAnnotations.get(uri) || new Map(); const annotationText = fileAnnotations.get(line) || "无标注"; // 设置CodeLens的显示内容和点击触发的修改命令 codeLens.command = { title: `📝 ${annotationText}`, // 加个图标让标注更醒目 command: "line-annotator.editAnnotation", // 后续要注册这个命令 arguments: [uri, line] // 传递文件URI和行号给命令 }; return codeLens; } }
然后在激活函数里注册CodeLens提供者和修改标注的命令:
export function activate(ctx: vscode.ExtensionContext): void { // 注册CodeLens提供者,这里用"*"支持所有文件类型,你可以改成特定语言比如"json" ctx.subscriptions.push( vscode.languages.registerCodeLensProvider("*", new TestCodeLensProvider()) ); // 注册修改标注的命令:点击标注时触发 ctx.subscriptions.push( vscode.commands.registerCommand("line-annotator.editAnnotation", async (uri: string, line: number) => { const fileAnnotations = lineAnnotations.get(uri) || new Map(); const currentText = fileAnnotations.get(line) || ""; // 弹出输入框让用户输入新标注内容 const newAnnotation = await vscode.window.showInputBox({ prompt: `修改第${line + 1}行的标注`, value: currentText }); if (newAnnotation !== undefined) { // 更新存储的标注数据 if (!fileAnnotations.size) { lineAnnotations.set(uri, fileAnnotations); } fileAnnotations.set(line, newAnnotation); // 刷新CodeLens,让修改立刻显示在编辑器中 await vscode.commands.executeCommand("editor.action.refreshCodeLenses"); } }) ); }
关键特性说明:
- 无文件修改:CodeLens是VS Code渲染的UI层元素,完全不会改动源文件的内容
- 动态更新:通过
lineAnnotations存储标注数据,修改后调用刷新命令即可实时更新界面 - 全行列覆盖:遍历文档所有行生成CodeLens,不会遗漏任何一行
- 交互友好:点击标注就能弹出输入框修改内容,操作流畅
如果你需要纯静态的文本标注(不需要点击交互),也可以用vscode.window.createTextEditorDecorationType实现行尾或行旁的文本装饰,但CodeLens更适合需要交互的场景。
内容的提问来源于stack exchange,提问作者Coder's Apprentice
相关产品推荐
相关产品推荐

