Introduce `workspace::Item::reload` to manually trigger a reload

Antonio Scandurra created

Change summary

crates/diagnostics/src/diagnostics.rs |  8 ++++++++
crates/editor/src/items.rs            | 25 +++++++++++++++++++++++++
crates/search/src/project_search.rs   |  9 +++++++++
crates/workspace/src/workspace.rs     | 15 +++++++++++++++
4 files changed, 57 insertions(+)

Detailed changes

crates/diagnostics/src/diagnostics.rs 🔗

@@ -478,6 +478,14 @@ impl workspace::Item for ProjectDiagnosticsEditor {
         self.editor.save(project, cx)
     }
 
+    fn reload(
+        &mut self,
+        project: ModelHandle<Project>,
+        cx: &mut ViewContext<Self>,
+    ) -> Task<Result<()>> {
+        self.editor.reload(project, cx)
+    }
+
     fn can_save_as(&self, _: &AppContext) -> bool {
         false
     }

crates/editor/src/items.rs 🔗

@@ -371,6 +371,31 @@ impl Item for Editor {
         })
     }
 
+    fn reload(
+        &mut self,
+        project: ModelHandle<Project>,
+        cx: &mut ViewContext<Self>,
+    ) -> Task<Result<()>> {
+        let buffer = self.buffer().clone();
+        let buffers = self.buffer.read(cx).all_buffers();
+        let reload_buffers =
+            project.update(cx, |project, cx| project.reload_buffers(buffers, true, cx));
+        cx.spawn(|this, mut cx| async move {
+            let transaction = reload_buffers.log_err().await;
+            this.update(&mut cx, |editor, cx| {
+                editor.request_autoscroll(Autoscroll::Fit, cx)
+            });
+            buffer.update(&mut cx, |buffer, _| {
+                if let Some(transaction) = transaction {
+                    if !buffer.is_singleton() {
+                        buffer.push_transaction(&transaction.0);
+                    }
+                }
+            });
+            Ok(())
+        })
+    }
+
     fn should_activate_item_on_event(event: &Event) -> bool {
         matches!(event, Event::Activate)
     }

crates/search/src/project_search.rs 🔗

@@ -280,6 +280,15 @@ impl Item for ProjectSearchView {
         unreachable!("save_as should not have been called")
     }
 
+    fn reload(
+        &mut self,
+        project: ModelHandle<Project>,
+        cx: &mut ViewContext<Self>,
+    ) -> Task<anyhow::Result<()>> {
+        self.results_editor
+            .update(cx, |editor, cx| editor.reload(project, cx))
+    }
+
     fn clone_on_split(&self, cx: &mut ViewContext<Self>) -> Option<Self>
     where
         Self: Sized,

crates/workspace/src/workspace.rs 🔗

@@ -237,6 +237,11 @@ pub trait Item: View {
         abs_path: PathBuf,
         cx: &mut ViewContext<Self>,
     ) -> Task<Result<()>>;
+    fn reload(
+        &mut self,
+        project: ModelHandle<Project>,
+        cx: &mut ViewContext<Self>,
+    ) -> Task<Result<()>>;
     fn should_activate_item_on_event(_: &Self::Event) -> bool {
         false
     }
@@ -380,6 +385,8 @@ pub trait ItemHandle: 'static + fmt::Debug {
         abs_path: PathBuf,
         cx: &mut MutableAppContext,
     ) -> Task<Result<()>>;
+    fn reload(&self, project: ModelHandle<Project>, cx: &mut MutableAppContext)
+        -> Task<Result<()>>;
     fn act_as_type(&self, type_id: TypeId, cx: &AppContext) -> Option<AnyViewHandle>;
     fn to_followable_item_handle(&self, cx: &AppContext) -> Option<Box<dyn FollowableItemHandle>>;
 }
@@ -531,6 +538,14 @@ impl<T: Item> ItemHandle for ViewHandle<T> {
         self.update(cx, |item, cx| item.save_as(project, abs_path, cx))
     }
 
+    fn reload(
+        &self,
+        project: ModelHandle<Project>,
+        cx: &mut MutableAppContext,
+    ) -> Task<Result<()>> {
+        self.update(cx, |item, cx| item.reload(project, cx))
+    }
+
     fn is_dirty(&self, cx: &AppContext) -> bool {
         self.read(cx).is_dirty(cx)
     }