mirror of
https://github.com/zed-industries/zed.git
synced 2025-01-23 18:32:17 +00:00
wip
This commit is contained in:
parent
685665f3c0
commit
d724387158
5 changed files with 50 additions and 41 deletions
1
Cargo.lock
generated
1
Cargo.lock
generated
|
@ -2241,6 +2241,7 @@ dependencies = [
|
||||||
"crossbeam-channel 0.5.0",
|
"crossbeam-channel 0.5.0",
|
||||||
"dirs",
|
"dirs",
|
||||||
"easy-parallel",
|
"easy-parallel",
|
||||||
|
"futures-core",
|
||||||
"gpui",
|
"gpui",
|
||||||
"ignore",
|
"ignore",
|
||||||
"lazy_static",
|
"lazy_static",
|
||||||
|
|
|
@ -20,6 +20,7 @@ dirs = "3.0"
|
||||||
easy-parallel = "3.1.0"
|
easy-parallel = "3.1.0"
|
||||||
gpui = {path = "../gpui"}
|
gpui = {path = "../gpui"}
|
||||||
ignore = {git = "https://github.com/zed-industries/ripgrep", rev = "1d152118f35b3e3590216709b86277062d79b8a0"}
|
ignore = {git = "https://github.com/zed-industries/ripgrep", rev = "1d152118f35b3e3590216709b86277062d79b8a0"}
|
||||||
|
futures-core = "0.3"
|
||||||
lazy_static = "1.4.0"
|
lazy_static = "1.4.0"
|
||||||
libc = "0.2"
|
libc = "0.2"
|
||||||
log = "0.4"
|
log = "0.4"
|
||||||
|
|
|
@ -3,6 +3,7 @@ mod point;
|
||||||
mod text;
|
mod text;
|
||||||
|
|
||||||
pub use anchor::*;
|
pub use anchor::*;
|
||||||
|
use futures_core::future::LocalBoxFuture;
|
||||||
pub use point::*;
|
pub use point::*;
|
||||||
pub use text::*;
|
pub use text::*;
|
||||||
|
|
||||||
|
@ -14,7 +15,7 @@ use crate::{
|
||||||
worktree::FileHandle,
|
worktree::FileHandle,
|
||||||
};
|
};
|
||||||
use anyhow::{anyhow, Result};
|
use anyhow::{anyhow, Result};
|
||||||
use gpui::{AppContext, Entity, ModelContext, Task};
|
use gpui::{AppContext, Entity, ModelContext};
|
||||||
use lazy_static::lazy_static;
|
use lazy_static::lazy_static;
|
||||||
use rand::prelude::*;
|
use rand::prelude::*;
|
||||||
use std::{
|
use std::{
|
||||||
|
@ -243,23 +244,25 @@ impl Buffer {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn save(&mut self, ctx: &mut ModelContext<Self>) -> Option<Task<Result<()>>> {
|
pub fn save(&mut self, ctx: &mut ModelContext<Self>) -> LocalBoxFuture<'static, Result<()>> {
|
||||||
if let Some(file) = &self.file {
|
if let Some(file) = &self.file {
|
||||||
let snapshot = self.snapshot();
|
let snapshot = self.snapshot();
|
||||||
|
let version = self.version.clone();
|
||||||
let result = file.save(snapshot, ctx.app());
|
let save_task = file.save(snapshot, ctx.app());
|
||||||
|
let task = ctx.spawn(save_task, |me, save_result, ctx| {
|
||||||
// TODO - don't do this until the save has finished
|
if save_result.is_ok() {
|
||||||
self.did_save(ctx);
|
me.did_save(version, ctx);
|
||||||
|
}
|
||||||
Some(result)
|
save_result
|
||||||
|
});
|
||||||
|
Box::pin(task)
|
||||||
} else {
|
} else {
|
||||||
None
|
Box::pin(async { Ok(()) })
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn did_save(&mut self, ctx: &mut ModelContext<Buffer>) {
|
fn did_save(&mut self, version: time::Global, ctx: &mut ModelContext<Buffer>) {
|
||||||
self.persisted_version = self.fragments.summary().max_version;
|
self.persisted_version = version;
|
||||||
ctx.emit(Event::Saved);
|
ctx.emit(Event::Saved);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -429,7 +432,7 @@ impl Buffer {
|
||||||
ctx.notify();
|
ctx.notify();
|
||||||
let changes = self.edits_since(old_version).collect::<Vec<_>>();
|
let changes = self.edits_since(old_version).collect::<Vec<_>>();
|
||||||
if !changes.is_empty() {
|
if !changes.is_empty() {
|
||||||
ctx.emit(Event::Edited(changes))
|
self.did_edit(changes, ctx);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -447,6 +450,10 @@ impl Buffer {
|
||||||
Ok(ops)
|
Ok(ops)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn did_edit(&self, changes: Vec<Edit>, ctx: &mut ModelContext<Self>) {
|
||||||
|
ctx.emit(Event::Edited(changes))
|
||||||
|
}
|
||||||
|
|
||||||
pub fn simulate_typing<T: Rng>(&mut self, rng: &mut T) {
|
pub fn simulate_typing<T: Rng>(&mut self, rng: &mut T) {
|
||||||
let end = rng.gen_range(0..self.len() + 1);
|
let end = rng.gen_range(0..self.len() + 1);
|
||||||
let start = rng.gen_range(0..end + 1);
|
let start = rng.gen_range(0..end + 1);
|
||||||
|
|
|
@ -5,12 +5,13 @@ use super::{
|
||||||
use crate::{
|
use crate::{
|
||||||
settings::Settings,
|
settings::Settings,
|
||||||
watch,
|
watch,
|
||||||
workspace::{self, ItemEventEffect},
|
workspace::{self, WorkspaceEvent},
|
||||||
};
|
};
|
||||||
use anyhow::Result;
|
use anyhow::Result;
|
||||||
|
use futures_core::future::LocalBoxFuture;
|
||||||
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, Task, View, ViewContext, WeakViewHandle,
|
ElementBox, Entity, FontCache, ModelHandle, View, ViewContext, WeakViewHandle,
|
||||||
};
|
};
|
||||||
use gpui::{geometry::vector::Vector2F, TextLayoutCache};
|
use gpui::{geometry::vector::Vector2F, TextLayoutCache};
|
||||||
use parking_lot::Mutex;
|
use parking_lot::Mutex;
|
||||||
|
@ -1152,11 +1153,11 @@ impl workspace::Item for Buffer {
|
||||||
}
|
}
|
||||||
|
|
||||||
impl workspace::ItemView for BufferView {
|
impl workspace::ItemView for BufferView {
|
||||||
fn event_effect(event: &Self::Event) -> ItemEventEffect {
|
fn to_workspace_event(event: &Self::Event) -> Option<WorkspaceEvent> {
|
||||||
match event {
|
match event {
|
||||||
Event::Activate => ItemEventEffect::Activate,
|
Event::Activate => Some(WorkspaceEvent::Activate),
|
||||||
Event::Edited => ItemEventEffect::ChangeTab,
|
Event::Saved => Some(WorkspaceEvent::TabStateChanged),
|
||||||
_ => ItemEventEffect::None,
|
_ => None,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1184,7 +1185,7 @@ impl workspace::ItemView for BufferView {
|
||||||
Some(clone)
|
Some(clone)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn save(&self, ctx: &mut ViewContext<Self>) -> Option<Task<Result<()>>> {
|
fn save(&self, ctx: &mut ViewContext<Self>) -> LocalBoxFuture<'static, Result<()>> {
|
||||||
self.buffer.update(ctx, |buffer, ctx| buffer.save(ctx))
|
self.buffer.update(ctx, |buffer, ctx| buffer.save(ctx))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -1,8 +1,9 @@
|
||||||
use super::{pane, Pane, PaneGroup, SplitDirection, Workspace};
|
use super::{pane, Pane, PaneGroup, SplitDirection, Workspace};
|
||||||
use crate::{settings::Settings, watch};
|
use crate::{settings::Settings, watch};
|
||||||
|
use futures_core::future::LocalBoxFuture;
|
||||||
use gpui::{
|
use gpui::{
|
||||||
color::rgbu, elements::*, keymap::Binding, AnyViewHandle, App, AppContext, Entity, ModelHandle,
|
color::rgbu, elements::*, keymap::Binding, AnyViewHandle, App, AppContext, Entity, ModelHandle,
|
||||||
MutableAppContext, Task, View, ViewContext, ViewHandle,
|
MutableAppContext, View, ViewContext, ViewHandle,
|
||||||
};
|
};
|
||||||
use log::{error, info};
|
use log::{error, info};
|
||||||
use std::{collections::HashSet, path::PathBuf};
|
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)]);
|
app.add_bindings(vec![Binding::new("cmd-s", "workspace:save", None)]);
|
||||||
}
|
}
|
||||||
|
|
||||||
pub enum ItemEventEffect {
|
pub enum WorkspaceEvent {
|
||||||
None,
|
TabStateChanged,
|
||||||
ChangeTab,
|
|
||||||
Activate,
|
Activate,
|
||||||
}
|
}
|
||||||
|
|
||||||
pub trait ItemView: View {
|
pub trait ItemView: View {
|
||||||
fn event_effect(event: &Self::Event) -> ItemEventEffect;
|
fn to_workspace_event(event: &Self::Event) -> Option<WorkspaceEvent>;
|
||||||
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>
|
||||||
|
@ -31,8 +31,8 @@ pub trait ItemView: View {
|
||||||
fn is_modified(&self, _: &AppContext) -> bool {
|
fn is_modified(&self, _: &AppContext) -> bool {
|
||||||
false
|
false
|
||||||
}
|
}
|
||||||
fn save(&self, _: &mut ViewContext<Self>) -> Option<Task<anyhow::Result<()>>> {
|
fn save(&self, _: &mut ViewContext<Self>) -> LocalBoxFuture<'static, anyhow::Result<()>> {
|
||||||
None
|
Box::pin(async { Ok(()) })
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -45,7 +45,7 @@ pub trait ItemViewHandle: Send + Sync {
|
||||||
fn id(&self) -> usize;
|
fn id(&self) -> usize;
|
||||||
fn to_any(&self) -> AnyViewHandle;
|
fn to_any(&self) -> AnyViewHandle;
|
||||||
fn is_modified(&self, ctx: &AppContext) -> bool;
|
fn is_modified(&self, ctx: &AppContext) -> bool;
|
||||||
fn save(&self, ctx: &mut MutableAppContext) -> Option<Task<anyhow::Result<()>>>;
|
fn save(&self, ctx: &mut MutableAppContext) -> LocalBoxFuture<'static, anyhow::Result<()>>;
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<T: ItemView> ItemViewHandle for ViewHandle<T> {
|
impl<T: ItemView> ItemViewHandle for ViewHandle<T> {
|
||||||
|
@ -71,21 +71,21 @@ 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| {
|
||||||
match T::event_effect(event) {
|
match T::to_workspace_event(event) {
|
||||||
ItemEventEffect::Activate => {
|
Some(WorkspaceEvent::Activate) => {
|
||||||
if let Some(ix) = pane.item_index(&item) {
|
if let Some(ix) = pane.item_index(&item) {
|
||||||
pane.activate_item(ix, ctx);
|
pane.activate_item(ix, ctx);
|
||||||
pane.activate(ctx);
|
pane.activate(ctx);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
ItemEventEffect::ChangeTab => ctx.notify(),
|
Some(WorkspaceEvent::TabStateChanged) => ctx.notify(),
|
||||||
_ => {}
|
_ => {}
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
fn save(&self, ctx: &mut MutableAppContext) -> Option<Task<anyhow::Result<()>>> {
|
fn save(&self, ctx: &mut MutableAppContext) -> LocalBoxFuture<'static, anyhow::Result<()>> {
|
||||||
self.update(ctx, |item, ctx| item.save(ctx))
|
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>) {
|
pub fn save_active_item(&mut self, _: &(), ctx: &mut ViewContext<Self>) {
|
||||||
self.active_pane.update(ctx, |pane, ctx| {
|
self.active_pane.update(ctx, |pane, ctx| {
|
||||||
if let Some(item) = pane.active_item() {
|
if let Some(item) = pane.active_item() {
|
||||||
if let Some(task) = item.save(ctx.app_mut()) {
|
let task = item.save(ctx.app_mut());
|
||||||
ctx.spawn(task, |_, result, _| {
|
ctx.spawn(task, |_, result, _| {
|
||||||
if let Err(e) = result {
|
if let Err(e) = result {
|
||||||
// TODO - present this error to the user
|
// TODO - present this error to the user
|
||||||
error!("failed to save item: {:?}, ", e);
|
error!("failed to save item: {:?}, ", e);
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
.detach();
|
.detach()
|
||||||
}
|
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue