Add a bias parameter when converting buffer points to fold points

This commit is contained in:
Max Brunsfeld 2021-07-28 15:08:24 -07:00
parent c1808d09ef
commit 05f8a61bc8
4 changed files with 83 additions and 63 deletions

View File

@ -528,14 +528,14 @@ impl Editor {
.first()
.unwrap()
.head()
.to_display_point(&display_map)
.to_display_point(&display_map, Bias::Left)
.row() as f32;
let last_cursor_bottom = self
.selections(cx)
.last()
.unwrap()
.head()
.to_display_point(&display_map)
.to_display_point(&display_map, Bias::Right)
.row() as f32
+ 1.0;
@ -575,7 +575,7 @@ impl Editor {
let mut target_left = std::f32::INFINITY;
let mut target_right = 0.0_f32;
for selection in self.selections(cx) {
let head = selection.head().to_display_point(&display_map);
let head = selection.head().to_display_point(&display_map, Bias::Left);
let start_column = head.column().saturating_sub(3);
let end_column = cmp::min(display_map.line_len(head.row()), head.column() + 3);
target_left = target_left
@ -806,7 +806,7 @@ impl Editor {
for selection in &mut selections {
let range = selection.point_range(buffer);
if range.start == range.end {
let head = selection.head().to_display_point(&display_map);
let head = selection.head().to_display_point(&display_map, Bias::Left);
let cursor = display_map
.anchor_before(movement::left(&display_map, head).unwrap(), Bias::Left);
selection.set_head(&buffer, cursor);
@ -829,7 +829,7 @@ impl Editor {
for selection in &mut selections {
let range = selection.point_range(buffer);
if range.start == range.end {
let head = selection.head().to_display_point(&display_map);
let head = selection.head().to_display_point(&display_map, Bias::Left);
let cursor = display_map
.anchor_before(movement::right(&display_map, head).unwrap(), Bias::Right);
selection.set_head(&buffer, cursor);
@ -856,7 +856,10 @@ impl Editor {
let mut selections = self.selections(app).iter().peekable();
while let Some(selection) = selections.next() {
let (mut rows, _) = selection.buffer_rows_for_display_rows(false, &display_map);
let goal_display_column = selection.head().to_display_point(&display_map).column();
let goal_display_column = selection
.head()
.to_display_point(&display_map, Bias::Left)
.column();
// Accumulate contiguous regions of rows that we want to delete.
while let Some(next_selection) = selections.peek() {
@ -886,7 +889,8 @@ impl Editor {
cursor_buffer_row = rows.start.saturating_sub(1);
}
let mut cursor = Point::new(cursor_buffer_row, 0).to_display_point(&display_map);
let mut cursor =
Point::new(cursor_buffer_row, 0).to_display_point(&display_map, Bias::Left);
*cursor.column_mut() =
cmp::min(goal_display_column, display_map.line_len(cursor.row()));
@ -1286,8 +1290,8 @@ impl Editor {
let mut selections = self.selections(app).to_vec();
{
for selection in &mut selections {
let start = selection.start.to_display_point(&display_map);
let end = selection.end.to_display_point(&display_map);
let start = selection.start.to_display_point(&display_map, Bias::Left);
let end = selection.end.to_display_point(&display_map, Bias::Left);
if start != end {
selection.end = selection.start.clone();
@ -1310,7 +1314,7 @@ impl Editor {
{
let buffer = self.buffer.read(cx);
for selection in &mut selections {
let head = selection.head().to_display_point(&display_map);
let head = selection.head().to_display_point(&display_map, Bias::Left);
let cursor = display_map
.anchor_before(movement::left(&display_map, head).unwrap(), Bias::Left);
selection.set_head(&buffer, cursor);
@ -1325,8 +1329,8 @@ impl Editor {
let mut selections = self.selections(cx.as_ref()).to_vec();
{
for selection in &mut selections {
let start = selection.start.to_display_point(&display_map);
let end = selection.end.to_display_point(&display_map);
let start = selection.start.to_display_point(&display_map, Bias::Left);
let end = selection.end.to_display_point(&display_map, Bias::Left);
if start != end {
selection.start = selection.end.clone();
@ -1350,7 +1354,7 @@ impl Editor {
let app = cx.as_ref();
let buffer = self.buffer.read(app);
for selection in &mut selections {
let head = selection.head().to_display_point(&display_map);
let head = selection.head().to_display_point(&display_map, Bias::Left);
let cursor = display_map
.anchor_before(movement::right(&display_map, head).unwrap(), Bias::Right);
selection.set_head(&buffer, cursor);
@ -1368,8 +1372,8 @@ impl Editor {
let mut selections = self.selections(cx.as_ref()).to_vec();
{
for selection in &mut selections {
let start = selection.start.to_display_point(&display_map);
let end = selection.end.to_display_point(&display_map);
let start = selection.start.to_display_point(&display_map, Bias::Left);
let end = selection.end.to_display_point(&display_map, Bias::Left);
if start != end {
selection.goal = SelectionGoal::None;
}
@ -1393,7 +1397,7 @@ impl Editor {
let app = cx.as_ref();
let buffer = self.buffer.read(app);
for selection in &mut selections {
let head = selection.head().to_display_point(&display_map);
let head = selection.head().to_display_point(&display_map, Bias::Left);
let (head, goal) = movement::up(&display_map, head, selection.goal).unwrap();
selection.set_head(&buffer, display_map.anchor_before(head, Bias::Left));
selection.goal = goal;
@ -1410,8 +1414,8 @@ impl Editor {
let mut selections = self.selections(cx.as_ref()).to_vec();
{
for selection in &mut selections {
let start = selection.start.to_display_point(&display_map);
let end = selection.end.to_display_point(&display_map);
let start = selection.start.to_display_point(&display_map, Bias::Left);
let end = selection.end.to_display_point(&display_map, Bias::Left);
if start != end {
selection.goal = SelectionGoal::None;
}
@ -1435,7 +1439,7 @@ impl Editor {
let app = cx.as_ref();
let buffer = self.buffer.read(app);
for selection in &mut selections {
let head = selection.head().to_display_point(&display_map);
let head = selection.head().to_display_point(&display_map, Bias::Left);
let (head, goal) = movement::down(&display_map, head, selection.goal).unwrap();
selection.set_head(&buffer, display_map.anchor_before(head, Bias::Right));
selection.goal = goal;
@ -1449,7 +1453,7 @@ impl Editor {
let mut selections = self.selections(cx).to_vec();
{
for selection in &mut selections {
let head = selection.head().to_display_point(&display_map);
let head = selection.head().to_display_point(&display_map, Bias::Left);
let new_head = movement::prev_word_boundary(&display_map, head).unwrap();
let anchor = display_map.anchor_before(new_head, Bias::Left);
selection.start = anchor.clone();
@ -1467,7 +1471,7 @@ impl Editor {
{
let buffer = self.buffer.read(cx);
for selection in &mut selections {
let head = selection.head().to_display_point(&display_map);
let head = selection.head().to_display_point(&display_map, Bias::Left);
let new_head = movement::prev_word_boundary(&display_map, head).unwrap();
let anchor = display_map.anchor_before(new_head, Bias::Left);
selection.set_head(buffer, anchor);
@ -1489,7 +1493,7 @@ impl Editor {
let mut selections = self.selections(cx).to_vec();
{
for selection in &mut selections {
let head = selection.head().to_display_point(&display_map);
let head = selection.head().to_display_point(&display_map, Bias::Left);
let new_head = movement::next_word_boundary(&display_map, head).unwrap();
let anchor = display_map.anchor_before(new_head, Bias::Left);
selection.start = anchor.clone();
@ -1507,7 +1511,7 @@ impl Editor {
{
let buffer = self.buffer.read(cx);
for selection in &mut selections {
let head = selection.head().to_display_point(&display_map);
let head = selection.head().to_display_point(&display_map, Bias::Left);
let new_head = movement::next_word_boundary(&display_map, head).unwrap();
let anchor = display_map.anchor_before(new_head, Bias::Left);
selection.set_head(buffer, anchor);
@ -1529,7 +1533,7 @@ impl Editor {
let mut selections = self.selections(cx).to_vec();
{
for selection in &mut selections {
let head = selection.head().to_display_point(&display_map);
let head = selection.head().to_display_point(&display_map, Bias::Left);
let new_head = movement::line_beginning(&display_map, head, true).unwrap();
let anchor = display_map.anchor_before(new_head, Bias::Left);
selection.start = anchor.clone();
@ -1551,7 +1555,7 @@ impl Editor {
{
let buffer = self.buffer.read(cx);
for selection in &mut selections {
let head = selection.head().to_display_point(&display_map);
let head = selection.head().to_display_point(&display_map, Bias::Left);
let new_head =
movement::line_beginning(&display_map, head, *toggle_indent).unwrap();
let anchor = display_map.anchor_before(new_head, Bias::Left);
@ -1574,7 +1578,7 @@ impl Editor {
let mut selections = self.selections(cx).to_vec();
{
for selection in &mut selections {
let head = selection.head().to_display_point(&display_map);
let head = selection.head().to_display_point(&display_map, Bias::Left);
let new_head = movement::line_end(&display_map, head).unwrap();
let anchor = display_map.anchor_before(new_head, Bias::Left);
selection.start = anchor.clone();
@ -1592,7 +1596,7 @@ impl Editor {
{
let buffer = self.buffer.read(cx);
for selection in &mut selections {
let head = selection.head().to_display_point(&display_map);
let head = selection.head().to_display_point(&display_map, Bias::Left);
let new_head = movement::line_end(&display_map, head).unwrap();
let anchor = display_map.anchor_before(new_head, Bias::Left);
selection.set_head(buffer, anchor);
@ -2480,7 +2484,9 @@ fn compute_scroll_position(
mut scroll_position: Vector2F,
scroll_top_anchor: &Anchor,
) -> Vector2F {
let scroll_top = scroll_top_anchor.to_display_point(snapshot).row() as f32;
let scroll_top = scroll_top_anchor
.to_display_point(snapshot, Bias::Left)
.row() as f32;
scroll_position.set_y(scroll_top + scroll_position.y());
scroll_position
}

View File

@ -80,8 +80,8 @@ impl Selection {
}
pub fn display_range(&self, map: &DisplayMapSnapshot) -> Range<DisplayPoint> {
let start = self.start.to_display_point(map);
let end = self.end.to_display_point(map);
let start = self.start.to_display_point(map, Bias::Left);
let end = self.end.to_display_point(map, Bias::Left);
if self.reversed {
end..start
} else {
@ -94,11 +94,11 @@ impl Selection {
include_end_if_at_line_start: bool,
map: &DisplayMapSnapshot,
) -> (Range<u32>, Range<u32>) {
let display_start = self.start.to_display_point(map);
let display_start = self.start.to_display_point(map, Bias::Left);
let buffer_start =
DisplayPoint::new(display_start.row(), 0).to_buffer_point(map, Bias::Left);
let mut display_end = self.end.to_display_point(map);
let mut display_end = self.end.to_display_point(map, Bias::Right);
if !include_end_if_at_line_start
&& display_end.row() != map.max_point().row()
&& display_start.row() != display_end.row()

View File

@ -117,24 +117,25 @@ impl DisplayMapSnapshot {
let mut point = display_point.to_buffer_point(self, Bias::Left);
while point.column != 0 {
point.column = 0;
display_point = point.to_display_point(self);
display_point = point.to_display_point(self, Bias::Left);
if display_point.column() != 0 {
*display_point.column_mut() = 0;
point = display_point.to_buffer_point(self, Bias::Left);
}
point = display_point.to_buffer_point(self, Bias::Left);
}
(display_point, point)
}
pub fn next_row_boundary(&self, mut display_point: DisplayPoint) -> (DisplayPoint, Point) {
let max_point = self.max_point();
*display_point.row_mut() += 1;
*display_point.column_mut() = 0;
let mut point = display_point.to_buffer_point(self, Bias::Right);
while point.column != 0 {
while point.column != 0 && display_point <= max_point {
point.column = 0;
point.row += 1;
display_point = point.to_display_point(self);
display_point = point.to_display_point(self, Bias::Right);
if display_point.column() != 0 {
*display_point.row_mut() += 1;
*display_point.column_mut() = 0;
@ -142,7 +143,7 @@ impl DisplayMapSnapshot {
}
}
(display_point, point)
(display_point.min(max_point), point)
}
pub fn max_point(&self) -> DisplayPoint {
@ -307,8 +308,8 @@ impl DisplayPoint {
}
impl Point {
pub fn to_display_point(self, map: &DisplayMapSnapshot) -> DisplayPoint {
let fold_point = self.to_fold_point(&map.folds_snapshot);
pub fn to_display_point(self, map: &DisplayMapSnapshot, bias: Bias) -> DisplayPoint {
let fold_point = self.to_fold_point(&map.folds_snapshot, bias);
let tab_point = map.tabs_snapshot.to_tab_point(fold_point);
let wrap_point = map.wraps_snapshot.to_wrap_point(tab_point);
DisplayPoint(wrap_point)
@ -316,8 +317,9 @@ impl Point {
}
impl Anchor {
pub fn to_display_point(&self, map: &DisplayMapSnapshot) -> DisplayPoint {
self.to_point(&map.buffer_snapshot).to_display_point(map)
pub fn to_display_point(&self, map: &DisplayMapSnapshot, bias: Bias) -> DisplayPoint {
self.to_point(&map.buffer_snapshot)
.to_display_point(map, bias)
}
}
@ -435,13 +437,13 @@ mod tests {
}
assert_eq!(
prev_buffer_bound.to_display_point(&snapshot),
prev_buffer_bound.to_display_point(&snapshot, Left),
prev_display_bound,
"{:?} to display point",
prev_buffer_bound
);
assert_eq!(
next_buffer_bound.to_display_point(&snapshot),
next_buffer_bound.to_display_point(&snapshot, Left),
next_display_bound,
"{:?} to display point",
next_buffer_bound
@ -787,40 +789,40 @@ mod tests {
let point = Point::new(0, "\t\t".len() as u32);
let display_point = DisplayPoint::new(0, "".len() as u32);
assert_eq!(point.to_display_point(&map), display_point);
assert_eq!(display_point.to_buffer_point(&map, Bias::Left), point,);
assert_eq!(point.to_display_point(&map, Left), display_point);
assert_eq!(display_point.to_buffer_point(&map, Left), point,);
let point = Point::new(1, "β\t".len() as u32);
let display_point = DisplayPoint::new(1, "β ".len() as u32);
assert_eq!(point.to_display_point(&map), display_point);
assert_eq!(display_point.to_buffer_point(&map, Bias::Left), point,);
assert_eq!(point.to_display_point(&map, Left), display_point);
assert_eq!(display_point.to_buffer_point(&map, Left), point,);
let point = Point::new(2, "🏀β\t\t".len() as u32);
let display_point = DisplayPoint::new(2, "🏀β ".len() as u32);
assert_eq!(point.to_display_point(&map), display_point);
assert_eq!(display_point.to_buffer_point(&map, Bias::Left), point,);
assert_eq!(point.to_display_point(&map, Left), display_point);
assert_eq!(display_point.to_buffer_point(&map, Left), point,);
// Display points inside of expanded tabs
assert_eq!(
DisplayPoint::new(0, "".len() as u32).to_buffer_point(&map, Bias::Right),
DisplayPoint::new(0, "".len() as u32).to_buffer_point(&map, Right),
Point::new(0, "\t\t".len() as u32),
);
assert_eq!(
DisplayPoint::new(0, "".len() as u32).to_buffer_point(&map, Bias::Left),
DisplayPoint::new(0, "".len() as u32).to_buffer_point(&map, Left),
Point::new(0, "\t".len() as u32),
);
assert_eq!(
DisplayPoint::new(0, "".len() as u32).to_buffer_point(&map, Bias::Right),
DisplayPoint::new(0, "".len() as u32).to_buffer_point(&map, Right),
Point::new(0, "\t".len() as u32),
);
assert_eq!(
DisplayPoint::new(0, "".len() as u32).to_buffer_point(&map, Bias::Left),
DisplayPoint::new(0, "".len() as u32).to_buffer_point(&map, Left),
Point::new(0, "".len() as u32),
);
// Clipping display points inside of multi-byte characters
assert_eq!(
map.clip_point(DisplayPoint::new(0, "".len() as u32 - 1), Bias::Left),
map.clip_point(DisplayPoint::new(0, "".len() as u32 - 1), Left),
DisplayPoint::new(0, 0)
);
assert_eq!(

View File

@ -77,14 +77,21 @@ impl FoldPoint {
}
impl Point {
pub fn to_fold_point(&self, snapshot: &Snapshot) -> FoldPoint {
pub fn to_fold_point(&self, snapshot: &Snapshot, bias: Bias) -> FoldPoint {
let mut cursor = snapshot.transforms.cursor::<Point, FoldPoint>();
cursor.seek(self, Bias::Right, &());
let overshoot = *self - cursor.seek_start();
FoldPoint(cmp::min(
cursor.sum_start().0 + overshoot,
cursor.sum_end(&()).0,
))
if cursor.item().map_or(false, |t| t.is_fold()) {
match bias {
Bias::Left => *cursor.sum_start(),
Bias::Right => cursor.sum_end(&()),
}
} else {
let overshoot = *self - cursor.seek_start();
FoldPoint(cmp::min(
cursor.sum_start().0 + overshoot,
cursor.sum_end(&()).0,
))
}
}
}
@ -1365,7 +1372,7 @@ mod tests {
let buffer_point = fold_point.to_buffer_point(&snapshot);
let buffer_offset = buffer_point.to_offset(&buffer);
assert_eq!(
buffer_point.to_fold_point(&snapshot),
buffer_point.to_fold_point(&snapshot, Right),
fold_point,
"buffer_Point.to_fold_point({:?})",
buffer_point,
@ -1413,7 +1420,9 @@ mod tests {
}
for (idx, buffer_row) in expected_buffer_rows.iter().enumerate() {
let fold_row = Point::new(*buffer_row, 0).to_fold_point(&snapshot).row();
let fold_row = Point::new(*buffer_row, 0)
.to_fold_point(&snapshot, Right)
.row();
assert_eq!(
snapshot.buffer_rows(fold_row).collect::<Vec<_>>(),
expected_buffer_rows[idx..],
@ -1421,7 +1430,10 @@ mod tests {
}
for fold_range in map.merged_fold_ranges(cx.as_ref()) {
let fold_point = fold_range.start.to_point(&buffer).to_fold_point(&snapshot);
let fold_point = fold_range
.start
.to_point(&buffer)
.to_fold_point(&snapshot, Right);
assert!(snapshot.is_line_folded(fold_point.row()));
}