LinkFile
A VSCode extension that lets you put the same @link:<id> marker in code and in Markdown docs, and then Ctrl+click (or Cmd+click on macOS) jumps between them. Designed for linking design docs to their implementation (and back).
How it works
LinkFile scans your workspace for a configurable keyword (default @link:) followed by an ID, builds a bidirectional index, and exposes each occurrence as a clickable link, hover preview, and command target.
┌──────────────────────────┐ ┌─────────────────────────────┐
│ src/auth.ts │ │ docs/design/auth.md │
│ │ shared │ │
│ // @link:auth-flow │<────────->│ <!-- @link:auth-flow --> │
│ export function login() │ ID │ │
│ │ │ ## 登录流程 │
└──────────────────────────┘ └─────────────────────────────┘
- Code → Doc: Ctrl+click
@link:auth-flow in auth.ts opens the matching doc anchor.
- Doc → Code: Ctrl+click
@link:auth-flow in auth.md. If multiple code locations declare the same ID, a Quick Pick lets you choose.
- Hover: see a preview of the other side without leaving the current file.
Features
- Bidirectional Ctrl+click navigation between code and Markdown docs
- Shared-ID model — any file that contains
@link:<id> joins the link
- Auto Quick Pick when an ID has multiple targets on the other side
- Hover preview showing the linked file, line number, and the first few lines
- Force-directed graph panel with a 2D / 3D toggle for visualizing file-to-file link relationships
- Commands: Go to Linked, Show References, Insert Anchor, Rebuild Index, Show 3D Force Graph, Show 2D Force Graph
- Status bar item showing the current number of indexed IDs
- Live updates while you type (debounced) and via a file system watcher
- Configurable: keyword, ID pattern, doc/code/exclude globs, preview size
- Works with any language: the anchor is detected by raw text, independent of comment syntax
Usage example
Put anchors on both sides using the same ID.
src/payments/checkout.ts:
// @link:payment-flow
export async function checkout(cart: Cart) {
// ...
}
docs/design/payments.md:
<!-- @link:payment-flow -->
## Checkout flow
The checkout endpoint performs the following steps ...
Now:
- In
checkout.ts, Ctrl+click @link:payment-flow → jumps to the doc anchor.
- In
payments.md, Ctrl+click @link:payment-flow → jumps to the code anchor (or shows a Quick Pick if you have multiple).
- Hover either anchor to see a preview of the linked location.
- Press
Ctrl+Alt+L (or Cmd+Alt+L on macOS) on an anchor for the same effect without clicking.
Commands
| Command |
Default keybinding |
Description |
LinkFile: Go to Linked |
Ctrl+Alt+L / Cmd+Alt+L |
Jump to the opposite-side anchor with the same ID |
LinkFile: Show References |
Ctrl+Alt+Shift+L / Cmd+Alt+Shift+L |
Quick Pick listing all code + doc references for an ID |
LinkFile: Insert Anchor |
— |
Insert an @link:<id> snippet (pick existing ID or create a new one) |
LinkFile: Rebuild Index |
— |
Force a full re-scan of the workspace |
LinkFile: Show 3D Force Graph |
Ctrl+Alt+G / Cmd+Alt+G |
Open the force graph panel in 3D mode |
LinkFile: Show 2D Force Graph |
Ctrl+Alt+2 / Cmd+Alt+2 |
Open the force graph panel in 2D mode |
Force Graph Panel
Run LinkFile: Show 3D Force Graph (Ctrl+Alt+G) or LinkFile: Show 2D Force Graph (Ctrl+Alt+2) from the Command Palette. Both commands target the same panel — the only difference is the initial rendering mode. A webview panel opens with:
- Left side — a searchable, single-select list of every file that contains at least one
@link:<id> anchor. The dot turns deep purple when a file is selected and light purple when it's a 1-hop neighbor; the number on the right is the anchor count.
- Right side — a force-directed graph. Every node is a file; every edge is the merged connection between two files. Hovering an edge shows the shared
@link: IDs.
- 2D / 3D tab in the top-right of the graph area. Click
2D to swap the renderer to force-graph; click 3D to swap back to 3d-force-graph. The current selection, camera-independent state, and overlay labels are preserved across the switch; the panel title also updates.
Interactions:
- Single-click a node or a list entry → selects that file (deep purple). Its 1-hop neighbors and every link chip between them are labeled on the graph. Clicking again or clicking the background clears the selection.
- Double-click a node or a list entry → opens that file in the editor at the first anchor line.
- Hover a node → tooltip shows full workspace path, kind, anchor count.
- Hover an edge → tooltip lists every shared ID between the two files.
Clear / Fit buttons in the toolbar: clear selection or recenter the camera.
- Filter box at the top filters the file list.
Node colors follow selection state (default gray, selected deep purple, linked light purple). Colors pick up VSCode theme variables where possible, so the panel blends with your theme.
Configuration
All settings live under linkFile.*:
| Setting |
Default |
Description |
linkFile.keyword |
@link: |
Prefix that introduces an anchor. Change it to @doc:, @ref:, etc. |
linkFile.idPattern |
[\w\-\./]+ |
Regex (no anchors/flags) for a valid ID |
linkFile.docGlobs |
["**/*.md", "**/*.mdx", "**/*.markdown"] |
Files treated as docs |
linkFile.codeGlobs |
["**/*"] |
Files scanned as code (docs take precedence) |
linkFile.exclude |
["**/node_modules/**", "**/.git/**", "**/dist/**", "**/out/**", "**/build/**", "**/.vscode-test/**"] |
Exclusion globs |
linkFile.maxFileSizeKB |
512 |
Skip files larger than this for performance |
linkFile.updateDebounceMs |
200 |
Debounce while typing |
linkFile.previewLines |
6 |
Lines shown in hover previews |
Changing any linkFile.* setting triggers an automatic re-index.
Build & debug
Requires Node 18+ and VSCode 1.85+.
npm install # install dev dependencies
npm run compile # one-shot build → dist/extension.js
npm run watch # esbuild in watch mode
npm run typecheck # tsc --noEmit
To launch a debug instance:
- Open this folder in VSCode.
- Press
F5 (runs the Run Extension launch configuration).
- A new Extension Development Host window opens with LinkFile loaded.
- Open a folder that contains some
.ts / .md files with @link:... anchors and try Ctrl+click.
Packaging
npx @vscode/vsce package
Produces a .vsix you can install with code --install-extension linkfile-0.1.0.vsix or via the Extensions view → ... → Install from VSIX.
Limitations (by design, for now)
- Clicks inside the Markdown preview are not yet supported. Preview is a sandboxed webview and requires a separate
markdown.markdownItPlugins integration; planned for a future release.
- Cross-workspace and cross-repo links are not followed.
- There is no automated rename refactor for IDs yet — rename via workspace-wide find & replace.
License
MIT