1mod anchor;
2mod operation_queue;
3mod patch;
4mod point;
5mod point_utf16;
6#[cfg(any(test, feature = "test-support"))]
7pub mod random_char_iter;
8pub mod rope;
9mod selection;
10#[cfg(test)]
11mod tests;
12
13pub use anchor::*;
14use anyhow::{anyhow, Result};
15use clock::ReplicaId;
16use collections::{HashMap, HashSet};
17use operation_queue::OperationQueue;
18pub use patch::Patch;
19pub use point::*;
20pub use point_utf16::*;
21#[cfg(any(test, feature = "test-support"))]
22pub use random_char_iter::*;
23use rope::TextDimension;
24pub use rope::{Chunks, Rope, TextSummary};
25pub use selection::*;
26use std::{
27 cmp::{self, Reverse},
28 iter::Iterator,
29 ops::{self, Deref, Range, Sub},
30 str,
31 sync::Arc,
32 time::{Duration, Instant},
33};
34pub use sum_tree::Bias;
35use sum_tree::{FilterCursor, SumTree};
36
37#[derive(Clone)]
38pub struct Buffer {
39 snapshot: Snapshot,
40 last_edit: clock::Local,
41 history: History,
42 selections: HashMap<SelectionSetId, SelectionSet>,
43 deferred_ops: OperationQueue,
44 deferred_replicas: HashSet<ReplicaId>,
45 replica_id: ReplicaId,
46 remote_id: u64,
47 local_clock: clock::Local,
48 lamport_clock: clock::Lamport,
49}
50
51#[derive(Clone)]
52pub struct Snapshot {
53 visible_text: Rope,
54 deleted_text: Rope,
55 undo_map: UndoMap,
56 fragments: SumTree<Fragment>,
57 pub version: clock::Global,
58}
59
60#[derive(Clone, Debug)]
61pub struct Transaction {
62 start: clock::Global,
63 end: clock::Global,
64 edits: Vec<clock::Local>,
65 ranges: Vec<Range<FullOffset>>,
66 selections_before: HashMap<SelectionSetId, Arc<AnchorRangeMap<SelectionState>>>,
67 selections_after: HashMap<SelectionSetId, Arc<AnchorRangeMap<SelectionState>>>,
68 first_edit_at: Instant,
69 last_edit_at: Instant,
70}
71
72impl Transaction {
73 pub fn starting_selection_set_ids<'a>(&'a self) -> impl Iterator<Item = SelectionSetId> + 'a {
74 self.selections_before.keys().copied()
75 }
76
77 fn push_edit(&mut self, edit: &EditOperation) {
78 self.edits.push(edit.timestamp.local());
79 self.end.observe(edit.timestamp.local());
80
81 let mut other_ranges = edit.ranges.iter().peekable();
82 let mut new_ranges = Vec::new();
83 let insertion_len = edit.new_text.as_ref().map_or(0, |t| t.len());
84 let mut delta = 0;
85
86 for mut self_range in self.ranges.iter().cloned() {
87 self_range.start += delta;
88 self_range.end += delta;
89
90 while let Some(other_range) = other_ranges.peek() {
91 let mut other_range = (*other_range).clone();
92 other_range.start += delta;
93 other_range.end += delta;
94
95 if other_range.start <= self_range.end {
96 other_ranges.next().unwrap();
97 delta += insertion_len;
98
99 if other_range.end < self_range.start {
100 new_ranges.push(other_range.start..other_range.end + insertion_len);
101 self_range.start += insertion_len;
102 self_range.end += insertion_len;
103 } else {
104 self_range.start = cmp::min(self_range.start, other_range.start);
105 self_range.end = cmp::max(self_range.end, other_range.end) + insertion_len;
106 }
107 } else {
108 break;
109 }
110 }
111
112 new_ranges.push(self_range);
113 }
114
115 for other_range in other_ranges {
116 new_ranges.push(other_range.start + delta..other_range.end + delta + insertion_len);
117 delta += insertion_len;
118 }
119
120 self.ranges = new_ranges;
121 }
122}
123
124#[derive(Clone)]
125pub struct History {
126 // TODO: Turn this into a String or Rope, maybe.
127 pub base_text: Arc<str>,
128 ops: HashMap<clock::Local, EditOperation>,
129 undo_stack: Vec<Transaction>,
130 redo_stack: Vec<Transaction>,
131 transaction_depth: usize,
132 group_interval: Duration,
133}
134
135impl History {
136 pub fn new(base_text: Arc<str>) -> Self {
137 Self {
138 base_text,
139 ops: Default::default(),
140 undo_stack: Vec::new(),
141 redo_stack: Vec::new(),
142 transaction_depth: 0,
143 group_interval: Duration::from_millis(300),
144 }
145 }
146
147 fn push(&mut self, op: EditOperation) {
148 self.ops.insert(op.timestamp.local(), op);
149 }
150
151 fn start_transaction(
152 &mut self,
153 start: clock::Global,
154 selections_before: HashMap<SelectionSetId, Arc<AnchorRangeMap<SelectionState>>>,
155 now: Instant,
156 ) {
157 self.transaction_depth += 1;
158 if self.transaction_depth == 1 {
159 self.undo_stack.push(Transaction {
160 start: start.clone(),
161 end: start,
162 edits: Vec::new(),
163 ranges: Vec::new(),
164 selections_before,
165 selections_after: Default::default(),
166 first_edit_at: now,
167 last_edit_at: now,
168 });
169 }
170 }
171
172 fn end_transaction(
173 &mut self,
174 selections_after: HashMap<SelectionSetId, Arc<AnchorRangeMap<SelectionState>>>,
175 now: Instant,
176 ) -> Option<&Transaction> {
177 assert_ne!(self.transaction_depth, 0);
178 self.transaction_depth -= 1;
179 if self.transaction_depth == 0 {
180 if self.undo_stack.last().unwrap().ranges.is_empty() {
181 self.undo_stack.pop();
182 None
183 } else {
184 let transaction = self.undo_stack.last_mut().unwrap();
185 transaction.selections_after = selections_after;
186 transaction.last_edit_at = now;
187 Some(transaction)
188 }
189 } else {
190 None
191 }
192 }
193
194 fn group(&mut self) {
195 let mut new_len = self.undo_stack.len();
196 let mut transactions = self.undo_stack.iter_mut();
197
198 if let Some(mut transaction) = transactions.next_back() {
199 while let Some(prev_transaction) = transactions.next_back() {
200 if transaction.first_edit_at - prev_transaction.last_edit_at <= self.group_interval
201 && transaction.start == prev_transaction.end
202 {
203 transaction = prev_transaction;
204 new_len -= 1;
205 } else {
206 break;
207 }
208 }
209 }
210
211 let (transactions_to_keep, transactions_to_merge) = self.undo_stack.split_at_mut(new_len);
212 if let Some(last_transaction) = transactions_to_keep.last_mut() {
213 for transaction in &*transactions_to_merge {
214 for edit_id in &transaction.edits {
215 last_transaction.push_edit(&self.ops[edit_id]);
216 }
217 }
218
219 if let Some(transaction) = transactions_to_merge.last_mut() {
220 last_transaction.last_edit_at = transaction.last_edit_at;
221 last_transaction
222 .selections_after
223 .extend(transaction.selections_after.drain());
224 last_transaction.end = transaction.end.clone();
225 }
226 }
227
228 self.undo_stack.truncate(new_len);
229 }
230
231 fn push_undo(&mut self, edit_id: clock::Local) {
232 assert_ne!(self.transaction_depth, 0);
233 let last_transaction = self.undo_stack.last_mut().unwrap();
234 last_transaction.push_edit(&self.ops[&edit_id]);
235 }
236
237 fn pop_undo(&mut self) -> Option<&Transaction> {
238 assert_eq!(self.transaction_depth, 0);
239 if let Some(transaction) = self.undo_stack.pop() {
240 self.redo_stack.push(transaction);
241 self.redo_stack.last()
242 } else {
243 None
244 }
245 }
246
247 fn pop_redo(&mut self) -> Option<&Transaction> {
248 assert_eq!(self.transaction_depth, 0);
249 if let Some(transaction) = self.redo_stack.pop() {
250 self.undo_stack.push(transaction);
251 self.undo_stack.last()
252 } else {
253 None
254 }
255 }
256}
257
258#[derive(Clone, Default, Debug)]
259struct UndoMap(HashMap<clock::Local, Vec<(clock::Local, u32)>>);
260
261impl UndoMap {
262 fn insert(&mut self, undo: &UndoOperation) {
263 for (edit_id, count) in &undo.counts {
264 self.0.entry(*edit_id).or_default().push((undo.id, *count));
265 }
266 }
267
268 fn is_undone(&self, edit_id: clock::Local) -> bool {
269 self.undo_count(edit_id) % 2 == 1
270 }
271
272 fn was_undone(&self, edit_id: clock::Local, version: &clock::Global) -> bool {
273 let undo_count = self
274 .0
275 .get(&edit_id)
276 .unwrap_or(&Vec::new())
277 .iter()
278 .filter(|(undo_id, _)| version.observed(*undo_id))
279 .map(|(_, undo_count)| *undo_count)
280 .max()
281 .unwrap_or(0);
282 undo_count % 2 == 1
283 }
284
285 fn undo_count(&self, edit_id: clock::Local) -> u32 {
286 self.0
287 .get(&edit_id)
288 .unwrap_or(&Vec::new())
289 .iter()
290 .map(|(_, undo_count)| *undo_count)
291 .max()
292 .unwrap_or(0)
293 }
294}
295
296struct Edits<'a, D: TextDimension<'a>, F: FnMut(&FragmentSummary) -> bool> {
297 visible_cursor: rope::Cursor<'a>,
298 deleted_cursor: rope::Cursor<'a>,
299 fragments_cursor: Option<FilterCursor<'a, F, Fragment, FragmentTextSummary>>,
300 undos: &'a UndoMap,
301 since: &'a clock::Global,
302 old_end: D,
303 new_end: D,
304}
305
306#[derive(Clone, Debug, Default, Eq, PartialEq)]
307pub struct Edit<D> {
308 pub old: Range<D>,
309 pub new: Range<D>,
310}
311
312impl<D> Edit<D>
313where
314 D: Sub<D, Output = D> + PartialEq + Copy,
315{
316 pub fn old_len(&self) -> D {
317 self.old.end - self.old.start
318 }
319
320 pub fn new_len(&self) -> D {
321 self.new.end - self.new.start
322 }
323
324 pub fn is_empty(&self) -> bool {
325 self.old.start == self.old.end && self.new.start == self.new.end
326 }
327}
328
329impl<D1, D2> Edit<(D1, D2)> {
330 pub fn flatten(self) -> (Edit<D1>, Edit<D2>) {
331 (
332 Edit {
333 old: self.old.start.0..self.old.end.0,
334 new: self.new.start.0..self.new.end.0,
335 },
336 Edit {
337 old: self.old.start.1..self.old.end.1,
338 new: self.new.start.1..self.new.end.1,
339 },
340 )
341 }
342}
343
344#[derive(Copy, Clone, Debug, Default, Eq, PartialEq)]
345pub struct InsertionTimestamp {
346 pub replica_id: ReplicaId,
347 pub local: clock::Seq,
348 pub lamport: clock::Seq,
349}
350
351impl InsertionTimestamp {
352 fn local(&self) -> clock::Local {
353 clock::Local {
354 replica_id: self.replica_id,
355 value: self.local,
356 }
357 }
358
359 fn lamport(&self) -> clock::Lamport {
360 clock::Lamport {
361 replica_id: self.replica_id,
362 value: self.lamport,
363 }
364 }
365}
366
367#[derive(Eq, PartialEq, Clone, Debug)]
368struct Fragment {
369 timestamp: InsertionTimestamp,
370 len: usize,
371 visible: bool,
372 deletions: HashSet<clock::Local>,
373 max_undos: clock::Global,
374}
375
376#[derive(Eq, PartialEq, Clone, Debug)]
377pub struct FragmentSummary {
378 text: FragmentTextSummary,
379 max_version: clock::Global,
380 min_insertion_version: clock::Global,
381 max_insertion_version: clock::Global,
382}
383
384#[derive(Copy, Default, Clone, Debug, PartialEq, Eq)]
385struct FragmentTextSummary {
386 visible: usize,
387 deleted: usize,
388}
389
390impl<'a> sum_tree::Dimension<'a, FragmentSummary> for FragmentTextSummary {
391 fn add_summary(&mut self, summary: &'a FragmentSummary, _: &Option<clock::Global>) {
392 self.visible += summary.text.visible;
393 self.deleted += summary.text.deleted;
394 }
395}
396
397#[derive(Clone, Debug, Eq, PartialEq)]
398pub enum Operation {
399 Edit(EditOperation),
400 Undo {
401 undo: UndoOperation,
402 lamport_timestamp: clock::Lamport,
403 },
404 UpdateSelections {
405 set_id: SelectionSetId,
406 selections: Arc<AnchorRangeMap<SelectionState>>,
407 lamport_timestamp: clock::Lamport,
408 },
409 RemoveSelections {
410 set_id: SelectionSetId,
411 lamport_timestamp: clock::Lamport,
412 },
413 SetActiveSelections {
414 set_id: Option<SelectionSetId>,
415 lamport_timestamp: clock::Lamport,
416 },
417 #[cfg(test)]
418 Test(clock::Lamport),
419}
420
421#[derive(Clone, Debug, Eq, PartialEq)]
422pub struct EditOperation {
423 pub timestamp: InsertionTimestamp,
424 pub version: clock::Global,
425 pub ranges: Vec<Range<FullOffset>>,
426 pub new_text: Option<String>,
427}
428
429#[derive(Clone, Debug, Eq, PartialEq)]
430pub struct UndoOperation {
431 pub id: clock::Local,
432 pub counts: HashMap<clock::Local, u32>,
433 pub ranges: Vec<Range<FullOffset>>,
434 pub version: clock::Global,
435}
436
437impl Buffer {
438 pub fn new(replica_id: u16, remote_id: u64, history: History) -> Buffer {
439 let mut fragments = SumTree::new();
440
441 let mut local_clock = clock::Local::new(replica_id);
442 let mut lamport_clock = clock::Lamport::new(replica_id);
443 let mut version = clock::Global::new();
444 let visible_text = Rope::from(history.base_text.as_ref());
445 if visible_text.len() > 0 {
446 let timestamp = InsertionTimestamp {
447 replica_id: 0,
448 local: 1,
449 lamport: 1,
450 };
451 local_clock.observe(timestamp.local());
452 lamport_clock.observe(timestamp.lamport());
453 version.observe(timestamp.local());
454 fragments.push(
455 Fragment {
456 timestamp,
457 len: visible_text.len(),
458 visible: true,
459 deletions: Default::default(),
460 max_undos: Default::default(),
461 },
462 &None,
463 );
464 }
465
466 Buffer {
467 snapshot: Snapshot {
468 visible_text,
469 deleted_text: Rope::new(),
470 fragments,
471 version,
472 undo_map: Default::default(),
473 },
474 last_edit: clock::Local::default(),
475 history,
476 selections: HashMap::default(),
477 deferred_ops: OperationQueue::new(),
478 deferred_replicas: HashSet::default(),
479 replica_id,
480 remote_id,
481 local_clock,
482 lamport_clock,
483 }
484 }
485
486 pub fn version(&self) -> clock::Global {
487 self.version.clone()
488 }
489
490 pub fn snapshot(&self) -> Snapshot {
491 Snapshot {
492 visible_text: self.visible_text.clone(),
493 deleted_text: self.deleted_text.clone(),
494 undo_map: self.undo_map.clone(),
495 fragments: self.fragments.clone(),
496 version: self.version.clone(),
497 }
498 }
499
500 pub fn replica_id(&self) -> ReplicaId {
501 self.local_clock.replica_id
502 }
503
504 pub fn remote_id(&self) -> u64 {
505 self.remote_id
506 }
507
508 pub fn deferred_ops_len(&self) -> usize {
509 self.deferred_ops.len()
510 }
511
512 pub fn edit<R, I, S, T>(&mut self, ranges: R, new_text: T) -> EditOperation
513 where
514 R: IntoIterator<IntoIter = I>,
515 I: ExactSizeIterator<Item = Range<S>>,
516 S: ToOffset,
517 T: Into<String>,
518 {
519 let new_text = new_text.into();
520 let new_text_len = new_text.len();
521 let new_text = if new_text_len > 0 {
522 Some(new_text)
523 } else {
524 None
525 };
526
527 self.start_transaction(None).unwrap();
528 let timestamp = InsertionTimestamp {
529 replica_id: self.replica_id,
530 local: self.local_clock.tick().value,
531 lamport: self.lamport_clock.tick().value,
532 };
533 let edit = self.apply_local_edit(ranges.into_iter(), new_text, timestamp);
534
535 self.history.push(edit.clone());
536 self.history.push_undo(edit.timestamp.local());
537 self.last_edit = edit.timestamp.local();
538 self.snapshot.version.observe(edit.timestamp.local());
539 self.end_transaction(None);
540 edit
541 }
542
543 fn apply_local_edit<S: ToOffset>(
544 &mut self,
545 ranges: impl ExactSizeIterator<Item = Range<S>>,
546 new_text: Option<String>,
547 timestamp: InsertionTimestamp,
548 ) -> EditOperation {
549 let mut edit = EditOperation {
550 timestamp,
551 version: self.version(),
552 ranges: Vec::with_capacity(ranges.len()),
553 new_text: None,
554 };
555
556 let mut ranges = ranges
557 .map(|range| range.start.to_offset(&*self)..range.end.to_offset(&*self))
558 .peekable();
559
560 let mut new_ropes =
561 RopeBuilder::new(self.visible_text.cursor(0), self.deleted_text.cursor(0));
562 let mut old_fragments = self.fragments.cursor::<FragmentTextSummary>();
563 let mut new_fragments =
564 old_fragments.slice(&ranges.peek().unwrap().start, Bias::Right, &None);
565 new_ropes.push_tree(new_fragments.summary().text);
566
567 let mut fragment_start = old_fragments.start().visible;
568 for range in ranges {
569 let fragment_end = old_fragments.end(&None).visible;
570
571 // If the current fragment ends before this range, then jump ahead to the first fragment
572 // that extends past the start of this range, reusing any intervening fragments.
573 if fragment_end < range.start {
574 // If the current fragment has been partially consumed, then consume the rest of it
575 // and advance to the next fragment before slicing.
576 if fragment_start > old_fragments.start().visible {
577 if fragment_end > fragment_start {
578 let mut suffix = old_fragments.item().unwrap().clone();
579 suffix.len = fragment_end - fragment_start;
580 new_ropes.push_fragment(&suffix, suffix.visible);
581 new_fragments.push(suffix, &None);
582 }
583 old_fragments.next(&None);
584 }
585
586 let slice = old_fragments.slice(&range.start, Bias::Right, &None);
587 new_ropes.push_tree(slice.summary().text);
588 new_fragments.push_tree(slice, &None);
589 fragment_start = old_fragments.start().visible;
590 }
591
592 let full_range_start = FullOffset(range.start + old_fragments.start().deleted);
593
594 // Preserve any portion of the current fragment that precedes this range.
595 if fragment_start < range.start {
596 let mut prefix = old_fragments.item().unwrap().clone();
597 prefix.len = range.start - fragment_start;
598 new_ropes.push_fragment(&prefix, prefix.visible);
599 new_fragments.push(prefix, &None);
600 fragment_start = range.start;
601 }
602
603 // Insert the new text before any existing fragments within the range.
604 if let Some(new_text) = new_text.as_deref() {
605 new_ropes.push_str(new_text);
606 new_fragments.push(
607 Fragment {
608 timestamp,
609 len: new_text.len(),
610 deletions: Default::default(),
611 max_undos: Default::default(),
612 visible: true,
613 },
614 &None,
615 );
616 }
617
618 // Advance through every fragment that intersects this range, marking the intersecting
619 // portions as deleted.
620 while fragment_start < range.end {
621 let fragment = old_fragments.item().unwrap();
622 let fragment_end = old_fragments.end(&None).visible;
623 let mut intersection = fragment.clone();
624 let intersection_end = cmp::min(range.end, fragment_end);
625 if fragment.visible {
626 intersection.len = intersection_end - fragment_start;
627 intersection.deletions.insert(timestamp.local());
628 intersection.visible = false;
629 }
630 if intersection.len > 0 {
631 new_ropes.push_fragment(&intersection, fragment.visible);
632 new_fragments.push(intersection, &None);
633 fragment_start = intersection_end;
634 }
635 if fragment_end <= range.end {
636 old_fragments.next(&None);
637 }
638 }
639
640 let full_range_end = FullOffset(range.end + old_fragments.start().deleted);
641 edit.ranges.push(full_range_start..full_range_end);
642 }
643
644 // If the current fragment has been partially consumed, then consume the rest of it
645 // and advance to the next fragment before slicing.
646 if fragment_start > old_fragments.start().visible {
647 let fragment_end = old_fragments.end(&None).visible;
648 if fragment_end > fragment_start {
649 let mut suffix = old_fragments.item().unwrap().clone();
650 suffix.len = fragment_end - fragment_start;
651 new_ropes.push_fragment(&suffix, suffix.visible);
652 new_fragments.push(suffix, &None);
653 }
654 old_fragments.next(&None);
655 }
656
657 let suffix = old_fragments.suffix(&None);
658 new_ropes.push_tree(suffix.summary().text);
659 new_fragments.push_tree(suffix, &None);
660 let (visible_text, deleted_text) = new_ropes.finish();
661 drop(old_fragments);
662
663 self.snapshot.fragments = new_fragments;
664 self.snapshot.visible_text = visible_text;
665 self.snapshot.deleted_text = deleted_text;
666 edit.new_text = new_text;
667 edit
668 }
669
670 pub fn apply_ops<I: IntoIterator<Item = Operation>>(&mut self, ops: I) -> Result<()> {
671 let mut deferred_ops = Vec::new();
672 for op in ops {
673 if self.can_apply_op(&op) {
674 self.apply_op(op)?;
675 } else {
676 self.deferred_replicas.insert(op.replica_id());
677 deferred_ops.push(op);
678 }
679 }
680 self.deferred_ops.insert(deferred_ops);
681 self.flush_deferred_ops()?;
682 Ok(())
683 }
684
685 fn apply_op(&mut self, op: Operation) -> Result<()> {
686 match op {
687 Operation::Edit(edit) => {
688 if !self.version.observed(edit.timestamp.local()) {
689 self.apply_remote_edit(
690 &edit.version,
691 &edit.ranges,
692 edit.new_text.as_deref(),
693 edit.timestamp,
694 );
695 self.snapshot.version.observe(edit.timestamp.local());
696 self.history.push(edit);
697 }
698 }
699 Operation::Undo {
700 undo,
701 lamport_timestamp,
702 } => {
703 if !self.version.observed(undo.id) {
704 self.apply_undo(&undo)?;
705 self.snapshot.version.observe(undo.id);
706 self.lamport_clock.observe(lamport_timestamp);
707 }
708 }
709 Operation::UpdateSelections {
710 set_id,
711 selections,
712 lamport_timestamp,
713 } => {
714 if let Some(set) = self.selections.get_mut(&set_id) {
715 set.selections = selections;
716 } else {
717 self.selections.insert(
718 set_id,
719 SelectionSet {
720 id: set_id,
721 selections,
722 active: false,
723 },
724 );
725 }
726 self.lamport_clock.observe(lamport_timestamp);
727 }
728 Operation::RemoveSelections {
729 set_id,
730 lamport_timestamp,
731 } => {
732 self.selections.remove(&set_id);
733 self.lamport_clock.observe(lamport_timestamp);
734 }
735 Operation::SetActiveSelections {
736 set_id,
737 lamport_timestamp,
738 } => {
739 for (id, set) in &mut self.selections {
740 if id.replica_id == lamport_timestamp.replica_id {
741 if Some(*id) == set_id {
742 set.active = true;
743 } else {
744 set.active = false;
745 }
746 }
747 }
748 self.lamport_clock.observe(lamport_timestamp);
749 }
750 #[cfg(test)]
751 Operation::Test(_) => {}
752 }
753 Ok(())
754 }
755
756 fn apply_remote_edit(
757 &mut self,
758 version: &clock::Global,
759 ranges: &[Range<FullOffset>],
760 new_text: Option<&str>,
761 timestamp: InsertionTimestamp,
762 ) {
763 if ranges.is_empty() {
764 return;
765 }
766
767 let cx = Some(version.clone());
768 let mut new_ropes =
769 RopeBuilder::new(self.visible_text.cursor(0), self.deleted_text.cursor(0));
770 let mut old_fragments = self.fragments.cursor::<VersionedFullOffset>();
771 let mut new_fragments = old_fragments.slice(
772 &VersionedFullOffset::Offset(ranges[0].start),
773 Bias::Left,
774 &cx,
775 );
776 new_ropes.push_tree(new_fragments.summary().text);
777
778 let mut fragment_start = old_fragments.start().full_offset();
779 for range in ranges {
780 let fragment_end = old_fragments.end(&cx).full_offset();
781
782 // If the current fragment ends before this range, then jump ahead to the first fragment
783 // that extends past the start of this range, reusing any intervening fragments.
784 if fragment_end < range.start {
785 // If the current fragment has been partially consumed, then consume the rest of it
786 // and advance to the next fragment before slicing.
787 if fragment_start > old_fragments.start().full_offset() {
788 if fragment_end > fragment_start {
789 let mut suffix = old_fragments.item().unwrap().clone();
790 suffix.len = fragment_end.0 - fragment_start.0;
791 new_ropes.push_fragment(&suffix, suffix.visible);
792 new_fragments.push(suffix, &None);
793 }
794 old_fragments.next(&cx);
795 }
796
797 let slice =
798 old_fragments.slice(&VersionedFullOffset::Offset(range.start), Bias::Left, &cx);
799 new_ropes.push_tree(slice.summary().text);
800 new_fragments.push_tree(slice, &None);
801 fragment_start = old_fragments.start().full_offset();
802 }
803
804 // If we are at the end of a non-concurrent fragment, advance to the next one.
805 let fragment_end = old_fragments.end(&cx).full_offset();
806 if fragment_end == range.start && fragment_end > fragment_start {
807 let mut fragment = old_fragments.item().unwrap().clone();
808 fragment.len = fragment_end.0 - fragment_start.0;
809 new_ropes.push_fragment(&fragment, fragment.visible);
810 new_fragments.push(fragment, &None);
811 old_fragments.next(&cx);
812 fragment_start = old_fragments.start().full_offset();
813 }
814
815 // Skip over insertions that are concurrent to this edit, but have a lower lamport
816 // timestamp.
817 while let Some(fragment) = old_fragments.item() {
818 if fragment_start == range.start
819 && fragment.timestamp.lamport() > timestamp.lamport()
820 {
821 new_ropes.push_fragment(fragment, fragment.visible);
822 new_fragments.push(fragment.clone(), &None);
823 old_fragments.next(&cx);
824 debug_assert_eq!(fragment_start, range.start);
825 } else {
826 break;
827 }
828 }
829 debug_assert!(fragment_start <= range.start);
830
831 // Preserve any portion of the current fragment that precedes this range.
832 if fragment_start < range.start {
833 let mut prefix = old_fragments.item().unwrap().clone();
834 prefix.len = range.start.0 - fragment_start.0;
835 fragment_start = range.start;
836 new_ropes.push_fragment(&prefix, prefix.visible);
837 new_fragments.push(prefix, &None);
838 }
839
840 // Insert the new text before any existing fragments within the range.
841 if let Some(new_text) = new_text {
842 new_ropes.push_str(new_text);
843 new_fragments.push(
844 Fragment {
845 timestamp,
846 len: new_text.len(),
847 deletions: Default::default(),
848 max_undos: Default::default(),
849 visible: true,
850 },
851 &None,
852 );
853 }
854
855 // Advance through every fragment that intersects this range, marking the intersecting
856 // portions as deleted.
857 while fragment_start < range.end {
858 let fragment = old_fragments.item().unwrap();
859 let fragment_end = old_fragments.end(&cx).full_offset();
860 let mut intersection = fragment.clone();
861 let intersection_end = cmp::min(range.end, fragment_end);
862 if fragment.was_visible(version, &self.undo_map) {
863 intersection.len = intersection_end.0 - fragment_start.0;
864 intersection.deletions.insert(timestamp.local());
865 intersection.visible = false;
866 }
867 if intersection.len > 0 {
868 new_ropes.push_fragment(&intersection, fragment.visible);
869 new_fragments.push(intersection, &None);
870 fragment_start = intersection_end;
871 }
872 if fragment_end <= range.end {
873 old_fragments.next(&cx);
874 }
875 }
876 }
877
878 // If the current fragment has been partially consumed, then consume the rest of it
879 // and advance to the next fragment before slicing.
880 if fragment_start > old_fragments.start().full_offset() {
881 let fragment_end = old_fragments.end(&cx).full_offset();
882 if fragment_end > fragment_start {
883 let mut suffix = old_fragments.item().unwrap().clone();
884 suffix.len = fragment_end.0 - fragment_start.0;
885 new_ropes.push_fragment(&suffix, suffix.visible);
886 new_fragments.push(suffix, &None);
887 }
888 old_fragments.next(&cx);
889 }
890
891 let suffix = old_fragments.suffix(&cx);
892 new_ropes.push_tree(suffix.summary().text);
893 new_fragments.push_tree(suffix, &None);
894 let (visible_text, deleted_text) = new_ropes.finish();
895 drop(old_fragments);
896
897 self.snapshot.fragments = new_fragments;
898 self.snapshot.visible_text = visible_text;
899 self.snapshot.deleted_text = deleted_text;
900 self.local_clock.observe(timestamp.local());
901 self.lamport_clock.observe(timestamp.lamport());
902 }
903
904 fn apply_undo(&mut self, undo: &UndoOperation) -> Result<()> {
905 self.snapshot.undo_map.insert(undo);
906
907 let mut cx = undo.version.clone();
908 for edit_id in undo.counts.keys().copied() {
909 cx.observe(edit_id);
910 }
911 let cx = Some(cx);
912
913 let mut old_fragments = self.fragments.cursor::<VersionedFullOffset>();
914 let mut new_fragments = old_fragments.slice(
915 &VersionedFullOffset::Offset(undo.ranges[0].start),
916 Bias::Right,
917 &cx,
918 );
919 let mut new_ropes =
920 RopeBuilder::new(self.visible_text.cursor(0), self.deleted_text.cursor(0));
921 new_ropes.push_tree(new_fragments.summary().text);
922
923 for range in &undo.ranges {
924 let mut end_offset = old_fragments.end(&cx).full_offset();
925
926 if end_offset < range.start {
927 let preceding_fragments = old_fragments.slice(
928 &VersionedFullOffset::Offset(range.start),
929 Bias::Right,
930 &cx,
931 );
932 new_ropes.push_tree(preceding_fragments.summary().text);
933 new_fragments.push_tree(preceding_fragments, &None);
934 }
935
936 while end_offset <= range.end {
937 if let Some(fragment) = old_fragments.item() {
938 let mut fragment = fragment.clone();
939 let fragment_was_visible = fragment.visible;
940
941 if fragment.was_visible(&undo.version, &self.undo_map)
942 || undo.counts.contains_key(&fragment.timestamp.local())
943 {
944 fragment.visible = fragment.is_visible(&self.undo_map);
945 fragment.max_undos.observe(undo.id);
946 }
947 new_ropes.push_fragment(&fragment, fragment_was_visible);
948 new_fragments.push(fragment, &None);
949
950 old_fragments.next(&cx);
951 if end_offset == old_fragments.end(&cx).full_offset() {
952 let unseen_fragments = old_fragments.slice(
953 &VersionedFullOffset::Offset(end_offset),
954 Bias::Right,
955 &cx,
956 );
957 new_ropes.push_tree(unseen_fragments.summary().text);
958 new_fragments.push_tree(unseen_fragments, &None);
959 }
960 end_offset = old_fragments.end(&cx).full_offset();
961 } else {
962 break;
963 }
964 }
965 }
966
967 let suffix = old_fragments.suffix(&cx);
968 new_ropes.push_tree(suffix.summary().text);
969 new_fragments.push_tree(suffix, &None);
970
971 drop(old_fragments);
972 let (visible_text, deleted_text) = new_ropes.finish();
973 self.snapshot.fragments = new_fragments;
974 self.snapshot.visible_text = visible_text;
975 self.snapshot.deleted_text = deleted_text;
976 Ok(())
977 }
978
979 fn flush_deferred_ops(&mut self) -> Result<()> {
980 self.deferred_replicas.clear();
981 let mut deferred_ops = Vec::new();
982 for op in self.deferred_ops.drain().cursor().cloned() {
983 if self.can_apply_op(&op) {
984 self.apply_op(op)?;
985 } else {
986 self.deferred_replicas.insert(op.replica_id());
987 deferred_ops.push(op);
988 }
989 }
990 self.deferred_ops.insert(deferred_ops);
991 Ok(())
992 }
993
994 fn can_apply_op(&self, op: &Operation) -> bool {
995 if self.deferred_replicas.contains(&op.replica_id()) {
996 false
997 } else {
998 match op {
999 Operation::Edit(edit) => self.version.ge(&edit.version),
1000 Operation::Undo { undo, .. } => self.version.ge(&undo.version),
1001 Operation::UpdateSelections { selections, .. } => {
1002 self.version.ge(selections.version())
1003 }
1004 Operation::RemoveSelections { .. } => true,
1005 Operation::SetActiveSelections { set_id, .. } => {
1006 set_id.map_or(true, |set_id| self.selections.contains_key(&set_id))
1007 }
1008 #[cfg(test)]
1009 Operation::Test(_) => true,
1010 }
1011 }
1012 }
1013
1014 pub fn peek_undo_stack(&self) -> Option<&Transaction> {
1015 self.history.undo_stack.last()
1016 }
1017
1018 pub fn start_transaction(
1019 &mut self,
1020 selection_set_ids: impl IntoIterator<Item = SelectionSetId>,
1021 ) -> Result<()> {
1022 self.start_transaction_at(selection_set_ids, Instant::now())
1023 }
1024
1025 pub fn start_transaction_at(
1026 &mut self,
1027 selection_set_ids: impl IntoIterator<Item = SelectionSetId>,
1028 now: Instant,
1029 ) -> Result<()> {
1030 let selections = selection_set_ids
1031 .into_iter()
1032 .map(|set_id| {
1033 let set = self
1034 .selections
1035 .get(&set_id)
1036 .expect("invalid selection set id");
1037 (set_id, set.selections.clone())
1038 })
1039 .collect();
1040 self.history
1041 .start_transaction(self.version.clone(), selections, now);
1042 Ok(())
1043 }
1044
1045 pub fn end_transaction(&mut self, selection_set_ids: impl IntoIterator<Item = SelectionSetId>) {
1046 self.end_transaction_at(selection_set_ids, Instant::now());
1047 }
1048
1049 pub fn end_transaction_at(
1050 &mut self,
1051 selection_set_ids: impl IntoIterator<Item = SelectionSetId>,
1052 now: Instant,
1053 ) -> Option<clock::Global> {
1054 let selections = selection_set_ids
1055 .into_iter()
1056 .map(|set_id| {
1057 let set = self
1058 .selections
1059 .get(&set_id)
1060 .expect("invalid selection set id");
1061 (set_id, set.selections.clone())
1062 })
1063 .collect();
1064
1065 if let Some(transaction) = self.history.end_transaction(selections, now) {
1066 let since = transaction.start.clone();
1067 self.history.group();
1068 Some(since)
1069 } else {
1070 None
1071 }
1072 }
1073
1074 pub fn remove_peer(&mut self, replica_id: ReplicaId) {
1075 self.selections
1076 .retain(|set_id, _| set_id.replica_id != replica_id)
1077 }
1078
1079 pub fn base_text(&self) -> &Arc<str> {
1080 &self.history.base_text
1081 }
1082
1083 pub fn history(&self) -> impl Iterator<Item = &EditOperation> {
1084 self.history.ops.values()
1085 }
1086
1087 pub fn undo(&mut self) -> Vec<Operation> {
1088 let mut ops = Vec::new();
1089 if let Some(transaction) = self.history.pop_undo().cloned() {
1090 let selections = transaction.selections_before.clone();
1091 ops.push(self.undo_or_redo(transaction).unwrap());
1092 for (set_id, selections) in selections {
1093 ops.extend(self.restore_selection_set(set_id, selections));
1094 }
1095 }
1096 ops
1097 }
1098
1099 pub fn redo(&mut self) -> Vec<Operation> {
1100 let mut ops = Vec::new();
1101 if let Some(transaction) = self.history.pop_redo().cloned() {
1102 let selections = transaction.selections_after.clone();
1103 ops.push(self.undo_or_redo(transaction).unwrap());
1104 for (set_id, selections) in selections {
1105 ops.extend(self.restore_selection_set(set_id, selections));
1106 }
1107 }
1108 ops
1109 }
1110
1111 fn undo_or_redo(&mut self, transaction: Transaction) -> Result<Operation> {
1112 let mut counts = HashMap::default();
1113 for edit_id in transaction.edits {
1114 counts.insert(edit_id, self.undo_map.undo_count(edit_id) + 1);
1115 }
1116
1117 let undo = UndoOperation {
1118 id: self.local_clock.tick(),
1119 counts,
1120 ranges: transaction.ranges,
1121 version: transaction.start.clone(),
1122 };
1123 self.apply_undo(&undo)?;
1124 self.snapshot.version.observe(undo.id);
1125
1126 Ok(Operation::Undo {
1127 undo,
1128 lamport_timestamp: self.lamport_clock.tick(),
1129 })
1130 }
1131
1132 pub fn selection_set(&self, set_id: SelectionSetId) -> Result<&SelectionSet> {
1133 self.selections
1134 .get(&set_id)
1135 .ok_or_else(|| anyhow!("invalid selection set id {:?}", set_id))
1136 }
1137
1138 pub fn selection_sets(&self) -> impl Iterator<Item = (&SelectionSetId, &SelectionSet)> {
1139 self.selections.iter()
1140 }
1141
1142 fn build_selection_anchor_range_map<T: ToOffset>(
1143 &self,
1144 selections: &[Selection<T>],
1145 ) -> Arc<AnchorRangeMap<SelectionState>> {
1146 Arc::new(self.anchor_range_map(
1147 Bias::Left,
1148 Bias::Left,
1149 selections.iter().map(|selection| {
1150 let start = selection.start.to_offset(self);
1151 let end = selection.end.to_offset(self);
1152 let range = start..end;
1153 let state = SelectionState {
1154 id: selection.id,
1155 reversed: selection.reversed,
1156 goal: selection.goal,
1157 };
1158 (range, state)
1159 }),
1160 ))
1161 }
1162
1163 pub fn update_selection_set<T: ToOffset>(
1164 &mut self,
1165 set_id: SelectionSetId,
1166 selections: &[Selection<T>],
1167 ) -> Result<Operation> {
1168 let selections = self.build_selection_anchor_range_map(selections);
1169 let set = self
1170 .selections
1171 .get_mut(&set_id)
1172 .ok_or_else(|| anyhow!("invalid selection set id {:?}", set_id))?;
1173 set.selections = selections.clone();
1174 Ok(Operation::UpdateSelections {
1175 set_id,
1176 selections,
1177 lamport_timestamp: self.lamport_clock.tick(),
1178 })
1179 }
1180
1181 pub fn restore_selection_set(
1182 &mut self,
1183 set_id: SelectionSetId,
1184 selections: Arc<AnchorRangeMap<SelectionState>>,
1185 ) -> Result<Operation> {
1186 let set = self
1187 .selections
1188 .get_mut(&set_id)
1189 .ok_or_else(|| anyhow!("invalid selection set id {:?}", set_id))?;
1190 set.selections = selections.clone();
1191 Ok(Operation::UpdateSelections {
1192 set_id,
1193 selections,
1194 lamport_timestamp: self.lamport_clock.tick(),
1195 })
1196 }
1197
1198 pub fn add_selection_set<T: ToOffset>(&mut self, selections: &[Selection<T>]) -> Operation {
1199 let selections = self.build_selection_anchor_range_map(selections);
1200 let set_id = self.lamport_clock.tick();
1201 self.selections.insert(
1202 set_id,
1203 SelectionSet {
1204 id: set_id,
1205 selections: selections.clone(),
1206 active: false,
1207 },
1208 );
1209 Operation::UpdateSelections {
1210 set_id,
1211 selections,
1212 lamport_timestamp: set_id,
1213 }
1214 }
1215
1216 pub fn add_raw_selection_set(&mut self, id: SelectionSetId, selections: SelectionSet) {
1217 self.selections.insert(id, selections);
1218 }
1219
1220 pub fn set_active_selection_set(
1221 &mut self,
1222 set_id: Option<SelectionSetId>,
1223 ) -> Result<Operation> {
1224 if let Some(set_id) = set_id {
1225 assert_eq!(set_id.replica_id, self.replica_id());
1226 }
1227
1228 for (id, set) in &mut self.selections {
1229 if id.replica_id == self.local_clock.replica_id {
1230 if Some(*id) == set_id {
1231 set.active = true;
1232 } else {
1233 set.active = false;
1234 }
1235 }
1236 }
1237
1238 Ok(Operation::SetActiveSelections {
1239 set_id,
1240 lamport_timestamp: self.lamport_clock.tick(),
1241 })
1242 }
1243
1244 pub fn remove_selection_set(&mut self, set_id: SelectionSetId) -> Result<Operation> {
1245 self.selections
1246 .remove(&set_id)
1247 .ok_or_else(|| anyhow!("invalid selection set id {:?}", set_id))?;
1248 Ok(Operation::RemoveSelections {
1249 set_id,
1250 lamport_timestamp: self.lamport_clock.tick(),
1251 })
1252 }
1253}
1254
1255#[cfg(any(test, feature = "test-support"))]
1256impl Buffer {
1257 fn random_byte_range(&mut self, start_offset: usize, rng: &mut impl rand::Rng) -> Range<usize> {
1258 let end = self.clip_offset(rng.gen_range(start_offset..=self.len()), Bias::Right);
1259 let start = self.clip_offset(rng.gen_range(start_offset..=end), Bias::Right);
1260 start..end
1261 }
1262
1263 pub fn randomly_edit<T>(
1264 &mut self,
1265 rng: &mut T,
1266 old_range_count: usize,
1267 ) -> (Vec<Range<usize>>, String, Operation)
1268 where
1269 T: rand::Rng,
1270 {
1271 let mut old_ranges: Vec<Range<usize>> = Vec::new();
1272 for _ in 0..old_range_count {
1273 let last_end = old_ranges.last().map_or(0, |last_range| last_range.end + 1);
1274 if last_end > self.len() {
1275 break;
1276 }
1277 old_ranges.push(self.random_byte_range(last_end, rng));
1278 }
1279 let new_text_len = rng.gen_range(0..10);
1280 let new_text: String = crate::random_char_iter::RandomCharIter::new(&mut *rng)
1281 .take(new_text_len)
1282 .collect();
1283 log::info!(
1284 "mutating buffer {} at {:?}: {:?}",
1285 self.replica_id,
1286 old_ranges,
1287 new_text
1288 );
1289 let op = self.edit(old_ranges.iter().cloned(), new_text.as_str());
1290 (old_ranges, new_text, Operation::Edit(op))
1291 }
1292
1293 pub fn randomly_mutate<T>(&mut self, rng: &mut T) -> Vec<Operation>
1294 where
1295 T: rand::Rng,
1296 {
1297 use rand::prelude::*;
1298
1299 let mut ops = vec![self.randomly_edit(rng, 5).2];
1300
1301 // Randomly add, remove or mutate selection sets.
1302 let replica_selection_sets = &self
1303 .selection_sets()
1304 .map(|(set_id, _)| *set_id)
1305 .filter(|set_id| self.replica_id == set_id.replica_id)
1306 .collect::<Vec<_>>();
1307 let set_id = replica_selection_sets.choose(rng);
1308 if set_id.is_some() && rng.gen_bool(1.0 / 6.0) {
1309 ops.push(self.remove_selection_set(*set_id.unwrap()).unwrap());
1310 } else {
1311 let mut ranges = Vec::new();
1312 for _ in 0..5 {
1313 ranges.push(self.random_byte_range(0, rng));
1314 }
1315 let new_selections = self.selections_from_ranges(ranges).unwrap();
1316
1317 let op = if set_id.is_none() || rng.gen_bool(1.0 / 5.0) {
1318 self.add_selection_set(&new_selections)
1319 } else {
1320 self.update_selection_set(*set_id.unwrap(), &new_selections)
1321 .unwrap()
1322 };
1323 ops.push(op);
1324 }
1325
1326 ops
1327 }
1328
1329 pub fn randomly_undo_redo(&mut self, rng: &mut impl rand::Rng) -> Vec<Operation> {
1330 use rand::prelude::*;
1331
1332 let mut ops = Vec::new();
1333 for _ in 0..rng.gen_range(1..=5) {
1334 if let Some(transaction) = self.history.undo_stack.choose(rng).cloned() {
1335 log::info!(
1336 "undoing buffer {} transaction {:?}",
1337 self.replica_id,
1338 transaction
1339 );
1340 ops.push(self.undo_or_redo(transaction).unwrap());
1341 }
1342 }
1343 ops
1344 }
1345
1346 fn selections_from_ranges<I>(&self, ranges: I) -> Result<Vec<Selection<usize>>>
1347 where
1348 I: IntoIterator<Item = Range<usize>>,
1349 {
1350 use std::sync::atomic::{self, AtomicUsize};
1351
1352 static NEXT_SELECTION_ID: AtomicUsize = AtomicUsize::new(0);
1353
1354 let mut ranges = ranges.into_iter().collect::<Vec<_>>();
1355 ranges.sort_unstable_by_key(|range| range.start);
1356
1357 let mut selections = Vec::<Selection<usize>>::with_capacity(ranges.len());
1358 for mut range in ranges {
1359 let mut reversed = false;
1360 if range.start > range.end {
1361 reversed = true;
1362 std::mem::swap(&mut range.start, &mut range.end);
1363 }
1364
1365 if let Some(selection) = selections.last_mut() {
1366 if selection.end >= range.start {
1367 selection.end = range.end;
1368 continue;
1369 }
1370 }
1371
1372 selections.push(Selection {
1373 id: NEXT_SELECTION_ID.fetch_add(1, atomic::Ordering::SeqCst),
1374 start: range.start,
1375 end: range.end,
1376 reversed,
1377 goal: SelectionGoal::None,
1378 });
1379 }
1380 Ok(selections)
1381 }
1382
1383 #[cfg(test)]
1384 pub fn selection_ranges<'a, D>(&'a self, set_id: SelectionSetId) -> Result<Vec<Range<D>>>
1385 where
1386 D: 'a + TextDimension<'a>,
1387 {
1388 Ok(self
1389 .selection_set(set_id)?
1390 .selections(self)
1391 .map(move |selection| {
1392 if selection.reversed {
1393 selection.end..selection.start
1394 } else {
1395 selection.start..selection.end
1396 }
1397 })
1398 .collect())
1399 }
1400
1401 #[cfg(test)]
1402 pub fn all_selection_ranges<'a, D>(
1403 &'a self,
1404 ) -> impl 'a + Iterator<Item = (SelectionSetId, Vec<Range<usize>>)>
1405 where
1406 D: 'a + TextDimension<'a>,
1407 {
1408 self.selections
1409 .keys()
1410 .map(move |set_id| (*set_id, self.selection_ranges(*set_id).unwrap()))
1411 }
1412}
1413
1414impl Deref for Buffer {
1415 type Target = Snapshot;
1416
1417 fn deref(&self) -> &Self::Target {
1418 &self.snapshot
1419 }
1420}
1421
1422impl Snapshot {
1423 pub fn as_rope(&self) -> &Rope {
1424 &self.visible_text
1425 }
1426
1427 pub fn row_count(&self) -> u32 {
1428 self.max_point().row + 1
1429 }
1430
1431 pub fn len(&self) -> usize {
1432 self.visible_text.len()
1433 }
1434
1435 pub fn chars(&self) -> impl Iterator<Item = char> + '_ {
1436 self.chars_at(0)
1437 }
1438
1439 pub fn chars_for_range<T: ToOffset>(&self, range: Range<T>) -> impl Iterator<Item = char> + '_ {
1440 self.text_for_range(range).flat_map(str::chars)
1441 }
1442
1443 pub fn contains_str_at<T>(&self, position: T, needle: &str) -> bool
1444 where
1445 T: ToOffset,
1446 {
1447 let position = position.to_offset(self);
1448 position == self.clip_offset(position, Bias::Left)
1449 && self
1450 .bytes_in_range(position..self.len())
1451 .flatten()
1452 .copied()
1453 .take(needle.len())
1454 .eq(needle.bytes())
1455 }
1456
1457 pub fn text(&self) -> String {
1458 self.text_for_range(0..self.len()).collect()
1459 }
1460
1461 pub fn text_summary(&self) -> TextSummary {
1462 self.visible_text.summary()
1463 }
1464
1465 pub fn max_point(&self) -> Point {
1466 self.visible_text.max_point()
1467 }
1468
1469 pub fn to_offset(&self, point: Point) -> usize {
1470 self.visible_text.point_to_offset(point)
1471 }
1472
1473 pub fn to_point(&self, offset: usize) -> Point {
1474 self.visible_text.offset_to_point(offset)
1475 }
1476
1477 pub fn version(&self) -> &clock::Global {
1478 &self.version
1479 }
1480
1481 pub fn chars_at<'a, T: ToOffset>(&'a self, position: T) -> impl Iterator<Item = char> + 'a {
1482 let offset = position.to_offset(self);
1483 self.visible_text.chars_at(offset)
1484 }
1485
1486 pub fn reversed_chars_at<'a, T: ToOffset>(
1487 &'a self,
1488 position: T,
1489 ) -> impl Iterator<Item = char> + 'a {
1490 let offset = position.to_offset(self);
1491 self.visible_text.reversed_chars_at(offset)
1492 }
1493
1494 pub fn bytes_in_range<'a, T: ToOffset>(&'a self, range: Range<T>) -> rope::Bytes<'a> {
1495 let start = range.start.to_offset(self);
1496 let end = range.end.to_offset(self);
1497 self.visible_text.bytes_in_range(start..end)
1498 }
1499
1500 pub fn text_for_range<'a, T: ToOffset>(&'a self, range: Range<T>) -> Chunks<'a> {
1501 let start = range.start.to_offset(self);
1502 let end = range.end.to_offset(self);
1503 self.visible_text.chunks_in_range(start..end)
1504 }
1505
1506 pub fn line_len(&self, row: u32) -> u32 {
1507 let row_start_offset = Point::new(row, 0).to_offset(self);
1508 let row_end_offset = if row >= self.max_point().row {
1509 self.len()
1510 } else {
1511 Point::new(row + 1, 0).to_offset(self) - 1
1512 };
1513 (row_end_offset - row_start_offset) as u32
1514 }
1515
1516 pub fn is_line_blank(&self, row: u32) -> bool {
1517 self.text_for_range(Point::new(row, 0)..Point::new(row, self.line_len(row)))
1518 .all(|chunk| chunk.matches(|c: char| !c.is_whitespace()).next().is_none())
1519 }
1520
1521 pub fn indent_column_for_line(&self, row: u32) -> u32 {
1522 let mut result = 0;
1523 for c in self.chars_at(Point::new(row, 0)) {
1524 if c == ' ' {
1525 result += 1;
1526 } else {
1527 break;
1528 }
1529 }
1530 result
1531 }
1532
1533 fn summary_for_anchor<'a, D>(&'a self, anchor: &Anchor) -> D
1534 where
1535 D: TextDimension<'a>,
1536 {
1537 let cx = Some(anchor.version.clone());
1538 let mut cursor = self.fragments.cursor::<(VersionedFullOffset, usize)>();
1539 cursor.seek(
1540 &VersionedFullOffset::Offset(anchor.full_offset),
1541 anchor.bias,
1542 &cx,
1543 );
1544 let overshoot = if cursor.item().map_or(false, |fragment| fragment.visible) {
1545 anchor.full_offset - cursor.start().0.full_offset()
1546 } else {
1547 0
1548 };
1549 self.text_summary_for_range(0..cursor.start().1 + overshoot)
1550 }
1551
1552 pub fn text_summary_for_range<'a, D, O: ToOffset>(&'a self, range: Range<O>) -> D
1553 where
1554 D: TextDimension<'a>,
1555 {
1556 self.visible_text
1557 .cursor(range.start.to_offset(self))
1558 .summary(range.end.to_offset(self))
1559 }
1560
1561 fn summaries_for_anchors<'a, D, I>(
1562 &'a self,
1563 version: clock::Global,
1564 bias: Bias,
1565 ranges: I,
1566 ) -> impl 'a + Iterator<Item = D>
1567 where
1568 D: 'a + TextDimension<'a>,
1569 I: 'a + IntoIterator<Item = &'a FullOffset>,
1570 {
1571 let cx = Some(version.clone());
1572 let mut summary = D::default();
1573 let mut rope_cursor = self.visible_text.cursor(0);
1574 let mut cursor = self.fragments.cursor::<(VersionedFullOffset, usize)>();
1575 ranges.into_iter().map(move |offset| {
1576 cursor.seek_forward(&VersionedFullOffset::Offset(*offset), bias, &cx);
1577 let overshoot = if cursor.item().map_or(false, |fragment| fragment.visible) {
1578 *offset - cursor.start().0.full_offset()
1579 } else {
1580 0
1581 };
1582 summary.add_assign(&rope_cursor.summary(cursor.start().1 + overshoot));
1583 summary.clone()
1584 })
1585 }
1586
1587 fn summaries_for_anchor_ranges<'a, D, I>(
1588 &'a self,
1589 version: clock::Global,
1590 start_bias: Bias,
1591 end_bias: Bias,
1592 ranges: I,
1593 ) -> impl 'a + Iterator<Item = Range<D>>
1594 where
1595 D: 'a + TextDimension<'a>,
1596 I: 'a + IntoIterator<Item = &'a Range<FullOffset>>,
1597 {
1598 let cx = Some(version);
1599 let mut summary = D::default();
1600 let mut rope_cursor = self.visible_text.cursor(0);
1601 let mut cursor = self.fragments.cursor::<(VersionedFullOffset, usize)>();
1602 ranges.into_iter().map(move |range| {
1603 cursor.seek_forward(&VersionedFullOffset::Offset(range.start), start_bias, &cx);
1604 let overshoot = if cursor.item().map_or(false, |fragment| fragment.visible) {
1605 range.start - cursor.start().0.full_offset()
1606 } else {
1607 0
1608 };
1609 summary.add_assign(&rope_cursor.summary::<D>(cursor.start().1 + overshoot));
1610 let start_summary = summary.clone();
1611
1612 cursor.seek_forward(&VersionedFullOffset::Offset(range.end), end_bias, &cx);
1613 let overshoot = if cursor.item().map_or(false, |fragment| fragment.visible) {
1614 range.end - cursor.start().0.full_offset()
1615 } else {
1616 0
1617 };
1618 summary.add_assign(&rope_cursor.summary::<D>(cursor.start().1 + overshoot));
1619 let end_summary = summary.clone();
1620
1621 start_summary..end_summary
1622 })
1623 }
1624
1625 pub fn anchor_before<T: ToOffset>(&self, position: T) -> Anchor {
1626 self.anchor_at(position, Bias::Left)
1627 }
1628
1629 pub fn anchor_after<T: ToOffset>(&self, position: T) -> Anchor {
1630 self.anchor_at(position, Bias::Right)
1631 }
1632
1633 pub fn anchor_at<T: ToOffset>(&self, position: T, bias: Bias) -> Anchor {
1634 Anchor {
1635 full_offset: position.to_full_offset(self, bias),
1636 bias,
1637 version: self.version.clone(),
1638 }
1639 }
1640
1641 pub fn anchor_map<T, E>(&self, bias: Bias, entries: E) -> AnchorMap<T>
1642 where
1643 E: IntoIterator<Item = (usize, T)>,
1644 {
1645 let version = self.version.clone();
1646 let mut cursor = self.fragments.cursor::<FragmentTextSummary>();
1647 let entries = entries
1648 .into_iter()
1649 .map(|(offset, value)| {
1650 cursor.seek_forward(&offset, bias, &None);
1651 let full_offset = FullOffset(cursor.start().deleted + offset);
1652 (full_offset, value)
1653 })
1654 .collect();
1655
1656 AnchorMap {
1657 version,
1658 bias,
1659 entries,
1660 }
1661 }
1662
1663 pub fn anchor_range_map<T, E>(
1664 &self,
1665 start_bias: Bias,
1666 end_bias: Bias,
1667 entries: E,
1668 ) -> AnchorRangeMap<T>
1669 where
1670 E: IntoIterator<Item = (Range<usize>, T)>,
1671 {
1672 let version = self.version.clone();
1673 let mut cursor = self.fragments.cursor::<FragmentTextSummary>();
1674 let entries = entries
1675 .into_iter()
1676 .map(|(range, value)| {
1677 let Range {
1678 start: start_offset,
1679 end: end_offset,
1680 } = range;
1681 cursor.seek_forward(&start_offset, start_bias, &None);
1682 let full_start_offset = FullOffset(cursor.start().deleted + start_offset);
1683 cursor.seek_forward(&end_offset, end_bias, &None);
1684 let full_end_offset = FullOffset(cursor.start().deleted + end_offset);
1685 (full_start_offset..full_end_offset, value)
1686 })
1687 .collect();
1688
1689 AnchorRangeMap {
1690 version,
1691 start_bias,
1692 end_bias,
1693 entries,
1694 }
1695 }
1696
1697 pub fn anchor_set<E>(&self, bias: Bias, entries: E) -> AnchorSet
1698 where
1699 E: IntoIterator<Item = usize>,
1700 {
1701 AnchorSet(self.anchor_map(bias, entries.into_iter().map(|range| (range, ()))))
1702 }
1703
1704 pub fn anchor_range_set<E>(
1705 &self,
1706 start_bias: Bias,
1707 end_bias: Bias,
1708 entries: E,
1709 ) -> AnchorRangeSet
1710 where
1711 E: IntoIterator<Item = Range<usize>>,
1712 {
1713 AnchorRangeSet(self.anchor_range_map(
1714 start_bias,
1715 end_bias,
1716 entries.into_iter().map(|range| (range, ())),
1717 ))
1718 }
1719
1720 pub fn anchor_range_multimap<T, E, O>(
1721 &self,
1722 start_bias: Bias,
1723 end_bias: Bias,
1724 entries: E,
1725 ) -> AnchorRangeMultimap<T>
1726 where
1727 T: Clone,
1728 E: IntoIterator<Item = (Range<O>, T)>,
1729 O: ToOffset,
1730 {
1731 let mut entries = entries
1732 .into_iter()
1733 .map(|(range, value)| AnchorRangeMultimapEntry {
1734 range: FullOffsetRange {
1735 start: range.start.to_full_offset(self, start_bias),
1736 end: range.end.to_full_offset(self, end_bias),
1737 },
1738 value,
1739 })
1740 .collect::<Vec<_>>();
1741 entries.sort_unstable_by_key(|i| (i.range.start, Reverse(i.range.end)));
1742 AnchorRangeMultimap {
1743 entries: SumTree::from_iter(entries, &()),
1744 version: self.version.clone(),
1745 start_bias,
1746 end_bias,
1747 }
1748 }
1749
1750 fn full_offset_for_anchor(&self, anchor: &Anchor) -> FullOffset {
1751 let cx = Some(anchor.version.clone());
1752 let mut cursor = self
1753 .fragments
1754 .cursor::<(VersionedFullOffset, FragmentTextSummary)>();
1755 cursor.seek(
1756 &VersionedFullOffset::Offset(anchor.full_offset),
1757 anchor.bias,
1758 &cx,
1759 );
1760 let overshoot = if cursor.item().is_some() {
1761 anchor.full_offset - cursor.start().0.full_offset()
1762 } else {
1763 0
1764 };
1765 let summary = cursor.start().1;
1766 FullOffset(summary.visible + summary.deleted + overshoot)
1767 }
1768
1769 pub fn clip_offset(&self, offset: usize, bias: Bias) -> usize {
1770 self.visible_text.clip_offset(offset, bias)
1771 }
1772
1773 pub fn clip_point(&self, point: Point, bias: Bias) -> Point {
1774 self.visible_text.clip_point(point, bias)
1775 }
1776
1777 pub fn clip_point_utf16(&self, point: PointUtf16, bias: Bias) -> PointUtf16 {
1778 self.visible_text.clip_point_utf16(point, bias)
1779 }
1780
1781 pub fn point_for_offset(&self, offset: usize) -> Result<Point> {
1782 if offset <= self.len() {
1783 Ok(self.text_summary_for_range(0..offset))
1784 } else {
1785 Err(anyhow!("offset out of bounds"))
1786 }
1787 }
1788
1789 pub fn edits_since<'a, D>(
1790 &'a self,
1791 since: &'a clock::Global,
1792 ) -> impl 'a + Iterator<Item = Edit<D>>
1793 where
1794 D: 'a + TextDimension<'a> + Ord,
1795 {
1796 let fragments_cursor = if *since == self.version {
1797 None
1798 } else {
1799 Some(
1800 self.fragments
1801 .filter(move |summary| !since.ge(&summary.max_version), &None),
1802 )
1803 };
1804
1805 Edits {
1806 visible_cursor: self.visible_text.cursor(0),
1807 deleted_cursor: self.deleted_text.cursor(0),
1808 fragments_cursor,
1809 undos: &self.undo_map,
1810 since,
1811 old_end: Default::default(),
1812 new_end: Default::default(),
1813 }
1814 }
1815}
1816
1817struct RopeBuilder<'a> {
1818 old_visible_cursor: rope::Cursor<'a>,
1819 old_deleted_cursor: rope::Cursor<'a>,
1820 new_visible: Rope,
1821 new_deleted: Rope,
1822}
1823
1824impl<'a> RopeBuilder<'a> {
1825 fn new(old_visible_cursor: rope::Cursor<'a>, old_deleted_cursor: rope::Cursor<'a>) -> Self {
1826 Self {
1827 old_visible_cursor,
1828 old_deleted_cursor,
1829 new_visible: Rope::new(),
1830 new_deleted: Rope::new(),
1831 }
1832 }
1833
1834 fn push_tree(&mut self, len: FragmentTextSummary) {
1835 self.push(len.visible, true, true);
1836 self.push(len.deleted, false, false);
1837 }
1838
1839 fn push_fragment(&mut self, fragment: &Fragment, was_visible: bool) {
1840 debug_assert!(fragment.len > 0);
1841 self.push(fragment.len, was_visible, fragment.visible)
1842 }
1843
1844 fn push(&mut self, len: usize, was_visible: bool, is_visible: bool) {
1845 let text = if was_visible {
1846 self.old_visible_cursor
1847 .slice(self.old_visible_cursor.offset() + len)
1848 } else {
1849 self.old_deleted_cursor
1850 .slice(self.old_deleted_cursor.offset() + len)
1851 };
1852 if is_visible {
1853 self.new_visible.append(text);
1854 } else {
1855 self.new_deleted.append(text);
1856 }
1857 }
1858
1859 fn push_str(&mut self, text: &str) {
1860 self.new_visible.push(text);
1861 }
1862
1863 fn finish(mut self) -> (Rope, Rope) {
1864 self.new_visible.append(self.old_visible_cursor.suffix());
1865 self.new_deleted.append(self.old_deleted_cursor.suffix());
1866 (self.new_visible, self.new_deleted)
1867 }
1868}
1869
1870impl<'a, D: TextDimension<'a> + Ord, F: FnMut(&FragmentSummary) -> bool> Iterator
1871 for Edits<'a, D, F>
1872{
1873 type Item = Edit<D>;
1874
1875 fn next(&mut self) -> Option<Self::Item> {
1876 let mut pending_edit: Option<Edit<D>> = None;
1877 let cursor = self.fragments_cursor.as_mut()?;
1878
1879 while let Some(fragment) = cursor.item() {
1880 let summary = self.visible_cursor.summary(cursor.start().visible);
1881 self.old_end.add_assign(&summary);
1882 self.new_end.add_assign(&summary);
1883 if pending_edit
1884 .as_ref()
1885 .map_or(false, |change| change.new.end < self.new_end)
1886 {
1887 break;
1888 }
1889
1890 if !fragment.was_visible(&self.since, &self.undos) && fragment.visible {
1891 let fragment_summary = self.visible_cursor.summary(cursor.end(&None).visible);
1892 let mut new_end = self.new_end.clone();
1893 new_end.add_assign(&fragment_summary);
1894 if let Some(pending_edit) = pending_edit.as_mut() {
1895 pending_edit.new.end = new_end.clone();
1896 } else {
1897 pending_edit = Some(Edit {
1898 old: self.old_end.clone()..self.old_end.clone(),
1899 new: self.new_end.clone()..new_end.clone(),
1900 });
1901 }
1902
1903 self.new_end = new_end;
1904 } else if fragment.was_visible(&self.since, &self.undos) && !fragment.visible {
1905 self.deleted_cursor.seek_forward(cursor.start().deleted);
1906 let fragment_summary = self.deleted_cursor.summary(cursor.end(&None).deleted);
1907 let mut old_end = self.old_end.clone();
1908 old_end.add_assign(&fragment_summary);
1909 if let Some(pending_edit) = pending_edit.as_mut() {
1910 pending_edit.old.end = old_end.clone();
1911 } else {
1912 pending_edit = Some(Edit {
1913 old: self.old_end.clone()..old_end.clone(),
1914 new: self.new_end.clone()..self.new_end.clone(),
1915 });
1916 }
1917
1918 self.old_end = old_end;
1919 }
1920
1921 cursor.next(&None);
1922 }
1923
1924 pending_edit
1925 }
1926}
1927
1928impl Fragment {
1929 fn is_visible(&self, undos: &UndoMap) -> bool {
1930 !undos.is_undone(self.timestamp.local())
1931 && self.deletions.iter().all(|d| undos.is_undone(*d))
1932 }
1933
1934 fn was_visible(&self, version: &clock::Global, undos: &UndoMap) -> bool {
1935 (version.observed(self.timestamp.local())
1936 && !undos.was_undone(self.timestamp.local(), version))
1937 && self
1938 .deletions
1939 .iter()
1940 .all(|d| !version.observed(*d) || undos.was_undone(*d, version))
1941 }
1942}
1943
1944impl sum_tree::Item for Fragment {
1945 type Summary = FragmentSummary;
1946
1947 fn summary(&self) -> Self::Summary {
1948 let mut max_version = clock::Global::new();
1949 max_version.observe(self.timestamp.local());
1950 for deletion in &self.deletions {
1951 max_version.observe(*deletion);
1952 }
1953 max_version.join(&self.max_undos);
1954
1955 let mut min_insertion_version = clock::Global::new();
1956 min_insertion_version.observe(self.timestamp.local());
1957 let max_insertion_version = min_insertion_version.clone();
1958 if self.visible {
1959 FragmentSummary {
1960 text: FragmentTextSummary {
1961 visible: self.len,
1962 deleted: 0,
1963 },
1964 max_version,
1965 min_insertion_version,
1966 max_insertion_version,
1967 }
1968 } else {
1969 FragmentSummary {
1970 text: FragmentTextSummary {
1971 visible: 0,
1972 deleted: self.len,
1973 },
1974 max_version,
1975 min_insertion_version,
1976 max_insertion_version,
1977 }
1978 }
1979 }
1980}
1981
1982impl sum_tree::Summary for FragmentSummary {
1983 type Context = Option<clock::Global>;
1984
1985 fn add_summary(&mut self, other: &Self, _: &Self::Context) {
1986 self.text.visible += &other.text.visible;
1987 self.text.deleted += &other.text.deleted;
1988 self.max_version.join(&other.max_version);
1989 self.min_insertion_version
1990 .meet(&other.min_insertion_version);
1991 self.max_insertion_version
1992 .join(&other.max_insertion_version);
1993 }
1994}
1995
1996impl Default for FragmentSummary {
1997 fn default() -> Self {
1998 FragmentSummary {
1999 text: FragmentTextSummary::default(),
2000 max_version: clock::Global::new(),
2001 min_insertion_version: clock::Global::new(),
2002 max_insertion_version: clock::Global::new(),
2003 }
2004 }
2005}
2006
2007#[derive(Copy, Clone, Debug, Default, PartialEq, Eq, PartialOrd, Ord, Hash)]
2008pub struct FullOffset(pub usize);
2009
2010impl FullOffset {
2011 const MAX: Self = FullOffset(usize::MAX);
2012}
2013
2014impl ops::AddAssign<usize> for FullOffset {
2015 fn add_assign(&mut self, rhs: usize) {
2016 self.0 += rhs;
2017 }
2018}
2019
2020impl ops::Add<usize> for FullOffset {
2021 type Output = Self;
2022
2023 fn add(mut self, rhs: usize) -> Self::Output {
2024 self += rhs;
2025 self
2026 }
2027}
2028
2029impl ops::Sub for FullOffset {
2030 type Output = usize;
2031
2032 fn sub(self, rhs: Self) -> Self::Output {
2033 self.0 - rhs.0
2034 }
2035}
2036
2037impl<'a> sum_tree::Dimension<'a, FragmentSummary> for usize {
2038 fn add_summary(&mut self, summary: &FragmentSummary, _: &Option<clock::Global>) {
2039 *self += summary.text.visible;
2040 }
2041}
2042
2043impl<'a> sum_tree::Dimension<'a, FragmentSummary> for FullOffset {
2044 fn add_summary(&mut self, summary: &FragmentSummary, _: &Option<clock::Global>) {
2045 self.0 += summary.text.visible + summary.text.deleted;
2046 }
2047}
2048
2049impl<'a> sum_tree::SeekTarget<'a, FragmentSummary, FragmentTextSummary> for usize {
2050 fn cmp(
2051 &self,
2052 cursor_location: &FragmentTextSummary,
2053 _: &Option<clock::Global>,
2054 ) -> cmp::Ordering {
2055 Ord::cmp(self, &cursor_location.visible)
2056 }
2057}
2058
2059#[derive(Copy, Clone, Debug, Eq, PartialEq)]
2060enum VersionedFullOffset {
2061 Offset(FullOffset),
2062 Invalid,
2063}
2064
2065impl VersionedFullOffset {
2066 fn full_offset(&self) -> FullOffset {
2067 if let Self::Offset(position) = self {
2068 *position
2069 } else {
2070 panic!("invalid version")
2071 }
2072 }
2073}
2074
2075impl Default for VersionedFullOffset {
2076 fn default() -> Self {
2077 Self::Offset(Default::default())
2078 }
2079}
2080
2081impl<'a> sum_tree::Dimension<'a, FragmentSummary> for VersionedFullOffset {
2082 fn add_summary(&mut self, summary: &'a FragmentSummary, cx: &Option<clock::Global>) {
2083 if let Self::Offset(offset) = self {
2084 let version = cx.as_ref().unwrap();
2085 if version.ge(&summary.max_insertion_version) {
2086 *offset += summary.text.visible + summary.text.deleted;
2087 } else if version.observed_any(&summary.min_insertion_version) {
2088 *self = Self::Invalid;
2089 }
2090 }
2091 }
2092}
2093
2094impl<'a> sum_tree::SeekTarget<'a, FragmentSummary, Self> for VersionedFullOffset {
2095 fn cmp(&self, cursor_position: &Self, _: &Option<clock::Global>) -> cmp::Ordering {
2096 match (self, cursor_position) {
2097 (Self::Offset(a), Self::Offset(b)) => Ord::cmp(a, b),
2098 (Self::Offset(_), Self::Invalid) => cmp::Ordering::Less,
2099 (Self::Invalid, _) => unreachable!(),
2100 }
2101 }
2102}
2103
2104impl Operation {
2105 fn replica_id(&self) -> ReplicaId {
2106 self.lamport_timestamp().replica_id
2107 }
2108
2109 fn lamport_timestamp(&self) -> clock::Lamport {
2110 match self {
2111 Operation::Edit(edit) => edit.timestamp.lamport(),
2112 Operation::Undo {
2113 lamport_timestamp, ..
2114 } => *lamport_timestamp,
2115 Operation::UpdateSelections {
2116 lamport_timestamp, ..
2117 } => *lamport_timestamp,
2118 Operation::RemoveSelections {
2119 lamport_timestamp, ..
2120 } => *lamport_timestamp,
2121 Operation::SetActiveSelections {
2122 lamport_timestamp, ..
2123 } => *lamport_timestamp,
2124 #[cfg(test)]
2125 Operation::Test(lamport_timestamp) => *lamport_timestamp,
2126 }
2127 }
2128
2129 pub fn is_edit(&self) -> bool {
2130 match self {
2131 Operation::Edit { .. } => true,
2132 _ => false,
2133 }
2134 }
2135}
2136
2137pub trait ToOffset {
2138 fn to_offset<'a>(&self, content: &Snapshot) -> usize;
2139
2140 fn to_full_offset<'a>(&self, content: &Snapshot, bias: Bias) -> FullOffset {
2141 let offset = self.to_offset(&content);
2142 let mut cursor = content.fragments.cursor::<FragmentTextSummary>();
2143 cursor.seek(&offset, bias, &None);
2144 FullOffset(offset + cursor.start().deleted)
2145 }
2146}
2147
2148impl ToOffset for Point {
2149 fn to_offset<'a>(&self, content: &Snapshot) -> usize {
2150 content.visible_text.point_to_offset(*self)
2151 }
2152}
2153
2154impl ToOffset for PointUtf16 {
2155 fn to_offset<'a>(&self, content: &Snapshot) -> usize {
2156 content.visible_text.point_utf16_to_offset(*self)
2157 }
2158}
2159
2160impl ToOffset for usize {
2161 fn to_offset<'a>(&self, content: &Snapshot) -> usize {
2162 assert!(*self <= content.len(), "offset is out of range");
2163 *self
2164 }
2165}
2166
2167impl ToOffset for Anchor {
2168 fn to_offset<'a>(&self, content: &Snapshot) -> usize {
2169 content.summary_for_anchor(self)
2170 }
2171}
2172
2173impl<'a> ToOffset for &'a Anchor {
2174 fn to_offset(&self, content: &Snapshot) -> usize {
2175 content.summary_for_anchor(self)
2176 }
2177}
2178
2179pub trait ToPoint {
2180 fn to_point<'a>(&self, content: &Snapshot) -> Point;
2181}
2182
2183impl ToPoint for Anchor {
2184 fn to_point<'a>(&self, content: &Snapshot) -> Point {
2185 content.summary_for_anchor(self)
2186 }
2187}
2188
2189impl ToPoint for usize {
2190 fn to_point<'a>(&self, content: &Snapshot) -> Point {
2191 content.visible_text.offset_to_point(*self)
2192 }
2193}
2194
2195impl ToPoint for Point {
2196 fn to_point<'a>(&self, _: &Snapshot) -> Point {
2197 *self
2198 }
2199}
2200
2201pub trait FromAnchor {
2202 fn from_anchor(anchor: &Anchor, content: &Snapshot) -> Self;
2203}
2204
2205impl FromAnchor for Point {
2206 fn from_anchor(anchor: &Anchor, content: &Snapshot) -> Self {
2207 anchor.to_point(content)
2208 }
2209}
2210
2211impl FromAnchor for usize {
2212 fn from_anchor(anchor: &Anchor, content: &Snapshot) -> Self {
2213 anchor.to_offset(content)
2214 }
2215}