diff --git a/crates/editor/src/multi_buffer.rs b/crates/editor/src/multi_buffer.rs index 42f4d72f52..c5d38bed6a 100644 --- a/crates/editor/src/multi_buffer.rs +++ b/crates/editor/src/multi_buffer.rs @@ -43,6 +43,7 @@ pub struct MultiBuffer { title: Option, } +#[derive(Clone)] struct History { next_transaction_id: TransactionId, undo_stack: Vec, @@ -168,6 +169,37 @@ impl MultiBuffer { } } + pub fn clone(&self, new_cx: &mut ModelContext) -> Self { + let mut buffers = HashMap::default(); + for (buffer_id, buffer_state) in self.buffers.borrow().iter() { + buffers.insert( + *buffer_id, + BufferState { + buffer: buffer_state.buffer.clone(), + last_version: buffer_state.last_version.clone(), + last_parse_count: buffer_state.last_parse_count, + last_selections_update_count: buffer_state.last_selections_update_count, + last_diagnostics_update_count: buffer_state.last_diagnostics_update_count, + last_file_update_count: buffer_state.last_file_update_count, + excerpts: buffer_state.excerpts.clone(), + _subscriptions: [ + new_cx.observe(&buffer_state.buffer, |_, _, cx| cx.notify()), + new_cx.subscribe(&buffer_state.buffer, Self::on_buffer_event), + ], + }, + ); + } + Self { + snapshot: RefCell::new(self.snapshot.borrow().clone()), + buffers: RefCell::new(buffers), + subscriptions: Default::default(), + singleton: self.singleton, + replica_id: self.replica_id, + history: self.history.clone(), + title: self.title.clone(), + } + } + pub fn with_title(mut self, title: String) -> Self { self.title = Some(title); self diff --git a/crates/find/src/project_find.rs b/crates/find/src/project_find.rs index 7bd9ee2784..8c9c31ac12 100644 --- a/crates/find/src/project_find.rs +++ b/crates/find/src/project_find.rs @@ -34,7 +34,6 @@ pub fn init(cx: &mut MutableAppContext) { struct ProjectFind { project: ModelHandle, excerpts: ModelHandle, - query: Option, pending_search: Option>>, highlighted_ranges: Vec>, } @@ -60,17 +59,26 @@ impl ProjectFind { Self { project, excerpts: cx.add_model(|_| MultiBuffer::new(replica_id)), - query: Default::default(), pending_search: Default::default(), highlighted_ranges: Default::default(), } } + fn clone(&self, new_cx: &mut ModelContext) -> Self { + Self { + project: self.project.clone(), + excerpts: self + .excerpts + .update(new_cx, |excerpts, cx| cx.add_model(|cx| excerpts.clone(cx))), + pending_search: Default::default(), + highlighted_ranges: self.highlighted_ranges.clone(), + } + } + fn search(&mut self, query: SearchQuery, cx: &mut ModelContext) { let search = self .project .update(cx, |project, cx| project.search(query.clone(), cx)); - self.query = Some(query.clone()); self.highlighted_ranges.clear(); self.pending_search = Some(cx.spawn_weak(|this, mut cx| async move { let matches = search.await; @@ -270,19 +278,38 @@ impl ItemView for ProjectFindView { Self: Sized, { let query_editor = cx.add_view(|cx| { - Editor::single_line( + let query = self.query_editor.read(cx).text(cx); + let editor = Editor::single_line( self.settings.clone(), Some(|theme| theme.find.editor.input.clone()), cx, - ) + ); + editor + .buffer() + .update(cx, |buffer, cx| buffer.edit([0..0], query, cx)); + editor }); - let results_editor = self.results_editor.update(cx, |results_editor, cx| { - cx.add_view(|cx| results_editor.clone(nav_history, cx)) - }); - cx.observe(&self.model, |this, _, cx| this.model_changed(true, cx)) + let model = self + .model + .update(cx, |model, cx| cx.add_model(|cx| model.clone(cx))); + + cx.observe(&model, |this, _, cx| this.model_changed(true, cx)) .detach(); + let results_editor = cx.add_view(|cx| { + let model = model.read(cx); + let excerpts = model.excerpts.clone(); + let project = model.project.clone(); + let scroll_position = self + .results_editor + .update(cx, |editor, cx| editor.scroll_position(cx)); + + let mut editor = Editor::for_buffer(excerpts, Some(project), self.settings.clone(), cx); + editor.set_nav_history(Some(nav_history)); + editor.set_scroll_position(scroll_position, cx); + editor + }); let mut view = Self { - model: self.model.clone(), + model, query_editor, results_editor, case_sensitive: self.case_sensitive, @@ -349,22 +376,7 @@ impl ProjectFindView { } fn model_changed(&mut self, reset_selections: bool, cx: &mut ViewContext) { - let model = self.model.read(cx); - let highlighted_ranges = model.highlighted_ranges.clone(); - if let Some(query) = model.query.clone() { - self.case_sensitive = query.case_sensitive(); - self.whole_word = query.whole_word(); - self.regex = query.is_regex(); - self.query_editor.update(cx, |query_editor, cx| { - if query_editor.text(cx) != query.as_str() { - query_editor.buffer().update(cx, |query_buffer, cx| { - let len = query_buffer.read(cx).len(); - query_buffer.edit([0..len], query.as_str(), cx); - }); - } - }); - } - + let highlighted_ranges = self.model.read(cx).highlighted_ranges.clone(); if !highlighted_ranges.is_empty() { let theme = &self.settings.borrow().theme.find; self.results_editor.update(cx, |editor, cx| {