From 5c862bfe983d58db2530b7a3b5abf85df710554a Mon Sep 17 00:00:00 2001 From: Antonio Scandurra Date: Fri, 28 Jan 2022 15:19:58 +0100 Subject: [PATCH] Maintain search results as query and active editor changes Co-Authored-By: Nathan Sobo --- Cargo.lock | 1 + crates/find/Cargo.toml | 3 ++- crates/find/src/find.rs | 57 ++++++++++++++++++++++++++++++++++++----- crates/gpui/src/app.rs | 16 ++++++++++++ 4 files changed, 69 insertions(+), 8 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index a876093e525fd92928d76efb3de58dd3b19a2fb0..889b620198a3c3240f96c64480e9cc8cf28cc352 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -1724,6 +1724,7 @@ name = "find" version = "0.1.0" dependencies = [ "aho-corasick", + "collections", "editor", "gpui", "postage", diff --git a/crates/find/Cargo.toml b/crates/find/Cargo.toml index cba620f6880970aac825132396d49fcfb8c27f58..8efce7024ecf7156aa1c11ec9ec6d171a5b59c15 100644 --- a/crates/find/Cargo.toml +++ b/crates/find/Cargo.toml @@ -7,10 +7,11 @@ edition = "2021" path = "src/find.rs" [dependencies] -aho-corasick = "0.7" +collections = { path = "../collections" } editor = { path = "../editor" } gpui = { path = "../gpui" } theme = { path = "../theme" } workspace = { path = "../workspace" } +aho-corasick = "0.7" postage = { version = "0.4.1", features = ["futures-traits"] } smol = { version = "1.2" } diff --git a/crates/find/src/find.rs b/crates/find/src/find.rs index ee70eca204a0731797adbf3d9520bc1d91508d15..a144019f28c307e61f17bdff1e220a201d95d645 100644 --- a/crates/find/src/find.rs +++ b/crates/find/src/find.rs @@ -1,8 +1,9 @@ use aho_corasick::AhoCorasickBuilder; +use collections::HashSet; use editor::{char_kind, Editor, EditorSettings}; use gpui::{ - action, elements::*, keymap::Binding, Entity, MutableAppContext, RenderContext, Task, View, - ViewContext, ViewHandle, + action, elements::*, keymap::Binding, Entity, MutableAppContext, RenderContext, Subscription, + Task, View, ViewContext, ViewHandle, WeakViewHandle, }; use postage::watch; use smol::future::yield_now; @@ -34,6 +35,8 @@ struct FindBar { settings: watch::Receiver, query_editor: ViewHandle, active_editor: Option>, + active_editor_subscription: Option, + highlighted_editors: HashSet>, pending_search: Option>, case_sensitive_mode: bool, whole_word_mode: bool, @@ -85,8 +88,19 @@ impl Toolbar for FindBar { item: Option>, cx: &mut ViewContext, ) -> bool { - self.active_editor = item.and_then(|item| item.act_as::(cx)); - self.active_editor.is_some() + self.active_editor_subscription.take(); + self.active_editor.take(); + self.pending_search.take(); + + if let Some(editor) = item.and_then(|item| item.act_as::(cx)) { + self.active_editor_subscription = + Some(cx.subscribe(&editor, Self::on_active_editor_event)); + self.active_editor = Some(editor); + self.update_matches(cx); + true + } else { + false + } } } @@ -114,6 +128,8 @@ impl FindBar { Self { query_editor, active_editor: None, + active_editor_subscription: None, + highlighted_editors: Default::default(), case_sensitive_mode: false, whole_word_mode: false, regex_mode: false, @@ -171,23 +187,49 @@ impl FindBar { } fn toggle_mode(&mut self, ToggleMode(mode): &ToggleMode, cx: &mut ViewContext) { - eprintln!("TOGGLE MODE"); let value = match mode { SearchMode::WholeWord => &mut self.whole_word_mode, SearchMode::CaseSensitive => &mut self.case_sensitive_mode, SearchMode::Regex => &mut self.regex_mode, }; *value = !*value; + self.update_matches(cx); cx.notify(); } fn on_query_editor_event( &mut self, _: ViewHandle, - _: &editor::Event, + event: &editor::Event, cx: &mut ViewContext, ) { - self.update_matches(cx); + match event { + editor::Event::Edited => { + for editor in self.highlighted_editors.drain() { + if let Some(editor) = editor.upgrade(cx) { + if Some(&editor) != self.active_editor.as_ref() { + editor.update(cx, |editor, cx| { + editor.clear_highlighted_ranges::(cx) + }); + } + } + } + self.update_matches(cx); + } + _ => {} + } + } + + fn on_active_editor_event( + &mut self, + _: ViewHandle, + event: &editor::Event, + cx: &mut ViewContext, + ) { + match event { + editor::Event::Edited => self.update_matches(cx), + _ => {} + } } fn update_matches(&mut self, cx: &mut ViewContext) { @@ -247,6 +289,7 @@ impl FindBar { { this.update(&mut cx, |this, cx| { let theme = &this.settings.borrow().theme.find; + this.highlighted_editors.insert(editor.downgrade()); editor.update(cx, |editor, cx| { editor.highlight_ranges::(ranges, theme.match_background, cx) }); diff --git a/crates/gpui/src/app.rs b/crates/gpui/src/app.rs index 31efb4991ea73b1b83cc03fbdd6546acb4d126e2..3a2124de95e3a04e1e360dda59fe3e37c62b253d 100644 --- a/crates/gpui/src/app.rs +++ b/crates/gpui/src/app.rs @@ -3246,6 +3246,7 @@ impl Drop for AnyModelHandle { self.ref_counts.lock().dec_model(self.model_id); } } + pub struct WeakViewHandle { window_id: usize, view_id: usize, @@ -3288,6 +3289,21 @@ impl Clone for WeakViewHandle { } } +impl PartialEq for WeakViewHandle { + fn eq(&self, other: &Self) -> bool { + self.window_id == other.window_id && self.view_id == other.view_id + } +} + +impl Eq for WeakViewHandle {} + +impl Hash for WeakViewHandle { + fn hash(&self, state: &mut H) { + self.window_id.hash(state); + self.view_id.hash(state); + } +} + #[derive(Clone, Copy, PartialEq, Eq, Hash)] pub struct ElementStateId(usize, usize);