From bacfed37b798a57936b5c9901925b62da824b622 Mon Sep 17 00:00:00 2001 From: Keith Simmons Date: Thu, 19 May 2022 11:22:53 -0700 Subject: [PATCH] Clone selections on editor split --- crates/editor/src/editor.rs | 46 +++++++++++++++++++--- crates/editor/src/element.rs | 4 +- crates/editor/src/selections_collection.rs | 1 + 3 files changed, 43 insertions(+), 8 deletions(-) diff --git a/crates/editor/src/editor.rs b/crates/editor/src/editor.rs index 9b160acf646737d63d6fa99eb2ab3aa1ffed41ae..c9e4732f9fcab55cbbf75b36ba04e9d796b994e3 100644 --- a/crates/editor/src/editor.rs +++ b/crates/editor/src/editor.rs @@ -862,7 +862,14 @@ impl Editor { ) -> Self { let buffer = cx.add_model(|cx| Buffer::new(0, String::new(), cx)); let buffer = cx.add_model(|cx| MultiBuffer::singleton(buffer, cx)); - Self::new(EditorMode::SingleLine, buffer, None, field_editor_style, cx) + Self::new( + EditorMode::SingleLine, + buffer, + None, + field_editor_style, + None, + cx, + ) } pub fn auto_height( @@ -877,6 +884,7 @@ impl Editor { buffer, None, field_editor_style, + None, cx, ) } @@ -887,7 +895,7 @@ impl Editor { cx: &mut ViewContext, ) -> Self { let buffer = cx.add_model(|cx| MultiBuffer::singleton(buffer, cx)); - Self::new(EditorMode::Full, buffer, project, None, cx) + Self::new(EditorMode::Full, buffer, project, None, None, cx) } pub fn for_multibuffer( @@ -895,7 +903,7 @@ impl Editor { project: Option>, cx: &mut ViewContext, ) -> Self { - Self::new(EditorMode::Full, buffer, project, None, cx) + Self::new(EditorMode::Full, buffer, project, None, None, cx) } pub fn clone(&self, cx: &mut ViewContext) -> Self { @@ -904,6 +912,7 @@ impl Editor { self.buffer.clone(), self.project.clone(), self.get_field_editor_theme, + Some(self.selections.clone()), cx, ); clone.scroll_position = self.scroll_position; @@ -917,6 +926,7 @@ impl Editor { buffer: ModelHandle, project: Option>, get_field_editor_theme: Option, + selections: Option, cx: &mut ViewContext, ) -> Self { let display_map = cx.add_model(|cx| { @@ -937,7 +947,8 @@ impl Editor { cx.observe(&display_map, Self::on_display_map_changed) .detach(); - let selections = SelectionsCollection::new(display_map.clone(), buffer.clone()); + let selections = selections + .unwrap_or_else(|| SelectionsCollection::new(display_map.clone(), buffer.clone())); let mut this = Self { handle: cx.weak_handle(), @@ -6025,7 +6036,10 @@ mod tests { use std::{cell::RefCell, rc::Rc, time::Instant}; use text::Point; use unindent::Unindent; - use util::test::{marked_text_by, marked_text_ranges, marked_text_ranges_by, sample_text}; + use util::{ + assert_set_eq, + test::{marked_text_by, marked_text_ranges, marked_text_ranges_by, sample_text}, + }; use workspace::{FollowableItem, ItemHandle}; #[gpui::test] @@ -6304,6 +6318,26 @@ mod tests { }); } + #[gpui::test] + fn test_clone_with_selections(cx: &mut gpui::MutableAppContext) { + let (text, selection_ranges) = marked_text_ranges(indoc! {" + The qu[ick brown + fox jum]ps over + the lazy dog + "}); + cx.set_global(Settings::test(cx)); + let buffer = MultiBuffer::build_simple(&text, cx); + + let (_, view) = cx.add_window(Default::default(), |cx| build_editor(buffer, cx)); + + let cloned_editor = view.update(cx, |view, cx| { + view.change_selections(None, cx, |s| s.select_ranges(selection_ranges.clone())); + view.clone(cx) + }); + + assert_set_eq!(cloned_editor.selections.ranges(cx), selection_ranges); + } + #[gpui::test] fn test_navigation_history(cx: &mut gpui::MutableAppContext) { cx.set_global(Settings::test(cx)); @@ -9765,7 +9799,7 @@ mod tests { } fn build_editor(buffer: ModelHandle, cx: &mut ViewContext) -> Editor { - Editor::new(EditorMode::Full, buffer, None, None, cx) + Editor::new(EditorMode::Full, buffer, None, None, None, cx) } fn assert_selection_ranges( diff --git a/crates/editor/src/element.rs b/crates/editor/src/element.rs index d3d67060f20f32c2c19e945d6d1cd7b99455a1f1..355d1f44337c9c855625ecc0255e51b57ee5db4b 100644 --- a/crates/editor/src/element.rs +++ b/crates/editor/src/element.rs @@ -1517,7 +1517,7 @@ mod tests { cx.set_global(Settings::test(cx)); let buffer = MultiBuffer::build_simple(&sample_text(6, 6, 'a'), cx); let (window_id, editor) = cx.add_window(Default::default(), |cx| { - Editor::new(EditorMode::Full, buffer, None, None, cx) + Editor::new(EditorMode::Full, buffer, None, None, None, cx) }); let element = EditorElement::new( editor.downgrade(), @@ -1539,7 +1539,7 @@ mod tests { cx.set_global(Settings::test(cx)); let buffer = MultiBuffer::build_simple("", cx); let (window_id, editor) = cx.add_window(Default::default(), |cx| { - Editor::new(EditorMode::Full, buffer, None, None, cx) + Editor::new(EditorMode::Full, buffer, None, None, None, cx) }); editor.update(cx, |editor, cx| { diff --git a/crates/editor/src/selections_collection.rs b/crates/editor/src/selections_collection.rs index aabfb676ff8be09aaa49352b2be17b2176570c0f..07fa2cd9b501d4e5964ddf776be12bc22a7bb87f 100644 --- a/crates/editor/src/selections_collection.rs +++ b/crates/editor/src/selections_collection.rs @@ -22,6 +22,7 @@ pub struct PendingSelection { pub mode: SelectMode, } +#[derive(Clone)] pub struct SelectionsCollection { display_map: ModelHandle, buffer: ModelHandle,