如何在VScode中实现复杂的自动缩进

4
我正在为VScode开发SAS语言扩展。之前,我曾经为Atom(https://github.com/akanosora/language-sas)和Vim(作为默认Vim包的一部分:https://github.com/vim/vim/blob/master/runtime/indent/sas.vim)开发了SAS语言扩展。
我对Atom中的自动缩进实现不太满意,而VScode提供了更或多或少相同的自动缩进机制。
对于SAS代码来说,正确的缩进非常棘手,因为块的结尾并不总是必需的。在SAS中,一个块通常以dataproc开始,并以runquit结束,您可以跳过run来关闭它。例如,以下代码在SAS中都可以使用:
data female; 
    set total;
    where gender = 0;
run;

data male; 
    set total;
    where gender = 1;
run; 

或者

data female; 
    set total;
    where gender = 0;

data male; 
    set total;
    where gender = 1;
run; 

所以,适用于SAS的正确自动缩进需要比increaseIndentPatterndecreaseIndentPattern更复杂的规则,因为它们并不总是相互匹配。在Vim中,我通过比较当前行上方最接近的rundata来实现这一点。如果run比前一个data更靠近当前data行,则不需要缩进。否则,缩进当前data行。我想知道在VScode中实现这个功能有多可行(也许不依赖于indentationRules设置,而是使用vscode.languages.* API?)我需要一些指导。

1
尽管SAS允许DATA/PROC步骤在没有run/quit的情况下结束,但通常认为利用这个特性是一种不良编码风格。如果我正在开发一种语言扩展,我会写一个期望每个步骤都被明确关闭的扩展。 - Quentin
2个回答

0

如果您需要更高级的缩进,可以考虑在正则表达式缩进规则之外使用格式化程序。要添加自定义格式化程序,您的扩展应该实现DocumentRangeFormattingEditProvider,然后通过调用registerDocumentRangeFormattingEditProvider来向VS Code注册。

通常情况下,格式化程序必须由用户调用。但是,用户也可以通过设置"editor.formatOnType": true来启用实时格式化。对于这种情况,您的扩展还应该实现OnTypeFormattingEditProvider,并通过调用registerOnTypeFormattingEditProvider来注册实时格式化程序。


0
你可以将dataproc关键字添加到"decreaseIndentPattern"规则中。这样,这些关键字既可用于取消缩进当前行,又可用于在下一行启动新的缩进块。
例如,考虑以下内容:
"indentationRules": {
    "increaseIndentPattern": "^\\s*(proc|data)\\s+.*;\\s*$",
    "decreaseIndentPattern": "^\\s*(run|((proc|data)\\s+.*))\\s*;"
}

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接