Detailed changes
@@ -251,6 +251,7 @@ gpui::actions!(
DisplayCursorNames,
DuplicateLineDown,
DuplicateLineUp,
+ DuplicateSelection,
ExpandAllHunkDiffs,
ExpandMacroRecursively,
FindAllReferences,
@@ -6119,6 +6119,28 @@ impl Editor {
});
}
+ pub fn duplicate_selection(&mut self, _: &DuplicateSelection, cx: &mut ViewContext<Self>) {
+ let display_map = self.display_map.update(cx, |map, cx| map.snapshot(cx));
+ let buffer = &display_map.buffer_snapshot;
+ let selections = self.selections.all::<Point>(cx);
+
+ let mut edits = Vec::new();
+ for selection in selections.iter() {
+ let start = selection.start;
+ let end = selection.end;
+ let text = buffer.text_for_range(start..end).collect::<String>();
+ edits.push((selection.end..selection.end, text));
+ }
+
+ self.transact(cx, |this, cx| {
+ this.buffer.update(cx, |buffer, cx| {
+ buffer.edit(edits, None, cx);
+ });
+
+ this.request_autoscroll(Autoscroll::fit(), cx);
+ });
+ }
+
pub fn duplicate_line(&mut self, upwards: bool, cx: &mut ViewContext<Self>) {
let display_map = self.display_map.update(cx, |map, cx| map.snapshot(cx));
let buffer = &display_map.buffer_snapshot;
@@ -3895,6 +3895,28 @@ fn test_duplicate_line(cx: &mut TestAppContext) {
]
);
});
+
+ let view = cx.add_window(|cx| {
+ let buffer = MultiBuffer::build_simple("abc\ndef\nghi\n", cx);
+ build_editor(buffer, cx)
+ });
+ _ = view.update(cx, |view, cx| {
+ view.change_selections(None, cx, |s| {
+ s.select_display_ranges([
+ DisplayPoint::new(DisplayRow(0), 1)..DisplayPoint::new(DisplayRow(1), 1),
+ DisplayPoint::new(DisplayRow(1), 2)..DisplayPoint::new(DisplayRow(2), 1),
+ ])
+ });
+ view.duplicate_selection(&DuplicateSelection, cx);
+ assert_eq!(view.display_text(cx), "abc\ndbc\ndef\ngf\nghi\n");
+ assert_eq!(
+ view.selections.display_ranges(cx),
+ vec![
+ DisplayPoint::new(DisplayRow(0), 1)..DisplayPoint::new(DisplayRow(1), 1),
+ DisplayPoint::new(DisplayRow(2), 2)..DisplayPoint::new(DisplayRow(3), 1),
+ ]
+ );
+ });
}
#[gpui::test]
@@ -218,6 +218,7 @@ impl EditorElement {
register_action(view, cx, Editor::cut_to_end_of_line);
register_action(view, cx, Editor::duplicate_line_up);
register_action(view, cx, Editor::duplicate_line_down);
+ register_action(view, cx, Editor::duplicate_selection);
register_action(view, cx, Editor::move_line_up);
register_action(view, cx, Editor::move_line_down);
register_action(view, cx, Editor::transpose);