@@ -1,4 +1,4 @@
1−use crate::{Rope, Selection, Tendril};
1+use crate::{Rope, Selection, SelectionRange, State, Tendril};
3// TODO: divided into three different operations, I sort of like having just
3// TODO: divided into three different operations, I sort of like having just
4// Splice { extent, Option<text>, distance } better.
4// Splice { extent, Option<text>, distance } better.
@@ -47,18 +47,6 @@ impl ChangeSet {
50− pub fn insert(doc: &Rope, pos: usize, c: char) -> Self {
51− let len = doc.len_chars();
55− Change::Insert(Tendril::from_char(c)),
56− Change::Retain(len - pos),
62 // TODO: from iter
50 // TODO: from iter
64 /// Combine two changesets together.
52 /// Combine two changesets together.
@@ -210,8 +198,11 @@ impl ChangeSet {
210 unimplemented!()
198 unimplemented!()
201+ /// Returns true if applied successfully.
213− pub fn apply(&self, text: &mut Rope) {
202+ pub fn apply(&self, text: &mut Rope) -> bool {
214− // TODO: validate text.chars() == self.len
203+ if text.len_chars() != self.len {
216 let mut pos = 0;
207 let mut pos = 0;
@@ -231,6 +222,7 @@ impl ChangeSet {
236 /// `true` when the set is empty.
228 /// `true` when the set is empty.
@@ -332,7 +324,60 @@ pub struct Transaction {
332 // scroll_into_view
324 // scroll_into_view
335−impl Transaction {}
327+impl Transaction {
328+ /// Returns true if applied successfully.
329+ pub fn apply(&self, state: &mut State) -> bool {
330+ // apply changes to the document
331+ if !self.changes.apply(&mut state.doc) {
335+ // update the selection: either take the selection specified in the transaction, or map the
336+ // current selection through changes.
337+ state.selection = self
340+ .unwrap_or_else(|| state.selection.clone().map(&self.changes));
345+ pub fn insert(state: &State, text: Tendril) -> Self {
346+ let len = state.doc.len_chars();
347+ let ranges = state.selection.ranges();
348+ let mut changes = Vec::with_capacity(2 * ranges.len() + 1);
351+ for range in state.selection.ranges() {
352+ let cur = range.head;
353+ changes.push(Change::Retain(cur));
354+ changes.push(Change::Insert(text.clone()));
357+ changes.push(Change::Retain(len - last));
359+ Self::from(ChangeSet { changes, len })
362+ pub fn change_selection<F>(selection: Selection, f: F) -> Self
364+ F: Fn(SelectionRange) -> ChangeSet,
366+ selection.ranges().iter().map(|range| true);
367+ // TODO: most idiomatic would be to return a
368+ // Change { from: x, to: y, insert: "str" }
373+impl From<ChangeSet> for Transaction {
374+ fn from(changes: ChangeSet) -> Self {
337#[cfg(test)]
382#[cfg(test)]
338mod test {
383mod test {