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"
|
version = "0.1.0"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"aho-corasick",
|
"aho-corasick",
|
||||||
|
"collections",
|
||||||
"editor",
|
"editor",
|
||||||
"gpui",
|
"gpui",
|
||||||
"postage",
|
"postage",
|
||||||
|
|
|
@ -7,10 +7,11 @@ edition = "2021"
|
||||||
path = "src/find.rs"
|
path = "src/find.rs"
|
||||||
|
|
||||||
[dependencies]
|
[dependencies]
|
||||||
aho-corasick = "0.7"
|
collections = { path = "../collections" }
|
||||||
editor = { path = "../editor" }
|
editor = { path = "../editor" }
|
||||||
gpui = { path = "../gpui" }
|
gpui = { path = "../gpui" }
|
||||||
theme = { path = "../theme" }
|
theme = { path = "../theme" }
|
||||||
workspace = { path = "../workspace" }
|
workspace = { path = "../workspace" }
|
||||||
|
aho-corasick = "0.7"
|
||||||
postage = { version = "0.4.1", features = ["futures-traits"] }
|
postage = { version = "0.4.1", features = ["futures-traits"] }
|
||||||
smol = { version = "1.2" }
|
smol = { version = "1.2" }
|
||||||
|
|
|
@ -1,8 +1,9 @@
|
||||||
use aho_corasick::AhoCorasickBuilder;
|
use aho_corasick::AhoCorasickBuilder;
|
||||||
|
use collections::HashSet;
|
||||||
use editor::{char_kind, Editor, EditorSettings};
|
use editor::{char_kind, Editor, EditorSettings};
|
||||||
use gpui::{
|
use gpui::{
|
||||||
action, elements::*, keymap::Binding, Entity, MutableAppContext, RenderContext, Task, View,
|
action, elements::*, keymap::Binding, Entity, MutableAppContext, RenderContext, Subscription,
|
||||||
ViewContext, ViewHandle,
|
Task, View, ViewContext, ViewHandle, WeakViewHandle,
|
||||||
};
|
};
|
||||||
use postage::watch;
|
use postage::watch;
|
||||||
use smol::future::yield_now;
|
use smol::future::yield_now;
|
||||||
|
@ -34,6 +35,8 @@ struct FindBar {
|
||||||
settings: watch::Receiver<Settings>,
|
settings: watch::Receiver<Settings>,
|
||||||
query_editor: ViewHandle<Editor>,
|
query_editor: ViewHandle<Editor>,
|
||||||
active_editor: Option<ViewHandle<Editor>>,
|
active_editor: Option<ViewHandle<Editor>>,
|
||||||
|
active_editor_subscription: Option<Subscription>,
|
||||||
|
highlighted_editors: HashSet<WeakViewHandle<Editor>>,
|
||||||
pending_search: Option<Task<()>>,
|
pending_search: Option<Task<()>>,
|
||||||
case_sensitive_mode: bool,
|
case_sensitive_mode: bool,
|
||||||
whole_word_mode: bool,
|
whole_word_mode: bool,
|
||||||
|
@ -85,8 +88,19 @@ impl Toolbar for FindBar {
|
||||||
item: Option<Box<dyn ItemViewHandle>>,
|
item: Option<Box<dyn ItemViewHandle>>,
|
||||||
cx: &mut ViewContext<Self>,
|
cx: &mut ViewContext<Self>,
|
||||||
) -> bool {
|
) -> bool {
|
||||||
self.active_editor = item.and_then(|item| item.act_as::<Editor>(cx));
|
self.active_editor_subscription.take();
|
||||||
self.active_editor.is_some()
|
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 {
|
Self {
|
||||||
query_editor,
|
query_editor,
|
||||||
active_editor: None,
|
active_editor: None,
|
||||||
|
active_editor_subscription: None,
|
||||||
|
highlighted_editors: Default::default(),
|
||||||
case_sensitive_mode: false,
|
case_sensitive_mode: false,
|
||||||
whole_word_mode: false,
|
whole_word_mode: false,
|
||||||
regex_mode: false,
|
regex_mode: false,
|
||||||
|
@ -171,24 +187,50 @@ impl FindBar {
|
||||||
}
|
}
|
||||||
|
|
||||||
fn toggle_mode(&mut self, ToggleMode(mode): &ToggleMode, cx: &mut ViewContext<Self>) {
|
fn toggle_mode(&mut self, ToggleMode(mode): &ToggleMode, cx: &mut ViewContext<Self>) {
|
||||||
eprintln!("TOGGLE MODE");
|
|
||||||
let value = match mode {
|
let value = match mode {
|
||||||
SearchMode::WholeWord => &mut self.whole_word_mode,
|
SearchMode::WholeWord => &mut self.whole_word_mode,
|
||||||
SearchMode::CaseSensitive => &mut self.case_sensitive_mode,
|
SearchMode::CaseSensitive => &mut self.case_sensitive_mode,
|
||||||
SearchMode::Regex => &mut self.regex_mode,
|
SearchMode::Regex => &mut self.regex_mode,
|
||||||
};
|
};
|
||||||
*value = !*value;
|
*value = !*value;
|
||||||
|
self.update_matches(cx);
|
||||||
cx.notify();
|
cx.notify();
|
||||||
}
|
}
|
||||||
|
|
||||||
fn on_query_editor_event(
|
fn on_query_editor_event(
|
||||||
&mut self,
|
&mut self,
|
||||||
_: ViewHandle<Editor>,
|
_: ViewHandle<Editor>,
|
||||||
_: &editor::Event,
|
event: &editor::Event,
|
||||||
cx: &mut ViewContext<Self>,
|
cx: &mut ViewContext<Self>,
|
||||||
) {
|
) {
|
||||||
|
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);
|
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>) {
|
fn update_matches(&mut self, cx: &mut ViewContext<Self>) {
|
||||||
let search = self.query_editor.read(cx).text(cx);
|
let search = self.query_editor.read(cx).text(cx);
|
||||||
|
@ -247,6 +289,7 @@ impl FindBar {
|
||||||
{
|
{
|
||||||
this.update(&mut cx, |this, cx| {
|
this.update(&mut cx, |this, cx| {
|
||||||
let theme = &this.settings.borrow().theme.find;
|
let theme = &this.settings.borrow().theme.find;
|
||||||
|
this.highlighted_editors.insert(editor.downgrade());
|
||||||
editor.update(cx, |editor, cx| {
|
editor.update(cx, |editor, cx| {
|
||||||
editor.highlight_ranges::<Self>(ranges, theme.match_background, 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);
|
self.ref_counts.lock().dec_model(self.model_id);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub struct WeakViewHandle<T> {
|
pub struct WeakViewHandle<T> {
|
||||||
window_id: usize,
|
window_id: usize,
|
||||||
view_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)]
|
#[derive(Clone, Copy, PartialEq, Eq, Hash)]
|
||||||
pub struct ElementStateId(usize, usize);
|
pub struct ElementStateId(usize, usize);
|
||||||
|
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue