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 = 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 = (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, 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 != 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 /// todo!() this name seems misleading
2513 pub fn anchor_range_around<T: ToOffset>(&self, position: Range<T>) -> Range<Anchor> {
2514 self.anchor_after(position.start)..self.anchor_before(position.end)
2515 }
2516
2517 /// Returns an anchor range for the given input position range that is anchored to the text before and after.
2518 /// todo!() this name seems misleading
2519 pub fn anchor_range_between<T: ToOffset>(&self, position: Range<T>) -> Range<Anchor> {
2520 self.anchor_before(position.start)..self.anchor_after(position.end)
2521 }
2522
2523 /// Returns an anchor for the given input position that is anchored to the text before the position.
2524 pub fn anchor_before<T: ToOffset>(&self, position: T) -> Anchor {
2525 self.anchor_at(position, Bias::Left)
2526 }
2527
2528 /// Returns an anchor for the given input position that is anchored to the text after the position.
2529 pub fn anchor_after<T: ToOffset>(&self, position: T) -> Anchor {
2530 self.anchor_at(position, Bias::Right)
2531 }
2532
2533 pub fn anchor_at<T: ToOffset>(&self, position: T, bias: Bias) -> Anchor {
2534 self.anchor_at_offset(position.to_offset(self), bias)
2535 }
2536
2537 fn anchor_at_offset(&self, mut offset: usize, bias: Bias) -> Anchor {
2538 if bias == Bias::Left && offset == 0 {
2539 Anchor::min_for_buffer(self.remote_id)
2540 } else if bias == Bias::Right
2541 && ((!cfg!(debug_assertions) && offset >= self.len()) || offset == self.len())
2542 {
2543 Anchor::max_for_buffer(self.remote_id)
2544 } else {
2545 if !self
2546 .visible_text
2547 .assert_char_boundary::<{ cfg!(debug_assertions) }>(offset)
2548 {
2549 offset = match bias {
2550 Bias::Left => self.visible_text.floor_char_boundary(offset),
2551 Bias::Right => self.visible_text.ceil_char_boundary(offset),
2552 };
2553 }
2554 let (start, _, item) = self.fragments.find::<usize, _>(&None, &offset, bias);
2555 let Some(fragment) = item else {
2556 // We got a bad offset, likely out of bounds
2557 debug_panic!(
2558 "Failed to find fragment at offset {} (len: {})",
2559 offset,
2560 self.len()
2561 );
2562 return Anchor::max_for_buffer(self.remote_id);
2563 };
2564 let overshoot = offset - start;
2565 Anchor::new(
2566 fragment.timestamp,
2567 fragment.insertion_offset + overshoot as u32,
2568 bias,
2569 self.remote_id,
2570 )
2571 }
2572 }
2573
2574 pub fn can_resolve(&self, anchor: &Anchor) -> bool {
2575 anchor.is_min()
2576 || anchor.is_max()
2577 || (self.remote_id == anchor.buffer_id && self.version.observed(anchor.timestamp()))
2578 }
2579
2580 pub fn clip_offset(&self, offset: usize, bias: Bias) -> usize {
2581 self.visible_text.clip_offset(offset, bias)
2582 }
2583
2584 pub fn clip_point(&self, point: Point, bias: Bias) -> Point {
2585 self.visible_text.clip_point(point, bias)
2586 }
2587
2588 pub fn clip_offset_utf16(&self, offset: OffsetUtf16, bias: Bias) -> OffsetUtf16 {
2589 self.visible_text.clip_offset_utf16(offset, bias)
2590 }
2591
2592 pub fn clip_point_utf16(&self, point: Unclipped<PointUtf16>, bias: Bias) -> PointUtf16 {
2593 self.visible_text.clip_point_utf16(point, bias)
2594 }
2595
2596 pub fn edits_since<'a, D>(
2597 &'a self,
2598 since: &'a clock::Global,
2599 ) -> impl 'a + Iterator<Item = Edit<D>>
2600 where
2601 D: TextDimension + Ord,
2602 {
2603 self.edits_since_in_range(
2604 since,
2605 Anchor::min_for_buffer(self.remote_id)..Anchor::max_for_buffer(self.remote_id),
2606 )
2607 }
2608
2609 pub fn anchored_edits_since<'a, D>(
2610 &'a self,
2611 since: &'a clock::Global,
2612 ) -> impl 'a + Iterator<Item = (Edit<D>, Range<Anchor>)>
2613 where
2614 D: TextDimension + Ord,
2615 {
2616 self.anchored_edits_since_in_range(
2617 since,
2618 Anchor::min_for_buffer(self.remote_id)..Anchor::max_for_buffer(self.remote_id),
2619 )
2620 }
2621
2622 pub fn edits_since_in_range<'a, D>(
2623 &'a self,
2624 since: &'a clock::Global,
2625 range: Range<Anchor>,
2626 ) -> impl 'a + Iterator<Item = Edit<D>>
2627 where
2628 D: TextDimension + Ord,
2629 {
2630 self.anchored_edits_since_in_range(since, range)
2631 .map(|item| item.0)
2632 }
2633
2634 pub fn anchored_edits_since_in_range<'a, D>(
2635 &'a self,
2636 since: &'a clock::Global,
2637 range: Range<Anchor>,
2638 ) -> impl 'a + Iterator<Item = (Edit<D>, Range<Anchor>)>
2639 where
2640 D: TextDimension + Ord,
2641 {
2642 if *since == self.version {
2643 return None.into_iter().flatten();
2644 }
2645 let mut cursor = self.fragments.filter(&None, move |summary| {
2646 !since.observed_all(&summary.max_version)
2647 });
2648 cursor.next();
2649 let fragments_cursor = Some(cursor);
2650 let start_fragment_id = self.fragment_id_for_anchor(&range.start);
2651 let (start, _, item) = self
2652 .fragments
2653 .find::<Dimensions<Option<&Locator>, FragmentTextSummary>, _>(
2654 &None,
2655 &Some(start_fragment_id),
2656 Bias::Left,
2657 );
2658 let mut visible_start = start.1.visible;
2659 let mut deleted_start = start.1.deleted;
2660 if let Some(fragment) = item {
2661 let overshoot = (range.start.offset - fragment.insertion_offset) as usize;
2662 if fragment.visible {
2663 visible_start += overshoot;
2664 } else {
2665 deleted_start += overshoot;
2666 }
2667 }
2668 let end_fragment_id = self.fragment_id_for_anchor(&range.end);
2669
2670 Some(Edits {
2671 visible_cursor: self.visible_text.cursor(visible_start),
2672 deleted_cursor: self.deleted_text.cursor(deleted_start),
2673 fragments_cursor,
2674 undos: &self.undo_map,
2675 since,
2676 old_end: D::zero(()),
2677 new_end: D::zero(()),
2678 range: (start_fragment_id, range.start.offset)..(end_fragment_id, range.end.offset),
2679 buffer_id: self.remote_id,
2680 })
2681 .into_iter()
2682 .flatten()
2683 }
2684
2685 pub fn has_edits_since_in_range(&self, since: &clock::Global, range: Range<Anchor>) -> bool {
2686 if *since != self.version {
2687 let start_fragment_id = self.fragment_id_for_anchor(&range.start);
2688 let end_fragment_id = self.fragment_id_for_anchor(&range.end);
2689 let mut cursor = self.fragments.filter::<_, usize>(&None, move |summary| {
2690 !since.observed_all(&summary.max_version)
2691 });
2692 cursor.next();
2693 while let Some(fragment) = cursor.item() {
2694 if fragment.id > *end_fragment_id {
2695 break;
2696 }
2697 if fragment.id > *start_fragment_id {
2698 let was_visible = fragment.was_visible(since, &self.undo_map);
2699 let is_visible = fragment.visible;
2700 if was_visible != is_visible {
2701 return true;
2702 }
2703 }
2704 cursor.next();
2705 }
2706 }
2707 false
2708 }
2709
2710 pub fn has_edits_since(&self, since: &clock::Global) -> bool {
2711 if *since != self.version {
2712 let mut cursor = self.fragments.filter::<_, usize>(&None, move |summary| {
2713 !since.observed_all(&summary.max_version)
2714 });
2715 cursor.next();
2716 while let Some(fragment) = cursor.item() {
2717 let was_visible = fragment.was_visible(since, &self.undo_map);
2718 let is_visible = fragment.visible;
2719 if was_visible != is_visible {
2720 return true;
2721 }
2722 cursor.next();
2723 }
2724 }
2725 false
2726 }
2727
2728 pub fn range_to_version(&self, range: Range<usize>, version: &clock::Global) -> Range<usize> {
2729 let mut offsets = self.offsets_to_version([range.start, range.end], version);
2730 offsets.next().unwrap()..offsets.next().unwrap()
2731 }
2732
2733 /// Converts the given sequence of offsets into their corresponding offsets
2734 /// at a prior version of this buffer.
2735 pub fn offsets_to_version<'a>(
2736 &'a self,
2737 offsets: impl 'a + IntoIterator<Item = usize>,
2738 version: &'a clock::Global,
2739 ) -> impl 'a + Iterator<Item = usize> {
2740 let mut edits = self.edits_since(version).peekable();
2741 let mut last_old_end = 0;
2742 let mut last_new_end = 0;
2743 offsets.into_iter().map(move |new_offset| {
2744 while let Some(edit) = edits.peek() {
2745 if edit.new.start > new_offset {
2746 break;
2747 }
2748
2749 if edit.new.end <= new_offset {
2750 last_new_end = edit.new.end;
2751 last_old_end = edit.old.end;
2752 edits.next();
2753 continue;
2754 }
2755
2756 let overshoot = new_offset - edit.new.start;
2757 return (edit.old.start + overshoot).min(edit.old.end);
2758 }
2759
2760 last_old_end + new_offset.saturating_sub(last_new_end)
2761 })
2762 }
2763
2764 /// Visually annotates a position or range with the `Debug` representation of a value. The
2765 /// callsite of this function is used as a key - previous annotations will be removed.
2766 #[cfg(debug_assertions)]
2767 #[track_caller]
2768 pub fn debug<R, V>(&self, ranges: &R, value: V)
2769 where
2770 R: debug::ToDebugRanges,
2771 V: std::fmt::Debug,
2772 {
2773 self.debug_with_key(std::panic::Location::caller(), ranges, value);
2774 }
2775
2776 /// Visually annotates a position or range with the `Debug` representation of a value. Previous
2777 /// debug annotations with the same key will be removed. The key is also used to determine the
2778 /// annotation's color.
2779 #[cfg(debug_assertions)]
2780 pub fn debug_with_key<K, R, V>(&self, key: &K, ranges: &R, value: V)
2781 where
2782 K: std::hash::Hash + 'static,
2783 R: debug::ToDebugRanges,
2784 V: std::fmt::Debug,
2785 {
2786 let ranges = ranges
2787 .to_debug_ranges(self)
2788 .into_iter()
2789 .map(|range| self.anchor_after(range.start)..self.anchor_before(range.end))
2790 .collect();
2791 debug::GlobalDebugRanges::with_locked(|debug_ranges| {
2792 debug_ranges.insert(key, ranges, format!("{value:?}").into());
2793 });
2794 }
2795}
2796
2797struct RopeBuilder<'a> {
2798 old_visible_cursor: rope::Cursor<'a>,
2799 old_deleted_cursor: rope::Cursor<'a>,
2800 new_visible: Rope,
2801 new_deleted: Rope,
2802}
2803
2804impl<'a> RopeBuilder<'a> {
2805 fn new(old_visible_cursor: rope::Cursor<'a>, old_deleted_cursor: rope::Cursor<'a>) -> Self {
2806 Self {
2807 old_visible_cursor,
2808 old_deleted_cursor,
2809 new_visible: Rope::new(),
2810 new_deleted: Rope::new(),
2811 }
2812 }
2813
2814 fn append(&mut self, len: FragmentTextSummary) {
2815 self.push(len.visible, true, true);
2816 self.push(len.deleted, false, false);
2817 }
2818
2819 fn push_fragment(&mut self, fragment: &Fragment, was_visible: bool) {
2820 debug_assert!(fragment.len > 0);
2821 self.push(fragment.len as usize, was_visible, fragment.visible)
2822 }
2823
2824 fn push(&mut self, len: usize, was_visible: bool, is_visible: bool) {
2825 let text = if was_visible {
2826 self.old_visible_cursor
2827 .slice(self.old_visible_cursor.offset() + len)
2828 } else {
2829 self.old_deleted_cursor
2830 .slice(self.old_deleted_cursor.offset() + len)
2831 };
2832 if is_visible {
2833 self.new_visible.append(text);
2834 } else {
2835 self.new_deleted.append(text);
2836 }
2837 }
2838
2839 fn push_str(&mut self, text: &str) {
2840 self.new_visible.push(text);
2841 }
2842
2843 fn finish(mut self) -> (Rope, Rope) {
2844 self.new_visible.append(self.old_visible_cursor.suffix());
2845 self.new_deleted.append(self.old_deleted_cursor.suffix());
2846 (self.new_visible, self.new_deleted)
2847 }
2848}
2849
2850impl<D: TextDimension + Ord, F: FnMut(&FragmentSummary) -> bool> Iterator for Edits<'_, D, F> {
2851 type Item = (Edit<D>, Range<Anchor>);
2852
2853 fn next(&mut self) -> Option<Self::Item> {
2854 let mut pending_edit: Option<Self::Item> = None;
2855 let cursor = self.fragments_cursor.as_mut()?;
2856
2857 while let Some(fragment) = cursor.item() {
2858 if fragment.id < *self.range.start.0 {
2859 cursor.next();
2860 continue;
2861 } else if fragment.id > *self.range.end.0 {
2862 break;
2863 }
2864
2865 if cursor.start().visible > self.visible_cursor.offset() {
2866 let summary = self.visible_cursor.summary(cursor.start().visible);
2867 self.old_end.add_assign(&summary);
2868 self.new_end.add_assign(&summary);
2869 }
2870
2871 if pending_edit
2872 .as_ref()
2873 .is_some_and(|(change, _)| change.new.end < self.new_end)
2874 {
2875 break;
2876 }
2877
2878 let start_anchor = Anchor::new(
2879 fragment.timestamp,
2880 fragment.insertion_offset,
2881 Bias::Right,
2882 self.buffer_id,
2883 );
2884 let end_anchor = Anchor::new(
2885 fragment.timestamp,
2886 fragment.insertion_offset + fragment.len,
2887 Bias::Left,
2888 self.buffer_id,
2889 );
2890
2891 if !fragment.was_visible(self.since, self.undos) && fragment.visible {
2892 let mut visible_end = cursor.end().visible;
2893 if fragment.id == *self.range.end.0 {
2894 visible_end = cmp::min(
2895 visible_end,
2896 cursor.start().visible
2897 + (self.range.end.1 - fragment.insertion_offset) as usize,
2898 );
2899 }
2900
2901 let fragment_summary = self.visible_cursor.summary(visible_end);
2902 let mut new_end = self.new_end;
2903 new_end.add_assign(&fragment_summary);
2904 if let Some((edit, range)) = pending_edit.as_mut() {
2905 edit.new.end = new_end;
2906 range.end = end_anchor;
2907 } else {
2908 pending_edit = Some((
2909 Edit {
2910 old: self.old_end..self.old_end,
2911 new: self.new_end..new_end,
2912 },
2913 start_anchor..end_anchor,
2914 ));
2915 }
2916
2917 self.new_end = new_end;
2918 } else if fragment.was_visible(self.since, self.undos) && !fragment.visible {
2919 let mut deleted_end = cursor.end().deleted;
2920 if fragment.id == *self.range.end.0 {
2921 deleted_end = cmp::min(
2922 deleted_end,
2923 cursor.start().deleted
2924 + (self.range.end.1 - fragment.insertion_offset) as usize,
2925 );
2926 }
2927
2928 if cursor.start().deleted > self.deleted_cursor.offset() {
2929 self.deleted_cursor.seek_forward(cursor.start().deleted);
2930 }
2931 let fragment_summary = self.deleted_cursor.summary(deleted_end);
2932 let mut old_end = self.old_end;
2933 old_end.add_assign(&fragment_summary);
2934 if let Some((edit, range)) = pending_edit.as_mut() {
2935 edit.old.end = old_end;
2936 range.end = end_anchor;
2937 } else {
2938 pending_edit = Some((
2939 Edit {
2940 old: self.old_end..old_end,
2941 new: self.new_end..self.new_end,
2942 },
2943 start_anchor..end_anchor,
2944 ));
2945 }
2946
2947 self.old_end = old_end;
2948 }
2949
2950 cursor.next();
2951 }
2952
2953 pending_edit
2954 }
2955}
2956
2957impl Fragment {
2958 fn is_visible(&self, undos: &UndoMap) -> bool {
2959 !undos.is_undone(self.timestamp) && self.deletions.iter().all(|d| undos.is_undone(*d))
2960 }
2961
2962 fn was_visible(&self, version: &clock::Global, undos: &UndoMap) -> bool {
2963 (version.observed(self.timestamp) && !undos.was_undone(self.timestamp, version))
2964 && self
2965 .deletions
2966 .iter()
2967 .all(|d| !version.observed(*d) || undos.was_undone(*d, version))
2968 }
2969}
2970
2971impl sum_tree::Item for Fragment {
2972 type Summary = FragmentSummary;
2973
2974 fn summary(&self, _cx: &Option<clock::Global>) -> Self::Summary {
2975 let mut max_version = clock::Global::new();
2976 max_version.observe(self.timestamp);
2977 for deletion in &self.deletions {
2978 max_version.observe(*deletion);
2979 }
2980 max_version.join(&self.max_undos);
2981
2982 let mut min_insertion_version = clock::Global::new();
2983 min_insertion_version.observe(self.timestamp);
2984 let max_insertion_version = min_insertion_version.clone();
2985 if self.visible {
2986 FragmentSummary {
2987 max_id: self.id.clone(),
2988 text: FragmentTextSummary {
2989 visible: self.len as usize,
2990 deleted: 0,
2991 },
2992 max_version,
2993 min_insertion_version,
2994 max_insertion_version,
2995 }
2996 } else {
2997 FragmentSummary {
2998 max_id: self.id.clone(),
2999 text: FragmentTextSummary {
3000 visible: 0,
3001 deleted: self.len as usize,
3002 },
3003 max_version,
3004 min_insertion_version,
3005 max_insertion_version,
3006 }
3007 }
3008 }
3009}
3010
3011impl sum_tree::Summary for FragmentSummary {
3012 type Context<'a> = &'a Option<clock::Global>;
3013
3014 fn zero(_cx: Self::Context<'_>) -> Self {
3015 Default::default()
3016 }
3017
3018 fn add_summary(&mut self, other: &Self, _: Self::Context<'_>) {
3019 self.max_id.assign(&other.max_id);
3020 self.text.visible += &other.text.visible;
3021 self.text.deleted += &other.text.deleted;
3022 self.max_version.join(&other.max_version);
3023 self.min_insertion_version
3024 .meet(&other.min_insertion_version);
3025 self.max_insertion_version
3026 .join(&other.max_insertion_version);
3027 }
3028}
3029
3030impl Default for FragmentSummary {
3031 fn default() -> Self {
3032 FragmentSummary {
3033 max_id: Locator::min(),
3034 text: FragmentTextSummary::default(),
3035 max_version: clock::Global::new(),
3036 min_insertion_version: clock::Global::new(),
3037 max_insertion_version: clock::Global::new(),
3038 }
3039 }
3040}
3041
3042impl sum_tree::Item for InsertionFragment {
3043 type Summary = InsertionFragmentKey;
3044
3045 fn summary(&self, _cx: ()) -> Self::Summary {
3046 InsertionFragmentKey {
3047 timestamp: self.timestamp,
3048 split_offset: self.split_offset,
3049 }
3050 }
3051}
3052
3053impl sum_tree::KeyedItem for InsertionFragment {
3054 type Key = InsertionFragmentKey;
3055
3056 fn key(&self) -> Self::Key {
3057 sum_tree::Item::summary(self, ())
3058 }
3059}
3060
3061impl InsertionFragment {
3062 fn new(fragment: &Fragment) -> Self {
3063 Self {
3064 timestamp: fragment.timestamp,
3065 split_offset: fragment.insertion_offset,
3066 fragment_id: fragment.id.clone(),
3067 }
3068 }
3069
3070 fn insert_new(fragment: &Fragment) -> sum_tree::Edit<Self> {
3071 sum_tree::Edit::Insert(Self::new(fragment))
3072 }
3073}
3074
3075impl sum_tree::ContextLessSummary for InsertionFragmentKey {
3076 fn zero() -> Self {
3077 InsertionFragmentKey {
3078 timestamp: Lamport::MIN,
3079 split_offset: 0,
3080 }
3081 }
3082
3083 fn add_summary(&mut self, summary: &Self) {
3084 *self = *summary;
3085 }
3086}
3087
3088#[derive(Copy, Clone, Debug, Default, PartialEq, Eq, PartialOrd, Ord, Hash)]
3089pub struct FullOffset(pub usize);
3090
3091impl ops::AddAssign<usize> for FullOffset {
3092 fn add_assign(&mut self, rhs: usize) {
3093 self.0 += rhs;
3094 }
3095}
3096
3097impl ops::Add<usize> for FullOffset {
3098 type Output = Self;
3099
3100 fn add(mut self, rhs: usize) -> Self::Output {
3101 self += rhs;
3102 self
3103 }
3104}
3105
3106impl ops::Sub for FullOffset {
3107 type Output = usize;
3108
3109 fn sub(self, rhs: Self) -> Self::Output {
3110 self.0 - rhs.0
3111 }
3112}
3113
3114impl sum_tree::Dimension<'_, FragmentSummary> for usize {
3115 fn zero(_: &Option<clock::Global>) -> Self {
3116 Default::default()
3117 }
3118
3119 fn add_summary(&mut self, summary: &FragmentSummary, _: &Option<clock::Global>) {
3120 *self += summary.text.visible;
3121 }
3122}
3123
3124impl sum_tree::Dimension<'_, FragmentSummary> for FullOffset {
3125 fn zero(_: &Option<clock::Global>) -> Self {
3126 Default::default()
3127 }
3128
3129 fn add_summary(&mut self, summary: &FragmentSummary, _: &Option<clock::Global>) {
3130 self.0 += summary.text.visible + summary.text.deleted;
3131 }
3132}
3133
3134impl<'a> sum_tree::Dimension<'a, FragmentSummary> for Option<&'a Locator> {
3135 fn zero(_: &Option<clock::Global>) -> Self {
3136 Default::default()
3137 }
3138
3139 fn add_summary(&mut self, summary: &'a FragmentSummary, _: &Option<clock::Global>) {
3140 *self = Some(&summary.max_id);
3141 }
3142}
3143
3144impl sum_tree::SeekTarget<'_, FragmentSummary, FragmentTextSummary> for usize {
3145 fn cmp(
3146 &self,
3147 cursor_location: &FragmentTextSummary,
3148 _: &Option<clock::Global>,
3149 ) -> cmp::Ordering {
3150 Ord::cmp(self, &cursor_location.visible)
3151 }
3152}
3153
3154#[derive(Copy, Clone, Debug, Eq, PartialEq)]
3155enum VersionedFullOffset {
3156 Offset(FullOffset),
3157 Invalid,
3158}
3159
3160impl VersionedFullOffset {
3161 fn full_offset(&self) -> FullOffset {
3162 if let Self::Offset(position) = self {
3163 *position
3164 } else {
3165 panic!("invalid version")
3166 }
3167 }
3168}
3169
3170impl Default for VersionedFullOffset {
3171 fn default() -> Self {
3172 Self::Offset(Default::default())
3173 }
3174}
3175
3176impl<'a> sum_tree::Dimension<'a, FragmentSummary> for VersionedFullOffset {
3177 fn zero(_cx: &Option<clock::Global>) -> Self {
3178 Default::default()
3179 }
3180
3181 fn add_summary(&mut self, summary: &'a FragmentSummary, cx: &Option<clock::Global>) {
3182 if let Self::Offset(offset) = self {
3183 let version = cx.as_ref().unwrap();
3184 if version.observed_all(&summary.max_insertion_version) {
3185 *offset += summary.text.visible + summary.text.deleted;
3186 } else if version.observed_any(&summary.min_insertion_version) {
3187 *self = Self::Invalid;
3188 }
3189 }
3190 }
3191}
3192
3193impl sum_tree::SeekTarget<'_, FragmentSummary, Self> for VersionedFullOffset {
3194 fn cmp(&self, cursor_position: &Self, _: &Option<clock::Global>) -> cmp::Ordering {
3195 match (self, cursor_position) {
3196 (Self::Offset(a), Self::Offset(b)) => Ord::cmp(a, b),
3197 (Self::Offset(_), Self::Invalid) => cmp::Ordering::Less,
3198 (Self::Invalid, _) => unreachable!(),
3199 }
3200 }
3201}
3202
3203impl Operation {
3204 fn replica_id(&self) -> ReplicaId {
3205 operation_queue::Operation::lamport_timestamp(self).replica_id
3206 }
3207
3208 pub fn timestamp(&self) -> clock::Lamport {
3209 match self {
3210 Operation::Edit(edit) => edit.timestamp,
3211 Operation::Undo(undo) => undo.timestamp,
3212 }
3213 }
3214
3215 pub fn as_edit(&self) -> Option<&EditOperation> {
3216 match self {
3217 Operation::Edit(edit) => Some(edit),
3218 _ => None,
3219 }
3220 }
3221
3222 pub fn is_edit(&self) -> bool {
3223 matches!(self, Operation::Edit { .. })
3224 }
3225}
3226
3227impl operation_queue::Operation for Operation {
3228 fn lamport_timestamp(&self) -> clock::Lamport {
3229 match self {
3230 Operation::Edit(edit) => edit.timestamp,
3231 Operation::Undo(undo) => undo.timestamp,
3232 }
3233 }
3234}
3235
3236pub trait ToOffset {
3237 fn to_offset(&self, snapshot: &BufferSnapshot) -> usize;
3238 /// Turns this point into the next offset in the buffer that comes after this, respecting utf8 boundaries.
3239 fn to_next_offset(&self, snapshot: &BufferSnapshot) -> usize {
3240 snapshot
3241 .visible_text
3242 .ceil_char_boundary(self.to_offset(snapshot) + 1)
3243 }
3244 /// Turns this point into the previous offset in the buffer that comes before this, respecting utf8 boundaries.
3245 fn to_previous_offset(&self, snapshot: &BufferSnapshot) -> usize {
3246 snapshot
3247 .visible_text
3248 .floor_char_boundary(self.to_offset(snapshot).saturating_sub(1))
3249 }
3250}
3251
3252impl ToOffset for Point {
3253 #[inline]
3254 fn to_offset(&self, snapshot: &BufferSnapshot) -> usize {
3255 snapshot.point_to_offset(*self)
3256 }
3257}
3258
3259impl ToOffset for usize {
3260 #[track_caller]
3261 fn to_offset(&self, snapshot: &BufferSnapshot) -> usize {
3262 if !snapshot
3263 .as_rope()
3264 .assert_char_boundary::<{ cfg!(debug_assertions) }>(*self)
3265 {
3266 snapshot.as_rope().floor_char_boundary(*self)
3267 } else {
3268 *self
3269 }
3270 }
3271}
3272
3273impl ToOffset for Anchor {
3274 #[inline]
3275 fn to_offset(&self, snapshot: &BufferSnapshot) -> usize {
3276 snapshot.summary_for_anchor(self)
3277 }
3278}
3279
3280impl<T: ToOffset> ToOffset for &T {
3281 #[inline]
3282 fn to_offset(&self, content: &BufferSnapshot) -> usize {
3283 (*self).to_offset(content)
3284 }
3285}
3286
3287impl ToOffset for PointUtf16 {
3288 #[inline]
3289 fn to_offset(&self, snapshot: &BufferSnapshot) -> usize {
3290 snapshot.point_utf16_to_offset(*self)
3291 }
3292}
3293
3294impl ToOffset for Unclipped<PointUtf16> {
3295 #[inline]
3296 fn to_offset(&self, snapshot: &BufferSnapshot) -> usize {
3297 snapshot.unclipped_point_utf16_to_offset(*self)
3298 }
3299}
3300
3301pub trait ToPoint {
3302 fn to_point(&self, snapshot: &BufferSnapshot) -> Point;
3303}
3304
3305impl ToPoint for Anchor {
3306 #[inline]
3307 fn to_point(&self, snapshot: &BufferSnapshot) -> Point {
3308 snapshot.summary_for_anchor(self)
3309 }
3310}
3311
3312impl ToPoint for usize {
3313 #[inline]
3314 fn to_point(&self, snapshot: &BufferSnapshot) -> Point {
3315 snapshot.offset_to_point(*self)
3316 }
3317}
3318
3319impl ToPoint for Point {
3320 #[inline]
3321 fn to_point(&self, _: &BufferSnapshot) -> Point {
3322 *self
3323 }
3324}
3325
3326impl ToPoint for Unclipped<PointUtf16> {
3327 #[inline]
3328 fn to_point(&self, snapshot: &BufferSnapshot) -> Point {
3329 snapshot.unclipped_point_utf16_to_point(*self)
3330 }
3331}
3332
3333pub trait ToPointUtf16 {
3334 fn to_point_utf16(&self, snapshot: &BufferSnapshot) -> PointUtf16;
3335}
3336
3337impl ToPointUtf16 for Anchor {
3338 #[inline]
3339 fn to_point_utf16(&self, snapshot: &BufferSnapshot) -> PointUtf16 {
3340 snapshot.summary_for_anchor(self)
3341 }
3342}
3343
3344impl ToPointUtf16 for usize {
3345 #[inline]
3346 fn to_point_utf16(&self, snapshot: &BufferSnapshot) -> PointUtf16 {
3347 snapshot.offset_to_point_utf16(*self)
3348 }
3349}
3350
3351impl ToPointUtf16 for PointUtf16 {
3352 #[inline]
3353 fn to_point_utf16(&self, _: &BufferSnapshot) -> PointUtf16 {
3354 *self
3355 }
3356}
3357
3358impl ToPointUtf16 for Point {
3359 #[inline]
3360 fn to_point_utf16(&self, snapshot: &BufferSnapshot) -> PointUtf16 {
3361 snapshot.point_to_point_utf16(*self)
3362 }
3363}
3364
3365pub trait ToOffsetUtf16 {
3366 fn to_offset_utf16(&self, snapshot: &BufferSnapshot) -> OffsetUtf16;
3367}
3368
3369impl ToOffsetUtf16 for Anchor {
3370 #[inline]
3371 fn to_offset_utf16(&self, snapshot: &BufferSnapshot) -> OffsetUtf16 {
3372 snapshot.summary_for_anchor(self)
3373 }
3374}
3375
3376impl ToOffsetUtf16 for usize {
3377 #[inline]
3378 fn to_offset_utf16(&self, snapshot: &BufferSnapshot) -> OffsetUtf16 {
3379 snapshot.offset_to_offset_utf16(*self)
3380 }
3381}
3382
3383impl ToOffsetUtf16 for OffsetUtf16 {
3384 #[inline]
3385 fn to_offset_utf16(&self, _snapshot: &BufferSnapshot) -> OffsetUtf16 {
3386 *self
3387 }
3388}
3389
3390pub trait FromAnchor {
3391 fn from_anchor(anchor: &Anchor, snapshot: &BufferSnapshot) -> Self;
3392}
3393
3394impl FromAnchor for Anchor {
3395 #[inline]
3396 fn from_anchor(anchor: &Anchor, _snapshot: &BufferSnapshot) -> Self {
3397 *anchor
3398 }
3399}
3400
3401impl FromAnchor for Point {
3402 #[inline]
3403 fn from_anchor(anchor: &Anchor, snapshot: &BufferSnapshot) -> Self {
3404 snapshot.summary_for_anchor(anchor)
3405 }
3406}
3407
3408impl FromAnchor for PointUtf16 {
3409 #[inline]
3410 fn from_anchor(anchor: &Anchor, snapshot: &BufferSnapshot) -> Self {
3411 snapshot.summary_for_anchor(anchor)
3412 }
3413}
3414
3415impl FromAnchor for usize {
3416 #[inline]
3417 fn from_anchor(anchor: &Anchor, snapshot: &BufferSnapshot) -> Self {
3418 snapshot.summary_for_anchor(anchor)
3419 }
3420}
3421
3422#[derive(Clone, Copy, Debug, PartialEq)]
3423pub enum LineEnding {
3424 Unix,
3425 Windows,
3426}
3427
3428impl Default for LineEnding {
3429 fn default() -> Self {
3430 #[cfg(unix)]
3431 return Self::Unix;
3432
3433 #[cfg(not(unix))]
3434 return Self::Windows;
3435 }
3436}
3437
3438impl LineEnding {
3439 pub fn as_str(&self) -> &'static str {
3440 match self {
3441 LineEnding::Unix => "\n",
3442 LineEnding::Windows => "\r\n",
3443 }
3444 }
3445
3446 pub fn label(&self) -> &'static str {
3447 match self {
3448 LineEnding::Unix => "LF",
3449 LineEnding::Windows => "CRLF",
3450 }
3451 }
3452
3453 pub fn detect(text: &str) -> Self {
3454 let mut max_ix = cmp::min(text.len(), 1000);
3455 while !text.is_char_boundary(max_ix) {
3456 max_ix -= 1;
3457 }
3458
3459 if let Some(ix) = text[..max_ix].find(['\n']) {
3460 if ix > 0 && text.as_bytes()[ix - 1] == b'\r' {
3461 Self::Windows
3462 } else {
3463 Self::Unix
3464 }
3465 } else {
3466 Self::default()
3467 }
3468 }
3469
3470 pub fn normalize(text: &mut String) {
3471 if let Cow::Owned(replaced) = LINE_SEPARATORS_REGEX.replace_all(text, "\n") {
3472 *text = replaced;
3473 }
3474 }
3475
3476 pub fn normalize_arc(text: Arc<str>) -> Arc<str> {
3477 if let Cow::Owned(replaced) = LINE_SEPARATORS_REGEX.replace_all(&text, "\n") {
3478 replaced.into()
3479 } else {
3480 text
3481 }
3482 }
3483
3484 pub fn normalize_cow(text: Cow<str>) -> Cow<str> {
3485 if let Cow::Owned(replaced) = LINE_SEPARATORS_REGEX.replace_all(&text, "\n") {
3486 replaced.into()
3487 } else {
3488 text
3489 }
3490 }
3491}
3492
3493pub fn chunks_with_line_ending(rope: &Rope, line_ending: LineEnding) -> impl Iterator<Item = &str> {
3494 rope.chunks().flat_map(move |chunk| {
3495 let mut newline = false;
3496 let end_with_newline = chunk.ends_with('\n').then_some(line_ending.as_str());
3497 chunk
3498 .lines()
3499 .flat_map(move |line| {
3500 let ending = if newline {
3501 Some(line_ending.as_str())
3502 } else {
3503 None
3504 };
3505 newline = true;
3506 ending.into_iter().chain([line])
3507 })
3508 .chain(end_with_newline)
3509 })
3510}
3511
3512#[cfg(debug_assertions)]
3513pub mod debug {
3514 use super::*;
3515 use parking_lot::Mutex;
3516 use std::any::TypeId;
3517 use std::hash::{Hash, Hasher};
3518
3519 static GLOBAL_DEBUG_RANGES: Mutex<Option<GlobalDebugRanges>> = Mutex::new(None);
3520
3521 pub struct GlobalDebugRanges {
3522 pub ranges: Vec<DebugRange>,
3523 key_to_occurrence_index: HashMap<Key, usize>,
3524 next_occurrence_index: usize,
3525 }
3526
3527 pub struct DebugRange {
3528 key: Key,
3529 pub ranges: Vec<Range<Anchor>>,
3530 pub value: Arc<str>,
3531 pub occurrence_index: usize,
3532 }
3533
3534 #[derive(Debug, Clone, PartialEq, Eq, Hash)]
3535 struct Key {
3536 type_id: TypeId,
3537 hash: u64,
3538 }
3539
3540 impl GlobalDebugRanges {
3541 pub fn with_locked<R>(f: impl FnOnce(&mut Self) -> R) -> R {
3542 let mut state = GLOBAL_DEBUG_RANGES.lock();
3543 if state.is_none() {
3544 *state = Some(GlobalDebugRanges {
3545 ranges: Vec::new(),
3546 key_to_occurrence_index: HashMap::default(),
3547 next_occurrence_index: 0,
3548 });
3549 }
3550 if let Some(global_debug_ranges) = state.as_mut() {
3551 f(global_debug_ranges)
3552 } else {
3553 unreachable!()
3554 }
3555 }
3556
3557 pub fn insert<K: Hash + 'static>(
3558 &mut self,
3559 key: &K,
3560 ranges: Vec<Range<Anchor>>,
3561 value: Arc<str>,
3562 ) {
3563 let occurrence_index = *self
3564 .key_to_occurrence_index
3565 .entry(Key::new(key))
3566 .or_insert_with(|| {
3567 let occurrence_index = self.next_occurrence_index;
3568 self.next_occurrence_index += 1;
3569 occurrence_index
3570 });
3571 let key = Key::new(key);
3572 let existing = self
3573 .ranges
3574 .iter()
3575 .enumerate()
3576 .rfind(|(_, existing)| existing.key == key);
3577 if let Some((existing_ix, _)) = existing {
3578 self.ranges.remove(existing_ix);
3579 }
3580 self.ranges.push(DebugRange {
3581 ranges,
3582 key,
3583 value,
3584 occurrence_index,
3585 });
3586 }
3587
3588 pub fn remove<K: Hash + 'static>(&mut self, key: &K) {
3589 self.remove_impl(&Key::new(key));
3590 }
3591
3592 fn remove_impl(&mut self, key: &Key) {
3593 let existing = self
3594 .ranges
3595 .iter()
3596 .enumerate()
3597 .rfind(|(_, existing)| &existing.key == key);
3598 if let Some((existing_ix, _)) = existing {
3599 self.ranges.remove(existing_ix);
3600 }
3601 }
3602
3603 pub fn remove_all_with_key_type<K: 'static>(&mut self) {
3604 self.ranges
3605 .retain(|item| item.key.type_id != TypeId::of::<K>());
3606 }
3607 }
3608
3609 impl Key {
3610 fn new<K: Hash + 'static>(key: &K) -> Self {
3611 let type_id = TypeId::of::<K>();
3612 let mut hasher = collections::FxHasher::default();
3613 key.hash(&mut hasher);
3614 Key {
3615 type_id,
3616 hash: hasher.finish(),
3617 }
3618 }
3619 }
3620
3621 pub trait ToDebugRanges {
3622 fn to_debug_ranges(&self, snapshot: &BufferSnapshot) -> Vec<Range<usize>>;
3623 }
3624
3625 impl<T: ToOffset> ToDebugRanges for T {
3626 fn to_debug_ranges(&self, snapshot: &BufferSnapshot) -> Vec<Range<usize>> {
3627 [self.to_offset(snapshot)].to_debug_ranges(snapshot)
3628 }
3629 }
3630
3631 impl<T: ToOffset + Clone> ToDebugRanges for Range<T> {
3632 fn to_debug_ranges(&self, snapshot: &BufferSnapshot) -> Vec<Range<usize>> {
3633 [self.clone()].to_debug_ranges(snapshot)
3634 }
3635 }
3636
3637 impl<T: ToOffset> ToDebugRanges for Vec<T> {
3638 fn to_debug_ranges(&self, snapshot: &BufferSnapshot) -> Vec<Range<usize>> {
3639 self.as_slice().to_debug_ranges(snapshot)
3640 }
3641 }
3642
3643 impl<T: ToOffset> ToDebugRanges for Vec<Range<T>> {
3644 fn to_debug_ranges(&self, snapshot: &BufferSnapshot) -> Vec<Range<usize>> {
3645 self.as_slice().to_debug_ranges(snapshot)
3646 }
3647 }
3648
3649 impl<T: ToOffset> ToDebugRanges for [T] {
3650 fn to_debug_ranges(&self, snapshot: &BufferSnapshot) -> Vec<Range<usize>> {
3651 self.iter()
3652 .map(|item| {
3653 let offset = item.to_offset(snapshot);
3654 offset..offset
3655 })
3656 .collect()
3657 }
3658 }
3659
3660 impl<T: ToOffset> ToDebugRanges for [Range<T>] {
3661 fn to_debug_ranges(&self, snapshot: &BufferSnapshot) -> Vec<Range<usize>> {
3662 self.iter()
3663 .map(|range| range.start.to_offset(snapshot)..range.end.to_offset(snapshot))
3664 .collect()
3665 }
3666 }
3667}