diff --git a/assets/keymaps/default-macos.json b/assets/keymaps/default-macos.json index f8b296e3e82feb90a9b3124ebc7919b3312d3070..7c56b433792389c27358e848c2d1c838219068fc 100644 --- a/assets/keymaps/default-macos.json +++ b/assets/keymaps/default-macos.json @@ -171,7 +171,7 @@ "cmd-f": "buffer_search::Deploy", "cmd-alt-f": "buffer_search::DeployReplace", "cmd-alt-l": ["buffer_search::Deploy", { "selection_search_enabled": true }], - "cmd-e": ["buffer_search::Deploy", { "focus": false }], + "cmd-e": "buffer_search::UseSelectionForFind", "cmd->": "agent::AddSelectionToThread", "cmd-alt-e": "editor::SelectEnclosingSymbol", "alt-enter": "editor::OpenSelectionsInMultibuffer", diff --git a/crates/debugger_tools/src/dap_log.rs b/crates/debugger_tools/src/dap_log.rs index fc2cbd9e1c3f6f3edc39322e51cef4e999c6fcca..749a6cd7888301ad72bf226638c4261763834775 100644 --- a/crates/debugger_tools/src/dap_log.rs +++ b/crates/debugger_tools/src/dap_log.rs @@ -1028,9 +1028,14 @@ impl SearchableItem for DapLogView { }) } - fn query_suggestion(&mut self, window: &mut Window, cx: &mut Context) -> String { + fn query_suggestion( + &mut self, + ignore_settings: bool, + window: &mut Window, + cx: &mut Context, + ) -> String { self.editor - .update(cx, |e, cx| e.query_suggestion(window, cx)) + .update(cx, |e, cx| e.query_suggestion(ignore_settings, window, cx)) } fn activate_match( diff --git a/crates/editor/src/items.rs b/crates/editor/src/items.rs index 5dc0563300ed20d15aa94a2b7d9e80187cd7c4a1..1752aefc5e6a0e7f3e83984b82288a432a74b487 100644 --- a/crates/editor/src/items.rs +++ b/crates/editor/src/items.rs @@ -1660,8 +1660,17 @@ impl SearchableItem for Editor { } } - fn query_suggestion(&mut self, window: &mut Window, cx: &mut Context) -> String { - let setting = EditorSettings::get_global(cx).seed_search_query_from_cursor; + fn query_suggestion( + &mut self, + ignore_settings: bool, + window: &mut Window, + cx: &mut Context, + ) -> String { + let setting = if ignore_settings { + SeedQuerySetting::Always + } else { + EditorSettings::get_global(cx).seed_search_query_from_cursor + }; let snapshot = self.snapshot(window, cx); let selection = self.selections.newest_adjusted(&snapshot.display_snapshot); let buffer_snapshot = snapshot.buffer_snapshot(); diff --git a/crates/editor/src/split.rs b/crates/editor/src/split.rs index b9d661a5ec7e383a3c7e8d7749f2ffc8bc1f9b83..77a3bf63c01f558dbc4cd0064a8769df7e551c35 100644 --- a/crates/editor/src/split.rs +++ b/crates/editor/src/split.rs @@ -1901,9 +1901,15 @@ impl SearchableItem for SplittableEditor { } } - fn query_suggestion(&mut self, window: &mut Window, cx: &mut Context) -> String { - self.focused_editor() - .update(cx, |editor, cx| editor.query_suggestion(window, cx)) + fn query_suggestion( + &mut self, + ignore_settings: bool, + window: &mut Window, + cx: &mut Context, + ) -> String { + self.focused_editor().update(cx, |editor, cx| { + editor.query_suggestion(ignore_settings, window, cx) + }) } fn activate_match( diff --git a/crates/language_tools/src/lsp_log_view.rs b/crates/language_tools/src/lsp_log_view.rs index e3a9c0b80d8f35f1060c93e2ee62e60aee02f908..06c7e9f77f6c601071ad1cb9fb8615937b6928fb 100644 --- a/crates/language_tools/src/lsp_log_view.rs +++ b/crates/language_tools/src/lsp_log_view.rs @@ -822,9 +822,14 @@ impl SearchableItem for LspLogView { }) } - fn query_suggestion(&mut self, window: &mut Window, cx: &mut Context) -> String { + fn query_suggestion( + &mut self, + ignore_settings: bool, + window: &mut Window, + cx: &mut Context, + ) -> String { self.editor - .update(cx, |e, cx| e.query_suggestion(window, cx)) + .update(cx, |e, cx| e.query_suggestion(ignore_settings, window, cx)) } fn activate_match( diff --git a/crates/markdown_preview/src/markdown_preview_view.rs b/crates/markdown_preview/src/markdown_preview_view.rs index c95d4480121b5aa74519e266b89105e416cc86c5..8230e332253b4a018b280d9ef35b812ccb6bcc33 100644 --- a/crates/markdown_preview/src/markdown_preview_view.rs +++ b/crates/markdown_preview/src/markdown_preview_view.rs @@ -956,7 +956,12 @@ impl SearchableItem for MarkdownPreviewView { } } - fn query_suggestion(&mut self, _window: &mut Window, cx: &mut Context) -> String { + fn query_suggestion( + &mut self, + _ignore_settings: bool, + _window: &mut Window, + cx: &mut Context, + ) -> String { self.markdown.read(cx).selected_text().unwrap_or_default() } diff --git a/crates/search/src/buffer_search.rs b/crates/search/src/buffer_search.rs index ca5acb53c084ca7208278ef7beeff8acf819b627..9dcef1b60e17713c495272d98e7a86f24a2553d5 100644 --- a/crates/search/src/buffer_search.rs +++ b/crates/search/src/buffer_search.rs @@ -56,7 +56,9 @@ use registrar::{ForDeployed, ForDismissed, SearchActionsRegistrar}; const MAX_BUFFER_SEARCH_HISTORY_SIZE: usize = 50; -pub use zed_actions::buffer_search::{Deploy, DeployReplace, Dismiss, FocusEditor}; +pub use zed_actions::buffer_search::{ + Deploy, DeployReplace, Dismiss, FocusEditor, UseSelectionForFind, +}; pub enum Event { UpdateLocation, @@ -839,6 +841,16 @@ impl BufferSearchBar { this.deploy(&Deploy::replace(), window, cx); } })); + registrar.register_handler(ForDeployed( + |this, action: &UseSelectionForFind, window, cx| { + this.use_selection_for_find(action, window, cx); + }, + )); + registrar.register_handler(ForDismissed( + |this, action: &UseSelectionForFind, window, cx| { + this.use_selection_for_find(action, window, cx); + }, + )); } pub fn new( @@ -991,7 +1003,7 @@ impl BufferSearchBar { let mut handle = self.query_editor.focus_handle(cx); let mut select_query = true; - let has_seed_text = self.query_suggestion(window, cx).is_some(); + let has_seed_text = self.query_suggestion(false, window, cx).is_some(); if deploy.replace_enabled && has_seed_text { handle = self.replacement_editor.focus_handle(cx); select_query = false; @@ -1100,7 +1112,7 @@ impl BufferSearchBar { } pub fn search_suggested(&mut self, window: &mut Window, cx: &mut Context) { - let search = self.query_suggestion(window, cx).map(|suggestion| { + let search = self.query_suggestion(false, window, cx).map(|suggestion| { self.search(&suggestion, Some(self.default_options), true, window, cx) }); @@ -1154,12 +1166,13 @@ impl BufferSearchBar { pub fn query_suggestion( &mut self, + ignore_settings: bool, window: &mut Window, cx: &mut Context, ) -> Option { self.active_searchable_item .as_ref() - .map(|searchable_item| searchable_item.query_suggestion(window, cx)) + .map(|searchable_item| searchable_item.query_suggestion(ignore_settings, window, cx)) .filter(|suggestion| !suggestion.is_empty()) } @@ -1224,6 +1237,26 @@ impl BufferSearchBar { )); } + pub fn use_selection_for_find( + &mut self, + _: &UseSelectionForFind, + window: &mut Window, + cx: &mut Context, + ) { + let Some(search_text) = self.query_suggestion(true, window, cx) else { + return; + }; + self.query_editor.update(cx, |query_editor, cx| { + query_editor.buffer().update(cx, |query_buffer, cx| { + let len = query_buffer.len(cx); + query_buffer.edit([(MultiBufferOffset(0)..len, search_text)], None, cx); + }); + }); + #[cfg(target_os = "macos")] + self.update_find_pasteboard(cx); + cx.notify(); + } + pub fn focus_editor(&mut self, _: &FocusEditor, window: &mut Window, cx: &mut Context) { if let Some(active_editor) = self.active_searchable_item.as_ref() { let handle = active_editor.item_focus_handle(cx); diff --git a/crates/search/src/project_search.rs b/crates/search/src/project_search.rs index 441c1cf47d11953480f77e0b30f686d89d05eb11..300ac8ed6dd27b50ccc6ce2845184c2a76a21a32 100644 --- a/crates/search/src/project_search.rs +++ b/crates/search/src/project_search.rs @@ -1181,7 +1181,7 @@ impl ProjectSearchView { } let editor = item.act_as::(cx)?; - let query = editor.query_suggestion(window, cx); + let query = editor.query_suggestion(false, window, cx); if query.is_empty() { None } else { Some(query) } }); diff --git a/crates/terminal_view/src/terminal_view.rs b/crates/terminal_view/src/terminal_view.rs index 34689aa6aa48e34c4c65bfd5d60ab867ea79c4a4..8b38ccdb50f766b723dbf9d84b0c6226667f253f 100644 --- a/crates/terminal_view/src/terminal_view.rs +++ b/crates/terminal_view/src/terminal_view.rs @@ -1852,7 +1852,12 @@ impl SearchableItem for TerminalView { } /// Returns the selection content to pre-load into this search - fn query_suggestion(&mut self, _window: &mut Window, cx: &mut Context) -> String { + fn query_suggestion( + &mut self, + _ignore_settings: bool, + _window: &mut Window, + cx: &mut Context, + ) -> String { self.terminal() .read(cx) .last_content diff --git a/crates/vim/src/normal/search.rs b/crates/vim/src/normal/search.rs index 22c453c877ec89fdbf432d19d89167285b78b12f..549e566683461681c13357c76c3fe4ded8e177f9 100644 --- a/crates/vim/src/normal/search.rs +++ b/crates/vim/src/normal/search.rs @@ -434,7 +434,6 @@ impl Vim { let count = Vim::take_count(cx).unwrap_or(1); Vim::take_forced_motion(cx); let prior_selections = self.editor_selections(window, cx); - let cursor_word = self.editor_cursor_word(window, cx); let vim = cx.entity(); let searched = pane.update(cx, |pane, cx| { @@ -456,10 +455,7 @@ impl Vim { if !search_bar.show(window, cx) { return None; } - let Some(query) = search_bar - .query_suggestion(window, cx) - .or_else(|| cursor_word) - else { + let Some(query) = search_bar.query_suggestion(true, window, cx) else { drop(search_bar.search("", None, false, window, cx)); return None; }; diff --git a/crates/vim/src/vim.rs b/crates/vim/src/vim.rs index ce0a83258910294432b501d3847a88e19f334b24..987def8a1ce63ffc0cf58dd63e4a1eb3cd4ddb60 100644 --- a/crates/vim/src/vim.rs +++ b/crates/vim/src/vim.rs @@ -33,9 +33,7 @@ use gpui::{ KeystrokeEvent, Render, Subscription, Task, WeakEntity, Window, actions, }; use insert::{NormalBefore, TemporaryNormal}; -use language::{ - CharKind, CharScopeContext, CursorShape, Point, Selection, SelectionGoal, TransactionId, -}; +use language::{CursorShape, Point, Selection, SelectionGoal, TransactionId}; pub use mode_indicator::ModeIndicator; use motion::Motion; use multi_buffer::ToPoint as _; @@ -1595,32 +1593,6 @@ impl Vim { .unwrap_or_default() } - fn editor_cursor_word( - &mut self, - window: &mut Window, - cx: &mut Context, - ) -> Option { - self.update_editor(cx, |_, editor, cx| { - let snapshot = &editor.snapshot(window, cx); - let selection = editor - .selections - .newest::(&snapshot.display_snapshot); - - let snapshot = snapshot.buffer_snapshot(); - let (range, kind) = - snapshot.surrounding_word(selection.start, Some(CharScopeContext::Completion)); - if kind == Some(CharKind::Word) { - let text: String = snapshot.text_for_range(range).collect(); - if !text.trim().is_empty() { - return Some(text); - } - } - - None - }) - .unwrap_or_default() - } - /// When doing an action that modifies the buffer, we start recording so that `.` /// will replay the action. pub fn start_recording(&mut self, cx: &mut Context) { diff --git a/crates/workspace/src/searchable.rs b/crates/workspace/src/searchable.rs index f0932a7d7b3e7880c27b40c28890f063f4de731e..1e6899868334a3a860b4e32610f0e2e5dc2ba83f 100644 --- a/crates/workspace/src/searchable.rs +++ b/crates/workspace/src/searchable.rs @@ -116,7 +116,12 @@ pub trait SearchableItem: Item + EventEmitter { window: &mut Window, cx: &mut Context, ); - fn query_suggestion(&mut self, window: &mut Window, cx: &mut Context) -> String; + fn query_suggestion( + &mut self, + ignore_settings: bool, + window: &mut Window, + cx: &mut Context, + ) -> String; fn activate_match( &mut self, index: usize, @@ -221,7 +226,7 @@ pub trait SearchableItemHandle: ItemHandle { window: &mut Window, cx: &mut App, ); - fn query_suggestion(&self, window: &mut Window, cx: &mut App) -> String; + fn query_suggestion(&self, ignore_settings: bool, window: &mut Window, cx: &mut App) -> String; fn activate_match( &self, index: usize, @@ -335,8 +340,10 @@ impl SearchableItemHandle for Entity { this.update_matches(matches.as_slice(), active_match_index, token, window, cx) }); } - fn query_suggestion(&self, window: &mut Window, cx: &mut App) -> String { - self.update(cx, |this, cx| this.query_suggestion(window, cx)) + fn query_suggestion(&self, ignore_settings: bool, window: &mut Window, cx: &mut App) -> String { + self.update(cx, |this, cx| { + this.query_suggestion(ignore_settings, window, cx) + }) } fn activate_match( &self, diff --git a/crates/zed_actions/src/lib.rs b/crates/zed_actions/src/lib.rs index c2e59fcddb00d1341d38162f0958b6cd71b832c6..f09fa27ddf267d1f208c5c89f9d5efaa5fde0b9c 100644 --- a/crates/zed_actions/src/lib.rs +++ b/crates/zed_actions/src/lib.rs @@ -467,7 +467,9 @@ pub mod buffer_search { /// Dismisses the search bar. Dismiss, /// Focuses back on the editor. - FocusEditor + FocusEditor, + /// Sets the search query to the current selection without opening the search bar or running a search. + UseSelectionForFind, ] ); }