Detailed changes
@@ -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",
@@ -1028,9 +1028,14 @@ impl SearchableItem for DapLogView {
})
}
- fn query_suggestion(&mut self, window: &mut Window, cx: &mut Context<Self>) -> String {
+ fn query_suggestion(
+ &mut self,
+ ignore_settings: bool,
+ window: &mut Window,
+ cx: &mut Context<Self>,
+ ) -> 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(
@@ -1660,8 +1660,17 @@ impl SearchableItem for Editor {
}
}
- fn query_suggestion(&mut self, window: &mut Window, cx: &mut Context<Self>) -> 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<Self>,
+ ) -> 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();
@@ -1901,9 +1901,15 @@ impl SearchableItem for SplittableEditor {
}
}
- fn query_suggestion(&mut self, window: &mut Window, cx: &mut Context<Self>) -> 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<Self>,
+ ) -> String {
+ self.focused_editor().update(cx, |editor, cx| {
+ editor.query_suggestion(ignore_settings, window, cx)
+ })
}
fn activate_match(
@@ -822,9 +822,14 @@ impl SearchableItem for LspLogView {
})
}
- fn query_suggestion(&mut self, window: &mut Window, cx: &mut Context<Self>) -> String {
+ fn query_suggestion(
+ &mut self,
+ ignore_settings: bool,
+ window: &mut Window,
+ cx: &mut Context<Self>,
+ ) -> 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(
@@ -956,7 +956,12 @@ impl SearchableItem for MarkdownPreviewView {
}
}
- fn query_suggestion(&mut self, _window: &mut Window, cx: &mut Context<Self>) -> String {
+ fn query_suggestion(
+ &mut self,
+ _ignore_settings: bool,
+ _window: &mut Window,
+ cx: &mut Context<Self>,
+ ) -> String {
self.markdown.read(cx).selected_text().unwrap_or_default()
}
@@ -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<Self>) {
- 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<Self>,
) -> Option<String> {
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<Self>,
+ ) {
+ 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<Self>) {
if let Some(active_editor) = self.active_searchable_item.as_ref() {
let handle = active_editor.item_focus_handle(cx);
@@ -1181,7 +1181,7 @@ impl ProjectSearchView {
}
let editor = item.act_as::<Editor>(cx)?;
- let query = editor.query_suggestion(window, cx);
+ let query = editor.query_suggestion(false, window, cx);
if query.is_empty() { None } else { Some(query) }
});
@@ -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<Self>) -> String {
+ fn query_suggestion(
+ &mut self,
+ _ignore_settings: bool,
+ _window: &mut Window,
+ cx: &mut Context<Self>,
+ ) -> String {
self.terminal()
.read(cx)
.last_content
@@ -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;
};
@@ -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<Self>,
- ) -> Option<String> {
- self.update_editor(cx, |_, editor, cx| {
- let snapshot = &editor.snapshot(window, cx);
- let selection = editor
- .selections
- .newest::<MultiBufferOffset>(&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<Self>) {
@@ -116,7 +116,12 @@ pub trait SearchableItem: Item + EventEmitter<SearchEvent> {
window: &mut Window,
cx: &mut Context<Self>,
);
- fn query_suggestion(&mut self, window: &mut Window, cx: &mut Context<Self>) -> String;
+ fn query_suggestion(
+ &mut self,
+ ignore_settings: bool,
+ window: &mut Window,
+ cx: &mut Context<Self>,
+ ) -> 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<T: SearchableItem> SearchableItemHandle for Entity<T> {
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,
@@ -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,
]
);
}