1mod anchor;
2pub mod locator;
3#[cfg(any(test, feature = "test-support"))]
4pub mod network;
5pub mod operation_queue;
6mod patch;
7mod selection;
8pub mod subscription;
9#[cfg(test)]
10mod tests;
11mod undo_map;
12
13pub use anchor::*;
14use anyhow::{Context as _, Result};
15use clock::LOCAL_BRANCH_REPLICA_ID;
16pub use clock::ReplicaId;
17use collections::{HashMap, HashSet};
18use locator::Locator;
19use operation_queue::OperationQueue;
20pub use patch::Patch;
21use postage::{oneshot, prelude::*};
22
23use regex::Regex;
24pub use rope::*;
25pub use selection::*;
26use std::{
27 borrow::Cow,
28 cmp::{self, Ordering, Reverse},
29 fmt::Display,
30 future::Future,
31 iter::Iterator,
32 num::NonZeroU64,
33 ops::{self, Deref, Range, Sub},
34 str,
35 sync::{Arc, LazyLock},
36 time::{Duration, Instant},
37};
38pub use subscription::*;
39pub use sum_tree::Bias;
40use sum_tree::{FilterCursor, SumTree, TreeMap, TreeSet};
41use undo_map::UndoMap;
42
43#[cfg(any(test, feature = "test-support"))]
44use util::RandomCharIter;
45
46static LINE_SEPARATORS_REGEX: LazyLock<Regex> =
47 LazyLock::new(|| Regex::new(r"\r\n|\r").expect("Failed to create LINE_SEPARATORS_REGEX"));
48
49pub type TransactionId = clock::Lamport;
50
51pub struct Buffer {
52 snapshot: BufferSnapshot,
53 history: History,
54 deferred_ops: OperationQueue<Operation>,
55 deferred_replicas: HashSet<ReplicaId>,
56 pub lamport_clock: clock::Lamport,
57 subscriptions: Topic,
58 edit_id_resolvers: HashMap<clock::Lamport, Vec<oneshot::Sender<()>>>,
59 wait_for_version_txs: Vec<(clock::Global, oneshot::Sender<()>)>,
60}
61
62#[repr(transparent)]
63#[derive(Clone, Copy, Debug, Hash, PartialEq, PartialOrd, Ord, Eq)]
64pub struct BufferId(NonZeroU64);
65
66impl Display for BufferId {
67 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
68 write!(f, "{}", self.0)
69 }
70}
71
72impl From<NonZeroU64> for BufferId {
73 fn from(id: NonZeroU64) -> Self {
74 BufferId(id)
75 }
76}
77
78impl BufferId {
79 /// Returns Err if `id` is outside of BufferId domain.
80 pub fn new(id: u64) -> anyhow::Result<Self> {
81 let id = NonZeroU64::new(id).context("Buffer id cannot be 0.")?;
82 Ok(Self(id))
83 }
84
85 /// Increments this buffer id, returning the old value.
86 /// So that's a post-increment operator in disguise.
87 pub fn next(&mut self) -> Self {
88 let old = *self;
89 self.0 = self.0.saturating_add(1);
90 old
91 }
92
93 pub fn to_proto(self) -> u64 {
94 self.into()
95 }
96}
97
98impl From<BufferId> for u64 {
99 fn from(id: BufferId) -> Self {
100 id.0.get()
101 }
102}
103
104#[derive(Clone)]
105pub struct BufferSnapshot {
106 replica_id: ReplicaId,
107 remote_id: BufferId,
108 visible_text: Rope,
109 deleted_text: Rope,
110 line_ending: LineEnding,
111 undo_map: UndoMap,
112 fragments: SumTree<Fragment>,
113 insertions: SumTree<InsertionFragment>,
114 insertion_slices: TreeSet<InsertionSlice>,
115 pub version: clock::Global,
116}
117
118#[derive(Clone, Debug)]
119pub struct HistoryEntry {
120 transaction: Transaction,
121 first_edit_at: Instant,
122 last_edit_at: Instant,
123 suppress_grouping: bool,
124}
125
126#[derive(Clone, Debug)]
127pub struct Transaction {
128 pub id: TransactionId,
129 pub edit_ids: Vec<clock::Lamport>,
130 pub start: clock::Global,
131}
132
133impl Transaction {
134 pub fn merge_in(&mut self, other: Transaction) {
135 self.edit_ids.extend(other.edit_ids);
136 }
137}
138
139impl HistoryEntry {
140 pub fn transaction_id(&self) -> TransactionId {
141 self.transaction.id
142 }
143}
144
145struct History {
146 base_text: Rope,
147 operations: TreeMap<clock::Lamport, Operation>,
148 undo_stack: Vec<HistoryEntry>,
149 redo_stack: Vec<HistoryEntry>,
150 transaction_depth: usize,
151 group_interval: Duration,
152}
153
154#[derive(Clone, Debug, Eq, PartialEq)]
155struct InsertionSlice {
156 edit_id: clock::Lamport,
157 insertion_id: clock::Lamport,
158 range: Range<usize>,
159}
160
161impl Ord for InsertionSlice {
162 fn cmp(&self, other: &Self) -> Ordering {
163 self.edit_id
164 .cmp(&other.edit_id)
165 .then_with(|| self.insertion_id.cmp(&other.insertion_id))
166 .then_with(|| self.range.start.cmp(&other.range.start))
167 .then_with(|| self.range.end.cmp(&other.range.end))
168 }
169}
170
171impl PartialOrd for InsertionSlice {
172 fn partial_cmp(&self, other: &Self) -> Option<Ordering> {
173 Some(self.cmp(other))
174 }
175}
176
177impl InsertionSlice {
178 fn from_fragment(edit_id: clock::Lamport, fragment: &Fragment) -> Self {
179 Self {
180 edit_id,
181 insertion_id: fragment.timestamp,
182 range: fragment.insertion_offset..fragment.insertion_offset + fragment.len,
183 }
184 }
185}
186
187impl History {
188 pub fn new(base_text: Rope) -> Self {
189 Self {
190 base_text,
191 operations: Default::default(),
192 undo_stack: Vec::new(),
193 redo_stack: Vec::new(),
194 transaction_depth: 0,
195 // Don't group transactions in tests unless we opt in, because it's a footgun.
196 #[cfg(any(test, feature = "test-support"))]
197 group_interval: Duration::ZERO,
198 #[cfg(not(any(test, feature = "test-support")))]
199 group_interval: Duration::from_millis(300),
200 }
201 }
202
203 fn push(&mut self, op: Operation) {
204 self.operations.insert(op.timestamp(), op);
205 }
206
207 fn start_transaction(
208 &mut self,
209 start: clock::Global,
210 now: Instant,
211 clock: &mut clock::Lamport,
212 ) -> Option<TransactionId> {
213 self.transaction_depth += 1;
214 if self.transaction_depth == 1 {
215 let id = clock.tick();
216 self.undo_stack.push(HistoryEntry {
217 transaction: Transaction {
218 id,
219 start,
220 edit_ids: Default::default(),
221 },
222 first_edit_at: now,
223 last_edit_at: now,
224 suppress_grouping: false,
225 });
226 Some(id)
227 } else {
228 None
229 }
230 }
231
232 fn end_transaction(&mut self, now: Instant) -> Option<&HistoryEntry> {
233 assert_ne!(self.transaction_depth, 0);
234 self.transaction_depth -= 1;
235 if self.transaction_depth == 0 {
236 if self
237 .undo_stack
238 .last()
239 .unwrap()
240 .transaction
241 .edit_ids
242 .is_empty()
243 {
244 self.undo_stack.pop();
245 None
246 } else {
247 self.redo_stack.clear();
248 let entry = self.undo_stack.last_mut().unwrap();
249 entry.last_edit_at = now;
250 Some(entry)
251 }
252 } else {
253 None
254 }
255 }
256
257 fn group(&mut self) -> Option<TransactionId> {
258 let mut count = 0;
259 let mut entries = self.undo_stack.iter();
260 if let Some(mut entry) = entries.next_back() {
261 while let Some(prev_entry) = entries.next_back() {
262 if !prev_entry.suppress_grouping
263 && entry.first_edit_at - prev_entry.last_edit_at < self.group_interval
264 {
265 entry = prev_entry;
266 count += 1;
267 } else {
268 break;
269 }
270 }
271 }
272 self.group_trailing(count)
273 }
274
275 fn group_until(&mut self, transaction_id: TransactionId) {
276 let mut count = 0;
277 for entry in self.undo_stack.iter().rev() {
278 if entry.transaction_id() == transaction_id {
279 self.group_trailing(count);
280 break;
281 } else if entry.suppress_grouping {
282 break;
283 } else {
284 count += 1;
285 }
286 }
287 }
288
289 fn group_trailing(&mut self, n: usize) -> Option<TransactionId> {
290 let new_len = self.undo_stack.len() - n;
291 let (entries_to_keep, entries_to_merge) = self.undo_stack.split_at_mut(new_len);
292 if let Some(last_entry) = entries_to_keep.last_mut() {
293 for entry in &*entries_to_merge {
294 for edit_id in &entry.transaction.edit_ids {
295 last_entry.transaction.edit_ids.push(*edit_id);
296 }
297 }
298
299 if let Some(entry) = entries_to_merge.last_mut() {
300 last_entry.last_edit_at = entry.last_edit_at;
301 }
302 }
303
304 self.undo_stack.truncate(new_len);
305 self.undo_stack.last().map(|e| e.transaction.id)
306 }
307
308 fn finalize_last_transaction(&mut self) -> Option<&Transaction> {
309 self.undo_stack.last_mut().map(|entry| {
310 entry.suppress_grouping = true;
311 &entry.transaction
312 })
313 }
314
315 fn push_transaction(&mut self, transaction: Transaction, now: Instant) {
316 assert_eq!(self.transaction_depth, 0);
317 self.undo_stack.push(HistoryEntry {
318 transaction,
319 first_edit_at: now,
320 last_edit_at: now,
321 suppress_grouping: false,
322 });
323 }
324
325 /// Differs from `push_transaction` in that it does not clear the redo
326 /// stack. Intended to be used to create a parent transaction to merge
327 /// potential child transactions into.
328 ///
329 /// The caller is responsible for removing it from the undo history using
330 /// `forget_transaction` if no edits are merged into it. Otherwise, if edits
331 /// are merged into this transaction, the caller is responsible for ensuring
332 /// the redo stack is cleared. The easiest way to ensure the redo stack is
333 /// cleared is to create transactions with the usual `start_transaction` and
334 /// `end_transaction` methods and merging the resulting transactions into
335 /// the transaction created by this method
336 fn push_empty_transaction(
337 &mut self,
338 start: clock::Global,
339 now: Instant,
340 clock: &mut clock::Lamport,
341 ) -> TransactionId {
342 assert_eq!(self.transaction_depth, 0);
343 let id = clock.tick();
344 let transaction = Transaction {
345 id,
346 start,
347 edit_ids: Vec::new(),
348 };
349 self.undo_stack.push(HistoryEntry {
350 transaction,
351 first_edit_at: now,
352 last_edit_at: now,
353 suppress_grouping: false,
354 });
355 id
356 }
357
358 fn push_undo(&mut self, op_id: clock::Lamport) {
359 assert_ne!(self.transaction_depth, 0);
360 if let Some(Operation::Edit(_)) = self.operations.get(&op_id) {
361 let last_transaction = self.undo_stack.last_mut().unwrap();
362 last_transaction.transaction.edit_ids.push(op_id);
363 }
364 }
365
366 fn pop_undo(&mut self) -> Option<&HistoryEntry> {
367 assert_eq!(self.transaction_depth, 0);
368 if let Some(entry) = self.undo_stack.pop() {
369 self.redo_stack.push(entry);
370 self.redo_stack.last()
371 } else {
372 None
373 }
374 }
375
376 fn remove_from_undo(&mut self, transaction_id: TransactionId) -> Option<&HistoryEntry> {
377 assert_eq!(self.transaction_depth, 0);
378
379 let entry_ix = self
380 .undo_stack
381 .iter()
382 .rposition(|entry| entry.transaction.id == transaction_id)?;
383 let entry = self.undo_stack.remove(entry_ix);
384 self.redo_stack.push(entry);
385 self.redo_stack.last()
386 }
387
388 fn remove_from_undo_until(&mut self, transaction_id: TransactionId) -> &[HistoryEntry] {
389 assert_eq!(self.transaction_depth, 0);
390
391 let redo_stack_start_len = self.redo_stack.len();
392 if let Some(entry_ix) = self
393 .undo_stack
394 .iter()
395 .rposition(|entry| entry.transaction.id == transaction_id)
396 {
397 self.redo_stack
398 .extend(self.undo_stack.drain(entry_ix..).rev());
399 }
400 &self.redo_stack[redo_stack_start_len..]
401 }
402
403 fn forget(&mut self, transaction_id: TransactionId) -> Option<Transaction> {
404 assert_eq!(self.transaction_depth, 0);
405 if let Some(entry_ix) = self
406 .undo_stack
407 .iter()
408 .rposition(|entry| entry.transaction.id == transaction_id)
409 {
410 Some(self.undo_stack.remove(entry_ix).transaction)
411 } else if let Some(entry_ix) = self
412 .redo_stack
413 .iter()
414 .rposition(|entry| entry.transaction.id == transaction_id)
415 {
416 Some(self.redo_stack.remove(entry_ix).transaction)
417 } else {
418 None
419 }
420 }
421
422 fn transaction(&self, transaction_id: TransactionId) -> Option<&Transaction> {
423 let entry = self
424 .undo_stack
425 .iter()
426 .rfind(|entry| entry.transaction.id == transaction_id)
427 .or_else(|| {
428 self.redo_stack
429 .iter()
430 .rfind(|entry| entry.transaction.id == transaction_id)
431 })?;
432 Some(&entry.transaction)
433 }
434
435 fn transaction_mut(&mut self, transaction_id: TransactionId) -> Option<&mut Transaction> {
436 let entry = self
437 .undo_stack
438 .iter_mut()
439 .rfind(|entry| entry.transaction.id == transaction_id)
440 .or_else(|| {
441 self.redo_stack
442 .iter_mut()
443 .rfind(|entry| entry.transaction.id == transaction_id)
444 })?;
445 Some(&mut entry.transaction)
446 }
447
448 fn merge_transactions(&mut self, transaction: TransactionId, destination: TransactionId) {
449 if let Some(transaction) = self.forget(transaction) {
450 if let Some(destination) = self.transaction_mut(destination) {
451 destination.edit_ids.extend(transaction.edit_ids);
452 }
453 }
454 }
455
456 fn pop_redo(&mut self) -> Option<&HistoryEntry> {
457 assert_eq!(self.transaction_depth, 0);
458 if let Some(entry) = self.redo_stack.pop() {
459 self.undo_stack.push(entry);
460 self.undo_stack.last()
461 } else {
462 None
463 }
464 }
465
466 fn remove_from_redo(&mut self, transaction_id: TransactionId) -> &[HistoryEntry] {
467 assert_eq!(self.transaction_depth, 0);
468
469 let undo_stack_start_len = self.undo_stack.len();
470 if let Some(entry_ix) = self
471 .redo_stack
472 .iter()
473 .rposition(|entry| entry.transaction.id == transaction_id)
474 {
475 self.undo_stack
476 .extend(self.redo_stack.drain(entry_ix..).rev());
477 }
478 &self.undo_stack[undo_stack_start_len..]
479 }
480}
481
482struct Edits<'a, D: TextDimension, F: FnMut(&FragmentSummary) -> bool> {
483 visible_cursor: rope::Cursor<'a>,
484 deleted_cursor: rope::Cursor<'a>,
485 fragments_cursor: Option<FilterCursor<'a, F, Fragment, FragmentTextSummary>>,
486 undos: &'a UndoMap,
487 since: &'a clock::Global,
488 old_end: D,
489 new_end: D,
490 range: Range<(&'a Locator, usize)>,
491 buffer_id: BufferId,
492}
493
494#[derive(Clone, Debug, Default, Eq, PartialEq)]
495pub struct Edit<D> {
496 pub old: Range<D>,
497 pub new: Range<D>,
498}
499
500impl<D> Edit<D>
501where
502 D: Sub<D, Output = D> + PartialEq + Copy,
503{
504 pub fn old_len(&self) -> D {
505 self.old.end - self.old.start
506 }
507
508 pub fn new_len(&self) -> D {
509 self.new.end - self.new.start
510 }
511
512 pub fn is_empty(&self) -> bool {
513 self.old.start == self.old.end && self.new.start == self.new.end
514 }
515}
516
517impl<D1, D2> Edit<(D1, D2)> {
518 pub fn flatten(self) -> (Edit<D1>, Edit<D2>) {
519 (
520 Edit {
521 old: self.old.start.0..self.old.end.0,
522 new: self.new.start.0..self.new.end.0,
523 },
524 Edit {
525 old: self.old.start.1..self.old.end.1,
526 new: self.new.start.1..self.new.end.1,
527 },
528 )
529 }
530}
531
532#[derive(Eq, PartialEq, Clone, Debug)]
533pub struct Fragment {
534 pub id: Locator,
535 pub timestamp: clock::Lamport,
536 pub insertion_offset: usize,
537 pub len: usize,
538 pub visible: bool,
539 pub deletions: HashSet<clock::Lamport>,
540 pub max_undos: clock::Global,
541}
542
543#[derive(Eq, PartialEq, Clone, Debug)]
544pub struct FragmentSummary {
545 text: FragmentTextSummary,
546 max_id: Locator,
547 max_version: clock::Global,
548 min_insertion_version: clock::Global,
549 max_insertion_version: clock::Global,
550}
551
552#[derive(Copy, Default, Clone, Debug, PartialEq, Eq)]
553struct FragmentTextSummary {
554 visible: usize,
555 deleted: usize,
556}
557
558impl<'a> sum_tree::Dimension<'a, FragmentSummary> for FragmentTextSummary {
559 fn zero(_: &Option<clock::Global>) -> Self {
560 Default::default()
561 }
562
563 fn add_summary(&mut self, summary: &'a FragmentSummary, _: &Option<clock::Global>) {
564 self.visible += summary.text.visible;
565 self.deleted += summary.text.deleted;
566 }
567}
568
569#[derive(Eq, PartialEq, Clone, Debug)]
570struct InsertionFragment {
571 timestamp: clock::Lamport,
572 split_offset: usize,
573 fragment_id: Locator,
574}
575
576#[derive(Clone, Copy, Debug, Default, PartialEq, Eq, PartialOrd, Ord)]
577struct InsertionFragmentKey {
578 timestamp: clock::Lamport,
579 split_offset: usize,
580}
581
582#[derive(Clone, Debug, Eq, PartialEq)]
583pub enum Operation {
584 Edit(EditOperation),
585 Undo(UndoOperation),
586}
587
588#[derive(Clone, Debug, Eq, PartialEq)]
589pub struct EditOperation {
590 pub timestamp: clock::Lamport,
591 pub version: clock::Global,
592 pub ranges: Vec<Range<FullOffset>>,
593 pub new_text: Vec<Arc<str>>,
594}
595
596#[derive(Clone, Debug, Eq, PartialEq)]
597pub struct UndoOperation {
598 pub timestamp: clock::Lamport,
599 pub version: clock::Global,
600 pub counts: HashMap<clock::Lamport, u32>,
601}
602
603/// Stores information about the indentation of a line (tabs and spaces).
604#[derive(Clone, Copy, Debug, Eq, PartialEq)]
605pub struct LineIndent {
606 pub tabs: u32,
607 pub spaces: u32,
608 pub line_blank: bool,
609}
610
611impl LineIndent {
612 pub fn from_chunks(chunks: &mut Chunks) -> Self {
613 let mut tabs = 0;
614 let mut spaces = 0;
615 let mut line_blank = true;
616
617 'outer: while let Some(chunk) = chunks.peek() {
618 for ch in chunk.chars() {
619 if ch == '\t' {
620 tabs += 1;
621 } else if ch == ' ' {
622 spaces += 1;
623 } else {
624 if ch != '\n' {
625 line_blank = false;
626 }
627 break 'outer;
628 }
629 }
630
631 chunks.next();
632 }
633
634 Self {
635 tabs,
636 spaces,
637 line_blank,
638 }
639 }
640
641 /// Constructs a new `LineIndent` which only contains spaces.
642 pub fn spaces(spaces: u32) -> Self {
643 Self {
644 tabs: 0,
645 spaces,
646 line_blank: true,
647 }
648 }
649
650 /// Constructs a new `LineIndent` which only contains tabs.
651 pub fn tabs(tabs: u32) -> Self {
652 Self {
653 tabs,
654 spaces: 0,
655 line_blank: true,
656 }
657 }
658
659 /// Indicates whether the line is empty.
660 pub fn is_line_empty(&self) -> bool {
661 self.tabs == 0 && self.spaces == 0 && self.line_blank
662 }
663
664 /// Indicates whether the line is blank (contains only whitespace).
665 pub fn is_line_blank(&self) -> bool {
666 self.line_blank
667 }
668
669 /// Returns the number of indentation characters (tabs or spaces).
670 pub fn raw_len(&self) -> u32 {
671 self.tabs + self.spaces
672 }
673
674 /// Returns the number of indentation characters (tabs or spaces), taking tab size into account.
675 pub fn len(&self, tab_size: u32) -> u32 {
676 self.tabs * tab_size + self.spaces
677 }
678}
679
680impl From<&str> for LineIndent {
681 fn from(value: &str) -> Self {
682 Self::from_iter(value.chars())
683 }
684}
685
686impl FromIterator<char> for LineIndent {
687 fn from_iter<T: IntoIterator<Item = char>>(chars: T) -> Self {
688 let mut tabs = 0;
689 let mut spaces = 0;
690 let mut line_blank = true;
691 for c in chars {
692 if c == '\t' {
693 tabs += 1;
694 } else if c == ' ' {
695 spaces += 1;
696 } else {
697 if c != '\n' {
698 line_blank = false;
699 }
700 break;
701 }
702 }
703 Self {
704 tabs,
705 spaces,
706 line_blank,
707 }
708 }
709}
710
711impl Buffer {
712 pub fn new(replica_id: u16, remote_id: BufferId, base_text: impl Into<String>) -> Buffer {
713 let mut base_text = base_text.into();
714 let line_ending = LineEnding::detect(&base_text);
715 LineEnding::normalize(&mut base_text);
716 Self::new_normalized(replica_id, remote_id, line_ending, Rope::from(base_text))
717 }
718
719 pub fn new_normalized(
720 replica_id: u16,
721 remote_id: BufferId,
722 line_ending: LineEnding,
723 normalized: Rope,
724 ) -> Buffer {
725 let history = History::new(normalized);
726 let mut fragments = SumTree::new(&None);
727 let mut insertions = SumTree::default();
728
729 let mut lamport_clock = clock::Lamport::new(replica_id);
730 let mut version = clock::Global::new();
731
732 let visible_text = history.base_text.clone();
733 if !visible_text.is_empty() {
734 let insertion_timestamp = clock::Lamport {
735 replica_id: 0,
736 value: 1,
737 };
738 lamport_clock.observe(insertion_timestamp);
739 version.observe(insertion_timestamp);
740 let fragment_id = Locator::between(&Locator::min(), &Locator::max());
741 let fragment = Fragment {
742 id: fragment_id,
743 timestamp: insertion_timestamp,
744 insertion_offset: 0,
745 len: visible_text.len(),
746 visible: true,
747 deletions: Default::default(),
748 max_undos: Default::default(),
749 };
750 insertions.push(InsertionFragment::new(&fragment), &());
751 fragments.push(fragment, &None);
752 }
753
754 Buffer {
755 snapshot: BufferSnapshot {
756 replica_id,
757 remote_id,
758 visible_text,
759 deleted_text: Rope::new(),
760 line_ending,
761 fragments,
762 insertions,
763 version,
764 undo_map: Default::default(),
765 insertion_slices: Default::default(),
766 },
767 history,
768 deferred_ops: OperationQueue::new(),
769 deferred_replicas: HashSet::default(),
770 lamport_clock,
771 subscriptions: Default::default(),
772 edit_id_resolvers: Default::default(),
773 wait_for_version_txs: Default::default(),
774 }
775 }
776
777 pub fn version(&self) -> clock::Global {
778 self.version.clone()
779 }
780
781 pub fn snapshot(&self) -> BufferSnapshot {
782 self.snapshot.clone()
783 }
784
785 pub fn branch(&self) -> Self {
786 Self {
787 snapshot: self.snapshot.clone(),
788 history: History::new(self.base_text().clone()),
789 deferred_ops: OperationQueue::new(),
790 deferred_replicas: HashSet::default(),
791 lamport_clock: clock::Lamport::new(LOCAL_BRANCH_REPLICA_ID),
792 subscriptions: Default::default(),
793 edit_id_resolvers: Default::default(),
794 wait_for_version_txs: Default::default(),
795 }
796 }
797
798 pub fn replica_id(&self) -> ReplicaId {
799 self.lamport_clock.replica_id
800 }
801
802 pub fn remote_id(&self) -> BufferId {
803 self.remote_id
804 }
805
806 pub fn deferred_ops_len(&self) -> usize {
807 self.deferred_ops.len()
808 }
809
810 pub fn transaction_group_interval(&self) -> Duration {
811 self.history.group_interval
812 }
813
814 pub fn edit<R, I, S, T>(&mut self, edits: R) -> Operation
815 where
816 R: IntoIterator<IntoIter = I>,
817 I: ExactSizeIterator<Item = (Range<S>, T)>,
818 S: ToOffset,
819 T: Into<Arc<str>>,
820 {
821 let edits = edits
822 .into_iter()
823 .map(|(range, new_text)| (range, new_text.into()));
824
825 self.start_transaction();
826 let timestamp = self.lamport_clock.tick();
827 let operation = Operation::Edit(self.apply_local_edit(edits, timestamp));
828
829 self.history.push(operation.clone());
830 self.history.push_undo(operation.timestamp());
831 self.snapshot.version.observe(operation.timestamp());
832 self.end_transaction();
833 operation
834 }
835
836 fn apply_local_edit<S: ToOffset, T: Into<Arc<str>>>(
837 &mut self,
838 edits: impl ExactSizeIterator<Item = (Range<S>, T)>,
839 timestamp: clock::Lamport,
840 ) -> EditOperation {
841 let mut edits_patch = Patch::default();
842 let mut edit_op = EditOperation {
843 timestamp,
844 version: self.version(),
845 ranges: Vec::with_capacity(edits.len()),
846 new_text: Vec::with_capacity(edits.len()),
847 };
848 let mut new_insertions = Vec::new();
849 let mut insertion_offset = 0;
850 let mut insertion_slices = Vec::new();
851
852 let mut edits = edits
853 .map(|(range, new_text)| (range.to_offset(&*self), new_text))
854 .peekable();
855
856 let mut new_ropes =
857 RopeBuilder::new(self.visible_text.cursor(0), self.deleted_text.cursor(0));
858 let mut old_fragments = self.fragments.cursor::<FragmentTextSummary>(&None);
859 let mut new_fragments = old_fragments.slice(&edits.peek().unwrap().0.start, Bias::Right);
860 new_ropes.append(new_fragments.summary().text);
861
862 let mut fragment_start = old_fragments.start().visible;
863 for (range, new_text) in edits {
864 let new_text = LineEnding::normalize_arc(new_text.into());
865 let fragment_end = old_fragments.end().visible;
866
867 // If the current fragment ends before this range, then jump ahead to the first fragment
868 // that extends past the start of this range, reusing any intervening fragments.
869 if fragment_end < range.start {
870 // If the current fragment has been partially consumed, then consume the rest of it
871 // and advance to the next fragment before slicing.
872 if fragment_start > old_fragments.start().visible {
873 if fragment_end > fragment_start {
874 let mut suffix = old_fragments.item().unwrap().clone();
875 suffix.len = fragment_end - fragment_start;
876 suffix.insertion_offset += fragment_start - old_fragments.start().visible;
877 new_insertions.push(InsertionFragment::insert_new(&suffix));
878 new_ropes.push_fragment(&suffix, suffix.visible);
879 new_fragments.push(suffix, &None);
880 }
881 old_fragments.next();
882 }
883
884 let slice = old_fragments.slice(&range.start, Bias::Right);
885 new_ropes.append(slice.summary().text);
886 new_fragments.append(slice, &None);
887 fragment_start = old_fragments.start().visible;
888 }
889
890 let full_range_start = FullOffset(range.start + old_fragments.start().deleted);
891
892 // Preserve any portion of the current fragment that precedes this range.
893 if fragment_start < range.start {
894 let mut prefix = old_fragments.item().unwrap().clone();
895 prefix.len = range.start - fragment_start;
896 prefix.insertion_offset += fragment_start - old_fragments.start().visible;
897 prefix.id = Locator::between(&new_fragments.summary().max_id, &prefix.id);
898 new_insertions.push(InsertionFragment::insert_new(&prefix));
899 new_ropes.push_fragment(&prefix, prefix.visible);
900 new_fragments.push(prefix, &None);
901 fragment_start = range.start;
902 }
903
904 // Insert the new text before any existing fragments within the range.
905 if !new_text.is_empty() {
906 let new_start = new_fragments.summary().text.visible;
907
908 let fragment = Fragment {
909 id: Locator::between(
910 &new_fragments.summary().max_id,
911 old_fragments
912 .item()
913 .map_or(&Locator::max(), |old_fragment| &old_fragment.id),
914 ),
915 timestamp,
916 insertion_offset,
917 len: new_text.len(),
918 deletions: Default::default(),
919 max_undos: Default::default(),
920 visible: true,
921 };
922 edits_patch.push(Edit {
923 old: fragment_start..fragment_start,
924 new: new_start..new_start + new_text.len(),
925 });
926 insertion_slices.push(InsertionSlice::from_fragment(timestamp, &fragment));
927 new_insertions.push(InsertionFragment::insert_new(&fragment));
928 new_ropes.push_str(new_text.as_ref());
929 new_fragments.push(fragment, &None);
930 insertion_offset += new_text.len();
931 }
932
933 // Advance through every fragment that intersects this range, marking the intersecting
934 // portions as deleted.
935 while fragment_start < range.end {
936 let fragment = old_fragments.item().unwrap();
937 let fragment_end = old_fragments.end().visible;
938 let mut intersection = fragment.clone();
939 let intersection_end = cmp::min(range.end, fragment_end);
940 if fragment.visible {
941 intersection.len = intersection_end - fragment_start;
942 intersection.insertion_offset += fragment_start - old_fragments.start().visible;
943 intersection.id =
944 Locator::between(&new_fragments.summary().max_id, &intersection.id);
945 intersection.deletions.insert(timestamp);
946 intersection.visible = false;
947 }
948 if intersection.len > 0 {
949 if fragment.visible && !intersection.visible {
950 let new_start = new_fragments.summary().text.visible;
951 edits_patch.push(Edit {
952 old: fragment_start..intersection_end,
953 new: new_start..new_start,
954 });
955 insertion_slices
956 .push(InsertionSlice::from_fragment(timestamp, &intersection));
957 }
958 new_insertions.push(InsertionFragment::insert_new(&intersection));
959 new_ropes.push_fragment(&intersection, fragment.visible);
960 new_fragments.push(intersection, &None);
961 fragment_start = intersection_end;
962 }
963 if fragment_end <= range.end {
964 old_fragments.next();
965 }
966 }
967
968 let full_range_end = FullOffset(range.end + old_fragments.start().deleted);
969 edit_op.ranges.push(full_range_start..full_range_end);
970 edit_op.new_text.push(new_text);
971 }
972
973 // If the current fragment has been partially consumed, then consume the rest of it
974 // and advance to the next fragment before slicing.
975 if fragment_start > old_fragments.start().visible {
976 let fragment_end = old_fragments.end().visible;
977 if fragment_end > fragment_start {
978 let mut suffix = old_fragments.item().unwrap().clone();
979 suffix.len = fragment_end - fragment_start;
980 suffix.insertion_offset += fragment_start - old_fragments.start().visible;
981 new_insertions.push(InsertionFragment::insert_new(&suffix));
982 new_ropes.push_fragment(&suffix, suffix.visible);
983 new_fragments.push(suffix, &None);
984 }
985 old_fragments.next();
986 }
987
988 let suffix = old_fragments.suffix();
989 new_ropes.append(suffix.summary().text);
990 new_fragments.append(suffix, &None);
991 let (visible_text, deleted_text) = new_ropes.finish();
992 drop(old_fragments);
993
994 self.snapshot.fragments = new_fragments;
995 self.snapshot.insertions.edit(new_insertions, &());
996 self.snapshot.visible_text = visible_text;
997 self.snapshot.deleted_text = deleted_text;
998 self.subscriptions.publish_mut(&edits_patch);
999 self.snapshot.insertion_slices.extend(insertion_slices);
1000 edit_op
1001 }
1002
1003 pub fn set_line_ending(&mut self, line_ending: LineEnding) {
1004 self.snapshot.line_ending = line_ending;
1005 }
1006
1007 pub fn apply_ops<I: IntoIterator<Item = Operation>>(&mut self, ops: I) {
1008 let mut deferred_ops = Vec::new();
1009 for op in ops {
1010 self.history.push(op.clone());
1011 if self.can_apply_op(&op) {
1012 self.apply_op(op);
1013 } else {
1014 self.deferred_replicas.insert(op.replica_id());
1015 deferred_ops.push(op);
1016 }
1017 }
1018 self.deferred_ops.insert(deferred_ops);
1019 self.flush_deferred_ops();
1020 }
1021
1022 fn apply_op(&mut self, op: Operation) {
1023 match op {
1024 Operation::Edit(edit) => {
1025 if !self.version.observed(edit.timestamp) {
1026 self.apply_remote_edit(
1027 &edit.version,
1028 &edit.ranges,
1029 &edit.new_text,
1030 edit.timestamp,
1031 );
1032 self.snapshot.version.observe(edit.timestamp);
1033 self.lamport_clock.observe(edit.timestamp);
1034 self.resolve_edit(edit.timestamp);
1035 }
1036 }
1037 Operation::Undo(undo) => {
1038 if !self.version.observed(undo.timestamp) {
1039 self.apply_undo(&undo);
1040 self.snapshot.version.observe(undo.timestamp);
1041 self.lamport_clock.observe(undo.timestamp);
1042 }
1043 }
1044 }
1045 self.wait_for_version_txs.retain_mut(|(version, tx)| {
1046 if self.snapshot.version().observed_all(version) {
1047 tx.try_send(()).ok();
1048 false
1049 } else {
1050 true
1051 }
1052 });
1053 }
1054
1055 fn apply_remote_edit(
1056 &mut self,
1057 version: &clock::Global,
1058 ranges: &[Range<FullOffset>],
1059 new_text: &[Arc<str>],
1060 timestamp: clock::Lamport,
1061 ) {
1062 if ranges.is_empty() {
1063 return;
1064 }
1065
1066 let edits = ranges.iter().zip(new_text.iter());
1067 let mut edits_patch = Patch::default();
1068 let mut insertion_slices = Vec::new();
1069 let cx = Some(version.clone());
1070 let mut new_insertions = Vec::new();
1071 let mut insertion_offset = 0;
1072 let mut new_ropes =
1073 RopeBuilder::new(self.visible_text.cursor(0), self.deleted_text.cursor(0));
1074 let mut old_fragments = self.fragments.cursor::<(VersionedFullOffset, usize)>(&cx);
1075 let mut new_fragments =
1076 old_fragments.slice(&VersionedFullOffset::Offset(ranges[0].start), Bias::Left);
1077 new_ropes.append(new_fragments.summary().text);
1078
1079 let mut fragment_start = old_fragments.start().0.full_offset();
1080 for (range, new_text) in edits {
1081 let fragment_end = old_fragments.end().0.full_offset();
1082
1083 // If the current fragment ends before this range, then jump ahead to the first fragment
1084 // that extends past the start of this range, reusing any intervening fragments.
1085 if fragment_end < range.start {
1086 // If the current fragment has been partially consumed, then consume the rest of it
1087 // and advance to the next fragment before slicing.
1088 if fragment_start > old_fragments.start().0.full_offset() {
1089 if fragment_end > fragment_start {
1090 let mut suffix = old_fragments.item().unwrap().clone();
1091 suffix.len = fragment_end.0 - fragment_start.0;
1092 suffix.insertion_offset +=
1093 fragment_start - old_fragments.start().0.full_offset();
1094 new_insertions.push(InsertionFragment::insert_new(&suffix));
1095 new_ropes.push_fragment(&suffix, suffix.visible);
1096 new_fragments.push(suffix, &None);
1097 }
1098 old_fragments.next();
1099 }
1100
1101 let slice =
1102 old_fragments.slice(&VersionedFullOffset::Offset(range.start), Bias::Left);
1103 new_ropes.append(slice.summary().text);
1104 new_fragments.append(slice, &None);
1105 fragment_start = old_fragments.start().0.full_offset();
1106 }
1107
1108 // If we are at the end of a non-concurrent fragment, advance to the next one.
1109 let fragment_end = old_fragments.end().0.full_offset();
1110 if fragment_end == range.start && fragment_end > fragment_start {
1111 let mut fragment = old_fragments.item().unwrap().clone();
1112 fragment.len = fragment_end.0 - fragment_start.0;
1113 fragment.insertion_offset += fragment_start - old_fragments.start().0.full_offset();
1114 new_insertions.push(InsertionFragment::insert_new(&fragment));
1115 new_ropes.push_fragment(&fragment, fragment.visible);
1116 new_fragments.push(fragment, &None);
1117 old_fragments.next();
1118 fragment_start = old_fragments.start().0.full_offset();
1119 }
1120
1121 // Skip over insertions that are concurrent to this edit, but have a lower lamport
1122 // timestamp.
1123 while let Some(fragment) = old_fragments.item() {
1124 if fragment_start == range.start && fragment.timestamp > timestamp {
1125 new_ropes.push_fragment(fragment, fragment.visible);
1126 new_fragments.push(fragment.clone(), &None);
1127 old_fragments.next();
1128 debug_assert_eq!(fragment_start, range.start);
1129 } else {
1130 break;
1131 }
1132 }
1133 debug_assert!(fragment_start <= range.start);
1134
1135 // Preserve any portion of the current fragment that precedes this range.
1136 if fragment_start < range.start {
1137 let mut prefix = old_fragments.item().unwrap().clone();
1138 prefix.len = range.start.0 - fragment_start.0;
1139 prefix.insertion_offset += fragment_start - old_fragments.start().0.full_offset();
1140 prefix.id = Locator::between(&new_fragments.summary().max_id, &prefix.id);
1141 new_insertions.push(InsertionFragment::insert_new(&prefix));
1142 fragment_start = range.start;
1143 new_ropes.push_fragment(&prefix, prefix.visible);
1144 new_fragments.push(prefix, &None);
1145 }
1146
1147 // Insert the new text before any existing fragments within the range.
1148 if !new_text.is_empty() {
1149 let mut old_start = old_fragments.start().1;
1150 if old_fragments.item().map_or(false, |f| f.visible) {
1151 old_start += fragment_start.0 - old_fragments.start().0.full_offset().0;
1152 }
1153 let new_start = new_fragments.summary().text.visible;
1154 let fragment = Fragment {
1155 id: Locator::between(
1156 &new_fragments.summary().max_id,
1157 old_fragments
1158 .item()
1159 .map_or(&Locator::max(), |old_fragment| &old_fragment.id),
1160 ),
1161 timestamp,
1162 insertion_offset,
1163 len: new_text.len(),
1164 deletions: Default::default(),
1165 max_undos: Default::default(),
1166 visible: true,
1167 };
1168 edits_patch.push(Edit {
1169 old: old_start..old_start,
1170 new: new_start..new_start + new_text.len(),
1171 });
1172 insertion_slices.push(InsertionSlice::from_fragment(timestamp, &fragment));
1173 new_insertions.push(InsertionFragment::insert_new(&fragment));
1174 new_ropes.push_str(new_text);
1175 new_fragments.push(fragment, &None);
1176 insertion_offset += new_text.len();
1177 }
1178
1179 // Advance through every fragment that intersects this range, marking the intersecting
1180 // portions as deleted.
1181 while fragment_start < range.end {
1182 let fragment = old_fragments.item().unwrap();
1183 let fragment_end = old_fragments.end().0.full_offset();
1184 let mut intersection = fragment.clone();
1185 let intersection_end = cmp::min(range.end, fragment_end);
1186 if fragment.was_visible(version, &self.undo_map) {
1187 intersection.len = intersection_end.0 - fragment_start.0;
1188 intersection.insertion_offset +=
1189 fragment_start - old_fragments.start().0.full_offset();
1190 intersection.id =
1191 Locator::between(&new_fragments.summary().max_id, &intersection.id);
1192 intersection.deletions.insert(timestamp);
1193 intersection.visible = false;
1194 insertion_slices.push(InsertionSlice::from_fragment(timestamp, &intersection));
1195 }
1196 if intersection.len > 0 {
1197 if fragment.visible && !intersection.visible {
1198 let old_start = old_fragments.start().1
1199 + (fragment_start.0 - old_fragments.start().0.full_offset().0);
1200 let new_start = new_fragments.summary().text.visible;
1201 edits_patch.push(Edit {
1202 old: old_start..old_start + intersection.len,
1203 new: new_start..new_start,
1204 });
1205 }
1206 new_insertions.push(InsertionFragment::insert_new(&intersection));
1207 new_ropes.push_fragment(&intersection, fragment.visible);
1208 new_fragments.push(intersection, &None);
1209 fragment_start = intersection_end;
1210 }
1211 if fragment_end <= range.end {
1212 old_fragments.next();
1213 }
1214 }
1215 }
1216
1217 // If the current fragment has been partially consumed, then consume the rest of it
1218 // and advance to the next fragment before slicing.
1219 if fragment_start > old_fragments.start().0.full_offset() {
1220 let fragment_end = old_fragments.end().0.full_offset();
1221 if fragment_end > fragment_start {
1222 let mut suffix = old_fragments.item().unwrap().clone();
1223 suffix.len = fragment_end.0 - fragment_start.0;
1224 suffix.insertion_offset += fragment_start - old_fragments.start().0.full_offset();
1225 new_insertions.push(InsertionFragment::insert_new(&suffix));
1226 new_ropes.push_fragment(&suffix, suffix.visible);
1227 new_fragments.push(suffix, &None);
1228 }
1229 old_fragments.next();
1230 }
1231
1232 let suffix = old_fragments.suffix();
1233 new_ropes.append(suffix.summary().text);
1234 new_fragments.append(suffix, &None);
1235 let (visible_text, deleted_text) = new_ropes.finish();
1236 drop(old_fragments);
1237
1238 self.snapshot.fragments = new_fragments;
1239 self.snapshot.visible_text = visible_text;
1240 self.snapshot.deleted_text = deleted_text;
1241 self.snapshot.insertions.edit(new_insertions, &());
1242 self.snapshot.insertion_slices.extend(insertion_slices);
1243 self.subscriptions.publish_mut(&edits_patch)
1244 }
1245
1246 fn fragment_ids_for_edits<'a>(
1247 &'a self,
1248 edit_ids: impl Iterator<Item = &'a clock::Lamport>,
1249 ) -> Vec<&'a Locator> {
1250 // Get all of the insertion slices changed by the given edits.
1251 let mut insertion_slices = Vec::new();
1252 for edit_id in edit_ids {
1253 let insertion_slice = InsertionSlice {
1254 edit_id: *edit_id,
1255 insertion_id: clock::Lamport::default(),
1256 range: 0..0,
1257 };
1258 let slices = self
1259 .snapshot
1260 .insertion_slices
1261 .iter_from(&insertion_slice)
1262 .take_while(|slice| slice.edit_id == *edit_id);
1263 insertion_slices.extend(slices)
1264 }
1265 insertion_slices
1266 .sort_unstable_by_key(|s| (s.insertion_id, s.range.start, Reverse(s.range.end)));
1267
1268 // Get all of the fragments corresponding to these insertion slices.
1269 let mut fragment_ids = Vec::new();
1270 let mut insertions_cursor = self.insertions.cursor::<InsertionFragmentKey>(&());
1271 for insertion_slice in &insertion_slices {
1272 if insertion_slice.insertion_id != insertions_cursor.start().timestamp
1273 || insertion_slice.range.start > insertions_cursor.start().split_offset
1274 {
1275 insertions_cursor.seek_forward(
1276 &InsertionFragmentKey {
1277 timestamp: insertion_slice.insertion_id,
1278 split_offset: insertion_slice.range.start,
1279 },
1280 Bias::Left,
1281 );
1282 }
1283 while let Some(item) = insertions_cursor.item() {
1284 if item.timestamp != insertion_slice.insertion_id
1285 || item.split_offset >= insertion_slice.range.end
1286 {
1287 break;
1288 }
1289 fragment_ids.push(&item.fragment_id);
1290 insertions_cursor.next();
1291 }
1292 }
1293 fragment_ids.sort_unstable();
1294 fragment_ids
1295 }
1296
1297 fn apply_undo(&mut self, undo: &UndoOperation) {
1298 self.snapshot.undo_map.insert(undo);
1299
1300 let mut edits = Patch::default();
1301 let mut old_fragments = self.fragments.cursor::<(Option<&Locator>, usize)>(&None);
1302 let mut new_fragments = SumTree::new(&None);
1303 let mut new_ropes =
1304 RopeBuilder::new(self.visible_text.cursor(0), self.deleted_text.cursor(0));
1305
1306 for fragment_id in self.fragment_ids_for_edits(undo.counts.keys()) {
1307 let preceding_fragments = old_fragments.slice(&Some(fragment_id), Bias::Left);
1308 new_ropes.append(preceding_fragments.summary().text);
1309 new_fragments.append(preceding_fragments, &None);
1310
1311 if let Some(fragment) = old_fragments.item() {
1312 let mut fragment = fragment.clone();
1313 let fragment_was_visible = fragment.visible;
1314
1315 fragment.visible = fragment.is_visible(&self.undo_map);
1316 fragment.max_undos.observe(undo.timestamp);
1317
1318 let old_start = old_fragments.start().1;
1319 let new_start = new_fragments.summary().text.visible;
1320 if fragment_was_visible && !fragment.visible {
1321 edits.push(Edit {
1322 old: old_start..old_start + fragment.len,
1323 new: new_start..new_start,
1324 });
1325 } else if !fragment_was_visible && fragment.visible {
1326 edits.push(Edit {
1327 old: old_start..old_start,
1328 new: new_start..new_start + fragment.len,
1329 });
1330 }
1331 new_ropes.push_fragment(&fragment, fragment_was_visible);
1332 new_fragments.push(fragment, &None);
1333
1334 old_fragments.next();
1335 }
1336 }
1337
1338 let suffix = old_fragments.suffix();
1339 new_ropes.append(suffix.summary().text);
1340 new_fragments.append(suffix, &None);
1341
1342 drop(old_fragments);
1343 let (visible_text, deleted_text) = new_ropes.finish();
1344 self.snapshot.fragments = new_fragments;
1345 self.snapshot.visible_text = visible_text;
1346 self.snapshot.deleted_text = deleted_text;
1347 self.subscriptions.publish_mut(&edits);
1348 }
1349
1350 fn flush_deferred_ops(&mut self) {
1351 self.deferred_replicas.clear();
1352 let mut deferred_ops = Vec::new();
1353 for op in self.deferred_ops.drain().iter().cloned() {
1354 if self.can_apply_op(&op) {
1355 self.apply_op(op);
1356 } else {
1357 self.deferred_replicas.insert(op.replica_id());
1358 deferred_ops.push(op);
1359 }
1360 }
1361 self.deferred_ops.insert(deferred_ops);
1362 }
1363
1364 fn can_apply_op(&self, op: &Operation) -> bool {
1365 if self.deferred_replicas.contains(&op.replica_id()) {
1366 false
1367 } else {
1368 self.version.observed_all(match op {
1369 Operation::Edit(edit) => &edit.version,
1370 Operation::Undo(undo) => &undo.version,
1371 })
1372 }
1373 }
1374
1375 pub fn has_deferred_ops(&self) -> bool {
1376 !self.deferred_ops.is_empty()
1377 }
1378
1379 pub fn peek_undo_stack(&self) -> Option<&HistoryEntry> {
1380 self.history.undo_stack.last()
1381 }
1382
1383 pub fn peek_redo_stack(&self) -> Option<&HistoryEntry> {
1384 self.history.redo_stack.last()
1385 }
1386
1387 pub fn start_transaction(&mut self) -> Option<TransactionId> {
1388 self.start_transaction_at(Instant::now())
1389 }
1390
1391 pub fn start_transaction_at(&mut self, now: Instant) -> Option<TransactionId> {
1392 self.history
1393 .start_transaction(self.version.clone(), now, &mut self.lamport_clock)
1394 }
1395
1396 pub fn end_transaction(&mut self) -> Option<(TransactionId, clock::Global)> {
1397 self.end_transaction_at(Instant::now())
1398 }
1399
1400 pub fn end_transaction_at(&mut self, now: Instant) -> Option<(TransactionId, clock::Global)> {
1401 if let Some(entry) = self.history.end_transaction(now) {
1402 let since = entry.transaction.start.clone();
1403 let id = self.history.group().unwrap();
1404 Some((id, since))
1405 } else {
1406 None
1407 }
1408 }
1409
1410 pub fn finalize_last_transaction(&mut self) -> Option<&Transaction> {
1411 self.history.finalize_last_transaction()
1412 }
1413
1414 pub fn group_until_transaction(&mut self, transaction_id: TransactionId) {
1415 self.history.group_until(transaction_id);
1416 }
1417
1418 pub fn base_text(&self) -> &Rope {
1419 &self.history.base_text
1420 }
1421
1422 pub fn operations(&self) -> &TreeMap<clock::Lamport, Operation> {
1423 &self.history.operations
1424 }
1425
1426 pub fn undo(&mut self) -> Option<(TransactionId, Operation)> {
1427 if let Some(entry) = self.history.pop_undo() {
1428 let transaction = entry.transaction.clone();
1429 let transaction_id = transaction.id;
1430 let op = self.undo_or_redo(transaction);
1431 Some((transaction_id, op))
1432 } else {
1433 None
1434 }
1435 }
1436
1437 pub fn undo_transaction(&mut self, transaction_id: TransactionId) -> Option<Operation> {
1438 let transaction = self
1439 .history
1440 .remove_from_undo(transaction_id)?
1441 .transaction
1442 .clone();
1443 Some(self.undo_or_redo(transaction))
1444 }
1445
1446 pub fn undo_to_transaction(&mut self, transaction_id: TransactionId) -> Vec<Operation> {
1447 let transactions = self
1448 .history
1449 .remove_from_undo_until(transaction_id)
1450 .iter()
1451 .map(|entry| entry.transaction.clone())
1452 .collect::<Vec<_>>();
1453
1454 transactions
1455 .into_iter()
1456 .map(|transaction| self.undo_or_redo(transaction))
1457 .collect()
1458 }
1459
1460 pub fn forget_transaction(&mut self, transaction_id: TransactionId) -> Option<Transaction> {
1461 self.history.forget(transaction_id)
1462 }
1463
1464 pub fn get_transaction(&self, transaction_id: TransactionId) -> Option<&Transaction> {
1465 self.history.transaction(transaction_id)
1466 }
1467
1468 pub fn merge_transactions(&mut self, transaction: TransactionId, destination: TransactionId) {
1469 self.history.merge_transactions(transaction, destination);
1470 }
1471
1472 pub fn redo(&mut self) -> Option<(TransactionId, Operation)> {
1473 if let Some(entry) = self.history.pop_redo() {
1474 let transaction = entry.transaction.clone();
1475 let transaction_id = transaction.id;
1476 let op = self.undo_or_redo(transaction);
1477 Some((transaction_id, op))
1478 } else {
1479 None
1480 }
1481 }
1482
1483 pub fn redo_to_transaction(&mut self, transaction_id: TransactionId) -> Vec<Operation> {
1484 let transactions = self
1485 .history
1486 .remove_from_redo(transaction_id)
1487 .iter()
1488 .map(|entry| entry.transaction.clone())
1489 .collect::<Vec<_>>();
1490
1491 transactions
1492 .into_iter()
1493 .map(|transaction| self.undo_or_redo(transaction))
1494 .collect()
1495 }
1496
1497 fn undo_or_redo(&mut self, transaction: Transaction) -> Operation {
1498 let mut counts = HashMap::default();
1499 for edit_id in transaction.edit_ids {
1500 counts.insert(edit_id, self.undo_map.undo_count(edit_id).saturating_add(1));
1501 }
1502
1503 let operation = self.undo_operations(counts);
1504 self.history.push(operation.clone());
1505 operation
1506 }
1507
1508 pub fn undo_operations(&mut self, counts: HashMap<clock::Lamport, u32>) -> Operation {
1509 let timestamp = self.lamport_clock.tick();
1510 let version = self.version();
1511 self.snapshot.version.observe(timestamp);
1512 let undo = UndoOperation {
1513 timestamp,
1514 version,
1515 counts,
1516 };
1517 self.apply_undo(&undo);
1518 Operation::Undo(undo)
1519 }
1520
1521 pub fn push_transaction(&mut self, transaction: Transaction, now: Instant) {
1522 self.history.push_transaction(transaction, now);
1523 }
1524
1525 /// Differs from `push_transaction` in that it does not clear the redo stack.
1526 /// The caller responsible for
1527 /// Differs from `push_transaction` in that it does not clear the redo
1528 /// stack. Intended to be used to create a parent transaction to merge
1529 /// potential child transactions into.
1530 ///
1531 /// The caller is responsible for removing it from the undo history using
1532 /// `forget_transaction` if no edits are merged into it. Otherwise, if edits
1533 /// are merged into this transaction, the caller is responsible for ensuring
1534 /// the redo stack is cleared. The easiest way to ensure the redo stack is
1535 /// cleared is to create transactions with the usual `start_transaction` and
1536 /// `end_transaction` methods and merging the resulting transactions into
1537 /// the transaction created by this method
1538 pub fn push_empty_transaction(&mut self, now: Instant) -> TransactionId {
1539 self.history
1540 .push_empty_transaction(self.version.clone(), now, &mut self.lamport_clock)
1541 }
1542
1543 pub fn edited_ranges_for_transaction_id<D>(
1544 &self,
1545 transaction_id: TransactionId,
1546 ) -> impl '_ + Iterator<Item = Range<D>>
1547 where
1548 D: TextDimension,
1549 {
1550 self.history
1551 .transaction(transaction_id)
1552 .into_iter()
1553 .flat_map(|transaction| self.edited_ranges_for_transaction(transaction))
1554 }
1555
1556 pub fn edited_ranges_for_edit_ids<'a, D>(
1557 &'a self,
1558 edit_ids: impl IntoIterator<Item = &'a clock::Lamport>,
1559 ) -> impl 'a + Iterator<Item = Range<D>>
1560 where
1561 D: TextDimension,
1562 {
1563 // get fragment ranges
1564 let mut cursor = self.fragments.cursor::<(Option<&Locator>, usize)>(&None);
1565 let offset_ranges = self
1566 .fragment_ids_for_edits(edit_ids.into_iter())
1567 .into_iter()
1568 .filter_map(move |fragment_id| {
1569 cursor.seek_forward(&Some(fragment_id), Bias::Left);
1570 let fragment = cursor.item()?;
1571 let start_offset = cursor.start().1;
1572 let end_offset = start_offset + if fragment.visible { fragment.len } else { 0 };
1573 Some(start_offset..end_offset)
1574 });
1575
1576 // combine adjacent ranges
1577 let mut prev_range: Option<Range<usize>> = None;
1578 let disjoint_ranges = offset_ranges
1579 .map(Some)
1580 .chain([None])
1581 .filter_map(move |range| {
1582 if let Some((range, prev_range)) = range.as_ref().zip(prev_range.as_mut()) {
1583 if prev_range.end == range.start {
1584 prev_range.end = range.end;
1585 return None;
1586 }
1587 }
1588 let result = prev_range.clone();
1589 prev_range = range;
1590 result
1591 });
1592
1593 // convert to the desired text dimension.
1594 let mut position = D::zero(&());
1595 let mut rope_cursor = self.visible_text.cursor(0);
1596 disjoint_ranges.map(move |range| {
1597 position.add_assign(&rope_cursor.summary(range.start));
1598 let start = position;
1599 position.add_assign(&rope_cursor.summary(range.end));
1600 let end = position;
1601 start..end
1602 })
1603 }
1604
1605 pub fn edited_ranges_for_transaction<'a, D>(
1606 &'a self,
1607 transaction: &'a Transaction,
1608 ) -> impl 'a + Iterator<Item = Range<D>>
1609 where
1610 D: TextDimension,
1611 {
1612 self.edited_ranges_for_edit_ids(&transaction.edit_ids)
1613 }
1614
1615 pub fn subscribe(&mut self) -> Subscription {
1616 self.subscriptions.subscribe()
1617 }
1618
1619 pub fn wait_for_edits<It: IntoIterator<Item = clock::Lamport>>(
1620 &mut self,
1621 edit_ids: It,
1622 ) -> impl 'static + Future<Output = Result<()>> + use<It> {
1623 let mut futures = Vec::new();
1624 for edit_id in edit_ids {
1625 if !self.version.observed(edit_id) {
1626 let (tx, rx) = oneshot::channel();
1627 self.edit_id_resolvers.entry(edit_id).or_default().push(tx);
1628 futures.push(rx);
1629 }
1630 }
1631
1632 async move {
1633 for mut future in futures {
1634 if future.recv().await.is_none() {
1635 anyhow::bail!("gave up waiting for edits");
1636 }
1637 }
1638 Ok(())
1639 }
1640 }
1641
1642 pub fn wait_for_anchors<It: IntoIterator<Item = Anchor>>(
1643 &mut self,
1644 anchors: It,
1645 ) -> impl 'static + Future<Output = Result<()>> + use<It> {
1646 let mut futures = Vec::new();
1647 for anchor in anchors {
1648 if !self.version.observed(anchor.timestamp)
1649 && anchor != Anchor::MAX
1650 && anchor != Anchor::MIN
1651 {
1652 let (tx, rx) = oneshot::channel();
1653 self.edit_id_resolvers
1654 .entry(anchor.timestamp)
1655 .or_default()
1656 .push(tx);
1657 futures.push(rx);
1658 }
1659 }
1660
1661 async move {
1662 for mut future in futures {
1663 if future.recv().await.is_none() {
1664 anyhow::bail!("gave up waiting for anchors");
1665 }
1666 }
1667 Ok(())
1668 }
1669 }
1670
1671 pub fn wait_for_version(
1672 &mut self,
1673 version: clock::Global,
1674 ) -> impl Future<Output = Result<()>> + use<> {
1675 let mut rx = None;
1676 if !self.snapshot.version.observed_all(&version) {
1677 let channel = oneshot::channel();
1678 self.wait_for_version_txs.push((version, channel.0));
1679 rx = Some(channel.1);
1680 }
1681 async move {
1682 if let Some(mut rx) = rx {
1683 if rx.recv().await.is_none() {
1684 anyhow::bail!("gave up waiting for version");
1685 }
1686 }
1687 Ok(())
1688 }
1689 }
1690
1691 pub fn give_up_waiting(&mut self) {
1692 self.edit_id_resolvers.clear();
1693 self.wait_for_version_txs.clear();
1694 }
1695
1696 fn resolve_edit(&mut self, edit_id: clock::Lamport) {
1697 for mut tx in self
1698 .edit_id_resolvers
1699 .remove(&edit_id)
1700 .into_iter()
1701 .flatten()
1702 {
1703 tx.try_send(()).ok();
1704 }
1705 }
1706}
1707
1708#[cfg(any(test, feature = "test-support"))]
1709impl Buffer {
1710 #[track_caller]
1711 pub fn edit_via_marked_text(&mut self, marked_string: &str) {
1712 let edits = self.edits_for_marked_text(marked_string);
1713 self.edit(edits);
1714 }
1715
1716 #[track_caller]
1717 pub fn edits_for_marked_text(&self, marked_string: &str) -> Vec<(Range<usize>, String)> {
1718 let old_text = self.text();
1719 let (new_text, mut ranges) = util::test::marked_text_ranges(marked_string, false);
1720 if ranges.is_empty() {
1721 ranges.push(0..new_text.len());
1722 }
1723
1724 assert_eq!(
1725 old_text[..ranges[0].start],
1726 new_text[..ranges[0].start],
1727 "invalid edit"
1728 );
1729
1730 let mut delta = 0;
1731 let mut edits = Vec::new();
1732 let mut ranges = ranges.into_iter().peekable();
1733
1734 while let Some(inserted_range) = ranges.next() {
1735 let new_start = inserted_range.start;
1736 let old_start = (new_start as isize - delta) as usize;
1737
1738 let following_text = if let Some(next_range) = ranges.peek() {
1739 &new_text[inserted_range.end..next_range.start]
1740 } else {
1741 &new_text[inserted_range.end..]
1742 };
1743
1744 let inserted_len = inserted_range.len();
1745 let deleted_len = old_text[old_start..]
1746 .find(following_text)
1747 .expect("invalid edit");
1748
1749 let old_range = old_start..old_start + deleted_len;
1750 edits.push((old_range, new_text[inserted_range].to_string()));
1751 delta += inserted_len as isize - deleted_len as isize;
1752 }
1753
1754 assert_eq!(
1755 old_text.len() as isize + delta,
1756 new_text.len() as isize,
1757 "invalid edit"
1758 );
1759
1760 edits
1761 }
1762
1763 pub fn check_invariants(&self) {
1764 // Ensure every fragment is ordered by locator in the fragment tree and corresponds
1765 // to an insertion fragment in the insertions tree.
1766 let mut prev_fragment_id = Locator::min();
1767 for fragment in self.snapshot.fragments.items(&None) {
1768 assert!(fragment.id > prev_fragment_id);
1769 prev_fragment_id = fragment.id.clone();
1770
1771 let insertion_fragment = self
1772 .snapshot
1773 .insertions
1774 .get(
1775 &InsertionFragmentKey {
1776 timestamp: fragment.timestamp,
1777 split_offset: fragment.insertion_offset,
1778 },
1779 &(),
1780 )
1781 .unwrap();
1782 assert_eq!(
1783 insertion_fragment.fragment_id, fragment.id,
1784 "fragment: {:?}\ninsertion: {:?}",
1785 fragment, insertion_fragment
1786 );
1787 }
1788
1789 let mut cursor = self.snapshot.fragments.cursor::<Option<&Locator>>(&None);
1790 for insertion_fragment in self.snapshot.insertions.cursor::<()>(&()) {
1791 cursor.seek(&Some(&insertion_fragment.fragment_id), Bias::Left);
1792 let fragment = cursor.item().unwrap();
1793 assert_eq!(insertion_fragment.fragment_id, fragment.id);
1794 assert_eq!(insertion_fragment.split_offset, fragment.insertion_offset);
1795 }
1796
1797 let fragment_summary = self.snapshot.fragments.summary();
1798 assert_eq!(
1799 fragment_summary.text.visible,
1800 self.snapshot.visible_text.len()
1801 );
1802 assert_eq!(
1803 fragment_summary.text.deleted,
1804 self.snapshot.deleted_text.len()
1805 );
1806
1807 assert!(!self.text().contains("\r\n"));
1808 }
1809
1810 pub fn set_group_interval(&mut self, group_interval: Duration) {
1811 self.history.group_interval = group_interval;
1812 }
1813
1814 pub fn random_byte_range(&self, start_offset: usize, rng: &mut impl rand::Rng) -> Range<usize> {
1815 let end = self.clip_offset(rng.gen_range(start_offset..=self.len()), Bias::Right);
1816 let start = self.clip_offset(rng.gen_range(start_offset..=end), Bias::Right);
1817 start..end
1818 }
1819
1820 pub fn get_random_edits<T>(
1821 &self,
1822 rng: &mut T,
1823 edit_count: usize,
1824 ) -> Vec<(Range<usize>, Arc<str>)>
1825 where
1826 T: rand::Rng,
1827 {
1828 let mut edits: Vec<(Range<usize>, Arc<str>)> = Vec::new();
1829 let mut last_end = None;
1830 for _ in 0..edit_count {
1831 if last_end.map_or(false, |last_end| last_end >= self.len()) {
1832 break;
1833 }
1834 let new_start = last_end.map_or(0, |last_end| last_end + 1);
1835 let range = self.random_byte_range(new_start, rng);
1836 last_end = Some(range.end);
1837
1838 let new_text_len = rng.gen_range(0..10);
1839 let new_text: String = RandomCharIter::new(&mut *rng).take(new_text_len).collect();
1840
1841 edits.push((range, new_text.into()));
1842 }
1843 edits
1844 }
1845
1846 pub fn randomly_edit<T>(
1847 &mut self,
1848 rng: &mut T,
1849 edit_count: usize,
1850 ) -> (Vec<(Range<usize>, Arc<str>)>, Operation)
1851 where
1852 T: rand::Rng,
1853 {
1854 let mut edits = self.get_random_edits(rng, edit_count);
1855 log::info!("mutating buffer {} with {:?}", self.replica_id, edits);
1856
1857 let op = self.edit(edits.iter().cloned());
1858 if let Operation::Edit(edit) = &op {
1859 assert_eq!(edits.len(), edit.new_text.len());
1860 for (edit, new_text) in edits.iter_mut().zip(&edit.new_text) {
1861 edit.1 = new_text.clone();
1862 }
1863 } else {
1864 unreachable!()
1865 }
1866
1867 (edits, op)
1868 }
1869
1870 pub fn randomly_undo_redo(&mut self, rng: &mut impl rand::Rng) -> Vec<Operation> {
1871 use rand::prelude::*;
1872
1873 let mut ops = Vec::new();
1874 for _ in 0..rng.gen_range(1..=5) {
1875 if let Some(entry) = self.history.undo_stack.choose(rng) {
1876 let transaction = entry.transaction.clone();
1877 log::info!(
1878 "undoing buffer {} transaction {:?}",
1879 self.replica_id,
1880 transaction
1881 );
1882 ops.push(self.undo_or_redo(transaction));
1883 }
1884 }
1885 ops
1886 }
1887}
1888
1889impl Deref for Buffer {
1890 type Target = BufferSnapshot;
1891
1892 fn deref(&self) -> &Self::Target {
1893 &self.snapshot
1894 }
1895}
1896
1897impl BufferSnapshot {
1898 pub fn as_rope(&self) -> &Rope {
1899 &self.visible_text
1900 }
1901
1902 pub fn rope_for_version(&self, version: &clock::Global) -> Rope {
1903 let mut rope = Rope::new();
1904
1905 let mut cursor = self
1906 .fragments
1907 .filter::<_, FragmentTextSummary>(&None, move |summary| {
1908 !version.observed_all(&summary.max_version)
1909 });
1910 cursor.next();
1911
1912 let mut visible_cursor = self.visible_text.cursor(0);
1913 let mut deleted_cursor = self.deleted_text.cursor(0);
1914
1915 while let Some(fragment) = cursor.item() {
1916 if cursor.start().visible > visible_cursor.offset() {
1917 let text = visible_cursor.slice(cursor.start().visible);
1918 rope.append(text);
1919 }
1920
1921 if fragment.was_visible(version, &self.undo_map) {
1922 if fragment.visible {
1923 let text = visible_cursor.slice(cursor.end().visible);
1924 rope.append(text);
1925 } else {
1926 deleted_cursor.seek_forward(cursor.start().deleted);
1927 let text = deleted_cursor.slice(cursor.end().deleted);
1928 rope.append(text);
1929 }
1930 } else if fragment.visible {
1931 visible_cursor.seek_forward(cursor.end().visible);
1932 }
1933
1934 cursor.next();
1935 }
1936
1937 if cursor.start().visible > visible_cursor.offset() {
1938 let text = visible_cursor.slice(cursor.start().visible);
1939 rope.append(text);
1940 }
1941
1942 rope
1943 }
1944
1945 pub fn remote_id(&self) -> BufferId {
1946 self.remote_id
1947 }
1948
1949 pub fn replica_id(&self) -> ReplicaId {
1950 self.replica_id
1951 }
1952
1953 pub fn row_count(&self) -> u32 {
1954 self.max_point().row + 1
1955 }
1956
1957 pub fn len(&self) -> usize {
1958 self.visible_text.len()
1959 }
1960
1961 pub fn is_empty(&self) -> bool {
1962 self.len() == 0
1963 }
1964
1965 pub fn chars(&self) -> impl Iterator<Item = char> + '_ {
1966 self.chars_at(0)
1967 }
1968
1969 pub fn chars_for_range<T: ToOffset>(&self, range: Range<T>) -> impl Iterator<Item = char> + '_ {
1970 self.text_for_range(range).flat_map(str::chars)
1971 }
1972
1973 pub fn reversed_chars_for_range<T: ToOffset>(
1974 &self,
1975 range: Range<T>,
1976 ) -> impl Iterator<Item = char> + '_ {
1977 self.reversed_chunks_in_range(range)
1978 .flat_map(|chunk| chunk.chars().rev())
1979 }
1980
1981 pub fn contains_str_at<T>(&self, position: T, needle: &str) -> bool
1982 where
1983 T: ToOffset,
1984 {
1985 let position = position.to_offset(self);
1986 position == self.clip_offset(position, Bias::Left)
1987 && self
1988 .bytes_in_range(position..self.len())
1989 .flatten()
1990 .copied()
1991 .take(needle.len())
1992 .eq(needle.bytes())
1993 }
1994
1995 pub fn common_prefix_at<T>(&self, position: T, needle: &str) -> Range<T>
1996 where
1997 T: ToOffset + TextDimension,
1998 {
1999 let offset = position.to_offset(self);
2000 let common_prefix_len = needle
2001 .char_indices()
2002 .map(|(index, _)| index)
2003 .chain([needle.len()])
2004 .take_while(|&len| len <= offset)
2005 .filter(|&len| {
2006 let left = self
2007 .chars_for_range(offset - len..offset)
2008 .flat_map(char::to_lowercase);
2009 let right = needle[..len].chars().flat_map(char::to_lowercase);
2010 left.eq(right)
2011 })
2012 .last()
2013 .unwrap_or(0);
2014 let start_offset = offset - common_prefix_len;
2015 let start = self.text_summary_for_range(0..start_offset);
2016 start..position
2017 }
2018
2019 pub fn text(&self) -> String {
2020 self.visible_text.to_string()
2021 }
2022
2023 pub fn line_ending(&self) -> LineEnding {
2024 self.line_ending
2025 }
2026
2027 pub fn deleted_text(&self) -> String {
2028 self.deleted_text.to_string()
2029 }
2030
2031 pub fn fragments(&self) -> impl Iterator<Item = &Fragment> {
2032 self.fragments.iter()
2033 }
2034
2035 pub fn text_summary(&self) -> TextSummary {
2036 self.visible_text.summary()
2037 }
2038
2039 pub fn max_point(&self) -> Point {
2040 self.visible_text.max_point()
2041 }
2042
2043 pub fn max_point_utf16(&self) -> PointUtf16 {
2044 self.visible_text.max_point_utf16()
2045 }
2046
2047 pub fn point_to_offset(&self, point: Point) -> usize {
2048 self.visible_text.point_to_offset(point)
2049 }
2050
2051 pub fn point_utf16_to_offset(&self, point: PointUtf16) -> usize {
2052 self.visible_text.point_utf16_to_offset(point)
2053 }
2054
2055 pub fn unclipped_point_utf16_to_offset(&self, point: Unclipped<PointUtf16>) -> usize {
2056 self.visible_text.unclipped_point_utf16_to_offset(point)
2057 }
2058
2059 pub fn unclipped_point_utf16_to_point(&self, point: Unclipped<PointUtf16>) -> Point {
2060 self.visible_text.unclipped_point_utf16_to_point(point)
2061 }
2062
2063 pub fn offset_utf16_to_offset(&self, offset: OffsetUtf16) -> usize {
2064 self.visible_text.offset_utf16_to_offset(offset)
2065 }
2066
2067 pub fn offset_to_offset_utf16(&self, offset: usize) -> OffsetUtf16 {
2068 self.visible_text.offset_to_offset_utf16(offset)
2069 }
2070
2071 pub fn offset_to_point(&self, offset: usize) -> Point {
2072 self.visible_text.offset_to_point(offset)
2073 }
2074
2075 pub fn offset_to_point_utf16(&self, offset: usize) -> PointUtf16 {
2076 self.visible_text.offset_to_point_utf16(offset)
2077 }
2078
2079 pub fn point_to_point_utf16(&self, point: Point) -> PointUtf16 {
2080 self.visible_text.point_to_point_utf16(point)
2081 }
2082
2083 pub fn version(&self) -> &clock::Global {
2084 &self.version
2085 }
2086
2087 pub fn chars_at<T: ToOffset>(&self, position: T) -> impl Iterator<Item = char> + '_ {
2088 let offset = position.to_offset(self);
2089 self.visible_text.chars_at(offset)
2090 }
2091
2092 pub fn reversed_chars_at<T: ToOffset>(&self, position: T) -> impl Iterator<Item = char> + '_ {
2093 let offset = position.to_offset(self);
2094 self.visible_text.reversed_chars_at(offset)
2095 }
2096
2097 pub fn reversed_chunks_in_range<T: ToOffset>(&self, range: Range<T>) -> rope::Chunks<'_> {
2098 let range = range.start.to_offset(self)..range.end.to_offset(self);
2099 self.visible_text.reversed_chunks_in_range(range)
2100 }
2101
2102 pub fn bytes_in_range<T: ToOffset>(&self, range: Range<T>) -> rope::Bytes<'_> {
2103 let start = range.start.to_offset(self);
2104 let end = range.end.to_offset(self);
2105 self.visible_text.bytes_in_range(start..end)
2106 }
2107
2108 pub fn reversed_bytes_in_range<T: ToOffset>(&self, range: Range<T>) -> rope::Bytes<'_> {
2109 let start = range.start.to_offset(self);
2110 let end = range.end.to_offset(self);
2111 self.visible_text.reversed_bytes_in_range(start..end)
2112 }
2113
2114 pub fn text_for_range<T: ToOffset>(&self, range: Range<T>) -> Chunks<'_> {
2115 let start = range.start.to_offset(self);
2116 let end = range.end.to_offset(self);
2117 self.visible_text.chunks_in_range(start..end)
2118 }
2119
2120 pub fn line_len(&self, row: u32) -> u32 {
2121 let row_start_offset = Point::new(row, 0).to_offset(self);
2122 let row_end_offset = if row >= self.max_point().row {
2123 self.len()
2124 } else {
2125 Point::new(row + 1, 0).to_offset(self) - 1
2126 };
2127 (row_end_offset - row_start_offset) as u32
2128 }
2129
2130 pub fn line_indents_in_row_range(
2131 &self,
2132 row_range: Range<u32>,
2133 ) -> impl Iterator<Item = (u32, LineIndent)> + '_ {
2134 let start = Point::new(row_range.start, 0).to_offset(self);
2135 let end = Point::new(row_range.end, self.line_len(row_range.end)).to_offset(self);
2136
2137 let mut chunks = self.as_rope().chunks_in_range(start..end);
2138 let mut row = row_range.start;
2139 let mut done = false;
2140 std::iter::from_fn(move || {
2141 if done {
2142 None
2143 } else {
2144 let indent = (row, LineIndent::from_chunks(&mut chunks));
2145 done = !chunks.next_line();
2146 row += 1;
2147 Some(indent)
2148 }
2149 })
2150 }
2151
2152 /// Returns the line indents in the given row range, exclusive of end row, in reversed order.
2153 pub fn reversed_line_indents_in_row_range(
2154 &self,
2155 row_range: Range<u32>,
2156 ) -> impl Iterator<Item = (u32, LineIndent)> + '_ {
2157 let start = Point::new(row_range.start, 0).to_offset(self);
2158
2159 let end_point;
2160 let end;
2161 if row_range.end > row_range.start {
2162 end_point = Point::new(row_range.end - 1, self.line_len(row_range.end - 1));
2163 end = end_point.to_offset(self);
2164 } else {
2165 end_point = Point::new(row_range.start, 0);
2166 end = start;
2167 };
2168
2169 let mut chunks = self.as_rope().chunks_in_range(start..end);
2170 // Move the cursor to the start of the last line if it's not empty.
2171 chunks.seek(end);
2172 if end_point.column > 0 {
2173 chunks.prev_line();
2174 }
2175
2176 let mut row = end_point.row;
2177 let mut done = false;
2178 std::iter::from_fn(move || {
2179 if done {
2180 None
2181 } else {
2182 let initial_offset = chunks.offset();
2183 let indent = (row, LineIndent::from_chunks(&mut chunks));
2184 if chunks.offset() > initial_offset {
2185 chunks.prev_line();
2186 }
2187 done = !chunks.prev_line();
2188 if !done {
2189 row -= 1;
2190 }
2191
2192 Some(indent)
2193 }
2194 })
2195 }
2196
2197 pub fn line_indent_for_row(&self, row: u32) -> LineIndent {
2198 LineIndent::from_iter(self.chars_at(Point::new(row, 0)))
2199 }
2200
2201 pub fn is_line_blank(&self, row: u32) -> bool {
2202 self.text_for_range(Point::new(row, 0)..Point::new(row, self.line_len(row)))
2203 .all(|chunk| chunk.matches(|c: char| !c.is_whitespace()).next().is_none())
2204 }
2205
2206 pub fn text_summary_for_range<D, O: ToOffset>(&self, range: Range<O>) -> D
2207 where
2208 D: TextDimension,
2209 {
2210 self.visible_text
2211 .cursor(range.start.to_offset(self))
2212 .summary(range.end.to_offset(self))
2213 }
2214
2215 pub fn summaries_for_anchors<'a, D, A>(&'a self, anchors: A) -> impl 'a + Iterator<Item = D>
2216 where
2217 D: 'a + TextDimension,
2218 A: 'a + IntoIterator<Item = &'a Anchor>,
2219 {
2220 let anchors = anchors.into_iter();
2221 self.summaries_for_anchors_with_payload::<D, _, ()>(anchors.map(|a| (a, ())))
2222 .map(|d| d.0)
2223 }
2224
2225 pub fn summaries_for_anchors_with_payload<'a, D, A, T>(
2226 &'a self,
2227 anchors: A,
2228 ) -> impl 'a + Iterator<Item = (D, T)>
2229 where
2230 D: 'a + TextDimension,
2231 A: 'a + IntoIterator<Item = (&'a Anchor, T)>,
2232 {
2233 let anchors = anchors.into_iter();
2234 let mut insertion_cursor = self.insertions.cursor::<InsertionFragmentKey>(&());
2235 let mut fragment_cursor = self.fragments.cursor::<(Option<&Locator>, usize)>(&None);
2236 let mut text_cursor = self.visible_text.cursor(0);
2237 let mut position = D::zero(&());
2238
2239 anchors.map(move |(anchor, payload)| {
2240 if *anchor == Anchor::MIN {
2241 return (D::zero(&()), payload);
2242 } else if *anchor == Anchor::MAX {
2243 return (D::from_text_summary(&self.visible_text.summary()), payload);
2244 }
2245
2246 let anchor_key = InsertionFragmentKey {
2247 timestamp: anchor.timestamp,
2248 split_offset: anchor.offset,
2249 };
2250 insertion_cursor.seek(&anchor_key, anchor.bias);
2251 if let Some(insertion) = insertion_cursor.item() {
2252 let comparison = sum_tree::KeyedItem::key(insertion).cmp(&anchor_key);
2253 if comparison == Ordering::Greater
2254 || (anchor.bias == Bias::Left
2255 && comparison == Ordering::Equal
2256 && anchor.offset > 0)
2257 {
2258 insertion_cursor.prev();
2259 }
2260 } else {
2261 insertion_cursor.prev();
2262 }
2263 let insertion = insertion_cursor.item().expect("invalid insertion");
2264 assert_eq!(insertion.timestamp, anchor.timestamp, "invalid insertion");
2265
2266 fragment_cursor.seek_forward(&Some(&insertion.fragment_id), Bias::Left);
2267 let fragment = fragment_cursor.item().unwrap();
2268 let mut fragment_offset = fragment_cursor.start().1;
2269 if fragment.visible {
2270 fragment_offset += anchor.offset - insertion.split_offset;
2271 }
2272
2273 position.add_assign(&text_cursor.summary(fragment_offset));
2274 (position, payload)
2275 })
2276 }
2277
2278 pub fn summary_for_anchor<D>(&self, anchor: &Anchor) -> D
2279 where
2280 D: TextDimension,
2281 {
2282 self.text_summary_for_range(0..self.offset_for_anchor(anchor))
2283 }
2284
2285 pub fn offset_for_anchor(&self, anchor: &Anchor) -> usize {
2286 if *anchor == Anchor::MIN {
2287 0
2288 } else if *anchor == Anchor::MAX {
2289 self.visible_text.len()
2290 } else {
2291 debug_assert!(anchor.buffer_id == Some(self.remote_id));
2292 let anchor_key = InsertionFragmentKey {
2293 timestamp: anchor.timestamp,
2294 split_offset: anchor.offset,
2295 };
2296 let mut insertion_cursor = self.insertions.cursor::<InsertionFragmentKey>(&());
2297 insertion_cursor.seek(&anchor_key, anchor.bias);
2298 if let Some(insertion) = insertion_cursor.item() {
2299 let comparison = sum_tree::KeyedItem::key(insertion).cmp(&anchor_key);
2300 if comparison == Ordering::Greater
2301 || (anchor.bias == Bias::Left
2302 && comparison == Ordering::Equal
2303 && anchor.offset > 0)
2304 {
2305 insertion_cursor.prev();
2306 }
2307 } else {
2308 insertion_cursor.prev();
2309 }
2310
2311 let Some(insertion) = insertion_cursor
2312 .item()
2313 .filter(|insertion| insertion.timestamp == anchor.timestamp)
2314 else {
2315 panic!(
2316 "invalid anchor {:?}. buffer id: {}, version: {:?}",
2317 anchor, self.remote_id, self.version
2318 );
2319 };
2320
2321 let mut fragment_cursor = self.fragments.cursor::<(Option<&Locator>, usize)>(&None);
2322 fragment_cursor.seek(&Some(&insertion.fragment_id), Bias::Left);
2323 let fragment = fragment_cursor.item().unwrap();
2324 let mut fragment_offset = fragment_cursor.start().1;
2325 if fragment.visible {
2326 fragment_offset += anchor.offset - insertion.split_offset;
2327 }
2328 fragment_offset
2329 }
2330 }
2331
2332 fn fragment_id_for_anchor(&self, anchor: &Anchor) -> &Locator {
2333 self.try_fragment_id_for_anchor(anchor).unwrap_or_else(|| {
2334 panic!(
2335 "invalid anchor {:?}. buffer id: {}, version: {:?}",
2336 anchor, self.remote_id, self.version,
2337 )
2338 })
2339 }
2340
2341 fn try_fragment_id_for_anchor(&self, anchor: &Anchor) -> Option<&Locator> {
2342 if *anchor == Anchor::MIN {
2343 Some(Locator::min_ref())
2344 } else if *anchor == Anchor::MAX {
2345 Some(Locator::max_ref())
2346 } else {
2347 let anchor_key = InsertionFragmentKey {
2348 timestamp: anchor.timestamp,
2349 split_offset: anchor.offset,
2350 };
2351 let mut insertion_cursor = self.insertions.cursor::<InsertionFragmentKey>(&());
2352 insertion_cursor.seek(&anchor_key, anchor.bias);
2353 if let Some(insertion) = insertion_cursor.item() {
2354 let comparison = sum_tree::KeyedItem::key(insertion).cmp(&anchor_key);
2355 if comparison == Ordering::Greater
2356 || (anchor.bias == Bias::Left
2357 && comparison == Ordering::Equal
2358 && anchor.offset > 0)
2359 {
2360 insertion_cursor.prev();
2361 }
2362 } else {
2363 insertion_cursor.prev();
2364 }
2365
2366 insertion_cursor
2367 .item()
2368 .filter(|insertion| {
2369 !cfg!(debug_assertions) || insertion.timestamp == anchor.timestamp
2370 })
2371 .map(|insertion| &insertion.fragment_id)
2372 }
2373 }
2374
2375 pub fn anchor_before<T: ToOffset>(&self, position: T) -> Anchor {
2376 self.anchor_at(position, Bias::Left)
2377 }
2378
2379 pub fn anchor_after<T: ToOffset>(&self, position: T) -> Anchor {
2380 self.anchor_at(position, Bias::Right)
2381 }
2382
2383 pub fn anchor_at<T: ToOffset>(&self, position: T, bias: Bias) -> Anchor {
2384 self.anchor_at_offset(position.to_offset(self), bias)
2385 }
2386
2387 fn anchor_at_offset(&self, offset: usize, bias: Bias) -> Anchor {
2388 if bias == Bias::Left && offset == 0 {
2389 Anchor::MIN
2390 } else if bias == Bias::Right && offset == self.len() {
2391 Anchor::MAX
2392 } else {
2393 let mut fragment_cursor = self.fragments.cursor::<usize>(&None);
2394 fragment_cursor.seek(&offset, bias);
2395 let fragment = fragment_cursor.item().unwrap();
2396 let overshoot = offset - *fragment_cursor.start();
2397 Anchor {
2398 timestamp: fragment.timestamp,
2399 offset: fragment.insertion_offset + overshoot,
2400 bias,
2401 buffer_id: Some(self.remote_id),
2402 }
2403 }
2404 }
2405
2406 pub fn can_resolve(&self, anchor: &Anchor) -> bool {
2407 *anchor == Anchor::MIN
2408 || *anchor == Anchor::MAX
2409 || (Some(self.remote_id) == anchor.buffer_id && self.version.observed(anchor.timestamp))
2410 }
2411
2412 pub fn clip_offset(&self, offset: usize, bias: Bias) -> usize {
2413 self.visible_text.clip_offset(offset, bias)
2414 }
2415
2416 pub fn clip_point(&self, point: Point, bias: Bias) -> Point {
2417 self.visible_text.clip_point(point, bias)
2418 }
2419
2420 pub fn clip_offset_utf16(&self, offset: OffsetUtf16, bias: Bias) -> OffsetUtf16 {
2421 self.visible_text.clip_offset_utf16(offset, bias)
2422 }
2423
2424 pub fn clip_point_utf16(&self, point: Unclipped<PointUtf16>, bias: Bias) -> PointUtf16 {
2425 self.visible_text.clip_point_utf16(point, bias)
2426 }
2427
2428 pub fn edits_since<'a, D>(
2429 &'a self,
2430 since: &'a clock::Global,
2431 ) -> impl 'a + Iterator<Item = Edit<D>>
2432 where
2433 D: TextDimension + Ord,
2434 {
2435 self.edits_since_in_range(since, Anchor::MIN..Anchor::MAX)
2436 }
2437
2438 pub fn anchored_edits_since<'a, D>(
2439 &'a self,
2440 since: &'a clock::Global,
2441 ) -> impl 'a + Iterator<Item = (Edit<D>, Range<Anchor>)>
2442 where
2443 D: TextDimension + Ord,
2444 {
2445 self.anchored_edits_since_in_range(since, Anchor::MIN..Anchor::MAX)
2446 }
2447
2448 pub fn edits_since_in_range<'a, D>(
2449 &'a self,
2450 since: &'a clock::Global,
2451 range: Range<Anchor>,
2452 ) -> impl 'a + Iterator<Item = Edit<D>>
2453 where
2454 D: TextDimension + Ord,
2455 {
2456 self.anchored_edits_since_in_range(since, range)
2457 .map(|item| item.0)
2458 }
2459
2460 pub fn anchored_edits_since_in_range<'a, D>(
2461 &'a self,
2462 since: &'a clock::Global,
2463 range: Range<Anchor>,
2464 ) -> impl 'a + Iterator<Item = (Edit<D>, Range<Anchor>)>
2465 where
2466 D: TextDimension + Ord,
2467 {
2468 let fragments_cursor = if *since == self.version {
2469 None
2470 } else {
2471 let mut cursor = self.fragments.filter(&None, move |summary| {
2472 !since.observed_all(&summary.max_version)
2473 });
2474 cursor.next();
2475 Some(cursor)
2476 };
2477 let mut cursor = self
2478 .fragments
2479 .cursor::<(Option<&Locator>, FragmentTextSummary)>(&None);
2480
2481 let start_fragment_id = self.fragment_id_for_anchor(&range.start);
2482 cursor.seek(&Some(start_fragment_id), Bias::Left);
2483 let mut visible_start = cursor.start().1.visible;
2484 let mut deleted_start = cursor.start().1.deleted;
2485 if let Some(fragment) = cursor.item() {
2486 let overshoot = range.start.offset - fragment.insertion_offset;
2487 if fragment.visible {
2488 visible_start += overshoot;
2489 } else {
2490 deleted_start += overshoot;
2491 }
2492 }
2493 let end_fragment_id = self.fragment_id_for_anchor(&range.end);
2494
2495 Edits {
2496 visible_cursor: self.visible_text.cursor(visible_start),
2497 deleted_cursor: self.deleted_text.cursor(deleted_start),
2498 fragments_cursor,
2499 undos: &self.undo_map,
2500 since,
2501 old_end: D::zero(&()),
2502 new_end: D::zero(&()),
2503 range: (start_fragment_id, range.start.offset)..(end_fragment_id, range.end.offset),
2504 buffer_id: self.remote_id,
2505 }
2506 }
2507
2508 pub fn has_edits_since_in_range(&self, since: &clock::Global, range: Range<Anchor>) -> bool {
2509 if *since != self.version {
2510 let start_fragment_id = self.fragment_id_for_anchor(&range.start);
2511 let end_fragment_id = self.fragment_id_for_anchor(&range.end);
2512 let mut cursor = self.fragments.filter::<_, usize>(&None, move |summary| {
2513 !since.observed_all(&summary.max_version)
2514 });
2515 cursor.next();
2516 while let Some(fragment) = cursor.item() {
2517 if fragment.id > *end_fragment_id {
2518 break;
2519 }
2520 if fragment.id > *start_fragment_id {
2521 let was_visible = fragment.was_visible(since, &self.undo_map);
2522 let is_visible = fragment.visible;
2523 if was_visible != is_visible {
2524 return true;
2525 }
2526 }
2527 cursor.next();
2528 }
2529 }
2530 false
2531 }
2532
2533 pub fn has_edits_since(&self, since: &clock::Global) -> bool {
2534 if *since != self.version {
2535 let mut cursor = self.fragments.filter::<_, usize>(&None, move |summary| {
2536 !since.observed_all(&summary.max_version)
2537 });
2538 cursor.next();
2539 while let Some(fragment) = cursor.item() {
2540 let was_visible = fragment.was_visible(since, &self.undo_map);
2541 let is_visible = fragment.visible;
2542 if was_visible != is_visible {
2543 return true;
2544 }
2545 cursor.next();
2546 }
2547 }
2548 false
2549 }
2550
2551 pub fn range_to_version(&self, range: Range<usize>, version: &clock::Global) -> Range<usize> {
2552 let mut offsets = self.offsets_to_version([range.start, range.end], version);
2553 offsets.next().unwrap()..offsets.next().unwrap()
2554 }
2555
2556 /// Converts the given sequence of offsets into their corresponding offsets
2557 /// at a prior version of this buffer.
2558 pub fn offsets_to_version<'a>(
2559 &'a self,
2560 offsets: impl 'a + IntoIterator<Item = usize>,
2561 version: &'a clock::Global,
2562 ) -> impl 'a + Iterator<Item = usize> {
2563 let mut edits = self.edits_since(version).peekable();
2564 let mut last_old_end = 0;
2565 let mut last_new_end = 0;
2566 offsets.into_iter().map(move |new_offset| {
2567 while let Some(edit) = edits.peek() {
2568 if edit.new.start > new_offset {
2569 break;
2570 }
2571
2572 if edit.new.end <= new_offset {
2573 last_new_end = edit.new.end;
2574 last_old_end = edit.old.end;
2575 edits.next();
2576 continue;
2577 }
2578
2579 let overshoot = new_offset - edit.new.start;
2580 return (edit.old.start + overshoot).min(edit.old.end);
2581 }
2582
2583 last_old_end + new_offset.saturating_sub(last_new_end)
2584 })
2585 }
2586}
2587
2588struct RopeBuilder<'a> {
2589 old_visible_cursor: rope::Cursor<'a>,
2590 old_deleted_cursor: rope::Cursor<'a>,
2591 new_visible: Rope,
2592 new_deleted: Rope,
2593}
2594
2595impl<'a> RopeBuilder<'a> {
2596 fn new(old_visible_cursor: rope::Cursor<'a>, old_deleted_cursor: rope::Cursor<'a>) -> Self {
2597 Self {
2598 old_visible_cursor,
2599 old_deleted_cursor,
2600 new_visible: Rope::new(),
2601 new_deleted: Rope::new(),
2602 }
2603 }
2604
2605 fn append(&mut self, len: FragmentTextSummary) {
2606 self.push(len.visible, true, true);
2607 self.push(len.deleted, false, false);
2608 }
2609
2610 fn push_fragment(&mut self, fragment: &Fragment, was_visible: bool) {
2611 debug_assert!(fragment.len > 0);
2612 self.push(fragment.len, was_visible, fragment.visible)
2613 }
2614
2615 fn push(&mut self, len: usize, was_visible: bool, is_visible: bool) {
2616 let text = if was_visible {
2617 self.old_visible_cursor
2618 .slice(self.old_visible_cursor.offset() + len)
2619 } else {
2620 self.old_deleted_cursor
2621 .slice(self.old_deleted_cursor.offset() + len)
2622 };
2623 if is_visible {
2624 self.new_visible.append(text);
2625 } else {
2626 self.new_deleted.append(text);
2627 }
2628 }
2629
2630 fn push_str(&mut self, text: &str) {
2631 self.new_visible.push(text);
2632 }
2633
2634 fn finish(mut self) -> (Rope, Rope) {
2635 self.new_visible.append(self.old_visible_cursor.suffix());
2636 self.new_deleted.append(self.old_deleted_cursor.suffix());
2637 (self.new_visible, self.new_deleted)
2638 }
2639}
2640
2641impl<D: TextDimension + Ord, F: FnMut(&FragmentSummary) -> bool> Iterator for Edits<'_, D, F> {
2642 type Item = (Edit<D>, Range<Anchor>);
2643
2644 fn next(&mut self) -> Option<Self::Item> {
2645 let mut pending_edit: Option<Self::Item> = None;
2646 let cursor = self.fragments_cursor.as_mut()?;
2647
2648 while let Some(fragment) = cursor.item() {
2649 if fragment.id < *self.range.start.0 {
2650 cursor.next();
2651 continue;
2652 } else if fragment.id > *self.range.end.0 {
2653 break;
2654 }
2655
2656 if cursor.start().visible > self.visible_cursor.offset() {
2657 let summary = self.visible_cursor.summary(cursor.start().visible);
2658 self.old_end.add_assign(&summary);
2659 self.new_end.add_assign(&summary);
2660 }
2661
2662 if pending_edit
2663 .as_ref()
2664 .map_or(false, |(change, _)| change.new.end < self.new_end)
2665 {
2666 break;
2667 }
2668
2669 let start_anchor = Anchor {
2670 timestamp: fragment.timestamp,
2671 offset: fragment.insertion_offset,
2672 bias: Bias::Right,
2673 buffer_id: Some(self.buffer_id),
2674 };
2675 let end_anchor = Anchor {
2676 timestamp: fragment.timestamp,
2677 offset: fragment.insertion_offset + fragment.len,
2678 bias: Bias::Left,
2679 buffer_id: Some(self.buffer_id),
2680 };
2681
2682 if !fragment.was_visible(self.since, self.undos) && fragment.visible {
2683 let mut visible_end = cursor.end().visible;
2684 if fragment.id == *self.range.end.0 {
2685 visible_end = cmp::min(
2686 visible_end,
2687 cursor.start().visible + (self.range.end.1 - fragment.insertion_offset),
2688 );
2689 }
2690
2691 let fragment_summary = self.visible_cursor.summary(visible_end);
2692 let mut new_end = self.new_end;
2693 new_end.add_assign(&fragment_summary);
2694 if let Some((edit, range)) = pending_edit.as_mut() {
2695 edit.new.end = new_end;
2696 range.end = end_anchor;
2697 } else {
2698 pending_edit = Some((
2699 Edit {
2700 old: self.old_end..self.old_end,
2701 new: self.new_end..new_end,
2702 },
2703 start_anchor..end_anchor,
2704 ));
2705 }
2706
2707 self.new_end = new_end;
2708 } else if fragment.was_visible(self.since, self.undos) && !fragment.visible {
2709 let mut deleted_end = cursor.end().deleted;
2710 if fragment.id == *self.range.end.0 {
2711 deleted_end = cmp::min(
2712 deleted_end,
2713 cursor.start().deleted + (self.range.end.1 - fragment.insertion_offset),
2714 );
2715 }
2716
2717 if cursor.start().deleted > self.deleted_cursor.offset() {
2718 self.deleted_cursor.seek_forward(cursor.start().deleted);
2719 }
2720 let fragment_summary = self.deleted_cursor.summary(deleted_end);
2721 let mut old_end = self.old_end;
2722 old_end.add_assign(&fragment_summary);
2723 if let Some((edit, range)) = pending_edit.as_mut() {
2724 edit.old.end = old_end;
2725 range.end = end_anchor;
2726 } else {
2727 pending_edit = Some((
2728 Edit {
2729 old: self.old_end..old_end,
2730 new: self.new_end..self.new_end,
2731 },
2732 start_anchor..end_anchor,
2733 ));
2734 }
2735
2736 self.old_end = old_end;
2737 }
2738
2739 cursor.next();
2740 }
2741
2742 pending_edit
2743 }
2744}
2745
2746impl Fragment {
2747 fn is_visible(&self, undos: &UndoMap) -> bool {
2748 !undos.is_undone(self.timestamp) && self.deletions.iter().all(|d| undos.is_undone(*d))
2749 }
2750
2751 fn was_visible(&self, version: &clock::Global, undos: &UndoMap) -> bool {
2752 (version.observed(self.timestamp) && !undos.was_undone(self.timestamp, version))
2753 && self
2754 .deletions
2755 .iter()
2756 .all(|d| !version.observed(*d) || undos.was_undone(*d, version))
2757 }
2758}
2759
2760impl sum_tree::Item for Fragment {
2761 type Summary = FragmentSummary;
2762
2763 fn summary(&self, _cx: &Option<clock::Global>) -> Self::Summary {
2764 let mut max_version = clock::Global::new();
2765 max_version.observe(self.timestamp);
2766 for deletion in &self.deletions {
2767 max_version.observe(*deletion);
2768 }
2769 max_version.join(&self.max_undos);
2770
2771 let mut min_insertion_version = clock::Global::new();
2772 min_insertion_version.observe(self.timestamp);
2773 let max_insertion_version = min_insertion_version.clone();
2774 if self.visible {
2775 FragmentSummary {
2776 max_id: self.id.clone(),
2777 text: FragmentTextSummary {
2778 visible: self.len,
2779 deleted: 0,
2780 },
2781 max_version,
2782 min_insertion_version,
2783 max_insertion_version,
2784 }
2785 } else {
2786 FragmentSummary {
2787 max_id: self.id.clone(),
2788 text: FragmentTextSummary {
2789 visible: 0,
2790 deleted: self.len,
2791 },
2792 max_version,
2793 min_insertion_version,
2794 max_insertion_version,
2795 }
2796 }
2797 }
2798}
2799
2800impl sum_tree::Summary for FragmentSummary {
2801 type Context = Option<clock::Global>;
2802
2803 fn zero(_cx: &Self::Context) -> Self {
2804 Default::default()
2805 }
2806
2807 fn add_summary(&mut self, other: &Self, _: &Self::Context) {
2808 self.max_id.assign(&other.max_id);
2809 self.text.visible += &other.text.visible;
2810 self.text.deleted += &other.text.deleted;
2811 self.max_version.join(&other.max_version);
2812 self.min_insertion_version
2813 .meet(&other.min_insertion_version);
2814 self.max_insertion_version
2815 .join(&other.max_insertion_version);
2816 }
2817}
2818
2819impl Default for FragmentSummary {
2820 fn default() -> Self {
2821 FragmentSummary {
2822 max_id: Locator::min(),
2823 text: FragmentTextSummary::default(),
2824 max_version: clock::Global::new(),
2825 min_insertion_version: clock::Global::new(),
2826 max_insertion_version: clock::Global::new(),
2827 }
2828 }
2829}
2830
2831impl sum_tree::Item for InsertionFragment {
2832 type Summary = InsertionFragmentKey;
2833
2834 fn summary(&self, _cx: &()) -> Self::Summary {
2835 InsertionFragmentKey {
2836 timestamp: self.timestamp,
2837 split_offset: self.split_offset,
2838 }
2839 }
2840}
2841
2842impl sum_tree::KeyedItem for InsertionFragment {
2843 type Key = InsertionFragmentKey;
2844
2845 fn key(&self) -> Self::Key {
2846 sum_tree::Item::summary(self, &())
2847 }
2848}
2849
2850impl InsertionFragment {
2851 fn new(fragment: &Fragment) -> Self {
2852 Self {
2853 timestamp: fragment.timestamp,
2854 split_offset: fragment.insertion_offset,
2855 fragment_id: fragment.id.clone(),
2856 }
2857 }
2858
2859 fn insert_new(fragment: &Fragment) -> sum_tree::Edit<Self> {
2860 sum_tree::Edit::Insert(Self::new(fragment))
2861 }
2862}
2863
2864impl sum_tree::Summary for InsertionFragmentKey {
2865 type Context = ();
2866
2867 fn zero(_cx: &()) -> Self {
2868 Default::default()
2869 }
2870
2871 fn add_summary(&mut self, summary: &Self, _: &()) {
2872 *self = *summary;
2873 }
2874}
2875
2876#[derive(Copy, Clone, Debug, Default, PartialEq, Eq, PartialOrd, Ord, Hash)]
2877pub struct FullOffset(pub usize);
2878
2879impl ops::AddAssign<usize> for FullOffset {
2880 fn add_assign(&mut self, rhs: usize) {
2881 self.0 += rhs;
2882 }
2883}
2884
2885impl ops::Add<usize> for FullOffset {
2886 type Output = Self;
2887
2888 fn add(mut self, rhs: usize) -> Self::Output {
2889 self += rhs;
2890 self
2891 }
2892}
2893
2894impl ops::Sub for FullOffset {
2895 type Output = usize;
2896
2897 fn sub(self, rhs: Self) -> Self::Output {
2898 self.0 - rhs.0
2899 }
2900}
2901
2902impl sum_tree::Dimension<'_, FragmentSummary> for usize {
2903 fn zero(_: &Option<clock::Global>) -> Self {
2904 Default::default()
2905 }
2906
2907 fn add_summary(&mut self, summary: &FragmentSummary, _: &Option<clock::Global>) {
2908 *self += summary.text.visible;
2909 }
2910}
2911
2912impl sum_tree::Dimension<'_, FragmentSummary> for FullOffset {
2913 fn zero(_: &Option<clock::Global>) -> Self {
2914 Default::default()
2915 }
2916
2917 fn add_summary(&mut self, summary: &FragmentSummary, _: &Option<clock::Global>) {
2918 self.0 += summary.text.visible + summary.text.deleted;
2919 }
2920}
2921
2922impl<'a> sum_tree::Dimension<'a, FragmentSummary> for Option<&'a Locator> {
2923 fn zero(_: &Option<clock::Global>) -> Self {
2924 Default::default()
2925 }
2926
2927 fn add_summary(&mut self, summary: &'a FragmentSummary, _: &Option<clock::Global>) {
2928 *self = Some(&summary.max_id);
2929 }
2930}
2931
2932impl sum_tree::SeekTarget<'_, FragmentSummary, FragmentTextSummary> for usize {
2933 fn cmp(
2934 &self,
2935 cursor_location: &FragmentTextSummary,
2936 _: &Option<clock::Global>,
2937 ) -> cmp::Ordering {
2938 Ord::cmp(self, &cursor_location.visible)
2939 }
2940}
2941
2942#[derive(Copy, Clone, Debug, Eq, PartialEq)]
2943enum VersionedFullOffset {
2944 Offset(FullOffset),
2945 Invalid,
2946}
2947
2948impl VersionedFullOffset {
2949 fn full_offset(&self) -> FullOffset {
2950 if let Self::Offset(position) = self {
2951 *position
2952 } else {
2953 panic!("invalid version")
2954 }
2955 }
2956}
2957
2958impl Default for VersionedFullOffset {
2959 fn default() -> Self {
2960 Self::Offset(Default::default())
2961 }
2962}
2963
2964impl<'a> sum_tree::Dimension<'a, FragmentSummary> for VersionedFullOffset {
2965 fn zero(_cx: &Option<clock::Global>) -> Self {
2966 Default::default()
2967 }
2968
2969 fn add_summary(&mut self, summary: &'a FragmentSummary, cx: &Option<clock::Global>) {
2970 if let Self::Offset(offset) = self {
2971 let version = cx.as_ref().unwrap();
2972 if version.observed_all(&summary.max_insertion_version) {
2973 *offset += summary.text.visible + summary.text.deleted;
2974 } else if version.observed_any(&summary.min_insertion_version) {
2975 *self = Self::Invalid;
2976 }
2977 }
2978 }
2979}
2980
2981impl sum_tree::SeekTarget<'_, FragmentSummary, Self> for VersionedFullOffset {
2982 fn cmp(&self, cursor_position: &Self, _: &Option<clock::Global>) -> cmp::Ordering {
2983 match (self, cursor_position) {
2984 (Self::Offset(a), Self::Offset(b)) => Ord::cmp(a, b),
2985 (Self::Offset(_), Self::Invalid) => cmp::Ordering::Less,
2986 (Self::Invalid, _) => unreachable!(),
2987 }
2988 }
2989}
2990
2991impl Operation {
2992 fn replica_id(&self) -> ReplicaId {
2993 operation_queue::Operation::lamport_timestamp(self).replica_id
2994 }
2995
2996 pub fn timestamp(&self) -> clock::Lamport {
2997 match self {
2998 Operation::Edit(edit) => edit.timestamp,
2999 Operation::Undo(undo) => undo.timestamp,
3000 }
3001 }
3002
3003 pub fn as_edit(&self) -> Option<&EditOperation> {
3004 match self {
3005 Operation::Edit(edit) => Some(edit),
3006 _ => None,
3007 }
3008 }
3009
3010 pub fn is_edit(&self) -> bool {
3011 matches!(self, Operation::Edit { .. })
3012 }
3013}
3014
3015impl operation_queue::Operation for Operation {
3016 fn lamport_timestamp(&self) -> clock::Lamport {
3017 match self {
3018 Operation::Edit(edit) => edit.timestamp,
3019 Operation::Undo(undo) => undo.timestamp,
3020 }
3021 }
3022}
3023
3024pub trait ToOffset {
3025 fn to_offset(&self, snapshot: &BufferSnapshot) -> usize;
3026}
3027
3028impl ToOffset for Point {
3029 fn to_offset(&self, snapshot: &BufferSnapshot) -> usize {
3030 snapshot.point_to_offset(*self)
3031 }
3032}
3033
3034impl ToOffset for usize {
3035 #[track_caller]
3036 fn to_offset(&self, snapshot: &BufferSnapshot) -> usize {
3037 assert!(
3038 *self <= snapshot.len(),
3039 "offset {} is out of range, max allowed is {}",
3040 self,
3041 snapshot.len()
3042 );
3043 *self
3044 }
3045}
3046
3047impl ToOffset for Anchor {
3048 fn to_offset(&self, snapshot: &BufferSnapshot) -> usize {
3049 snapshot.summary_for_anchor(self)
3050 }
3051}
3052
3053impl<T: ToOffset> ToOffset for &T {
3054 fn to_offset(&self, content: &BufferSnapshot) -> usize {
3055 (*self).to_offset(content)
3056 }
3057}
3058
3059impl ToOffset for PointUtf16 {
3060 fn to_offset(&self, snapshot: &BufferSnapshot) -> usize {
3061 snapshot.point_utf16_to_offset(*self)
3062 }
3063}
3064
3065impl ToOffset for Unclipped<PointUtf16> {
3066 fn to_offset(&self, snapshot: &BufferSnapshot) -> usize {
3067 snapshot.unclipped_point_utf16_to_offset(*self)
3068 }
3069}
3070
3071pub trait ToPoint {
3072 fn to_point(&self, snapshot: &BufferSnapshot) -> Point;
3073}
3074
3075impl ToPoint for Anchor {
3076 fn to_point(&self, snapshot: &BufferSnapshot) -> Point {
3077 snapshot.summary_for_anchor(self)
3078 }
3079}
3080
3081impl ToPoint for usize {
3082 fn to_point(&self, snapshot: &BufferSnapshot) -> Point {
3083 snapshot.offset_to_point(*self)
3084 }
3085}
3086
3087impl ToPoint for Point {
3088 fn to_point(&self, _: &BufferSnapshot) -> Point {
3089 *self
3090 }
3091}
3092
3093impl ToPoint for Unclipped<PointUtf16> {
3094 fn to_point(&self, snapshot: &BufferSnapshot) -> Point {
3095 snapshot.unclipped_point_utf16_to_point(*self)
3096 }
3097}
3098
3099pub trait ToPointUtf16 {
3100 fn to_point_utf16(&self, snapshot: &BufferSnapshot) -> PointUtf16;
3101}
3102
3103impl ToPointUtf16 for Anchor {
3104 fn to_point_utf16(&self, snapshot: &BufferSnapshot) -> PointUtf16 {
3105 snapshot.summary_for_anchor(self)
3106 }
3107}
3108
3109impl ToPointUtf16 for usize {
3110 fn to_point_utf16(&self, snapshot: &BufferSnapshot) -> PointUtf16 {
3111 snapshot.offset_to_point_utf16(*self)
3112 }
3113}
3114
3115impl ToPointUtf16 for PointUtf16 {
3116 fn to_point_utf16(&self, _: &BufferSnapshot) -> PointUtf16 {
3117 *self
3118 }
3119}
3120
3121impl ToPointUtf16 for Point {
3122 fn to_point_utf16(&self, snapshot: &BufferSnapshot) -> PointUtf16 {
3123 snapshot.point_to_point_utf16(*self)
3124 }
3125}
3126
3127pub trait ToOffsetUtf16 {
3128 fn to_offset_utf16(&self, snapshot: &BufferSnapshot) -> OffsetUtf16;
3129}
3130
3131impl ToOffsetUtf16 for Anchor {
3132 fn to_offset_utf16(&self, snapshot: &BufferSnapshot) -> OffsetUtf16 {
3133 snapshot.summary_for_anchor(self)
3134 }
3135}
3136
3137impl ToOffsetUtf16 for usize {
3138 fn to_offset_utf16(&self, snapshot: &BufferSnapshot) -> OffsetUtf16 {
3139 snapshot.offset_to_offset_utf16(*self)
3140 }
3141}
3142
3143impl ToOffsetUtf16 for OffsetUtf16 {
3144 fn to_offset_utf16(&self, _snapshot: &BufferSnapshot) -> OffsetUtf16 {
3145 *self
3146 }
3147}
3148
3149pub trait FromAnchor {
3150 fn from_anchor(anchor: &Anchor, snapshot: &BufferSnapshot) -> Self;
3151}
3152
3153impl FromAnchor for Anchor {
3154 fn from_anchor(anchor: &Anchor, _snapshot: &BufferSnapshot) -> Self {
3155 *anchor
3156 }
3157}
3158
3159impl FromAnchor for Point {
3160 fn from_anchor(anchor: &Anchor, snapshot: &BufferSnapshot) -> Self {
3161 snapshot.summary_for_anchor(anchor)
3162 }
3163}
3164
3165impl FromAnchor for PointUtf16 {
3166 fn from_anchor(anchor: &Anchor, snapshot: &BufferSnapshot) -> Self {
3167 snapshot.summary_for_anchor(anchor)
3168 }
3169}
3170
3171impl FromAnchor for usize {
3172 fn from_anchor(anchor: &Anchor, snapshot: &BufferSnapshot) -> Self {
3173 snapshot.summary_for_anchor(anchor)
3174 }
3175}
3176
3177#[derive(Clone, Copy, Debug, PartialEq)]
3178pub enum LineEnding {
3179 Unix,
3180 Windows,
3181}
3182
3183impl Default for LineEnding {
3184 fn default() -> Self {
3185 #[cfg(unix)]
3186 return Self::Unix;
3187
3188 #[cfg(not(unix))]
3189 return Self::Windows;
3190 }
3191}
3192
3193impl LineEnding {
3194 pub fn as_str(&self) -> &'static str {
3195 match self {
3196 LineEnding::Unix => "\n",
3197 LineEnding::Windows => "\r\n",
3198 }
3199 }
3200
3201 pub fn detect(text: &str) -> Self {
3202 let mut max_ix = cmp::min(text.len(), 1000);
3203 while !text.is_char_boundary(max_ix) {
3204 max_ix -= 1;
3205 }
3206
3207 if let Some(ix) = text[..max_ix].find(['\n']) {
3208 if ix > 0 && text.as_bytes()[ix - 1] == b'\r' {
3209 Self::Windows
3210 } else {
3211 Self::Unix
3212 }
3213 } else {
3214 Self::default()
3215 }
3216 }
3217
3218 pub fn normalize(text: &mut String) {
3219 if let Cow::Owned(replaced) = LINE_SEPARATORS_REGEX.replace_all(text, "\n") {
3220 *text = replaced;
3221 }
3222 }
3223
3224 pub fn normalize_arc(text: Arc<str>) -> Arc<str> {
3225 if let Cow::Owned(replaced) = LINE_SEPARATORS_REGEX.replace_all(&text, "\n") {
3226 replaced.into()
3227 } else {
3228 text
3229 }
3230 }
3231
3232 pub fn normalize_cow(text: Cow<str>) -> Cow<str> {
3233 if let Cow::Owned(replaced) = LINE_SEPARATORS_REGEX.replace_all(&text, "\n") {
3234 replaced.into()
3235 } else {
3236 text
3237 }
3238 }
3239}