diff --git a/assets/keymaps/default.json b/assets/keymaps/default.json index 635adfb64d..46474fd33a 100644 --- a/assets/keymaps/default.json +++ b/assets/keymaps/default.json @@ -15,7 +15,7 @@ "shift-cmd-}": "pane::ActivateNextItem", "cmd-w": "pane::CloseActiveItem", "cmd-shift-W": "workspace::CloseWindow", - "alt-cmd-w": "pane::CloseInactiveItems", + "cmd-k alt-cmd-w": "pane::CloseInactiveItems", "cmd-s": "workspace::Save", "cmd-shift-S": "workspace::SaveAs", "cmd-=": "zed::IncreaseBufferFontSize", @@ -146,7 +146,25 @@ "bindings": { "cmd-f": "project_search::ToggleFocus", "cmd-g": "search::SelectNextMatch", - "cmd-shift-G": "search::SelectPrevMatch" + "cmd-shift-G": "search::SelectPrevMatch", + "alt-cmd-c": [ + "search::ToggleSearchOption", + { + "option": "CaseSensitive" + } + ], + "alt-cmd-w": [ + "search::ToggleSearchOption", + { + "option": "WholeWord" + } + ], + "alt-cmd-r": [ + "search::ToggleSearchOption", + { + "option": "Regex" + } + ] } }, { diff --git a/crates/search/src/buffer_search.rs b/crates/search/src/buffer_search.rs index ce36e63ad2..f96801f050 100644 --- a/crates/search/src/buffer_search.rs +++ b/crates/search/src/buffer_search.rs @@ -1,12 +1,12 @@ use crate::{ active_match_index, match_index_for_direction, query_suggestion_for_editor, Direction, - SearchOption, SelectNextMatch, SelectPrevMatch, + SearchOption, SelectNextMatch, SelectPrevMatch, ToggleSearchOption, }; use collections::HashMap; use editor::{Anchor, Autoscroll, Editor}; use gpui::{ - actions, elements::*, impl_actions, impl_internal_actions, platform::CursorStyle, AppContext, - Entity, MutableAppContext, RenderContext, Subscription, Task, View, ViewContext, ViewHandle, + actions, elements::*, impl_actions, platform::CursorStyle, AppContext, Entity, + MutableAppContext, RenderContext, Subscription, Task, View, ViewContext, ViewHandle, WeakViewHandle, }; use language::OffsetRangeExt; @@ -21,12 +21,8 @@ pub struct Deploy { pub focus: bool, } -#[derive(Clone, PartialEq)] -pub struct ToggleSearchOption(pub SearchOption); - actions!(buffer_search, [Dismiss, FocusEditor]); impl_actions!(buffer_search, [Deploy]); -impl_internal_actions!(buffer_search, [ToggleSearchOption]); pub enum Event { UpdateLocation, @@ -36,7 +32,21 @@ pub fn init(cx: &mut MutableAppContext) { cx.add_action(BufferSearchBar::deploy); cx.add_action(BufferSearchBar::dismiss); cx.add_action(BufferSearchBar::focus_editor); - cx.add_action(BufferSearchBar::toggle_search_option); + cx.add_action( + |pane: &mut Pane, + ToggleSearchOption { option }: &ToggleSearchOption, + cx: &mut ViewContext| { + if let Some(search_bar) = pane.toolbar().read(cx).item_of_type::() { + if search_bar.update(cx, |search_bar, cx| search_bar.show(false, false, cx)) { + search_bar.update(cx, |search_bar, cx| { + search_bar.toggle_search_option(*option, cx); + }); + return; + } + } + cx.propagate_action(); + }, + ); cx.add_action(BufferSearchBar::select_next_match); cx.add_action(BufferSearchBar::select_prev_match); cx.add_action(BufferSearchBar::select_next_match_on_pane); @@ -215,16 +225,18 @@ impl BufferSearchBar { cx.notify(); } - fn show(&mut self, focus: bool, cx: &mut ViewContext) -> bool { + fn show(&mut self, focus: bool, suggest_query: bool, cx: &mut ViewContext) -> bool { let editor = if let Some(editor) = self.active_editor.clone() { editor } else { return false; }; - let text = query_suggestion_for_editor(&editor, cx); - if !text.is_empty() { - self.set_query(&text, cx); + if suggest_query { + let text = query_suggestion_for_editor(&editor, cx); + if !text.is_empty() { + self.set_query(&text, cx); + } } if focus { @@ -253,11 +265,12 @@ impl BufferSearchBar { fn render_search_option( &self, icon: &str, - search_option: SearchOption, + option: SearchOption, cx: &mut RenderContext, ) -> ElementBox { - let is_active = self.is_search_option_enabled(search_option); - MouseEventHandler::new::(search_option as usize, cx, |state, cx| { + let tooltip_style = cx.global::().theme.tooltip.clone(); + let is_active = self.is_search_option_enabled(option); + MouseEventHandler::new::(option as usize, cx, |state, cx| { let style = &cx .global::() .theme @@ -269,8 +282,15 @@ impl BufferSearchBar { .with_style(style.container) .boxed() }) - .on_click(move |_, _, cx| cx.dispatch_action(ToggleSearchOption(search_option))) + .on_click(move |_, _, cx| cx.dispatch_action(ToggleSearchOption { option })) .with_cursor_style(CursorStyle::PointingHand) + .with_tooltip::( + option as usize, + format!("Toggle {}", option.label()), + Some(Box::new(ToggleSearchOption { option })), + tooltip_style, + cx, + ) .boxed() } @@ -303,7 +323,7 @@ impl BufferSearchBar { fn deploy(pane: &mut Pane, action: &Deploy, cx: &mut ViewContext) { if let Some(search_bar) = pane.toolbar().read(cx).item_of_type::() { - if search_bar.update(cx, |search_bar, cx| search_bar.show(action.focus, cx)) { + if search_bar.update(cx, |search_bar, cx| search_bar.show(action.focus, true, cx)) { return; } } @@ -334,11 +354,7 @@ impl BufferSearchBar { } } - fn toggle_search_option( - &mut self, - ToggleSearchOption(search_option): &ToggleSearchOption, - cx: &mut ViewContext, - ) { + fn toggle_search_option(&mut self, search_option: SearchOption, cx: &mut ViewContext) { let value = match search_option { SearchOption::WholeWord => &mut self.whole_word, SearchOption::CaseSensitive => &mut self.case_sensitive, @@ -591,7 +607,7 @@ mod tests { let search_bar = cx.add_view(Default::default(), |cx| { let mut search_bar = BufferSearchBar::new(cx); search_bar.set_active_pane_item(Some(&editor), cx); - search_bar.show(false, cx); + search_bar.show(false, true, cx); search_bar }); @@ -619,7 +635,7 @@ mod tests { // Switch to a case sensitive search. search_bar.update(cx, |search_bar, cx| { - search_bar.toggle_search_option(&ToggleSearchOption(SearchOption::CaseSensitive), cx); + search_bar.toggle_search_option(SearchOption::CaseSensitive, cx); }); editor.next_notification(&cx).await; editor.update(cx, |editor, cx| { @@ -676,7 +692,7 @@ mod tests { // Switch to a whole word search. search_bar.update(cx, |search_bar, cx| { - search_bar.toggle_search_option(&ToggleSearchOption(SearchOption::WholeWord), cx); + search_bar.toggle_search_option(SearchOption::WholeWord, cx); }); editor.next_notification(&cx).await; editor.update(cx, |editor, cx| { diff --git a/crates/search/src/project_search.rs b/crates/search/src/project_search.rs index a7cfb020b5..0ba74348f8 100644 --- a/crates/search/src/project_search.rs +++ b/crates/search/src/project_search.rs @@ -655,7 +655,7 @@ impl ProjectSearchBar { fn toggle_search_option( &mut self, - ToggleSearchOption(option): &ToggleSearchOption, + ToggleSearchOption { option }: &ToggleSearchOption, cx: &mut ViewContext, ) { if let Some(search_view) = self.active_project_search.as_ref() { @@ -705,8 +705,9 @@ impl ProjectSearchBar { option: SearchOption, cx: &mut RenderContext, ) -> ElementBox { + let tooltip_style = cx.global::().theme.tooltip.clone(); let is_active = self.is_option_enabled(option, cx); - MouseEventHandler::new::(option as usize, cx, |state, cx| { + MouseEventHandler::new::(option as usize, cx, |state, cx| { let style = &cx .global::() .theme @@ -718,8 +719,15 @@ impl ProjectSearchBar { .with_style(style.container) .boxed() }) - .on_click(move |_, _, cx| cx.dispatch_action(ToggleSearchOption(option))) + .on_click(move |_, _, cx| cx.dispatch_action(ToggleSearchOption { option })) .with_cursor_style(CursorStyle::PointingHand) + .with_tooltip::( + option as usize, + format!("Toggle {}", option.label()), + Some(Box::new(ToggleSearchOption { option })), + tooltip_style, + cx, + ) .boxed() } diff --git a/crates/search/src/search.rs b/crates/search/src/search.rs index 68bdc78c7a..048eb1ddeb 100644 --- a/crates/search/src/search.rs +++ b/crates/search/src/search.rs @@ -1,7 +1,8 @@ pub use buffer_search::BufferSearchBar; use editor::{display_map::ToDisplayPoint, Anchor, Bias, Editor, MultiBufferSnapshot}; -use gpui::{actions, impl_internal_actions, MutableAppContext, ViewHandle}; +use gpui::{actions, impl_actions, MutableAppContext, ViewHandle}; pub use project_search::{ProjectSearchBar, ProjectSearchView}; +use serde::Deserialize; use std::{ cmp::{self, Ordering}, ops::Range, @@ -15,19 +16,31 @@ pub fn init(cx: &mut MutableAppContext) { project_search::init(cx); } -#[derive(Clone, PartialEq)] -pub struct ToggleSearchOption(pub SearchOption); +#[derive(Clone, PartialEq, Deserialize)] +pub struct ToggleSearchOption { + pub option: SearchOption, +} actions!(search, [SelectNextMatch, SelectPrevMatch]); -impl_internal_actions!(search, [ToggleSearchOption]); +impl_actions!(search, [ToggleSearchOption]); -#[derive(Clone, Copy, PartialEq)] +#[derive(Clone, Copy, PartialEq, Deserialize)] pub enum SearchOption { WholeWord, CaseSensitive, Regex, } +impl SearchOption { + pub fn label(&self) -> &'static str { + match self { + SearchOption::WholeWord => "Match Whole Word", + SearchOption::CaseSensitive => "Match Case", + SearchOption::Regex => "Use Regular Expression", + } + } +} + #[derive(Clone, Copy, PartialEq, Eq)] pub enum Direction { Prev,