diff --git a/Cargo.lock b/Cargo.lock index f9f9e76cc5..8e292181c2 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -14746,6 +14746,7 @@ dependencies = [ "log", "project", "rand 0.8.5", + "regex", "schemars", "search", "serde", diff --git a/crates/terminal_view/Cargo.toml b/crates/terminal_view/Cargo.toml index f117e1ab37..2096e25fbd 100644 --- a/crates/terminal_view/Cargo.toml +++ b/crates/terminal_view/Cargo.toml @@ -29,6 +29,7 @@ itertools.workspace = true language.workspace = true log.workspace = true project.workspace = true +regex.workspace = true task.workspace = true schemars.workspace = true search.workspace = true diff --git a/crates/terminal_view/src/terminal_view.rs b/crates/terminal_view/src/terminal_view.rs index 3f392da438..7b5d717643 100644 --- a/crates/terminal_view/src/terminal_view.rs +++ b/crates/terminal_view/src/terminal_view.rs @@ -57,10 +57,6 @@ use std::{ time::Duration, }; -const REGEX_SPECIAL_CHARS: &[char] = &[ - '\\', '.', '*', '+', '?', '|', '(', ')', '[', ']', '{', '}', '^', '$', -]; - const CURSOR_BLINK_INTERVAL: Duration = Duration::from_millis(500); const GIT_DIFF_PATH_PREFIXES: &[&str] = &["a", "b"]; @@ -1258,26 +1254,16 @@ fn possible_open_target( }) } -fn regex_to_literal(regex: &str) -> String { - regex - .chars() - .flat_map(|c| { - if REGEX_SPECIAL_CHARS.contains(&c) { - vec!['\\', c] - } else { - vec![c] - } - }) - .collect() -} - -pub fn regex_search_for_query(query: &project::search::SearchQuery) -> Option { - let query = query.as_str(); - if query == "." { - return None; +fn regex_search_for_query(query: &project::search::SearchQuery) -> Option { + let str = query.as_str(); + if query.is_regex() { + if str == "." { + return None; + } + RegexSearch::new(str).ok() + } else { + RegexSearch::new(®ex::escape(str)).ok() } - let searcher = RegexSearch::new(query); - searcher.ok() } impl TerminalView { @@ -1740,24 +1726,7 @@ impl SearchableItem for TerminalView { _: &mut Window, cx: &mut Context, ) -> Task> { - let searcher = match &*query { - SearchQuery::Text { .. } => regex_search_for_query( - &(SearchQuery::text( - regex_to_literal(query.as_str()), - query.whole_word(), - query.case_sensitive(), - query.include_ignored(), - query.files_to_include().clone(), - query.files_to_exclude().clone(), - false, - None, - ) - .unwrap()), - ), - SearchQuery::Regex { .. } => regex_search_for_query(&query), - }; - - if let Some(s) = searcher { + if let Some(s) = regex_search_for_query(&query) { self.terminal() .update(cx, |term, cx| term.find_matches(s, cx)) } else { @@ -2052,14 +2021,4 @@ mod tests { project.update(cx, |project, cx| project.set_active_path(Some(p), cx)); }); } - - #[test] - fn escapes_only_special_characters() { - assert_eq!(regex_to_literal(r"test(\w)"), r"test\(\\w\)".to_string()); - } - - #[test] - fn empty_string_stays_empty() { - assert_eq!(regex_to_literal(""), "".to_string()); - } }