Properly register workspace handlers for search elements (#4100)
This commit is contained in:
@@ -1148,7 +1148,7 @@ impl Render for AssistantPanel {
|
|||||||
|panel, cx| panel.toolbar.read(cx).item_of_type::<BufferSearchBar>(),
|
|panel, cx| panel.toolbar.read(cx).item_of_type::<BufferSearchBar>(),
|
||||||
cx,
|
cx,
|
||||||
);
|
);
|
||||||
BufferSearchBar::register_inner(&mut registrar);
|
BufferSearchBar::register(&mut registrar);
|
||||||
registrar.into_div()
|
registrar.into_div()
|
||||||
} else {
|
} else {
|
||||||
div()
|
div()
|
||||||
|
|||||||
@@ -429,6 +429,11 @@ pub trait SearchActionsRegistrar {
|
|||||||
&mut self,
|
&mut self,
|
||||||
callback: fn(&mut BufferSearchBar, &A, &mut ViewContext<BufferSearchBar>),
|
callback: fn(&mut BufferSearchBar, &A, &mut ViewContext<BufferSearchBar>),
|
||||||
);
|
);
|
||||||
|
|
||||||
|
fn register_handler_for_dismissed_search<A: Action>(
|
||||||
|
&mut self,
|
||||||
|
callback: fn(&mut BufferSearchBar, &A, &mut ViewContext<BufferSearchBar>),
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
type GetSearchBar<T> =
|
type GetSearchBar<T> =
|
||||||
@@ -457,16 +462,62 @@ impl<'a, 'b, T: 'static> DivRegistrar<'a, 'b, T> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
impl<T: 'static> SearchActionsRegistrar for DivRegistrar<'_, '_, T> {
|
impl<T: 'static> SearchActionsRegistrar for DivRegistrar<'_, '_, T> {
|
||||||
fn register_handler<A: gpui::Action>(
|
fn register_handler<A: Action>(
|
||||||
&mut self,
|
&mut self,
|
||||||
callback: fn(&mut BufferSearchBar, &A, &mut ViewContext<BufferSearchBar>),
|
callback: fn(&mut BufferSearchBar, &A, &mut ViewContext<BufferSearchBar>),
|
||||||
) {
|
) {
|
||||||
let getter = self.search_getter;
|
let getter = self.search_getter;
|
||||||
self.div = self.div.take().map(|div| {
|
self.div = self.div.take().map(|div| {
|
||||||
div.on_action(self.cx.listener(move |this, action, cx| {
|
div.on_action(self.cx.listener(move |this, action, cx| {
|
||||||
(getter)(this, cx)
|
let should_notify = (getter)(this, cx)
|
||||||
.clone()
|
.clone()
|
||||||
.map(|search_bar| search_bar.update(cx, |this, cx| callback(this, action, cx)));
|
.map(|search_bar| {
|
||||||
|
search_bar.update(cx, |search_bar, cx| {
|
||||||
|
if search_bar.is_dismissed()
|
||||||
|
|| search_bar.active_searchable_item.is_none()
|
||||||
|
{
|
||||||
|
false
|
||||||
|
} else {
|
||||||
|
callback(search_bar, action, cx);
|
||||||
|
true
|
||||||
|
}
|
||||||
|
})
|
||||||
|
})
|
||||||
|
.unwrap_or(false);
|
||||||
|
if should_notify {
|
||||||
|
cx.notify();
|
||||||
|
} else {
|
||||||
|
cx.propagate();
|
||||||
|
}
|
||||||
|
}))
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
fn register_handler_for_dismissed_search<A: Action>(
|
||||||
|
&mut self,
|
||||||
|
callback: fn(&mut BufferSearchBar, &A, &mut ViewContext<BufferSearchBar>),
|
||||||
|
) {
|
||||||
|
let getter = self.search_getter;
|
||||||
|
self.div = self.div.take().map(|div| {
|
||||||
|
div.on_action(self.cx.listener(move |this, action, cx| {
|
||||||
|
let should_notify = (getter)(this, cx)
|
||||||
|
.clone()
|
||||||
|
.map(|search_bar| {
|
||||||
|
search_bar.update(cx, |search_bar, cx| {
|
||||||
|
if search_bar.is_dismissed() {
|
||||||
|
callback(search_bar, action, cx);
|
||||||
|
true
|
||||||
|
} else {
|
||||||
|
false
|
||||||
|
}
|
||||||
|
})
|
||||||
|
})
|
||||||
|
.unwrap_or(false);
|
||||||
|
if should_notify {
|
||||||
|
cx.notify();
|
||||||
|
} else {
|
||||||
|
cx.propagate();
|
||||||
|
}
|
||||||
}))
|
}))
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
@@ -488,44 +539,86 @@ impl SearchActionsRegistrar for Workspace {
|
|||||||
pane.update(cx, move |this, cx| {
|
pane.update(cx, move |this, cx| {
|
||||||
this.toolbar().update(cx, move |this, cx| {
|
this.toolbar().update(cx, move |this, cx| {
|
||||||
if let Some(search_bar) = this.item_of_type::<BufferSearchBar>() {
|
if let Some(search_bar) = this.item_of_type::<BufferSearchBar>() {
|
||||||
search_bar.update(cx, move |this, cx| callback(this, action, cx));
|
let should_notify = search_bar.update(cx, move |search_bar, cx| {
|
||||||
cx.notify();
|
if search_bar.is_dismissed()
|
||||||
|
|| search_bar.active_searchable_item.is_none()
|
||||||
|
{
|
||||||
|
false
|
||||||
|
} else {
|
||||||
|
callback(search_bar, action, cx);
|
||||||
|
true
|
||||||
|
}
|
||||||
|
});
|
||||||
|
if should_notify {
|
||||||
|
cx.notify();
|
||||||
|
} else {
|
||||||
|
cx.propagate();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
})
|
||||||
|
});
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
fn register_handler_for_dismissed_search<A: Action>(
|
||||||
|
&mut self,
|
||||||
|
callback: fn(&mut BufferSearchBar, &A, &mut ViewContext<BufferSearchBar>),
|
||||||
|
) {
|
||||||
|
self.register_action(move |workspace, action: &A, cx| {
|
||||||
|
if workspace.has_active_modal(cx) {
|
||||||
|
cx.propagate();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
let pane = workspace.active_pane();
|
||||||
|
pane.update(cx, move |this, cx| {
|
||||||
|
this.toolbar().update(cx, move |this, cx| {
|
||||||
|
if let Some(search_bar) = this.item_of_type::<BufferSearchBar>() {
|
||||||
|
let should_notify = search_bar.update(cx, move |search_bar, cx| {
|
||||||
|
if search_bar.is_dismissed() {
|
||||||
|
callback(search_bar, action, cx);
|
||||||
|
true
|
||||||
|
} else {
|
||||||
|
false
|
||||||
|
}
|
||||||
|
});
|
||||||
|
if should_notify {
|
||||||
|
cx.notify();
|
||||||
|
} else {
|
||||||
|
cx.propagate();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl BufferSearchBar {
|
impl BufferSearchBar {
|
||||||
pub fn register_inner(registrar: &mut impl SearchActionsRegistrar) {
|
pub fn register(registrar: &mut impl SearchActionsRegistrar) {
|
||||||
registrar.register_handler(|this, action: &ToggleCaseSensitive, cx| {
|
registrar.register_handler(|this, action: &ToggleCaseSensitive, cx| {
|
||||||
if this.supported_options().case {
|
if this.supported_options().case {
|
||||||
this.toggle_case_sensitive(action, cx);
|
this.toggle_case_sensitive(action, cx);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
registrar.register_handler(|this, action: &ToggleWholeWord, cx| {
|
registrar.register_handler(|this, action: &ToggleWholeWord, cx| {
|
||||||
if this.supported_options().word {
|
if this.supported_options().word {
|
||||||
this.toggle_whole_word(action, cx);
|
this.toggle_whole_word(action, cx);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
registrar.register_handler(|this, action: &ToggleReplace, cx| {
|
registrar.register_handler(|this, action: &ToggleReplace, cx| {
|
||||||
if this.supported_options().replacement {
|
if this.supported_options().replacement {
|
||||||
this.toggle_replace(action, cx);
|
this.toggle_replace(action, cx);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
registrar.register_handler(|this, _: &ActivateRegexMode, cx| {
|
registrar.register_handler(|this, _: &ActivateRegexMode, cx| {
|
||||||
if this.supported_options().regex {
|
if this.supported_options().regex {
|
||||||
this.activate_search_mode(SearchMode::Regex, cx);
|
this.activate_search_mode(SearchMode::Regex, cx);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
registrar.register_handler(|this, _: &ActivateTextMode, cx| {
|
registrar.register_handler(|this, _: &ActivateTextMode, cx| {
|
||||||
this.activate_search_mode(SearchMode::Text, cx);
|
this.activate_search_mode(SearchMode::Text, cx);
|
||||||
});
|
});
|
||||||
|
|
||||||
registrar.register_handler(|this, action: &CycleMode, cx| {
|
registrar.register_handler(|this, action: &CycleMode, cx| {
|
||||||
if this.supported_options().regex {
|
if this.supported_options().regex {
|
||||||
// If regex is not supported then search has just one mode (text) - in that case there's no point in supporting
|
// If regex is not supported then search has just one mode (text) - in that case there's no point in supporting
|
||||||
@@ -533,7 +626,6 @@ impl BufferSearchBar {
|
|||||||
this.cycle_mode(action, cx)
|
this.cycle_mode(action, cx)
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
registrar.register_handler(|this, action: &SelectNextMatch, cx| {
|
registrar.register_handler(|this, action: &SelectNextMatch, cx| {
|
||||||
this.select_next_match(action, cx);
|
this.select_next_match(action, cx);
|
||||||
});
|
});
|
||||||
@@ -544,19 +636,13 @@ impl BufferSearchBar {
|
|||||||
this.select_all_matches(action, cx);
|
this.select_all_matches(action, cx);
|
||||||
});
|
});
|
||||||
registrar.register_handler(|this, _: &editor::Cancel, cx| {
|
registrar.register_handler(|this, _: &editor::Cancel, cx| {
|
||||||
if this.dismissed {
|
this.dismiss(&Dismiss, cx);
|
||||||
cx.propagate();
|
|
||||||
} else {
|
|
||||||
this.dismiss(&Dismiss, cx);
|
|
||||||
}
|
|
||||||
});
|
});
|
||||||
registrar.register_handler(|this, deploy, cx| {
|
registrar.register_handler_for_dismissed_search(|this, deploy, cx| {
|
||||||
this.deploy(deploy, cx);
|
this.deploy(deploy, cx);
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
fn register(workspace: &mut Workspace) {
|
|
||||||
Self::register_inner(workspace);
|
|
||||||
}
|
|
||||||
pub fn new(cx: &mut ViewContext<Self>) -> Self {
|
pub fn new(cx: &mut ViewContext<Self>) -> Self {
|
||||||
let query_editor = cx.new_view(|cx| Editor::single_line(cx));
|
let query_editor = cx.new_view(|cx| Editor::single_line(cx));
|
||||||
cx.subscribe(&query_editor, Self::on_query_editor_event)
|
cx.subscribe(&query_editor, Self::on_query_editor_event)
|
||||||
|
|||||||
@@ -12,10 +12,10 @@ use editor::{
|
|||||||
};
|
};
|
||||||
use editor::{EditorElement, EditorStyle};
|
use editor::{EditorElement, EditorStyle};
|
||||||
use gpui::{
|
use gpui::{
|
||||||
actions, div, AnyElement, AnyView, AppContext, Context as _, Element, EntityId, EventEmitter,
|
actions, div, Action, AnyElement, AnyView, AppContext, Context as _, Element, EntityId,
|
||||||
FocusHandle, FocusableView, FontStyle, FontWeight, Hsla, InteractiveElement, IntoElement,
|
EventEmitter, FocusHandle, FocusableView, FontStyle, FontWeight, Hsla, InteractiveElement,
|
||||||
KeyContext, Model, ModelContext, ParentElement, PromptLevel, Render, SharedString, Styled,
|
IntoElement, KeyContext, Model, ModelContext, ParentElement, PromptLevel, Render, SharedString,
|
||||||
Subscription, Task, TextStyle, View, ViewContext, VisualContext, WeakModel, WeakView,
|
Styled, Subscription, Task, TextStyle, View, ViewContext, VisualContext, WeakModel, WeakView,
|
||||||
WhiteSpace, WindowContext,
|
WhiteSpace, WindowContext,
|
||||||
};
|
};
|
||||||
use menu::Confirm;
|
use menu::Confirm;
|
||||||
@@ -36,6 +36,7 @@ use std::{
|
|||||||
time::{Duration, Instant},
|
time::{Duration, Instant},
|
||||||
};
|
};
|
||||||
use theme::ThemeSettings;
|
use theme::ThemeSettings;
|
||||||
|
use workspace::{DeploySearch, NewSearch};
|
||||||
|
|
||||||
use ui::{
|
use ui::{
|
||||||
h_flex, prelude::*, v_flex, Icon, IconButton, IconName, Label, LabelCommon, LabelSize,
|
h_flex, prelude::*, v_flex, Icon, IconButton, IconName, Label, LabelCommon, LabelSize,
|
||||||
@@ -60,10 +61,64 @@ struct ActiveSettings(HashMap<WeakModel<Project>, ProjectSearchSettings>);
|
|||||||
pub fn init(cx: &mut AppContext) {
|
pub fn init(cx: &mut AppContext) {
|
||||||
cx.set_global(ActiveSettings::default());
|
cx.set_global(ActiveSettings::default());
|
||||||
cx.observe_new_views(|workspace: &mut Workspace, _cx| {
|
cx.observe_new_views(|workspace: &mut Workspace, _cx| {
|
||||||
workspace
|
register_workspace_action(workspace, move |search_bar, _: &ToggleFilters, cx| {
|
||||||
.register_action(ProjectSearchView::new_search)
|
search_bar.toggle_filters(cx);
|
||||||
.register_action(ProjectSearchView::deploy_search)
|
});
|
||||||
.register_action(ProjectSearchBar::search_in_new);
|
register_workspace_action(workspace, move |search_bar, _: &ToggleCaseSensitive, cx| {
|
||||||
|
search_bar.toggle_search_option(SearchOptions::CASE_SENSITIVE, cx);
|
||||||
|
});
|
||||||
|
register_workspace_action(workspace, move |search_bar, _: &ToggleWholeWord, cx| {
|
||||||
|
search_bar.toggle_search_option(SearchOptions::WHOLE_WORD, cx);
|
||||||
|
});
|
||||||
|
register_workspace_action(workspace, move |search_bar, action: &ToggleReplace, cx| {
|
||||||
|
search_bar.toggle_replace(action, cx)
|
||||||
|
});
|
||||||
|
register_workspace_action(workspace, move |search_bar, _: &ActivateRegexMode, cx| {
|
||||||
|
search_bar.activate_search_mode(SearchMode::Regex, cx)
|
||||||
|
});
|
||||||
|
register_workspace_action(workspace, move |search_bar, _: &ActivateTextMode, cx| {
|
||||||
|
search_bar.activate_search_mode(SearchMode::Text, cx)
|
||||||
|
});
|
||||||
|
register_workspace_action(
|
||||||
|
workspace,
|
||||||
|
move |search_bar, _: &ActivateSemanticMode, cx| {
|
||||||
|
search_bar.activate_search_mode(SearchMode::Semantic, cx)
|
||||||
|
},
|
||||||
|
);
|
||||||
|
register_workspace_action(workspace, move |search_bar, action: &CycleMode, cx| {
|
||||||
|
search_bar.cycle_mode(action, cx)
|
||||||
|
});
|
||||||
|
register_workspace_action(
|
||||||
|
workspace,
|
||||||
|
move |search_bar, action: &SelectNextMatch, cx| {
|
||||||
|
search_bar.select_next_match(action, cx)
|
||||||
|
},
|
||||||
|
);
|
||||||
|
register_workspace_action(
|
||||||
|
workspace,
|
||||||
|
move |search_bar, action: &SelectPrevMatch, cx| {
|
||||||
|
search_bar.select_prev_match(action, cx)
|
||||||
|
},
|
||||||
|
);
|
||||||
|
|
||||||
|
register_workspace_action_for_dismissed_search(
|
||||||
|
workspace,
|
||||||
|
move |workspace, action: &NewSearch, cx| {
|
||||||
|
ProjectSearchView::new_search(workspace, action, cx)
|
||||||
|
},
|
||||||
|
);
|
||||||
|
register_workspace_action_for_dismissed_search(
|
||||||
|
workspace,
|
||||||
|
move |workspace, action: &DeploySearch, cx| {
|
||||||
|
ProjectSearchView::deploy_search(workspace, action, cx)
|
||||||
|
},
|
||||||
|
);
|
||||||
|
register_workspace_action_for_dismissed_search(
|
||||||
|
workspace,
|
||||||
|
move |workspace, action: &SearchInNew, cx| {
|
||||||
|
ProjectSearchView::search_in_new(workspace, action, cx)
|
||||||
|
},
|
||||||
|
);
|
||||||
})
|
})
|
||||||
.detach();
|
.detach();
|
||||||
}
|
}
|
||||||
@@ -960,6 +1015,37 @@ impl ProjectSearchView {
|
|||||||
Self::existing_or_new_search(workspace, existing, cx)
|
Self::existing_or_new_search(workspace, existing, cx)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn search_in_new(workspace: &mut Workspace, _: &SearchInNew, cx: &mut ViewContext<Workspace>) {
|
||||||
|
if let Some(search_view) = workspace
|
||||||
|
.active_item(cx)
|
||||||
|
.and_then(|item| item.downcast::<ProjectSearchView>())
|
||||||
|
{
|
||||||
|
let new_query = search_view.update(cx, |search_view, cx| {
|
||||||
|
let new_query = search_view.build_search_query(cx);
|
||||||
|
if new_query.is_some() {
|
||||||
|
if let Some(old_query) = search_view.model.read(cx).active_query.clone() {
|
||||||
|
search_view.query_editor.update(cx, |editor, cx| {
|
||||||
|
editor.set_text(old_query.as_str(), cx);
|
||||||
|
});
|
||||||
|
search_view.search_options = SearchOptions::from_query(&old_query);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
new_query
|
||||||
|
});
|
||||||
|
if let Some(new_query) = new_query {
|
||||||
|
let model = cx.new_model(|cx| {
|
||||||
|
let mut model = ProjectSearch::new(workspace.project().clone(), cx);
|
||||||
|
model.search(new_query, cx);
|
||||||
|
model
|
||||||
|
});
|
||||||
|
workspace.add_item(
|
||||||
|
Box::new(cx.new_view(|cx| ProjectSearchView::new(model, cx, None))),
|
||||||
|
cx,
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// Add another search tab to the workspace.
|
// Add another search tab to the workspace.
|
||||||
fn new_search(
|
fn new_search(
|
||||||
workspace: &mut Workspace,
|
workspace: &mut Workspace,
|
||||||
@@ -1262,17 +1348,11 @@ impl ProjectSearchView {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Default for ProjectSearchBar {
|
|
||||||
fn default() -> Self {
|
|
||||||
Self::new()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl ProjectSearchBar {
|
impl ProjectSearchBar {
|
||||||
pub fn new() -> Self {
|
pub fn new() -> Self {
|
||||||
Self {
|
Self {
|
||||||
active_project_search: Default::default(),
|
active_project_search: None,
|
||||||
subscription: Default::default(),
|
subscription: None,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1303,37 +1383,6 @@ impl ProjectSearchBar {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn search_in_new(workspace: &mut Workspace, _: &SearchInNew, cx: &mut ViewContext<Workspace>) {
|
|
||||||
if let Some(search_view) = workspace
|
|
||||||
.active_item(cx)
|
|
||||||
.and_then(|item| item.downcast::<ProjectSearchView>())
|
|
||||||
{
|
|
||||||
let new_query = search_view.update(cx, |search_view, cx| {
|
|
||||||
let new_query = search_view.build_search_query(cx);
|
|
||||||
if new_query.is_some() {
|
|
||||||
if let Some(old_query) = search_view.model.read(cx).active_query.clone() {
|
|
||||||
search_view.query_editor.update(cx, |editor, cx| {
|
|
||||||
editor.set_text(old_query.as_str(), cx);
|
|
||||||
});
|
|
||||||
search_view.search_options = SearchOptions::from_query(&old_query);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
new_query
|
|
||||||
});
|
|
||||||
if let Some(new_query) = new_query {
|
|
||||||
let model = cx.new_model(|cx| {
|
|
||||||
let mut model = ProjectSearch::new(workspace.project().clone(), cx);
|
|
||||||
model.search(new_query, cx);
|
|
||||||
model
|
|
||||||
});
|
|
||||||
workspace.add_item(
|
|
||||||
Box::new(cx.new_view(|cx| ProjectSearchView::new(model, cx, None))),
|
|
||||||
cx,
|
|
||||||
);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
fn tab(&mut self, _: &editor::Tab, cx: &mut ViewContext<Self>) {
|
fn tab(&mut self, _: &editor::Tab, cx: &mut ViewContext<Self>) {
|
||||||
self.cycle_field(Direction::Next, cx);
|
self.cycle_field(Direction::Next, cx);
|
||||||
}
|
}
|
||||||
@@ -1502,6 +1551,22 @@ impl ProjectSearchBar {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn select_next_match(&mut self, _: &SelectNextMatch, cx: &mut ViewContext<Self>) {
|
||||||
|
if let Some(search) = self.active_project_search.as_ref() {
|
||||||
|
search.update(cx, |this, cx| {
|
||||||
|
this.select_match(Direction::Next, cx);
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn select_prev_match(&mut self, _: &SelectPrevMatch, cx: &mut ViewContext<Self>) {
|
||||||
|
if let Some(search) = self.active_project_search.as_ref() {
|
||||||
|
search.update(cx, |this, cx| {
|
||||||
|
this.select_match(Direction::Prev, cx);
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
fn new_placeholder_text(&self, cx: &mut ViewContext<Self>) -> Option<String> {
|
fn new_placeholder_text(&self, cx: &mut ViewContext<Self>) -> Option<String> {
|
||||||
let previous_query_keystrokes = cx
|
let previous_query_keystrokes = cx
|
||||||
.bindings_for_action(&PreviousHistoryQuery {})
|
.bindings_for_action(&PreviousHistoryQuery {})
|
||||||
@@ -1870,6 +1935,8 @@ impl Render for ProjectSearchBar {
|
|||||||
}))
|
}))
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
|
.on_action(cx.listener(Self::select_next_match))
|
||||||
|
.on_action(cx.listener(Self::select_prev_match))
|
||||||
.child(
|
.child(
|
||||||
h_flex()
|
h_flex()
|
||||||
.justify_between()
|
.justify_between()
|
||||||
@@ -1963,6 +2030,60 @@ impl ToolbarItemView for ProjectSearchBar {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn register_workspace_action<A: Action>(
|
||||||
|
workspace: &mut Workspace,
|
||||||
|
callback: fn(&mut ProjectSearchBar, &A, &mut ViewContext<ProjectSearchBar>),
|
||||||
|
) {
|
||||||
|
workspace.register_action(move |workspace, action: &A, cx| {
|
||||||
|
if workspace.has_active_modal(cx) {
|
||||||
|
cx.propagate();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
workspace.active_pane().update(cx, |pane, cx| {
|
||||||
|
pane.toolbar().update(cx, move |workspace, cx| {
|
||||||
|
if let Some(search_bar) = workspace.item_of_type::<ProjectSearchBar>() {
|
||||||
|
search_bar.update(cx, move |search_bar, cx| {
|
||||||
|
if search_bar.active_project_search.is_some() {
|
||||||
|
callback(search_bar, action, cx);
|
||||||
|
cx.notify();
|
||||||
|
} else {
|
||||||
|
cx.propagate();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
});
|
||||||
|
})
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
fn register_workspace_action_for_dismissed_search<A: Action>(
|
||||||
|
workspace: &mut Workspace,
|
||||||
|
callback: fn(&mut Workspace, &A, &mut ViewContext<Workspace>),
|
||||||
|
) {
|
||||||
|
workspace.register_action(move |workspace, action: &A, cx| {
|
||||||
|
if workspace.has_active_modal(cx) {
|
||||||
|
cx.propagate();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
let should_notify = workspace
|
||||||
|
.active_pane()
|
||||||
|
.read(cx)
|
||||||
|
.toolbar()
|
||||||
|
.read(cx)
|
||||||
|
.item_of_type::<ProjectSearchBar>()
|
||||||
|
.map(|search_bar| search_bar.read(cx).active_project_search.is_none())
|
||||||
|
.unwrap_or(false);
|
||||||
|
if should_notify {
|
||||||
|
callback(workspace, action, cx);
|
||||||
|
cx.notify();
|
||||||
|
} else {
|
||||||
|
cx.propagate();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
#[cfg(test)]
|
#[cfg(test)]
|
||||||
pub mod tests {
|
pub mod tests {
|
||||||
use super::*;
|
use super::*;
|
||||||
|
|||||||
@@ -387,7 +387,7 @@ impl Render for TerminalPanel {
|
|||||||
},
|
},
|
||||||
cx,
|
cx,
|
||||||
);
|
);
|
||||||
BufferSearchBar::register_inner(&mut registrar);
|
BufferSearchBar::register(&mut registrar);
|
||||||
registrar.into_div().size_full().child(self.pane.clone())
|
registrar.into_div().size_full().child(self.pane.clone())
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user