首页 > 解决方案 > 带有分层大纲、DocumentSymbol 的 VSCode 语言扩展

问题描述

我试图让大纲在 VScode 中使用自定义语言。我有下面的代码,但我觉得它很慢,因为我在课堂上找到范围的方式。有没有更好的方法来找到范围并分配孩子。我考虑过只跟踪括号的深度并将所有深度较高的函数/方法/类分配到先前深度的最后一项中。

它基于这个答案

class JSLDocumentSymbolProvider implements vscode.DocumentSymbolProvider {
public provideDocumentSymbols(document: vscode.TextDocument,
        token: vscode.CancellationToken): Thenable<vscode.DocumentSymbol[]> {
    return new Promise((resolve, reject) => {
        var symbols: vscode.DocumentSymbol[] = [];
        var depth = 0;
        for (var i = 0; i < document.lineCount; i++) {
            var line = document.lineAt(i);
            var txt = line.text;
            var ltxt = txt.toLowerCase();
            let open_brackets = ltxt.match(/\(/g) || [];
            let close_brackets = ltxt.match(/\)/g) || [];
            // console.log(ltxt)
            // console.log(open_brackets, close_brackets)
            //console.log(i, open_brackets.length, close_brackets.length)

            depth += open_brackets.length - close_brackets.length;
            //console.log(depth);

            if (ltxt.includes("define class(")) {
                let sname = txt.trim().substr(14, txt.trim().length - 16); //this is hard coded right now but it's kind of working
                let detail = "ARGS:x, y returns z";
                let start_pos = new vscode.Position(i, 0); 
                let n_bracket = 1;
                let i_char = 0;
                //let children: vscode.DocumentSymbol[] = []
                let ds = new vscode.DocumentSymbol(sname, detail, vscode.SymbolKind.Class, line.range, line.range);

                for(var i_line = i; n_bracket > 0; i_line++){
                    let class_line = document.lineAt(i_line);
                    let mtxt = class_line.text;
                    let ic;
                    if(i == i_line) ic = 16;
                    else ic = 0;
                    for(i_char = ic; i_char < mtxt.length; i_char++){
                        if(mtxt[i_char] === "(") n_bracket++;
                        else if(mtxt[i_char] === ")") n_bracket--;
                        if(n_bracket === 0) break
                    }
                    if (/(\w[\w\d\s]*)=\s*method\({((?:\s*(?:\w[\w\d\s]*)(?:=[^,]*)?,?\s*)*)},/i.test(mtxt)) { 
                        let result = mtxt.match(/(\w[\w\d\s]*)=\s*method\({((?:\s*(?:\w[\w\d\s]*)(?:=[^,]*)?,?\s*)*)},/i)!;
                        let mname = result[1].trim();
                        let m_details = ""
                        if(result.length == 3){
                            m_details = result[2].trim();
                        }
                        ds.children.push(new vscode.DocumentSymbol(mname, m_details, vscode.SymbolKind.Method, class_line.range, class_line.range));
                    }
                    if(n_bracket === 0) break
                }
                let end_pos = new vscode.Position(i_line, i_char);
                let rng = new vscode.Range(start_pos, end_pos);
                ds.range = rng;
                //ds.children = children;
                symbols.push(ds);
            }
            else if (/(\w[\w\d\s]*)=\s*function\({((?:\s*(?:\w[\w\d\s]*)(?:=[^,]*)?,?\s*)*)},/.test(ltxt)) { 
                let result = txt.match(/(\w[\w\d\s]*)=\s*function\({((?:\s*(?:\w[\w\d\s]*)(?:=[^,]*)?,?\s*)*)},/i)!;
                let sname = result[1].trim();
                let detail = "";
                if(result.length == 3){
                    detail = "(" + result[2].trim() + ")";
                }
                symbols.push(new vscode.DocumentSymbol(sname, detail, vscode.SymbolKind.Function, line.range, line.range));
            }
        } 

        resolve(symbols);
    });
}

}

标签: visual-studio-codevscode-extensions

解决方案


推荐阅读