From 09470b9d577b58f05bb9ee263c7a06f7fa6b78ac Mon Sep 17 00:00:00 2001 From: dinocosta Date: Mon, 18 Aug 2025 22:57:54 +0100 Subject: [PATCH] fix: fix issue with conflicting pattern items Fix issue where having conflicting pattern items in the search query could lead to erroneous results. For example, if the search query was `test\c\C\c`, one would expect for the case sensitivity option to be disabled, seeing as `\c` is the last pattern item. However, since the code was simply iterating over `PATTERN_ITEMS`, it did not take into consideration that: 1. The same pattern item could appear more than once in the query 2. The order of the pattern item in the query should take precedence over the order of the pattern item in `PATTERN_ITEMS` As such, this commit fixes that so that the implementation actually iterates over the pattern items capture in the query, ensuring that, if `\c\C\c` is found, the last pattern item is the one that will be applied. --- crates/search/src/buffer_search.rs | 62 +++++++++++++++++++++++++++--- 1 file changed, 57 insertions(+), 5 deletions(-) diff --git a/crates/search/src/buffer_search.rs b/crates/search/src/buffer_search.rs index 8f8fc544a4..bf8c6e1ed8 100644 --- a/crates/search/src/buffer_search.rs +++ b/crates/search/src/buffer_search.rs @@ -51,6 +51,8 @@ const MAX_BUFFER_SEARCH_HISTORY_SIZE: usize = 50; /// value. /// When any of the patterns is present in the search query, the corresponding /// search option, and value, is applied. +// TODO: Should this be updated to an HashMap so we can easily determine the +// search option for a given pattern? static PATTERN_ITEMS: [(&str, &SearchOptions, bool); 2] = [ ("\\c", &SearchOptions::CASE_SENSITIVE, false), ("\\C", &SearchOptions::CASE_SENSITIVE, true), @@ -1526,10 +1528,16 @@ impl BufferSearchBar { let mut pattern_item_options = Vec::new(); let query = self.raw_query(cx); - PATTERN_ITEMS - .iter() - .filter(|(pattern, _, _)| query.contains(pattern)) - .for_each(|(_pattern, search_option, value)| { + self.pattern_items_regex + .captures_iter(&query) + .map(|capture| capture.extract()) + .map(|(str, [])| { + PATTERN_ITEMS + .iter() + .find(|(pattern, _, _)| *pattern == str) + .expect("should only capture valid pattern items") + }) + .for_each(|(_, search_option, value)| { match (search_options.contains(**search_option), value) { (true, false) => { search_options.toggle(**search_option); @@ -3017,6 +3025,50 @@ mod tests { ); }); + 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 preceeded 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 preceeded 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| { @@ -3024,7 +3076,7 @@ mod tests { assert_eq!( search_bar.search_options, SearchOptions::REGEX | SearchOptions::CASE_SENSITIVE, - "Should have case sensitivity enabled when \\c pattern item is removed" + "Should have case sensitivity enabled when all pattern items are removed and original search options are restored" ); }); }