Files
orca/src/shared/quick-open-separator-match.ts
T
Neil fff8718c76 Improve Quick Open matching, file locations and recent history (#25371)
* Match Quick Open queries across path terms and identifier separators

* Honor ignored-file and symlink preferences on file inventory hosts

* Open pasted file locations and remember successful workspace file visits

* Verify bounded directory listing preferences across execution routes

* Preserve symlink preferences on legacy directory fallback

* Preserve bounded Quick Open terms and separator alternatives

* Revoke stale Quick Open selections and preserve literal file locations

* Validate recent Quick Open candidates independently on their host

* Use complete old-host inventory fixtures for Quick Open compatibility

* Keep Quick Open validation current across palette and workspace changes

* Route recent candidates through relay file listing dispatch

* Record Quick Open hook renders as test snapshots

* Localize Quick Open eligibility errors and search aliases

* Validate file inventory with bundled search and runtime preferences

* test: use directory junction fixtures on Windows

* fix: negotiate Quick Open policies with nested SSH hosts

* fix: refresh cached linked folders after target changes

* Retry stale expanded links after reads settle and targets recover

* Scope stale refresh request lifetime to the visible workspace

* test: seed linked-folder fixture before watcher startup

* Keep Quick Open responsive and compatible with older hosts

* Exercise directory discovery with unprivileged Windows junctions
2026-10-05 21:52:28 -07:00

39 lines
1.4 KiB
TypeScript

/** Keeps alternative character positions without recursively retrying path prefixes. */
export function matchQuickOpenSeparatorAlternatives(
query: string,
path: string,
boundaries: ReadonlySet<number> | undefined
): number | null {
if (!boundaries?.size && !/[-_ ]/.test(path)) {
return null
}
let previous = new Float64Array(path.length + 1).fill(Infinity)
let current = new Float64Array(path.length + 1)
previous[0] = 0
for (let qi = 0; qi < query.length; qi++) {
current.fill(Infinity)
const separator = query[qi] === '-' || query[qi] === '_'
let best = Infinity
for (let ti = 0; ti < path.length; ti++) {
if (ti > 0) {
best = Math.min(best, previous[ti] - ti)
}
const actual = path[ti]
const matches = separator
? actual === '-' || actual === '_' || actual === ' '
: actual === query[qi]
if (matches) {
const prefix = Math.min(previous[0], best + ti)
const boundary = ti > 0 && '/.-_'.includes(path[ti - 1]) ? 5 : 0
current[ti + 1] = Math.min(current[ti + 1], prefix - boundary)
}
if (separator && ti > 0 && boundaries?.has(ti)) {
current[ti] = Math.min(current[ti], previous[ti] + 2)
}
}
;[previous, current] = [current, previous]
}
const score = previous.reduce((best, value) => Math.min(best, value), Infinity)
return Number.isFinite(score) ? score : null
}