@@ -723,6 +723,67 @@ export function Prompt(props: PromptProps) {
723723 )
724724 }
725725
726+ function expandPasteExtmark ( extmark : { id : number ; start : number ; end : number } ) {
727+ const partIndex = store . extmarkToPartIndex . get ( extmark . id )
728+ const part = partIndex === undefined ? undefined : store . prompt . parts [ partIndex ]
729+ if ( part ?. type !== "text" || ! part . source ?. text ) return false
730+
731+ const nextInput = store . prompt . input . slice ( 0 , extmark . start ) + part . text + store . prompt . input . slice ( extmark . end )
732+ const delta = part . text . length - ( extmark . end - extmark . start )
733+ const nextParts = store . prompt . parts
734+ . flatMap ( ( item , index ) => {
735+ if ( index === partIndex ) return [ ]
736+ const next = structuredClone ( unwrap ( item ) )
737+ if ( next . type === "agent" && next . source && next . source . start >= extmark . end ) {
738+ next . source . start += delta
739+ next . source . end += delta
740+ }
741+ if ( next . type === "file" && next . source ?. text && next . source . text . start >= extmark . end ) {
742+ next . source . text . start += delta
743+ next . source . text . end += delta
744+ }
745+ if ( next . type === "text" && next . source ?. text && next . source . text . start >= extmark . end ) {
746+ next . source . text . start += delta
747+ next . source . text . end += delta
748+ }
749+ return [ next ]
750+ } )
751+ . filter ( ( item ) : item is PromptInfo [ "parts" ] [ number ] => item !== undefined )
752+
753+ input . setText ( nextInput )
754+ setStore ( "prompt" , {
755+ input : nextInput ,
756+ parts : nextParts ,
757+ } )
758+ restoreExtmarksFromParts ( nextParts )
759+ input . cursorOffset = extmark . start + part . text . length
760+ return true
761+ }
762+
763+ function expandPasteBlockAtMouse ( event : MouseEvent ) {
764+ if ( event . button !== 0 ) return false
765+ const localX = event . x - input . x
766+ const localY = event . y - input . y
767+ if ( localX < 0 || localY < 0 || localX >= input . width || localY >= input . height ) return false
768+
769+ const previousOffset = input . cursorOffset
770+ input . editorView . setLocalSelection ( localX , localY , localX , localY , undefined , undefined , true , false )
771+ input . editorView . resetLocalSelection ( )
772+ const offset = input . cursorOffset
773+ const extmark = input . extmarks . getAllForTypeId ( promptPartTypeId ) . find ( ( item ) => {
774+ const partIndex = store . extmarkToPartIndex . get ( item . id )
775+ const part = partIndex === undefined ? undefined : store . prompt . parts [ partIndex ]
776+ if ( part ?. type !== "text" ) return false
777+ return ( offset >= item . start && offset <= item . end ) || ( offset + 1 >= item . start && offset + 1 <= item . end )
778+ } )
779+ if ( ! extmark ) {
780+ input . cursorOffset = previousOffset
781+ return false
782+ }
783+
784+ return expandPasteExtmark ( extmark )
785+ }
786+
726787 const stashCommands = createMemo ( ( ) =>
727788 [
728789 {
@@ -1458,6 +1519,11 @@ export function Prompt(props: PromptProps) {
14581519 } , 0 )
14591520 } }
14601521 onMouseDown = { ( r : MouseEvent ) => r . target ?. focus ( ) }
1522+ onMouseUp = { ( event : MouseEvent ) => {
1523+ if ( ! expandPasteBlockAtMouse ( event ) ) return
1524+ event . preventDefault ( )
1525+ event . stopPropagation ( )
1526+ } }
14611527 focusedBackgroundColor = { theme . backgroundElement }
14621528 cursorColor = { props . disabled ? theme . backgroundElement : theme . text }
14631529 syntaxStyle = { syntax ( ) }
0 commit comments