Add a way to configure default search options (#17179)
Closes https://github.com/zed-industries/zed/issues/4646 ```json // Search options to enable by default when opening new project and buffer searches. "search": { "whole_word": false, "case_sensitive": false, "include_ignored": false, "regex": false } ``` Release Notes: - Added `search` settings section to configure default options enabled in buffer and project searches ([#4646](https://github.com/zed-industries/zed/issues/4646)) --------- Co-authored-by: Kirill Bulatov <mail4score@gmail.com>
This commit is contained in:
parent
8985fd87c2
commit
65961b80fc
8 changed files with 85 additions and 8 deletions
|
@ -279,6 +279,13 @@
|
||||||
"relative_line_numbers": false,
|
"relative_line_numbers": false,
|
||||||
// If 'search_wrap' is disabled, search result do not wrap around the end of the file.
|
// If 'search_wrap' is disabled, search result do not wrap around the end of the file.
|
||||||
"search_wrap": true,
|
"search_wrap": true,
|
||||||
|
// Search options to enable by default when opening new project and buffer searches.
|
||||||
|
"search": {
|
||||||
|
"whole_word": false,
|
||||||
|
"case_sensitive": false,
|
||||||
|
"include_ignored": false,
|
||||||
|
"regex": false
|
||||||
|
},
|
||||||
// When to populate a new search's query based on the text under the cursor.
|
// When to populate a new search's query based on the text under the cursor.
|
||||||
// This setting can take the following three values:
|
// This setting can take the following three values:
|
||||||
//
|
//
|
||||||
|
|
|
@ -59,7 +59,9 @@ use convert_case::{Case, Casing};
|
||||||
use debounced_delay::DebouncedDelay;
|
use debounced_delay::DebouncedDelay;
|
||||||
use display_map::*;
|
use display_map::*;
|
||||||
pub use display_map::{DisplayPoint, FoldPlaceholder};
|
pub use display_map::{DisplayPoint, FoldPlaceholder};
|
||||||
pub use editor_settings::{CurrentLineHighlight, EditorSettings, ScrollBeyondLastLine};
|
pub use editor_settings::{
|
||||||
|
CurrentLineHighlight, EditorSettings, ScrollBeyondLastLine, SearchSettings,
|
||||||
|
};
|
||||||
pub use editor_settings_controls::*;
|
pub use editor_settings_controls::*;
|
||||||
use element::LineWithInvisibles;
|
use element::LineWithInvisibles;
|
||||||
pub use element::{
|
pub use element::{
|
||||||
|
|
|
@ -28,6 +28,8 @@ pub struct EditorSettings {
|
||||||
#[serde(default)]
|
#[serde(default)]
|
||||||
pub double_click_in_multibuffer: DoubleClickInMultibuffer,
|
pub double_click_in_multibuffer: DoubleClickInMultibuffer,
|
||||||
pub search_wrap: bool,
|
pub search_wrap: bool,
|
||||||
|
#[serde(default)]
|
||||||
|
pub search: SearchSettings,
|
||||||
pub auto_signature_help: bool,
|
pub auto_signature_help: bool,
|
||||||
pub show_signature_help_after_edits: bool,
|
pub show_signature_help_after_edits: bool,
|
||||||
pub jupyter: Jupyter,
|
pub jupyter: Jupyter,
|
||||||
|
@ -156,6 +158,40 @@ pub enum ScrollBeyondLastLine {
|
||||||
VerticalScrollMargin,
|
VerticalScrollMargin,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Default options for buffer and project search items.
|
||||||
|
#[derive(Copy, Clone, Default, Debug, Serialize, Deserialize, JsonSchema, PartialEq, Eq)]
|
||||||
|
pub struct SearchSettings {
|
||||||
|
#[serde(default)]
|
||||||
|
pub whole_word: bool,
|
||||||
|
#[serde(default)]
|
||||||
|
pub case_sensitive: bool,
|
||||||
|
#[serde(default)]
|
||||||
|
pub include_ignored: bool,
|
||||||
|
#[serde(default)]
|
||||||
|
pub regex: bool,
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Clone, Default, Serialize, Deserialize, JsonSchema, Debug)]
|
||||||
|
pub struct SearchSettingsContent {
|
||||||
|
pub whole_word: Option<bool>,
|
||||||
|
pub case_sensitive: Option<bool>,
|
||||||
|
pub include_ignored: Option<bool>,
|
||||||
|
pub regex: Option<bool>,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Settings for SearchSettings {
|
||||||
|
const KEY: Option<&'static str> = Some("search");
|
||||||
|
|
||||||
|
type FileContent = SearchSettingsContent;
|
||||||
|
|
||||||
|
fn load(
|
||||||
|
sources: SettingsSources<Self::FileContent>,
|
||||||
|
_: &mut gpui::AppContext,
|
||||||
|
) -> anyhow::Result<Self> {
|
||||||
|
sources.json_merge()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
#[derive(Clone, Default, Serialize, Deserialize, JsonSchema)]
|
#[derive(Clone, Default, Serialize, Deserialize, JsonSchema)]
|
||||||
pub struct EditorSettingsContent {
|
pub struct EditorSettingsContent {
|
||||||
/// Whether the cursor blinks in the editor.
|
/// Whether the cursor blinks in the editor.
|
||||||
|
@ -251,6 +287,11 @@ pub struct EditorSettingsContent {
|
||||||
/// Default: true
|
/// Default: true
|
||||||
pub search_wrap: Option<bool>,
|
pub search_wrap: Option<bool>,
|
||||||
|
|
||||||
|
/// Defaults to use when opening a new buffer and project search items.
|
||||||
|
///
|
||||||
|
/// Default: nothing is enabled
|
||||||
|
pub search: Option<SearchSettings>,
|
||||||
|
|
||||||
/// Whether to automatically show a signature help pop-up or not.
|
/// Whether to automatically show a signature help pop-up or not.
|
||||||
///
|
///
|
||||||
/// Default: false
|
/// Default: false
|
||||||
|
|
|
@ -9,7 +9,7 @@ use any_vec::AnyVec;
|
||||||
use collections::HashMap;
|
use collections::HashMap;
|
||||||
use editor::{
|
use editor::{
|
||||||
actions::{Tab, TabPrev},
|
actions::{Tab, TabPrev},
|
||||||
DisplayPoint, Editor, EditorElement, EditorSettings, EditorStyle,
|
DisplayPoint, Editor, EditorElement, EditorSettings, EditorStyle, SearchSettings,
|
||||||
};
|
};
|
||||||
use futures::channel::oneshot;
|
use futures::channel::oneshot;
|
||||||
use gpui::{
|
use gpui::{
|
||||||
|
@ -22,7 +22,7 @@ use project::{
|
||||||
search_history::{SearchHistory, SearchHistoryCursor},
|
search_history::{SearchHistory, SearchHistoryCursor},
|
||||||
};
|
};
|
||||||
use serde::Deserialize;
|
use serde::Deserialize;
|
||||||
use settings::Settings;
|
use settings::{Settings, SettingsStore};
|
||||||
use std::sync::Arc;
|
use std::sync::Arc;
|
||||||
use theme::ThemeSettings;
|
use theme::ThemeSettings;
|
||||||
|
|
||||||
|
@ -96,6 +96,7 @@ pub struct BufferSearchBar {
|
||||||
scroll_handle: ScrollHandle,
|
scroll_handle: ScrollHandle,
|
||||||
editor_scroll_handle: ScrollHandle,
|
editor_scroll_handle: ScrollHandle,
|
||||||
editor_needed_width: Pixels,
|
editor_needed_width: Pixels,
|
||||||
|
_subscriptions: Vec<Subscription>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl BufferSearchBar {
|
impl BufferSearchBar {
|
||||||
|
@ -505,6 +506,12 @@ impl BufferSearchBar {
|
||||||
cx.subscribe(&replacement_editor, Self::on_replacement_editor_event)
|
cx.subscribe(&replacement_editor, Self::on_replacement_editor_event)
|
||||||
.detach();
|
.detach();
|
||||||
|
|
||||||
|
let search_options = SearchOptions::from_settings(&SearchSettings::get_global(cx));
|
||||||
|
|
||||||
|
let settings_subscription = cx.observe_global::<SettingsStore>(move |this, cx| {
|
||||||
|
this.default_options = SearchOptions::from_settings(&SearchSettings::get_global(cx));
|
||||||
|
});
|
||||||
|
|
||||||
Self {
|
Self {
|
||||||
query_editor,
|
query_editor,
|
||||||
query_editor_focused: false,
|
query_editor_focused: false,
|
||||||
|
@ -514,8 +521,8 @@ impl BufferSearchBar {
|
||||||
active_searchable_item_subscription: None,
|
active_searchable_item_subscription: None,
|
||||||
active_match_index: None,
|
active_match_index: None,
|
||||||
searchable_items_with_matches: Default::default(),
|
searchable_items_with_matches: Default::default(),
|
||||||
default_options: SearchOptions::NONE,
|
default_options: search_options,
|
||||||
search_options: SearchOptions::NONE,
|
search_options,
|
||||||
pending_search: None,
|
pending_search: None,
|
||||||
query_contains_error: false,
|
query_contains_error: false,
|
||||||
dismissed: true,
|
dismissed: true,
|
||||||
|
@ -530,6 +537,7 @@ impl BufferSearchBar {
|
||||||
scroll_handle: ScrollHandle::new(),
|
scroll_handle: ScrollHandle::new(),
|
||||||
editor_scroll_handle: ScrollHandle::new(),
|
editor_scroll_handle: ScrollHandle::new(),
|
||||||
editor_needed_width: px(0.),
|
editor_needed_width: px(0.),
|
||||||
|
_subscriptions: vec![settings_subscription],
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -602,6 +610,9 @@ impl BufferSearchBar {
|
||||||
let Some(handle) = self.active_searchable_item.as_ref() else {
|
let Some(handle) = self.active_searchable_item.as_ref() else {
|
||||||
return false;
|
return false;
|
||||||
};
|
};
|
||||||
|
if self.default_options != self.search_options {
|
||||||
|
self.search_options = self.default_options;
|
||||||
|
}
|
||||||
|
|
||||||
self.dismissed = false;
|
self.dismissed = false;
|
||||||
handle.search_bar_visibility_changed(true, cx);
|
handle.search_bar_visibility_changed(true, cx);
|
||||||
|
@ -1203,6 +1214,7 @@ mod tests {
|
||||||
language::init(cx);
|
language::init(cx);
|
||||||
Project::init_settings(cx);
|
Project::init_settings(cx);
|
||||||
theme::init(theme::LoadThemes::JustBase, cx);
|
theme::init(theme::LoadThemes::JustBase, cx);
|
||||||
|
crate::init(cx);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -668,7 +668,9 @@ impl ProjectSearchView {
|
||||||
let (mut options, filters_enabled) = if let Some(settings) = settings {
|
let (mut options, filters_enabled) = if let Some(settings) = settings {
|
||||||
(settings.search_options, settings.filters_enabled)
|
(settings.search_options, settings.filters_enabled)
|
||||||
} else {
|
} else {
|
||||||
(SearchOptions::NONE, false)
|
let search_options =
|
||||||
|
SearchOptions::from_settings(&EditorSettings::get_global(cx).search);
|
||||||
|
(search_options, false)
|
||||||
};
|
};
|
||||||
|
|
||||||
{
|
{
|
||||||
|
@ -3537,7 +3539,7 @@ pub mod tests {
|
||||||
editor::init(cx);
|
editor::init(cx);
|
||||||
workspace::init_settings(cx);
|
workspace::init_settings(cx);
|
||||||
Project::init_settings(cx);
|
Project::init_settings(cx);
|
||||||
super::init(cx);
|
crate::init(cx);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -1,8 +1,10 @@
|
||||||
use bitflags::bitflags;
|
use bitflags::bitflags;
|
||||||
pub use buffer_search::BufferSearchBar;
|
pub use buffer_search::BufferSearchBar;
|
||||||
|
use editor::SearchSettings;
|
||||||
use gpui::{actions, Action, AppContext, IntoElement};
|
use gpui::{actions, Action, AppContext, IntoElement};
|
||||||
use project::search::SearchQuery;
|
use project::search::SearchQuery;
|
||||||
pub use project_search::ProjectSearchView;
|
pub use project_search::ProjectSearchView;
|
||||||
|
use settings::Settings;
|
||||||
use ui::{prelude::*, Tooltip};
|
use ui::{prelude::*, Tooltip};
|
||||||
use ui::{ButtonStyle, IconButton};
|
use ui::{ButtonStyle, IconButton};
|
||||||
use workspace::notifications::NotificationId;
|
use workspace::notifications::NotificationId;
|
||||||
|
@ -13,6 +15,7 @@ pub mod project_search;
|
||||||
pub(crate) mod search_bar;
|
pub(crate) mod search_bar;
|
||||||
|
|
||||||
pub fn init(cx: &mut AppContext) {
|
pub fn init(cx: &mut AppContext) {
|
||||||
|
SearchSettings::register(cx);
|
||||||
menu::init();
|
menu::init();
|
||||||
buffer_search::init(cx);
|
buffer_search::init(cx);
|
||||||
project_search::init(cx);
|
project_search::init(cx);
|
||||||
|
@ -93,6 +96,15 @@ impl SearchOptions {
|
||||||
options
|
options
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn from_settings(settings: &SearchSettings) -> SearchOptions {
|
||||||
|
let mut options = SearchOptions::NONE;
|
||||||
|
options.set(SearchOptions::WHOLE_WORD, settings.whole_word);
|
||||||
|
options.set(SearchOptions::CASE_SENSITIVE, settings.case_sensitive);
|
||||||
|
options.set(SearchOptions::INCLUDE_IGNORED, settings.include_ignored);
|
||||||
|
options.set(SearchOptions::REGEX, settings.regex);
|
||||||
|
options
|
||||||
|
}
|
||||||
|
|
||||||
pub fn as_button(
|
pub fn as_button(
|
||||||
&self,
|
&self,
|
||||||
active: bool,
|
active: bool,
|
||||||
|
|
|
@ -16,12 +16,12 @@ impl VimTestContext {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
cx.update(|cx| {
|
cx.update(|cx| {
|
||||||
search::init(cx);
|
|
||||||
let settings = SettingsStore::test(cx);
|
let settings = SettingsStore::test(cx);
|
||||||
cx.set_global(settings);
|
cx.set_global(settings);
|
||||||
release_channel::init(SemanticVersion::default(), cx);
|
release_channel::init(SemanticVersion::default(), cx);
|
||||||
command_palette::init(cx);
|
command_palette::init(cx);
|
||||||
crate::init(cx);
|
crate::init(cx);
|
||||||
|
search::init(cx);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -3442,6 +3442,7 @@ mod tests {
|
||||||
);
|
);
|
||||||
tasks_ui::init(cx);
|
tasks_ui::init(cx);
|
||||||
initialize_workspace(app_state.clone(), prompt_builder, cx);
|
initialize_workspace(app_state.clone(), prompt_builder, cx);
|
||||||
|
search::init(cx);
|
||||||
app_state
|
app_state
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue