Return a Task<Result<()>> in {ItemView,Buffer,MultiBuffer}::save

This commit is contained in:
Antonio Scandurra 2022-01-20 09:58:24 +01:00
parent 634340dd84
commit 71082d4cdc
7 changed files with 27 additions and 32 deletions

View file

@ -560,7 +560,7 @@ impl workspace::ItemView for ProjectDiagnosticsEditor {
true true
} }
fn save(&mut self, cx: &mut ViewContext<Self>) -> Result<Task<Result<()>>> { fn save(&mut self, cx: &mut ViewContext<Self>) -> Task<Result<()>> {
self.excerpts.update(cx, |excerpts, cx| excerpts.save(cx)) self.excerpts.update(cx, |excerpts, cx| excerpts.save(cx))
} }

View file

@ -160,20 +160,18 @@ impl ItemView for Editor {
self.project_entry(cx).is_some() self.project_entry(cx).is_some()
} }
fn save(&mut self, cx: &mut ViewContext<Self>) -> Result<Task<Result<()>>> { fn save(&mut self, cx: &mut ViewContext<Self>) -> Task<Result<()>> {
let buffer = self.buffer().clone(); let buffer = self.buffer().clone();
Ok(cx.spawn(|editor, mut cx| async move { cx.spawn(|editor, mut cx| async move {
buffer buffer
.update(&mut cx, |buffer, cx| buffer.format(cx).log_err()) .update(&mut cx, |buffer, cx| buffer.format(cx).log_err())
.await; .await;
editor.update(&mut cx, |editor, cx| { editor.update(&mut cx, |editor, cx| {
editor.request_autoscroll(Autoscroll::Fit, cx) editor.request_autoscroll(Autoscroll::Fit, cx)
}); });
buffer buffer.update(&mut cx, |buffer, cx| buffer.save(cx)).await?;
.update(&mut cx, |buffer, cx| buffer.save(cx))?
.await?;
Ok(()) Ok(())
})) })
} }
fn can_save_as(&self, _: &AppContext) -> bool { fn can_save_as(&self, _: &AppContext) -> bool {

View file

@ -812,18 +812,18 @@ impl MultiBuffer {
}) })
} }
pub fn save(&mut self, cx: &mut ModelContext<Self>) -> Result<Task<Result<()>>> { pub fn save(&mut self, cx: &mut ModelContext<Self>) -> Task<Result<()>> {
let mut save_tasks = Vec::new(); let mut save_tasks = Vec::new();
for BufferState { buffer, .. } in self.buffers.borrow().values() { for BufferState { buffer, .. } in self.buffers.borrow().values() {
save_tasks.push(buffer.update(cx, |buffer, cx| buffer.save(cx))?); save_tasks.push(buffer.update(cx, |buffer, cx| buffer.save(cx)));
} }
Ok(cx.spawn(|_, _| async move { cx.spawn(|_, _| async move {
for save in save_tasks { for save in save_tasks {
save.await?; save.await?;
} }
Ok(()) Ok(())
})) })
} }
pub fn language<'a>(&self, cx: &'a AppContext) -> Option<&'a Arc<Language>> { pub fn language<'a>(&self, cx: &'a AppContext) -> Option<&'a Arc<Language>> {

View file

@ -510,21 +510,22 @@ impl Buffer {
pub fn save( pub fn save(
&mut self, &mut self,
cx: &mut ModelContext<Self>, cx: &mut ModelContext<Self>,
) -> Result<Task<Result<(clock::Global, SystemTime)>>> { ) -> Task<Result<(clock::Global, SystemTime)>> {
let file = self let file = if let Some(file) = self.file.as_ref() {
.file file
.as_ref() } else {
.ok_or_else(|| anyhow!("buffer has no file"))?; return Task::ready(Err(anyhow!("buffer has no file")));
};
let text = self.as_rope().clone(); let text = self.as_rope().clone();
let version = self.version(); let version = self.version();
let save = file.save(self.remote_id(), text, version, cx.as_mut()); let save = file.save(self.remote_id(), text, version, cx.as_mut());
Ok(cx.spawn(|this, mut cx| async move { cx.spawn(|this, mut cx| async move {
let (version, mtime) = save.await?; let (version, mtime) = save.await?;
this.update(&mut cx, |this, cx| { this.update(&mut cx, |this, cx| {
this.did_save(version.clone(), mtime, None, cx); this.did_save(version.clone(), mtime, None, cx);
}); });
Ok((version, mtime)) Ok((version, mtime))
})) })
} }
pub fn set_language(&mut self, language: Option<Arc<Language>>, cx: &mut ModelContext<Self>) { pub fn set_language(&mut self, language: Option<Arc<Language>>, cx: &mut ModelContext<Self>) {

View file

@ -455,7 +455,7 @@ impl Worktree {
let worktree_id = envelope.payload.worktree_id; let worktree_id = envelope.payload.worktree_id;
let buffer_id = envelope.payload.buffer_id; let buffer_id = envelope.payload.buffer_id;
let save = cx.spawn(|_, mut cx| async move { let save = cx.spawn(|_, mut cx| async move {
buffer.update(&mut cx, |buffer, cx| buffer.save(cx))?.await buffer.update(&mut cx, |buffer, cx| buffer.save(cx)).await
}); });
cx.background() cx.background()
@ -3094,7 +3094,7 @@ mod tests {
.unwrap(); .unwrap();
let save = buffer.update(&mut cx, |buffer, cx| { let save = buffer.update(&mut cx, |buffer, cx| {
buffer.edit(Some(0..0), "a line of text.\n".repeat(10 * 1024), cx); buffer.edit(Some(0..0), "a line of text.\n".repeat(10 * 1024), cx);
buffer.save(cx).unwrap() buffer.save(cx)
}); });
save.await.unwrap(); save.await.unwrap();
@ -3132,7 +3132,7 @@ mod tests {
.unwrap(); .unwrap();
let save = buffer.update(&mut cx, |buffer, cx| { let save = buffer.update(&mut cx, |buffer, cx| {
buffer.edit(Some(0..0), "a line of text.\n".repeat(10 * 1024), cx); buffer.edit(Some(0..0), "a line of text.\n".repeat(10 * 1024), cx);
buffer.save(cx).unwrap() buffer.save(cx)
}); });
save.await.unwrap(); save.await.unwrap();

View file

@ -1474,7 +1474,7 @@ mod tests {
.await; .await;
// Edit the buffer as the host and concurrently save as guest B. // Edit the buffer as the host and concurrently save as guest B.
let save_b = buffer_b.update(&mut cx_b, |buf, cx| buf.save(cx).unwrap()); let save_b = buffer_b.update(&mut cx_b, |buf, cx| buf.save(cx));
buffer_a.update(&mut cx_a, |buf, cx| buf.edit([0..0], "hi-a, ", cx)); buffer_a.update(&mut cx_a, |buf, cx| buf.edit([0..0], "hi-a, ", cx));
save_b.await.unwrap(); save_b.await.unwrap();
assert_eq!( assert_eq!(
@ -1591,7 +1591,6 @@ mod tests {
buffer_b buffer_b
.update(&mut cx_b, |buf, cx| buf.save(cx)) .update(&mut cx_b, |buf, cx| buf.save(cx))
.unwrap()
.await .await
.unwrap(); .unwrap();
worktree_b worktree_b

View file

@ -168,14 +168,14 @@ pub trait ItemView: View {
false false
} }
fn can_save(&self, cx: &AppContext) -> bool; fn can_save(&self, cx: &AppContext) -> bool;
fn save(&mut self, cx: &mut ViewContext<Self>) -> Result<Task<Result<()>>>; fn save(&mut self, cx: &mut ViewContext<Self>) -> Task<Result<()>>;
fn can_save_as(&self, cx: &AppContext) -> bool; fn can_save_as(&self, cx: &AppContext) -> bool;
fn save_as( fn save_as(
&mut self, &mut self,
project: ModelHandle<Project>, project: ModelHandle<Project>,
abs_path: PathBuf, abs_path: PathBuf,
cx: &mut ViewContext<Self>, cx: &mut ViewContext<Self>,
) -> Task<anyhow::Result<()>>; ) -> Task<Result<()>>;
fn should_activate_item_on_event(_: &Self::Event) -> bool { fn should_activate_item_on_event(_: &Self::Event) -> bool {
false false
} }
@ -222,7 +222,7 @@ pub trait ItemViewHandle {
fn has_conflict(&self, cx: &AppContext) -> bool; fn has_conflict(&self, cx: &AppContext) -> bool;
fn can_save(&self, cx: &AppContext) -> bool; fn can_save(&self, cx: &AppContext) -> bool;
fn can_save_as(&self, cx: &AppContext) -> bool; fn can_save_as(&self, cx: &AppContext) -> bool;
fn save(&self, cx: &mut MutableAppContext) -> Result<Task<Result<()>>>; fn save(&self, cx: &mut MutableAppContext) -> Task<Result<()>>;
fn save_as( fn save_as(
&self, &self,
project: ModelHandle<Project>, project: ModelHandle<Project>,
@ -377,7 +377,7 @@ impl<T: ItemView> ItemViewHandle for ViewHandle<T> {
self.update(cx, |this, cx| this.navigate(data, cx)); self.update(cx, |this, cx| this.navigate(data, cx));
} }
fn save(&self, cx: &mut MutableAppContext) -> Result<Task<Result<()>>> { fn save(&self, cx: &mut MutableAppContext) -> Task<Result<()>> {
self.update(cx, |item, cx| item.save(cx)) self.update(cx, |item, cx| item.save(cx))
} }
@ -822,15 +822,12 @@ impl Workspace {
cx.spawn(|_, mut cx| async move { cx.spawn(|_, mut cx| async move {
let answer = answer.recv().await; let answer = answer.recv().await;
if answer == Some(0) { if answer == Some(0) {
cx.update(|cx| item.save(cx))?.await?; cx.update(|cx| item.save(cx)).await?;
} }
Ok(()) Ok(())
}) })
} else { } else {
cx.spawn(|_, mut cx| async move { item.save(cx)
cx.update(|cx| item.save(cx))?.await?;
Ok(())
})
} }
} else if item.can_save_as(cx) { } else if item.can_save_as(cx) {
let worktree = self.worktrees(cx).first(); let worktree = self.worktrees(cx).first();