aboutsummaryrefslogtreecommitdiff
path: root/helix-core/src/transaction.rs
diff options
context:
space:
mode:
authorBlaž Hrastnik2022-02-13 09:31:51 +0000
committerBlaž Hrastnik2022-02-13 09:31:51 +0000
commitbd549d8a20cce98e24c8653a4a86107c786cbaa3 (patch)
tree0780b58d41b6181e69023265cdb54517e2953778 /helix-core/src/transaction.rs
parent7ad8eaaef0b292f4be6c66298cea40d2b928e172 (diff)
parent7083b98a388b30e0b61caac9bf6ccc1d79eadf81 (diff)
Merge remote-tracking branch 'origin/master' into debug
Diffstat (limited to 'helix-core/src/transaction.rs')
-rw-r--r--helix-core/src/transaction.rs42
1 files changed, 17 insertions, 25 deletions
diff --git a/helix-core/src/transaction.rs b/helix-core/src/transaction.rs
index dfc18fbe..2e34a986 100644
--- a/helix-core/src/transaction.rs
+++ b/helix-core/src/transaction.rs
@@ -22,7 +22,7 @@ pub enum Assoc {
}
// ChangeSpec = Change | ChangeSet | Vec<Change>
-#[derive(Debug, Clone, PartialEq, Eq)]
+#[derive(Debug, Default, Clone, PartialEq, Eq)]
pub struct ChangeSet {
pub(crate) changes: Vec<Operation>,
/// The required document length. Will refuse to apply changes unless it matches.
@@ -30,16 +30,6 @@ pub struct ChangeSet {
len_after: usize,
}
-impl Default for ChangeSet {
- fn default() -> Self {
- Self {
- changes: Vec::new(),
- len: 0,
- len_after: 0,
- }
- }
-}
-
impl ChangeSet {
pub fn with_capacity(capacity: usize) -> Self {
Self {
@@ -95,7 +85,7 @@ impl ChangeSet {
let new_last = match self.changes.as_mut_slice() {
[.., Insert(prev)] | [.., Insert(prev), Delete(_)] => {
- prev.push_tendril(&fragment);
+ prev.push_str(&fragment);
return;
}
[.., last @ Delete(_)] => std::mem::replace(last, Insert(fragment)),
@@ -199,7 +189,7 @@ impl ChangeSet {
// TODO: cover this with a test
// figure out the byte index of the truncated string end
let (pos, _) = s.char_indices().nth(j).unwrap();
- s.pop_front(pos as u32);
+ s.replace_range(0..pos, "");
head_a = Some(Insert(s));
head_b = changes_b.next();
}
@@ -221,9 +211,11 @@ impl ChangeSet {
Ordering::Greater => {
// figure out the byte index of the truncated string end
let (pos, _) = s.char_indices().nth(j).unwrap();
- let pos = pos as u32;
- changes.insert(s.subtendril(0, pos));
- head_a = Some(Insert(s.subtendril(pos, s.len() as u32 - pos)));
+ let mut before = s;
+ let after = before.split_off(pos);
+
+ changes.insert(before);
+ head_a = Some(Insert(after));
head_b = changes_b.next();
}
}
@@ -287,7 +279,7 @@ impl ChangeSet {
}
Delete(n) => {
let text = Cow::from(original_doc.slice(pos..pos + *n));
- changes.insert(Tendril::from_slice(&text));
+ changes.insert(Tendril::from(text.as_ref()));
pos += n;
}
Insert(s) => {
@@ -330,7 +322,7 @@ impl ChangeSet {
/// `true` when the set is empty.
#[inline]
pub fn is_empty(&self) -> bool {
- self.changes.is_empty()
+ self.changes.is_empty() || self.changes == [Operation::Retain(self.len)]
}
/// Map a position through the changes.
@@ -419,7 +411,7 @@ impl ChangeSet {
/// Transaction represents a single undoable unit of changes. Several changes can be grouped into
/// a single transaction.
-#[derive(Debug, Default, Clone)]
+#[derive(Debug, Default, Clone, PartialEq, Eq)]
pub struct Transaction {
changes: ChangeSet,
selection: Option<Selection>,
@@ -720,19 +712,19 @@ mod test {
#[test]
fn optimized_composition() {
let mut state = State::new("".into());
- let t1 = Transaction::insert(&state.doc, &state.selection, Tendril::from_char('h'));
+ let t1 = Transaction::insert(&state.doc, &state.selection, Tendril::from("h"));
t1.apply(&mut state.doc);
state.selection = state.selection.clone().map(t1.changes());
- let t2 = Transaction::insert(&state.doc, &state.selection, Tendril::from_char('e'));
+ let t2 = Transaction::insert(&state.doc, &state.selection, Tendril::from("e"));
t2.apply(&mut state.doc);
state.selection = state.selection.clone().map(t2.changes());
- let t3 = Transaction::insert(&state.doc, &state.selection, Tendril::from_char('l'));
+ let t3 = Transaction::insert(&state.doc, &state.selection, Tendril::from("l"));
t3.apply(&mut state.doc);
state.selection = state.selection.clone().map(t3.changes());
- let t4 = Transaction::insert(&state.doc, &state.selection, Tendril::from_char('l'));
+ let t4 = Transaction::insert(&state.doc, &state.selection, Tendril::from("l"));
t4.apply(&mut state.doc);
state.selection = state.selection.clone().map(t4.changes());
- let t5 = Transaction::insert(&state.doc, &state.selection, Tendril::from_char('o'));
+ let t5 = Transaction::insert(&state.doc, &state.selection, Tendril::from("o"));
t5.apply(&mut state.doc);
state.selection = state.selection.clone().map(t5.changes());
@@ -771,7 +763,7 @@ mod test {
#[test]
fn combine_with_utf8() {
- const TEST_CASE: &'static str = "Hello, これはヘリックスエディターです!";
+ const TEST_CASE: &str = "Hello, これはヘリックスエディターです!";
let empty = Rope::from("");
let a = ChangeSet::new(&empty);