From d724387158a09453e7c72505e08856614e58bb2a Mon Sep 17 00:00:00 2001 From: Max Brunsfeld Date: Tue, 6 Apr 2021 18:25:50 -0700 Subject: [PATCH] wip --- Cargo.lock | 1 + zed/Cargo.toml | 1 + zed/src/editor/buffer/mod.rs | 33 ++++++++++++++--------- zed/src/editor/buffer_view.rs | 15 ++++++----- zed/src/workspace/workspace_view.rs | 41 ++++++++++++++--------------- 5 files changed, 50 insertions(+), 41 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 4cd3076580..38d75ed246 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -2241,6 +2241,7 @@ dependencies = [ "crossbeam-channel 0.5.0", "dirs", "easy-parallel", + "futures-core", "gpui", "ignore", "lazy_static", diff --git a/zed/Cargo.toml b/zed/Cargo.toml index c7026445cc..b1cecf1ae0 100644 --- a/zed/Cargo.toml +++ b/zed/Cargo.toml @@ -20,6 +20,7 @@ dirs = "3.0" easy-parallel = "3.1.0" gpui = {path = "../gpui"} ignore = {git = "https://github.com/zed-industries/ripgrep", rev = "1d152118f35b3e3590216709b86277062d79b8a0"} +futures-core = "0.3" lazy_static = "1.4.0" libc = "0.2" log = "0.4" diff --git a/zed/src/editor/buffer/mod.rs b/zed/src/editor/buffer/mod.rs index 9fcca50113..2e25a70bae 100644 --- a/zed/src/editor/buffer/mod.rs +++ b/zed/src/editor/buffer/mod.rs @@ -3,6 +3,7 @@ mod point; mod text; pub use anchor::*; +use futures_core::future::LocalBoxFuture; pub use point::*; pub use text::*; @@ -14,7 +15,7 @@ use crate::{ worktree::FileHandle, }; use anyhow::{anyhow, Result}; -use gpui::{AppContext, Entity, ModelContext, Task}; +use gpui::{AppContext, Entity, ModelContext}; use lazy_static::lazy_static; use rand::prelude::*; use std::{ @@ -243,23 +244,25 @@ impl Buffer { } } - pub fn save(&mut self, ctx: &mut ModelContext) -> Option>> { + pub fn save(&mut self, ctx: &mut ModelContext) -> LocalBoxFuture<'static, Result<()>> { if let Some(file) = &self.file { let snapshot = self.snapshot(); - - let result = file.save(snapshot, ctx.app()); - - // TODO - don't do this until the save has finished - self.did_save(ctx); - - Some(result) + let version = self.version.clone(); + let save_task = file.save(snapshot, ctx.app()); + let task = ctx.spawn(save_task, |me, save_result, ctx| { + if save_result.is_ok() { + me.did_save(version, ctx); + } + save_result + }); + Box::pin(task) } else { - None + Box::pin(async { Ok(()) }) } } - fn did_save(&mut self, ctx: &mut ModelContext) { - self.persisted_version = self.fragments.summary().max_version; + fn did_save(&mut self, version: time::Global, ctx: &mut ModelContext) { + self.persisted_version = version; ctx.emit(Event::Saved); } @@ -429,7 +432,7 @@ impl Buffer { ctx.notify(); let changes = self.edits_since(old_version).collect::>(); if !changes.is_empty() { - ctx.emit(Event::Edited(changes)) + self.did_edit(changes, ctx); } } @@ -447,6 +450,10 @@ impl Buffer { Ok(ops) } + fn did_edit(&self, changes: Vec, ctx: &mut ModelContext) { + ctx.emit(Event::Edited(changes)) + } + pub fn simulate_typing(&mut self, rng: &mut T) { let end = rng.gen_range(0..self.len() + 1); let start = rng.gen_range(0..end + 1); diff --git a/zed/src/editor/buffer_view.rs b/zed/src/editor/buffer_view.rs index a02c9fa54a..3057bd4ffc 100644 --- a/zed/src/editor/buffer_view.rs +++ b/zed/src/editor/buffer_view.rs @@ -5,12 +5,13 @@ use super::{ use crate::{ settings::Settings, watch, - workspace::{self, ItemEventEffect}, + workspace::{self, WorkspaceEvent}, }; use anyhow::Result; +use futures_core::future::LocalBoxFuture; use gpui::{ fonts::Properties as FontProperties, keymap::Binding, text_layout, App, AppContext, Element, - ElementBox, Entity, FontCache, ModelHandle, Task, View, ViewContext, WeakViewHandle, + ElementBox, Entity, FontCache, ModelHandle, View, ViewContext, WeakViewHandle, }; use gpui::{geometry::vector::Vector2F, TextLayoutCache}; use parking_lot::Mutex; @@ -1152,11 +1153,11 @@ impl workspace::Item for Buffer { } impl workspace::ItemView for BufferView { - fn event_effect(event: &Self::Event) -> ItemEventEffect { + fn to_workspace_event(event: &Self::Event) -> Option { match event { - Event::Activate => ItemEventEffect::Activate, - Event::Edited => ItemEventEffect::ChangeTab, - _ => ItemEventEffect::None, + Event::Activate => Some(WorkspaceEvent::Activate), + Event::Saved => Some(WorkspaceEvent::TabStateChanged), + _ => None, } } @@ -1184,7 +1185,7 @@ impl workspace::ItemView for BufferView { Some(clone) } - fn save(&self, ctx: &mut ViewContext) -> Option>> { + fn save(&self, ctx: &mut ViewContext) -> LocalBoxFuture<'static, Result<()>> { self.buffer.update(ctx, |buffer, ctx| buffer.save(ctx)) } diff --git a/zed/src/workspace/workspace_view.rs b/zed/src/workspace/workspace_view.rs index adc3a3b5f9..5c62139a45 100644 --- a/zed/src/workspace/workspace_view.rs +++ b/zed/src/workspace/workspace_view.rs @@ -1,8 +1,9 @@ use super::{pane, Pane, PaneGroup, SplitDirection, Workspace}; use crate::{settings::Settings, watch}; +use futures_core::future::LocalBoxFuture; use gpui::{ color::rgbu, elements::*, keymap::Binding, AnyViewHandle, App, AppContext, Entity, ModelHandle, - MutableAppContext, Task, View, ViewContext, ViewHandle, + MutableAppContext, View, ViewContext, ViewHandle, }; use log::{error, info}; use std::{collections::HashSet, path::PathBuf}; @@ -12,14 +13,13 @@ pub fn init(app: &mut App) { app.add_bindings(vec![Binding::new("cmd-s", "workspace:save", None)]); } -pub enum ItemEventEffect { - None, - ChangeTab, +pub enum WorkspaceEvent { + TabStateChanged, Activate, } pub trait ItemView: View { - fn event_effect(event: &Self::Event) -> ItemEventEffect; + fn to_workspace_event(event: &Self::Event) -> Option; fn title(&self, app: &AppContext) -> String; fn entry_id(&self, app: &AppContext) -> Option<(usize, usize)>; fn clone_on_split(&self, _: &mut ViewContext) -> Option @@ -31,8 +31,8 @@ pub trait ItemView: View { fn is_modified(&self, _: &AppContext) -> bool { false } - fn save(&self, _: &mut ViewContext) -> Option>> { - None + fn save(&self, _: &mut ViewContext) -> LocalBoxFuture<'static, anyhow::Result<()>> { + Box::pin(async { Ok(()) }) } } @@ -45,7 +45,7 @@ pub trait ItemViewHandle: Send + Sync { fn id(&self) -> usize; fn to_any(&self) -> AnyViewHandle; fn is_modified(&self, ctx: &AppContext) -> bool; - fn save(&self, ctx: &mut MutableAppContext) -> Option>>; + fn save(&self, ctx: &mut MutableAppContext) -> LocalBoxFuture<'static, anyhow::Result<()>>; } impl ItemViewHandle for ViewHandle { @@ -71,21 +71,21 @@ impl ItemViewHandle for ViewHandle { fn set_parent_pane(&self, pane: &ViewHandle, app: &mut MutableAppContext) { pane.update(app, |_, ctx| { ctx.subscribe_to_view(self, |pane, item, event, ctx| { - match T::event_effect(event) { - ItemEventEffect::Activate => { + match T::to_workspace_event(event) { + Some(WorkspaceEvent::Activate) => { if let Some(ix) = pane.item_index(&item) { pane.activate_item(ix, ctx); pane.activate(ctx); } } - ItemEventEffect::ChangeTab => ctx.notify(), + Some(WorkspaceEvent::TabStateChanged) => ctx.notify(), _ => {} } }) }) } - fn save(&self, ctx: &mut MutableAppContext) -> Option>> { + fn save(&self, ctx: &mut MutableAppContext) -> LocalBoxFuture<'static, anyhow::Result<()>> { self.update(ctx, |item, ctx| item.save(ctx)) } @@ -240,15 +240,14 @@ impl WorkspaceView { pub fn save_active_item(&mut self, _: &(), ctx: &mut ViewContext) { self.active_pane.update(ctx, |pane, ctx| { if let Some(item) = pane.active_item() { - if let Some(task) = item.save(ctx.app_mut()) { - ctx.spawn(task, |_, result, _| { - if let Err(e) = result { - // TODO - present this error to the user - error!("failed to save item: {:?}, ", e); - } - }) - .detach(); - } + let task = item.save(ctx.app_mut()); + ctx.spawn(task, |_, result, _| { + if let Err(e) = result { + // TODO - present this error to the user + error!("failed to save item: {:?}, ", e); + } + }) + .detach() } }); }