fix: speed up fff file search (#31366)
This commit is contained in:
parent
1772e8ee6e
commit
b1a6c40ad0
7 changed files with 68 additions and 39 deletions
|
|
@ -134,15 +134,12 @@ function item(hit: Fff.Hit): Item {
|
|||
}
|
||||
|
||||
function collectPaths<T>(
|
||||
out: { items: T[]; scores: Array<{ total: number }> },
|
||||
items: T[],
|
||||
toPath: (item: T) => string,
|
||||
opts?: { includeZeroScore?: boolean },
|
||||
): string[] {
|
||||
return Array.from(
|
||||
new Set(
|
||||
out.items.flatMap((item, idx): string[] => {
|
||||
const score = out.scores[idx]
|
||||
if (!score || (!opts?.includeZeroScore && score.total <= 0)) return []
|
||||
items.flatMap((item): string[] => {
|
||||
const text = toPath(item)
|
||||
if (!text) return []
|
||||
return [text]
|
||||
|
|
@ -162,7 +159,7 @@ function searchFff(
|
|||
if (!out.ok) return out
|
||||
return {
|
||||
ok: true,
|
||||
value: collectPaths(out.value, (entry) => normalize(entry.relativePath), { includeZeroScore: !query }),
|
||||
value: collectPaths(out.value.items, (entry) => normalize(entry.relativePath)),
|
||||
}
|
||||
}
|
||||
if (kind === "all") {
|
||||
|
|
@ -170,14 +167,14 @@ function searchFff(
|
|||
if (!out.ok) return out
|
||||
return {
|
||||
ok: true,
|
||||
value: collectPaths(out.value, (entry) => normalize(entry.item.relativePath), { includeZeroScore: !query }),
|
||||
value: collectPaths(out.value.items, (entry) => normalize(entry.item.relativePath)),
|
||||
}
|
||||
}
|
||||
const out = pick.fileSearch(query, opts)
|
||||
if (!out.ok) return out
|
||||
return {
|
||||
ok: true,
|
||||
value: collectPaths(out.value, (entry) => normalize(entry.relativePath), { includeZeroScore: !query }),
|
||||
value: collectPaths(out.value.items, (entry) => normalize(entry.relativePath)),
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -241,6 +238,13 @@ export const layer: Layer.Layer<Service, never, FSUtil.Service | Ripgrep.Service
|
|||
// remove before process exit, so use ripgrep instead of native FFF there.
|
||||
if (process.env.OPENCODE_TEST_HOME) return undefined
|
||||
|
||||
const dir = FSUtil.resolve(cwd)
|
||||
const existing = state.pick.get(dir)
|
||||
if (existing) return existing
|
||||
|
||||
const pending = state.wait.get(dir)
|
||||
if (pending) return yield* Deferred.await(pending)
|
||||
|
||||
const available = yield* fffSync("check availability", () => Fff.available()).pipe(
|
||||
Effect.catch((error) => {
|
||||
log.warn("fff availability check failed", { error })
|
||||
|
|
@ -249,13 +253,6 @@ export const layer: Layer.Layer<Service, never, FSUtil.Service | Ripgrep.Service
|
|||
)
|
||||
if (!available) return undefined
|
||||
|
||||
const dir = FSUtil.resolve(cwd)
|
||||
const existing = state.pick.get(dir)
|
||||
if (existing) return existing
|
||||
|
||||
const pending = state.wait.get(dir)
|
||||
if (pending) return yield* Deferred.await(pending)
|
||||
|
||||
const gate = yield* Deferred.make<Picker, Error>()
|
||||
state.wait.set(dir, gate)
|
||||
return yield* Effect.gen(function* () {
|
||||
|
|
@ -353,13 +350,12 @@ export const layer: Layer.Layer<Service, never, FSUtil.Service | Ripgrep.Service
|
|||
const query = input.query.trim()
|
||||
const kind = input.kind ?? "file"
|
||||
|
||||
const pick = yield* picker(input.cwd)
|
||||
if (!pick) return undefined
|
||||
|
||||
const entry = yield* acquire(input.cwd).pipe(Effect.catch(() => Effect.succeed<Picker | undefined>(undefined)))
|
||||
if (!entry) return undefined
|
||||
const dir = FSUtil.resolve(input.cwd)
|
||||
const limit = input.limit ?? 100
|
||||
const fffResult = yield* fffSync(`${kind} search`, () =>
|
||||
searchFff(pick, kind, query, {
|
||||
searchFff(entry.pick, kind, query, {
|
||||
pageIndex: 0,
|
||||
currentFile: input.current, // supports both relative and absolute (relative preferred)
|
||||
pageSize: limit,
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue