@@ -617,6 +617,9 @@ fn left(map: &DisplaySnapshot, mut point: DisplayPoint, times: usize) -> Display
fn backspace(map: &DisplaySnapshot, mut point: DisplayPoint, times: usize) -> DisplayPoint {
for _ in 0..times {
point = movement::left(map, point);
+ if point.is_zero() {
+ break;
+ }
}
point
}
@@ -624,6 +627,9 @@ fn backspace(map: &DisplaySnapshot, mut point: DisplayPoint, times: usize) -> Di
fn space(map: &DisplaySnapshot, mut point: DisplayPoint, times: usize) -> DisplayPoint {
for _ in 0..times {
point = wrapping_right(map, point);
+ if point == map.max_point() {
+ break;
+ }
}
point
}
@@ -768,7 +774,7 @@ pub(crate) fn next_word_start(
let scope = map.buffer_snapshot.language_scope_at(point.to_point(map));
for _ in 0..times {
let mut crossed_newline = false;
- point = movement::find_boundary(map, point, FindRange::MultiLine, |left, right| {
+ let new_point = movement::find_boundary(map, point, FindRange::MultiLine, |left, right| {
let left_kind = coerce_punctuation(char_kind(&scope, left), ignore_punctuation);
let right_kind = coerce_punctuation(char_kind(&scope, right), ignore_punctuation);
let at_newline = right == '\n';
@@ -779,7 +785,11 @@ pub(crate) fn next_word_start(
crossed_newline |= at_newline;
found
- })
+ });
+ if point == new_point {
+ break;
+ }
+ point = new_point;
}
point
}
@@ -792,21 +802,30 @@ fn next_word_end(
) -> DisplayPoint {
let scope = map.buffer_snapshot.language_scope_at(point.to_point(map));
for _ in 0..times {
- if point.column() < map.line_len(point.row()) {
- *point.column_mut() += 1;
- } else if point.row() < map.max_buffer_row() {
- *point.row_mut() += 1;
- *point.column_mut() = 0;
+ let mut new_point = point;
+ if new_point.column() < map.line_len(new_point.row()) {
+ *new_point.column_mut() += 1;
+ } else if new_point.row() < map.max_buffer_row() {
+ *new_point.row_mut() += 1;
+ *new_point.column_mut() = 0;
}
- point =
- movement::find_boundary_exclusive(map, point, FindRange::MultiLine, |left, right| {
+ let new_point = movement::find_boundary_exclusive(
+ map,
+ new_point,
+ FindRange::MultiLine,
+ |left, right| {
let left_kind = coerce_punctuation(char_kind(&scope, left), ignore_punctuation);
let right_kind = coerce_punctuation(char_kind(&scope, right), ignore_punctuation);
left_kind != right_kind && left_kind != CharKind::Whitespace
- });
- point = map.clip_point(point, Bias::Left);
+ },
+ );
+ let new_point = map.clip_point(new_point, Bias::Left);
+ if point == new_point {
+ break;
+ }
+ point = new_point;
}
point
}
@@ -821,13 +840,17 @@ fn previous_word_start(
for _ in 0..times {
// This works even though find_preceding_boundary is called for every character in the line containing
// cursor because the newline is checked only once.
- point =
+ let new_point =
movement::find_preceding_boundary(map, point, FindRange::MultiLine, |left, right| {
let left_kind = coerce_punctuation(char_kind(&scope, left), ignore_punctuation);
let right_kind = coerce_punctuation(char_kind(&scope, right), ignore_punctuation);
(left_kind != right_kind && !right.is_whitespace()) || left == '\n'
});
+ if point == new_point {
+ break;
+ }
+ point = new_point;
}
point
}
@@ -967,10 +990,14 @@ fn find_forward(
for _ in 0..times {
found = false;
- to = find_boundary(map, to, FindRange::SingleLine, |_, right| {
+ let new_to = find_boundary(map, to, FindRange::SingleLine, |_, right| {
found = right == target;
found
});
+ if to == new_to {
+ break;
+ }
+ to = new_to;
}
if found {
@@ -995,7 +1022,12 @@ fn find_backward(
let mut to = from;
for _ in 0..times {
- to = find_preceding_boundary(map, to, FindRange::SingleLine, |_, right| right == target);
+ let new_to =
+ find_preceding_boundary(map, to, FindRange::SingleLine, |_, right| right == target);
+ if to == new_to {
+ break;
+ }
+ to = new_to;
}
if map.buffer_snapshot.chars_at(to.to_point(map)).next() == Some(target) {