Improve the performance of filename completion over large repositories. (#938)

This commit is contained in:
DeWitt Clinton
2025-06-12 07:09:38 -07:00
committed by GitHub
parent 9072a4e5ee
commit f2ab6d08c4
6 changed files with 84 additions and 11 deletions

View File

@@ -13,6 +13,7 @@ import {
unescapePath,
getErrorMessage,
Config,
FileDiscoveryService,
} from '@gemini-cli/core';
import {
MAX_SUGGESTIONS_TO_SHOW,
@@ -251,21 +252,53 @@ export function useCompletion(
return foundSuggestions.slice(0, maxResults);
};
const findFilesWithGlob = async (
searchPrefix: string,
fileDiscoveryService: FileDiscoveryService,
maxResults = 50,
): Promise<Suggestion[]> => {
const globPattern = `**/${searchPrefix}*`;
const files = await fileDiscoveryService.glob(globPattern, {
cwd,
dot: true,
});
const suggestions: Suggestion[] = files
.map((file: string) => {
const relativePath = path.relative(cwd, file);
return {
label: relativePath,
value: escapePath(relativePath),
};
})
.slice(0, maxResults);
return suggestions;
};
const fetchSuggestions = async () => {
setIsLoadingSuggestions(true);
let fetchedSuggestions: Suggestion[] = [];
// Get centralized file discovery service if config is available
const fileDiscovery = config ? await config.getFileService() : null;
const fileDiscoveryService = config
? await config.getFileService()
: null;
try {
// If there's no slash, or it's the root, do a recursive search from cwd
if (partialPath.indexOf('/') === -1 && prefix) {
fetchedSuggestions = await findFilesRecursively(
cwd,
prefix,
fileDiscovery,
);
if (fileDiscoveryService) {
fetchedSuggestions = await findFilesWithGlob(
prefix,
fileDiscoveryService,
);
} else {
fetchedSuggestions = await findFilesRecursively(
cwd,
prefix,
fileDiscoveryService,
);
}
} else {
// Original behavior: list files in the specific directory
const lowerPrefix = prefix.toLowerCase();
@@ -282,7 +315,10 @@ export function useCompletion(
cwd,
path.join(baseDirAbsolute, entry.name),
);
if (fileDiscovery && fileDiscovery.shouldIgnoreFile(relativePath)) {
if (
fileDiscoveryService &&
fileDiscoveryService.shouldIgnoreFile(relativePath)
) {
continue;
}