diff --git a/src/operation_transformation/edited_text.rs b/src/operation_transformation/edited_text.rs index 090d965..3e37641 100644 --- a/src/operation_transformation/edited_text.rs +++ b/src/operation_transformation/edited_text.rs @@ -7,7 +7,7 @@ use crate::{ operation_transformation::utils::{ cook_operations::cook_operations, elongate_operations::elongate_operations, }, - tokenizer::{word_tokenizer::word_tokenizer, Tokenizer}, + tokenizer::{Tokenizer, word_tokenizer::word_tokenizer}, utils::{side::Side, string_builder::StringBuilder}, }; diff --git a/src/operation_transformation/operation.rs b/src/operation_transformation/operation.rs index 63702cd..29fdeff 100644 --- a/src/operation_transformation/operation.rs +++ b/src/operation_transformation/operation.rs @@ -245,7 +245,7 @@ where Operation::create_delete_with_text( order + overlap, text.chars() - .skip((deleted_character_count - new_length) as usize) + .skip(deleted_character_count - new_length) .collect::(), ) }, diff --git a/src/operation_transformation/utils/cook_operations.rs b/src/operation_transformation/utils/cook_operations.rs index c642d3c..7d5f85e 100644 --- a/src/operation_transformation/utils/cook_operations.rs +++ b/src/operation_transformation/utils/cook_operations.rs @@ -1,12 +1,13 @@ use crate::{diffs::raw_operation::RawOperation, operation_transformation::Operation}; -/// Turn raw operations into ordered operations while keeping track of indexes. +/// Turn raw operations into ordered operations while keeping track of the +/// original token's indexes. pub fn cook_operations(raw_operations: I) -> impl Iterator> where I: IntoIterator>, T: PartialEq + Clone + std::fmt::Debug, { - let mut order = 0; // this is the start index of the operation on the original text + let mut original_text_index = 0; // this is the start index of the operation on the original text raw_operations.into_iter().map(move |raw_operation| { let length = raw_operation.original_text_length(); @@ -14,24 +15,30 @@ where match raw_operation { RawOperation::Equal(..) => { let op = if cfg!(debug_assertions) { - Operation::create_equal_with_text(order, raw_operation.get_original_text()) + Operation::create_equal_with_text( + original_text_index, + raw_operation.get_original_text(), + ) } else { - Operation::create_equal(order, length) + Operation::create_equal(original_text_index, length) }; - order += length; + original_text_index += length; op } - RawOperation::Insert(tokens) => Operation::create_insert(order, tokens), + RawOperation::Insert(tokens) => Operation::create_insert(original_text_index, tokens), RawOperation::Delete(..) => { let op = if cfg!(debug_assertions) { - Operation::create_delete_with_text(order, raw_operation.get_original_text()) + Operation::create_delete_with_text( + original_text_index, + raw_operation.get_original_text(), + ) } else { - Operation::create_delete(order, length) + Operation::create_delete(original_text_index, length) }; - order += length; + original_text_index += length; op } diff --git a/src/operation_transformation/utils/elongate_operations.rs b/src/operation_transformation/utils/elongate_operations.rs index 212ba7e..1368346 100644 --- a/src/operation_transformation/utils/elongate_operations.rs +++ b/src/operation_transformation/utils/elongate_operations.rs @@ -17,6 +17,9 @@ where let mut maybe_previous_insert: Option> = None; let mut maybe_previous_delete: Option> = None; + // We don't elongate `equals` as they're needed to maintain cursor positions + // when merging against deletes. + let mut result: Vec> = raw_operations .into_iter() .flat_map(|next| match next { @@ -60,68 +63,3 @@ where result } - -// #[cfg(test)] -// mod tests { - -// use super::*; - -// #[test] -// fn test_elongate_operations_empty() { -// let operations: Vec> = vec![]; -// let result = elongate_operations(operations); -// assert_eq!(result, vec![]); -// } - -// #[test] -// fn test_elongate_operations_single_operation() { -// let operations = vec![RawOperation::Insert(vec!["test".into()])]; -// let result = elongate_operations(operations); -// assert_eq!(result.len(), 1); -// assert!(matches!(result[0], RawOperation::Insert(_))); -// } - -// #[test] -// fn test_elongate_operations_interleaved() { -// let operations = vec![ -// RawOperation::Insert(vec!["a".into()]), -// RawOperation::Delete(vec!["b".into()]), -// RawOperation::Insert(vec!["c".into()]), -// RawOperation::Delete(vec!["d".into()]), -// ]; -// let result = elongate_operations(operations); -// assert_eq!(result.len(), 2); -// assert!(matches!(result[0], RawOperation::Insert(_))); -// assert!(matches!(result[1], RawOperation::Delete(_))); -// } - -// #[test] -// fn test_elongate_operations_with_equal() { -// let operations = vec![ -// RawOperation::Equal(vec!["a".into()]), -// RawOperation::Equal(vec!["b".into()]), -// RawOperation::Insert(vec!["c".into()]), -// RawOperation::Insert(vec!["d".into()]), -// ]; -// let result = elongate_operations(operations); -// assert_eq!(result.len(), 2); -// assert!(matches!(result[0], RawOperation::Equal(_))); -// assert!(matches!(result[1], RawOperation::Insert(_))); -// } - -// #[test] -// fn test_elongate_operations_mixed_sequence() { -// let operations = vec![ -// RawOperation::Insert(vec!["a".into()]), -// RawOperation::Equal(vec!["b".into()]), -// RawOperation::Delete(vec!["c".into()]), -// RawOperation::Equal(vec!["d".into()]), -// ]; -// let result = elongate_operations(operations); -// assert_eq!(result.len(), 4); -// assert!(matches!(result[0], RawOperation::Insert(_))); -// assert!(matches!(result[1], RawOperation::Equal(_))); -// assert!(matches!(result[2], RawOperation::Delete(_))); -// assert!(matches!(result[3], RawOperation::Equal(_))); -// } -// }