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