Skip to content

Feat/hyperlinks#6949

Open
krawitzzZ wants to merge 3 commits into
zed-industries:mainfrom
krawitzzZ:feat/hyperlinks
Open

Feat/hyperlinks#6949
krawitzzZ wants to merge 3 commits into
zed-industries:mainfrom
krawitzzZ:feat/hyperlinks

Conversation

@krawitzzZ

Copy link
Copy Markdown

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 to Zed.

How it works

Zed renders links returned by language servers through the LSP textDocument/documentLink request (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 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).

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 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:

{
  "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 languageIds 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:

{
  "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.

  • I've read CONTRIBUTING.md and followed the relevant guidance for adding or updating my extension.

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.
@cla-bot

cla-bot Bot commented Jul 24, 2026

Copy link
Copy Markdown

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'.

@krawitzzZ

Copy link
Copy Markdown
Author

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

@cla-bot cla-bot Bot added the cla-signed label Jul 24, 2026
@cla-bot

cla-bot Bot commented Jul 24, 2026

Copy link
Copy Markdown

The cla-bot has been summoned, and re-checked this pull request!

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

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant