diff --git a/src/components/chat/message-input.tsx b/src/components/chat/message-input.tsx index 2aa83cc..80637e9 100644 --- a/src/components/chat/message-input.tsx +++ b/src/components/chat/message-input.tsx @@ -46,7 +46,9 @@ import type { } from "@/lib/types" import { ATTACH_FILE_TO_SESSION_EVENT, + APPEND_TEXT_TO_SESSION_EVENT, type AttachFileToSessionDetail, + type AppendTextToSessionDetail, } from "@/lib/session-attachment-events" import { ModeSelector } from "@/components/chat/mode-selector" import { SessionConfigSelector } from "@/components/chat/session-config-selector" @@ -778,6 +780,29 @@ export function MessageInput({ } }, [appendResourceAttachments, attachmentTabId]) + useEffect(() => { + if (!attachmentTabId) return + + const handleAppendText = (event: Event) => { + const customEvent = event as CustomEvent + if (!customEvent.detail) return + if (customEvent.detail.tabId !== attachmentTabId) return + const appendText = customEvent.detail.text + setText((prev) => { + if (prev.length === 0) return appendText + return prev.endsWith(" ") ? prev + appendText : prev + " " + appendText + }) + requestAnimationFrame(() => { + textareaRef.current?.focus() + }) + } + + window.addEventListener(APPEND_TEXT_TO_SESSION_EVENT, handleAppendText) + return () => { + window.removeEventListener(APPEND_TEXT_TO_SESSION_EVENT, handleAppendText) + } + }, [attachmentTabId]) + useEffect(() => { let cancelled = false const unlisteners: Array<() => void | Promise> = [] diff --git a/src/components/layout/aux-panel-file-tree-tab.tsx b/src/components/layout/aux-panel-file-tree-tab.tsx index 6875666..7ced47f 100644 --- a/src/components/layout/aux-panel-file-tree-tab.tsx +++ b/src/components/layout/aux-panel-file-tree-tab.tsx @@ -38,7 +38,10 @@ import { stopFileTreeWatch, } from "@/lib/tauri" import { disposeTauriListener } from "@/lib/tauri-listener" -import { emitAttachFileToSession } from "@/lib/session-attachment-events" +import { + emitAttachFileToSession, + emitAppendTextToSession, +} from "@/lib/session-attachment-events" import type { FileTreeChangedEvent, FileTreeNode, @@ -612,6 +615,17 @@ function RenderNode({ const isGitMenuDisabled = !gitEnabled || isGitignoreIgnored const shouldRenderChildren = expandedPaths.has(node.path) + const handleAttachDirToSession = () => { + if (!activeSessionTabId) return + const relativePath = node.path.endsWith("/") + ? `@${node.path} ` + : `@${node.path}/ ` + emitAppendTextToSession({ + tabId: activeSessionTabId, + text: relativePath, + }) + } + const handleOpenDirInSystemExplorer = async () => { try { await revealItemInDir(absolutePath) @@ -669,6 +683,12 @@ function RenderNode({ + + {t("attachToCurrentSession")} + {t("new")} diff --git a/src/lib/session-attachment-events.ts b/src/lib/session-attachment-events.ts index ad1c7ae..d16cd58 100644 --- a/src/lib/session-attachment-events.ts +++ b/src/lib/session-attachment-events.ts @@ -15,3 +15,21 @@ export function emitAttachFileToSession( }) ) } + +export const APPEND_TEXT_TO_SESSION_EVENT = "codeg:append-text-to-session" + +export interface AppendTextToSessionDetail { + tabId: string + text: string +} + +export function emitAppendTextToSession( + detail: AppendTextToSessionDetail +): void { + if (typeof window === "undefined") return + window.dispatchEvent( + new CustomEvent(APPEND_TEXT_TO_SESSION_EVENT, { + detail, + }) + ) +}