Add hyperlinks language server - #6949
Conversation
Turns text matching regex rules into clickable links via a language server implementing textDocument/documentLink, configured through the hyperlinkRules array in Zed LSP settings.
Adds semantic-token highlighting of matches.
|
We require contributors to sign our Contributor License Agreement, and we don't have @krawitzzZ on file. You can sign our CLA at https://zed.dev/cla. Once you've signed, post a comment here that says '@cla-bot check'. |
@cla-bot check |
|
The cla-bot has been summoned, and re-checked this pull request! |
MrSubidubi
left a comment
There was a problem hiding this comment.
Thanks for this!
Please make sure your extension fulfills the extension publishing prerequisites. Particularly, you will need to update your extension ID as outlined in the documentation. Once you did the necessary updates, please update everything related here. Thanks!
Thanks for the review! I've renamed the extension into |
MrSubidubi
left a comment
There was a problem hiding this comment.
Could you please elaborate why https://github.com/krawitzzZ/zed-hyperlinks/blob/cc667162dfc90f4304744280b6d412290db6b4e9/src/lib.rs#L42-L51 is needed?
Also, you are invoking a JS language server - please publish that to NPM as described in our extension publishing prerequisites - we'll soon clarify this.
Also, you seem to use the same settings for both the initialization as well as the workspace settings request, which seems odd.
Thanks for the review!
NPM — the language server is now published to npm as Init vs workspace settings — that was incorrect. They now map separately:
Rules stay under I've updated the submodule to |
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 extensiondlevs/vscode-pattern-linksto Zed.hyperlinks-lspHow it works
Zed renders links returned by language servers through the LSP
textDocument/documentLinkrequest (added in zed#56011, enabled by default). The extension provides a tiny language server that scans open documents for the configured regex rules and returns aDocumentLinkfor 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 (JSRegExp).The server additionally reports a custom
hyperlinkLSP semantic token for every match, so matched text can be visually highlighted (see 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-serverrepo (main.jsasset, version pinned insrc/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 viaset_language_server_installation_status(Failed).Configuration
There is no per-extension settings UI, so rules live under the language server's settings:
{ "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;galways applied)languages(optional list of LSPlanguageIds 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
hyperlinksemantic token per match (multi-line matches are split into one token per line, as LSP requires). Users opt in viasettings.jsonby enabling semantic tokens (off by default) and adding a rule for thehyperlinktoken type:{ "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+ ahyperlinkrule 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 coveringdocumentLinkandsemanticTokens/full.Extension:
cargo testfor the version/path helpers;cargo build --target wasm32-wasip1passes.I've read CONTRIBUTING.md and followed the relevant guidance for adding or updating my extension.