@@ -4,6 +4,7 @@ use crate::{
FocusSearch, NextHistoryQuery, PreviousHistoryQuery, ReplaceAll, ReplaceNext, SearchOption,
SearchOptions, SearchSource, SelectAllMatches, SelectNextMatch, SelectPreviousMatch,
ToggleCaseSensitive, ToggleRegex, ToggleReplace, ToggleSelection, ToggleWholeWord,
+ buffer_search::registrar::WithResultsOrExternalQuery,
search_bar::{ActionButtonState, input_base_styles, render_action_button, render_text_input},
};
use any_vec::AnyVec;
@@ -43,7 +44,7 @@ use workspace::{
};
pub use registrar::DivRegistrar;
-use registrar::{ForDeployed, ForDismissed, SearchActionsRegistrar, WithResults};
+use registrar::{ForDeployed, ForDismissed, SearchActionsRegistrar};
const MAX_BUFFER_SEARCH_HISTORY_SIZE: usize = 50;
@@ -110,6 +111,8 @@ pub struct BufferSearchBar {
active_searchable_item_subscriptions: Option<[Subscription; 2]>,
#[cfg(not(target_os = "macos"))]
active_searchable_item_subscriptions: Option<Subscription>,
+ #[cfg(target_os = "macos")]
+ pending_external_query: Option<(String, SearchOptions)>,
active_search: Option<Arc<SearchQuery>>,
searchable_items_with_matches: HashMap<Box<dyn WeakSearchableItemHandle>, AnyVec<dyn Send>>,
pending_search: Option<Task<()>>,
@@ -510,24 +513,27 @@ impl ToolbarItemView for BufferSearchBar {
}
cx.defer_in(window, |this, window, cx| {
- if let Some(item) = cx.read_from_find_pasteboard()
- && let Some(text) = item.text()
- {
- if this.query(cx) != text {
- let search_options = item
- .metadata()
- .and_then(|m| m.parse().ok())
- .and_then(SearchOptions::from_bits)
- .unwrap_or(this.search_options);
-
- drop(this.search(
- &text,
- Some(search_options),
- true,
- window,
- cx,
- ));
- }
+ let Some(item) = cx.read_from_find_pasteboard() else {
+ return;
+ };
+ let Some(text) = item.text() else {
+ return;
+ };
+
+ if this.query(cx) == text {
+ return;
+ }
+
+ let search_options = item
+ .metadata()
+ .and_then(|m| m.parse().ok())
+ .and_then(SearchOptions::from_bits)
+ .unwrap_or(this.search_options);
+
+ if this.dismissed {
+ this.pending_external_query = Some((text, search_options));
+ } else {
+ drop(this.search(&text, Some(search_options), true, window, cx));
}
});
}),
@@ -594,14 +600,16 @@ impl BufferSearchBar {
cx.propagate();
}
}));
- registrar.register_handler(WithResults(|this, action: &SelectNextMatch, window, cx| {
- if this.supported_options(cx).find_in_results {
- cx.propagate();
- } else {
- this.select_next_match(action, window, cx);
- }
- }));
- registrar.register_handler(WithResults(
+ registrar.register_handler(WithResultsOrExternalQuery(
+ |this, action: &SelectNextMatch, window, cx| {
+ if this.supported_options(cx).find_in_results {
+ cx.propagate();
+ } else {
+ this.select_next_match(action, window, cx);
+ }
+ },
+ ));
+ registrar.register_handler(WithResultsOrExternalQuery(
|this, action: &SelectPreviousMatch, window, cx| {
if this.supported_options(cx).find_in_results {
cx.propagate();
@@ -610,7 +618,7 @@ impl BufferSearchBar {
}
},
));
- registrar.register_handler(WithResults(
+ registrar.register_handler(WithResultsOrExternalQuery(
|this, action: &SelectAllMatches, window, cx| {
if this.supported_options(cx).find_in_results {
cx.propagate();
@@ -707,6 +715,8 @@ impl BufferSearchBar {
replacement_editor_focused: false,
active_searchable_item: None,
active_searchable_item_subscriptions: None,
+ #[cfg(target_os = "macos")]
+ pending_external_query: None,
active_match_index: None,
searchable_items_with_matches: Default::default(),
default_options: search_options,
@@ -852,11 +862,20 @@ impl BufferSearchBar {
self.search(&suggestion, Some(self.default_options), true, window, cx)
});
+ #[cfg(target_os = "macos")]
+ let search = search.or_else(|| {
+ self.pending_external_query
+ .take()
+ .map(|(query, options)| self.search(&query, Some(options), true, window, cx))
+ });
+
if let Some(search) = search {
cx.spawn_in(window, async move |this, cx| {
if search.await.is_ok() {
this.update_in(cx, |this, window, cx| {
- this.activate_current_match(window, cx)
+ if !this.dismissed {
+ this.activate_current_match(window, cx)
+ }
})
} else {
Ok(())
@@ -1071,6 +1090,22 @@ impl BufferSearchBar {
window: &mut Window,
cx: &mut Context<Self>,
) {
+ #[cfg(target_os = "macos")]
+ if let Some((query, options)) = self.pending_external_query.take() {
+ let search_rx = self.search(&query, Some(options), true, window, cx);
+ cx.spawn_in(window, async move |this, cx| {
+ if search_rx.await.is_ok() {
+ this.update_in(cx, |this, window, cx| {
+ this.activate_current_match(window, cx);
+ })
+ .ok();
+ }
+ })
+ .detach();
+
+ return;
+ }
+
if let Some(index) = self.active_match_index
&& let Some(searchable_item) = self.active_searchable_item.as_ref()
&& let Some(matches) = self
@@ -1271,6 +1306,8 @@ impl BufferSearchBar {
let (done_tx, done_rx) = oneshot::channel();
let query = self.query(cx);
self.pending_search.take();
+ #[cfg(target_os = "macos")]
+ self.pending_external_query.take();
if let Some(active_searchable_item) = self.active_searchable_item.as_ref() {
self.query_error = None;
@@ -1367,8 +1404,8 @@ impl BufferSearchBar {
cx,
);
}
- let _ = done_tx.send(());
}
+ let _ = done_tx.send(());
cx.notify();
}
})