Better Go To File is a fast, local file picker for VS Code, Cursor, and Neovim. It combines structured filename matching with editor and repository context, while keeping one rule non-negotiable: when your text identifies a file clearly, that explicit intent wins.
It is designed for monorepos and other large workspaces where generic names such as index.ts,
routes.ts, and button.tsx make a conventional fuzzy picker noisy.
- Literal when you are precise. Exact filenames, extension-free stems, paths, module families, word boundaries, camel case, and acronyms all have distinct ranking tiers.
- Contextual when you are not. Frecency, learned query choices, the active package, nearby directories, open tabs, and Git tracking state help resolve genuine ambiguity.
- Stable while you choose. The initial picker and every input change may publish one result list—never a stream of late background reshuffles.
- Fast on the typing path. Candidate features are precomputed, prefix searches reuse narrower pools, impossible files are rejected cheaply, and only the bounded visible top-K is retained.
- Native-looking in VS Code and Cursor. Results use the active file icon theme, including image-backed and font-backed themes, language associations, and ignored-file styling.
- Private by design. Search history, frecency, Git analysis, contributor relationships, and indexes stay on the local machine. The extension has no telemetry service.
Every adapter uses the same editor-neutral query parser and ranking engine. Host-specific capabilities remain in the host:
| Capability | VS Code / Cursor | Neovim |
|---|---|---|
| Structured lexical ranking and multi-root search | ✓ | ✓ |
| Frecency, active/open-file context, and query learning | ✓ | ✓ |
| Git tracked/ignored/untracked state | ✓ | ✓ |
| One immutable result publication per input revision | ✓ | ✓ |
| Persistent warm workspace and validated Git-state cache | ✓ | — |
| Contributor relationships and live worktree priors | ✓ | — |
| Active file-theme icons and ignored-file badges | ✓ | — |
| Related files, counterparts, experts, and diagnostics | ✓ | — |
The shared sidecar protocol is intentionally editor-neutral, so more adapters can be added without reimplementing ranking. See Cross-editor architecture.
Install Better Go To File from the Visual Studio Marketplace.
The extension requires VS Code 1.97 or newer.
Download the .vsix from the
latest GitHub release, then run
Extensions: Install from VSIX... in Cursor.
You can also install from a terminal:
cursor --install-extension /path/to/better-go-to-file.vsix --forceThe same VSIX can be installed manually in VS Code with code --install-extension.
Neovim 0.10+ is the target support range. The adapter has no Telescope or other Lua plugin
dependency; its long-lived search engine requires Node.js or Bun.
Use editors/neovim from a source checkout, or extract
better-go-to-file-neovim.tar.gz from a release that includes it. The archive expands to a
better-go-to-file.nvim/ plugin directory.
require("better_go_to_file").setup({
keymaps = {
open = "<C-p>",
},
})See the complete Neovim installation and configuration guide.
Run Better Go To File: Open from the Command Palette.
To replace the built-in file picker, enable:
{
"betterGoToFile.replaceBuiltInGoToFile": true
}This binds Cmd+P on macOS and Ctrl+P on Windows/Linux. On Windows/Linux it also replaces the
equivalent Ctrl+E Quick Open binding. The takeover is active only with an open workspace and
outside terminals or another Quick Pick. User-defined keybindings still take precedence.
To keep the built-in picker and add a separate shortcut:
[
{
"key": "ctrl+u",
"mac": "cmd+u",
"command": "betterGoToFile.open",
"when": "workspaceFolderCount > 0 && !inQuickOpen && !terminalFocus"
}
]All whitespace-separated tokens must match. Longer tokens are tested first for fast rejection, but the original token order is retained for structural scoring. Forward path order, compact spans, package-plus-filename matches, and distinct repeated occurrences rank higher.
| Input | Meaning |
|---|---|
queryCompiler |
Prefer an exact filename stem or module-family stem |
query compiler |
Require both tokens; prefer their forward structural order |
qc |
Match filename acronyms such as QueryCompiler |
hs |
Match uppercase-run boundaries such as HTTPServer |
src/search config |
Combine path and filename intent |
src\search\config |
Windows separators are normalized to / |
queryCompiler.ts:42 |
Open line 42 |
queryCompiler.ts:42:7 |
Open line 42, column 7 |
queryCompiler@compileQuery |
Open the file, then continue into symbol search in VS Code/Cursor |
>, @, #, or : as prefix |
Hand off to the matching native Quick Access mode in VS Code/Cursor |
Conventional module suffixes such as .test, .spec, .stories, .d, and .generated are
recognized as related stems. This keeps implementation and counterpart files close enough for
explicit selection learning to remember which one you prefer.
Opening the picker creates an initial revision. Every actual input change creates the next monotonic revision, even if the same text is entered again later.
For each revision Better Go To File:
- associates the current query with one monotonically increasing revision;
- scores one captured catalog/configuration input synchronously;
- builds a detached result array and publishes that array at most once.
While a new revision is pending, the previous rows remain visible. Index refreshes, Git changes, icon loading, contributor history, active-editor changes, persistence, window resizing, duplicate responses, and stale timers cannot patch or reorder an already-published list. Their state becomes eligible on the next input change.
Accepting while work is pending synchronizes with the current revision instead of opening a stale first result. The Neovim sidecar additionally uses a latest-only request mailbox, so rapid typing does not accumulate a FIFO backlog.
The main search pipeline is:
- Restore or build the index. Package roots and reusable lexical features are computed once.
- Reuse a safe prefix pool. A longer query can search the exact matches of a shorter prefix.
- Filter lexically. Every token must match; a recall-safe letter mask rejects impossible candidates before substring or fuzzy work.
- Score explicit structure. Exact names/stems, paths, boundaries, acronyms, package matches, ordered words, substrings, and fuzzy matches form progressively weaker tiers.
- Add local context. Frecency, query-selection memory, active/open files, package proximity, directory proximity, and Git tracking state break close ties.
- Gate repository priors. VS Code/Cursor contributor and worktree priors are scaled and capped using the top lexical score gap, so an outlier prior cannot bulldoze a decisive textual winner.
- Keep only top-K. A bounded heap avoids sorting every matching file merely to display the first 200.
The full model is documented in Search ranking. VS Code/Cursor contributor analysis is separated into Contributor intelligence.
Better Go To File learns from files opened through the picker:
- Frecency tracks recent and repeated opens with time decay.
- Query-selection memory records the exact normalized query plus bounded token and prefix forms.
- Learned associations decay, are capped per query and globally, and are persisted atomically.
- A result-row pin action can make a query-to-file choice explicit.
Better Go To File: Ranking Preferencescan pin, unpin, remove, or reset associations.
Learning never updates a visible revision. A selection affects only a later input change.
| Command | Purpose |
|---|---|
Better Go To File: Open |
Open the main picker. |
Better Go To File: Related Files |
Rank imports, Git co-changes, counterparts, and nearby file families for the active file. |
Better Go To File: Open Counterpart |
Jump among implementation/test, component/story, source/generated, router/service, and similar. |
Better Go To File: File Experts |
Rank canonical contributors with meaningful evidence for the active file. |
Better Go To File: Search Contributor's Files |
Search an immutable snapshot of one canonical contributor's strongest current file history. |
Better Go To File: Contributor Relationships |
Inspect inferred contributor overlap, activity, focus, and ranking components. |
Better Go To File: Recent Work Contexts |
Reopen recent and modified files grouped by feature-sized work sessions. |
Better Go To File: Explain Current Result |
Show the lexical, context, Git, frecency, and learning breakdown for a captured result. |
Better Go To File: Ranking Preferences |
Inspect and manage local query-selection learning. |
Better Go To File: Reindex Now |
Request a complete live workspace-index refresh. |
Better Go To File: Index Health |
Inspect cache source, index freshness, Git coverage, limits, errors, and metadata size. |
Better Go To File: Benchmark This Workspace |
Measure cold and warm end-to-end picker snapshots over representative workspace queries. |
Better Go To File: Open (debug) |
Open the main picker with score details visible. |
Better Go To File: Inspect Icons |
Diagnose active icon-theme resolution against sampled files. |
Main-picker rows also expose actions for explaining their captured rank and managing the current query preference.
A practical starting point:
{
"betterGoToFile.replaceBuiltInGoToFile": true,
"betterGoToFile.gitignored.visibility": "auto",
"betterGoToFile.scoring.preset": "balanced",
"betterGoToFile.contributorRelationships.backgroundRefresh": true
}Available presets are balanced, exact, recent, nearby, and fuzzy. You can layer validated
JSON overrides over a preset without forking the scorer.
The authoritative reference for all eight VS Code/Cursor settings, ignored-file semantics, preset behavior, custom scoring, and every Neovim option is Configuration.
The VS Code/Cursor adapter activates only when one of its commands is invoked. It restores versioned workspace, Git-state, frecency, selection-learning, and contributor snapshots from the editor's extension storage, then validates or replaces them in the background.
- Cached files can make the picker useful before the live scan completes.
- Git repositories use bounded tracked/untracked enumeration; non-Git folders use an iterative filesystem scanner.
- Workspace changes become copy-on-write subtree refreshes after the live index is ready.
- Watcher bursts are bounded and coalesced; failed refreshes retry without discarding the last good index.
- Contributor history starts only after the picker-critical index, frecency, and Git state are usable, and can be disabled independently.
The status bar and Index Health command expose whether results came from an empty, cached, or live
index and whether a refresh or persistence operation is still active.
The repository contains both a synthetic 4k/50k/100k scorer benchmark and an in-editor full-pipeline benchmark. A representative 100,000-file development run measured:
| Query shape | Median |
|---|---|
| Broad one-character query | 19.59 ms |
| Selective full-pool query | 2.15 ms |
| Two-token full-pool query | 3.80 ms |
| Reversed two-token query | 4.22 ms |
| Zero-hit query | 0.77 ms |
| Final incremental prefix search | 2.34 ms |
These numbers are hardware-dependent reference measurements, not latency guarantees. Run
Better Go To File: Benchmark This Workspace for the actual editor pipeline on your repository, or
bun run bench:search --assert from a source checkout.
The VS Code/Cursor adapter derives contributor relationships entirely from local Git history after the picker is already usable. It respects Git mailmap data, excludes merge commits from touch analysis, filters bots, and conservatively collapses duplicate signatures using strong evidence such as identical emails, GitHub numeric no-reply account IDs, and validated enterprise/plus aliases. Ambiguous identities stay separate.
Contributor history can be disabled:
{
"betterGoToFile.contributorRelationships.backgroundRefresh": false
}No repository data, file content, Git identity, query history, or learned preference is sent to a Better Go To File service.
- Configuration and command reference
- Search ranking and performance design
- Contributor intelligence
- Cross-editor architecture and stability protocol
- Neovim guide
- Development, validation, packaging, and releases
Better Go To File uses Bun, TypeScript, native VS Code APIs, and dependency-free Lua for the Neovim adapter.
bun install --frozen-lockfile
bun run checkRuntime TypeScript lives under src/, tests under test/, and the Neovim adapter under
editors/neovim/. See Development for focused validation, the scoring CLI,
debugging, benchmarks, packaging, and release artifacts.
Licensed under the MIT License.
