如何在VSCode中添加自定义折叠提供器且不覆盖其他扩展折叠?
解决VS Code中PHP扩展添加自定义折叠范围不覆盖原有扩展的问题
核心思路
不要直接替代原有折叠提供器,而是收集所有其他提供器的折叠范围,再合并自己的自定义范围返回,避免递归调用的同时保留原有折叠功能。
实现步骤及代码示例
- 确保依赖扩展激活:先激活目标PHP扩展(以主流的Intelephense为例),保证能获取到它的折叠提供器。
- 过滤自身提供器:获取所有PHP语言的折叠提供器,排除自己以避免递归调用。
- 收集原有折叠范围:遍历其他提供器,调用其折叠范围获取方法,收集结果。
- 添加自定义范围:根据需求生成自己的折叠规则(比如特定代码块、注释块)。
- 合并返回结果:将原有范围和自定义范围合并后返回给VS Code。
import * as vscode from 'vscode'; export function activate(context: vscode.ExtensionContext) { // 定义自定义折叠提供器 const customFoldingProvider: vscode.FoldingRangeProvider = { async provideFoldingRanges( document: vscode.TextDocument, foldingContext: vscode.FoldingContext, token: vscode.CancellationToken ): Promise<vscode.FoldingRange[] | undefined> { // 激活Intelephense扩展(可替换为你正在使用的PHP扩展ID) const phpExtension = vscode.extensions.getExtension('bmewburn.vscode-intelephense-client'); if (phpExtension && !phpExtension.isActive) { await phpExtension.activate(); } // 获取所有PHP折叠提供器,排除自身避免递归 const allProviders = vscode.languages.getFoldingRangeProviders('php'); const otherProviders = Array.from(allProviders.values()).filter(provider => provider !== customFoldingProvider); // 收集原有扩展的折叠范围 let originalRanges: vscode.FoldingRange[] = []; for (const provider of otherProviders) { try { const ranges = await provider.provideFoldingRanges(document, foldingContext, token); if (ranges) { originalRanges = originalRanges.concat(ranges); } } catch (error) { console.error('获取原有折叠范围失败:', error); } } // 生成自定义折叠范围(示例:折叠所有多行注释) const customRanges: vscode.FoldingRange[] = []; const text = document.getText(); const commentRegex = /\/\*[\s\S]*?\*\//g; let match; while ((match = commentRegex.exec(text)) !== null) { const startPos = document.positionAt(match.index); const endPos = document.positionAt(match.index + match[0].length); if (startPos.line !== endPos.line) { // 仅处理多行注释 customRanges.push(new vscode.FoldingRange(startPos.line, endPos.line, vscode.FoldingRangeKind.Comment)); } } // 合并并返回所有折叠范围 return [...originalRanges, ...customRanges]; } }; // 注册自定义折叠提供器 const disposable = vscode.languages.registerFoldingRangeProvider('php', customFoldingProvider); context.subscriptions.push(disposable); }
注意事项
- 扩展ID替换:如果使用的不是Intelephense,需要将代码中的扩展ID替换为你正在使用的PHP扩展的实际ID。
- 错误处理:调用其他提供器时必须捕获异常,防止第三方扩展的错误导致自身扩展崩溃。
- 范围冲突:自定义范围尽量避免与原有范围重叠,若重叠VS Code会自动处理,但可能影响用户的折叠体验。
内容的提问来源于stack exchange,提问作者Liam Hammett
相关产品推荐
相关产品推荐

