Update tab's modified icon via a saved event emitted from buffer

Max Brunsfeld created

Change summary

zed/src/editor/buffer/mod.rs        |  5 +++++
zed/src/editor/buffer_view.rs       | 20 +++++++++++++-------
zed/src/editor/display_map/mod.rs   |  1 +
zed/src/file_finder.rs              |  2 +-
zed/src/workspace/workspace_view.rs | 24 +++++++++++++++++-------
5 files changed, 37 insertions(+), 15 deletions(-)

Detailed changes

zed/src/editor/buffer/mod.rs 🔗

@@ -244,6 +244,10 @@ impl Buffer {
     pub fn save(&self, ctx: &mut ModelContext<Self>) -> Option<Task<Result<()>>> {
         if let Some(file) = &self.file {
             let snapshot = self.snapshot();
+
+            // TODO - don't emit this until the save has finished
+            ctx.emit(Event::Saved);
+
             Some(file.save(snapshot, ctx.app()))
         } else {
             None
@@ -1395,6 +1399,7 @@ impl Snapshot {
 #[derive(Clone, Debug, Eq, PartialEq)]
 pub enum Event {
     Edited(Vec<Edit>),
+    Saved,
 }
 
 impl Entity for Buffer {

zed/src/editor/buffer_view.rs 🔗

@@ -2,12 +2,15 @@ use super::{
     buffer, movement, Anchor, Bias, Buffer, BufferElement, DisplayMap, DisplayPoint, Point,
     ToOffset, ToPoint,
 };
-use crate::{settings::Settings, watch, workspace};
+use crate::{
+    settings::Settings,
+    watch,
+    workspace::{self, ItemEventEffect},
+};
 use anyhow::Result;
 use gpui::{
     fonts::Properties as FontProperties, keymap::Binding, text_layout, App, AppContext, Element,
-    ElementBox, Entity, FontCache, ModelHandle, MutableAppContext, Task, View, ViewContext,
-    WeakViewHandle,
+    ElementBox, Entity, FontCache, ModelHandle, Task, View, ViewContext, WeakViewHandle,
 };
 use gpui::{geometry::vector::Vector2F, TextLayoutCache};
 use parking_lot::Mutex;
@@ -1091,6 +1094,7 @@ impl BufferView {
     ) {
         match event {
             buffer::Event::Edited(_) => ctx.emit(Event::Edited),
+            buffer::Event::Saved => ctx.emit(Event::Saved),
         }
     }
 }
@@ -1106,6 +1110,7 @@ pub enum Event {
     Activate,
     Edited,
     Blurred,
+    Saved,
 }
 
 impl Entity for BufferView {
@@ -1147,10 +1152,11 @@ impl workspace::Item for Buffer {
 }
 
 impl workspace::ItemView for BufferView {
-    fn is_activate_event(event: &Self::Event) -> bool {
+    fn event_effect(event: &Self::Event) -> ItemEventEffect {
         match event {
-            Event::Activate => true,
-            _ => false,
+            Event::Activate => ItemEventEffect::Activate,
+            Event::Edited => ItemEventEffect::ChangeTab,
+            _ => ItemEventEffect::None,
         }
     }
 
@@ -1178,7 +1184,7 @@ impl workspace::ItemView for BufferView {
         Some(clone)
     }
 
-    fn save(&self, ctx: &mut MutableAppContext) -> Option<Task<Result<()>>> {
+    fn save(&self, ctx: &mut ViewContext<Self>) -> Option<Task<Result<()>>> {
         self.buffer.update(ctx, |buffer, ctx| buffer.save(ctx))
     }
 

zed/src/editor/display_map/mod.rs 🔗

@@ -126,6 +126,7 @@ impl DisplayMap {
     fn handle_buffer_event(&mut self, event: &buffer::Event, ctx: &mut ModelContext<Self>) {
         match event {
             buffer::Event::Edited(edits) => self.fold_map.apply_edits(edits, ctx.app()).unwrap(),
+            _ => {}
         }
     }
 }

zed/src/file_finder.rs 🔗

@@ -309,7 +309,7 @@ impl FileFinder {
                 }
             }
             Blurred => ctx.emit(Event::Dismissed),
-            Activate => {}
+            _ => {}
         }
     }
 

zed/src/workspace/workspace_view.rs 🔗

@@ -12,8 +12,14 @@ pub fn init(app: &mut App) {
     app.add_bindings(vec![Binding::new("cmd-s", "workspace:save", None)]);
 }
 
+pub enum ItemEventEffect {
+    None,
+    ChangeTab,
+    Activate,
+}
+
 pub trait ItemView: View {
-    fn is_activate_event(event: &Self::Event) -> bool;
+    fn event_effect(event: &Self::Event) -> ItemEventEffect;
     fn title(&self, app: &AppContext) -> String;
     fn entry_id(&self, app: &AppContext) -> Option<(usize, usize)>;
     fn clone_on_split(&self, _: &mut ViewContext<Self>) -> Option<Self>
@@ -25,7 +31,7 @@ pub trait ItemView: View {
     fn is_modified(&self, _: &AppContext) -> bool {
         false
     }
-    fn save(&self, _: &mut MutableAppContext) -> Option<Task<anyhow::Result<()>>> {
+    fn save(&self, _: &mut ViewContext<Self>) -> Option<Task<anyhow::Result<()>>> {
         None
     }
 }
@@ -65,18 +71,22 @@ impl<T: ItemView> ItemViewHandle for ViewHandle<T> {
     fn set_parent_pane(&self, pane: &ViewHandle<Pane>, app: &mut MutableAppContext) {
         pane.update(app, |_, ctx| {
             ctx.subscribe_to_view(self, |pane, item, event, ctx| {
-                if T::is_activate_event(event) {
-                    if let Some(ix) = pane.item_index(&item) {
-                        pane.activate_item(ix, ctx);
-                        pane.activate(ctx);
+                match T::event_effect(event) {
+                    ItemEventEffect::Activate => {
+                        if let Some(ix) = pane.item_index(&item) {
+                            pane.activate_item(ix, ctx);
+                            pane.activate(ctx);
+                        }
                     }
+                    ItemEventEffect::ChangeTab => ctx.notify(),
+                    _ => {}
                 }
             })
         })
     }
 
     fn save(&self, ctx: &mut MutableAppContext) -> Option<Task<anyhow::Result<()>>> {
-        self.update(ctx, |item, ctx| item.save(ctx.app_mut()))
+        self.update(ctx, |item, ctx| item.save(ctx))
     }
 
     fn is_modified(&self, ctx: &AppContext) -> bool {