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

This commit is contained in:
Max Brunsfeld 2021-04-06 15:47:05 -07:00
parent dabd6abe37
commit bd37b11306
5 changed files with 37 additions and 15 deletions

View file

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

View file

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

View file

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

View file

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

View file

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