Extract a Selection::buffer_row_range method
This commit is contained in:
@@ -1,7 +1,7 @@
|
||||
use crate::{
|
||||
editor::{
|
||||
buffer::{Anchor, Buffer, Point, ToPoint},
|
||||
display_map::DisplayMap,
|
||||
display_map::{Bias, DisplayMap},
|
||||
DisplayPoint,
|
||||
},
|
||||
time,
|
||||
@@ -72,4 +72,27 @@ impl Selection {
|
||||
start..end
|
||||
}
|
||||
}
|
||||
|
||||
pub fn buffer_row_range(&self, map: &DisplayMap, ctx: &AppContext) -> Range<u32> {
|
||||
let display_start = self.start.to_display_point(map, ctx).unwrap();
|
||||
let buffer_start = DisplayPoint::new(display_start.row(), 0)
|
||||
.to_buffer_point(map, Bias::Left, ctx)
|
||||
.unwrap();
|
||||
|
||||
let mut display_end = self.end.to_display_point(map, ctx).unwrap();
|
||||
if display_end != map.max_point(ctx)
|
||||
&& display_start.row() != display_end.row()
|
||||
&& display_end.column() == 0
|
||||
{
|
||||
*display_end.row_mut() -= 1;
|
||||
}
|
||||
let buffer_end = DisplayPoint::new(
|
||||
display_end.row(),
|
||||
map.line_len(display_end.row(), ctx).unwrap(),
|
||||
)
|
||||
.to_buffer_point(map, Bias::Left, ctx)
|
||||
.unwrap();
|
||||
|
||||
buffer_start.row..buffer_end.row + 1
|
||||
}
|
||||
}
|
||||
|
||||
@@ -554,6 +554,7 @@ impl BufferView {
|
||||
self.start_transaction(ctx);
|
||||
|
||||
let app = ctx.as_ref();
|
||||
let map = self.display_map.read(app);
|
||||
let buffer = self.buffer.read(app);
|
||||
|
||||
let mut new_cursors = Vec::new();
|
||||
@@ -561,52 +562,49 @@ impl BufferView {
|
||||
|
||||
let mut selections = self.selections(app).iter().peekable();
|
||||
while let Some(selection) = selections.next() {
|
||||
let start = selection.start.to_point(buffer).unwrap();
|
||||
let mut end = selection.end.to_point(buffer).unwrap();
|
||||
let goal_column = if selection.reversed {
|
||||
start.column
|
||||
} else {
|
||||
end.column
|
||||
};
|
||||
let mut range = selection.buffer_row_range(map, app);
|
||||
let goal_display_column = selection
|
||||
.head()
|
||||
.to_display_point(map, app)
|
||||
.unwrap()
|
||||
.column();
|
||||
|
||||
// Accumulate contiguous regions of rows that we want to delete.
|
||||
while let Some(next_selection) = selections.peek() {
|
||||
let next_start = next_selection.start.to_point(buffer).unwrap();
|
||||
if next_start.row <= end.row + 1 {
|
||||
end = next_selection.end.to_point(buffer).unwrap();
|
||||
let next_range = next_selection.buffer_row_range(map, app);
|
||||
if next_range.start <= range.end {
|
||||
range.end = next_range.end;
|
||||
selections.next().unwrap();
|
||||
} else {
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
// When the deletion straddles multiple rows but ends at the beginning of a line, avoid
|
||||
// deleting that final line.
|
||||
if start.row != end.row && end.column == 0 {
|
||||
end.row -= 1;
|
||||
}
|
||||
|
||||
let mut edit_start = Point::new(start.row, 0).to_offset(buffer).unwrap();
|
||||
let mut edit_start = Point::new(range.start, 0).to_offset(buffer).unwrap();
|
||||
let edit_end;
|
||||
let mut cursor;
|
||||
|
||||
if let Ok(end_offset) = Point::new(end.row + 1, 0).to_offset(buffer) {
|
||||
let cursor_buffer_row;
|
||||
if let Ok(end_offset) = Point::new(range.end, 0).to_offset(buffer) {
|
||||
// If there's a line after the range, delete the \n from the end of the row range
|
||||
// and position the cursor on the next line.
|
||||
edit_end = end_offset;
|
||||
cursor = Point::new(end.row + 1, goal_column);
|
||||
cursor_buffer_row = range.end;
|
||||
} else {
|
||||
// If there isn't a line after the range, delete the \n from the line before the
|
||||
// start of the row range and position the cursor there.
|
||||
edit_start = edit_start.saturating_sub(1);
|
||||
edit_end = buffer.len();
|
||||
cursor = Point::new(start.row.saturating_sub(1), goal_column);
|
||||
cursor_buffer_row = range.start.saturating_sub(1);
|
||||
}
|
||||
// We tried to maintain the column of the original cursor but the new line may be
|
||||
// shorter, so clip the new cursor's column.
|
||||
cursor.column = cmp::min(cursor.column, buffer.line_len(cursor.row).unwrap());
|
||||
|
||||
new_cursors.push(cursor);
|
||||
let mut cursor = Point::new(cursor_buffer_row, 0)
|
||||
.to_display_point(map, app)
|
||||
.unwrap();
|
||||
*cursor.column_mut() = cmp::min(
|
||||
goal_display_column,
|
||||
map.line_len(cursor.row(), app).unwrap(),
|
||||
);
|
||||
|
||||
new_cursors.push(cursor.to_buffer_point(map, Bias::Left, app).unwrap());
|
||||
edit_ranges.push(edit_start..edit_end);
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user