Implement Buffer::is_modified by storing persisted version
This commit is contained in:
parent
bd37b11306
commit
685665f3c0
1 changed files with 43 additions and 10 deletions
|
@ -36,6 +36,7 @@ pub struct Buffer {
|
||||||
fragments: SumTree<Fragment>,
|
fragments: SumTree<Fragment>,
|
||||||
insertion_splits: HashMap<time::Local, SumTree<InsertionSplit>>,
|
insertion_splits: HashMap<time::Local, SumTree<InsertionSplit>>,
|
||||||
pub version: time::Global,
|
pub version: time::Global,
|
||||||
|
persisted_version: time::Global,
|
||||||
last_edit: time::Local,
|
last_edit: time::Local,
|
||||||
selections: HashMap<SelectionSetId, Vec<Selection>>,
|
selections: HashMap<SelectionSetId, Vec<Selection>>,
|
||||||
pub selections_last_update: SelectionsVersion,
|
pub selections_last_update: SelectionsVersion,
|
||||||
|
@ -216,6 +217,7 @@ impl Buffer {
|
||||||
fragments,
|
fragments,
|
||||||
insertion_splits,
|
insertion_splits,
|
||||||
version: time::Global::new(),
|
version: time::Global::new(),
|
||||||
|
persisted_version: time::Global::new(),
|
||||||
last_edit: time::Local::default(),
|
last_edit: time::Local::default(),
|
||||||
selections: HashMap::default(),
|
selections: HashMap::default(),
|
||||||
selections_last_update: 0,
|
selections_last_update: 0,
|
||||||
|
@ -241,21 +243,28 @@ impl Buffer {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn save(&self, ctx: &mut ModelContext<Self>) -> Option<Task<Result<()>>> {
|
pub fn save(&mut 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
|
let result = file.save(snapshot, ctx.app());
|
||||||
ctx.emit(Event::Saved);
|
|
||||||
|
|
||||||
Some(file.save(snapshot, ctx.app()))
|
// TODO - don't do this until the save has finished
|
||||||
|
self.did_save(ctx);
|
||||||
|
|
||||||
|
Some(result)
|
||||||
} else {
|
} else {
|
||||||
None
|
None
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn did_save(&mut self, ctx: &mut ModelContext<Buffer>) {
|
||||||
|
self.persisted_version = self.fragments.summary().max_version;
|
||||||
|
ctx.emit(Event::Saved);
|
||||||
|
}
|
||||||
|
|
||||||
pub fn is_modified(&self) -> bool {
|
pub fn is_modified(&self) -> bool {
|
||||||
self.version != time::Global::new()
|
self.fragments.summary().max_version > self.persisted_version
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn text_summary(&self) -> TextSummary {
|
pub fn text_summary(&self) -> TextSummary {
|
||||||
|
@ -1374,6 +1383,7 @@ impl Clone for Buffer {
|
||||||
fragments: self.fragments.clone(),
|
fragments: self.fragments.clone(),
|
||||||
insertion_splits: self.insertion_splits.clone(),
|
insertion_splits: self.insertion_splits.clone(),
|
||||||
version: self.version.clone(),
|
version: self.version.clone(),
|
||||||
|
persisted_version: self.persisted_version.clone(),
|
||||||
last_edit: self.last_edit.clone(),
|
last_edit: self.last_edit.clone(),
|
||||||
selections: self.selections.clone(),
|
selections: self.selections.clone(),
|
||||||
selections_last_update: self.selections_last_update.clone(),
|
selections_last_update: self.selections_last_update.clone(),
|
||||||
|
@ -1953,6 +1963,7 @@ impl ToPoint for usize {
|
||||||
#[cfg(test)]
|
#[cfg(test)]
|
||||||
mod tests {
|
mod tests {
|
||||||
use super::*;
|
use super::*;
|
||||||
|
use gpui::App;
|
||||||
use std::collections::BTreeMap;
|
use std::collections::BTreeMap;
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
|
@ -1975,7 +1986,6 @@ mod tests {
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn test_edit_events() {
|
fn test_edit_events() {
|
||||||
use gpui::App;
|
|
||||||
use std::{cell::RefCell, rc::Rc};
|
use std::{cell::RefCell, rc::Rc};
|
||||||
|
|
||||||
App::test((), |mut app| async move {
|
App::test((), |mut app| async move {
|
||||||
|
@ -2489,11 +2499,34 @@ mod tests {
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn test_is_modified() -> Result<()> {
|
fn test_is_modified() -> Result<()> {
|
||||||
let mut buffer = Buffer::new(0, "abc");
|
App::test((), |mut app| async move {
|
||||||
assert!(!buffer.is_modified());
|
let model = app.add_model(|_| Buffer::new(0, "abc"));
|
||||||
buffer.edit(vec![1..2], "", None)?;
|
model.update(&mut app, |buffer, ctx| {
|
||||||
assert!(buffer.is_modified());
|
// initially, buffer isn't modified.
|
||||||
|
assert!(!buffer.is_modified());
|
||||||
|
|
||||||
|
// after editing, buffer is modified.
|
||||||
|
buffer.edit(vec![1..2], "", None).unwrap();
|
||||||
|
assert!(buffer.text() == "ac");
|
||||||
|
assert!(buffer.is_modified());
|
||||||
|
|
||||||
|
// after saving, buffer is not modified.
|
||||||
|
buffer.did_save(ctx);
|
||||||
|
assert!(!buffer.is_modified());
|
||||||
|
|
||||||
|
// after editing again, buffer is modified.
|
||||||
|
buffer.edit(vec![1..1], "B", None).unwrap();
|
||||||
|
buffer.edit(vec![2..2], "D", None).unwrap();
|
||||||
|
assert!(buffer.text() == "aBDc");
|
||||||
|
assert!(buffer.is_modified());
|
||||||
|
|
||||||
|
// TODO - currently, after restoring the buffer to its
|
||||||
|
// saved state, it is still considered modified.
|
||||||
|
buffer.edit(vec![1..3], "", None).unwrap();
|
||||||
|
assert!(buffer.text() == "ac");
|
||||||
|
assert!(buffer.is_modified());
|
||||||
|
});
|
||||||
|
});
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue