Skip to content

Commit cfd0f99

Browse files
kbrillamattrbeck
authored andcommitted
feat(language-service): add Document Symbols support for Angular templates
Add DocumentSymbol provider for Angular templates, surfacing structural elements like components, directives, control flow blocks, and template variables in the VS Code Outline and breadcrumbs. resolves #65488
1 parent ed150e5 commit cfd0f99

File tree

10 files changed

+1357
-1
lines changed

10 files changed

+1357
-1
lines changed

packages/language-service/api.ts

Lines changed: 67 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -89,6 +89,60 @@ export interface ApplyRefactoringResult extends Omit<ts.RefactorEditInfo, 'notAp
8989
warningMessage?: string;
9090
}
9191

92+
/**
93+
* Angular-specific LSP SymbolKind values for template symbols.
94+
* These are used for symbols that don't have a direct TypeScript ScriptElementKind mapping.
95+
* Values match LSP SymbolKind enum: https://microsoft.github.io/language-server-protocol/specifications/lsp/3.17/specification/#symbolKind
96+
*/
97+
export enum AngularSymbolKind {
98+
Namespace = 3,
99+
Class = 5,
100+
Array = 18,
101+
Object = 19,
102+
Struct = 23,
103+
Event = 24,
104+
}
105+
106+
/**
107+
* A document symbol representing an Angular template element.
108+
* This uses TypeScript's NavigationTree structure so it can be merged with TS symbols.
109+
*/
110+
export interface TemplateDocumentSymbol {
111+
/** Display name for the symbol */
112+
text: string;
113+
/** Kind of symbol (using TypeScript's ScriptElementKind for compatibility) */
114+
kind: ts.ScriptElementKind;
115+
/**
116+
* Optional LSP SymbolKind override for Angular-specific symbol types.
117+
* When set, this takes precedence over the default ScriptElementKind mapping.
118+
*/
119+
lspKind?: AngularSymbolKind;
120+
/** Span covering the entire symbol */
121+
spans: ts.TextSpan[];
122+
/** Span for just the name (used for selection) */
123+
nameSpan?: ts.TextSpan;
124+
/** Child symbols */
125+
childItems?: TemplateDocumentSymbol[];
126+
/**
127+
* The name of the class this template belongs to.
128+
* Only set for root-level symbols in TypeScript files with inline templates.
129+
* Used to merge template symbols into the correct component class when
130+
* multiple components exist in the same file.
131+
*/
132+
className?: string;
133+
}
134+
135+
/**
136+
* Options for customizing document symbols behavior.
137+
*/
138+
export interface DocumentSymbolsOptions {
139+
/**
140+
* Show all implicit @for loop variables ($index, $count, $first, $last, $even, $odd).
141+
* When false (default), only explicitly aliased variables like `let i = $index` are shown.
142+
*/
143+
showImplicitForVariables?: boolean;
144+
}
145+
92146
/**
93147
* Result for linked editing ranges containing the ranges and optional word pattern.
94148
*/
@@ -415,6 +469,19 @@ export interface NgLanguageService extends ts.LanguageService {
415469
config?: InlayHintsConfig,
416470
): AngularInlayHint[];
417471

472+
/**
473+
* Gets document symbols for Angular templates, including control flow blocks,
474+
* elements, components, template references, and @let declarations.
475+
* Returns symbols in NavigationTree format for compatibility with TypeScript.
476+
*
477+
* @param fileName The file path to get template symbols for
478+
* @param options Optional configuration for document symbols behavior
479+
*/
480+
getTemplateDocumentSymbols(
481+
fileName: string,
482+
options?: DocumentSymbolsOptions,
483+
): TemplateDocumentSymbol[];
484+
418485
applyRefactoring(
419486
fileName: string,
420487
positionOrRange: number | ts.TextRange,

0 commit comments

Comments
 (0)