@@ -400,9 +400,7 @@ impl ChangeSet {
400400/// a single transaction.
401401#[derive(Debug, Clone)]
402402pub struct Transaction {
403− /// Changes made to the buffer.
404− pub(crate) changes: ChangeSet,
405− /// When set, explicitly updates the selection.
403+ changes: ChangeSet,
406404 selection: Option<Selection>,
407405 // effects, annotations
408406 // scroll_into_view
@@ -417,40 +415,35 @@ impl Transaction {
417415 }
418416 }
419417
418+ /// Changes made to the buffer.
420419 pub fn changes(&self) -> &ChangeSet {
421420 &self.changes
422421 }
423422
423+ /// When set, explicitly updates the selection.
424+ pub fn selection(&self) -> Option<&Selection> {
425+ self.selection.as_ref()
426+ }
427+
424428 /// Returns true if applied successfully.
425− pub fn apply(&self, state: &mut State) -> bool {
429+ pub fn apply(&self, doc: &mut Rope) -> bool {
426430 if !self.changes.is_empty() {
427431 // apply changes to the document
428− if !self.changes.apply(&mut state.doc) {
432+ if !self.changes.apply(doc) {
429433 return false;
430434 }
431435 }
432436
433− // TODO: also avoid mapping the selection if not necessary
434−
435− // update the selection: either take the selection specified in the transaction, or map the
436− // current selection through changes.
437− state.selection = self
438− .selection
439− .clone()
440− .unwrap_or_else(|| state.selection.clone().map(&self.changes));
441−
442437 true
443438 }
444439
445440 /// Generate a transaction that reverts this one.
446− pub fn invert(&self, original: &State) -> Self {
447− let changes = self.changes.invert(&original.doc);
448− // Store the current cursor position
449− let selection = original.selection.clone();
441+ pub fn invert(&self, original: &Rope) -> Self {
442+ let changes = self.changes.invert(original);
450443
451444 Self {
452445 changes,
453− selection: Some(selection),
446+ selection: None,
454447 }
455448 }
456449
@@ -675,7 +668,7 @@ mod test {
675668 // (1, 1, None) is a useless 0-width delete
676669 vec![(1, 1, None), (6, 11, Some("void".into())), (12, 17, None)].into_iter(),
677670 );
678− transaction.apply(&mut state);
671+ transaction.apply(&mut state.doc);
679672 assert_eq!(state.doc, Rope::from_str("hello void! 123"));
680673 }
681674
@@ -691,15 +684,20 @@ mod test {
691684 fn optimized_composition() {
692685 let mut state = State::new("".into());
693686 let t1 = Transaction::insert(&state.doc, &state.selection, Tendril::from_char('h'));
694− t1.apply(&mut state);
687+ t1.apply(&mut state.doc);
688+ state.selection = state.selection.clone().map(t1.changes());
695689 let t2 = Transaction::insert(&state.doc, &state.selection, Tendril::from_char('e'));
696− t2.apply(&mut state);
690+ t2.apply(&mut state.doc);
691+ state.selection = state.selection.clone().map(t2.changes());
697692 let t3 = Transaction::insert(&state.doc, &state.selection, Tendril::from_char('l'));
698− t3.apply(&mut state);
693+ t3.apply(&mut state.doc);
694+ state.selection = state.selection.clone().map(t3.changes());
699695 let t4 = Transaction::insert(&state.doc, &state.selection, Tendril::from_char('l'));
700− t4.apply(&mut state);
696+ t4.apply(&mut state.doc);
697+ state.selection = state.selection.clone().map(t4.changes());
701698 let t5 = Transaction::insert(&state.doc, &state.selection, Tendril::from_char('o'));
702− t5.apply(&mut state);
699+ t5.apply(&mut state.doc);
700+ state.selection = state.selection.clone().map(t5.changes());
703701
704702 assert_eq!(state.doc, Rope::from_str("hello"));
705703