diff --git a/src/components/chat/message-input.tsx b/src/components/chat/message-input.tsx index 35b8f55..72e7314 100644 --- a/src/components/chat/message-input.tsx +++ b/src/components/chat/message-input.tsx @@ -20,6 +20,7 @@ import { ListPlus, Plus, Send, + Command, Square, X, } from "lucide-react" @@ -54,6 +55,7 @@ import { ModeSelector } from "@/components/chat/mode-selector" import { SessionConfigSelector } from "@/components/chat/session-config-selector" import { SlashCommandMenu } from "@/components/chat/slash-command-menu" import { FileMentionMenu } from "@/components/chat/file-mention-menu" +import { DropdownRadioItemContent } from "@/components/chat/dropdown-radio-item-content" import { useFileTree } from "@/hooks/use-file-tree" import { joinFsPath } from "@/lib/path-utils" import { @@ -314,6 +316,7 @@ export function MessageInput({ const textareaRef = useRef(null) const lastDomDropAtRef = useRef(0) const composingRef = useRef(false) + const cursorPosRef = useRef(null) const textRef = useRef(text) const disabledRef = useRef(disabled) const isPromptingRef = useRef(isPrompting) @@ -778,6 +781,24 @@ export function MessageInput({ setSlashMenuOpen(false) }, []) + const handleSlashPopoverSelect = useCallback((cmd: AvailableCommandInfo) => { + const pos = cursorPosRef.current ?? textRef.current.length + const before = textRef.current.slice(0, pos) + const after = textRef.current.slice(pos) + const needsSpace = pos > 0 && !/\s$/.test(before) + const insertion = `${needsSpace ? " " : ""}/${cmd.name} ` + const newText = before + insertion + after + setText(newText) + requestAnimationFrame(() => { + const ta = textareaRef.current + if (ta) { + ta.focus() + const newPos = pos + insertion.length + ta.setSelectionRange(newPos, newPos) + } + }) + }, []) + const atTriggerPosRef = useRef(atTriggerPos) useEffect(() => { atTriggerPosRef.current = atTriggerPos @@ -1476,26 +1497,60 @@ export function MessageInput({ autoFocus={autoFocus} />
-
+
+ + + + + + {slashCommands.map((cmd) => ( + handleSlashPopoverSelect(cmd)} + > + + + ))} + + {/* 宽屏内联显示,窄屏(<300px)通过"更多"气泡显示 */}
{selectorItems}
{hasAnySelector && ( diff --git a/src/components/chat/session-config-selector.tsx b/src/components/chat/session-config-selector.tsx index 781088f..c8a9402 100644 --- a/src/components/chat/session-config-selector.tsx +++ b/src/components/chat/session-config-selector.tsx @@ -37,9 +37,12 @@ export function SessionConfigSelector({