Allow deleting entries from the project panel

This commit is contained in:
Max Brunsfeld 2022-05-04 17:53:29 -07:00
parent 509ede0e80
commit 4b1c46fa45
9 changed files with 198 additions and 8 deletions

View file

@ -263,6 +263,7 @@ impl Project {
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_rename_project_entry);
client.add_model_request_handler(Self::handle_delete_project_entry);
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_reload_buffers);
@ -768,6 +769,35 @@ impl Project {
}
}
pub fn delete_entry(
&mut self,
entry_id: ProjectEntryId,
cx: &mut ModelContext<Self>,
) -> Option<Task<Result<()>>> {
let worktree = self.worktree_for_entry(entry_id, cx)?;
if self.is_local() {
worktree.update(cx, |worktree, cx| {
worktree.as_local_mut().unwrap().delete_entry(entry_id, cx)
})
} else {
let client = self.client.clone();
let project_id = self.remote_id().unwrap();
Some(cx.spawn_weak(|_, mut cx| async move {
client
.request(proto::DeleteProjectEntry {
project_id,
entry_id: entry_id.to_proto(),
})
.await?;
worktree
.update(&mut cx, move |worktree, cx| {
worktree.as_remote().unwrap().delete_entry(entry_id, cx)
})
.await
}))
}
}
pub fn can_share(&self, cx: &AppContext) -> bool {
self.is_local() && self.visible_worktrees(cx).next().is_some()
}
@ -3858,6 +3888,21 @@ impl Project {
})
}
async fn handle_delete_project_entry(
this: ModelHandle<Self>,
envelope: TypedEnvelope<proto::DeleteProjectEntry>,
_: Arc<Client>,
mut cx: AsyncAppContext,
) -> Result<proto::Ack> {
this.update(&mut cx, |this, cx| {
let entry_id = ProjectEntryId::from_proto(envelope.payload.entry_id);
this.delete_entry(entry_id, cx)
.ok_or_else(|| anyhow!("invalid entry"))
})?
.await?;
Ok(proto::Ack {})
}
async fn handle_update_diagnostic_summary(
this: ModelHandle<Self>,
envelope: TypedEnvelope<proto::UpdateDiagnosticSummary>,

View file

@ -1,4 +1,4 @@
use crate::ProjectEntryId;
use crate::{ProjectEntryId, RemoveOptions};
use super::{
fs::{self, Fs},
@ -712,6 +712,44 @@ impl LocalWorktree {
self.write_entry_internal(path, Some(text), cx)
}
pub fn delete_entry(
&self,
entry_id: ProjectEntryId,
cx: &mut ModelContext<Worktree>,
) -> Option<Task<Result<()>>> {
let entry = self.entry_for_id(entry_id)?.clone();
let abs_path = self.absolutize(&entry.path);
let delete = cx.background().spawn({
let fs = self.fs.clone();
let abs_path = abs_path.clone();
async move {
if entry.is_file() {
fs.remove_file(&abs_path, Default::default()).await
} else {
fs.remove_dir(
&abs_path,
RemoveOptions {
recursive: true,
ignore_if_not_exists: false,
},
)
.await
}
}
});
Some(cx.spawn(|this, mut cx| async move {
delete.await?;
this.update(&mut cx, |this, _| {
let this = this.as_local_mut().unwrap();
let mut snapshot = this.background_snapshot.lock();
snapshot.delete_entry(entry_id);
});
this.update(&mut cx, |this, cx| this.poll_snapshot(cx));
Ok(())
}))
}
pub fn rename_entry(
&self,
entry_id: ProjectEntryId,
@ -1019,6 +1057,29 @@ impl RemoteWorktree {
})
})
}
pub(crate) fn delete_entry(
&self,
id: ProjectEntryId,
cx: &mut ModelContext<Worktree>,
) -> Task<Result<()>> {
cx.spawn(|this, mut cx| async move {
this.update(&mut cx, |worktree, _| {
worktree
.as_remote_mut()
.unwrap()
.finish_pending_remote_updates()
})
.await;
this.update(&mut cx, |worktree, _| {
let worktree = worktree.as_remote_mut().unwrap();
let mut snapshot = worktree.background_snapshot.lock();
snapshot.delete_entry(id);
worktree.snapshot = snapshot.clone();
});
Ok(())
})
}
}
impl Snapshot {
@ -1048,6 +1109,15 @@ impl Snapshot {
Ok(entry)
}
fn delete_entry(&mut self, entry_id: ProjectEntryId) -> bool {
if let Some(entry) = self.entries_by_id.remove(&entry_id, &()) {
self.entries_by_path.remove(&PathKey(entry.path), &());
true
} else {
false
}
}
pub(crate) fn apply_remote_update(&mut self, update: proto::UpdateWorktree) -> Result<()> {
let mut entries_by_path_edits = Vec::new();
let mut entries_by_id_edits = Vec::new();