diff --git a/crates/project/src/project.rs b/crates/project/src/project.rs index 1b357648e6c5935e31caf541205752e106858493..214ff11bc8c9dd1579b50ce0def9094ec0f98f81 100644 --- a/crates/project/src/project.rs +++ b/crates/project/src/project.rs @@ -4163,23 +4163,36 @@ impl Project { let path = path.as_ref(); 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(), - }); + if path.is_absolute() { + for worktree in worktree_store.visible_worktrees(cx) { + let worktree_abs_path = worktree.read(cx).abs_path(); + + if let Ok(relative_path) = path.strip_prefix(worktree_abs_path) { + return Some(ProjectPath { + worktree_id: worktree.read(cx).id(), + path: relative_path.into(), + }); + } + } + } else { + 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(), - }); + 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(), + }); + } } } diff --git a/crates/project/src/project_tests.rs b/crates/project/src/project_tests.rs index 394d89c04e3edcf5a525b1dfde6b3612524070ee..e4188485165624823c438ff1facb9f8eaf2b2c17 100644 --- a/crates/project/src/project_tests.rs +++ b/crates/project/src/project_tests.rs @@ -8766,3 +8766,89 @@ fn git_status(repo: &git2::Repository) -> collections::HashMap>()) { + worktree + .read_with(cx, |tree, _| tree.as_local().unwrap().scan_complete()) + .await; + } + cx.run_until_parked(); + + let (project1_abs_path, project1_id, project2_abs_path, project2_id) = + project.read_with(cx, |project, cx| { + let worktrees: Vec<_> = project.worktrees(cx).collect(); + let abs_path1 = worktrees[0].read(cx).abs_path().to_path_buf(); + let id1 = worktrees[0].read(cx).id(); + let abs_path2 = worktrees[1].read(cx).abs_path().to_path_buf(); + let id2 = worktrees[1].read(cx).id(); + (abs_path1, id1, abs_path2, id2) + }); + + project.update(cx, |project, cx| { + let abs_path = project1_abs_path.join("file1.txt"); + let found_path = project.find_project_path(abs_path, cx).unwrap(); + assert_eq!(found_path.worktree_id, project1_id); + assert_eq!(found_path.path.as_ref(), Path::new("file1.txt")); + + let abs_path = project1_abs_path.join("subdir").join("file2.txt"); + let found_path = project.find_project_path(abs_path, cx).unwrap(); + assert_eq!(found_path.worktree_id, project1_id); + assert_eq!(found_path.path.as_ref(), Path::new("subdir/file2.txt")); + + let abs_path = project2_abs_path.join("file3.txt"); + let found_path = project.find_project_path(abs_path, cx).unwrap(); + assert_eq!(found_path.worktree_id, project2_id); + assert_eq!(found_path.path.as_ref(), Path::new("file3.txt")); + + let abs_path = project1_abs_path.join("nonexistent.txt"); + let found_path = project.find_project_path(abs_path, cx); + assert!( + found_path.is_some(), + "Should find project path for nonexistent file in worktree" + ); + + // Test with an absolute path outside any worktree + let abs_path = Path::new("/some/other/path"); + let found_path = project.find_project_path(abs_path, cx); + assert!( + found_path.is_none(), + "Should not find project path for path outside any worktree" + ); + }); +}