mirror of
https://github.com/google-gemini/gemini-cli.git
synced 2026-04-27 05:24:34 -07:00
feat(core): improve @file autocomplete to prioritize filenames (#21064)
This commit is contained in:
@@ -13,6 +13,44 @@ import { AsyncFzf, type FzfResultItem } from 'fzf';
|
||||
import { unescapePath } from '../paths.js';
|
||||
import type { FileDiscoveryService } from '../../services/fileDiscoveryService.js';
|
||||
|
||||
// Tiebreaker: Prefers shorter paths.
|
||||
const byLengthAsc = (a: { item: string }, b: { item: string }) =>
|
||||
a.item.length - b.item.length;
|
||||
|
||||
// Tiebreaker: Prefers matches at the start of the filename (basename prefix).
|
||||
const byBasenamePrefix = (
|
||||
a: { item: string; positions: Set<number> },
|
||||
b: { item: string; positions: Set<number> },
|
||||
) => {
|
||||
const getBasenameStart = (p: string) => {
|
||||
const trimmed = p.endsWith('/') ? p.slice(0, -1) : p;
|
||||
return Math.max(trimmed.lastIndexOf('/'), trimmed.lastIndexOf('\\')) + 1;
|
||||
};
|
||||
const aDiff = Math.min(...a.positions) - getBasenameStart(a.item);
|
||||
const bDiff = Math.min(...b.positions) - getBasenameStart(b.item);
|
||||
|
||||
const aIsFilenameMatch = aDiff >= 0;
|
||||
const bIsFilenameMatch = bDiff >= 0;
|
||||
|
||||
if (aIsFilenameMatch && !bIsFilenameMatch) return -1;
|
||||
if (!aIsFilenameMatch && bIsFilenameMatch) return 1;
|
||||
if (aIsFilenameMatch && bIsFilenameMatch) return aDiff - bDiff;
|
||||
|
||||
return 0; // Both are directory matches, let subsequent tiebreakers decide.
|
||||
};
|
||||
|
||||
// Tiebreaker: Prefers matches closer to the end of the path.
|
||||
const byMatchPosFromEnd = (
|
||||
a: { item: string; positions: Set<number> },
|
||||
b: { item: string; positions: Set<number> },
|
||||
) => {
|
||||
const maxPosA = Math.max(-1, ...a.positions);
|
||||
const maxPosB = Math.max(-1, ...b.positions);
|
||||
const distA = a.item.length - maxPosA;
|
||||
const distB = b.item.length - maxPosB;
|
||||
return distA - distB;
|
||||
};
|
||||
|
||||
export interface FileSearchOptions {
|
||||
projectRoot: string;
|
||||
ignoreDirs: string[];
|
||||
@@ -192,6 +230,8 @@ class RecursiveFileSearch implements FileSearch {
|
||||
// files, because the v2 algorithm is just too slow in those cases.
|
||||
this.fzf = new AsyncFzf(this.allFiles, {
|
||||
fuzzy: this.allFiles.length > 20000 ? 'v1' : 'v2',
|
||||
forward: false,
|
||||
tiebreakers: [byBasenamePrefix, byMatchPosFromEnd, byLengthAsc],
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user