@@ -3,7 +3,7 @@ mod fold_map;
mod tab_map;
mod wrap_map;
-use crate::{Anchor, MultiBuffer, MultiBufferSnapshot, ToOffset, ToPoint};
+use crate::{Anchor, AnchorRangeExt, MultiBuffer, MultiBufferSnapshot, ToOffset, ToPoint};
use block_map::{BlockMap, BlockPoint};
use collections::{HashMap, HashSet};
use fold_map::FoldMap;
@@ -97,6 +97,15 @@ impl DisplayMap {
}
}
+ pub fn set_state(&mut self, other: &DisplaySnapshot, cx: &mut ModelContext<Self>) {
+ self.fold(
+ other
+ .folds_in_range(0..other.buffer_snapshot.len())
+ .map(|fold| fold.to_offset(&other.buffer_snapshot)),
+ cx,
+ );
+ }
+
pub fn fold<T: ToOffset>(
&mut self,
ranges: impl IntoIterator<Item = Range<T>>,
@@ -892,14 +892,7 @@ 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,
- None,
- cx,
- )
+ Self::new(EditorMode::SingleLine, buffer, None, field_editor_style, cx)
}
pub fn auto_height(
@@ -914,7 +907,6 @@ impl Editor {
buffer,
None,
field_editor_style,
- None,
cx,
)
}
@@ -925,7 +917,7 @@ impl Editor {
cx: &mut ViewContext<Self>,
) -> Self {
let buffer = cx.add_model(|cx| MultiBuffer::singleton(buffer, cx));
- Self::new(EditorMode::Full, buffer, project, None, None, cx)
+ Self::new(EditorMode::Full, buffer, project, None, cx)
}
pub fn for_multibuffer(
@@ -933,7 +925,7 @@ impl Editor {
project: Option<ModelHandle<Project>>,
cx: &mut ViewContext<Self>,
) -> Self {
- Self::new(EditorMode::Full, buffer, project, None, None, cx)
+ Self::new(EditorMode::Full, buffer, project, None, cx)
}
pub fn clone(&self, cx: &mut ViewContext<Self>) -> Self {
@@ -942,9 +934,15 @@ impl Editor {
self.buffer.clone(),
self.project.clone(),
self.get_field_editor_theme,
- Some(self.selections.clone()),
cx,
);
+ self.display_map.update(cx, |display_map, cx| {
+ let snapshot = display_map.snapshot(cx);
+ clone.display_map.update(cx, |display_map, cx| {
+ display_map.set_state(&snapshot, cx);
+ });
+ });
+ clone.selections.set_state(&self.selections);
clone.scroll_position = self.scroll_position;
clone.scroll_top_anchor = self.scroll_top_anchor.clone();
clone.searchable = self.searchable;
@@ -956,7 +954,6 @@ impl Editor {
buffer: ModelHandle<MultiBuffer>,
project: Option<ModelHandle<Project>>,
get_field_editor_theme: Option<GetFieldEditorTheme>,
- selections: Option<SelectionsCollection>,
cx: &mut ViewContext<Self>,
) -> Self {
let display_map = cx.add_model(|cx| {
@@ -977,8 +974,7 @@ impl Editor {
cx.observe(&display_map, Self::on_display_map_changed)
.detach();
- let selections = selections
- .unwrap_or_else(|| SelectionsCollection::new(display_map.clone(), buffer.clone()));
+ let selections = SelectionsCollection::new(display_map.clone(), buffer.clone());
let mut this = Self {
handle: cx.weak_handle(),
@@ -6468,23 +6464,55 @@ mod tests {
}
#[gpui::test]
- fn test_clone_with_selections(cx: &mut gpui::MutableAppContext) {
+ fn test_clone(cx: &mut gpui::MutableAppContext) {
let (text, selection_ranges) = marked_text_ranges(indoc! {"
- The qu[ick brown
- fox jum]ps over
- the lazy dog
+ one
+ two
+ three[]
+ four
+ five[]
"});
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 (_, editor) = cx.add_window(Default::default(), |cx| build_editor(buffer, cx));
+
+ editor.update(cx, |editor, cx| {
+ editor.change_selections(None, cx, |s| s.select_ranges(selection_ranges.clone()));
+ editor.fold_ranges(
+ [
+ Point::new(1, 0)..Point::new(2, 0),
+ Point::new(3, 0)..Point::new(4, 0),
+ ],
+ cx,
+ );
+ });
- let cloned_editor = view.update(cx, |view, cx| {
- view.change_selections(None, cx, |s| s.select_ranges(selection_ranges.clone()));
- view.clone(cx)
+ let (_, cloned_editor) = editor.update(cx, |editor, cx| {
+ cx.add_window(Default::default(), |cx| editor.clone(cx))
});
- assert_set_eq!(cloned_editor.selections.ranges(cx), selection_ranges);
+ let snapshot = editor.update(cx, |e, cx| e.snapshot(cx));
+ let cloned_snapshot = cloned_editor.update(cx, |e, cx| e.snapshot(cx));
+
+ assert_eq!(
+ cloned_editor.update(cx, |e, cx| e.display_text(cx)),
+ editor.update(cx, |e, cx| e.display_text(cx))
+ );
+ assert_eq!(
+ cloned_snapshot
+ .folds_in_range(0..text.len())
+ .collect::<Vec<_>>(),
+ snapshot.folds_in_range(0..text.len()).collect::<Vec<_>>(),
+ );
+ assert_set_eq!(
+ cloned_editor.read(cx).selections.ranges::<Point>(cx),
+ editor.read(cx).selections.ranges(cx)
+ );
+ assert_set_eq!(
+ cloned_editor.update(cx, |e, cx| dbg!(e.selections.display_ranges(cx))),
+ editor.update(cx, |e, cx| dbg!(e.selections.display_ranges(cx)))
+ );
}
#[gpui::test]
@@ -1444,7 +1444,7 @@ impl Element for EditorElement {
{
return false;
}
-
+
let point = if paint.text_bounds.contains_point(*position) {
let (point, overshoot) =
paint.point_for_position(&self.snapshot(cx), layout, *position);
@@ -1791,7 +1791,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, None, cx)
+ Editor::new(EditorMode::Full, buffer, None, None, cx)
});
let element = EditorElement::new(
editor.downgrade(),
@@ -1813,7 +1813,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, None, cx)
+ Editor::new(EditorMode::Full, buffer, None, None, cx)
});
editor.update(cx, |editor, cx| {
@@ -77,7 +77,7 @@ pub(crate) fn build_editor(
buffer: ModelHandle<MultiBuffer>,
cx: &mut ViewContext<Editor>,
) -> Editor {
- Editor::new(EditorMode::Full, buffer, None, None, None, cx)
+ Editor::new(EditorMode::Full, buffer, None, None, cx)
}
pub struct EditorTestContext<'a> {
@@ -428,7 +428,7 @@ impl<'a> EditorLspTestContext<'a> {
let (window_id, editor) = cx.add_window(Default::default(), |cx| {
let buffer = cx.add_model(|cx| MultiBuffer::singleton(buffer, cx));
- Editor::new(EditorMode::Full, buffer, Some(project), None, None, cx)
+ Editor::new(EditorMode::Full, buffer, Some(project), None, cx)
});
editor.update(cx, |_, cx| cx.focus_self());