From acb0f4d807553684f3627202d4fd603059555c0e Mon Sep 17 00:00:00 2001 From: Mario Zechner Date: Sat, 14 Mar 2026 04:12:38 +0100 Subject: [PATCH] fix(tui): preserve ./ prefix in tab completion, closes #2087 --- packages/tui/src/autocomplete.ts | 4 +++ packages/tui/test/autocomplete.test.ts | 46 ++++++++++++++++++++++++++ 2 files changed, 50 insertions(+) diff --git a/packages/tui/src/autocomplete.ts b/packages/tui/src/autocomplete.ts index 7a7f55b5..3fb1b670 100644 --- a/packages/tui/src/autocomplete.ts +++ b/packages/tui/src/autocomplete.ts @@ -575,6 +575,10 @@ export class CombinedAutocompleteProvider implements AutocompleteProvider { } } else { relativePath = join(dirname(displayPrefix), name); + // path.join normalizes away ./ prefix, preserve it + if (displayPrefix.startsWith("./") && !relativePath.startsWith("./")) { + relativePath = `./${relativePath}`; + } } } else { // For standalone entries, preserve ~/ if original prefix was ~/ diff --git a/packages/tui/test/autocomplete.test.ts b/packages/tui/test/autocomplete.test.ts index 6f06b89a..9693b975 100644 --- a/packages/tui/test/autocomplete.test.ts +++ b/packages/tui/test/autocomplete.test.ts @@ -331,6 +331,52 @@ describe("CombinedAutocompleteProvider", () => { }); }); + describe("dot-slash path completion", () => { + let baseDir = ""; + + beforeEach(() => { + baseDir = mkdtempSync(join(tmpdir(), "pi-autocomplete-")); + }); + + afterEach(() => { + rmSync(baseDir, { recursive: true, force: true }); + }); + + test("preserves ./ prefix when completing paths", () => { + setupFolder(baseDir, { + files: { + "update.sh": "#!/bin/bash", + "utils.ts": "export {};", + }, + }); + + const provider = new CombinedAutocompleteProvider([], baseDir); + const line = "./up"; + const result = provider.getForceFileSuggestions([line], 0, line.length); + + assert.notEqual(result, null, "Should return suggestions for ./ path"); + const values = result?.items.map((item) => item.value); + assert.ok(values?.includes("./update.sh"), `Expected ./update.sh in ${JSON.stringify(values)}`); + }); + + test("preserves ./ prefix for directory completions", () => { + setupFolder(baseDir, { + dirs: ["src"], + files: { + "src/index.ts": "export {};", + }, + }); + + const provider = new CombinedAutocompleteProvider([], baseDir); + const line = "./sr"; + const result = provider.getForceFileSuggestions([line], 0, line.length); + + assert.notEqual(result, null, "Should return suggestions for ./ directory path"); + const values = result?.items.map((item) => item.value); + assert.ok(values?.includes("./src/"), `Expected ./src/ in ${JSON.stringify(values)}`); + }); + }); + describe("quoted path completion", () => { let baseDir = "";