summaryrefslogtreecommitdiff
path: root/packages/cli/src/ui/hooks/useCompletion.ts
diff options
context:
space:
mode:
Diffstat (limited to 'packages/cli/src/ui/hooks/useCompletion.ts')
-rw-r--r--packages/cli/src/ui/hooks/useCompletion.ts62
1 files changed, 51 insertions, 11 deletions
diff --git a/packages/cli/src/ui/hooks/useCompletion.ts b/packages/cli/src/ui/hooks/useCompletion.ts
index f3ad7847..520ba7c6 100644
--- a/packages/cli/src/ui/hooks/useCompletion.ts
+++ b/packages/cli/src/ui/hooks/useCompletion.ts
@@ -12,6 +12,7 @@ import {
escapePath,
unescapePath,
getErrorMessage,
+ Config,
} from '@gemini-code/core';
import {
MAX_SUGGESTIONS_TO_SHOW,
@@ -37,6 +38,7 @@ export function useCompletion(
cwd: string,
isActive: boolean,
slashCommands: SlashCommand[],
+ config?: Config,
): UseCompletionReturn {
const [suggestions, setSuggestions] = useState<Suggestion[]>([]);
const [activeSuggestionIndex, setActiveSuggestionIndex] =
@@ -184,6 +186,7 @@ export function useCompletion(
const findFilesRecursively = async (
startDir: string,
searchPrefix: string,
+ fileDiscovery: { shouldIgnoreFile: (path: string) => boolean } | null,
currentRelativePath = '',
depth = 0,
maxDepth = 10, // Limit recursion depth
@@ -201,6 +204,19 @@ export function useCompletion(
if (foundSuggestions.length >= maxResults) break;
const entryPathRelative = path.join(currentRelativePath, entry.name);
+ const entryPathFromRoot = path.relative(
+ cwd,
+ path.join(startDir, entry.name),
+ );
+
+ // Check if this entry should be ignored by git-aware filtering
+ if (
+ fileDiscovery &&
+ fileDiscovery.shouldIgnoreFile(entryPathFromRoot)
+ ) {
+ continue;
+ }
+
if (entry.name.toLowerCase().startsWith(lowerSearchPrefix)) {
foundSuggestions.push({
label: entryPathRelative + (entry.isDirectory() ? '/' : ''),
@@ -219,6 +235,7 @@ export function useCompletion(
await findFilesRecursively(
path.join(startDir, entry.name),
searchPrefix, // Pass original searchPrefix for recursive calls
+ fileDiscovery,
entryPathRelative,
depth + 1,
maxDepth,
@@ -237,25 +254,48 @@ export function useCompletion(
const fetchSuggestions = async () => {
setIsLoadingSuggestions(true);
let fetchedSuggestions: Suggestion[] = [];
+
+ // Get centralized file discovery service if config is available
+ const fileDiscovery = 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);
+ fetchedSuggestions = await findFilesRecursively(
+ cwd,
+ prefix,
+ fileDiscovery,
+ );
} else {
// Original behavior: list files in the specific directory
const lowerPrefix = prefix.toLowerCase();
const entries = await fs.readdir(baseDirAbsolute, {
withFileTypes: true,
});
- fetchedSuggestions = entries
- .filter((entry) => entry.name.toLowerCase().startsWith(lowerPrefix))
- .map((entry) => {
- const label = entry.isDirectory() ? entry.name + '/' : entry.name;
- return {
- label,
- value: escapePath(label), // Value for completion should be just the name part
- };
- });
+
+ // Filter entries using git-aware filtering
+ const filteredEntries = [];
+ for (const entry of entries) {
+ if (!entry.name.toLowerCase().startsWith(lowerPrefix)) continue;
+
+ const relativePath = path.relative(
+ cwd,
+ path.join(baseDirAbsolute, entry.name),
+ );
+ if (fileDiscovery && fileDiscovery.shouldIgnoreFile(relativePath)) {
+ continue;
+ }
+
+ filteredEntries.push(entry);
+ }
+
+ fetchedSuggestions = filteredEntries.map((entry) => {
+ const label = entry.isDirectory() ? entry.name + '/' : entry.name;
+ return {
+ label,
+ value: escapePath(label), // Value for completion should be just the name part
+ };
+ });
}
// Sort by depth, then directories first, then alphabetically
@@ -307,7 +347,7 @@ export function useCompletion(
isMounted = false;
clearTimeout(debounceTimeout);
};
- }, [query, cwd, isActive, resetCompletionState, slashCommands]);
+ }, [query, cwd, isActive, resetCompletionState, slashCommands, config]);
return {
suggestions,