Detailed changes
@@ -1266,6 +1266,27 @@ async fn test_share_project(
let client_b_collaborator = project.collaborators().get(&client_b_peer_id).unwrap();
assert_eq!(client_b_collaborator.replica_id, replica_id_b);
});
+ project_b.read_with(cx_b, |project, cx| {
+ let worktree = project.worktrees(cx).next().unwrap().read(cx);
+ assert_eq!(
+ worktree.paths().map(AsRef::as_ref).collect::<Vec<_>>(),
+ [
+ Path::new(".gitignore"),
+ Path::new("a.txt"),
+ Path::new("b.txt"),
+ Path::new("ignored-dir"),
+ ]
+ );
+ });
+
+ project_b
+ .update(cx_b, |project, cx| {
+ let worktree = project.worktrees(cx).next().unwrap();
+ let entry = worktree.read(cx).entry_for_path("ignored-dir").unwrap();
+ project.expand_entry(worktree_id, entry.id, cx).unwrap()
+ })
+ .await
+ .unwrap();
project_b.read_with(cx_b, |project, cx| {
let worktree = project.worktrees(cx).next().unwrap().read(cx);
assert_eq!(
@@ -1073,6 +1073,40 @@ impl Project {
}
}
+ pub fn expand_entry(
+ &mut self,
+ worktree_id: WorktreeId,
+ entry_id: ProjectEntryId,
+ cx: &mut ModelContext<Self>,
+ ) -> Option<Task<Result<()>>> {
+ let worktree = self.worktree_for_id(worktree_id, cx)?;
+ if self.is_local() {
+ worktree.update(cx, |worktree, cx| {
+ worktree.as_local_mut().unwrap().expand_entry(entry_id, cx)
+ })
+ } else {
+ let worktree = worktree.downgrade();
+ let request = self.client.request(proto::ExpandProjectEntry {
+ project_id: self.remote_id().unwrap(),
+ entry_id: entry_id.to_proto(),
+ });
+ Some(cx.spawn_weak(|_, mut cx| async move {
+ let response = request.await?;
+ if let Some(worktree) = worktree.upgrade(&cx) {
+ worktree
+ .update(&mut cx, |worktree, _| {
+ worktree
+ .as_remote_mut()
+ .unwrap()
+ .wait_for_snapshot(response.worktree_scan_id as usize)
+ })
+ .await?;
+ }
+ Ok(())
+ }))
+ }
+ }
+
pub fn shared(&mut self, project_id: u64, cx: &mut ModelContext<Self>) -> Result<()> {
if self.client_state.is_some() {
return Err(anyhow!("project was already shared"));
@@ -5404,31 +5438,6 @@ impl Project {
Some(ProjectPath { worktree_id, path })
}
- pub fn mark_entry_expanded(
- &mut self,
- worktree_id: WorktreeId,
- entry_id: ProjectEntryId,
- cx: &mut ModelContext<Self>,
- ) -> Option<()> {
- if self.is_local() {
- let worktree = self.worktree_for_id(worktree_id, cx)?;
- worktree.update(cx, |worktree, cx| {
- worktree
- .as_local_mut()
- .unwrap()
- .expand_entry_for_id(entry_id, cx);
- });
- } else if let Some(project_id) = self.remote_id() {
- cx.background()
- .spawn(self.client.request(proto::ExpandProjectEntry {
- project_id,
- entry_id: entry_id.to_proto(),
- }))
- .log_err();
- }
- Some(())
- }
-
pub fn absolute_path(&self, project_path: &ProjectPath, cx: &AppContext) -> Option<PathBuf> {
let workspace_root = self
.worktree_for_id(project_path.worktree_id, cx)?
@@ -5736,18 +5745,22 @@ impl Project {
envelope: TypedEnvelope<proto::ExpandProjectEntry>,
_: Arc<Client>,
mut cx: AsyncAppContext,
- ) -> Result<proto::Ack> {
+ ) -> Result<proto::ExpandProjectEntryResponse> {
let entry_id = ProjectEntryId::from_proto(envelope.payload.entry_id);
let worktree = this
.read_with(&cx, |this, cx| this.worktree_for_entry(entry_id, cx))
.ok_or_else(|| anyhow!("invalid request"))?;
- worktree.update(&mut cx, |worktree, cx| {
- worktree
- .as_local_mut()
- .unwrap()
- .expand_entry_for_id(entry_id, cx)
- });
- Ok(proto::Ack {})
+ worktree
+ .update(&mut cx, |worktree, cx| {
+ worktree
+ .as_local_mut()
+ .unwrap()
+ .expand_entry(entry_id, cx)
+ .ok_or_else(|| anyhow!("invalid entry"))
+ })?
+ .await?;
+ let worktree_scan_id = worktree.read_with(&cx, |worktree, _| worktree.scan_id()) as u64;
+ Ok(proto::ExpandProjectEntryResponse { worktree_scan_id })
}
async fn handle_update_diagnostic_summary(
@@ -1127,21 +1127,17 @@ impl LocalWorktree {
}))
}
- pub fn expand_entry_for_id(
+ pub fn expand_entry(
&mut self,
entry_id: ProjectEntryId,
- _cx: &mut ModelContext<Worktree>,
- ) -> barrier::Receiver {
- let (tx, rx) = barrier::channel();
- if let Some(entry) = self.entry_for_id(entry_id) {
- self.scan_requests_tx
- .try_send(ScanRequest {
- relative_paths: vec![entry.path.clone()],
- done: tx,
- })
- .ok();
- }
- rx
+ cx: &mut ModelContext<Worktree>,
+ ) -> Option<Task<Result<()>>> {
+ let path = self.entry_for_id(entry_id)?.path.clone();
+ let mut refresh = self.refresh_entries_for_paths(vec![path]);
+ Some(cx.background().spawn(async move {
+ refresh.next().await;
+ Ok(())
+ }))
}
pub fn refresh_entries_for_paths(&self, paths: Vec<Arc<Path>>) -> barrier::Receiver {
@@ -1337,7 +1333,7 @@ impl RemoteWorktree {
self.completed_scan_id >= scan_id
}
- fn wait_for_snapshot(&mut self, scan_id: usize) -> impl Future<Output = Result<()>> {
+ pub(crate) fn wait_for_snapshot(&mut self, scan_id: usize) -> impl Future<Output = Result<()>> {
let (tx, rx) = oneshot::channel();
if self.observed_snapshot(scan_id) {
let _ = tx.send(());
@@ -423,7 +423,7 @@ impl ProjectPanel {
Ok(_) => self.select_next(&SelectNext, cx),
Err(ix) => {
self.project.update(cx, |project, cx| {
- project.mark_entry_expanded(worktree_id, entry_id, cx);
+ project.expand_entry(worktree_id, entry_id, cx);
});
expanded_dir_ids.insert(ix, entry_id);
@@ -477,7 +477,7 @@ impl ProjectPanel {
expanded_dir_ids.remove(ix);
}
Err(ix) => {
- project.mark_entry_expanded(worktree_id, entry_id, cx);
+ project.expand_entry(worktree_id, entry_id, cx);
expanded_dir_ids.insert(ix, entry_id);
}
}
@@ -1084,7 +1084,7 @@ impl ProjectPanel {
.worktree_for_id(worktree_id, cx)
.zip(self.expanded_dir_ids.get_mut(&worktree_id))
{
- project.mark_entry_expanded(worktree_id, entry_id, cx);
+ project.expand_entry(worktree_id, entry_id, cx);
let worktree = worktree.read(cx);
if let Some(mut entry) = worktree.entry_for_id(entry_id) {
@@ -62,8 +62,9 @@ message Envelope {
RenameProjectEntry rename_project_entry = 46;
CopyProjectEntry copy_project_entry = 47;
DeleteProjectEntry delete_project_entry = 48;
- ExpandProjectEntry expand_project_entry = 114;
ProjectEntryResponse project_entry_response = 49;
+ ExpandProjectEntry expand_project_entry = 114;
+ ExpandProjectEntryResponse expand_project_entry_response = 115;
UpdateDiagnosticSummary update_diagnostic_summary = 50;
StartLanguageServer start_language_server = 51;
@@ -378,6 +379,10 @@ message ExpandProjectEntry {
uint64 entry_id = 2;
}
+message ExpandProjectEntryResponse {
+ uint64 worktree_scan_id = 1;
+}
+
message ProjectEntryResponse {
Entry entry = 1;
uint64 worktree_scan_id = 2;
@@ -201,6 +201,7 @@ messages!(
(Ping, Foreground),
(PrepareRename, Background),
(PrepareRenameResponse, Background),
+ (ExpandProjectEntryResponse, Foreground),
(ProjectEntryResponse, Foreground),
(RejoinRoom, Foreground),
(RejoinRoomResponse, Foreground),
@@ -256,7 +257,7 @@ request_messages!(
(CreateRoom, CreateRoomResponse),
(DeclineCall, Ack),
(DeleteProjectEntry, ProjectEntryResponse),
- (ExpandProjectEntry, Ack),
+ (ExpandProjectEntry, ExpandProjectEntryResponse),
(Follow, FollowResponse),
(FormatBuffers, FormatBuffersResponse),
(GetChannelMessages, GetChannelMessagesResponse),