diff --git a/zed/src/editor/buffer/mod.rs b/zed/src/editor/buffer/mod.rs index 82881afca3975f2259ea1b4a123c8cc7e13c198d..1951a764b7c368df37dabb39d41ef3ac6390d343 100644 --- a/zed/src/editor/buffer/mod.rs +++ b/zed/src/editor/buffer/mod.rs @@ -390,9 +390,11 @@ impl Buffer { move |this, history, ctx| { if let (Ok(history), true) = (history, this.version == version) { let task = this.set_text_via_diff(history.base_text, ctx); - ctx.spawn(task, |this, ops, _| { + ctx.spawn(task, move |this, ops, ctx| { if ops.is_some() { this.saved_version = this.version.clone(); + this.saved_mtime = file.mtime(); + ctx.emit(Event::Reloaded); } }) .detach(); @@ -586,7 +588,7 @@ impl Buffer { && self .file .as_ref() - .map_or(false, |f| f.mtime() != self.saved_mtime) + .map_or(false, |f| f.mtime() > self.saved_mtime) } pub fn version(&self) -> time::Global { @@ -1931,6 +1933,7 @@ pub enum Event { Dirtied, Saved, FileHandleChanged, + Reloaded, } impl Entity for Buffer { diff --git a/zed/src/editor/buffer_view.rs b/zed/src/editor/buffer_view.rs index a76f558b96784d5686a5a3b1d0c75e15285a4b24..c2aef72ff103fa48e7c07f201b366fdf31ab8137 100644 --- a/zed/src/editor/buffer_view.rs +++ b/zed/src/editor/buffer_view.rs @@ -2401,6 +2401,7 @@ impl BufferView { buffer::Event::Dirtied => ctx.emit(Event::Dirtied), buffer::Event::Saved => ctx.emit(Event::Saved), buffer::Event::FileHandleChanged => ctx.emit(Event::FileHandleChanged), + buffer::Event::Reloaded => ctx.emit(Event::FileHandleChanged), } } } @@ -2505,6 +2506,10 @@ impl workspace::ItemView for BufferView { fn is_dirty(&self, ctx: &AppContext) -> bool { self.buffer.read(ctx).is_dirty() } + + fn has_conflict(&self, ctx: &AppContext) -> bool { + self.buffer.read(ctx).has_conflict() + } } #[cfg(test)] diff --git a/zed/src/workspace.rs b/zed/src/workspace.rs index 7253e0a5af9777bf50e3cd0d1fc56ff9159b2745..b60cd63487df9d838ad4a8cf544cca29d2a586e0 100644 --- a/zed/src/workspace.rs +++ b/zed/src/workspace.rs @@ -119,6 +119,9 @@ pub trait ItemView: View { fn is_dirty(&self, _: &AppContext) -> bool { false } + fn has_conflict(&self, _: &AppContext) -> bool { + false + } fn save( &mut self, _: Option, @@ -157,6 +160,7 @@ pub trait ItemViewHandle: Send + Sync { fn id(&self) -> usize; fn to_any(&self) -> AnyViewHandle; fn is_dirty(&self, ctx: &AppContext) -> bool; + fn has_conflict(&self, ctx: &AppContext) -> bool; fn save( &self, file: Option, @@ -247,6 +251,10 @@ impl ItemViewHandle for ViewHandle { self.read(ctx).is_dirty(ctx) } + fn has_conflict(&self, ctx: &AppContext) -> bool { + self.read(ctx).has_conflict(ctx) + } + fn id(&self) -> usize { self.id() } diff --git a/zed/src/workspace/pane.rs b/zed/src/workspace/pane.rs index e7957ec9489d0db6bcb103ef3c1cb4197a75c45e..4108ac67a540b69ac204b9a3de43d258dac215b9 100644 --- a/zed/src/workspace/pane.rs +++ b/zed/src/workspace/pane.rs @@ -228,6 +228,7 @@ impl Pane { line_height - 2., mouse_state.hovered, item.is_dirty(ctx), + item.has_conflict(ctx), ctx, )) .right() @@ -296,15 +297,25 @@ impl Pane { item_id: usize, close_icon_size: f32, tab_hovered: bool, - is_modified: bool, + is_dirty: bool, + has_conflict: bool, ctx: &AppContext, ) -> ElementBox { enum TabCloseButton {} - let modified_color = ColorU::from_u32(0x556de8ff); - let mut clicked_color = modified_color; + let dirty_color = ColorU::from_u32(0x556de8ff); + let conflict_color = ColorU::from_u32(0xe45349ff); + let mut clicked_color = dirty_color; clicked_color.a = 180; + let current_color = if has_conflict { + Some(conflict_color) + } else if is_dirty { + Some(dirty_color) + } else { + None + }; + let icon = if tab_hovered { let mut icon = Svg::new("icons/x.svg"); @@ -314,13 +325,13 @@ impl Pane { .with_background_color(if mouse_state.clicked { clicked_color } else { - modified_color + dirty_color }) .with_corner_radius(close_icon_size / 2.) .boxed() } else { - if is_modified { - icon = icon.with_color(modified_color); + if let Some(current_color) = current_color { + icon = icon.with_color(current_color); } icon.boxed() } @@ -331,11 +342,11 @@ impl Pane { let diameter = 8.; ConstrainedBox::new( Canvas::new(move |bounds, ctx| { - if is_modified { + if let Some(current_color) = current_color { let square = RectF::new(bounds.origin(), vec2f(diameter, diameter)); ctx.scene.push_quad(Quad { bounds: square, - background: Some(modified_color), + background: Some(current_color), border: Default::default(), corner_radius: diameter / 2., });