visual-studio-code - 带有分层大纲、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);
});
}
}
解决方案
推荐阅读
- php - 从 URL 检索信息
- ios - 滚动时自定义 UITableViewCell 获取错误属性
- visual-studio - GENERATEFAKES 因 CS0234 而失败
- javascript - 查询中的 Firebase StartAfter 未按预期工作
- wordpress - 在 wordpress 中通过 add_query_arg() 获取热门帖子链接
- java - Android:将 JSONObject 转换为 JSONArray 返回 null
- javascript - 如何围绕一个形状移动
- javascript - 带有 js 的 Onclick 事件 html h-tag
- android - Android Socket 连接到服务器但不写任何东西
- xml - Xsl 结合 substring-before 和 format-number