text.rs

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