|
|
@@ -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,
|