diff --git a/crates/call/src/room.rs b/crates/call/src/room.rs index 09b49716e0..b2e79f820d 100644 --- a/crates/call/src/room.rs +++ b/crates/call/src/room.rs @@ -8,7 +8,7 @@ use collections::{BTreeMap, HashSet}; use futures::StreamExt; use gpui::{AsyncAppContext, Entity, ModelContext, ModelHandle, MutableAppContext, Task}; use project::Project; -use std::sync::Arc; +use std::{os::unix::prelude::OsStrExt, sync::Arc}; use util::ResultExt; #[derive(Clone, Debug, PartialEq, Eq)] @@ -389,6 +389,7 @@ impl Room { id: worktree.id().to_proto(), root_name: worktree.root_name().into(), visible: worktree.is_visible(), + abs_path: worktree.abs_path().as_os_str().as_bytes().to_vec(), } }) .collect(), diff --git a/crates/collab/src/integration_tests.rs b/crates/collab/src/integration_tests.rs index debd2d56be..e715a995a7 100644 --- a/crates/collab/src/integration_tests.rs +++ b/crates/collab/src/integration_tests.rs @@ -3038,7 +3038,7 @@ async fn test_references(cx_a: &mut TestAppContext, cx_b: &mut TestAppContext) { assert_eq!(references[1].buffer, references[0].buffer); assert_eq!( three_buffer.file().unwrap().full_path(cx), - Path::new("/OUTSIDE_PROJECT/three.rs") + Path::new("/root/dir-2/three.rs") ); assert_eq!(references[0].range.to_offset(two_buffer), 24..27); diff --git a/crates/collab/src/rpc.rs b/crates/collab/src/rpc.rs index 564e173fec..bb8d7c2325 100644 --- a/crates/collab/src/rpc.rs +++ b/crates/collab/src/rpc.rs @@ -42,6 +42,7 @@ use std::{ marker::PhantomData, net::SocketAddr, ops::{Deref, DerefMut}, + os::unix::prelude::OsStrExt, rc::Rc, sync::{ atomic::{AtomicBool, Ordering::SeqCst}, @@ -941,6 +942,7 @@ impl Server { id: *id, root_name: worktree.root_name.clone(), visible: worktree.visible, + abs_path: worktree.abs_path.as_os_str().as_bytes().to_vec(), }) .collect::>(); @@ -989,6 +991,7 @@ impl Server { let message = proto::UpdateWorktree { project_id: project_id.to_proto(), worktree_id: *worktree_id, + abs_path: worktree.abs_path.as_os_str().as_bytes().to_vec(), root_name: worktree.root_name.clone(), updated_entries: worktree.entries.values().cloned().collect(), removed_entries: Default::default(), diff --git a/crates/collab/src/rpc/store.rs b/crates/collab/src/rpc/store.rs index b7dd39cff1..fb21538d60 100644 --- a/crates/collab/src/rpc/store.rs +++ b/crates/collab/src/rpc/store.rs @@ -66,6 +66,7 @@ pub struct Collaborator { #[derive(Default, Serialize)] pub struct Worktree { + pub abs_path: PathBuf, pub root_name: String, pub visible: bool, #[serde(skip)] diff --git a/crates/project/src/project_tests.rs b/crates/project/src/project_tests.rs index 1b0294c4d1..a9ac5f4411 100644 --- a/crates/project/src/project_tests.rs +++ b/crates/project/src/project_tests.rs @@ -2164,6 +2164,7 @@ async fn test_rescan_and_remote_updates( proto::WorktreeMetadata { id: initial_snapshot.id().to_proto(), root_name: initial_snapshot.root_name().into(), + abs_path: initial_snapshot.abs_path().as_os_str().as_bytes().to_vec(), visible: true, }, rpc.clone(), diff --git a/crates/project/src/worktree.rs b/crates/project/src/worktree.rs index c58fcd4638..9f0ebe32f7 100644 --- a/crates/project/src/worktree.rs +++ b/crates/project/src/worktree.rs @@ -87,6 +87,7 @@ pub struct RemoteWorktree { #[derive(Clone)] pub struct Snapshot { id: WorktreeId, + abs_path: Arc, root_name: String, root_char_bag: CharBag, entries_by_path: SumTree, @@ -118,7 +119,6 @@ impl std::fmt::Debug for GitRepositoryEntry { } pub struct LocalSnapshot { - abs_path: Arc, ignores_by_parent_abs_path: HashMap, (Arc, usize)>, git_repositories: Vec, removed_entry_ids: HashMap, @@ -130,7 +130,6 @@ pub struct LocalSnapshot { impl Clone for LocalSnapshot { fn clone(&self) -> Self { Self { - abs_path: self.abs_path.clone(), ignores_by_parent_abs_path: self.ignores_by_parent_abs_path.clone(), git_repositories: self.git_repositories.iter().cloned().collect(), removed_entry_ids: self.removed_entry_ids.clone(), @@ -221,8 +220,11 @@ impl Worktree { .collect(); let root_name = worktree.root_name.clone(); let visible = worktree.visible; + + let abs_path = PathBuf::from(OsString::from_vec(worktree.abs_path)); let snapshot = Snapshot { id: WorktreeId(remote_id as usize), + abs_path: Arc::from(abs_path.deref()), root_name, root_char_bag, entries_by_path: Default::default(), @@ -372,6 +374,13 @@ impl Worktree { Self::Remote(worktree) => worktree.poll_snapshot(cx), }; } + + pub fn abs_path(&self) -> Arc { + match self { + Worktree::Local(worktree) => worktree.abs_path.clone(), + Worktree::Remote(worktree) => worktree.abs_path.clone(), + } + } } impl LocalWorktree { @@ -402,13 +411,13 @@ impl LocalWorktree { watch::channel_with(ScanState::Initializing); let tree = cx.add_model(move |cx: &mut ModelContext| { let mut snapshot = LocalSnapshot { - abs_path, ignores_by_parent_abs_path: Default::default(), git_repositories: Default::default(), removed_entry_ids: Default::default(), next_entry_id, snapshot: Snapshot { id: WorktreeId::from_usize(cx.model_id()), + abs_path, root_name: root_name.clone(), root_char_bag, entries_by_path: Default::default(), @@ -647,6 +656,7 @@ impl LocalWorktree { id: self.id().to_proto(), root_name: self.root_name().to_string(), visible: self.visible, + abs_path: self.abs_path().as_os_str().as_bytes().to_vec(), } } @@ -980,6 +990,7 @@ impl LocalWorktree { let update = proto::UpdateWorktree { project_id, worktree_id, + abs_path: snapshot.abs_path().as_os_str().as_bytes().to_vec(), root_name: snapshot.root_name().to_string(), updated_entries: snapshot .entries_by_path @@ -1389,6 +1400,7 @@ impl LocalSnapshot { proto::UpdateWorktree { project_id, worktree_id: self.id().to_proto(), + abs_path: self.abs_path().as_os_str().as_bytes().to_vec(), root_name, updated_entries: self.entries_by_path.iter().map(Into::into).collect(), removed_entries: Default::default(), @@ -1456,6 +1468,7 @@ impl LocalSnapshot { proto::UpdateWorktree { project_id, worktree_id, + abs_path: self.abs_path().as_os_str().as_bytes().to_vec(), root_name: self.root_name().to_string(), updated_entries, removed_entries, @@ -1844,16 +1857,13 @@ impl language::File for File { if worktree.is_visible() { full_path.push(worktree.root_name()); } else { - if let Some(path) = worktree.as_local().map(|local| local.abs_path.clone()) { - if let Ok(trimmed_path) = path.strip_prefix(cx.global::().as_path()) { - full_path.push("~"); - full_path.push(trimmed_path); - } else { - full_path.push(path) - } + let path = worktree.abs_path(); + + if worktree.is_local() && path.starts_with(cx.global::().as_path()) { + full_path.push("~"); + full_path.push(path.strip_prefix(cx.global::().as_path()).unwrap()); } else { - full_path.push(Path::new("/OUTSIDE_PROJECT")); - full_path.push(worktree.root_name()); + full_path.push(path) } } @@ -3473,7 +3483,6 @@ mod tests { let fs = Arc::new(RealFs); let next_entry_id = Arc::new(AtomicUsize::new(0)); let mut initial_snapshot = LocalSnapshot { - abs_path: root_dir.path().into(), removed_entry_ids: Default::default(), ignores_by_parent_abs_path: Default::default(), git_repositories: Default::default(), @@ -3482,6 +3491,7 @@ mod tests { id: WorktreeId::from_usize(0), entries_by_path: Default::default(), entries_by_id: Default::default(), + abs_path: root_dir.path().into(), root_name: Default::default(), root_char_bag: Default::default(), scan_id: 0, diff --git a/crates/rpc/proto/zed.proto b/crates/rpc/proto/zed.proto index 1248bb0551..1f4c067fca 100644 --- a/crates/rpc/proto/zed.proto +++ b/crates/rpc/proto/zed.proto @@ -266,6 +266,7 @@ message UpdateWorktree { repeated uint64 removed_entries = 5; uint64 scan_id = 6; bool is_last_update = 7; + bytes abs_path = 8; } message UpdateWorktreeExtensions { @@ -1052,6 +1053,7 @@ message WorktreeMetadata { uint64 id = 1; string root_name = 2; bool visible = 3; + bytes abs_path = 4; } message UpdateDiffBase { diff --git a/crates/rpc/src/proto.rs b/crates/rpc/src/proto.rs index 069fde4e59..827a8ff1a8 100644 --- a/crates/rpc/src/proto.rs +++ b/crates/rpc/src/proto.rs @@ -435,6 +435,7 @@ pub fn split_worktree_update( project_id: message.project_id, worktree_id: message.worktree_id, root_name: message.root_name.clone(), + abs_path: message.abs_path.clone(), updated_entries, removed_entries: mem::take(&mut message.removed_entries), scan_id: message.scan_id, diff --git a/crates/rpc/src/rpc.rs b/crates/rpc/src/rpc.rs index 5fb9ca79a2..558f52e684 100644 --- a/crates/rpc/src/rpc.rs +++ b/crates/rpc/src/rpc.rs @@ -6,4 +6,4 @@ pub use conn::Connection; pub use peer::*; mod macros; -pub const PROTOCOL_VERSION: u32 = 35; +pub const PROTOCOL_VERSION: u32 = 37;