VS Code扩展开发:如何实现点击后隐藏单个CodeLens
实现方案
vscode.CodeLensProvider原生没有提供直接隐藏单个已渲染CodeLens的API,可以通过「状态标记+主动触发刷新」的方式实现点击隐藏效果,具体实现步骤如下:
- 第一步:维护隐藏状态集合
在扩展全局作用域定义一个Set结构,存储所有需要隐藏的CodeLens的唯一标识,避免不同位置、不同文档的CodeLens混淆:// 存储已点击、需要隐藏的CodeLens唯一标识 const hiddenCodeLensSet = new Set<string>(); - 第二步:改造CodeLens绑定命令的回调逻辑
每个CodeLens绑定的自定义命令回调里,除了执行原本的业务逻辑,还要做两个操作:将当前CodeLens的唯一标识加入隐藏集合、主动触发当前文档的CodeLens重新计算渲染:// 注册CodeLens点击命令 vscode.commands.registerCommand('yourExtension.codeLensAction', ( lensKey: string, docUri: vscode.Uri, /* 你原本业务需要的其他参数 */ ) => { // 执行CodeLens原本的点击业务逻辑 // 例:跳转、执行重构、显示提示等 // your business logic here // 标记当前CodeLens为隐藏状态 hiddenCodeLensSet.add(lensKey); // 触发当前文档的CodeLens重新计算,刷新渲染 vscode.commands.executeCommand('vscode.executeCodeLensProvider', docUri); }); - 第三步:在CodeLens计算逻辑中过滤已隐藏项
在provideCodeLenses方法里,每次生成CodeLens列表时,提前判断当前项是否在隐藏集合中,如果已经被标记隐藏就跳过不生成,渲染时自然就不会显示这个CodeLens:class CustomCodeLensProvider implements vscode.CodeLensProvider { provideCodeLenses( document: vscode.TextDocument, token: vscode.CancellationToken ): vscode.CodeLens[] { const result: vscode.CodeLens[] = []; // 遍历你原本需要渲染CodeLens的所有位置 for (const renderItem of allLensRenderTargets) { // 生成当前CodeLens的唯一key,可根据业务调整规则,只要能唯一区分单个CodeLens即可 const currentLensKey = `${document.uri.toString()}_${renderItem.range.start.line}_${renderItem.bizId}`; // 已标记隐藏的项直接跳过 if (hiddenCodeLensSet.has(currentLensKey)) { continue; } // 正常生成CodeLens,将key和当前文档uri作为参数传入命令 const codeLens = new vscode.CodeLens(renderItem.range, { title: renderItem.showText, command: 'yourExtension.codeLensAction', arguments: [currentLensKey, document.uri, ...renderItem.bizArgs] }); result.push(codeLens); } return result; } }
补充说明
- 如果需要在文档关闭重开后恢复显示所有CodeLens,可以监听
vscode.workspace.onDidCloseTextDocument事件,在回调里清理掉对应文档关联的所有隐藏标识即可。 - CodeLens的唯一key生成规则可以按需调整,如果你在生成CodeLens时已经给每个项分配了全局唯一id,直接用id作为key更稳妥,避免行号变动导致的匹配错误。

内容的提问来源于stack exchange,提问作者rara
相关产品推荐
相关产品推荐

