diff --git a/packages/tui/src/autocomplete.ts b/packages/tui/src/autocomplete.ts index 6af1fa2b..23ae73ef 100644 --- a/packages/tui/src/autocomplete.ts +++ b/packages/tui/src/autocomplete.ts @@ -80,7 +80,7 @@ function buildCompletionValue( } const openQuote = `${prefix}"`; - const closeQuote = options.isDirectory ? "" : '"'; + const closeQuote = '"'; return `${openQuote}${path}${closeQuote}`; } @@ -320,16 +320,19 @@ export class CombinedAutocompleteProvider implements AutocompleteProvider { if (prefix.startsWith("@")) { // This is a file attachment completion // Don't add space after directories so user can continue autocompleting - const isDirectory = item.value.endsWith("/"); + const isDirectory = item.label.endsWith("/"); const suffix = isDirectory ? "" : " "; const newLine = `${beforePrefix + item.value}${suffix}${afterCursor}`; const newLines = [...lines]; newLines[cursorLine] = newLine; + const hasTrailingQuote = item.value.endsWith('"'); + const cursorOffset = isDirectory && hasTrailingQuote ? item.value.length - 1 : item.value.length; + return { lines: newLines, cursorLine, - cursorCol: beforePrefix.length + item.value.length + suffix.length, + cursorCol: beforePrefix.length + cursorOffset + suffix.length, }; } @@ -341,10 +344,14 @@ export class CombinedAutocompleteProvider implements AutocompleteProvider { const newLines = [...lines]; newLines[cursorLine] = newLine; + const isDirectory = item.label.endsWith("/"); + const hasTrailingQuote = item.value.endsWith('"'); + const cursorOffset = isDirectory && hasTrailingQuote ? item.value.length - 1 : item.value.length; + return { lines: newLines, cursorLine, - cursorCol: beforePrefix.length + item.value.length, + cursorCol: beforePrefix.length + cursorOffset, }; } @@ -353,10 +360,14 @@ export class CombinedAutocompleteProvider implements AutocompleteProvider { const newLines = [...lines]; newLines[cursorLine] = newLine; + const isDirectory = item.label.endsWith("/"); + const hasTrailingQuote = item.value.endsWith('"'); + const cursorOffset = isDirectory && hasTrailingQuote ? item.value.length - 1 : item.value.length; + return { lines: newLines, cursorLine, - cursorCol: beforePrefix.length + item.value.length, + cursorCol: beforePrefix.length + cursorOffset, }; } diff --git a/packages/tui/test/autocomplete.test.ts b/packages/tui/test/autocomplete.test.ts index cd68c609..d619c846 100644 --- a/packages/tui/test/autocomplete.test.ts +++ b/packages/tui/test/autocomplete.test.ts @@ -244,7 +244,7 @@ describe("CombinedAutocompleteProvider", () => { const result = provider.getSuggestions([line], 0, line.length); const values = result?.items.map((item) => item.value); - assert.ok(values?.includes('@"my folder/')); + assert.ok(values?.includes('@"my folder/"')); }); test("continues autocomplete inside quoted @ paths", () => { @@ -256,8 +256,8 @@ describe("CombinedAutocompleteProvider", () => { }); const provider = new CombinedAutocompleteProvider([], baseDir, requireFdPath()); - const line = '@"my folder/'; - const result = provider.getSuggestions([line], 0, line.length); + const line = '@"my folder/"'; + const result = provider.getSuggestions([line], 0, line.length - 1); assert.notEqual(result, null, "Should return suggestions for quoted folder path"); const values = result?.items.map((item) => item.value); @@ -291,7 +291,7 @@ describe("CombinedAutocompleteProvider", () => { assert.notEqual(result, null, "Should return suggestions for path completion"); const values = result?.items.map((item) => item.value); - assert.ok(values?.includes('"my folder/')); + assert.ok(values?.includes('"my folder/"')); }); test("continues completion inside quoted paths", () => { @@ -303,8 +303,8 @@ describe("CombinedAutocompleteProvider", () => { }); const provider = new CombinedAutocompleteProvider([], baseDir); - const line = '"my folder/'; - const result = provider.getForceFileSuggestions([line], 0, line.length); + const line = '"my folder/"'; + const result = provider.getForceFileSuggestions([line], 0, line.length - 1); assert.notEqual(result, null, "Should return suggestions for quoted folder path"); const values = result?.items.map((item) => item.value);