You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在VSCode中添加自定义折叠提供器且不覆盖其他扩展折叠?

解决VS Code中PHP扩展添加自定义折叠范围不覆盖原有扩展的问题

核心思路

不要直接替代原有折叠提供器,而是收集所有其他提供器的折叠范围,再合并自己的自定义范围返回,避免递归调用的同时保留原有折叠功能。

实现步骤及代码示例

  1. 确保依赖扩展激活:先激活目标PHP扩展(以主流的Intelephense为例),保证能获取到它的折叠提供器。
  2. 过滤自身提供器:获取所有PHP语言的折叠提供器,排除自己以避免递归调用。
  3. 收集原有折叠范围:遍历其他提供器,调用其折叠范围获取方法,收集结果。
  4. 添加自定义范围:根据需求生成自己的折叠规则(比如特定代码块、注释块)。
  5. 合并返回结果:将原有范围和自定义范围合并后返回给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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.20 17:18:30