mirror of
https://github.com/zed-industries/zed.git
synced 2024-10-26 08:31:04 +00:00
terminal: Fix non regex search to actually be non regex (#7330)
Alacritty seems to support only regex search out of the box. This PR just escapes all special regex chars to make non regex search work as expected. Disclaimer: New to Rust. Release Notes: -Fixed text search not working correctly in terminal ([#4880](https://github.com/zed-industries/zed/issues/4880))
This commit is contained in:
parent
4f5fea5dba
commit
b4b59f8706
1 changed files with 45 additions and 18 deletions
|
@ -46,6 +46,10 @@ use std::{
|
|||
time::Duration,
|
||||
};
|
||||
|
||||
const REGEX_SPECIAL_CHARS: &[char] = &[
|
||||
'\\', '.', '*', '+', '?', '|', '(', ')', '[', ']', '{', '}', '^', '$',
|
||||
];
|
||||
|
||||
const CURSOR_BLINK_INTERVAL: Duration = Duration::from_millis(500);
|
||||
|
||||
///Event to transmit the scroll from the element to the view
|
||||
|
@ -436,21 +440,6 @@ impl TerminalView {
|
|||
.detach();
|
||||
}
|
||||
|
||||
pub fn find_matches(
|
||||
&mut self,
|
||||
query: Arc<project::search::SearchQuery>,
|
||||
cx: &mut ViewContext<Self>,
|
||||
) -> Task<Vec<RangeInclusive<Point>>> {
|
||||
let searcher = regex_search_for_query(&query);
|
||||
|
||||
if let Some(searcher) = searcher {
|
||||
self.terminal
|
||||
.update(cx, |term, cx| term.find_matches(searcher, cx))
|
||||
} else {
|
||||
cx.background_executor().spawn(async { Vec::new() })
|
||||
}
|
||||
}
|
||||
|
||||
pub fn terminal(&self) -> &Model<Terminal> {
|
||||
&self.terminal
|
||||
}
|
||||
|
@ -656,6 +645,19 @@ fn possible_open_targets(
|
|||
possible_open_paths_metadata(fs, row, column, potential_abs_paths, cx)
|
||||
}
|
||||
|
||||
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<RegexSearch> {
|
||||
let query = query.as_str();
|
||||
if query == "." {
|
||||
|
@ -916,12 +918,27 @@ impl SearchableItem for TerminalView {
|
|||
/// Get all of the matches for this query, should be done on the background
|
||||
fn find_matches(
|
||||
&mut self,
|
||||
query: Arc<project::search::SearchQuery>,
|
||||
query: Arc<SearchQuery>,
|
||||
cx: &mut ViewContext<Self>,
|
||||
) -> Task<Vec<Self::Match>> {
|
||||
if let Some(searcher) = regex_search_for_query(&query) {
|
||||
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().to_vec(),
|
||||
query.files_to_exclude().to_vec(),
|
||||
)
|
||||
.unwrap()),
|
||||
),
|
||||
SearchQuery::Regex { .. } => regex_search_for_query(&query),
|
||||
};
|
||||
|
||||
if let Some(s) = searcher {
|
||||
self.terminal()
|
||||
.update(cx, |term, cx| term.find_matches(searcher, cx))
|
||||
.update(cx, |term, cx| term.find_matches(s, cx))
|
||||
} else {
|
||||
Task::ready(vec![])
|
||||
}
|
||||
|
@ -1212,4 +1229,14 @@ 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());
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue