Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 5 additions & 0 deletions .changeset/fix-at-mention-slash-arg.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
"@moonshot-ai/kimi-code": patch
---

Fix @ file mentions not opening when typed inside a slash command argument.
33 changes: 19 additions & 14 deletions apps/kimi-code/src/tui/components/editor/file-mention-provider.ts
Original file line number Diff line number Diff line change
Expand Up @@ -67,20 +67,11 @@ export class FileMentionProvider implements AutocompleteProvider {
const currentLine = lines[cursorLine] ?? '';
const textBeforeCursor = currentLine.slice(0, cursorCol);

if (shouldSuppressLeadingWhitespaceSlashPath(textBeforeCursor, options.force)) {
return null;
}

if (
shouldSuppressSlashArgumentCompletion(
textBeforeCursor,
currentLine.slice(cursorCol),
options.force,
)
) {
return null;
}

// `@` file / folder mentions take priority over the slash-command guards
// below. Without this, typing `@` inside a slash command's argument text
// (e.g. `/goal Fix the @|checkout docs`) would be swallowed by
// `shouldSuppressSlashArgumentCompletion` before the mention branch ever
// runs, so the file list never opens.
const atPrefix = extractAtPrefix(textBeforeCursor);
if (atPrefix !== null) {
if (this.fdPath === null || this.additionalDirs.length > 0) {
Expand All @@ -104,6 +95,20 @@ export class FileMentionProvider implements AutocompleteProvider {
}
}

if (shouldSuppressLeadingWhitespaceSlashPath(textBeforeCursor, options.force)) {
return null;
}

if (
shouldSuppressSlashArgumentCompletion(
textBeforeCursor,
currentLine.slice(cursorCol),
options.force,
)
) {
return null;
}

// Handle slash-command name completion ourselves so that aliases are
// searchable and visible in the label.
if (!options.force && textBeforeCursor.startsWith('/')) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -99,6 +99,21 @@ describe('FileMentionProvider', () => {
expect(result).toBeNull();
});

it('opens @ file mention when typed in the middle of a slash command argument', async () => {
writeFileSync(join(workDir, 'README.md'), 'readme');
const provider = new FileMentionProvider([GOAL_COMMAND], workDir, NO_FD);
// Cursor sits in the middle of the /goal argument text, right after a
// freshly typed `@`. The slash-argument guard must not suppress the @
// file list here.
const line = '/goal Fix the @checkout docs';
const result = await provider.getSuggestions([line], 0, '/goal Fix the @'.length, {
signal: ctrl(),
});
expect(result).not.toBeNull();
expect(result!.prefix).toBe('@');
expect(result!.items.map((item) => item.value)).toContain('@README.md');
});

it('still completes slash arguments at the end of an empty argument', async () => {
const provider = new FileMentionProvider([GOAL_COMMAND], workDir, NO_FD);
const line = '/goal ';
Expand Down
Loading