Fix being unable to put a cursor after trailing deletion hunks (#26621)

Closes #26541

Release Notes:

- Fixed a bug that prevented putting the cursor after a deletion hunk at
the end of a file, in the absence of trailing newlines

---------

Co-authored-by: Max <max@zed.dev>
This commit is contained in:
Cole Miller 2025-03-13 12:56:54 -04:00 committed by GitHub
parent 25f407baab
commit 2eb4d6b7eb
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
2 changed files with 131 additions and 29 deletions

View file

@ -2007,22 +2007,17 @@ impl MultiBuffer {
cx: &App,
) -> Option<(Entity<Buffer>, Point, ExcerptId)> {
let snapshot = self.read(cx);
let point = point.to_point(&snapshot);
let mut cursor = snapshot.cursor::<Point>();
cursor.seek(&point);
cursor.region().and_then(|region| {
if !region.is_main_buffer {
return None;
}
let overshoot = point - region.range.start;
let buffer_point = region.buffer_range.start + overshoot;
let buffer = self.buffers.borrow()[&region.buffer.remote_id()]
let (buffer, point, is_main_buffer) =
snapshot.point_to_buffer_point(point.to_point(&snapshot))?;
Some((
self.buffers
.borrow()
.get(&buffer.remote_id())?
.buffer
.clone();
Some((buffer, buffer_point, region.excerpt.id))
})
.clone(),
point,
is_main_buffer,
))
}
pub fn buffer_point_to_anchor(
@ -4176,22 +4171,36 @@ impl MultiBufferSnapshot {
let region = cursor.region()?;
let overshoot = offset - region.range.start;
let buffer_offset = region.buffer_range.start + overshoot;
if buffer_offset > region.buffer.len() {
if buffer_offset == region.buffer.len() + 1
&& region.has_trailing_newline
&& !region.is_main_buffer
{
return Some((&cursor.excerpt()?.buffer, cursor.main_buffer_position()?));
} else if buffer_offset > region.buffer.len() {
return None;
}
Some((region.buffer, buffer_offset))
}
pub fn point_to_buffer_point(&self, point: Point) -> Option<(&BufferSnapshot, Point, bool)> {
pub fn point_to_buffer_point(
&self,
point: Point,
) -> Option<(&BufferSnapshot, Point, ExcerptId)> {
let mut cursor = self.cursor::<Point>();
cursor.seek(&point);
let region = cursor.region()?;
let overshoot = point - region.range.start;
let buffer_point = region.buffer_range.start + overshoot;
if buffer_point > region.buffer.max_point() {
let excerpt = cursor.excerpt()?;
if buffer_point == region.buffer.max_point() + Point::new(1, 0)
&& region.has_trailing_newline
&& !region.is_main_buffer
{
return Some((&excerpt.buffer, cursor.main_buffer_position()?, excerpt.id));
} else if buffer_point > region.buffer.max_point() {
return None;
}
Some((region.buffer, buffer_point, region.is_main_buffer))
Some((region.buffer, buffer_point, excerpt.id))
}
pub fn suggested_indents(
@ -4733,6 +4742,9 @@ impl MultiBufferSnapshot {
.buffer
.text_summary_for_range(region.buffer_range.start.key..buffer_point),
);
if point == region.range.end.key && region.has_trailing_newline {
position.add_assign(&D::from_text_summary(&TextSummary::newline()));
}
return Some(position);
} else {
return Some(D::from_text_summary(&self.text_summary()));