@@ -528,7 +528,7 @@ impl EditOperation {
let buffer = project
.update(&mut cx, |project, cx| {
let project_path = project
- .project_path_for_full_path(Path::new(&path), cx)
+ .find_project_path(Path::new(&path), cx)
.with_context(|| format!("worktree not found for {:?}", path))?;
anyhow::Ok(project.open_buffer(project_path, cx))
})??
@@ -8341,36 +8341,47 @@ impl Project {
})
}
- /// Attempts to find a `ProjectPath` corresponding to the given full path.
+ /// Attempts to find a `ProjectPath` corresponding to the given path. If the path
+ /// is a *full path*, meaning it starts with the root name of a worktree, we'll locate
+ /// it in that worktree. Otherwise, we'll attempt to find it as a relative path in
+ /// the first visible worktree that has an entry for that relative path.
///
- /// This method iterates through all worktrees in the project, trying to match
- /// the given full path against each worktree's root name. If a match is found,
- /// it returns a `ProjectPath` containing the worktree ID and the relative path
- /// within that worktree.
+ /// We use this to resolve edit steps, when there's a chance an LLM may omit the workree
+ /// root name from paths.
///
/// # Arguments
///
- /// * `full_path` - A reference to a `Path` representing the full path to resolve.
+ /// * `path` - A full path that starts with a worktree root name, or alternatively a
+ /// relative path within a visible worktree.
/// * `cx` - A reference to the `AppContext`.
///
/// # Returns
///
/// Returns `Some(ProjectPath)` if a matching worktree is found, otherwise `None`.
- pub fn project_path_for_full_path(
- &self,
- full_path: &Path,
- cx: &AppContext,
- ) -> Option<ProjectPath> {
- self.worktree_store.read_with(cx, |worktree_store, cx| {
- worktree_store.worktrees().find_map(|worktree| {
- let worktree_root_name = worktree.read(cx).root_name();
- let relative_path = full_path.strip_prefix(worktree_root_name).ok()?;
- Some(ProjectPath {
+ pub fn find_project_path(&self, path: &Path, cx: &AppContext) -> Option<ProjectPath> {
+ let worktree_store = self.worktree_store.read(cx);
+
+ for worktree in worktree_store.visible_worktrees(cx) {
+ let worktree_root_name = worktree.read(cx).root_name();
+ if let Ok(relative_path) = path.strip_prefix(worktree_root_name) {
+ return Some(ProjectPath {
worktree_id: worktree.read(cx).id(),
path: relative_path.into(),
- })
- })
- })
+ });
+ }
+ }
+
+ for worktree in worktree_store.visible_worktrees(cx) {
+ let worktree = worktree.read(cx);
+ if let Some(entry) = worktree.entry_for_path(path) {
+ return Some(ProjectPath {
+ worktree_id: worktree.id(),
+ path: entry.path.clone(),
+ });
+ }
+ }
+
+ None
}
pub fn get_workspace_root(