PackagesTree
The packages the codebase runs: each package, then (when it runs more than one) each compatible range, then the definitions that use it. A package or range opens its page (README, API, users).
import { running, session } from "#codebase/tcmts/vscode/extension"; import type { PackageNode, PackageRange } from "#codebase/tcmts/vscode/extension"; import * as vscode from "vscode"; export class PackagesTree implements vscode.TreeDataProvider<PackageNode> { changed = new vscode.EventEmitter<PackageNode | undefined | void>(); onDidChangeTreeData = this.changed.event; refresh() { this.changed.fire(); } async getChildren(element?: PackageNode): Promise<PackageNode[]> { if (!running()) return []; const client = session.client!; if (!element) { const pkgs = (await client.sendRequest("tcm/packages", {})) as { name: string; ranges: PackageRange[] }[]; return pkgs.map((p): PackageNode => (p.ranges.length === 1 ? { kind: "range", name: p.name, ...p.ranges[0]!, only: true } : { kind: "package", ...p })); } if (element.kind === "package") return element.ranges.map((r) => ({ kind: "range" as const, name: element.name, ...r })); if (element.kind === "range") { const users = (await client.sendRequest("tcm/packageUsers", { name: element.name, range: element.range })) as { path: string; hash: string; signature: string; kind?: string }[]; return users.map(({ kind, ...u }) => ({ kind: "user" as const, userKind: kind, ...u })); } return []; } getTreeItem(e: PackageNode): vscode.TreeItem { if (e.kind === "user") { const item = new vscode.TreeItem(e.path, vscode.TreeItemCollapsibleState.None); item.description = e.userKind === "type" ? "type" : e.signature; item.iconPath = new vscode.ThemeIcon(e.userKind === "type" ? "symbol-interface" : "symbol-function"); item.command = { command: "tcm.openPage", title: "Open page", arguments: [{ hash: e.hash }] }; return item; } if (e.kind === "package") { const item = new vscode.TreeItem(e.name, vscode.TreeItemCollapsibleState.Collapsed); item.id = `package:${e.name}`; item.description = `${e.ranges.length} ranges: ${e.ranges.map((r) => r.version).join(", ")}`; item.iconPath = new vscode.ThemeIcon("package"); item.contextValue = "package"; return item; } const label = e.only ? e.name : `${e.name} ${e.range}`; const item = new vscode.TreeItem(label, e.users ? vscode.TreeItemCollapsibleState.Collapsed : vscode.TreeItemCollapsibleState.None); item.id = `package:${e.name}@${e.range}`; item.description = `${e.version} · ${e.users ? `${e.users} use${e.users === 1 ? "" : "s"}` : "unused"}`; item.iconPath = new vscode.ThemeIcon(e.only ? "package" : "tag"); item.tooltip = new vscode.MarkdownString( `**${e.name}** ${e.version} (range ${e.range})${e.types ? `\n\ntypes: @types ${e.types}` : ""}${e.integrity ? `\n\n\`${e.integrity.slice(0, 30)}…\`` : ""}`, ); item.contextValue = "packageRange"; item.command = { command: "tcm.openPackagePage", title: "Open page", arguments: [e] }; return item; } }
uses
- tcmts.vscode.extension.PackageNode
- tcmts.vscode.extension.PackageRange
- tcmts.vscode.extension.running
- tcmts.vscode.extension.session