feat(language-service): add Document Symbols support for Angular templates#66690
feat(language-service): add Document Symbols support for Angular templates#66690kbrilla wants to merge 4 commits intoangular:mainfrom
Conversation
| // Get the navigation tree from TypeScript's language service. | ||
| // This includes classes, functions, variables, and for Angular files, | ||
| // also includes template symbols via the Angular language service. | ||
| const navigationTree = languageService.getNavigationTree(scriptInfo.fileName); |
There was a problem hiding this comment.
Should this only happen for TS files? What do we do about symbols for external templates (html files)
There was a problem hiding this comment.
I've refactored the code to make the two paths clearer:
// For HTML template files, we only need Angular template symbols (no TS symbols)
if (isHtmlFile) {
// Returns template symbols at root level
return convertTemplateSymbols(templateSymbols, scriptInfo);
}
// For TypeScript files, get navigation tree + merge template symbols into classes
// ... TS symbols with (template) node nested under classTest at ivy_spec.ts:411 verifies external HTML templates work.
There was a problem hiding this comment.
I see in the screenshots that the document symbols are separated by the provider. In that case, should we even include the TS document symbols in TS files?
There was a problem hiding this comment.
hmm, yes it is duplicating some positions, but so is html template one doing - should it also skip positions handled by native html? or make it configurable mayby?
There was a problem hiding this comment.
For typescript, I think we should only include the parents of the inline template but should not provide other things from typescript (e.g. ngOnInit random various functions in the file, etc). For HTML, we can leave it as-is to keep it consistent for inline and external templates.
| args.push('--suppressAngularDiagnosticCodes', suppressAngularDiagnosticCodes); | ||
| } | ||
|
|
||
| const documentSymbolsEnabled = config.get<boolean>('angular.documentSymbols.enabled', true); |
There was a problem hiding this comment.
We use middleware above to prevent the angular language server from processing files in projects that don't use Angular. Since the extension activates on all html and ts files, this is relatively important.
There was a problem hiding this comment.
Thx for the hint! Added the provideDocumentSymbols middleware with isInAngularProject guard.
9b9c431 to
9e2edd7
Compare
8b102aa to
a0de8d6
Compare
This commit adds infrastructure for features to request configuration from the VS Code client using the LSP workspace/configuration protocol. This is the preferred approach over CLI arguments because: 1. Configuration changes take effect immediately without restarting 2. Supports per-workspace and per-folder configuration 3. VS Code automatically merges settings from different scopes: - Default settings - User settings (global) - Workspace settings - Workspace folder settings - Language-specific settings The new utilities include: - getWorkspaceConfiguration: Request multiple config sections at once - getConfigurationSection: Convenience wrapper for single sections - flattenConfiguration: Flatten nested config to dot-notation keys This infrastructure will be used by: - Inlay hints feature (PR angular#66731) - Document symbols feature (PR angular#66690)
a0de8d6 to
4b96714
Compare
🔗 Dependency UpdateThis PR now depends on #66734 (feat(language-server): add shared workspace/configuration utilities). Changes in this update:
Merge Order:
The PR has been rebased onto the |
4b96714 to
6fabcea
Compare
Update: Hybrid Approach ImplementedFollowing @atscott's feedback, I've implemented the hybrid approach (Option 1 + 2 from the analysis): Changes:
Default behavior (new):With
|
6fabcea to
e57626d
Compare
sorry, that’s not really what I asked. Please remove all typescript symbols outside of the ancestors of the template property |
| * ); | ||
| * ``` | ||
| */ | ||
| export async function getConfigurationSection<T = unknown>( |
There was a problem hiding this comment.
I don't see this used anywhere
e57626d to
c9b1442
Compare
c9b1442 to
5ca4d1d
Compare
5ca4d1d to
ac699af
Compare
|
I'm leaving out inlay styles support: |
…ettings grouping Add shared workspace configuration helper utilities and move extension settings to grouped configuration sections, without inlay-hint feature options yet.
…lates Adds comprehensive Document Symbols support for Angular templates, enabling the Outline panel, breadcrumbs navigation, and 'Go to Symbol' (Cmd+Shift+O / Ctrl+Shift+O) features to work with Angular template syntax. Features: - Block syntax: @if, @else, @for, @switch, @case, @defer, @Placeholder, etc. - Structural directives: *ngIf, *ngFor, *ngSwitch, etc. - HTML elements and components - Template reference variables (#ref) - Loop variables and aliases (let item, let i = $index) - @let declarations For TypeScript files with inline templates, shows component class containers with template symbols nested inside (no TypeScript methods/properties shown). For external HTML templates, shows template symbols at root level. Configuration: - angular.documentSymbols.enabled: Enable/disable feature (default: true) - angular.documentSymbols.showImplicitForVariables: Show implicit @for variables Depends on workspace/configuration utilities from the previous commit. Closes angular#66691
975ac56 to
8ac4109
Compare



PR: feat(language-service): add Document Symbols support for Angular templates
Description
Adds comprehensive Document Symbols support for Angular templates, enabling the Outline panel, breadcrumbs navigation, and "Go to Symbol" (Cmd+Shift+O / Ctrl+Shift+O) features to work with Angular template syntax.
Features
Block Syntax Support
@if,@else,@else ifwith expression and alias display@forwith track expression and context variables@switch,@case,@defaultblocks@defer,@placeholder,@loading,@errorblocks with triggers@letdeclarationsStructural Directive Support
*ngIf,*ngFor,*ngSwitch,*ngSwitchCase,*ngSwitchDefault*ngTemplateOutlet,*ngComponentOutlet,*ngPlural,*ngPluralCaseTemplate File Support
(template)node in component classtemplateUrl)Multi-Component Support
Variables and References
let item)#ref)let i = $index)as alias)SymbolKind Mappings
@if,@else,@switch,@case@for,@empty@defer,@placeholder,@loading,@errorConfiguration
angular.documentSymbols.enabled(default:true)Enables Angular-specific document symbols.
angular.documentSymbols.showImplicitForVariables(default:false)Shows all implicit
@forloop variables ($index,$count,$first,$last,$even,$odd).Example
Template:
@for (item of items; track item.id; let i = $index) { @if (item.visible; as isVisible) { <div #container (click)="onClick()"> {{ item.name }} </div> } }Outline:
Breaking Changes
None
Related Issues
Closes #66691
AI Disclosure
This PR was developed using Claude Opus 4.6 and GPT 5.3 Max AI assistants under human orchestration and review by @kbrilla.