From 6122f460953c2f162a1ea91213b72db914b39456 Mon Sep 17 00:00:00 2001 From: maan2003 <49202620+maan2003@users.noreply.github.com> Date: Wed, 23 Jul 2025 11:48:45 +0530 Subject: [PATCH] project: Fix search filter patterns on remote projects (#34748) we were join(",") and split(",") to serialize the patterns. This doesn't work when pattern includes a "," example: *.{ts,tsx} (very common pattern used by agent) help needed: how will this work on version mismatch? Release Notes: - Fixed search filter patterns on remote projects. --- crates/project/src/search.rs | 49 +++++++++++++++++++++++---------- crates/proto/proto/buffer.proto | 6 ++-- 2 files changed, 39 insertions(+), 16 deletions(-) diff --git a/crates/project/src/search.rs b/crates/project/src/search.rs index 44732b23cd..4f024837c8 100644 --- a/crates/project/src/search.rs +++ b/crates/project/src/search.rs @@ -193,6 +193,30 @@ impl SearchQuery { } pub fn from_proto(message: proto::SearchQuery) -> Result { + let files_to_include = if message.files_to_include.is_empty() { + message + .files_to_include_legacy + .split(',') + .map(str::trim) + .filter(|&glob_str| !glob_str.is_empty()) + .map(|s| s.to_string()) + .collect() + } else { + message.files_to_include + }; + + let files_to_exclude = if message.files_to_exclude.is_empty() { + message + .files_to_exclude_legacy + .split(',') + .map(str::trim) + .filter(|&glob_str| !glob_str.is_empty()) + .map(|s| s.to_string()) + .collect() + } else { + message.files_to_exclude + }; + if message.regex { Self::regex( message.query, @@ -200,8 +224,8 @@ impl SearchQuery { message.case_sensitive, message.include_ignored, false, - deserialize_path_matches(&message.files_to_include)?, - deserialize_path_matches(&message.files_to_exclude)?, + PathMatcher::new(files_to_include)?, + PathMatcher::new(files_to_exclude)?, message.match_full_paths, None, // search opened only don't need search remote ) @@ -211,8 +235,8 @@ impl SearchQuery { message.whole_word, message.case_sensitive, message.include_ignored, - deserialize_path_matches(&message.files_to_include)?, - deserialize_path_matches(&message.files_to_exclude)?, + PathMatcher::new(files_to_include)?, + PathMatcher::new(files_to_exclude)?, false, None, // search opened only don't need search remote ) @@ -236,15 +260,20 @@ impl SearchQuery { } pub fn to_proto(&self) -> proto::SearchQuery { + let files_to_include = self.files_to_include().sources().to_vec(); + let files_to_exclude = self.files_to_exclude().sources().to_vec(); proto::SearchQuery { query: self.as_str().to_string(), regex: self.is_regex(), whole_word: self.whole_word(), case_sensitive: self.case_sensitive(), include_ignored: self.include_ignored(), - files_to_include: self.files_to_include().sources().join(","), - files_to_exclude: self.files_to_exclude().sources().join(","), + files_to_include: files_to_include.clone(), + files_to_exclude: files_to_exclude.clone(), match_full_paths: self.match_full_paths(), + // Populate legacy fields for backwards compatibility + files_to_include_legacy: files_to_include.join(","), + files_to_exclude_legacy: files_to_exclude.join(","), } } @@ -520,14 +549,6 @@ impl SearchQuery { } } -pub fn deserialize_path_matches(glob_set: &str) -> anyhow::Result { - let globs = glob_set - .split(',') - .map(str::trim) - .filter(|&glob_str| !glob_str.is_empty()); - Ok(PathMatcher::new(globs)?) -} - #[cfg(test)] mod tests { use super::*; diff --git a/crates/proto/proto/buffer.proto b/crates/proto/proto/buffer.proto index 09a05a50cd..f4dacf2fdc 100644 --- a/crates/proto/proto/buffer.proto +++ b/crates/proto/proto/buffer.proto @@ -288,10 +288,12 @@ message SearchQuery { bool regex = 3; bool whole_word = 4; bool case_sensitive = 5; - string files_to_include = 6; - string files_to_exclude = 7; + repeated string files_to_include = 10; + repeated string files_to_exclude = 11; bool match_full_paths = 9; bool include_ignored = 8; + string files_to_include_legacy = 6; + string files_to_exclude_legacy = 7; } message FindSearchCandidates {