Skip to content

Support LSP document symbols in breadcrumbs and outline UI - #48780

Merged
SomeoneToIgnore merged 2 commits into
mainfrom
kb/document-symbols
Feb 11, 2026
Merged

Support LSP document symbols in breadcrumbs and outline UI#48780
SomeoneToIgnore merged 2 commits into
mainfrom
kb/document-symbols

Conversation

@SomeoneToIgnore

@SomeoneToIgnore SomeoneToIgnore commented Feb 9, 2026

Copy link
Copy Markdown
Contributor

Closes #23095

By default is disabled with "document_symbols": "off" language settings, when enabled, starts to show LSP symbols in breadcrumbs, outline modal and outline panel, instead of tree-sitter ones based on outlines.scm.

Before (tree-sitter):
image

After (LSP):
image

The downside we have now is that LSP ranges are smaller than tree-sitter and do not capture mod, fn and other syntax.
For now, this is omitted, later the plan is to have icons based on the kind of the symbol returned via LSP.

Release Notes:

  • Supported LSP document symbols in breadcrumbs and outline UI, enabled with "document_symbols": "on" language settings

@SomeoneToIgnore SomeoneToIgnore self-assigned this Feb 9, 2026
@cla-bot cla-bot Bot added the cla-signed The user has signed the Contributor License Agreement label Feb 9, 2026
@zed-community-bot zed-community-bot Bot added the staff Pull requests authored by a current member of Zed staff label Feb 9, 2026
@SomeoneToIgnore
SomeoneToIgnore force-pushed the kb/document-symbols branch 3 times, most recently from 7e37ea6 to 4b6a1b2 Compare February 9, 2026 14:44
@SomeoneToIgnore SomeoneToIgnore changed the title Support LSP document symbols in outline UI Support LSP document symbols in breadcrumbs and outline UI Feb 10, 2026
@SomeoneToIgnore
SomeoneToIgnore force-pushed the kb/document-symbols branch 12 times, most recently from fea765e to ab241b1 Compare February 10, 2026 21:59
Buffer registration will do that later for us
@SomeoneToIgnore
SomeoneToIgnore marked this pull request as ready for review February 10, 2026 22:03
@SomeoneToIgnore
SomeoneToIgnore force-pushed the kb/document-symbols branch 3 times, most recently from c813b8b to a25c24c Compare February 11, 2026 10:14
@SomeoneToIgnore
SomeoneToIgnore merged commit 56504fd into main Feb 11, 2026
40 of 42 checks passed
@SomeoneToIgnore
SomeoneToIgnore deleted the kb/document-symbols branch February 11, 2026 19:30
SomeoneToIgnore added a commit that referenced this pull request Feb 13, 2026
Follow-up of #48780

Fixes incorrect multi byte characters treatment in the symbol range when
highlighting:
<img width="1728" height="507" alt="image"
src="https://github.com/user-attachments/assets/c6639220-f08a-4ea8-bf99-926566e356ae"
/>

Fixes multiple language servers' duplicate data display:
<img width="1726" height="925" alt="image"
src="https://github.com/user-attachments/assets/ca98ee29-732e-4c8e-adf4-21a9523a5a9c"
/>


Release Notes:

- N/A
morgankrey added a commit that referenced this pull request Feb 19, 2026
Auto-applied queued documentation suggestions from:
- PR #48908
- PR #48909
- PR #48910
- PR #48912
- PR #48930
- PR #44794
- PR #48763
- PR #45073
- PR #48495
- PR #49374
- PR #49139
- PR #48780
- PR #48619
- PR #48978
- PR #48962
- PR #48988
- PR #47860
- PR #49015
- PR #47095
- PR #47475
- PR #48542
- PR #46766
- PR #47754
- PR #48807
- PR #44506
- PR #49051
- PR #49069
- PR #48842
- PR #48851
- PR #48736
- PR #47673
- PR #49094
- PR #49098
- PR #49622

Generated with script/docs-suggest-publish for human review in draft PR.
morgankrey added a commit that referenced this pull request Feb 25, 2026
Auto-applied queued documentation suggestions from:
- PR #48908
- PR #48909
- PR #48910
- PR #48912
- PR #48930
- PR #44794
- PR #48763
- PR #45073
- PR #48495
- PR #49374
- PR #49139
- PR #48780
- PR #48619
- PR #48978
- PR #48962
- PR #48988
- PR #47860
- PR #49015
- PR #47095
- PR #47475
- PR #48542
- PR #46766
- PR #47754
- PR #48807
- PR #44506
- PR #49051
- PR #49069
- PR #48842
- PR #48851
- PR #48736
- PR #47673
- PR #49094
- PR #49098
- PR #49622
- PR #49554
- PR #49710
- PR #49716
- PR #49732
- PR #49788
- PR #49876
- PR #49902
- PR #49910
- PR #49390
- PR #50027

Generated with script/docs-suggest-publish for human review in draft PR.
morgankrey added a commit that referenced this pull request Feb 25, 2026
Auto-applied documentation from:
- PR #48619: agent single_file_review default change
- PR #48978: enriched symbol names in outline
- PR #49015: audio device selection for collab
- PR #47095: MCP error handling
- PR #47475: OpenRouter default model requirement

Skipped (already documented):
- PR #49139, PR #48780, PR #48988, PR #47860
morgankrey added a commit that referenced this pull request Feb 25, 2026
Auto-applied queued documentation suggestions from:
- PR #48908
- PR #48909
- PR #48910
- PR #48912
- PR #48930
- PR #44794
- PR #48763
- PR #45073
- PR #48495
- PR #49374
- PR #49139
- PR #48780
- PR #48619
- PR #48978
- PR #48962
- PR #48988
- PR #47860
- PR #49015
- PR #47095
- PR #47475
- PR #48542
- PR #46766
- PR #47754
- PR #48807
- PR #44506
- PR #49051
- PR #49069
- PR #48842
- PR #48851
- PR #48736
- PR #47673
- PR #49094
- PR #49098
- PR #49622
- PR #49554
- PR #49710
- PR #49716
- PR #49732
- PR #49788
- PR #49876
- PR #49902
- PR #49910
- PR #49390
- PR #50027

Generated with script/docs-suggest-publish for human review in draft PR.
morgankrey added a commit that referenced this pull request Feb 25, 2026
Auto-applied documentation from:
- PR #48619: agent single_file_review default change
- PR #48978: enriched symbol names in outline
- PR #49015: audio device selection for collab
- PR #47095: MCP error handling
- PR #47475: OpenRouter default model requirement

Skipped (already documented):
- PR #49139, PR #48780, PR #48988, PR #47860
@boozook

boozook commented Feb 26, 2026

Copy link
Copy Markdown

Thank you so much! It's just a salvation from the inferiority of some "comment TODO highlighting" plugin!
Before ("document_symbols": "off"):
Screenshot 2026-02-26 at 20 19 00

After ("document_symbols": "on"):
Screenshot 2026-02-26 at 20 19 20

I'm so happy now, thank you @SomeoneToIgnore and all!

mikebronner added a commit to mike-bronner/zed-laravel that referenced this pull request May 23, 2026
Zed's outline panel is tree-sitter-driven by default — LSP documentSymbol
only fires when users opt into "document_symbols": "on" per-language
setting (added in zed-industries/zed#48780). When they do, it *replaces*
tree-sitter outlines with LSP ones, so the previous version would have
regressed controllers/jobs/services to empty outlines. This change makes
enabling the Zed setting a strict upgrade.

- New php_outline.rs: tree-sitter PhpFileStructure with classes /
  interfaces / traits / enums + methods + properties + free functions.
  Visibility, return types, and extends clauses preserved.
- Livewire and Model extractors now consume the structured output and
  apply their respective filters (public-only / relationship+scope).
  Only one parse per file.
- New generic-PHP path emits the full class structure for any .php file
  outside routes/ — matches tree-sitter outline.scm parity plus Laravel
  sugar (route files, Blade nesting, Livewire/Eloquent specialisation).
- FileKind simplified to {RouteFile, Blade, Php, Other}; Livewire/Model/
  Generic differentiation happens inside extraction.
- LSP SymbolKind mapper handles new Interface/Trait/Enum variants.
- 17 new tests (13 for php_outline tree-sitter walker, 4 for generic-PHP
  scenarios including multi-class files, function_exists-guarded helpers,
  and the "no extends" path).
mikebronner added a commit to mike-bronner/zed-laravel that referenced this pull request May 23, 2026
Zed's outline panel is tree-sitter-driven by default — LSP documentSymbol
only fires when users opt into "document_symbols": "on" per-language
setting (added in zed-industries/zed#48780). When they do, it *replaces*
tree-sitter outlines with LSP ones, so the previous version would have
regressed controllers/jobs/services to empty outlines. This change makes
enabling the Zed setting a strict upgrade.

- New php_outline.rs: tree-sitter PhpFileStructure with classes /
  interfaces / traits / enums + methods + properties + free functions.
  Visibility, return types, and extends clauses preserved.
- Livewire and Model extractors now consume the structured output and
  apply their respective filters (public-only / relationship+scope).
  Only one parse per file.
- New generic-PHP path emits the full class structure for any .php file
  outside routes/ — matches tree-sitter outline.scm parity plus Laravel
  sugar (route files, Blade nesting, Livewire/Eloquent specialisation).
- FileKind simplified to {RouteFile, Blade, Php, Other}; Livewire/Model/
  Generic differentiation happens inside extraction.
- LSP SymbolKind mapper handles new Interface/Trait/Enum variants.
- 17 new tests (13 for php_outline tree-sitter walker, 4 for generic-PHP
  scenarios including multi-class files, function_exists-guarded helpers,
  and the "no extends" path).
mikebronner added a commit to mike-bronner/zed-laravel that referenced this pull request May 23, 2026
* feat: ✨ Implement textDocument/documentSymbol for outline panels (closes #12)

Surfaces Laravel-aware structure to outline-supporting editors (Zed
outline, Helix symbol picker, Neovim aerial, etc.) for four file kinds:

- Route files: METHOD URI [name=...] per Route::verb() call
- Blade: @section / @Push / @stack / @yield / @component with nesting
- Livewire components: class + public properties + public methods
- Eloquent models: class + relationship methods + scope* methods

Extraction is centralized in document_symbols.rs (LSP-agnostic, pure
functions) and memoized through the Salsa actor per file version,
mirroring the existing parse_blade_loop_blocks pattern. Cache is
invalidated on did_change and on file removal.

* feat: ✨ Extend documentSymbol to plain PHP files via tree-sitter

Zed's outline panel is tree-sitter-driven by default — LSP documentSymbol
only fires when users opt into "document_symbols": "on" per-language
setting (added in zed-industries/zed#48780). When they do, it *replaces*
tree-sitter outlines with LSP ones, so the previous version would have
regressed controllers/jobs/services to empty outlines. This change makes
enabling the Zed setting a strict upgrade.

- New php_outline.rs: tree-sitter PhpFileStructure with classes /
  interfaces / traits / enums + methods + properties + free functions.
  Visibility, return types, and extends clauses preserved.
- Livewire and Model extractors now consume the structured output and
  apply their respective filters (public-only / relationship+scope).
  Only one parse per file.
- New generic-PHP path emits the full class structure for any .php file
  outside routes/ — matches tree-sitter outline.scm parity plus Laravel
  sugar (route files, Blade nesting, Livewire/Eloquent specialisation).
- FileKind simplified to {RouteFile, Blade, Php, Other}; Livewire/Model/
  Generic differentiation happens inside extraction.
- LSP SymbolKind mapper handles new Interface/Trait/Enum variants.
- 17 new tests (13 for php_outline tree-sitter walker, 4 for generic-PHP
  scenarios including multi-class files, function_exists-guarded helpers,
  and the "no extends" path).

* refactor: ♻️ Refine documentSymbol scope after real-world testing

Three connected changes informed by opening the outline panel on real
Laravel projects and noticing what was missing, broken, or duplicated.

**Tree-sitter route outline (route_outline.rs)**

Replaces the regex-based route extractor with a proper tree-sitter walker
that follows `Route::*` call chains. Handles:

- Nested `Route::group(...)` containers — emitted as hierarchical
  symbols labelled `group [prefix=/api, name=api.]`, with their child
  routes nested inside
- All Route methods: get/post/put/patch/delete/options/any/match/view/
  redirect/permanentRedirect/fallback/livewire/resource/apiResource/
  singleton/apiSingleton
- Prefix and name chains via `->prefix(...)` and `->name(...)` with
  inheritance from the enclosing group
- Closures inside group calls get the closure expression range (not the
  wider chain) and `kind: Function` so Zed's outline doesn't overlay a
  `Closure` child node inside the group

**Extended Blade outline**

`extract_blade_symbols` now covers the modern tag-based component
syntax in addition to `@` directives:

- `<x-button>`, `<livewire:counter>`, `<flux:icon>` — paired tags
  nest their children; self-closing tags emit as leaves with ` />` in
  the label so source shape is visible
- `<x-slot:header>` and `<x-slot name="footer">` — both forms render
  uniformly as `<x-slot:NAME>`
- `@props(['title', ...])` — captures the first declared prop
- `@include`, `@includeIf`, `@includeWhen`, `@includeUnless`,
  `@includeFirst` — each labelled with its target

Directive argument parsing now uses a balanced-paren scanner so
`@includeWhen($user->method(), 'partial')` and `@props(['a','b'])`
parse correctly.

**Drop PHP class outline; delegate to PHP LSP**

Most Zed users with Laravel projects have the `php` extension installed,
which registers Intelephense / Phpactor / PhpTools. Those servers
return their own documentSymbol responses, and Zed merges responses
across all LSPs serving a file — so anything we emit for `.php` files
shows up twice in the outline panel: once with our rich labels and
once with the PHP LSP's bare names + locals + catch clauses.

We can't deduplicate from our side and our tree-sitter approximation
doesn't add Laravel-specific information at the class-member level that
Intelephense doesn't already cover. So `FileKind::Php` now returns
empty and we keep our contribution focused on shapes the PHP LSP
can't see: routes and Blade.

`php_outline.rs` stays as a reusable PHP structure parser (with
parameter extraction added) for potential future use in hover or
completions, but it's no longer wired into documentSymbol.

**Other**

- README rewritten to describe the new scope (outline section and
  feature list) and to explain that PHP outlines come from the user's
  PHP LSP, not from us
- Diagnostic logging added to `Backend::document_symbol` for future
  troubleshooting of LSP-merge issues like the one this commit
  responds to

* docs: 📝 Outline panel — requirements, config, scope

Spell out the prerequisites and configuration for the LSP-driven outline:

- A Requirements table mapping each outline kind (route files, Blade,
  PHP classes) to the extensions and `document_symbols` settings that
  must be in place
- A combined settings.json snippet showing `document_symbols: on` for
  both `PHP` (unlocks our route outline + your PHP LSP's class outline)
  and `Blade` (unlocks our Blade outline)
- Inline list of every recognised Route method (resource, apiResource,
  singleton, livewire, ...) and Blade construct (`@props`, `<x-slot:*>`,
  `<flux:*>`, ...) so users know what's covered without reading source
- Concrete example tree for a nested route group with inherited prefix
  and name chains
- Explicit pointer to the official PHP Zed extension as the recommended
  way to get a PHP LSP, with a troubleshooting note for when class
  outlines are missing
jasonsmithio pushed a commit to paddleboarddev/paddleboard that referenced this pull request May 31, 2026
Follow-up of zed-industries/zed#48780

Fixes incorrect multi byte characters treatment in the symbol range when
highlighting:
<img width="1728" height="507" alt="image"
src="https://github.com/user-attachments/assets/c6639220-f08a-4ea8-bf99-926566e356ae"
/>

Fixes multiple language servers' duplicate data display:
<img width="1726" height="925" alt="image"
src="https://github.com/user-attachments/assets/ca98ee29-732e-4c8e-adf4-21a9523a5a9c"
/>


Release Notes:

- N/A
jonx pushed a commit to jonx/zed-aros that referenced this pull request Jul 17, 2026
jonx pushed a commit to jonx/zed-aros that referenced this pull request Jul 17, 2026
Follow-up of zed-industries#48780

Fixes incorrect multi byte characters treatment in the symbol range when
highlighting:
<img width="1728" height="507" alt="image"
src="https://github.com/user-attachments/assets/c6639220-f08a-4ea8-bf99-926566e356ae"
/>

Fixes multiple language servers' duplicate data display:
<img width="1726" height="925" alt="image"
src="https://github.com/user-attachments/assets/ca98ee29-732e-4c8e-adf4-21a9523a5a9c"
/>


Release Notes:

- N/A
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

cla-signed The user has signed the Contributor License Agreement staff Pull requests authored by a current member of Zed staff

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Populate Outline Panel from language server textDocument/documentSymbol

2 participants