@@ -176,6 +176,7 @@ impl TextEditBuilder {
176
176
pub fn finish ( self ) -> TextEdit {
177
177
let mut indels = self . indels ;
178
178
assert_disjoint_or_equal ( & mut indels) ;
179
+ indels = coalesce_indels ( indels) ;
179
180
TextEdit { indels }
180
181
}
181
182
pub fn invalidates_offset ( & self , offset : TextSize ) -> bool {
@@ -205,6 +206,21 @@ where
205
206
indels. clone ( ) . zip ( indels. skip ( 1 ) ) . all ( |( l, r) | l. delete . end ( ) <= r. delete . start ( ) || l == r)
206
207
}
207
208
209
+ fn coalesce_indels ( indels : Vec < Indel > ) -> Vec < Indel > {
210
+ indels
211
+ . into_iter ( )
212
+ . coalesce ( |mut a, b| {
213
+ if a. delete . end ( ) == b. delete . start ( ) {
214
+ a. insert . push_str ( & b. insert ) ;
215
+ a. delete = TextRange :: new ( a. delete . start ( ) , b. delete . end ( ) ) ;
216
+ Ok ( a)
217
+ } else {
218
+ Err ( ( a, b) )
219
+ }
220
+ } )
221
+ . collect_vec ( )
222
+ }
223
+
208
224
#[ cfg( test) ]
209
225
mod tests {
210
226
use super :: { TextEdit , TextEditBuilder , TextRange } ;
@@ -261,4 +277,40 @@ mod tests {
261
277
let edit2 = TextEdit :: delete ( range ( 9 , 13 ) ) ;
262
278
assert ! ( edit1. union ( edit2) . is_err( ) ) ;
263
279
}
280
+
281
+ #[ test]
282
+ fn test_coalesce_disjoint ( ) {
283
+ let mut builder = TextEditBuilder :: default ( ) ;
284
+ builder. replace ( range ( 1 , 3 ) , "aa" . into ( ) ) ;
285
+ builder. replace ( range ( 5 , 7 ) , "bb" . into ( ) ) ;
286
+ let edit = builder. finish ( ) ;
287
+
288
+ assert_eq ! ( edit. indels. len( ) , 2 ) ;
289
+ }
290
+
291
+ #[ test]
292
+ fn test_coalesce_adjacent ( ) {
293
+ let mut builder = TextEditBuilder :: default ( ) ;
294
+ builder. replace ( range ( 1 , 3 ) , "aa" . into ( ) ) ;
295
+ builder. replace ( range ( 3 , 5 ) , "bb" . into ( ) ) ;
296
+
297
+ let edit = builder. finish ( ) ;
298
+ assert_eq ! ( edit. indels. len( ) , 1 ) ;
299
+ assert_eq ! ( edit. indels[ 0 ] . insert, "aabb" ) ;
300
+ assert_eq ! ( edit. indels[ 0 ] . delete, range( 1 , 5 ) ) ;
301
+ }
302
+
303
+ #[ test]
304
+ fn test_coalesce_adjacent_series ( ) {
305
+ let mut builder = TextEditBuilder :: default ( ) ;
306
+ builder. replace ( range ( 1 , 3 ) , "au" . into ( ) ) ;
307
+ builder. replace ( range ( 3 , 5 ) , "www" . into ( ) ) ;
308
+ builder. replace ( range ( 5 , 8 ) , "" . into ( ) ) ;
309
+ builder. replace ( range ( 8 , 9 ) , "ub" . into ( ) ) ;
310
+
311
+ let edit = builder. finish ( ) ;
312
+ assert_eq ! ( edit. indels. len( ) , 1 ) ;
313
+ assert_eq ! ( edit. indels[ 0 ] . insert, "auwwwub" ) ;
314
+ assert_eq ! ( edit. indels[ 0 ] . delete, range( 1 , 9 ) ) ;
315
+ }
264
316
}
0 commit comments