Fix panic when doing various cursor movements with a pending mouse selection (#13016)

This fixes a panic in the `SelectionsCollection::first_anchor` when
there was a pending mouse selection and no other selections. Until
recently, this method was only used in vim mode, but as of
https://github.com/zed-industries/zed/commit/53b0720d546b6541fbf236d2f9d2dadbce6f126e,
it's also used in the normal `move_up` and `move_down` actions.

So until recently, the panic that this fixes could only happen in vim
mode.

Release Notes:

- Fixed a crash that could happen when using certain cursor-motion
bindings with a pending mouse selection.
This commit is contained in:
Max Brunsfeld
2024-06-13 16:22:45 -07:00
committed by GitHub
parent 01ba1ddef7
commit 066cdc2297
2 changed files with 40 additions and 1 deletions
+36
View File
@@ -481,6 +481,42 @@ fn test_canceling_pending_selection(cx: &mut TestAppContext) {
});
}
#[gpui::test]
fn test_movement_actions_with_pending_selection(cx: &mut TestAppContext) {
init_test(cx, |_| {});
let view = cx.add_window(|cx| {
let buffer = MultiBuffer::build_simple("aaaaaa\nbbbbbb\ncccccc\ndddddd\n", cx);
build_editor(buffer, cx)
});
_ = view.update(cx, |view, cx| {
view.begin_selection(DisplayPoint::new(DisplayRow(2), 2), false, 1, cx);
assert_eq!(
view.selections.display_ranges(cx),
[DisplayPoint::new(DisplayRow(2), 2)..DisplayPoint::new(DisplayRow(2), 2)]
);
view.move_down(&Default::default(), cx);
assert_eq!(
view.selections.display_ranges(cx),
[DisplayPoint::new(DisplayRow(3), 2)..DisplayPoint::new(DisplayRow(3), 2)]
);
view.begin_selection(DisplayPoint::new(DisplayRow(2), 2), false, 1, cx);
assert_eq!(
view.selections.display_ranges(cx),
[DisplayPoint::new(DisplayRow(2), 2)..DisplayPoint::new(DisplayRow(2), 2)]
);
view.move_up(&Default::default(), cx);
assert_eq!(
view.selections.display_ranges(cx),
[DisplayPoint::new(DisplayRow(1), 2)..DisplayPoint::new(DisplayRow(1), 2)]
);
});
}
#[gpui::test]
fn test_clone(cx: &mut TestAppContext) {
init_test(cx, |_| {});
+4 -1
View File
@@ -256,7 +256,10 @@ impl SelectionsCollection {
}
pub fn first_anchor(&self) -> Selection<Anchor> {
self.disjoint[0].clone()
self.pending
.as_ref()
.map(|pending| pending.selection.clone())
.unwrap_or_else(|| self.disjoint.first().cloned().unwrap())
}
pub fn first<D: TextDimension + Ord + Sub<D, Output = D>>(