Go to Symbol in Editor: fuzzy-match the query against a symbol's full ancestor path (e.g. `prod port` → `production.server.port`)
- Dominant language
- TypeScript
- Stars
- 193k
- Forks
- 42.4k
- PR merge metrics
- PR metrics pending
Description
### Problem
`Go to Symbol in Editor` (Ctrl+Shift+O / the `@` quick access prefix) is hard to use in files where the same symbol name occurs at several places in the symbol tree. The picker shows a flat list of identically-labelled entries and there is no way to type *which one* I mean.
Minimal example — a JSON file:
```json
{
"production": {
"server": { "port": 2000 }
},
"development": {
"server": { "port": 3000 }
}
}
```
Typing `@port` lists two `port` entries, both described as `server`. Nothing I can type narrows this down to the production one — I have to fall back on arrow keys plus the preview, which defeats the purpose of the picker. The same thing happens in real files all the time: `settings.json` / `launch.json` / `*.csproj`-style config, YAML pipelines, Markdown files with repeated headings under different sections, and code with a method name repeated across several classes in one file.
I would like the query to be matched against the symbol's **ancestor path**, so that:
- `prod port` matches `production.server.port`
- `dev port` matches `development.server.port`
- `prod server` matches `production.server`
i.e. each space-separated piece of the query is fuzzy-matched against a segment of the path `production → server → port`, in path order, and the leaf still has to match the last piece.
### Why the existing container filter does not cover this
There *is* already a documented "narrow down by container" behaviour (from the quick access test plans, [#93643](https://github.com/microsoft/vscode/issues/93643) / [#93645](https://github.com/microsoft/vscode/issues/93645)): typing `foo bar` matches symbols whose **label** matches `foo` and whose **description** matches `bar`. Two things stop it from solving the case above:
1. **Only the immediate parent is available.** `OutlineModel._flattenDocumentSymbols` sets `containerName` to the direct parent's name only:
https://github.com/microsoft/vscode/blob/main/src/vs/editor/contrib/documentSymbols/browser/outlineModel.ts#L372-L389
So for both `port` symbols the container is `server`, and the grandparent (`production` / `development`) — the only part that actually distinguishes them — is never matched against and never shown.
2. **The order is fixed leaf-first.** In `doGetSymbolPicks`, `query.values[0]` scores the label and the remaining pieces score the container:
https://github.com/microsoft/vscode/blob/main/src/vs/editor/contrib/quickAccess/browser/gotoSymbolQuickAccess.ts#L250-L329
So `port prod` is the only shape the current syntax could ever accept, whereas the way people actually think about (and read) these paths is outside-in: `prod port`. Deep paths (`a.b.c.d`) have no expressible query at all.
### Proposed behaviour
For `Go to Symbol in Editor`:
- Build the full ancestor path for each flattened symbol (`production • server` for the leaf above) instead of just the direct parent.
- When the query has multiple space-separated pieces, match them against the path segments **in order**, allowing gaps — the last piece against the symbol label, earlier pieces against ancestors. `prod port` → `production` / (skip `server`) / `port`. Each piece keeps using the existing fuzzy scorer, so `prod`, `pr`, and `production` all work.
- Keep scoring the whole query against the label first (as the code already does today) so single-word queries and labels that legitimately contain spaces — e.g. a Markdown heading `change log` — are unaffected.
- Show the matched path as the item description with highlights on the matched segments, so it is visible *which* `port` each row is.
Nice-to-haves, if the above lands:
- Accept a separator as well as a space (`prod.port`, `prod/port`), which is what the JSON/YAML path already looks like when copied out of the file.
- Apply the same path matching to the `@:` grouped variant and to the Outline view's filter box.
### Alternatives considered
- `Ctrl+F` / regex search: works, but loses symbol semantics, kind icons, and the jump-to-symbol behaviour, and matches values as well as keys.
- Outline view: shows the hierarchy, but requires manual expansion and has no path-aware filter, so it is slower than typing.
- Breadcrumbs: give context for the cursor's current position, not a way to search for a target.
### Related issues (none of these ask for path-aware matching in the editor picker)
- [#109548](https://github.com/microsoft/vscode/issues/109548) — multiple substrings within a *single* symbol name, in `Go to Symbol in Workspace`.
- [#116420](https://github.com/microsoft/vscode/issues/116420) — search inside the breadcrumbs picker.
- [#146374](https://github.com/microsoft/vscode/issues/146374) — hierarchical *display* for `Go to Symbol in Editor` (this request is about matching, and would help without a UI change).
- [#157195](https://github.com/microsoft/vscode/issues/157195), [#27317](https://github.com/microsoft/vscode/issues/27317) — ranking/sort order in the pickers.
Contributor guide
Assessment
This issue has not been assessed yet.