export type TestCommandArgumentCompletion = { value: string; label: string; description: string; }; const TEST_COMMAND_FLAG_COMPLETIONS: TestCommandArgumentCompletion[] = [ { value: "--info", label: "--info", description: "Show full command output", }, { value: "--tags", label: "--tags", description: "Run with Go build tags", }, { value: "--comment", label: "--comment", description: "Ask the model to analyze the test results", }, ]; export function completeTestCommandArguments( argumentPrefix: string, ): TestCommandArgumentCompletion[] | null { if (isCompletingTagValue(argumentPrefix)) return null; const usedFlags = collectUsedFlags(argumentPrefix); const currentToken = currentCompletionToken(argumentPrefix); const matches = TEST_COMMAND_FLAG_COMPLETIONS.filter( (item) => !usedFlags.has(item.value) && item.value.startsWith(currentToken), ); return matches.length > 0 ? matches : null; } /** * Detects whether the cursor is inside a `/test` args context and returns * the text after `/test ` (or "" right after the command). Returns * undefined when the line is not a `/test` command line. */ export function testCommandTailBeforeCursor( line: string, cursorCol: number, ): string | undefined { const beforeCursor = line.slice(0, cursorCol); if (beforeCursor === "/test") return ""; if (!beforeCursor.startsWith("/test ")) return undefined; return beforeCursor.slice("/test ".length); } export function currentCompletionToken(argumentPrefix: string): string { if (argumentPrefix.trim() === "" || /\s$/.test(argumentPrefix)) return ""; return argumentPrefix.trim().split(/\s+/).at(-1) ?? ""; } function collectUsedFlags(argumentPrefix: string): Set { const usedFlags = new Set(); const tokens = argumentPrefix.trim() === "" ? [] : argumentPrefix.trim().split(/\s+/); for (const token of tokens) { if (token === "--info") usedFlags.add("--info"); if (token === "--comment") usedFlags.add("--comment"); if (token === "--tags" || token.startsWith("--tags=")) { usedFlags.add("--tags"); } } return usedFlags; } function isCompletingTagValue(argumentPrefix: string): boolean { return /(?:^|\s)--tags\s+\S+$/.test(argumentPrefix); }