diff --git a/assets/settings/default.json b/assets/settings/default.json index f62cc1844732db2a49dc835a155e861f4268632f..9e560998098c9f9617eb29f7b5d8aefd140f45b4 100644 --- a/assets/settings/default.json +++ b/assets/settings/default.json @@ -602,7 +602,9 @@ "whole_word": false, "case_sensitive": false, "include_ignored": false, - "regex": false + "regex": false, + // Whether to center the cursor on each search match when navigating. + "center_on_match": false }, // When to populate a new search's query based on the text under the cursor. // This setting can take the following three values: diff --git a/crates/editor/src/editor_settings.rs b/crates/editor/src/editor_settings.rs index dc67ab3ed6c8cfdbe88809e32d615789c01eef60..1a84631aa5a0a91a0ec56c0aab7ca58b51facbb1 100644 --- a/crates/editor/src/editor_settings.rs +++ b/crates/editor/src/editor_settings.rs @@ -159,6 +159,7 @@ pub struct SearchSettings { pub case_sensitive: bool, pub include_ignored: bool, pub regex: bool, + pub center_on_match: bool, } impl EditorSettings { @@ -249,6 +250,7 @@ impl Settings for EditorSettings { case_sensitive: search.case_sensitive.unwrap(), include_ignored: search.include_ignored.unwrap(), regex: search.regex.unwrap(), + center_on_match: search.center_on_match.unwrap(), }, auto_signature_help: editor.auto_signature_help.unwrap(), show_signature_help_after_edits: editor.show_signature_help_after_edits.unwrap(), diff --git a/crates/editor/src/items.rs b/crates/editor/src/items.rs index c064e3dbaf2873fef03d65dbd5794e6453599cec..726ac800d601f8d98055d4e577b3af4f9ed436e2 100644 --- a/crates/editor/src/items.rs +++ b/crates/editor/src/items.rs @@ -1593,7 +1593,12 @@ impl SearchableItem for Editor { ) { self.unfold_ranges(&[matches[index].clone()], false, true, cx); let range = self.range_for_match(&matches[index], collapse); - self.change_selections(Default::default(), window, cx, |s| { + let autoscroll = if EditorSettings::get_global(cx).search.center_on_match { + Autoscroll::center() + } else { + Autoscroll::fit() + }; + self.change_selections(SelectionEffects::scroll(autoscroll), window, cx, |s| { s.select_ranges([range]); }) } diff --git a/crates/search/src/buffer_search.rs b/crates/search/src/buffer_search.rs index f01073b6228ed3d314990187e63262a111f365c5..cd25c6c1bff63839a3f15a2d1cd50f7f55987a74 100644 --- a/crates/search/src/buffer_search.rs +++ b/crates/search/src/buffer_search.rs @@ -2813,6 +2813,7 @@ mod tests { case_sensitive: false, include_ignored: false, regex: false, + center_on_match: false, }, cx, ); @@ -2875,6 +2876,7 @@ mod tests { case_sensitive: true, include_ignored: false, regex: false, + center_on_match: false, }, cx, ); @@ -2912,6 +2914,7 @@ mod tests { case_sensitive: true, include_ignored: false, regex: false, + center_on_match: false, }, cx, ); @@ -2938,6 +2941,7 @@ mod tests { case_sensitive: Some(search_settings.case_sensitive), include_ignored: Some(search_settings.include_ignored), regex: Some(search_settings.regex), + center_on_match: Some(search_settings.center_on_match), }); }); }); diff --git a/crates/search/src/project_search.rs b/crates/search/src/project_search.rs index 042b58db0460f18668624b0ee8d3343e748244aa..9ee92c73008338e0ee655f3d02cb1dcbf1a3326b 100644 --- a/crates/search/src/project_search.rs +++ b/crates/search/src/project_search.rs @@ -12,7 +12,9 @@ use editor::{ SelectionEffects, VimFlavor, actions::{Backtab, SelectAll, Tab}, items::active_match_index, - multibuffer_context_lines, vim_flavor, + multibuffer_context_lines, + scroll::Autoscroll, + vim_flavor, }; use futures::{StreamExt, stream::FuturesOrdered}; use gpui::{ @@ -1346,8 +1348,13 @@ impl ProjectSearchView { self.results_editor.update(cx, |editor, cx| { let collapse = vim_flavor(cx) == Some(VimFlavor::Vim); let range_to_select = editor.range_for_match(&range_to_select, collapse); + let autoscroll = if EditorSettings::get_global(cx).search.center_on_match { + Autoscroll::center() + } else { + Autoscroll::fit() + }; editor.unfold_ranges(std::slice::from_ref(&range_to_select), false, true, cx); - editor.change_selections(Default::default(), window, cx, |s| { + editor.change_selections(SelectionEffects::scroll(autoscroll), window, cx, |s| { s.select_ranges([range_to_select]) }); }); diff --git a/crates/settings/src/settings_content/editor.rs b/crates/settings/src/settings_content/editor.rs index 920f02a0f6597454c82d421247787e8ad6f7f74b..d1f6347e4d86f301f64e3ec01c3932f9e7bf3bd3 100644 --- a/crates/settings/src/settings_content/editor.rs +++ b/crates/settings/src/settings_content/editor.rs @@ -699,6 +699,8 @@ pub struct SearchSettingsContent { pub case_sensitive: Option, pub include_ignored: Option, pub regex: Option, + /// Whether to center the cursor on each search match when navigating. + pub center_on_match: Option, } #[skip_serializing_none] diff --git a/crates/settings_ui/src/page_data.rs b/crates/settings_ui/src/page_data.rs index 8075e6396ae0011d00f7a9a65fc3732c08823787..5f1282a9a2e612c7d759231ff6ec84c06ae11e18 100644 --- a/crates/settings_ui/src/page_data.rs +++ b/crates/settings_ui/src/page_data.rs @@ -2450,6 +2450,29 @@ pub(crate) fn settings_data(cx: &App) -> Vec { metadata: None, files: USER, }), + SettingsPageItem::SettingItem(SettingItem { + title: "Center on Match", + description: "Whether to center the current match in the editor", + field: Box::new(SettingField { + json_path: Some("editor.search.center_on_match"), + pick: |settings_content| { + settings_content + .editor + .search + .as_ref() + .and_then(|search| search.center_on_match.as_ref()) + }, + write: |settings_content, value| { + settings_content + .editor + .search + .get_or_insert_default() + .center_on_match = value; + }, + }), + metadata: None, + files: USER, + }), SettingsPageItem::SettingItem(SettingItem { title: "Seed Search Query From Cursor", description: "When to populate a new search's query based on the text under the cursor.", diff --git a/docs/src/configuring-zed.md b/docs/src/configuring-zed.md index 054b6b1b5c812bed95dc7db6e63522b11b86c09c..77906a83a499a2e09ebbb93842545075bd46b8a7 100644 --- a/docs/src/configuring-zed.md +++ b/docs/src/configuring-zed.md @@ -3163,6 +3163,12 @@ Non-negative `integer` values - Setting: `search_wrap` - Default: `true` +## Center on Match + +- Description: If `center_on_match` is enabled, the editor will center the cursor on the current match when searching. +- Setting: `center_on_match` +- Default: `false` + ## Seed Search Query From Cursor - Description: When to populate a new search's query based on the text under the cursor.