@@ -77,7 +77,7 @@ use ::git::{
7777use aho_corasick::AhoCorasick;
7878use anyhow::{Context as _, Result, anyhow};
7979use blink_manager::BlinkManager;
80- use buffer_diff::{ DiffHunkStatus, DiffHunkStatusKind} ;
80+ use buffer_diff::DiffHunkStatus;
8181use client::{Collaborator, ParticipantIndex, parse_zed_link};
8282use clock::ReplicaId;
8383use code_context_menus::{
@@ -20028,51 +20028,58 @@ impl Editor {
2002820028 buffer_ranges.last()
2002920029 }?;
2003020030
20031- let selection = text::ToPoint::to_point(&range.start, buffer).row
20032- ..text::ToPoint::to_point(&range.end, buffer).row;
20031+ let Some(buffer_diff) = multi_buffer.diff_for(buffer.remote_id()) else {
20032+ let selection = text::ToPoint::to_point(&range.start, buffer).row
20033+ ..text::ToPoint::to_point(&range.end, buffer).row;
2003320034
20034- let end_line_start_point = Point::new(selection.end, 0 );
20035- let end_line_start_anchor = multi_buffer_snapshot.anchor_before(end_line_start_point) ;
20035+ return Some((multi_buffer.buffer(buffer.remote_id()).unwrap(), selection) );
20036+ } ;
2003620037
20037- let ranges = [Anchor::min()..end_line_start_anchor] ;
20038+ let buffer_diff_snapshot = buffer_diff.read(cx).snapshot(cx) ;
2003820039
20039- let diff_hunks = self
20040- .diff_hunks_in_ranges(&ranges, &multi_buffer_snapshot)
20041- .filter(|hunk| hunk.row_range.start.0 < selection .end);
20040+ let beginning_anchor = buffer.anchor_before(Point::new(0, 0));
20041+ let start_anchor = buffer.anchor_before(&range.start);
20042+ let end_anchor = buffer.anchor_after(&range .end);
2004220043
2004320044 struct Offsets {
2004420045 start: isize,
2004520046 end: isize,
2004620047 }
2004720048
20048- let offsets = diff_hunks.fold(Offsets { start: 0, end: 0 }, |mut acc, h| {
20049- let hunk_offset = match h.status() {
20050- DiffHunkStatus {
20051- kind: DiffHunkStatusKind::Added,
20052- secondary: _,
20053- } => -(h.row_range.len() as isize),
20054- DiffHunkStatus {
20055- kind: DiffHunkStatusKind::Deleted,
20056- secondary: _,
20057- } => h.row_range.len() as isize,
20058- _ => 0,
20059- };
20049+ let mut delta = Offsets { start: 0, end: 0 };
20050+
20051+ for hunk in
20052+ buffer_diff_snapshot.hunks_intersecting_range(beginning_anchor..end_anchor, buffer)
20053+ {
20054+ let initial_size = hunk.diff_base_byte_range.end as isize
20055+ - hunk.diff_base_byte_range.start as isize;
20056+
20057+ let buffer_range = hunk.buffer_range.to_offset(&buffer);
20058+ let changed_size =
20059+ (cmp::min(buffer_range.end, range.end) as isize) - buffer_range.start as isize;
2006020060
20061- if h.row_range.start.0 < selection.start {
20062- acc.start += hunk_offset;
20061+ if hunk.buffer_range.start.cmp(&start_anchor, buffer).is_le() {
20062+ delta.start += initial_size;
20063+ delta.start -= changed_size;
2006320064 }
20064- acc.end += hunk_offset;
20065- acc
20066- });
2006720065
20068- let diff_aware_selection = Range {
20069- start: selection.start.saturating_add_signed(offsets.start as i32),
20070- end: selection.end.saturating_add_signed(offsets.end as i32),
20071- };
20066+ delta.end += initial_size;
20067+ delta.end -= changed_size;
20068+ }
20069+
20070+ let start_row_in_base_buffer = buffer_diff_snapshot
20071+ .base_text()
20072+ .offset_to_point((range.start as isize + delta.start) as usize)
20073+ .row;
20074+ let end_row_in_base_buffer = buffer_diff_snapshot
20075+ .base_text()
20076+ // off by one
20077+ .offset_to_point((range.end as isize + delta.end) as usize)
20078+ .row;
2007220079
2007320080 Some((
2007420081 multi_buffer.buffer(buffer.remote_id()).unwrap(),
20075- diff_aware_selection ,
20082+ start_row_in_base_buffer..end_row_in_base_buffer ,
2007620083 ))
2007720084 });
2007820085
0 commit comments