import type { DocumentSymbol, Range } from 'vscode' import type { SourceRange } from '../contract' import type { SymbolNode } from '../symbolLinks' import { commands, Uri, workspace } from 'vscode' /** * 一个文件的文档符号(`vscode.executeDocumentSymbolProvider`,由这种语言的扩展给):先把文件读进来(不显示),范围换成那个文件里的下标。 * 没装这种语言的扩展时是空的。注释里的仓库链接、「了解一块代码」在没有语言插件的文件里找符号都用它。 */ export async function documentSymbolNodes(uri: string): Promise { const doc = await workspace.openTextDocument(Uri.parse(uri)) const symbols = await commands.executeCommand('vscode.executeDocumentSymbolProvider', doc.uri) const span = (range: Range): SourceRange => ({ startIndex: doc.offsetAt(range.start), endIndex: doc.offsetAt(range.end) }) const node = (symbol: DocumentSymbol): SymbolNode => ({ name: symbol.name, range: span(symbol.range), selection: span(symbol.selectionRange), children: (symbol.children ?? []).map(node), }) return Array.isArray(symbols) ? symbols.map(node) : [] }