feat(coding-agent,tui): add stacked autocomplete providers closes #2983
This commit is contained in:
@@ -1,4 +1,4 @@
|
||||
import type { AutocompleteProvider, AutocompleteSuggestions, CombinedAutocompleteProvider } from "../autocomplete.js";
|
||||
import type { AutocompleteProvider, AutocompleteSuggestions } from "../autocomplete.js";
|
||||
import { getKeybindings } from "../keybindings.js";
|
||||
import { decodePrintableKey, matchesKey } from "../keys.js";
|
||||
import { KillRing } from "../kill-ring.js";
|
||||
@@ -1054,17 +1054,16 @@ export class Editor implements Component, Focusable {
|
||||
if (char === "/" && this.isAtStartOfMessage()) {
|
||||
this.tryTriggerAutocomplete();
|
||||
}
|
||||
// Auto-trigger for "@" file reference (fuzzy search)
|
||||
else if (char === "@") {
|
||||
// Auto-trigger for symbol-based completion like @ or # at token boundaries
|
||||
else if (char === "@" || char === "#") {
|
||||
const currentLine = this.state.lines[this.state.cursorLine] || "";
|
||||
const textBeforeCursor = currentLine.slice(0, this.state.cursorCol);
|
||||
// Only trigger if @ is after whitespace or at start of line
|
||||
const charBeforeAt = textBeforeCursor[textBeforeCursor.length - 2];
|
||||
if (textBeforeCursor.length === 1 || charBeforeAt === " " || charBeforeAt === "\t") {
|
||||
const charBeforeSymbol = textBeforeCursor[textBeforeCursor.length - 2];
|
||||
if (textBeforeCursor.length === 1 || charBeforeSymbol === " " || charBeforeSymbol === "\t") {
|
||||
this.tryTriggerAutocomplete();
|
||||
}
|
||||
}
|
||||
// Also auto-trigger when typing letters in a slash command context
|
||||
// Also auto-trigger when typing letters in a slash command or symbol completion context
|
||||
else if (/[a-zA-Z0-9.\-_]/.test(char)) {
|
||||
const currentLine = this.state.lines[this.state.cursorLine] || "";
|
||||
const textBeforeCursor = currentLine.slice(0, this.state.cursorCol);
|
||||
@@ -1072,8 +1071,8 @@ export class Editor implements Component, Focusable {
|
||||
if (this.isInSlashCommandContext(textBeforeCursor)) {
|
||||
this.tryTriggerAutocomplete();
|
||||
}
|
||||
// Check if we're in an @ file reference context
|
||||
else if (textBeforeCursor.match(/(?:^|[\s])@[^\s]*$/)) {
|
||||
// Check if we're in a symbol-based completion context like @ or #
|
||||
else if (textBeforeCursor.match(/(?:^|[\s])[@#][^\s]*$/)) {
|
||||
this.tryTriggerAutocomplete();
|
||||
}
|
||||
}
|
||||
@@ -1240,8 +1239,8 @@ export class Editor implements Component, Focusable {
|
||||
if (this.isInSlashCommandContext(textBeforeCursor)) {
|
||||
this.tryTriggerAutocomplete();
|
||||
}
|
||||
// @ file reference context
|
||||
else if (textBeforeCursor.match(/(?:^|[\s])@[^\s]*$/)) {
|
||||
// Symbol-based completion context like @ or #
|
||||
else if (textBeforeCursor.match(/(?:^|[\s])[@#][^\s]*$/)) {
|
||||
this.tryTriggerAutocomplete();
|
||||
}
|
||||
}
|
||||
@@ -1604,8 +1603,8 @@ export class Editor implements Component, Focusable {
|
||||
if (this.isInSlashCommandContext(textBeforeCursor)) {
|
||||
this.tryTriggerAutocomplete();
|
||||
}
|
||||
// @ file reference context
|
||||
else if (textBeforeCursor.match(/(?:^|[\s])@[^\s]*$/)) {
|
||||
// Symbol-based completion context like @ or #
|
||||
else if (textBeforeCursor.match(/(?:^|[\s])[@#][^\s]*$/)) {
|
||||
this.tryTriggerAutocomplete();
|
||||
}
|
||||
}
|
||||
@@ -2108,10 +2107,13 @@ export class Editor implements Component, Focusable {
|
||||
if (!this.autocompleteProvider) return;
|
||||
|
||||
if (options.force) {
|
||||
const provider = this.autocompleteProvider as CombinedAutocompleteProvider;
|
||||
const shouldTrigger =
|
||||
!provider.shouldTriggerFileCompletion ||
|
||||
provider.shouldTriggerFileCompletion(this.state.lines, this.state.cursorLine, this.state.cursorCol);
|
||||
!this.autocompleteProvider.shouldTriggerFileCompletion ||
|
||||
this.autocompleteProvider.shouldTriggerFileCompletion(
|
||||
this.state.lines,
|
||||
this.state.cursorLine,
|
||||
this.state.cursorCol,
|
||||
);
|
||||
if (!shouldTrigger) {
|
||||
return;
|
||||
}
|
||||
@@ -2162,8 +2164,8 @@ export class Editor implements Component, Focusable {
|
||||
|
||||
const currentLine = this.state.lines[this.state.cursorLine] || "";
|
||||
const textBeforeCursor = currentLine.slice(0, this.state.cursorCol);
|
||||
const isAttachmentContext = /(?:^|[ \t])@(?:"[^"]*|[^\s]*)$/.test(textBeforeCursor);
|
||||
return isAttachmentContext ? ATTACHMENT_AUTOCOMPLETE_DEBOUNCE_MS : 0;
|
||||
const isSymbolAutocompleteContext = /(?:^|[ \t])(?:@(?:"[^"]*|[^\s]*)|#[^\s]*)$/.test(textBeforeCursor);
|
||||
return isSymbolAutocompleteContext ? ATTACHMENT_AUTOCOMPLETE_DEBOUNCE_MS : 0;
|
||||
}
|
||||
|
||||
private async runAutocompleteRequest(
|
||||
|
||||
Reference in New Issue
Block a user