Skip to content

Commit b8ae95d

Browse files
committed
Use offsets instead of row ranges
1 parent 5976649 commit b8ae95d

File tree

1 file changed

+38
-31
lines changed

1 file changed

+38
-31
lines changed

crates/editor/src/editor.rs

Lines changed: 38 additions & 31 deletions
Original file line numberDiff line numberDiff line change
@@ -77,7 +77,7 @@ use ::git::{
7777
use aho_corasick::AhoCorasick;
7878
use anyhow::{Context as _, Result, anyhow};
7979
use blink_manager::BlinkManager;
80-
use buffer_diff::{DiffHunkStatus, DiffHunkStatusKind};
80+
use buffer_diff::DiffHunkStatus;
8181
use client::{Collaborator, ParticipantIndex, parse_zed_link};
8282
use clock::ReplicaId;
8383
use 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

Comments
 (0)