project: Normalize line endings in textual project search (#58628)
Release Notes: - Fixed an issue with project search on windows where multiline string searches would not work correctly due to newline differences
This commit is contained in:
1 parent
2d18262735
commit
6ca46fcf2c
2 files changed
+74
-2
No files matched your search
@@ -103,7 +103,8 @@ impl SearchQuery {
|
||||
match_full_paths: bool,
|
||||
buffers: Option<Vec<Entity<Buffer>>>,
|
||||
) -> Result<Self> {
|
||||
let query = query.to_string();
|
||||
let mut query = query.to_string();
|
||||
text::LineEnding::normalize(&mut query);
|
||||
if !case_sensitive && !query.is_ascii() {
|
||||
// AhoCorasickBuilder doesn't support case-insensitive search with unicode characters
|
||||
// Fallback to regex search as recommended by
|
||||
@@ -189,7 +190,8 @@ impl SearchQuery {
|
||||
match_full_paths: bool,
|
||||
buffers: Option<Vec<Entity<Buffer>>>,
|
||||
) -> Result<Self> {
|
||||
let query = query.to_string();
|
||||
let mut query = query.to_string();
|
||||
text::LineEnding::normalize(&mut query);
|
||||
let inner = SearchInputs {
|
||||
query: Arc::from(query.as_str()),
|
||||
files_to_include,
|
||||
@@ -402,6 +404,7 @@ impl SearchQuery {
|
||||
let mut text = String::new();
|
||||
if query_str.contains('\n') {
|
||||
reader.read_to_string(&mut text)?;
|
||||
text::LineEnding::normalize(&mut text);
|
||||
Ok(search.is_match(&text))
|
||||
} else {
|
||||
let mut bytes_read = 0;
|
||||
@@ -425,6 +428,7 @@ impl SearchQuery {
|
||||
let mut text = String::new();
|
||||
if *multiline {
|
||||
reader.read_to_string(&mut text)?;
|
||||
text::LineEnding::normalize(&mut text);
|
||||
Ok(regex.is_match(&text)?)
|
||||
} else {
|
||||
let mut bytes_read = 0;
|
||||
|
||||
@@ -7443,6 +7443,74 @@ async fn test_search(cx: &mut gpui::TestAppContext) {
|
||||
);
|
||||
}
|
||||
|
||||
#[gpui::test]
|
||||
async fn test_search_multiline_crlf(cx: &mut gpui::TestAppContext) {
|
||||
init_test(cx);
|
||||
|
||||
let fs = FakeFs::new(cx.executor());
|
||||
fs.insert_tree(
|
||||
path!("/dir"),
|
||||
json!({
|
||||
"crlf.rs": "alpha\r\nbeta\r\ngamma",
|
||||
"lf.rs": "alpha\nbeta\ngamma",
|
||||
}),
|
||||
)
|
||||
.await;
|
||||
let project = Project::test(fs.clone(), [path!("/dir").as_ref()], cx).await;
|
||||
|
||||
// A query with CRLF line endings should match buffers regardless of their
|
||||
// on-disk line endings (buffers always store normalized `\n`).
|
||||
assert_eq!(
|
||||
search(
|
||||
&project,
|
||||
SearchQuery::text(
|
||||
"alpha\r\nbeta",
|
||||
false,
|
||||
true,
|
||||
false,
|
||||
Default::default(),
|
||||
Default::default(),
|
||||
false,
|
||||
None,
|
||||
)
|
||||
.unwrap(),
|
||||
cx
|
||||
)
|
||||
.await
|
||||
.unwrap(),
|
||||
HashMap::from_iter([
|
||||
(path!("dir/crlf.rs").to_string(), vec![0..10]),
|
||||
(path!("dir/lf.rs").to_string(), vec![0..10]),
|
||||
])
|
||||
);
|
||||
|
||||
// The reverse: a query with LF line endings should match a file that is
|
||||
// stored with CRLF line endings on disk.
|
||||
assert_eq!(
|
||||
search(
|
||||
&project,
|
||||
SearchQuery::text(
|
||||
"alpha\nbeta",
|
||||
false,
|
||||
true,
|
||||
false,
|
||||
Default::default(),
|
||||
Default::default(),
|
||||
false,
|
||||
None,
|
||||
)
|
||||
.unwrap(),
|
||||
cx
|
||||
)
|
||||
.await
|
||||
.unwrap(),
|
||||
HashMap::from_iter([
|
||||
(path!("dir/crlf.rs").to_string(), vec![0..10]),
|
||||
(path!("dir/lf.rs").to_string(), vec![0..10]),
|
||||
])
|
||||
);
|
||||
}
|
||||
|
||||
#[gpui::test]
|
||||
async fn test_search_with_inclusions(cx: &mut gpui::TestAppContext) {
|
||||
init_test(cx);
|
||||
|
||||
Reference in new issue
Block a user