diff --git a/packages/tui/src/autocomplete.ts b/packages/tui/src/autocomplete.ts index 0aeda9d1..84f0be2f 100644 --- a/packages/tui/src/autocomplete.ts +++ b/packages/tui/src/autocomplete.ts @@ -101,6 +101,13 @@ function walkDirectoryWithFd( "--type", "d", "--full-path", + "--hidden", + "--exclude", + ".git", + "--exclude", + ".git/*", + "--exclude", + ".git/**", ]; // Add query as pattern if provided @@ -122,6 +129,11 @@ function walkDirectoryWithFd( const results: Array<{ path: string; isDirectory: boolean }> = []; for (const line of lines) { + const normalizedPath = line.endsWith("/") ? line.slice(0, -1) : line; + if (normalizedPath === ".git" || normalizedPath.startsWith(".git/") || normalizedPath.includes("/.git/")) { + continue; + } + // fd outputs directories with trailing / const isDirectory = line.endsWith("/"); results.push({ diff --git a/packages/tui/test/autocomplete.test.ts b/packages/tui/test/autocomplete.test.ts index 089cc86b..6713c51f 100644 --- a/packages/tui/test/autocomplete.test.ts +++ b/packages/tui/test/autocomplete.test.ts @@ -247,6 +247,26 @@ describe("CombinedAutocompleteProvider", () => { assert.ok(values?.includes('@"my folder/"')); }); + test("includes hidden paths but excludes .git", () => { + setupFolder(baseDir, { + dirs: [".pi", ".github", ".git"], + files: { + ".pi/config.json": "{}", + ".github/workflows/ci.yml": "name: ci", + ".git/config": "[core]", + }, + }); + + const provider = new CombinedAutocompleteProvider([], baseDir, requireFdPath()); + const line = "@"; + const result = provider.getSuggestions([line], 0, line.length); + + const values = result?.items.map((item) => item.value) ?? []; + assert.ok(values.includes("@.pi/")); + assert.ok(values.includes("@.github/")); + assert.ok(!values.some((value) => value === "@.git" || value.startsWith("@.git/"))); + }); + test("continues autocomplete inside quoted @ paths", () => { setupFolder(baseDir, { files: {