Fix tab completion for absolute paths

- Fix //tmp issue: distinguish slash commands from file paths by checking if anything precedes the /
- Fix symlinks to directories (like /tmp) not getting trailing slash
This commit is contained in:
Mario Zechner 2025-12-21 02:41:38 +01:00
parent bf51dd4126
commit 918750eb9e
3 changed files with 24 additions and 7 deletions

View file

@ -2,6 +2,14 @@
## [Unreleased]
## [0.25.1] - 2025-12-21
### Fixed
- **Gemini image reading broken**: Fixed the `read` tool returning images causing flaky/broken responses with Gemini models. Images in tool results are now properly formatted per the Gemini API spec.
- **Tab completion for absolute paths**: Fixed tab completion for absolute paths like `/tmp` producing `//tmp`. Also fixed inability to continue tabbing through subdirectories after completing an absolute path.
## [0.25.0] - 2025-12-20
### Added

View file

@ -1,5 +1,5 @@
import { spawnSync } from "child_process";
import { readdirSync } from "fs";
import { readdirSync, statSync } from "fs";
import { homedir } from "os";
import { basename, dirname, join } from "path";
@ -197,8 +197,10 @@ export class CombinedAutocompleteProvider implements AutocompleteProvider {
const beforePrefix = currentLine.slice(0, cursorCol - prefix.length);
const afterCursor = currentLine.slice(cursorCol);
// Check if we're completing a slash command (prefix starts with "/")
if (prefix.startsWith("/")) {
// Check if we're completing a slash command (prefix starts with "/" but NOT a file path)
// Slash commands are at the start of the line and don't contain path separators after the first /
const isSlashCommand = prefix.startsWith("/") && beforePrefix.trim() === "" && !prefix.slice(1).includes("/");
if (isSlashCommand) {
// This is a command name completion
const newLine = beforePrefix + "/" + item.value + " " + afterCursor;
const newLines = [...lines];
@ -367,7 +369,16 @@ export class CombinedAutocompleteProvider implements AutocompleteProvider {
continue;
}
const isDirectory = entry.isDirectory();
// Check if entry is a directory (or a symlink pointing to a directory)
let isDirectory = entry.isDirectory();
if (!isDirectory && entry.isSymbolicLink()) {
try {
const fullPath = join(searchDir, entry.name);
isDirectory = statSync(fullPath).isDirectory();
} catch {
// Broken symlink or permission error - treat as file
}
}
let relativePath: string;
const name = entry.name;

View file

@ -1245,7 +1245,7 @@ export class Editor implements Component {
const beforeCursor = currentLine.slice(0, this.state.cursorCol);
// Check if we're in a slash command context
if (beforeCursor.trimStart().startsWith("/")) {
if (beforeCursor.trimStart().startsWith("/") && !beforeCursor.trimStart().includes(" ")) {
this.handleSlashCommandCompletion();
} else {
this.forceFileAutocomplete();
@ -1253,8 +1253,6 @@ export class Editor implements Component {
}
private handleSlashCommandCompletion(): void {
// For now, fall back to regular autocomplete (slash commands)
// This can be extended later to handle command-specific argument completion
this.tryTriggerAutocomplete(true);
}