diff --git a/crates/project/src/project.rs b/crates/project/src/project.rs index e188ebd5e32947777f987ff43df52f09d006d58f..86cd849212e12802b4b1e24ae308113004532141 100644 --- a/crates/project/src/project.rs +++ b/crates/project/src/project.rs @@ -1035,6 +1035,7 @@ impl Project { client.add_entity_request_handler(Self::handle_open_new_buffer); client.add_entity_message_handler(Self::handle_create_buffer_for_peer); client.add_entity_message_handler(Self::handle_toggle_lsp_logs); + client.add_entity_request_handler(Self::handle_load_binary_file); WorktreeStore::init(&client); BufferStore::init(&client); @@ -5169,6 +5170,22 @@ impl Project { }) } + async fn handle_load_binary_file( + this: Entity, + envelope: TypedEnvelope, + mut cx: AsyncApp, + ) -> Result { + // let peer_id = envelope.original_sender_id()?; + // let worktree_id = WorktreeId::from_proto(envelope.payload.worktree_id); + // let path = RelPath::from_proto(&envelope.payload.path)?; + // let open_buffer = this + // .update(&mut cx, |this, cx| { + // this.open_buffer(ProjectPath { worktree_id, path }, cx) + // })? + // .await?; + // Project::respond_to_open_buffer_request(this, open_buffer, peer_id, &mut cx) + } + fn set_worktrees_from_proto( &mut self, worktrees: Vec, diff --git a/crates/proto/proto/worktree.proto b/crates/proto/proto/worktree.proto index 9ab9e95438d220834351308ea83ffe9a18dec999..0fcafe1a2b6d1ebd181d437ebfdd5bf6b22321ce 100644 --- a/crates/proto/proto/worktree.proto +++ b/crates/proto/proto/worktree.proto @@ -158,3 +158,14 @@ message UpdateUserSettings { uint64 project_id = 1; string contents = 2; } + +message LoadBinaryFile{ + uint64 project_id = 1; + uint64 worktree_id = 2; + string path = 3; +} + +message BinaryFileResponse { + Entry entry = 1; + bytes content = 2; +} diff --git a/crates/proto/proto/zed.proto b/crates/proto/proto/zed.proto index 44450f83d1e6554e80fac951f5cb5e28dd830de1..7c4abab39be8c109b6f3e365859617dab7f0f214 100644 --- a/crates/proto/proto/zed.proto +++ b/crates/proto/proto/zed.proto @@ -427,7 +427,10 @@ message Envelope { GetTreeDiffResponse get_tree_diff_response = 385; GetBlobContent get_blob_content = 386; - GetBlobContentResponse get_blob_content_response = 387; // current max + GetBlobContentResponse get_blob_content_response = 387; + + LoadBinaryFile load_binary_file = 388; + BinaryFileResponse binary_file_response = 389; // current max } reserved 87 to 88; diff --git a/crates/proto/src/proto.rs b/crates/proto/src/proto.rs index af9bf99a721b4450b746043fbb7411dfa182d1fa..827810e5ec330a0785c36062bd32d36f6133de69 100644 --- a/crates/proto/src/proto.rs +++ b/crates/proto/src/proto.rs @@ -157,6 +157,8 @@ messages!( (ListToolchainsResponse, Foreground), (LoadCommitDiff, Foreground), (LoadCommitDiffResponse, Foreground), + (LoadBinaryFile, Background), + (BinaryFileResponse, Background), (LspExtExpandMacro, Background), (LspExtExpandMacroResponse, Background), (LspExtOpenDocs, Background), @@ -389,6 +391,7 @@ request_messages!( (LeaveChannelBuffer, Ack), (LeaveRoom, Ack), (LoadCommitDiff, LoadCommitDiffResponse), + (LoadBinaryFile, BinaryFileResponse), (MarkNotificationRead, Ack), (MoveChannel, Ack), (OnTypeFormatting, OnTypeFormattingResponse), diff --git a/crates/remote_server/src/headless_project.rs b/crates/remote_server/src/headless_project.rs index 5d50853601b3949835a350559d48ef755419c93d..5801d81dd98bb3d85a60044d09b9ffeede376fe9 100644 --- a/crates/remote_server/src/headless_project.rs +++ b/crates/remote_server/src/headless_project.rs @@ -259,6 +259,7 @@ impl HeadlessProject { session.add_entity_request_handler(Self::handle_open_server_settings); session.add_entity_request_handler(Self::handle_get_directory_environment); session.add_entity_message_handler(Self::handle_toggle_lsp_logs); + session.add_entity_request_handler(Self::handle_load_binary_file); session.add_entity_request_handler(BufferStore::handle_update_buffer); session.add_entity_message_handler(BufferStore::handle_close_buffer); @@ -629,6 +630,34 @@ impl HeadlessProject { }) } + pub async fn handle_load_binary_file( + this: Entity, + message: TypedEnvelope, + mut cx: AsyncApp, + ) -> Result { + // let worktree_id = WorktreeId::from_proto(message.payload.worktree_id); + // let path = RelPath::from_proto(&message.payload.path)?; + // let (buffer_store, buffer) = this.update(&mut cx, |this, cx| { + // let buffer_store = this.buffer_store.clone(); + // let buffer = this.buffer_store.update(cx, |buffer_store, cx| { + // buffer_store.open_buffer(ProjectPath { worktree_id, path }, cx) + // }); + // anyhow::Ok((buffer_store, buffer)) + // })??; + + // let buffer = buffer.await?; + // let buffer_id = buffer.read_with(&cx, |b, _| b.remote_id())?; + // buffer_store.update(&mut cx, |buffer_store, cx| { + // buffer_store + // .create_buffer_for_peer(&buffer, REMOTE_SERVER_PEER_ID, cx) + // .detach_and_log_err(cx); + // })?; + + // Ok(proto::OpenBufferResponse { + // buffer_id: buffer_id.to_proto(), + // }) + } + async fn handle_find_search_candidates( this: Entity, envelope: TypedEnvelope, diff --git a/crates/worktree/src/worktree.rs b/crates/worktree/src/worktree.rs index a4d3f61141c8b05a7ff2ccf2ef0df5896833f199..f17804b995904bebf4497540fae74ffaf40fbb0f 100644 --- a/crates/worktree/src/worktree.rs +++ b/crates/worktree/src/worktree.rs @@ -719,9 +719,7 @@ impl Worktree { ) -> Task> { match self { Worktree::Local(this) => this.load_binary_file(path, cx), - Worktree::Remote(_) => { - Task::ready(Err(anyhow!("remote worktrees can't yet load binary files"))) - } + Worktree::Remote(this) => this.load_binary_file(path, cx), } } @@ -1970,7 +1968,7 @@ impl RemoteWorktree { paths_to_copy: Vec>, local_fs: Arc, cx: &Context, - ) -> Task>> { + ) -> Task>> { let client = self.client.clone(); let worktree_id = self.id().to_proto(); let project_id = self.project_id; @@ -2028,6 +2026,33 @@ impl RemoteWorktree { Ok(copied_entry_ids) }) } + + fn load_binary_file( + &self, + path: &RelPath, + cx: &Context, + ) -> Task> { + let path = Arc::from(path); + let abs_path = self.absolutize(&path); + // let fs = self.fs.clone(); + // let entry = self.refresh_entry(path.clone(), None, cx); + // let is_private = self.is_path_private(&path); + let response = self.client.request(proto::LoadBinaryFile{ + path: path.to_proto(), + project_id: self.project_id(), + worktree_id: self.id().to_proto(), + }); + let worktree = cx.weak_entity(); + cx.background_spawn(async move { + let proto::BinaryFileResponse { entry, content } = response.await?; + let worktree = worktree.upgrade().context("worktree was dropped")?; + // TODO: check is_private + Ok(LoadedBinaryFile { + file: File::for_entry(entry.unwrap().into(), worktree), + content, + }) + }) + } } impl Snapshot { @@ -5551,7 +5576,7 @@ impl CreatedEntry { } } -fn parse_gitfile(content: &str) -> anyhow::Result<&Path> { +fn parse_gitfile(content: &str) -> Result<&Path> { let path = content .strip_prefix("gitdir:") .with_context(|| format!("parsing gitfile content {content:?}"))?;