@@ -21,7 +21,7 @@ const getKeywordRanges = (
2121 const ranges : { start : number ; end : number } [ ] = [ ]
2222 // This regex is a combination of all keyword types
2323 const regex =
24- / ` ( [ ^ \s ` ] * \. [ ^ \s ` ] + ) ` | ( # C h a n g e s : [ ^ \s , ; : ! ? ] + ) | ( # S e l e c t i o n ) | ( # S a v e d C o n t e x t : (?: W o r k s p a c e S t a t e | J S O N ) \s + " [ ^ " ] + " ) | ( # (?: C o m m i t | C o n t e x t A t C o m m i t ) : [ ^ : ] + : [ ^ \s " ] + \s + " (?: \\ .| [ ^ " \\ ] ) * " ) / g
24+ / ` ( [ ^ \s ` ] * \. [ ^ \s ` ] + ) ` | ( # C h a n g e s : [ ^ \s , ; : ! ? ] + ) | ( # S e l e c t i o n ) | ( # S a v e d C o n t e x t : (?: W o r k s p a c e S t a t e | J S O N ) \s + " [ ^ " ] + " ) | ( # (?: C o m m i t | C o n t e x t A t C o m m i t ) : [ ^ : ] + : [ ^ \s " ] + \s + " (?: \\ .| [ ^ " \\ ] ) * " ) | ( < f r a g m e n t p a t h = " [ ^ " ] + " > \n [ \s \S ] * ? \n < \/ f r a g m e n t > ) / g
2525
2626 let match
2727 while ( ( match = regex . exec ( text ) ) !== null ) {
@@ -126,6 +126,23 @@ const reconstruct_raw_value_from_node = (node: Node): string => {
126126 '\\"'
127127 ) } "${ suffix } `
128128 }
129+ } else if ( el . dataset . type == 'pasted-lines-keyword' ) {
130+ const path = el . dataset . path
131+ const content = el . dataset . content
132+ if ( ! path || content === undefined ) return ''
133+
134+ const line_count = content . split ( '\n' ) . length
135+ const lines_text = line_count == 1 ? 'line' : 'lines'
136+ const label = `Pasted ${ line_count } ${ lines_text } `
137+ const index = inner_content . indexOf ( label )
138+
139+ if ( index != - 1 ) {
140+ const prefix = inner_content . substring ( 0 , index )
141+ const suffix = inner_content . substring ( index + label . length )
142+ return `${ prefix } <fragment path="${ path } ">\n${ content } \n</fragment>${ suffix } `
143+ }
144+
145+ return `<fragment path="${ path } ">\n${ content } \n</fragment>`
129146 }
130147
131148 return inner_content
@@ -287,6 +304,20 @@ export const use_handlers = (
287304 const search_pattern = `#ContextAtCommit:${ repo_name } :${ commit_hash } "${ commit_message . replace ( / " / g, '\\"' ) } "`
288305 const start_index = props . value . indexOf ( search_pattern )
289306
307+ if ( start_index !== - 1 ) {
308+ apply_keyword_deletion ( start_index , start_index + search_pattern . length )
309+ }
310+ } else if ( keyword_type == 'pasted-lines-keyword' ) {
311+ const path = keyword_element . dataset . path
312+ const content = keyword_element . dataset . content
313+ if ( ! path || content === undefined ) return
314+
315+ // Since we can't reliably search for multiline content with indexOf easily if formatting varies,
316+ // and we just clicked a specific element, we might need a better way.
317+ // However, we construct exact strings.
318+ const search_pattern = `<fragment path="${ path } ">\n${ content } \n</fragment>`
319+ const start_index = props . value . indexOf ( search_pattern )
320+
290321 if ( start_index !== - 1 ) {
291322 apply_keyword_deletion ( start_index , start_index + search_pattern . length )
292323 }
@@ -536,6 +567,27 @@ export const use_handlers = (
536567 return false
537568 }
538569
570+ const handle_pasted_lines_keyword_deletion = (
571+ raw_pos : number ,
572+ context_file_paths : string [ ]
573+ ) : boolean => {
574+ const text_before_cursor = props . value . substring ( 0 , raw_pos )
575+ const match = text_before_cursor . match (
576+ / < f r a g m e n t p a t h = " [ ^ " ] + " > \n [ \s \S ] * ?\n < \/ f r a g m e n t > $ /
577+ )
578+
579+ if ( match ) {
580+ const start_of_match = raw_pos - match [ 0 ] . length
581+ const new_value =
582+ props . value . substring ( 0 , start_of_match ) +
583+ props . value . substring ( raw_pos )
584+ const new_raw_cursor_pos = start_of_match
585+ update_value ( new_value , new_raw_cursor_pos )
586+ return true
587+ }
588+ return false
589+ }
590+
539591 const handle_keyword_deletion_by_backspace = (
540592 el : HTMLElement ,
541593 display_pos : number
@@ -570,6 +622,10 @@ export const use_handlers = (
570622 return handle_commit_keyword_deletion ( raw_pos , context_file_paths )
571623 }
572624
625+ if ( el . dataset . type == 'pasted-lines-keyword' ) {
626+ return handle_pasted_lines_keyword_deletion ( raw_pos , context_file_paths )
627+ }
628+
573629 return false
574630 }
575631
@@ -607,7 +663,8 @@ export const use_handlers = (
607663 parent . dataset . type == 'selection-keyword' ||
608664 parent . dataset . type == 'saved-context-keyword' ||
609665 parent . dataset . type == 'commit-keyword' ||
610- parent . dataset . type == 'contextatcommit-keyword'
666+ parent . dataset . type == 'contextatcommit-keyword' ||
667+ parent . dataset . type == 'pasted-lines-keyword'
611668 ) {
612669 const rangeAfter = document . createRange ( )
613670 rangeAfter . selectNodeContents ( parent )
@@ -632,7 +689,8 @@ export const use_handlers = (
632689 el . dataset . type == 'selection-keyword' ||
633690 el . dataset . type == 'saved-context-keyword' ||
634691 el . dataset . type == 'commit-keyword' ||
635- el . dataset . type == 'contextatcommit-keyword'
692+ el . dataset . type == 'contextatcommit-keyword' ||
693+ el . dataset . type == 'pasted-lines-keyword'
636694 ) {
637695 const display_pos = get_caret_position_from_div ( input_ref . current )
638696 if ( handle_keyword_deletion_by_backspace ( el , display_pos ) ) {
0 commit comments