首页 > 解决方案 > VSCode:扩展:根据找到的第一个空白行或下一个类似部分的开头折叠部分

问题描述

如何根据起始折叠标记后的第一个空白行制定 VSCode 扩展折叠策略?

## Some section   --|
Any text...         |  (this should fold)
...more text.     --|
                       (blank line)
## Another section     (next fold...)

我在 language-configuration.json 中尝试了很多正则表达式。

    "folding": {
        "markers": {
            "start": "^##",
            "end": "^\\s*$"
    } },

如果我更改内容以使用空白(或空格)行以外的其他内容作为结束分隔符进行测试,则它可以工作。不能使用下一个开始标记来标记最后一个的结束或将其包含在折叠中(我尝试了前瞻正则表达式,但我认为正则表达式是逐行应用的,并且匹配项不能跨越行?)

它类似于 VSCode 处理良好的 Markdown 所需的折叠(不知道这是否使用更复杂的方法,例如https://code.visualstudio.com/api/references/vscode-api#FoldingRangeProvider)。

也许 [folding] 修复程序中的某些内容不应该在函数与它有关之后折叠空格。

标签: visual-studio-codevscode-extensionsfoldingblank-line

解决方案


我学到了什么: 1.beginend正则表达式逐行应用。2. tmLanguage start/end regex 将在空行上工作,但目前语言配置折叠似乎不适用于空行。

由于在这种情况下空行是在下一个开始部分结束的黑客:

为了解决将一个部分折叠到下一个类似部分的问题,我使用了FoldingRangeProvider

    disposable = vscode.languages.registerFoldingRangeProvider('myExt', {
        provideFoldingRanges(document, context, token) {
            //console.log('folding range invoked'); // comes here on every character edit
            let sectionStart = 0, FR = [], re = /^## /;  // regex to detect start of region

            for (let i = 0; i < document.lineCount; i++) {

                if (re.test(document.lineAt(i).text)) {
                    if (sectionStart > 0) {
                        FR.push(new vscode.FoldingRange(sectionStart, i - 1, vscode.FoldingRangeKind.Region));
                    }
                    sectionStart = i;
                }
            }
            if (sectionStart > 0) { FR.push(new vscode.FoldingRange(sectionStart, document.lineCount - 1, vscode.FoldingRangeKind.Region)); }

            return FR;
        }
    });

设置"editor.foldingStrategy": "auto"。您可以更复杂地保留部分之间的空白。


推荐阅读