Skip to content

lsp: Honor dynamic LSP document selectors#59243

Open
aviatesk wants to merge 1 commit into
zed-industries:mainfrom
aviatesk:lsp-select-aware-routing
Open

lsp: Honor dynamic LSP document selectors#59243
aviatesk wants to merge 1 commit into
zed-industries:mainfrom
aviatesk:lsp-select-aware-routing

Conversation

@aviatesk

Copy link
Copy Markdown
Contributor

Previously, Zed ignored the documentSelector of a dynamically registered textDocument capability and treated every such capability as global to all buffers opened in the server. As a result, Zed could route a request to a server for a document outside the registration's selector -- for example, a URI whose language matches the selector but whose scheme the server never registered for (and is thus unknown to it). I do not think Zed exhibits this in practice today, but it is possible in principle and violates the LSP specification.

Track textDocument dynamic registrations by method and registration id so Zed can keep each registration's documentSelector instead of treating dynamically registered capabilities as global for every open buffer.

Use the stored selectors when routing local LSP requests, including single-server requests, multi-server requests, completion-specific routing, capability checks, and range-formatting availability. Static initialize-time capabilities continue to apply to every buffer attached to the server, while dynamically registered textDocument features now require a matching selector. The initial matching support covers language and URI scheme, with pattern matching intentionally left fail-open.

Update completion trigger management to derive triggers from static capabilities plus matching dynamic completion registrations, and recalculate triggers when completion registrations change. Also make pull diagnostic requests require an advertised diagnostic provider so selector-aware routing can correctly gate dynamic diagnostic registrations.

Add an integration test covering dynamic completion registrations whose selectors do and do not match the current file buffer, asserting both request routing and completion trigger updates.

Objective

  • Describe the objective or issue this PR addresses.
  • If you're fixing a specific issue, use "Fixes #X" for each issue as described in the GitHub docs.

Solution

  • Describe the solution used to achieve the objective above.

Testing

  • Did you test these changes? If so, how?
  • Are there any parts that need more testing?
  • How can other people (reviewers) test your changes? Is there anything specific they need to know?
  • If relevant, what platforms did you test these changes on, and are there any important ones you can't test?

Self-Review Checklist:

  • I've reviewed my own diff for quality, security, and reliability
  • Unsafe blocks (if any) have justifying comments
  • The content adheres to Zed's UI standards (UX/UI and icon guidelines)
  • Tests cover the new/changed behavior
  • Performance impact has been considered and is acceptable

Showcase

This section is optional. If this PR does not include a visual change or does not add a new user-facing feature, you can delete this section.

  • Help others understand the result of this PR by showcasing your awesome work!
  • If this PR includes a visual change, consider adding a screenshot, GIF, or video
    • A before/after comparison is very useful for changes to existing features!

While a showcase should aim to be brief and digestible, you can use a toggleable section to save space on longer showcases:

Click to view showcase

My super cool demos here


Release Notes:

  • N/A or Added/Fixed/Improved ...

Previously, Zed ignored the `documentSelector` of a dynamically
registered `textDocument` capability and treated every such capability
as global to all buffers opened in the server. As a result, Zed could
route a request to a server for a document outside the registration's
selector -- for example, a URI whose language matches the selector but
whose scheme the server never registered for (and is thus unknown to it).
I do not think Zed exhibits this in practice today, but it is possible
in principle and violates the LSP specification.

Track `textDocument` dynamic registrations by method and registration id
so Zed can keep each registration's `documentSelector` instead of
treating dynamically registered capabilities as global for every open
buffer.

Use the stored selectors when routing local LSP requests, including
single-server requests, multi-server requests, completion-specific
routing, capability checks, and range-formatting availability. Static
initialize-time capabilities continue to apply to every buffer attached
to the server, while dynamically registered `textDocument` features now
require a matching selector. The initial matching support covers
language and URI scheme, with pattern matching intentionally left
fail-open.

Update completion trigger management to derive triggers from static
capabilities plus matching dynamic completion registrations, and
recalculate triggers when completion registrations change. Also make
pull diagnostic requests require an advertised diagnostic provider so
selector-aware routing can correctly gate dynamic diagnostic
registrations.

Add an integration test covering dynamic completion registrations whose
selectors do and do not match the current file buffer, asserting both
request routing and completion trigger updates.
@cla-bot cla-bot Bot added the cla-signed The user has signed the Contributor License Agreement label Jun 13, 2026
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

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant