Skip to content
Open
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
31 changes: 22 additions & 9 deletions packages/pi-fff/src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -78,20 +78,28 @@ function resolveToolNames(mode: FffMode): ToolNames {
// Cursor store — simple bounded Map for pagination cursors
// ---------------------------------------------------------------------------

const cursorCache = new Map<string, GrepCursor>();
// Fuzzy-fallback cursors must resume a fuzzy query: the engine cursor is bound
// to the match stream that produced it, so replaying it against the literal
// query (which matched nothing) would turn every resume into "No matches found".
interface StoredCursor {
cursor: GrepCursor;
fuzzy: boolean;
}

const cursorCache = new Map<string, StoredCursor>();
let cursorCounter = 0;

function storeCursor(cursor: GrepCursor): string {
function storeCursor(cursor: GrepCursor, fuzzy: boolean): string {
const id = `fff_c${++cursorCounter}`;
cursorCache.set(id, cursor);
cursorCache.set(id, { cursor, fuzzy });
if (cursorCache.size > 200) {
const first = cursorCache.keys().next().value;
if (first) cursorCache.delete(first);
}
return id;
}

function getCursor(id: string): GrepCursor | undefined {
function getCursor(id: string): StoredCursor | undefined {
return cursorCache.get(id);
}

Expand Down Expand Up @@ -897,12 +905,15 @@ export default function fffExtension(pi: ExtensionAPI) {
// (case-insensitive when pattern is all lowercase).
const smartCase = params.caseSensitive !== true;

const storedCursor = params.cursor ? getCursor(params.cursor) : undefined;
const resumeFuzzy = storedCursor?.fuzzy === true;

const grepResult = picker.grep(query, {
mode,
mode: resumeFuzzy ? "fuzzy" : mode,
smartCase,
maxMatchesPerFile: pageSize,
pageSize,
cursor: (params.cursor ? getCursor(params.cursor) : null) ?? null,
cursor: storedCursor?.cursor ?? null,
beforeContext: context,
afterContext: context,
classifyDefinitions: true,
Expand Down Expand Up @@ -954,7 +965,9 @@ export default function fffExtension(pi: ExtensionAPI) {
notices.push(`Invalid regex: ${result.regexFallbackError}, used literal match`);
}
if (result.nextCursor) {
notices.push(`Continue with cursor="${storeCursor(result.nextCursor)}"`);
notices.push(
`Continue with cursor="${storeCursor(result.nextCursor, fuzzyNotice !== null || resumeFuzzy)}"`,
Comment thread
coderabbitai[bot] marked this conversation as resolved.
);
}

if (notices.length > 0) output += `\n\n[${notices.join(". ")}]`;
Expand Down Expand Up @@ -1186,7 +1199,7 @@ export default function fffExtension(pi: ExtensionAPI) {
maxMatchesPerFile: pageSize,
pageSize,
smartCase: true,
cursor: (params.cursor ? getCursor(params.cursor) : null) ?? null,
cursor: (params.cursor ? getCursor(params.cursor)?.cursor : null) ?? null,
beforeContext: context,
afterContext: context,
});
Expand All @@ -1201,7 +1214,7 @@ export default function fffExtension(pi: ExtensionAPI) {
notices.push(`${effectiveLimit}+ matches (refine patterns)`);
if (result.nextCursor)
notices.push(
`More available. cursor="${storeCursor(result.nextCursor)}" to continue`,
`More available. cursor="${storeCursor(result.nextCursor, false)}" to continue`,
);

if (notices.length > 0) output += `\n\n[${notices.join(". ")}]`;
Expand Down
Loading