(filePath: string)
| 395 | |
| 396 | // Handle file selection |
| 397 | const selectFile = async (filePath: string) => { |
| 398 | const beforeCursor = inputText.slice(0, cursorPosition); |
| 399 | |
| 400 | // Find the first @ symbol that starts a file search context (same logic as updateFileSearchState) |
| 401 | let firstAtIndex = -1; |
| 402 | for (let i = beforeCursor.length - 1; i >= 0; i--) { |
| 403 | if (beforeCursor[i] === "@") { |
| 404 | // Check if this @ is at the start of a word (preceded by space/newline or start of string) |
| 405 | const beforeAt = beforeCursor.slice(0, i); |
| 406 | const lastChar = beforeAt[beforeAt.length - 1]; |
| 407 | if (i === 0 || lastChar === " " || lastChar === "\n") { |
| 408 | // Check if there's any space/newline between this @ and cursor |
| 409 | const afterThis = beforeCursor.slice(i + 1); |
| 410 | if (!afterThis.includes(" ") && !afterThis.includes("\n")) { |
| 411 | firstAtIndex = i; |
| 412 | break; |
| 413 | } |
| 414 | } |
| 415 | } |
| 416 | } |
| 417 | |
| 418 | if (firstAtIndex !== -1) { |
| 419 | const beforeAt = inputText.slice(0, firstAtIndex); |
| 420 | const afterCursor = inputText.slice(cursorPosition); |
| 421 | |
| 422 | // Replace the partial file reference with the full file path |
| 423 | const newText = beforeAt + "@" + filePath + " " + afterCursor; |
| 424 | const newCursorPos = firstAtIndex + 1 + filePath.length + 1; |
| 425 | |
| 426 | textBuffer.setText(newText); |
| 427 | textBuffer.setCursor(newCursorPos); |
| 428 | setInputText(newText); |
| 429 | setCursorPosition(newCursorPos); |
| 430 | setShowFileSearch(false); |
| 431 | |
| 432 | // Read the file content and notify parent component |
| 433 | if (onFileAttached) { |
| 434 | try { |
| 435 | const fs = await import("fs/promises"); |
| 436 | const path = await import("path"); |
| 437 | const absolutePath = path.resolve(filePath); |
| 438 | const content = await fs.readFile(absolutePath, "utf-8"); |
| 439 | onFileAttached(absolutePath, content); |
| 440 | } catch (error) { |
| 441 | // If file doesn't exist, just attach the filename without content |
| 442 | if (error instanceof Error && (error as any).code === "ENOENT") { |
| 443 | const path = await import("path"); |
| 444 | const absolutePath = path.resolve(filePath); |
| 445 | onFileAttached(absolutePath, filePath); |
| 446 | } else { |
| 447 | console.error(`Error reading file ${filePath}:`, error); |
| 448 | } |
| 449 | } |
| 450 | } |
| 451 | } |
| 452 | }; |
| 453 | |
| 454 | const handleSlashCommandNavigation = (key: any): boolean => { |
no test coverage detected