Skip to content

Commit

Permalink
reload history with reload command
Browse files Browse the repository at this point in the history
  • Loading branch information
kirawi committed Feb 19, 2023
1 parent b83fb40 commit d650195
Show file tree
Hide file tree
Showing 4 changed files with 59 additions and 22 deletions.
22 changes: 22 additions & 0 deletions helix-core/src/history.rs
Original file line number Diff line number Diff line change
Expand Up @@ -189,6 +189,23 @@ impl History {
Ok((last_saved_revision, history))
}

pub fn merge(&mut self, mut other: History, offset: usize) -> std::io::Result<()> {
let revisions = self.revisions.split_off(offset);
let len = other.revisions.len();
for r in revisions {
let parent = if r.parent < offset {
r.parent
} else {
len + (r.parent - offset)
};
other.revisions.get_mut(parent).unwrap().last_child =
NonZeroUsize::new(other.revisions.len());
other.revisions.push(r);
}
self.revisions = other.revisions;
Ok(())
}

pub fn read_header<R: Read>(reader: &mut R, path: &Path) -> std::io::Result<(usize, usize)> {
let header = read_string(reader)?;
if HEADER_TAG != header {
Expand Down Expand Up @@ -259,6 +276,11 @@ impl History {
self.current == 0
}

#[inline]
pub fn is_empty(&self) -> bool {
self.revisions.len() <= 1
}

/// Returns the changes since the given revision composed into a transaction.
/// Returns None if there are no changes between the current and given revisions.
pub fn changes_since(&self, revision: usize) -> Option<Transaction> {
Expand Down
7 changes: 3 additions & 4 deletions helix-term/src/application.rs
Original file line number Diff line number Diff line change
Expand Up @@ -515,10 +515,6 @@ impl Application {
}
};

if doc_save_event.serialize_error {
self.editor.set_error("failed to serialize history");
}

let doc = match self.editor.document_mut(doc_save_event.doc_id) {
None => {
warn!(
Expand Down Expand Up @@ -570,6 +566,9 @@ impl Application {
lines,
bytes
));
if doc_save_event.serialize_error {
self.editor.set_error("failed to serialize history");
}
}

#[inline(always)]
Expand Down
1 change: 1 addition & 0 deletions helix-term/tests/test/commands.rs
Original file line number Diff line number Diff line change
Expand Up @@ -486,6 +486,7 @@ async fn test_persistent_undo() -> anyhow::Result<()> {
.with_file(file.path(), None)
.build()?;

// TODO: Test if the history file is valid.
test_key_sequence(
&mut app,
Some(&format!(
Expand Down
51 changes: 33 additions & 18 deletions helix-view/src/document.rs
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@ use std::path::{Path, PathBuf};
use std::str::FromStr;
use std::sync::Arc;
use std::time::SystemTime;
use tokio::fs::OpenOptions;

use helix_core::{
encoding,
Expand Down Expand Up @@ -591,7 +592,7 @@ impl Document {
.load()
.persistent_undo
.then(|| self.history.get_mut().clone());
let undo_file = self.undo_file(Some(&path))?.unwrap();
let undofile_path = self.undo_file(Some(&path))?.unwrap();
// We encode the file according to the `Document`'s encoding.
let future = async move {
use tokio::{fs, fs::File};
Expand Down Expand Up @@ -624,16 +625,22 @@ impl Document {
if let Some(history) = history {
let res = {
let path = path.clone();
let mut undofile = OpenOptions::new()
.write(true)
.read(true)
.create(true)
.open(&undofile_path)
.await?
.into_std()
.await;
tokio::task::spawn_blocking(move || -> anyhow::Result<()> {
use std::fs;
let append =
History::read_header(&mut fs::File::open(&undo_file)?, &path).is_ok();
let mut undo_file = std::fs::OpenOptions::new()
.write(true)
.truncate(!append)
.read(true)
.open(&undo_file)?;
history.serialize(&mut undo_file, &path, current_rev, append)?;
History::deserialize(&mut std::fs::File::open(&undofile_path)?, &path)
.is_ok();
if !append {
undofile.set_len(0)?;
}
history.serialize(&mut undofile, &path, current_rev, append)?;
Ok(())
})
.await
Expand Down Expand Up @@ -717,14 +724,16 @@ impl Document {
let mut file = std::fs::File::open(&path)?;
let (rope, ..) = from_reader(&mut file, Some(encoding))?;

// Calculate the difference between the buffer and source text, and apply it.
// This is not considered a modification of the contents of the file regardless
// of the encoding.
let transaction = helix_core::diff::compare_ropes(self.text(), &rope);
self.apply(&transaction, view.id);
self.append_changes_to_history(view);
self.reset_modified();

if let Err(e) = self.load_history() {
log::error!("{}", e);
// Calculate the difference between the buffer and source text, and apply it.
// This is not considered a modification of the contents of the file regardless
// of the encoding.
let transaction = helix_core::diff::compare_ropes(self.text(), &rope);
self.apply(&transaction, view.id);
self.append_changes_to_history(view);
self.reset_modified();
}
self.last_saved_time = SystemTime::now();

self.detect_indent_and_line_ending();
Expand Down Expand Up @@ -761,7 +770,13 @@ impl Document {
&mut undo_file,
self.path().unwrap(),
)?;
self.history.set(history);

if self.history.get_mut().is_empty() {
self.history.set(history);
} else {
let offset = self.get_last_saved_revision() + 1;
self.history.get_mut().merge(history, offset)?;
}
self.set_last_saved_revision(last_saved_revision);
}
}
Expand Down

0 comments on commit d650195

Please sign in to comment.