mirror of
https://github.com/zed-industries/zed.git
synced 2025-01-28 21:32:39 +00:00
Allow guests to rename stuff
Co-Authored-By: Antonio Scandurra <me@as-cii.com> Co-Authored-By: Nathan Sobo <nathan@zed.dev>
This commit is contained in:
parent
470d693d5e
commit
438e4e7a19
7 changed files with 113 additions and 29 deletions
|
@ -127,6 +127,7 @@ impl Server {
|
||||||
.add_request_handler(Server::forward_project_request::<proto::ReloadBuffers>)
|
.add_request_handler(Server::forward_project_request::<proto::ReloadBuffers>)
|
||||||
.add_request_handler(Server::forward_project_request::<proto::FormatBuffers>)
|
.add_request_handler(Server::forward_project_request::<proto::FormatBuffers>)
|
||||||
.add_request_handler(Server::forward_project_request::<proto::CreateProjectEntry>)
|
.add_request_handler(Server::forward_project_request::<proto::CreateProjectEntry>)
|
||||||
|
.add_request_handler(Server::forward_project_request::<proto::RenameProjectEntry>)
|
||||||
.add_request_handler(Server::update_buffer)
|
.add_request_handler(Server::update_buffer)
|
||||||
.add_message_handler(Server::update_buffer_file)
|
.add_message_handler(Server::update_buffer_file)
|
||||||
.add_message_handler(Server::buffer_reloaded)
|
.add_message_handler(Server::buffer_reloaded)
|
||||||
|
@ -1810,7 +1811,7 @@ mod tests {
|
||||||
}
|
}
|
||||||
|
|
||||||
#[gpui::test(iterations = 10)]
|
#[gpui::test(iterations = 10)]
|
||||||
async fn test_worktree_manipulation(
|
async fn test_fs_operations(
|
||||||
executor: Arc<Deterministic>,
|
executor: Arc<Deterministic>,
|
||||||
cx_a: &mut TestAppContext,
|
cx_a: &mut TestAppContext,
|
||||||
cx_b: &mut TestAppContext,
|
cx_b: &mut TestAppContext,
|
||||||
|
@ -1848,14 +1849,12 @@ mod tests {
|
||||||
let worktree_b =
|
let worktree_b =
|
||||||
project_b.read_with(cx_b, |project, cx| project.worktrees(cx).next().unwrap());
|
project_b.read_with(cx_b, |project, cx| project.worktrees(cx).next().unwrap());
|
||||||
|
|
||||||
project_b
|
let entry = project_b
|
||||||
.update(cx_b, |project, cx| {
|
.update(cx_b, |project, cx| {
|
||||||
project.create_file((worktree_id, "c.txt"), cx).unwrap()
|
project.create_file((worktree_id, "c.txt"), cx).unwrap()
|
||||||
})
|
})
|
||||||
.await
|
.await
|
||||||
.unwrap();
|
.unwrap();
|
||||||
|
|
||||||
executor.run_until_parked();
|
|
||||||
worktree_a.read_with(cx_a, |worktree, _| {
|
worktree_a.read_with(cx_a, |worktree, _| {
|
||||||
assert_eq!(
|
assert_eq!(
|
||||||
worktree
|
worktree
|
||||||
|
@ -1874,6 +1873,32 @@ mod tests {
|
||||||
[".zed.toml", "a.txt", "b.txt", "c.txt"]
|
[".zed.toml", "a.txt", "b.txt", "c.txt"]
|
||||||
);
|
);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
project_b
|
||||||
|
.update(cx_b, |project, cx| {
|
||||||
|
project.rename_entry(entry.id, Path::new("d.txt"), cx)
|
||||||
|
})
|
||||||
|
.unwrap()
|
||||||
|
.await
|
||||||
|
.unwrap();
|
||||||
|
worktree_a.read_with(cx_a, |worktree, _| {
|
||||||
|
assert_eq!(
|
||||||
|
worktree
|
||||||
|
.paths()
|
||||||
|
.map(|p| p.to_string_lossy())
|
||||||
|
.collect::<Vec<_>>(),
|
||||||
|
[".zed.toml", "a.txt", "b.txt", "d.txt"]
|
||||||
|
);
|
||||||
|
});
|
||||||
|
worktree_b.read_with(cx_b, |worktree, _| {
|
||||||
|
assert_eq!(
|
||||||
|
worktree
|
||||||
|
.paths()
|
||||||
|
.map(|p| p.to_string_lossy())
|
||||||
|
.collect::<Vec<_>>(),
|
||||||
|
[".zed.toml", "a.txt", "b.txt", "d.txt"]
|
||||||
|
);
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
#[gpui::test(iterations = 10)]
|
#[gpui::test(iterations = 10)]
|
||||||
|
|
|
@ -262,6 +262,7 @@ impl Project {
|
||||||
client.add_model_message_handler(Self::handle_update_diagnostic_summary);
|
client.add_model_message_handler(Self::handle_update_diagnostic_summary);
|
||||||
client.add_model_message_handler(Self::handle_update_worktree);
|
client.add_model_message_handler(Self::handle_update_worktree);
|
||||||
client.add_model_request_handler(Self::handle_create_project_entry);
|
client.add_model_request_handler(Self::handle_create_project_entry);
|
||||||
|
client.add_model_request_handler(Self::handle_rename_project_entry);
|
||||||
client.add_model_request_handler(Self::handle_apply_additional_edits_for_completion);
|
client.add_model_request_handler(Self::handle_apply_additional_edits_for_completion);
|
||||||
client.add_model_request_handler(Self::handle_apply_code_action);
|
client.add_model_request_handler(Self::handle_apply_code_action);
|
||||||
client.add_model_request_handler(Self::handle_reload_buffers);
|
client.add_model_request_handler(Self::handle_reload_buffers);
|
||||||
|
@ -736,9 +737,9 @@ impl Project {
|
||||||
new_path: impl Into<Arc<Path>>,
|
new_path: impl Into<Arc<Path>>,
|
||||||
cx: &mut ModelContext<Self>,
|
cx: &mut ModelContext<Self>,
|
||||||
) -> Option<Task<Result<Entry>>> {
|
) -> Option<Task<Result<Entry>>> {
|
||||||
|
let worktree = self.worktree_for_entry(entry_id, cx)?;
|
||||||
|
let new_path = new_path.into();
|
||||||
if self.is_local() {
|
if self.is_local() {
|
||||||
let worktree = self.worktree_for_entry(entry_id, cx)?;
|
|
||||||
|
|
||||||
worktree.update(cx, |worktree, cx| {
|
worktree.update(cx, |worktree, cx| {
|
||||||
worktree
|
worktree
|
||||||
.as_local_mut()
|
.as_local_mut()
|
||||||
|
@ -746,7 +747,27 @@ impl Project {
|
||||||
.rename_entry(entry_id, new_path, cx)
|
.rename_entry(entry_id, new_path, cx)
|
||||||
})
|
})
|
||||||
} else {
|
} else {
|
||||||
todo!()
|
let client = self.client.clone();
|
||||||
|
let project_id = self.remote_id().unwrap();
|
||||||
|
|
||||||
|
Some(cx.spawn_weak(|_, mut cx| async move {
|
||||||
|
let response = client
|
||||||
|
.request(proto::RenameProjectEntry {
|
||||||
|
project_id,
|
||||||
|
entry_id: entry_id.to_proto(),
|
||||||
|
new_path: new_path.as_os_str().as_bytes().to_vec(),
|
||||||
|
})
|
||||||
|
.await?;
|
||||||
|
worktree.update(&mut cx, |worktree, _| {
|
||||||
|
let worktree = worktree.as_remote_mut().unwrap();
|
||||||
|
worktree.snapshot.remove_entry(entry_id);
|
||||||
|
worktree.snapshot.insert_entry(
|
||||||
|
response
|
||||||
|
.entry
|
||||||
|
.ok_or_else(|| anyhow!("missing entry in response"))?,
|
||||||
|
)
|
||||||
|
})
|
||||||
|
}))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -3802,7 +3823,7 @@ impl Project {
|
||||||
envelope: TypedEnvelope<proto::CreateProjectEntry>,
|
envelope: TypedEnvelope<proto::CreateProjectEntry>,
|
||||||
_: Arc<Client>,
|
_: Arc<Client>,
|
||||||
mut cx: AsyncAppContext,
|
mut cx: AsyncAppContext,
|
||||||
) -> Result<proto::CreateProjectEntryResponse> {
|
) -> Result<proto::ProjectEntryResponse> {
|
||||||
let entry = this
|
let entry = this
|
||||||
.update(&mut cx, |this, cx| {
|
.update(&mut cx, |this, cx| {
|
||||||
let worktree_id = WorktreeId::from_proto(envelope.payload.worktree_id);
|
let worktree_id = WorktreeId::from_proto(envelope.payload.worktree_id);
|
||||||
|
@ -3820,7 +3841,26 @@ impl Project {
|
||||||
})
|
})
|
||||||
})?
|
})?
|
||||||
.await?;
|
.await?;
|
||||||
Ok(proto::CreateProjectEntryResponse {
|
Ok(proto::ProjectEntryResponse {
|
||||||
|
entry: Some((&entry).into()),
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
async fn handle_rename_project_entry(
|
||||||
|
this: ModelHandle<Self>,
|
||||||
|
envelope: TypedEnvelope<proto::RenameProjectEntry>,
|
||||||
|
_: Arc<Client>,
|
||||||
|
mut cx: AsyncAppContext,
|
||||||
|
) -> Result<proto::ProjectEntryResponse> {
|
||||||
|
let entry = this
|
||||||
|
.update(&mut cx, |this, cx| {
|
||||||
|
let entry_id = ProjectEntryId::from_proto(envelope.payload.entry_id);
|
||||||
|
let new_path = PathBuf::from(OsString::from_vec(envelope.payload.new_path));
|
||||||
|
this.rename_entry(entry_id, new_path, cx)
|
||||||
|
.ok_or_else(|| anyhow!("invalid entry"))
|
||||||
|
})?
|
||||||
|
.await?;
|
||||||
|
Ok(proto::ProjectEntryResponse {
|
||||||
entry: Some((&entry).into()),
|
entry: Some((&entry).into()),
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
|
@ -956,6 +956,14 @@ impl Snapshot {
|
||||||
self.entries_by_id.get(&entry_id, &()).is_some()
|
self.entries_by_id.get(&entry_id, &()).is_some()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub(crate) fn remove_entry(&mut self, entry_id: ProjectEntryId) -> Option<Entry> {
|
||||||
|
if let Some(entry) = self.entries_by_id.remove(&entry_id, &()) {
|
||||||
|
self.entries_by_path.remove(&PathKey(entry.path), &())
|
||||||
|
} else {
|
||||||
|
None
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
pub(crate) fn insert_entry(&mut self, entry: proto::Entry) -> Result<Entry> {
|
pub(crate) fn insert_entry(&mut self, entry: proto::Entry) -> Result<Entry> {
|
||||||
let entry = Entry::try_from((&self.root_char_bag, entry))?;
|
let entry = Entry::try_from((&self.root_char_bag, entry))?;
|
||||||
self.entries_by_id.insert_or_replace(
|
self.entries_by_id.insert_or_replace(
|
||||||
|
|
|
@ -295,11 +295,6 @@ impl ProjectPanel {
|
||||||
Ok(())
|
Ok(())
|
||||||
}))
|
}))
|
||||||
} else {
|
} else {
|
||||||
// TODO - implement this for remote projects
|
|
||||||
if !worktree.read(cx).is_local() {
|
|
||||||
return None;
|
|
||||||
}
|
|
||||||
|
|
||||||
let old_path = entry.path.clone();
|
let old_path = entry.path.clone();
|
||||||
let new_path = if let Some(parent) = old_path.parent() {
|
let new_path = if let Some(parent) = old_path.parent() {
|
||||||
parent.join(filename)
|
parent.join(filename)
|
||||||
|
|
|
@ -38,9 +38,9 @@ message Envelope {
|
||||||
UpdateWorktree update_worktree = 31;
|
UpdateWorktree update_worktree = 31;
|
||||||
|
|
||||||
CreateProjectEntry create_project_entry = 32;
|
CreateProjectEntry create_project_entry = 32;
|
||||||
CreateProjectEntryResponse create_project_entry_response = 33;
|
RenameProjectEntry rename_project_entry = 33;
|
||||||
RenameProjectEntry rename_project_entry = 34;
|
DeleteProjectEntry delete_project_entry = 34;
|
||||||
DeleteProjectEntry delete_project_entry = 35;
|
ProjectEntryResponse project_entry_response = 35;
|
||||||
|
|
||||||
UpdateDiagnosticSummary update_diagnostic_summary = 36;
|
UpdateDiagnosticSummary update_diagnostic_summary = 36;
|
||||||
StartLanguageServer start_language_server = 37;
|
StartLanguageServer start_language_server = 37;
|
||||||
|
@ -171,16 +171,10 @@ message CreateProjectEntry {
|
||||||
bool is_directory = 4;
|
bool is_directory = 4;
|
||||||
}
|
}
|
||||||
|
|
||||||
message CreateProjectEntryResponse {
|
|
||||||
Entry entry = 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
message RenameProjectEntry {
|
message RenameProjectEntry {
|
||||||
uint64 project_id = 1;
|
uint64 project_id = 1;
|
||||||
uint64 old_worktree_id = 2;
|
uint64 entry_id = 2;
|
||||||
string old_path = 3;
|
bytes new_path = 3;
|
||||||
uint64 new_worktree_id = 4;
|
|
||||||
string new_path = 5;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
message DeleteProjectEntry {
|
message DeleteProjectEntry {
|
||||||
|
@ -189,6 +183,10 @@ message DeleteProjectEntry {
|
||||||
string path = 3;
|
string path = 3;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
message ProjectEntryResponse {
|
||||||
|
Entry entry = 1;
|
||||||
|
}
|
||||||
|
|
||||||
message AddProjectCollaborator {
|
message AddProjectCollaborator {
|
||||||
uint64 project_id = 1;
|
uint64 project_id = 1;
|
||||||
Collaborator collaborator = 2;
|
Collaborator collaborator = 2;
|
||||||
|
|
|
@ -148,7 +148,6 @@ messages!(
|
||||||
(BufferSaved, Foreground),
|
(BufferSaved, Foreground),
|
||||||
(ChannelMessageSent, Foreground),
|
(ChannelMessageSent, Foreground),
|
||||||
(CreateProjectEntry, Foreground),
|
(CreateProjectEntry, Foreground),
|
||||||
(CreateProjectEntryResponse, Foreground),
|
|
||||||
(DeleteProjectEntry, Foreground),
|
(DeleteProjectEntry, Foreground),
|
||||||
(Error, Foreground),
|
(Error, Foreground),
|
||||||
(Follow, Foreground),
|
(Follow, Foreground),
|
||||||
|
@ -177,8 +176,6 @@ messages!(
|
||||||
(JoinChannelResponse, Foreground),
|
(JoinChannelResponse, Foreground),
|
||||||
(JoinProject, Foreground),
|
(JoinProject, Foreground),
|
||||||
(JoinProjectResponse, Foreground),
|
(JoinProjectResponse, Foreground),
|
||||||
(StartLanguageServer, Foreground),
|
|
||||||
(UpdateLanguageServer, Foreground),
|
|
||||||
(LeaveChannel, Foreground),
|
(LeaveChannel, Foreground),
|
||||||
(LeaveProject, Foreground),
|
(LeaveProject, Foreground),
|
||||||
(OpenBufferById, Background),
|
(OpenBufferById, Background),
|
||||||
|
@ -190,6 +187,7 @@ messages!(
|
||||||
(PerformRenameResponse, Background),
|
(PerformRenameResponse, Background),
|
||||||
(PrepareRename, Background),
|
(PrepareRename, Background),
|
||||||
(PrepareRenameResponse, Background),
|
(PrepareRenameResponse, Background),
|
||||||
|
(ProjectEntryResponse, Foreground),
|
||||||
(RegisterProjectResponse, Foreground),
|
(RegisterProjectResponse, Foreground),
|
||||||
(Ping, Foreground),
|
(Ping, Foreground),
|
||||||
(RegisterProject, Foreground),
|
(RegisterProject, Foreground),
|
||||||
|
@ -204,6 +202,7 @@ messages!(
|
||||||
(SendChannelMessage, Foreground),
|
(SendChannelMessage, Foreground),
|
||||||
(SendChannelMessageResponse, Foreground),
|
(SendChannelMessageResponse, Foreground),
|
||||||
(ShareProject, Foreground),
|
(ShareProject, Foreground),
|
||||||
|
(StartLanguageServer, Foreground),
|
||||||
(Test, Foreground),
|
(Test, Foreground),
|
||||||
(Unfollow, Foreground),
|
(Unfollow, Foreground),
|
||||||
(UnregisterProject, Foreground),
|
(UnregisterProject, Foreground),
|
||||||
|
@ -214,6 +213,7 @@ messages!(
|
||||||
(UpdateContacts, Foreground),
|
(UpdateContacts, Foreground),
|
||||||
(UpdateDiagnosticSummary, Foreground),
|
(UpdateDiagnosticSummary, Foreground),
|
||||||
(UpdateFollowers, Foreground),
|
(UpdateFollowers, Foreground),
|
||||||
|
(UpdateLanguageServer, Foreground),
|
||||||
(UpdateWorktree, Foreground),
|
(UpdateWorktree, Foreground),
|
||||||
);
|
);
|
||||||
|
|
||||||
|
@ -223,7 +223,7 @@ request_messages!(
|
||||||
ApplyCompletionAdditionalEdits,
|
ApplyCompletionAdditionalEdits,
|
||||||
ApplyCompletionAdditionalEditsResponse
|
ApplyCompletionAdditionalEditsResponse
|
||||||
),
|
),
|
||||||
(CreateProjectEntry, CreateProjectEntryResponse),
|
(CreateProjectEntry, ProjectEntryResponse),
|
||||||
(Follow, FollowResponse),
|
(Follow, FollowResponse),
|
||||||
(FormatBuffers, FormatBuffersResponse),
|
(FormatBuffers, FormatBuffersResponse),
|
||||||
(GetChannelMessages, GetChannelMessagesResponse),
|
(GetChannelMessages, GetChannelMessagesResponse),
|
||||||
|
@ -246,6 +246,7 @@ request_messages!(
|
||||||
(RegisterProject, RegisterProjectResponse),
|
(RegisterProject, RegisterProjectResponse),
|
||||||
(RegisterWorktree, Ack),
|
(RegisterWorktree, Ack),
|
||||||
(ReloadBuffers, ReloadBuffersResponse),
|
(ReloadBuffers, ReloadBuffersResponse),
|
||||||
|
(RenameProjectEntry, ProjectEntryResponse),
|
||||||
(SaveBuffer, BufferSaved),
|
(SaveBuffer, BufferSaved),
|
||||||
(SearchProject, SearchProjectResponse),
|
(SearchProject, SearchProjectResponse),
|
||||||
(SendChannelMessage, SendChannelMessageResponse),
|
(SendChannelMessage, SendChannelMessageResponse),
|
||||||
|
|
|
@ -502,6 +502,23 @@ impl<T: KeyedItem> SumTree<T> {
|
||||||
replaced
|
replaced
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn remove(&mut self, key: &T::Key, cx: &<T::Summary as Summary>::Context) -> Option<T> {
|
||||||
|
let mut removed = None;
|
||||||
|
*self = {
|
||||||
|
let mut cursor = self.cursor::<T::Key>();
|
||||||
|
let mut new_tree = cursor.slice(key, Bias::Left, cx);
|
||||||
|
if let Some(item) = cursor.item() {
|
||||||
|
if item.key() == *key {
|
||||||
|
removed = Some(item.clone());
|
||||||
|
cursor.next(cx);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
new_tree.push_tree(cursor.suffix(cx), cx);
|
||||||
|
new_tree
|
||||||
|
};
|
||||||
|
removed
|
||||||
|
}
|
||||||
|
|
||||||
pub fn edit(
|
pub fn edit(
|
||||||
&mut self,
|
&mut self,
|
||||||
mut edits: Vec<Edit<T>>,
|
mut edits: Vec<Edit<T>>,
|
||||||
|
|
Loading…
Reference in a new issue