@@ -806,6 +806,67 @@ export function Prompt(props: PromptProps) {
806806 )
807807 }
808808
809+ function expandPasteExtmark ( extmark : { id : number ; start : number ; end : number } ) {
810+ const partIndex = store . extmarkToPartIndex . get ( extmark . id )
811+ const part = partIndex === undefined ? undefined : store . prompt . parts [ partIndex ]
812+ if ( part ?. type !== "text" || ! part . source ?. text ) return false
813+
814+ const nextInput = store . prompt . input . slice ( 0 , extmark . start ) + part . text + store . prompt . input . slice ( extmark . end )
815+ const delta = part . text . length - ( extmark . end - extmark . start )
816+ const nextParts = store . prompt . parts
817+ . flatMap ( ( item , index ) => {
818+ if ( index === partIndex ) return [ ]
819+ const next = structuredClone ( unwrap ( item ) )
820+ if ( next . type === "agent" && next . source && next . source . start >= extmark . end ) {
821+ next . source . start += delta
822+ next . source . end += delta
823+ }
824+ if ( next . type === "file" && next . source ?. text && next . source . text . start >= extmark . end ) {
825+ next . source . text . start += delta
826+ next . source . text . end += delta
827+ }
828+ if ( next . type === "text" && next . source ?. text && next . source . text . start >= extmark . end ) {
829+ next . source . text . start += delta
830+ next . source . text . end += delta
831+ }
832+ return [ next ]
833+ } )
834+ . filter ( ( item ) : item is PromptInfo [ "parts" ] [ number ] => item !== undefined )
835+
836+ input . setText ( nextInput )
837+ setStore ( "prompt" , {
838+ input : nextInput ,
839+ parts : nextParts ,
840+ } )
841+ restoreExtmarksFromParts ( nextParts )
842+ input . cursorOffset = extmark . start + part . text . length
843+ return true
844+ }
845+
846+ function expandPasteBlockAtMouse ( event : MouseEvent ) {
847+ if ( event . button !== 0 ) return false
848+ const localX = event . x - input . x
849+ const localY = event . y - input . y
850+ if ( localX < 0 || localY < 0 || localX >= input . width || localY >= input . height ) return false
851+
852+ const previousOffset = input . cursorOffset
853+ input . editorView . setLocalSelection ( localX , localY , localX , localY , undefined , undefined , true , false )
854+ input . editorView . resetLocalSelection ( )
855+ const offset = input . cursorOffset
856+ const extmark = input . extmarks . getAllForTypeId ( promptPartTypeId ) . find ( ( item ) => {
857+ const partIndex = store . extmarkToPartIndex . get ( item . id )
858+ const part = partIndex === undefined ? undefined : store . prompt . parts [ partIndex ]
859+ if ( part ?. type !== "text" ) return false
860+ return ( offset >= item . start && offset <= item . end ) || ( offset + 1 >= item . start && offset + 1 <= item . end )
861+ } )
862+ if ( ! extmark ) {
863+ input . cursorOffset = previousOffset
864+ return false
865+ }
866+
867+ return expandPasteExtmark ( extmark )
868+ }
869+
809870 const stashCommands = createMemo ( ( ) =>
810871 [
811872 {
@@ -1572,6 +1633,11 @@ export function Prompt(props: PromptProps) {
15721633 } , 0 )
15731634 } }
15741635 onMouseDown = { ( r : MouseEvent ) => r . target ?. focus ( ) }
1636+ onMouseUp = { ( event : MouseEvent ) => {
1637+ if ( ! expandPasteBlockAtMouse ( event ) ) return
1638+ event . preventDefault ( )
1639+ event . stopPropagation ( )
1640+ } }
15751641 focusedBackgroundColor = { theme . backgroundElement }
15761642 cursorColor = { props . disabled ? theme . backgroundElement : theme . text }
15771643 syntaxStyle = { syntax ( ) }
0 commit comments