CodebaseTree
Sidebar items: namespaces, then the definitions directly in each (grouped by role in big namespaces).
import { GROUP_OVER, ROLES } from "#codebase/tcmts/cli/pages"; import { definitionItem, ROLE_ICONS, running as running_1, session } from "#codebase/tcmts/vscode/extension"; import type { CodebaseNode, DefinitionEntry, RunningApp } from "#codebase/tcmts/vscode/extension"; import * as vscode from "vscode"; export class CodebaseTree implements vscode.TreeDataProvider<CodebaseNode> { running: Map<string, RunningApp>; changed = new vscode.EventEmitter<CodebaseNode | undefined | void>(); onDidChangeTreeData = this.changed.event; constructor(running: Map<string, RunningApp>) { this.running = running; } refresh() { this.changed.fire(); } async getChildren(element?: CodebaseNode): Promise<CodebaseNode[]> { if (element?.kind === "group") return element.definitions; if (element && element.kind !== "namespace") return []; if (!running_1()) return []; const t = (await session.client!.sendRequest("tcm/tree", { namespace: element?.path ?? "", })) as { namespaces: { name: string; path: string; count: number }[]; definitions: DefinitionEntry[]; }; const namespaces = t.namespaces.map((n) => ({ ...n, kind: "namespace" as const })); if (t.definitions.length <= GROUP_OVER) return [...namespaces, ...t.definitions]; const groups = ROLES.map(([role, label]) => ({ kind: "group" as const, role, label, icon: ROLE_ICONS[role], definitions: t.definitions.filter((d) => d.role === role), })); return [...namespaces, ...groups.filter((g) => g.definitions.length)]; } getTreeItem(e: CodebaseNode): vscode.TreeItem { if (e.kind === "group") { const item = new vscode.TreeItem( e.label, e.role === "test" ? vscode.TreeItemCollapsibleState.Collapsed : vscode.TreeItemCollapsibleState.Expanded, ); item.id = `group:${e.definitions[0]!.path}:${e.role}`; item.description = String(e.definitions.length); item.iconPath = new vscode.ThemeIcon(e.icon); return item; } if (e.kind === "namespace") { const item = new vscode.TreeItem(e.name, vscode.TreeItemCollapsibleState.Collapsed); item.description = String(e.count); item.iconPath = new vscode.ThemeIcon("symbol-namespace"); item.contextValue = "namespace"; item.tooltip = e.path; return item; } const item = definitionItem(e); if (e.role === "app") { const run = this.running.get(e.path); if (run) item.description = run.url ? `running · ${run.url}` : "starting…"; item.contextValue = run ? "definition.app.running" : "definition.app"; } return item; } }
uses
- tcmts.cli.pages.GROUP_OVER
- tcmts.cli.pages.ROLES
- tcmts.vscode.extension.CodebaseNode
- tcmts.vscode.extension.DefinitionEntry
- tcmts.vscode.extension.ROLE_ICONS
- tcmts.vscode.extension.RunningApp
- tcmts.vscode.extension.definitionItem
- tcmts.vscode.extension.running
- tcmts.vscode.extension.session