@@ -1000,23 +1000,35 @@ fn merge_text_and_snippet_edits(
1000
1000
1001
1001
let mut new_text = current_indel. insert ;
1002
1002
1003
- // escape out snippet text
1004
- stdx:: replace ( & mut new_text, '\\' , r"\\" ) ;
1005
- stdx:: replace ( & mut new_text, '$' , r"\$" ) ;
1003
+ // find which snippet bits need to be escaped
1004
+ let escape_places =
1005
+ new_text. rmatch_indices ( [ '\\' , '$' ] ) . map ( |( insert, _) | insert) . collect_vec ( ) ;
1006
+ let mut escape_places = escape_places. into_iter ( ) . peekable ( ) ;
1007
+ let mut escape_prior_bits = |new_text : & mut String , up_to : usize | {
1008
+ for before in escape_places. peeking_take_while ( |insert| * insert >= up_to) {
1009
+ new_text. insert ( before, '\\' ) ;
1010
+ }
1011
+ } ;
1006
1012
1007
- // ... and apply!
1013
+ // insert snippets, and escaping any needed bits along the way
1008
1014
for ( index, range) in all_snippets. iter ( ) . rev ( ) {
1009
- let start = ( range. start ( ) - new_range. start ( ) ) . into ( ) ;
1010
- let end = ( range . end ( ) - new_range . start ( ) ) . into ( ) ;
1015
+ let text_range = range - new_range. start ( ) ;
1016
+ let ( start , end) = ( text_range . start ( ) . into ( ) , text_range . end ( ) . into ( ) ) ;
1011
1017
1012
1018
if range. is_empty ( ) {
1019
+ escape_prior_bits ( & mut new_text, start) ;
1013
1020
new_text. insert_str ( start, & format ! ( "${index}" ) ) ;
1014
1021
} else {
1022
+ escape_prior_bits ( & mut new_text, end) ;
1015
1023
new_text. insert ( end, '}' ) ;
1024
+ escape_prior_bits ( & mut new_text, start) ;
1016
1025
new_text. insert_str ( start, & format ! ( "${{{index}:" ) ) ;
1017
1026
}
1018
1027
}
1019
1028
1029
+ // escape any remaining bits
1030
+ escape_prior_bits ( & mut new_text, 0 ) ;
1031
+
1020
1032
edits. push ( snippet_text_edit (
1021
1033
line_index,
1022
1034
true ,
0 commit comments