Maintain search results as query and active editor changes
Co-Authored-By: Nathan Sobo <nathan@zed.dev>
This commit is contained in:
parent
860e37d50f
commit
5c862bfe98
4 changed files with 69 additions and 8 deletions
1
Cargo.lock
generated
1
Cargo.lock
generated
|
@ -1724,6 +1724,7 @@ name = "find"
|
|||
version = "0.1.0"
|
||||
dependencies = [
|
||||
"aho-corasick",
|
||||
"collections",
|
||||
"editor",
|
||||
"gpui",
|
||||
"postage",
|
||||
|
|
|
@ -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" }
|
||||
|
|
|
@ -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<Settings>,
|
||||
query_editor: ViewHandle<Editor>,
|
||||
active_editor: Option<ViewHandle<Editor>>,
|
||||
active_editor_subscription: Option<Subscription>,
|
||||
highlighted_editors: HashSet<WeakViewHandle<Editor>>,
|
||||
pending_search: Option<Task<()>>,
|
||||
case_sensitive_mode: bool,
|
||||
whole_word_mode: bool,
|
||||
|
@ -85,8 +88,19 @@ impl Toolbar for FindBar {
|
|||
item: Option<Box<dyn ItemViewHandle>>,
|
||||
cx: &mut ViewContext<Self>,
|
||||
) -> bool {
|
||||
self.active_editor = item.and_then(|item| item.act_as::<Editor>(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::<Editor>(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<Self>) {
|
||||
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>,
|
||||
_: &editor::Event,
|
||||
event: &editor::Event,
|
||||
cx: &mut ViewContext<Self>,
|
||||
) {
|
||||
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::<Self>(cx)
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
self.update_matches(cx);
|
||||
}
|
||||
_ => {}
|
||||
}
|
||||
}
|
||||
|
||||
fn on_active_editor_event(
|
||||
&mut self,
|
||||
_: ViewHandle<Editor>,
|
||||
event: &editor::Event,
|
||||
cx: &mut ViewContext<Self>,
|
||||
) {
|
||||
match event {
|
||||
editor::Event::Edited => self.update_matches(cx),
|
||||
_ => {}
|
||||
}
|
||||
}
|
||||
|
||||
fn update_matches(&mut self, cx: &mut ViewContext<Self>) {
|
||||
|
@ -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::<Self>(ranges, theme.match_background, cx)
|
||||
});
|
||||
|
|
|
@ -3246,6 +3246,7 @@ impl Drop for AnyModelHandle {
|
|||
self.ref_counts.lock().dec_model(self.model_id);
|
||||
}
|
||||
}
|
||||
|
||||
pub struct WeakViewHandle<T> {
|
||||
window_id: usize,
|
||||
view_id: usize,
|
||||
|
@ -3288,6 +3289,21 @@ impl<T> Clone for WeakViewHandle<T> {
|
|||
}
|
||||
}
|
||||
|
||||
impl<T> PartialEq for WeakViewHandle<T> {
|
||||
fn eq(&self, other: &Self) -> bool {
|
||||
self.window_id == other.window_id && self.view_id == other.view_id
|
||||
}
|
||||
}
|
||||
|
||||
impl<T> Eq for WeakViewHandle<T> {}
|
||||
|
||||
impl<T> Hash for WeakViewHandle<T> {
|
||||
fn hash<H: Hasher>(&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);
|
||||
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue