diff --git a/crates/editor/src/editor_tests.rs b/crates/editor/src/editor_tests.rs index 10fb420017bc23..8049ba14b07ff1 100644 --- a/crates/editor/src/editor_tests.rs +++ b/crates/editor/src/editor_tests.rs @@ -4234,6 +4234,53 @@ fn test_newline_respects_read_only(cx: &mut TestAppContext) { }); } +#[gpui::test] +async fn test_newline_below_with_cursor_on_deleted_hunk(cx: &mut TestAppContext) { + init_test(cx, |_| {}); + let mut cx = EditorTestContext::new(cx).await; + + cx.set_state("aaa\nbbb\ncˇcc"); + cx.set_head_text("aaa\nXXX\nbbb\nccc"); + cx.run_until_parked(); + cx.update_editor(|editor, window, cx| { + editor.expand_all_diff_hunks(&Default::default(), window, cx); + }); + cx.run_until_parked(); + + cx.update_editor(|editor, window, cx| { + editor.change_selections(Default::default(), window, cx, |s| { + s.select_display_ranges([ + DisplayPoint::new(DisplayRow(1), 0)..DisplayPoint::new(DisplayRow(1), 0), + DisplayPoint::new(DisplayRow(3), 3)..DisplayPoint::new(DisplayRow(3), 3), + ]); + }); + }); + + cx.update_editor(|editor, window, cx| { + editor.newline_below(&NewlineBelow, window, cx); + }); + cx.run_until_parked(); + + assert_eq!(cx.buffer(|buffer, _| buffer.text()), "aaa\nbbb\nccc\n"); + + let cursors = cx.update_editor(|editor, window, cx| { + let display_snapshot = editor.snapshot(window, cx).display_snapshot; + editor + .selections + .all_display(&display_snapshot) + .iter() + .map(|selection| selection.head()) + .collect::>() + }); + assert_eq!( + cursors, + vec![ + DisplayPoint::new(DisplayRow(1), 0), + DisplayPoint::new(DisplayRow(4), 0), + ], + ); +} + #[gpui::test] fn test_newline_below_multibuffer(cx: &mut TestAppContext) { init_test(cx, |_| {}); diff --git a/crates/editor/src/input.rs b/crates/editor/src/input.rs index a894093c45afc4..164138a4d9a77d 100644 --- a/crates/editor/src/input.rs +++ b/crates/editor/src/input.rs @@ -841,7 +841,7 @@ impl Editor { } let mut buffer_edits: HashMap, Vec)> = HashMap::default(); - let mut rows = Vec::new(); + let mut rows: Vec> = Vec::new(); let mut rows_inserted = 0; for selection in self.selections.all_adjusted(&self.display_snapshot(cx)) { @@ -852,6 +852,7 @@ impl Editor { let Some((buffer_handle, buffer_point)) = self.buffer.read(cx).point_to_buffer_point(point, cx) else { + rows.push(None); continue; }; @@ -862,7 +863,7 @@ impl Editor { .push(buffer_point); rows_inserted += 1; - rows.push(row + rows_inserted); + rows.push(Some(row + rows_inserted)); } self.transact(window, cx, |editor, window, cx| { @@ -882,21 +883,21 @@ impl Editor { editor.change_selections(Default::default(), window, cx, |s| { let mut index = 0; - s.move_cursors_with(&mut |map, _, _| { - let row = rows[index]; + s.maybe_move_cursors_with(&mut |map, _, _| { + let row = rows.get(index).copied().flatten(); index += 1; - let point = Point::new(row, 0); + let point = Point::new(row?, 0); let boundary = map.next_line_boundary(point).1; let clipped = map.clip_point(boundary, Bias::Left); - (clipped, SelectionGoal::None) + Some((clipped, SelectionGoal::None)) }); }); let mut indent_edits = Vec::new(); let multibuffer_snapshot = editor.buffer.read(cx).snapshot(cx); - for row in rows { + for row in rows.into_iter().flatten() { let indents = multibuffer_snapshot.suggested_indents(row..row + 1, cx); for (row, indent) in indents { if indent.len == 0 {