mirror of https://github.com/helix-editor/helix
commit
7761c88d61
|
@ -65,9 +65,7 @@ impl History {
|
||||||
self.cursor == 0
|
self.cursor == 0
|
||||||
}
|
}
|
||||||
|
|
||||||
// TODO: I'd like to pass Transaction by reference but it fights with the borrowck
|
pub fn undo(&mut self) -> Option<&Transaction> {
|
||||||
|
|
||||||
pub fn undo(&mut self) -> Option<Transaction> {
|
|
||||||
if self.at_root() {
|
if self.at_root() {
|
||||||
// We're at the root of undo, nothing to do.
|
// We're at the root of undo, nothing to do.
|
||||||
return None;
|
return None;
|
||||||
|
@ -77,17 +75,17 @@ impl History {
|
||||||
|
|
||||||
self.cursor = current_revision.parent;
|
self.cursor = current_revision.parent;
|
||||||
|
|
||||||
Some(current_revision.revert.clone())
|
Some(¤t_revision.revert)
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn redo(&mut self) -> Option<Transaction> {
|
pub fn redo(&mut self) -> Option<&Transaction> {
|
||||||
let current_revision = &self.revisions[self.cursor];
|
let current_revision = &self.revisions[self.cursor];
|
||||||
|
|
||||||
// for now, simply pick the latest child (linear undo / redo)
|
// for now, simply pick the latest child (linear undo / redo)
|
||||||
if let Some((index, transaction)) = current_revision.children.last() {
|
if let Some((index, transaction)) = current_revision.children.last() {
|
||||||
self.cursor = *index;
|
self.cursor = *index;
|
||||||
|
|
||||||
return Some(transaction.clone());
|
return Some(&transaction);
|
||||||
}
|
}
|
||||||
None
|
None
|
||||||
}
|
}
|
||||||
|
|
|
@ -415,7 +415,7 @@ impl ChangeSet {
|
||||||
|
|
||||||
/// Transaction represents a single undoable unit of changes. Several changes can be grouped into
|
/// Transaction represents a single undoable unit of changes. Several changes can be grouped into
|
||||||
/// a single transaction.
|
/// a single transaction.
|
||||||
#[derive(Debug, Clone)]
|
#[derive(Debug, Default, Clone)]
|
||||||
pub struct Transaction {
|
pub struct Transaction {
|
||||||
changes: ChangeSet,
|
changes: ChangeSet,
|
||||||
selection: Option<Selection>,
|
selection: Option<Selection>,
|
||||||
|
|
|
@ -1,4 +1,5 @@
|
||||||
use anyhow::{Context, Error};
|
use anyhow::{Context, Error};
|
||||||
|
use std::cell::Cell;
|
||||||
use std::future::Future;
|
use std::future::Future;
|
||||||
use std::path::{Component, Path, PathBuf};
|
use std::path::{Component, Path, PathBuf};
|
||||||
use std::sync::Arc;
|
use std::sync::Arc;
|
||||||
|
@ -40,7 +41,10 @@ pub struct Document {
|
||||||
/// State at last commit. Used for calculating reverts.
|
/// State at last commit. Used for calculating reverts.
|
||||||
old_state: Option<State>,
|
old_state: Option<State>,
|
||||||
/// Undo tree.
|
/// Undo tree.
|
||||||
history: History,
|
// It can be used as a cell where we will take it out to get some parts of the history and put
|
||||||
|
// it back as it separated from the edits. We could split out the parts manually but that will
|
||||||
|
// be more troublesome.
|
||||||
|
history: Cell<History>,
|
||||||
last_saved_revision: usize,
|
last_saved_revision: usize,
|
||||||
version: i32, // should be usize?
|
version: i32, // should be usize?
|
||||||
|
|
||||||
|
@ -121,7 +125,7 @@ impl Document {
|
||||||
old_state,
|
old_state,
|
||||||
diagnostics: Vec::new(),
|
diagnostics: Vec::new(),
|
||||||
version: 0,
|
version: 0,
|
||||||
history: History::default(),
|
history: Cell::new(History::default()),
|
||||||
last_saved_revision: 0,
|
last_saved_revision: 0,
|
||||||
language_server: None,
|
language_server: None,
|
||||||
}
|
}
|
||||||
|
@ -190,7 +194,9 @@ impl Document {
|
||||||
let language_server = self.language_server.clone();
|
let language_server = self.language_server.clone();
|
||||||
|
|
||||||
// reset the modified flag
|
// reset the modified flag
|
||||||
self.last_saved_revision = self.history.current_revision();
|
let history = self.history.take();
|
||||||
|
self.last_saved_revision = history.current_revision();
|
||||||
|
self.history.set(history);
|
||||||
|
|
||||||
async move {
|
async move {
|
||||||
use tokio::{fs::File, io::AsyncWriteExt};
|
use tokio::{fs::File, io::AsyncWriteExt};
|
||||||
|
@ -335,7 +341,8 @@ impl Document {
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn undo(&mut self, view_id: ViewId) -> bool {
|
pub fn undo(&mut self, view_id: ViewId) -> bool {
|
||||||
if let Some(transaction) = self.history.undo() {
|
let mut history = self.history.take();
|
||||||
|
if let Some(transaction) = history.undo() {
|
||||||
let success = self._apply(&transaction, view_id);
|
let success = self._apply(&transaction, view_id);
|
||||||
|
|
||||||
// reset changeset to fix len
|
// reset changeset to fix len
|
||||||
|
@ -343,11 +350,13 @@ impl Document {
|
||||||
|
|
||||||
return success;
|
return success;
|
||||||
}
|
}
|
||||||
|
self.history.set(history);
|
||||||
false
|
false
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn redo(&mut self, view_id: ViewId) -> bool {
|
pub fn redo(&mut self, view_id: ViewId) -> bool {
|
||||||
if let Some(transaction) = self.history.redo() {
|
let mut history = self.history.take();
|
||||||
|
if let Some(transaction) = history.redo() {
|
||||||
let success = self._apply(&transaction, view_id);
|
let success = self._apply(&transaction, view_id);
|
||||||
|
|
||||||
// reset changeset to fix len
|
// reset changeset to fix len
|
||||||
|
@ -355,6 +364,7 @@ impl Document {
|
||||||
|
|
||||||
return success;
|
return success;
|
||||||
}
|
}
|
||||||
|
self.history.set(history);
|
||||||
false
|
false
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -373,7 +383,9 @@ impl Document {
|
||||||
// HAXX: we need to reconstruct the state as it was before the changes..
|
// HAXX: we need to reconstruct the state as it was before the changes..
|
||||||
let old_state = self.old_state.take().expect("no old_state available");
|
let old_state = self.old_state.take().expect("no old_state available");
|
||||||
|
|
||||||
self.history.commit_revision(&transaction, &old_state);
|
let mut history = self.history.take();
|
||||||
|
history.commit_revision(&transaction, &old_state);
|
||||||
|
self.history.set(history);
|
||||||
}
|
}
|
||||||
|
|
||||||
#[inline]
|
#[inline]
|
||||||
|
@ -383,9 +395,11 @@ impl Document {
|
||||||
|
|
||||||
#[inline]
|
#[inline]
|
||||||
pub fn is_modified(&self) -> bool {
|
pub fn is_modified(&self) -> bool {
|
||||||
|
let history = self.history.take();
|
||||||
|
let current_revision = history.current_revision();
|
||||||
|
self.history.set(history);
|
||||||
self.path.is_some()
|
self.path.is_some()
|
||||||
&& (self.history.current_revision() != self.last_saved_revision
|
&& (current_revision != self.last_saved_revision || !self.changes.is_empty())
|
||||||
|| !self.changes.is_empty())
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#[inline]
|
#[inline]
|
||||||
|
|
Loading…
Reference in New Issue