Gracefully handle models searching for empty glob (#27370)
Richard Feldman
created 9 months ago
Sometimes we've seen models provide an empty string for the path search
glob. This assumes they meant "*" when that happens.
Separately, this also removes an unnecessary `clone` of a `String`.
Release Notes:
- N/A
Change summary
crates/assistant_tools/src/edit_files_tool/replace.rs | 5 +++--
crates/assistant_tools/src/path_search_tool.rs | 6 +++++-
crates/util/src/paths.rs | 6 +++---
3 files changed, 11 insertions(+), 6 deletions(-)
Detailed changes
@@ -1,5 +1,6 @@
use language::{BufferSnapshot, Diff, Point, ToOffset};
use project::search::SearchQuery;
+use std::iter;
use util::{paths::PathMatcher, ResultExt as _};
/// Performs an exact string replacement in a buffer, requiring precise character-for-character matching.
@@ -11,8 +12,8 @@ pub async fn replace_exact(old: &str, new: &str, snapshot: &BufferSnapshot) -> O
false,
true,
true,
- PathMatcher::new(&[]).ok()?,
- PathMatcher::new(&[]).ok()?,
+ PathMatcher::new(iter::empty::<&str>()).ok()?,
+ PathMatcher::new(iter::empty::<&str>()).ok()?,
None,
)
.log_err()?;
@@ -71,7 +71,11 @@ impl Tool for PathSearchTool {
Ok(input) => (input.offset.unwrap_or(0), input.glob),
Err(err) => return Task::ready(Err(anyhow!(err))),
};
- let path_matcher = match PathMatcher::new(&[glob.clone()]) {
+
+ let path_matcher = match PathMatcher::new([
+ // Sometimes models try to search for "". In this case, return all paths in the project.
+ if glob.is_empty() { "*" } else { &glob },
+ ]) {
Ok(matcher) => matcher,
Err(err) => return Task::ready(Err(anyhow!("Invalid glob: {err}"))),
};
@@ -377,10 +377,10 @@ impl PartialEq for PathMatcher {
impl Eq for PathMatcher {}
impl PathMatcher {
- pub fn new(globs: &[String]) -> Result<Self, globset::Error> {
+ pub fn new(globs: impl IntoIterator<Item = impl AsRef<str>>) -> Result<Self, globset::Error> {
let globs = globs
- .iter()
- .map(|glob| Glob::new(glob))
+ .into_iter()
+ .map(|as_str| Glob::new(as_str.as_ref()))
.collect::<Result<Vec<_>, _>>()?;
let sources = globs.iter().map(|glob| glob.glob().to_owned()).collect();
let mut glob_builder = GlobSetBuilder::new();