refactor: implement case sensitive pattern items in search query
In order to simplify the implementation of pattern items in search queries, this commit updates the `project::search::SearchQuery::regex` function so as to support both `\\c` and `\\C` in the provided query. This means that we no longer need to have both `BufferSearchBar` and `ProjectSearchView` handling pattern items, so the `search::pattern_items` module can now safely be removed. It's worth noting that, since these are now handled at the `SearchQuery` level, this removes the updates to the UI regarding search options, that were being triggered by the pattern items being processed and applied to the search options. Co-authored-by: Conrad Irwin <conrad.irwin@gmail.com>
This commit is contained in:
parent
d28e52d9e7
commit
c69f4f49f0
3 changed files with 142 additions and 330 deletions
|
@ -143,7 +143,7 @@ impl SearchQuery {
|
|||
pub fn regex(
|
||||
query: impl ToString,
|
||||
whole_word: bool,
|
||||
case_sensitive: bool,
|
||||
mut case_sensitive: bool,
|
||||
include_ignored: bool,
|
||||
one_match_per_line: bool,
|
||||
files_to_include: PathMatcher,
|
||||
|
@ -153,6 +153,14 @@ impl SearchQuery {
|
|||
) -> Result<Self> {
|
||||
let mut query = query.to_string();
|
||||
let initial_query = Arc::from(query.as_str());
|
||||
|
||||
if let Some((case_sensitive_from_pattern, new_query)) =
|
||||
Self::case_sensitive_from_pattern(&query)
|
||||
{
|
||||
case_sensitive = case_sensitive_from_pattern;
|
||||
query = new_query
|
||||
}
|
||||
|
||||
if whole_word {
|
||||
let mut word_query = String::new();
|
||||
if let Some(first) = query.get(0..1)
|
||||
|
@ -192,6 +200,45 @@ impl SearchQuery {
|
|||
})
|
||||
}
|
||||
|
||||
/// Extracts case sensitivity settings from pattern items in the provided
|
||||
/// query and returns the same query, with the pattern items removed.
|
||||
///
|
||||
/// The following pattern modifiers are supported:
|
||||
///
|
||||
/// - `\c` (case_sensitive: false)
|
||||
/// - `\C` (case_sensitive: true)
|
||||
///
|
||||
/// If no pattern item were found, `None` will be returned.
|
||||
fn case_sensitive_from_pattern(query: &str) -> Option<(bool, String)> {
|
||||
if !(query.contains("\\c") || query.contains("\\C")) {
|
||||
return None;
|
||||
}
|
||||
|
||||
let mut was_escaped = false;
|
||||
let mut new_query = String::new();
|
||||
let mut is_case_sensitive = None;
|
||||
|
||||
for c in query.chars() {
|
||||
if was_escaped {
|
||||
if c == 'c' {
|
||||
is_case_sensitive = Some(false);
|
||||
} else if c == 'C' {
|
||||
is_case_sensitive = Some(true);
|
||||
} else {
|
||||
new_query.push('\\');
|
||||
new_query.push(c);
|
||||
}
|
||||
was_escaped = false
|
||||
} else if c == '\\' {
|
||||
was_escaped = true
|
||||
} else {
|
||||
new_query.push(c);
|
||||
}
|
||||
}
|
||||
|
||||
is_case_sensitive.map(|c| (c, new_query))
|
||||
}
|
||||
|
||||
pub fn from_proto(message: proto::SearchQuery) -> Result<Self> {
|
||||
let files_to_include = if message.files_to_include.is_empty() {
|
||||
message
|
||||
|
@ -596,4 +643,87 @@ mod tests {
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_case_sensitive_pattern_items() {
|
||||
let case_sensitive = false;
|
||||
let search_query = SearchQuery::regex(
|
||||
"test\\C",
|
||||
false,
|
||||
case_sensitive,
|
||||
false,
|
||||
false,
|
||||
Default::default(),
|
||||
Default::default(),
|
||||
false,
|
||||
None,
|
||||
)
|
||||
.expect("Should be able to create a regex SearchQuery");
|
||||
|
||||
assert_eq!(
|
||||
search_query.case_sensitive(),
|
||||
true,
|
||||
"Case sensitivity should be enabled when \\C pattern item is present in the query."
|
||||
);
|
||||
|
||||
let case_sensitive = true;
|
||||
let search_query = SearchQuery::regex(
|
||||
"test\\c",
|
||||
true,
|
||||
case_sensitive,
|
||||
false,
|
||||
false,
|
||||
Default::default(),
|
||||
Default::default(),
|
||||
false,
|
||||
None,
|
||||
)
|
||||
.expect("Should be able to create a regex SearchQuery");
|
||||
|
||||
assert_eq!(
|
||||
search_query.case_sensitive(),
|
||||
false,
|
||||
"Case sensitivity should be disabled when \\c pattern item is present, even if initially set to true."
|
||||
);
|
||||
|
||||
let case_sensitive = false;
|
||||
let search_query = SearchQuery::regex(
|
||||
"test\\c\\C",
|
||||
false,
|
||||
case_sensitive,
|
||||
false,
|
||||
false,
|
||||
Default::default(),
|
||||
Default::default(),
|
||||
false,
|
||||
None,
|
||||
)
|
||||
.expect("Should be able to create a regex SearchQuery");
|
||||
|
||||
assert_eq!(
|
||||
search_query.case_sensitive(),
|
||||
true,
|
||||
"Case sensitivity should be enabled when \\C is the last pattern item, even after a \\c."
|
||||
);
|
||||
|
||||
let case_sensitive = false;
|
||||
let search_query = SearchQuery::regex(
|
||||
"tests\\\\C",
|
||||
false,
|
||||
case_sensitive,
|
||||
false,
|
||||
false,
|
||||
Default::default(),
|
||||
Default::default(),
|
||||
false,
|
||||
None,
|
||||
)
|
||||
.expect("Should be able to create a regex SearchQuery");
|
||||
|
||||
assert_eq!(
|
||||
search_query.case_sensitive(),
|
||||
false,
|
||||
"Case sensitivity should not be enabled when \\C pattern item is preceded by a backslash."
|
||||
);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -4,7 +4,6 @@ use crate::{
|
|||
FocusSearch, NextHistoryQuery, PreviousHistoryQuery, ReplaceAll, ReplaceNext, SearchOption,
|
||||
SearchOptions, SearchSource, SelectAllMatches, SelectNextMatch, SelectPreviousMatch,
|
||||
ToggleCaseSensitive, ToggleRegex, ToggleReplace, ToggleSelection, ToggleWholeWord,
|
||||
pattern_items::PatternItems,
|
||||
search_bar::{ActionButtonState, input_base_styles, render_action_button, render_text_input},
|
||||
};
|
||||
use any_vec::AnyVec;
|
||||
|
@ -112,10 +111,6 @@ pub struct BufferSearchBar {
|
|||
pending_search: Option<Task<()>>,
|
||||
search_options: SearchOptions,
|
||||
default_options: SearchOptions,
|
||||
/// Pattern items that have been applied from the query to the search
|
||||
/// options. Tracking these allows us to revert the search options to their
|
||||
/// original state as pattern items are removed from the query.
|
||||
pattern_items: PatternItems,
|
||||
configured_options: SearchOptions,
|
||||
query_error: Option<String>,
|
||||
dismissed: bool,
|
||||
|
@ -660,7 +655,6 @@ impl BufferSearchBar {
|
|||
default_options: search_options,
|
||||
configured_options: search_options,
|
||||
search_options,
|
||||
pattern_items: Default::default(),
|
||||
pending_search: None,
|
||||
query_error: None,
|
||||
dismissed: true,
|
||||
|
@ -816,14 +810,9 @@ impl BufferSearchBar {
|
|||
});
|
||||
}
|
||||
|
||||
/// Returns the raw query string without any of the pattern items removed.
|
||||
pub fn raw_query(&self, cx: &App) -> String {
|
||||
self.query_editor.read(cx).text(cx)
|
||||
}
|
||||
|
||||
/// Returns the sanitized query string with pattern items removed.
|
||||
pub fn query(&self, cx: &App) -> String {
|
||||
PatternItems::clean_query(&self.raw_query(cx))
|
||||
self.query_editor.read(cx).text(cx)
|
||||
}
|
||||
|
||||
pub fn replacement(&self, cx: &mut App) -> String {
|
||||
|
@ -1055,7 +1044,6 @@ impl BufferSearchBar {
|
|||
editor::EditorEvent::Blurred => self.query_editor_focused = false,
|
||||
editor::EditorEvent::Edited { .. } => {
|
||||
self.smartcase(window, cx);
|
||||
self.apply_pattern_items(cx);
|
||||
self.clear_matches(window, cx);
|
||||
let search = self.update_matches(false, window, cx);
|
||||
|
||||
|
@ -1465,22 +1453,6 @@ impl BufferSearchBar {
|
|||
}
|
||||
}
|
||||
|
||||
// Determines which pattern items are present in the search query and
|
||||
// updates the search options accordingly, only if the regex search option
|
||||
// is enabled.
|
||||
fn apply_pattern_items(&mut self, cx: &mut Context<Self>) {
|
||||
if self.search_options.contains(SearchOptions::REGEX) {
|
||||
// Determine what the search options were before the pattern items
|
||||
// were applied, so we can reapply them and determine which ones
|
||||
// actually have an effect on the search options, which are the ones
|
||||
// we need to keep track of.
|
||||
let query = self.raw_query(cx);
|
||||
let search_options = self.pattern_items.revert(self.search_options);
|
||||
self.pattern_items = PatternItems::from_search_options(search_options, &query);
|
||||
self.set_search_options(self.pattern_items.apply(search_options), cx);
|
||||
}
|
||||
}
|
||||
|
||||
fn adjust_query_regex_language(&self, cx: &mut App) {
|
||||
let enable = self.search_options.contains(SearchOptions::REGEX);
|
||||
let query_buffer = self
|
||||
|
@ -2867,156 +2839,6 @@ mod tests {
|
|||
});
|
||||
}
|
||||
|
||||
#[gpui::test]
|
||||
async fn test_pattern_items(cx: &mut TestAppContext) {
|
||||
let (_editor, search_bar, cx) = init_test(cx);
|
||||
|
||||
update_search_settings(
|
||||
SearchSettings {
|
||||
button: true,
|
||||
whole_word: false,
|
||||
case_sensitive: false,
|
||||
include_ignored: false,
|
||||
regex: false,
|
||||
},
|
||||
cx,
|
||||
);
|
||||
|
||||
search_bar.update_in(cx, |search_bar, window, cx| {
|
||||
search_bar.show(window, cx);
|
||||
assert_eq!(
|
||||
search_bar.search_options,
|
||||
SearchOptions::NONE,
|
||||
"Should have no search options enabled by default"
|
||||
);
|
||||
|
||||
cx.focus_view(&search_bar.query_editor, window);
|
||||
});
|
||||
|
||||
cx.simulate_input("test\\C");
|
||||
|
||||
search_bar.update_in(cx, |search_bar, _, _| {
|
||||
assert_eq!(
|
||||
search_bar.search_options,
|
||||
SearchOptions::NONE,
|
||||
"Should not apply pattern items if regex not enabled"
|
||||
);
|
||||
});
|
||||
|
||||
cx.simulate_keystrokes("backspace backspace");
|
||||
|
||||
search_bar.update_in(cx, |search_bar, window, cx| {
|
||||
search_bar.toggle_search_option(SearchOptions::REGEX, window, cx);
|
||||
});
|
||||
|
||||
cx.simulate_input("\\C");
|
||||
|
||||
search_bar.update_in(cx, |search_bar, _, _| {
|
||||
assert_eq!(
|
||||
search_bar.search_options,
|
||||
SearchOptions::REGEX | SearchOptions::CASE_SENSITIVE,
|
||||
"Should have case sensitivity enabled when \\C pattern item is present and regex is enabled"
|
||||
);
|
||||
});
|
||||
|
||||
// Remove `\\C` from the query to check if the search option is
|
||||
// correctly reverted to its default state.
|
||||
cx.simulate_keystrokes("backspace backspace");
|
||||
search_bar.update_in(cx, |search_bar, window, cx| {
|
||||
assert_eq!(search_bar.raw_query(cx), "test");
|
||||
assert_eq!(
|
||||
search_bar.search_options,
|
||||
SearchOptions::REGEX,
|
||||
"Should have case sensitivity disabled when \\C pattern item is removed"
|
||||
);
|
||||
|
||||
search_bar.toggle_search_option(SearchOptions::CASE_SENSITIVE, window, cx);
|
||||
assert_eq!(
|
||||
search_bar.search_options,
|
||||
SearchOptions::REGEX | SearchOptions::CASE_SENSITIVE,
|
||||
"Should have case sensitivity enabled by default"
|
||||
);
|
||||
});
|
||||
cx.run_until_parked();
|
||||
|
||||
cx.simulate_input("\\c");
|
||||
cx.run_until_parked();
|
||||
search_bar.update(cx, |search_bar, cx| {
|
||||
assert_eq!(search_bar.raw_query(cx), "test\\c");
|
||||
assert_eq!(
|
||||
search_bar.search_options,
|
||||
SearchOptions::REGEX,
|
||||
"Should have no case sensitivity enabled when \\c pattern item is present"
|
||||
);
|
||||
});
|
||||
|
||||
cx.simulate_input("\\C");
|
||||
cx.run_until_parked();
|
||||
search_bar.update(cx, |search_bar, cx| {
|
||||
assert_eq!(search_bar.raw_query(cx), "test\\c\\C");
|
||||
assert_eq!(
|
||||
search_bar.search_options,
|
||||
SearchOptions::REGEX | SearchOptions::CASE_SENSITIVE,
|
||||
"Should have case sensitivity enabled when \\C pattern item is present, even if preceded by \\c"
|
||||
);
|
||||
});
|
||||
|
||||
cx.simulate_input("\\c");
|
||||
cx.run_until_parked();
|
||||
search_bar.update(cx, |search_bar, cx| {
|
||||
assert_eq!(search_bar.raw_query(cx), "test\\c\\C\\c");
|
||||
assert_eq!(
|
||||
search_bar.search_options,
|
||||
SearchOptions::REGEX,
|
||||
"Should have no case sensitivity enabled when \\c pattern item is present, even if preceded by \\C"
|
||||
);
|
||||
});
|
||||
|
||||
cx.simulate_keystrokes("backspace backspace");
|
||||
|
||||
search_bar.update(cx, |search_bar, cx| {
|
||||
assert_eq!(search_bar.raw_query(cx), "test\\c\\C");
|
||||
assert_eq!(
|
||||
search_bar.search_options,
|
||||
SearchOptions::REGEX | SearchOptions::CASE_SENSITIVE,
|
||||
"Should have case sensitivity enabled when suffix \\c pattern item is removed"
|
||||
);
|
||||
});
|
||||
|
||||
cx.simulate_keystrokes("backspace backspace");
|
||||
|
||||
search_bar.update(cx, |search_bar, cx| {
|
||||
assert_eq!(search_bar.raw_query(cx), "test\\c");
|
||||
assert_eq!(
|
||||
search_bar.search_options,
|
||||
SearchOptions::REGEX,
|
||||
"Should have case sensitivity disabled when suffix \\C pattern item is removed and a \\c pattern item is still present"
|
||||
);
|
||||
});
|
||||
|
||||
cx.simulate_keystrokes("backspace backspace");
|
||||
|
||||
search_bar.update(cx, |search_bar, cx| {
|
||||
assert_eq!(search_bar.raw_query(cx), "test");
|
||||
assert_eq!(
|
||||
search_bar.search_options,
|
||||
SearchOptions::REGEX | SearchOptions::CASE_SENSITIVE,
|
||||
"Should have case sensitivity enabled when all pattern items are removed and original search options are restored"
|
||||
);
|
||||
});
|
||||
|
||||
cx.simulate_input("\\\\c");
|
||||
cx.run_until_parked();
|
||||
search_bar.update(cx, |search_bar, cx| {
|
||||
assert_eq!(search_bar.raw_query(cx), "test\\\\c");
|
||||
assert_eq!(
|
||||
search_bar.search_options,
|
||||
SearchOptions::REGEX | SearchOptions::CASE_SENSITIVE,
|
||||
"Should still have case sensitivity enabled when pattern item is preceded by another \\"
|
||||
);
|
||||
});
|
||||
}
|
||||
|
||||
fn update_search_settings(search_settings: SearchSettings, cx: &mut TestAppContext) {
|
||||
cx.update(|cx| {
|
||||
SettingsStore::update_global(cx, |store, cx| {
|
||||
|
|
|
@ -3,7 +3,6 @@ use crate::{
|
|||
SearchOption, SearchOptions, SearchSource, SelectNextMatch, SelectPreviousMatch,
|
||||
ToggleCaseSensitive, ToggleIncludeIgnored, ToggleRegex, ToggleReplace, ToggleWholeWord,
|
||||
buffer_search::Deploy,
|
||||
pattern_items::PatternItems,
|
||||
search_bar::{ActionButtonState, input_base_styles, render_action_button, render_text_input},
|
||||
};
|
||||
use anyhow::Context as _;
|
||||
|
@ -211,7 +210,6 @@ pub struct ProjectSearchView {
|
|||
replacement_editor: Entity<Editor>,
|
||||
results_editor: Entity<Editor>,
|
||||
search_options: SearchOptions,
|
||||
pattern_items: PatternItems,
|
||||
panels_with_errors: HashMap<InputPanel, String>,
|
||||
active_match_index: Option<usize>,
|
||||
search_id: usize,
|
||||
|
@ -777,10 +775,9 @@ impl ProjectSearchView {
|
|||
// Subscribe to query_editor in order to reraise editor events for workspace item activation purposes
|
||||
subscriptions.push(
|
||||
cx.subscribe(&query_editor, |this, _, event: &EditorEvent, cx| {
|
||||
if let EditorEvent::Edited { .. } = event {
|
||||
this.apply_pattern_items(&this.search_query_text_raw(cx));
|
||||
|
||||
if EditorSettings::get_global(cx).use_smartcase_search {
|
||||
if let EditorEvent::Edited { .. } = event
|
||||
&& EditorSettings::get_global(cx).use_smartcase_search
|
||||
{
|
||||
let query = this.search_query_text(cx);
|
||||
if !query.is_empty()
|
||||
&& this.search_options.contains(SearchOptions::CASE_SENSITIVE)
|
||||
|
@ -789,7 +786,6 @@ impl ProjectSearchView {
|
|||
this.toggle_search_option(SearchOptions::CASE_SENSITIVE, cx);
|
||||
}
|
||||
}
|
||||
}
|
||||
cx.emit(ViewEvent::EditorEvent(event.clone()))
|
||||
}),
|
||||
);
|
||||
|
@ -884,7 +880,6 @@ impl ProjectSearchView {
|
|||
query_editor,
|
||||
results_editor,
|
||||
search_options: options,
|
||||
pattern_items: Default::default(),
|
||||
panels_with_errors: HashMap::default(),
|
||||
active_match_index: None,
|
||||
included_files_editor,
|
||||
|
@ -1138,14 +1133,9 @@ impl ProjectSearchView {
|
|||
}
|
||||
}
|
||||
|
||||
/// Returns the search query text with pattern items.
|
||||
fn search_query_text_raw(&self, cx: &App) -> String {
|
||||
self.query_editor.read(cx).text(cx)
|
||||
}
|
||||
|
||||
/// Returns the search query text without pattern items.
|
||||
pub fn search_query_text(&self, cx: &App) -> String {
|
||||
PatternItems::clean_query(&self.search_query_text_raw(cx))
|
||||
self.query_editor.read(cx).text(cx)
|
||||
}
|
||||
|
||||
fn build_search_query(&mut self, cx: &mut Context<Self>) -> Option<SearchQuery> {
|
||||
|
@ -1571,21 +1561,6 @@ impl ProjectSearchView {
|
|||
})
|
||||
}
|
||||
}
|
||||
|
||||
// Determines which pattern items are present in the search query and
|
||||
// updates the search options accordingly, only if the regex search option
|
||||
// is enabled.
|
||||
fn apply_pattern_items(&mut self, query: &str) {
|
||||
if self.search_options.contains(SearchOptions::REGEX) {
|
||||
// Determine what the search options were before the pattern items
|
||||
// were applied, so we can reapply them and determine which ones
|
||||
// actually have an effect on the search options, which are the ones
|
||||
// we need to keep track of.
|
||||
let search_options = self.pattern_items.revert(self.search_options);
|
||||
self.pattern_items = PatternItems::from_search_options(search_options, &query);
|
||||
self.search_options = self.pattern_items.apply(search_options);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fn buffer_search_query(
|
||||
|
@ -4152,121 +4127,6 @@ pub mod tests {
|
|||
});
|
||||
}
|
||||
|
||||
#[gpui::test]
|
||||
async fn test_pattern_items(cx: &mut TestAppContext) {
|
||||
init_test(cx);
|
||||
|
||||
let fs = FakeFs::new(cx.background_executor.clone());
|
||||
fs.insert_tree(
|
||||
path!("/dir"),
|
||||
json!({
|
||||
"one.rs": "const ONE: usize = 1;",
|
||||
"two.rs": "const TWO: usize = one::ONE + one::ONE;",
|
||||
"three.rs": "const THREE: usize = one::ONE + two::TWO;",
|
||||
"four.rs": "const FOUR: usize = one::ONE + three::THREE;",
|
||||
}),
|
||||
)
|
||||
.await;
|
||||
let project = Project::test(fs.clone(), [path!("/dir").as_ref()], cx).await;
|
||||
let window = cx.add_window(|window, cx| Workspace::test_new(project.clone(), window, cx));
|
||||
let workspace = window.root(cx).unwrap();
|
||||
|
||||
let project_search = cx.new(|cx| ProjectSearch::new(project.clone(), cx));
|
||||
let project_search_settings = ProjectSearchSettings {
|
||||
filters_enabled: false,
|
||||
search_options: SearchOptions::REGEX,
|
||||
};
|
||||
let project_search_view = cx.add_window(|window, cx| {
|
||||
ProjectSearchView::new(
|
||||
workspace.downgrade(),
|
||||
project_search.clone(),
|
||||
window,
|
||||
cx,
|
||||
Some(project_search_settings),
|
||||
)
|
||||
});
|
||||
|
||||
project_search_view
|
||||
.update(cx, |view, window, cx| {
|
||||
// Verify that `test\\c` does not change search options, as
|
||||
// `SearchOptions::CASE_SENSITIVE` is disabled.
|
||||
view.query_editor.update(cx, |editor, cx| {
|
||||
editor.set_text("test\\c", window, cx);
|
||||
});
|
||||
|
||||
assert_eq!(view.search_query_text_raw(cx), "test\\c");
|
||||
assert_eq!(view.search_query_text(cx), "test");
|
||||
|
||||
view.apply_pattern_items(&view.search_query_text_raw(cx));
|
||||
|
||||
assert_eq!(
|
||||
view.search_options,
|
||||
SearchOptions::REGEX,
|
||||
"Case sensitivity should remain disabled if only pattern item is '\\c'"
|
||||
);
|
||||
|
||||
// Verify that `test\\c\\C\\c` does not change search options,
|
||||
// as even though `\\C` should enabled
|
||||
// `SearchOptions::CASE_SENSITIVE`, the last `\\c` should
|
||||
// disable it.
|
||||
view.query_editor.update(cx, |editor, cx| {
|
||||
editor.set_text("test\\c\\C\\c", window, cx);
|
||||
});
|
||||
|
||||
assert_eq!(view.search_query_text_raw(cx), "test\\c\\C\\c");
|
||||
assert_eq!(view.search_query_text(cx), "test");
|
||||
|
||||
view.apply_pattern_items(&view.search_query_text_raw(cx));
|
||||
|
||||
assert_eq!(
|
||||
view.search_options,
|
||||
SearchOptions::REGEX,
|
||||
"Case sensitivity should be disabled if '\\c' follows '\\C'"
|
||||
);
|
||||
|
||||
// Verify that a single `\\C` pattern item in the search query
|
||||
// enables the `SearchOptions::CASE_SENSITIVE` option.
|
||||
view.query_editor.update(cx, |editor, cx| {
|
||||
editor.set_text("test\\C", window, cx);
|
||||
});
|
||||
|
||||
assert_eq!(view.search_query_text_raw(cx), "test\\C");
|
||||
assert_eq!(view.search_query_text(cx), "test");
|
||||
|
||||
view.apply_pattern_items(&view.search_query_text_raw(cx));
|
||||
|
||||
assert_eq!(
|
||||
view.search_options,
|
||||
SearchOptions::REGEX | SearchOptions::CASE_SENSITIVE,
|
||||
"Case sensitivity should be enabled when '\\C' is used"
|
||||
);
|
||||
|
||||
// Since `SearchOptions::CASE_SENSITIVE` is now enabled, we can
|
||||
// check that a pattern item preceded by a backslash, for
|
||||
// example, `\\\\c`, does not affect the search option and is
|
||||
// not even recognized as a valid pattern item.
|
||||
// We need to clear the `pattern_items` before testing this, as
|
||||
// calling `apply_pattern_items` will revert it, so the
|
||||
// `CASE_SENSITIVE` option would be turned off.
|
||||
view.pattern_items = PatternItems::default();
|
||||
view.query_editor.update(cx, |editor, cx| {
|
||||
editor.set_text("test\\\\c", window, cx);
|
||||
});
|
||||
|
||||
assert_eq!(view.search_query_text_raw(cx), "test\\\\c");
|
||||
assert_eq!(view.search_query_text(cx), "test\\\\c");
|
||||
|
||||
view.apply_pattern_items(&view.search_query_text_raw(cx));
|
||||
|
||||
assert_eq!(
|
||||
view.search_options,
|
||||
SearchOptions::REGEX | SearchOptions::CASE_SENSITIVE,
|
||||
"Case sensitivity should remain enabled when pattern item is preceded by a backslash"
|
||||
);
|
||||
})
|
||||
.unwrap();
|
||||
}
|
||||
|
||||
fn init_test(cx: &mut TestAppContext) {
|
||||
cx.update(|cx| {
|
||||
let settings = SettingsStore::test(cx);
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue