@@ -93,9 +93,9 @@ pub fn assure_ends_with_nl(out: &mut Vec<u8>, nl: &BStr) {
9393 }
9494}
9595
96- pub fn write_conflict_marker ( out : & mut Vec < u8 > , marker : u8 , label : Option < & BStr > , marker_size : usize , nl : & BStr ) {
96+ pub fn write_conflict_marker ( out : & mut Vec < u8 > , marker : u8 , label : Option < & BStr > , marker_size : u8 , nl : & BStr ) {
9797 assure_ends_with_nl ( out, nl) ;
98- out. extend ( std:: iter:: repeat ( marker) . take ( marker_size) ) ;
98+ out. extend ( std:: iter:: repeat ( marker) . take ( marker_size as usize ) ) ;
9999 if let Some ( label) = label {
100100 out. push ( b' ' ) ;
101101 out. extend_from_slice ( label) ;
@@ -132,8 +132,8 @@ pub fn fill_ancestor(Range { start, end }: &Range<u32>, in_out: &mut Vec<Hunk>)
132132 for ( idx, next_idx) in ( first_idx..in_out. len ( ) ) . map ( |idx| ( idx, idx + 1 ) ) {
133133 let Some ( next_hunk) = in_out. get ( next_idx) else { break } ;
134134 let hunk = & in_out[ idx] ;
135- if let Some ( lines_to_add) = next_hunk. after . start . checked_sub ( hunk. after . end ) . filter ( is_nonzero) {
136- in_out. push ( ancestor_hunk ( hunk. after . end , lines_to_add) ) ;
135+ if let Some ( lines_to_add) = next_hunk. before . start . checked_sub ( hunk. before . end ) . filter ( is_nonzero) {
136+ in_out. push ( ancestor_hunk ( hunk. before . end , lines_to_add) ) ;
137137 added_hunks = true ;
138138 }
139139 }
@@ -414,21 +414,46 @@ fn write_tokens(
414414}
415415
416416/// Find all hunks in `iter` which aren't from the same side as `hunk` and intersect with it.
417- /// Return `true` if `out` is non-empty after the operation, indicating overlapping hunks were found.
418- pub fn take_intersecting ( hunk : & Hunk , iter : & mut Peekable < impl Iterator < Item = Hunk > > , out : & mut Vec < Hunk > ) -> bool {
419- out. clear ( ) ;
420- while iter
421- . peek ( )
422- . filter ( |b_hunk| {
423- b_hunk. side != hunk. side
424- && ( hunk. before . contains ( & b_hunk. before . start )
425- || ( hunk. before . is_empty ( ) && hunk. before . start == b_hunk. before . start ) )
426- } )
427- . is_some ( )
428- {
429- out. extend ( iter. next ( ) ) ;
417+ /// Also put `hunk` into `input` so it's the first item, and possibly put more hunks of the side of `hunk` so
418+ /// `iter` doesn't have any overlapping hunks left.
419+ /// Return `true` if `intersecting` is non-empty after the operation, indicating overlapping hunks were found.
420+ pub fn take_intersecting (
421+ iter : & mut Peekable < impl Iterator < Item = Hunk > > ,
422+ input : & mut Vec < Hunk > ,
423+ intersecting : & mut Vec < Hunk > ,
424+ ) -> Option < ( ) > {
425+ input. clear ( ) ;
426+ input. push ( iter. next ( ) ?) ;
427+ intersecting. clear ( ) ;
428+
429+ fn left_overlaps_right ( left : & Hunk , right : & Hunk ) -> bool {
430+ left. side != right. side
431+ && ( right. before . contains ( & left. before . start )
432+ || ( right. before . is_empty ( ) && right. before . start == left. before . start ) )
433+ }
434+
435+ loop {
436+ let hunk = input. last ( ) . expect ( "just pushed" ) ;
437+ while iter. peek ( ) . filter ( |b_hunk| left_overlaps_right ( b_hunk, hunk) ) . is_some ( ) {
438+ intersecting. extend ( iter. next ( ) ) ;
439+ }
440+ // The hunks that overlap might themselves overlap with a following hunk of the other side.
441+ // If so, split it so it doesn't overlap anymore.
442+ let mut found_more_intersections = false ;
443+ while intersecting
444+ . last_mut ( )
445+ . zip ( iter. peek_mut ( ) )
446+ . filter ( |( last_intersecting, candidate) | left_overlaps_right ( candidate, last_intersecting) )
447+ . is_some ( )
448+ {
449+ input. extend ( iter. next ( ) ) ;
450+ found_more_intersections = true ;
451+ }
452+ if !found_more_intersections {
453+ break ;
454+ }
430455 }
431- !out . is_empty ( )
456+ Some ( ( ) )
432457}
433458
434459pub fn tokens ( input : & [ u8 ] ) -> imara_diff:: sources:: ByteLines < ' _ , true > {
0 commit comments