Skip to content

Support LSP document links - #56011

Merged
SomeoneToIgnore merged 1 commit into
mainfrom
kb/document-links
May 26, 2026
Merged

Support LSP document links#56011
SomeoneToIgnore merged 1 commit into
mainfrom
kb/document-links

Conversation

@SomeoneToIgnore

@SomeoneToIgnore SomeoneToIgnore commented May 7, 2026

Copy link
Copy Markdown
Contributor

Closes #33587

LSP.document.links.mov

Release Notes:

  • Supported LSP document links (enabled by default, use "lsp_document_links": false to turn it off)

@SomeoneToIgnore SomeoneToIgnore self-assigned this May 7, 2026
@cla-bot cla-bot Bot added the cla-signed The user has signed the Contributor License Agreement label May 7, 2026
@zed-community-bot zed-community-bot Bot added the staff Pull requests authored by a current member of Zed staff label May 7, 2026
@SomeoneToIgnore
SomeoneToIgnore force-pushed the kb/document-links branch 10 times, most recently from 9d2ae70 to a50b793 Compare May 8, 2026 09:27
@SomeoneToIgnore
SomeoneToIgnore marked this pull request as ready for review May 8, 2026 09:39
@SomeoneToIgnore
SomeoneToIgnore requested a review from Veykril May 8, 2026 09:39
@SomeoneToIgnore
SomeoneToIgnore force-pushed the kb/document-links branch 2 times, most recently from e660f37 to 96ce1de Compare May 8, 2026 12:28
# Conflicts:
#	crates/editor/src/editor.rs
@SomeoneToIgnore
SomeoneToIgnore added this pull request to the merge queue May 26, 2026
Merged via the queue into main with commit 3e77442 May 26, 2026
33 checks passed
@SomeoneToIgnore
SomeoneToIgnore deleted the kb/document-links branch May 26, 2026 07:12
@aviatesk

aviatesk commented May 26, 2026

Copy link
Copy Markdown
Collaborator

Dynamic registration seems to need to be fixed. Opened a follow up PR: #57749

aviatesk added a commit to aviatesk/zed that referenced this pull request May 26, 2026
`register_server_capabilities` / `unregister_server_capabilities` had no
arm for `textDocument/documentLink`, so when a server saw our
`documentLink.dynamicRegistration` capability and chose to register
the provider dynamically, the registration silently fell into the
`unhandled capability registration` warning. `document_link_provider`
stayed `None`, `GetDocumentLinks::check_capabilities` returned false,
and no `textDocument/documentLink` request was ever sent.

Fixes up zed-industries#56011.

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
fjgbue pushed a commit to fjgbue/zed that referenced this pull request May 26, 2026
…dustries#57749)

`register_server_capabilities` / `unregister_server_capabilities` had no
arm for `textDocument/documentLink`, so when a server saw our
`documentLink.dynamicRegistration` capability and chose to register the
provider dynamically, the registration silently fell into the `unhandled
capability registration` warning. `document_link_provider` stayed
`None`, `GetDocumentLinks::check_capabilities` returned false, and no
`textDocument/documentLink` request was ever sent.

Follow-up to zed-industries#56011

Release Notes:

- N/A

Co-authored-by: Claude Opus 4.7 <noreply@anthropic.com>
@aviatesk

Copy link
Copy Markdown
Collaborator

One more follow-up I wonder about: should we render document link ranges as underlined by default, similar to how VS Code does?

Right now, textDocument/documentLink seems to be surfaced mostly like textDocument/definition and it becomes visible when hovering or command-clicking a position. But documentLink is document-scoped rather than position-scoped. So unlike textDocument/definition, the server can return all jumpable link ranges for the document in one request, and each DocumentLink already includes the range it applies to. In that sense it feels closer to documentColor, diagnostics, or code lenses, and once we have the document-level data, surfacing it directly in the editor improves discoverability.

Would you be open to that as a follow-up?

@SomeoneToIgnore

SomeoneToIgnore commented May 27, 2026

Copy link
Copy Markdown
Contributor Author

I'd ask a designer for that, myself is not very open to that as it adds more visual noise than needed.

@aviatesk

Copy link
Copy Markdown
Collaborator

Understood. I think the noise argument has a validity. Since I only mentioned it as a tentative suggestion, I will hold off on upstreaming this idea for now.

jasonsmithio pushed a commit to paddleboarddev/paddleboard that referenced this pull request May 31, 2026
`register_server_capabilities` / `unregister_server_capabilities` had no
arm for `textDocument/documentLink`, so when a server saw our
`documentLink.dynamicRegistration` capability and chose to register the
provider dynamically, the registration silently fell into the `unhandled
capability registration` warning. `document_link_provider` stayed
`None`, `GetDocumentLinks::check_capabilities` returned false, and no
`textDocument/documentLink` request was ever sent.

Follow-up to zed-industries/zed#56011

Release Notes:

- N/A

Co-authored-by: Claude Opus 4.7 <noreply@anthropic.com>
TomPlanche pushed a commit to TomPlanche/zed that referenced this pull request Jun 2, 2026
Closes zed-industries#33587


https://github.com/user-attachments/assets/bbaea8a9-402e-485b-800e-2f4486142956

Release Notes:

- Supported LSP document links (enabled by default, use
`"lsp_document_links": false` to turn it off)
TomPlanche pushed a commit to TomPlanche/zed that referenced this pull request Jun 2, 2026
…dustries#57749)

`register_server_capabilities` / `unregister_server_capabilities` had no
arm for `textDocument/documentLink`, so when a server saw our
`documentLink.dynamicRegistration` capability and chose to register the
provider dynamically, the registration silently fell into the `unhandled
capability registration` warning. `document_link_provider` stayed
`None`, `GetDocumentLinks::check_capabilities` returned false, and no
`textDocument/documentLink` request was ever sent.

Follow-up to zed-industries#56011

Release Notes:

- N/A

Co-authored-by: Claude Opus 4.7 <noreply@anthropic.com>
jonx pushed a commit to jonx/zed-aros that referenced this pull request Jul 17, 2026
Closes zed-industries#33587


https://github.com/user-attachments/assets/bbaea8a9-402e-485b-800e-2f4486142956

Release Notes:

- Supported LSP document links (enabled by default, use
`"lsp_document_links": false` to turn it off)
jonx pushed a commit to jonx/zed-aros that referenced this pull request Jul 17, 2026
…dustries#57749)

`register_server_capabilities` / `unregister_server_capabilities` had no
arm for `textDocument/documentLink`, so when a server saw our
`documentLink.dynamicRegistration` capability and chose to register the
provider dynamically, the registration silently fell into the `unhandled
capability registration` warning. `document_link_provider` stayed
`None`, `GetDocumentLinks::check_capabilities` returned false, and no
`textDocument/documentLink` request was ever sent.

Follow-up to zed-industries#56011

Release Notes:

- N/A

Co-authored-by: Claude Opus 4.7 <noreply@anthropic.com>
jolutz pushed a commit to jolutz/zed that referenced this pull request Aug 8, 2026
Closes zed-industries#33587


https://github.com/user-attachments/assets/bbaea8a9-402e-485b-800e-2f4486142956

Release Notes:

- Supported LSP document links (enabled by default, use
`"lsp_document_links": false` to turn it off)
pull Bot pushed a commit to ashusevim/extensions that referenced this pull request Aug 21, 2026
# Summary

Adds **Hyperlinks**, an extension that turns text matching user-defined
regex patterns into clickable links in the editor — e.g. `ISSUE-123` →
your issue tracker, `#42` → a GitHub issue. It's a port of the VS Code
extension
[`dlevs/vscode-pattern-links`](https://github.com/dlevs/vscode-pattern-links)
to Zed.

- Extension repo: https://github.com/krawitzzZ/zed-hyperlinks
- Language server repo:
https://github.com/krawitzzZ/zed-hyperlinks-server
- Extension ID: `hyperlinks-lsp`

## How it works

Zed renders links returned by language servers through the LSP
`textDocument/documentLink` request (added in
[zed#56011](zed-industries/zed#56011), enabled
by default). The extension provides a tiny language server that scans
open documents for the configured regex rules and returns a
`DocumentLink` for each match, with the target URL built from a template
(`$0` = whole match, `$1`, `$2`, … = capture groups; `\$` for a literal
`$`). Matching semantics mirror the upstream VS Code extension (JS
`RegExp`).

The server additionally reports a custom `hyperlink` LSP semantic token
for every match, so matched text can be visually highlighted (see
[Highlighting](#highlighting)).

## Why the language server is downloaded, not bundled

Per the publishing guidelines, the extension does not ship the language
server. Instead, the WASM extension downloads it at runtime from a
pinned GitHub release of the separate
[`zed-hyperlinks-server`](https://github.com/krawitzzZ/zed-hyperlinks-server)
repo (`main.js` asset, version pinned in `src/lib.rs`), caches it under
the extension's work dir, cleans up older cached versions, and runs it
with Zed's bundled Node (`node_binary_path`). Download failures surface
via `set_language_server_installation_status(Failed)`.

## Configuration

There is no per-extension settings UI, so rules live under the language
server's settings:

```json
{
  "lsp": {
    "hyperlinks": {
      "settings": {
        "hyperlinkRules": [
          {
            "linkPattern": "ISSUE-\\d+",
            "linkTarget": "https://myorg.atlassian.net/browse/$0"
          },
          {
            "linkPattern": "#(\\d+)",
            "linkTarget": "https://github.com/my-org/my-repo/issues/$1",
            "languages": ["markdown", "plaintext"]
          }
        ]
      }
    }
  }
}
```

Per-rule fields:

- `linkPattern` (required)
- `linkTarget` (required)
- `linkPatternFlags` (optional JS regex flags; `g` always applied)
- `languages` (optional list of LSP `languageId`s to scope the rule;
empty = all)

## Highlighting

Zed doesn't style document links on its own, so matches are clickable
but look like ordinary text by default. The server therefore emits a
custom `hyperlink` semantic token per match (multi-line matches are
split into one token per line, as LSP requires). Users opt in via
`settings.json` by enabling semantic tokens (off by default) and adding
a rule for the `hyperlink` token type:

```json
{
  "semantic_tokens": "combined",
  "global_lsp_settings": {
    "semantic_token_rules": [
      { "token_type": "hyperlink", "underline": true, "foreground_color": "#4c9df3" }
    ]
  }
}
```

The extension intentionally does not ship default semantic token rules:
it provides a language server (not a language), and per Zed's docs
shipping rules that way can override/break other language servers'
configuration. Styling is left to the user's `semantic_token_rules`.

## Note on supported languages

Zed has no "all languages" wildcard for extension-provided language
servers, so the server is attached to an explicit list of common
languages in `extension.toml` (Plain Text, Markdown, and popular
programming languages). This is the closest equivalent to the VS Code
extension's "all languages" default; more can be added on request.

## Testing

- Installed and tested locally as a dev extension (links appear and open
on Cmd/Ctrl-click; matches highlight once `semantic_tokens` + a
`hyperlink` rule are set).
- Language server (`node --test`, 31 tests): substitution, rule
normalization, offset/position math, link computation, semantic-token
encoding (single-line, delta-encoded multi-match, multi-line splitting,
language filtering), plus end-to-end stdio LSP sessions covering
`documentLink` and `semanticTokens/full`.
- Extension: `cargo test` for the version/path helpers; `cargo build
--target wasm32-wasip1` passes.

- [x] I've read [CONTRIBUTING.md](../CONTRIBUTING.md) and followed the
relevant guidance for adding or updating my extension.
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.

LSP: support for document links (textDocument/documentLink)

3 participants