A Cursor / VS Code extension that turns text into clickable links based on regex patterns — in both the editor and the integrated terminal.
- Define regex rules that make matching text clickable anywhere in the editor
- Same rules also intercept matching text in the integrated terminal
- Supports capture group substitution (
$0,$1, …) for dynamic URLs - Rules can be scoped to specific editor languages
- Live reload — config changes apply instantly without restarting
- VS Code or Cursor 1.58.0 or newer — the terminal link provider API was finalized in 1.58
- Node.js 20 or newer to build.
@vscode/vsce3.x declaresengines: { node: ">= 20" }; on Node 18 packaging dies withReferenceError: File is not definedfrom its bundledundici. npm only warns about the mismatch instead of blocking, so the failure surfaces at run time.
git clone https://github.com/mc-nv/cursor-link-patterns
cd cursor-link-patterns
npm install
npm run compile
npx @vscode/vsce packageThen in Cursor or VS Code:
- Open the Command Palette (
Cmd+Shift+P) - Run
Extensions: Install from VSIX... - Select the generated
cursor-link-patterns-*.vsixfile
Or from the command line:
code --install-extension cursor-link-patterns-*.vsixCursor ships its own
codeshim. If Cursor is installed,which codemay resolve to…/.cursor-server/bin/…/bin/remote-cli/code, and the extension will land in Cursor rather than VS Code. Check first, and over SSH or in a devcontainer install from the remote side — the extension host runs there, so a local install is never loaded.
Cursor is not served by the Visual Studio Marketplace — it resolves extensions through its own
gallery (marketplace.cursorapi.com), so a VSIX built locally has to be side-loaded.
Local Cursor
cursor --install-extension cursor-link-patterns-*.vsix --force--force is required when reinstalling a version that is already present; without it the CLI
reports the extension as already installed and exits.
Remote Cursor (SSH / devcontainer / WSL)
The cursor and code commands on PATH inside a remote session are thin shims that need a live
window. To install headlessly, call the server binary directly on the remote host:
~/.cursor-server/bin/linux-x64/<commit-hash>/bin/cursor-server \
--install-extension cursor-link-patterns-*.vsix --forceSubstitute the single directory under ~/.cursor-server/bin/linux-x64/. Extensions land in
~/.cursor-server/extensions/.
Verifying
cursor --list-extensions --show-versions | grep cursor-link-patterns~/.cursor-server/extensions/extensions.json records what is actually registered — an entry with
"source": "vsix" was side-loaded, "gallery" came from the registry. A stale version directory
may linger next to the new one after an upgrade; only the manifest entry matters, and Cursor
removes the leftover on its next start.
Reload the window (Developer: Reload Window) to activate a freshly installed version.
npm install
npm run compileOpen the project folder in Cursor and press F5 to launch an Extension Development Host.
Add rules to your user, workspace, or .code-workspace settings:
"cursorLinkPatterns.rules": [
{
"linkPattern": "TRI-(\\d+)",
"linkTarget": "https://linear.app/issue/TRI-$1",
"languages": ["*"]
}
]| Property | Required | Description |
|---|---|---|
linkPattern |
Yes* | Regular expression to match. Can also be an array of patterns that share the same linkTarget |
linkPatterns |
Yes* | Array of regex patterns sharing the same linkTarget. Merged with linkPattern if both are set |
linkTarget |
Yes | URL template — $0 full match, $1 first capture group, etc. Use \$ for a literal $ |
linkPatternFlags |
No | Regex flags e.g. "i" for case-insensitive. g is always added automatically |
languages |
No | Editor language IDs to apply the rule to. Defaults to ["*"] (all). Has no effect on terminal links |
* At least one of linkPattern or linkPatterns must be set.
Linear / Jira tickets
{
"linkPattern": "TRI-(\\d+)",
"linkTarget": "https://linear.app/issue/TRI-$1"
}GitHub PRs
{
"linkPattern": "PR#(\\d+)",
"linkTarget": "https://github.com/my-org/my-repo/pull/$1"
}Only in markdown files
{
"linkPattern": "DOCS-(\\d+)",
"linkTarget": "https://confluence.example.com/pages/$1",
"languages": ["markdown"]
}Multiple patterns sharing one target
{
"linkPatterns": [
"TRI-(\\d+)",
"ENG-(\\d+)",
"OPS-(\\d+)"
],
"linkTarget": "https://linear.app/issue/$0"
}Rules can be added per workspace in a .code-workspace file:
{
"folders": [...],
"settings": {
"cursorLinkPatterns.rules": [
{
"linkPattern": "TRI-(\\d+)",
"linkTarget": "https://linear.app/issue/TRI-$1"
}
]
}
}A
.code-workspaceonly applies when you open the file itself, viaFile → Open Workspace from File…— the title bar then reads "… (Workspace)". Open the same directory as a plain folder and the file is inert: both itssettingsand itsextensions.recommendationsare ignored, and rules must live in.vscode/settings.jsoninstead.
Note that extensions.recommendations never installs anything on its own — it only surfaces a
prompt. The extension still has to be installed.
MIT