diff --git a/packages/app/src/components/prompt-input.tsx b/packages/app/src/components/prompt-input.tsx index 3ce2d82a4f..b75d4f47cf 100644 --- a/packages/app/src/components/prompt-input.tsx +++ b/packages/app/src/components/prompt-input.tsx @@ -573,7 +573,8 @@ export const PromptInput: Component = (props) => { const pinned: AtOption[] = open.map((path) => ({ type: "file", path, display: path, recent: true })) if (!query.trim()) return [...agents, ...pinned] const pathy = /[./\\]/.test(query) - const paths = await files.searchFiles(query) + const seek = query.replaceAll("\\", "/") + const paths = await files.searchFiles(seek) const fileOptions: AtOption[] = paths .filter((path) => !seen.has(path)) .map((path) => ({ type: "file", path, display: path })) @@ -583,6 +584,7 @@ export const PromptInput: Component = (props) => { key: atKey, filterKeys: ["display"], stale: false, + fuzzy: (query) => !/[./\\]/.test(query), groupBy: (item) => { if (item.type === "agent") return "agent" if (item.recent) return "recent" diff --git a/packages/opencode/test/file/fff.test.ts b/packages/opencode/test/file/fff.test.ts index 33e4727b29..dd3284cb38 100644 --- a/packages/opencode/test/file/fff.test.ts +++ b/packages/opencode/test/file/fff.test.ts @@ -1,4 +1,4 @@ -import { describe, expect, test } from "bun:test" +import { afterEach, describe, expect, test } from "bun:test" import fs from "fs/promises" import path from "path" import { tmpdir } from "../fixture/fixture" @@ -10,6 +10,10 @@ async function write(file: string, body: string) { await fs.writeFile(file, body) } +afterEach(async () => { + await Instance.disposeAll() +}) + describe("file.fff", () => { test("allowed respects hidden filter", async () => { expect(Fff.allowed({ rel: "visible.txt", hidden: true })).toBe(true) diff --git a/packages/ui/src/hooks/use-filtered-list.tsx b/packages/ui/src/hooks/use-filtered-list.tsx index 782f25d43b..62e1840cb4 100644 --- a/packages/ui/src/hooks/use-filtered-list.tsx +++ b/packages/ui/src/hooks/use-filtered-list.tsx @@ -15,6 +15,7 @@ export interface FilteredListProps { onSelect?: (value: T | undefined, index: number) => void noInitialSelection?: boolean stale?: boolean + fuzzy?: boolean | ((filter: string) => boolean) } export function useFilteredList(props: FilteredListProps) { @@ -31,11 +32,12 @@ export function useFilteredList(props: FilteredListProps) { async ({ filter, items }) => { const query = filter ?? "" const needle = query.toLowerCase() + const fuzzy = typeof props.fuzzy === "function" ? props.fuzzy(query) : (props.fuzzy ?? true) const all = (await Promise.resolve(items)) || [] const result = pipe( all, (x) => { - if (!needle) return x + if (!needle || !fuzzy) return x if (!props.filterKeys && Array.isArray(x) && x.every((e) => typeof e === "string")) { return fuzzysort.go(needle, x).map((x) => x.target) as T[] }