RelatiTreeRelatiTree adds a Related Files tree view to the Explorer sidebar. It shows the files related to the file you are currently editing (its service, style, test, …), plus file groups discovered by scanning the whole workspace — all driven by rules you define per workspace folder in a Relationships are described with a single path-pattern language —
Open Features
Getting startedOpen any file and run RelatiTree: Add Group for Active File… — it creates
Open If nothing shows up, run RelatiTree: Explain Matching (Active File) — it renders the full match trace of every group against the current file, and every config problem is also in the Problems panel. The pattern languagePatterns match against the file path relative to the workspace folder (POSIX-style, e.g.
Mnemonic:
Configuration referenceTop level
Groups
Static entries (
|
| Field | Description |
|---|---|
label |
Description shown next to the file. |
path |
Templated path (${var\|filter}), resolved against the workspace folder. |
alwaysShow |
Show the entry even while the file doesn’t exist (with create actions). |
template |
Templated path to a template file used by New from Template — the template’s content is expanded too. |
Dynamic entries (find)
| Field | Description |
|---|---|
label |
Section name (defaults to the first pattern). |
find / exclude |
Path pattern(s) searched across the workspace folder. May use ${var} for match captures and {name} to capture per-file variables. |
itemLabel |
Per-file label template — may use captures from find (e.g. "${variant}"). |
hideWhenEmpty |
Hide the section when nothing matches (costs an eager search). |
maxResults |
Files shown before Show more (default 100). |
collapsed |
Render the section initially collapsed. |
Alternate (bidirectional) groups
With "alternate": true, a group becomes a cluster: opening any member shows the target file plus the other entries (the file you are on is never listed), and Open Alternate File (Ctrl+Alt+A) jumps between them.
Reverse matching is defined as a round trip — a file reverse-matches only if a target exists on disk such that opening it would have shown this file in that entry. Reverse entry points are static entries whose capture references use no filters and cover every capture of the match pattern; the match pattern itself must contain only literals and captures (no wildcards). Run Explain Matching to see each entry’s eligibility, and watch the Problems panel: an alternate flag that can never fire is warned about at load time.
Template expansion
${name} is replaced by the variable’s value; ${name|filter1|filter2} pipes it through filters. Templates may nest (${a${b}}), and \${ escapes a literal ${.
Variables are resolved most-specific-last:
- Built-ins:
workspaceFolder(name),workspaceFolderPath,workspaceFolderFsPath,workspaceFolderUri - Config-level
variables - Group-level
variables - Captures from the matched file’s path (and, for
itemLabel, fromfind)
Available filters:
| Filter | Effect |
|---|---|
upper / lower |
Whole-string case change. |
upperfirst / lowerfirst |
Change only the first character. |
camel, pascal, snake, kebab, constant, dot, path, sentence, title, train, swap, sponge, no |
Case conversions (via change-case-all). |
slice:start[:end] |
String.prototype.slice semantics, e.g. ${name\|slice:0:-3}. |
replace:/pattern/flags:replacement |
Regex replace (flags default to g). |
replace:pattern:replacement[:flags] |
Literal-string replace. |
Filter names are case-insensitive; unknown or malformed filters leave the value unchanged.
Commands & keybindings
| Command | Default keybinding | Description |
|---|---|---|
| RelatiTree: Open Related File… | Ctrl+Alt+R / Cmd+Alt+R |
QuickPick over the active file’s related files. Enter opens (missing static entries are created first); the ⧉ button opens to the side without closing the picker. |
| RelatiTree: Open Alternate File | Ctrl+Alt+A / Cmd+Alt+A |
Jump across an alternate cluster. One candidate opens immediately; several go through a QuickPick. |
| RelatiTree: Explain Matching (Active File) | — | Live markdown document with every group’s match trace and all config problems. Also the ? button on the view title. |
| RelatiTree: Add Group for Active File… | — | Create the config (or append a group skeleton) for the file you have open. |
Tree actions: Open, Open to the Side (inline ⧉), Open and Set as Anchor, Copy Path / Relative Path, Reveal in Explorer View / OS File Manager, New File / New from Template on missing static entries, Open All Related Files / Open All, per-node Refresh, and Open Configuration (jumps to the group’s definition). Re-anchor to Active Editor sits on the Active File row while the anchor is detached.
Notes
- Opening from the tree or the QuickPick keeps the anchor; Open Alternate File moves it — jumping means your work moved there.
.relatedfilesrc.jsonand.relatedfilesrc.jsoncare both recognized (in that precedence order) and parsed withjsonc-parser— comments and trailing commas are supported either way.schemas/related-files.schema.json(generated from the source of truth) provides editor autocompletion/validation.- A broken config never takes the tree down: the affected folder shows a clickable Configuration error row, details go to the Problems panel, and other folders keep working.
- Workspace searches are bounded: a hard scan cap of 5,000 candidates per pattern plus a display cap (default 100,
maxResults) with an explicit Show more row. Patterns that would scan the entire workspace are flagged in the Problems panel when you save the config. - Saving the config reloads the tree and re-publishes diagnostics automatically — no manual refresh needed.
Development
npm install
npm run compile # type-check, lint, and bundle to dist/extension.js
npm run watch # esbuild + tsc in watch mode
npm test # compile + lint + vscode-test (src/test/**/*.test.ts)
npm run generate-schema # regenerate schemas/related-files.schema.json from the Zod schema
Press F5 in VS Code to launch an Extension Development Host with the extension loaded. The examples/ folder is a self-contained sample workspace (examples/examples.code-workspace) exercising every config feature.
Design records live in docs/redesign/ (pattern language & schema, QuickPick, empty-state guides, display control, alternate).