@@ -10,7 +10,15 @@ import { EditorRefPlugin } from "@lexical/react/LexicalEditorRefPlugin"
1010import { HistoryPlugin } from "@lexical/react/LexicalHistoryPlugin"
1111import { LexicalErrorBoundary } from "@lexical/react/LexicalErrorBoundary"
1212import { OnChangePlugin } from "@lexical/react/LexicalOnChangePlugin"
13- import { $getRoot , EditorState , LexicalEditor } from "lexical"
13+ import {
14+ $getRoot ,
15+ EditorState ,
16+ LexicalEditor ,
17+ $getSelection ,
18+ $isRangeSelection ,
19+ $createParagraphNode ,
20+ $createTextNode ,
21+ } from "lexical"
1422
1523import { cn } from "@/lib/utils"
1624import { ModeSelector } from "./ModeSelector"
@@ -25,11 +33,13 @@ import { IndexingStatusBadge } from "./IndexingStatusBadge"
2533import { MentionNode } from "./lexical/MentionNode"
2634import { LexicalMentionPlugin , type MentionInfo , type LexicalMentionPluginRef } from "./lexical/LexicalMentionPlugin"
2735import { LexicalSelectAllPlugin } from "./lexical/LexicalSelectAllPlugin"
36+ import { LexicalPromptHistoryPlugin } from "./lexical/LexicalPromptHistoryPlugin"
2837import ContextMenu from "./ContextMenu"
2938import { ContextMenuOptionType , getContextMenuOptions , SearchResult } from "@/utils/context-mentions"
3039import { MAX_IMAGES_PER_MESSAGE } from "./ChatView"
3140import { CloudAccountSwitcher } from "../cloud/CloudAccountSwitcher"
3241import { ChatContextBar } from "./ChatContextBar"
42+ import { usePromptHistoryData } from "./hooks/usePromptHistoryData"
3343
3444type ChatTextAreaProps = {
3545 inputValue : string
@@ -84,11 +94,11 @@ export const ChatLexicalTextArea = forwardRef<LexicalEditor, ChatTextAreaProps>(
8494 listApiConfigMeta,
8595 customModes,
8696 customModePrompts,
87- // cwd,
97+ cwd,
8898 pinnedApiConfigs,
8999 togglePinnedApiConfig,
90- // taskHistory,
91- // clineMessages,
100+ taskHistory,
101+ clineMessages,
92102 commands,
93103 cloudUserInfo,
94104 } = useExtensionState ( )
@@ -106,6 +116,13 @@ export const ChatLexicalTextArea = forwardRef<LexicalEditor, ChatTextAreaProps>(
106116 const searchTimeoutRef = useRef < NodeJS . Timeout | null > ( null )
107117 const [ isEnhancingPrompt , setIsEnhancingPrompt ] = useState ( false )
108118 const [ isMouseDownOnMenu , setIsMouseDownOnMenu ] = useState ( false )
119+ const editorRef = useRef < LexicalEditor | null > ( null )
120+
121+ const { promptHistory } = usePromptHistoryData ( {
122+ clineMessages,
123+ taskHistory,
124+ cwd,
125+ } )
109126
110127 // Find the ID and display text for the currently selected API configuration.
111128 const { currentConfigId, displayName } = useMemo ( ( ) => {
@@ -310,10 +327,49 @@ export const ChatLexicalTextArea = forwardRef<LexicalEditor, ChatTextAreaProps>(
310327 } else if ( message . type === "ttsStop" ) {
311328 setIsTtsPlaying ( false )
312329 } else if ( message . type === "enhancedPrompt" ) {
313- if ( message . text ) {
330+ if ( message . text && editorRef . current ) {
331+ editorRef . current . update ( ( ) => {
332+ const root = $getRoot ( )
333+ const selection = $getSelection ( )
334+
335+ // Clear current content
336+ root . clear ( )
337+
338+ // Insert new text
339+ const paragraphNode = $createParagraphNode ( )
340+ const textNode = $createTextNode ( message . text )
341+ paragraphNode . append ( textNode )
342+ root . append ( paragraphNode )
343+
344+ // Move cursor to end
345+ if ( $isRangeSelection ( selection ) ) {
346+ root . selectEnd ( )
347+ }
348+ } )
314349 setInputValue ( message . text )
315350 }
316351 setIsEnhancingPrompt ( false )
352+ } else if ( message . type === "insertTextIntoTextarea" ) {
353+ if ( message . text && editorRef . current ) {
354+ // Insert text at cursor position
355+ editorRef . current . update ( ( ) => {
356+ const selection = $getSelection ( )
357+ if ( $isRangeSelection ( selection ) ) {
358+ const anchor = selection . anchor
359+ const textContent = anchor . getNode ( ) . getTextContent ( )
360+ const offset = anchor . offset
361+
362+ // Check if we need to add a space before
363+ const textBefore = textContent . slice ( 0 , offset )
364+ const needsSpaceBefore = textBefore . length > 0 && ! textBefore . endsWith ( " " )
365+ const prefix = needsSpaceBefore ? " " : ""
366+
367+ // Insert the text with space after
368+ const insertText = prefix + message . text + " "
369+ selection . insertText ( insertText )
370+ }
371+ } )
372+ }
317373 } else if ( message . type === "commitSearchResults" ) {
318374 const commits = message . commits . map ( ( commit : any ) => ( {
319375 type : ContextMenuOptionType . Git ,
@@ -329,9 +385,6 @@ export const ChatLexicalTextArea = forwardRef<LexicalEditor, ChatTextAreaProps>(
329385 if ( message . requestId === searchRequestId ) {
330386 setFileSearchResults ( message . results || [ ] )
331387 }
332- } else if ( message . type === "insertTextIntoTextarea" ) {
333- // Lexical editor handles inserts differently. Future improvement.
334- console . log ( "Insert text requested for Lexical, but not yet implemented:" , message . text )
335388 }
336389 }
337390
@@ -698,6 +751,10 @@ export const ChatLexicalTextArea = forwardRef<LexicalEditor, ChatTextAreaProps>(
698751 { /* see: https://github.com/facebook/lexical/discussions/3590#discussioncomment-8955421 */ }
699752 < EditorRefPlugin
700753 editorRef = { ( el ) => {
754+ // Store editor ref locally
755+ editorRef . current = el
756+
757+ // Also forward to parent ref
701758 if ( typeof ref === "function" ) {
702759 ref ( el )
703760 } else if ( ref ) {
@@ -776,6 +833,10 @@ export const ChatLexicalTextArea = forwardRef<LexicalEditor, ChatTextAreaProps>(
776833 onMentionUpdate = { handleMentionUpdate }
777834 materialIconsBaseUri = { materialIconsBaseUri }
778835 />
836+ < LexicalPromptHistoryPlugin
837+ promptHistory = { promptHistory }
838+ showContextMenu = { showContextMenu }
839+ />
779840 < LexicalSelectAllPlugin />
780841 </ LexicalComposer >
781842
0 commit comments