buffer.rs

   1mod anchor;
   2mod point;
   3pub mod rope;
   4mod selection;
   5
   6pub use anchor::*;
   7use parking_lot::Mutex;
   8pub use point::*;
   9pub use rope::{Chunks, Rope, TextSummary};
  10use seahash::SeaHasher;
  11pub use selection::*;
  12use similar::{ChangeTag, TextDiff};
  13use tree_sitter::{InputEdit, Parser, QueryCursor};
  14
  15use crate::{
  16    language::{Language, Tree},
  17    operation_queue::{self, OperationQueue},
  18    settings::{StyleId, ThemeMap},
  19    sum_tree::{self, FilterCursor, SumTree},
  20    time::{self, ReplicaId},
  21    util::Bias,
  22    worktree::FileHandle,
  23};
  24use anyhow::{anyhow, Result};
  25use gpui::{AppContext, Entity, ModelContext, Task};
  26use lazy_static::lazy_static;
  27use std::{
  28    cell::RefCell,
  29    cmp,
  30    hash::BuildHasher,
  31    iter::Iterator,
  32    ops::{Deref, DerefMut, Range},
  33    str,
  34    sync::Arc,
  35    time::{Duration, Instant, SystemTime, UNIX_EPOCH},
  36};
  37
  38const UNDO_GROUP_INTERVAL: Duration = Duration::from_millis(300);
  39
  40#[derive(Clone, Default)]
  41struct DeterministicState;
  42
  43impl BuildHasher for DeterministicState {
  44    type Hasher = SeaHasher;
  45
  46    fn build_hasher(&self) -> Self::Hasher {
  47        SeaHasher::new()
  48    }
  49}
  50
  51#[cfg(test)]
  52type HashMap<K, V> = std::collections::HashMap<K, V, DeterministicState>;
  53
  54#[cfg(test)]
  55type HashSet<T> = std::collections::HashSet<T, DeterministicState>;
  56
  57#[cfg(not(test))]
  58type HashMap<K, V> = std::collections::HashMap<K, V>;
  59
  60#[cfg(not(test))]
  61type HashSet<T> = std::collections::HashSet<T>;
  62
  63thread_local! {
  64    static PARSER: RefCell<Parser> = RefCell::new(Parser::new());
  65}
  66
  67lazy_static! {
  68    static ref QUERY_CURSORS: Mutex<Vec<QueryCursor>> = Default::default();
  69}
  70
  71struct QueryCursorHandle(Option<QueryCursor>);
  72
  73impl QueryCursorHandle {
  74    fn new() -> Self {
  75        QueryCursorHandle(Some(
  76            QUERY_CURSORS
  77                .lock()
  78                .pop()
  79                .unwrap_or_else(|| QueryCursor::new()),
  80        ))
  81    }
  82}
  83
  84impl Deref for QueryCursorHandle {
  85    type Target = QueryCursor;
  86
  87    fn deref(&self) -> &Self::Target {
  88        self.0.as_ref().unwrap()
  89    }
  90}
  91
  92impl DerefMut for QueryCursorHandle {
  93    fn deref_mut(&mut self) -> &mut Self::Target {
  94        self.0.as_mut().unwrap()
  95    }
  96}
  97
  98impl Drop for QueryCursorHandle {
  99    fn drop(&mut self) {
 100        let mut cursor = self.0.take().unwrap();
 101        cursor.set_byte_range(0..usize::MAX);
 102        cursor.set_point_range(Point::zero().into()..Point::MAX.into());
 103        QUERY_CURSORS.lock().push(cursor)
 104    }
 105}
 106
 107pub struct Buffer {
 108    fragments: SumTree<Fragment>,
 109    visible_text: Rope,
 110    deleted_text: Rope,
 111    pub version: time::Global,
 112    saved_version: time::Global,
 113    saved_mtime: SystemTime,
 114    last_edit: time::Local,
 115    undo_map: UndoMap,
 116    history: History,
 117    file: Option<FileHandle>,
 118    language: Option<Arc<Language>>,
 119    syntax_tree: Mutex<Option<SyntaxTree>>,
 120    is_parsing: bool,
 121    selections: HashMap<SelectionSetId, Arc<[Selection]>>,
 122    pub selections_last_update: SelectionsVersion,
 123    deferred_ops: OperationQueue<Operation>,
 124    deferred_replicas: HashSet<ReplicaId>,
 125    replica_id: ReplicaId,
 126    local_clock: time::Local,
 127    lamport_clock: time::Lamport,
 128}
 129
 130#[derive(Clone)]
 131struct SyntaxTree {
 132    tree: Tree,
 133    parsed: bool,
 134    version: time::Global,
 135}
 136
 137#[derive(Clone)]
 138struct Transaction {
 139    start: time::Global,
 140    buffer_was_dirty: bool,
 141    edits: Vec<time::Local>,
 142    selections_before: Option<(SelectionSetId, Arc<[Selection]>)>,
 143    selections_after: Option<(SelectionSetId, Arc<[Selection]>)>,
 144    first_edit_at: Instant,
 145    last_edit_at: Instant,
 146}
 147
 148#[derive(Clone)]
 149pub struct History {
 150    // TODO: Turn this into a String or Rope, maybe.
 151    pub base_text: Arc<str>,
 152    ops: HashMap<time::Local, EditOperation>,
 153    undo_stack: Vec<Transaction>,
 154    redo_stack: Vec<Transaction>,
 155    transaction_depth: usize,
 156    group_interval: Duration,
 157}
 158
 159impl History {
 160    pub fn new(base_text: Arc<str>) -> Self {
 161        Self {
 162            base_text,
 163            ops: Default::default(),
 164            undo_stack: Vec::new(),
 165            redo_stack: Vec::new(),
 166            transaction_depth: 0,
 167            group_interval: UNDO_GROUP_INTERVAL,
 168        }
 169    }
 170
 171    fn push(&mut self, op: EditOperation) {
 172        self.ops.insert(op.timestamp.local(), op);
 173    }
 174
 175    fn start_transaction(
 176        &mut self,
 177        start: time::Global,
 178        buffer_was_dirty: bool,
 179        selections: Option<(SelectionSetId, Arc<[Selection]>)>,
 180        now: Instant,
 181    ) {
 182        self.transaction_depth += 1;
 183        if self.transaction_depth == 1 {
 184            self.undo_stack.push(Transaction {
 185                start,
 186                buffer_was_dirty,
 187                edits: Vec::new(),
 188                selections_before: selections,
 189                selections_after: None,
 190                first_edit_at: now,
 191                last_edit_at: now,
 192            });
 193        }
 194    }
 195
 196    fn end_transaction(
 197        &mut self,
 198        selections: Option<(SelectionSetId, Arc<[Selection]>)>,
 199        now: Instant,
 200    ) -> Option<&Transaction> {
 201        assert_ne!(self.transaction_depth, 0);
 202        self.transaction_depth -= 1;
 203        if self.transaction_depth == 0 {
 204            let transaction = self.undo_stack.last_mut().unwrap();
 205            transaction.selections_after = selections;
 206            transaction.last_edit_at = now;
 207            Some(transaction)
 208        } else {
 209            None
 210        }
 211    }
 212
 213    fn group(&mut self) {
 214        let mut new_len = self.undo_stack.len();
 215        let mut transactions = self.undo_stack.iter_mut();
 216
 217        if let Some(mut transaction) = transactions.next_back() {
 218            for prev_transaction in transactions.next_back() {
 219                if transaction.first_edit_at - prev_transaction.last_edit_at <= self.group_interval
 220                {
 221                    prev_transaction.edits.append(&mut transaction.edits);
 222                    prev_transaction.last_edit_at = transaction.last_edit_at;
 223                    prev_transaction.selections_after = transaction.selections_after.take();
 224                    transaction = prev_transaction;
 225                    new_len -= 1;
 226                } else {
 227                    break;
 228                }
 229            }
 230        }
 231
 232        self.undo_stack.truncate(new_len);
 233    }
 234
 235    fn push_undo(&mut self, edit_id: time::Local) {
 236        assert_ne!(self.transaction_depth, 0);
 237        self.undo_stack.last_mut().unwrap().edits.push(edit_id);
 238    }
 239
 240    fn pop_undo(&mut self) -> Option<&Transaction> {
 241        assert_eq!(self.transaction_depth, 0);
 242        if let Some(transaction) = self.undo_stack.pop() {
 243            self.redo_stack.push(transaction);
 244            self.redo_stack.last()
 245        } else {
 246            None
 247        }
 248    }
 249
 250    fn pop_redo(&mut self) -> Option<&Transaction> {
 251        assert_eq!(self.transaction_depth, 0);
 252        if let Some(transaction) = self.redo_stack.pop() {
 253            self.undo_stack.push(transaction);
 254            self.undo_stack.last()
 255        } else {
 256            None
 257        }
 258    }
 259}
 260
 261#[derive(Clone, Default, Debug)]
 262struct UndoMap(HashMap<time::Local, Vec<UndoOperation>>);
 263
 264impl UndoMap {
 265    fn insert(&mut self, undo: UndoOperation) {
 266        self.0.entry(undo.edit_id).or_default().push(undo);
 267    }
 268
 269    fn is_undone(&self, edit_id: time::Local) -> bool {
 270        self.undo_count(edit_id) % 2 == 1
 271    }
 272
 273    fn was_undone(&self, edit_id: time::Local, version: &time::Global) -> bool {
 274        let undo_count = self
 275            .0
 276            .get(&edit_id)
 277            .unwrap_or(&Vec::new())
 278            .iter()
 279            .filter(|undo| version.observed(undo.id))
 280            .map(|undo| undo.count)
 281            .max()
 282            .unwrap_or(0);
 283        undo_count % 2 == 1
 284    }
 285
 286    fn undo_count(&self, edit_id: time::Local) -> u32 {
 287        self.0
 288            .get(&edit_id)
 289            .unwrap_or(&Vec::new())
 290            .iter()
 291            .map(|undo| undo.count)
 292            .max()
 293            .unwrap_or(0)
 294    }
 295}
 296
 297struct Edits<'a, F: Fn(&FragmentSummary) -> bool> {
 298    deleted_text: &'a Rope,
 299    cursor: FilterCursor<'a, F, Fragment, FragmentTextSummary>,
 300    undos: &'a UndoMap,
 301    since: time::Global,
 302    delta: isize,
 303}
 304
 305#[derive(Clone, Debug, Default, Eq, PartialEq)]
 306pub struct Edit {
 307    pub old_range: Range<usize>,
 308    pub new_range: Range<usize>,
 309    pub old_lines: Point,
 310}
 311
 312impl Edit {
 313    pub fn delta(&self) -> isize {
 314        (self.new_range.end - self.new_range.start) as isize
 315            - (self.old_range.end - self.old_range.start) as isize
 316    }
 317
 318    pub fn old_extent(&self) -> usize {
 319        self.old_range.end - self.old_range.start
 320    }
 321}
 322
 323struct Diff {
 324    base_version: time::Global,
 325    new_text: Arc<str>,
 326    changes: Vec<(ChangeTag, usize)>,
 327}
 328
 329#[derive(Copy, Clone, Debug, Default, Eq, PartialEq)]
 330struct InsertionTimestamp {
 331    replica_id: ReplicaId,
 332    local: time::Seq,
 333    lamport: time::Seq,
 334}
 335
 336impl InsertionTimestamp {
 337    fn local(&self) -> time::Local {
 338        time::Local {
 339            replica_id: self.replica_id,
 340            value: self.local,
 341        }
 342    }
 343
 344    fn lamport(&self) -> time::Lamport {
 345        time::Lamport {
 346            replica_id: self.replica_id,
 347            value: self.lamport,
 348        }
 349    }
 350}
 351
 352#[derive(Eq, PartialEq, Clone, Debug)]
 353struct Fragment {
 354    timestamp: InsertionTimestamp,
 355    len: usize,
 356    visible: bool,
 357    deletions: HashSet<time::Local>,
 358    max_undos: time::Global,
 359}
 360
 361#[derive(Eq, PartialEq, Clone, Debug)]
 362pub struct FragmentSummary {
 363    text: FragmentTextSummary,
 364    max_version: time::Global,
 365    min_insertion_version: time::Global,
 366    max_insertion_version: time::Global,
 367}
 368
 369#[derive(Copy, Default, Clone, Debug, PartialEq, Eq)]
 370struct FragmentTextSummary {
 371    visible: usize,
 372    deleted: usize,
 373}
 374
 375impl<'a> sum_tree::Dimension<'a, FragmentSummary> for FragmentTextSummary {
 376    fn add_summary(&mut self, summary: &'a FragmentSummary, _: &Option<time::Global>) {
 377        self.visible += summary.text.visible;
 378        self.deleted += summary.text.deleted;
 379    }
 380}
 381
 382#[derive(Clone, Debug, Eq, PartialEq)]
 383pub enum Operation {
 384    Edit(EditOperation),
 385    Undo {
 386        undo: UndoOperation,
 387        lamport_timestamp: time::Lamport,
 388    },
 389    UpdateSelections {
 390        set_id: SelectionSetId,
 391        selections: Option<Arc<[Selection]>>,
 392        lamport_timestamp: time::Lamport,
 393    },
 394}
 395
 396#[derive(Clone, Debug, Eq, PartialEq)]
 397pub struct EditOperation {
 398    timestamp: InsertionTimestamp,
 399    version: time::Global,
 400    ranges: Vec<Range<usize>>,
 401    new_text: Option<String>,
 402}
 403
 404#[derive(Copy, Clone, Debug, Eq, PartialEq)]
 405pub struct UndoOperation {
 406    id: time::Local,
 407    edit_id: time::Local,
 408    count: u32,
 409}
 410
 411impl Buffer {
 412    pub fn new<T: Into<Arc<str>>>(
 413        replica_id: ReplicaId,
 414        base_text: T,
 415        cx: &mut ModelContext<Self>,
 416    ) -> Self {
 417        Self::build(replica_id, History::new(base_text.into()), None, None, cx)
 418    }
 419
 420    pub fn from_history(
 421        replica_id: ReplicaId,
 422        history: History,
 423        file: Option<FileHandle>,
 424        language: Option<Arc<Language>>,
 425        cx: &mut ModelContext<Self>,
 426    ) -> Self {
 427        Self::build(replica_id, history, file, language, cx)
 428    }
 429
 430    fn build(
 431        replica_id: ReplicaId,
 432        history: History,
 433        file: Option<FileHandle>,
 434        language: Option<Arc<Language>>,
 435        cx: &mut ModelContext<Self>,
 436    ) -> Self {
 437        let saved_mtime;
 438        if let Some(file) = file.as_ref() {
 439            saved_mtime = file.mtime();
 440            file.observe_from_model(cx, |this, file, cx| {
 441                let version = this.version.clone();
 442                if this.version == this.saved_version {
 443                    if file.is_deleted() {
 444                        cx.emit(Event::Dirtied);
 445                    } else {
 446                        cx.spawn(|handle, mut cx| async move {
 447                            let (current_version, history) = handle.read_with(&cx, |this, cx| {
 448                                (this.version.clone(), file.load_history(cx.as_ref()))
 449                            });
 450                            if let (Ok(history), true) = (history.await, current_version == version)
 451                            {
 452                                let diff = handle
 453                                    .read_with(&cx, |this, cx| this.diff(history.base_text, cx))
 454                                    .await;
 455                                handle.update(&mut cx, |this, cx| {
 456                                    if let Some(_ops) = this.set_text_via_diff(diff, cx) {
 457                                        this.saved_version = this.version.clone();
 458                                        this.saved_mtime = file.mtime();
 459                                        cx.emit(Event::Reloaded);
 460                                    }
 461                                });
 462                            }
 463                        })
 464                        .detach();
 465                    }
 466                }
 467                cx.emit(Event::FileHandleChanged);
 468            });
 469        } else {
 470            saved_mtime = UNIX_EPOCH;
 471        }
 472
 473        let mut fragments = SumTree::new();
 474
 475        let visible_text = Rope::from(history.base_text.as_ref());
 476        if visible_text.len() > 0 {
 477            fragments.push(
 478                Fragment {
 479                    timestamp: Default::default(),
 480                    len: visible_text.len(),
 481                    visible: true,
 482                    deletions: Default::default(),
 483                    max_undos: Default::default(),
 484                },
 485                &None,
 486            );
 487        }
 488
 489        let mut result = Self {
 490            visible_text,
 491            deleted_text: Rope::new(),
 492            fragments,
 493            version: time::Global::new(),
 494            saved_version: time::Global::new(),
 495            last_edit: time::Local::default(),
 496            undo_map: Default::default(),
 497            history,
 498            file,
 499            syntax_tree: Mutex::new(None),
 500            is_parsing: false,
 501            language,
 502            saved_mtime,
 503            selections: HashMap::default(),
 504            selections_last_update: 0,
 505            deferred_ops: OperationQueue::new(),
 506            deferred_replicas: HashSet::default(),
 507            replica_id,
 508            local_clock: time::Local::new(replica_id),
 509            lamport_clock: time::Lamport::new(replica_id),
 510        };
 511        result.reparse(cx);
 512        result
 513    }
 514
 515    pub fn snapshot(&self) -> Snapshot {
 516        Snapshot {
 517            text: self.visible_text.clone(),
 518            tree: self.syntax_tree(),
 519            language: self.language.clone(),
 520            query_cursor: QueryCursorHandle::new(),
 521        }
 522    }
 523
 524    pub fn file(&self) -> Option<&FileHandle> {
 525        self.file.as_ref()
 526    }
 527
 528    pub fn save(
 529        &mut self,
 530        new_file: Option<FileHandle>,
 531        cx: &mut ModelContext<Self>,
 532    ) -> Task<Result<()>> {
 533        let text = self.visible_text.clone();
 534        let version = self.version.clone();
 535        let file = self.file.clone();
 536
 537        cx.spawn(|handle, mut cx| async move {
 538            if let Some(file) = new_file.as_ref().or(file.as_ref()) {
 539                let result = cx.read(|cx| file.save(text, cx.as_ref())).await;
 540                if result.is_ok() {
 541                    handle.update(&mut cx, |me, cx| me.did_save(version, new_file, cx));
 542                }
 543                result
 544            } else {
 545                Ok(())
 546            }
 547        })
 548    }
 549
 550    fn did_save(
 551        &mut self,
 552        version: time::Global,
 553        file: Option<FileHandle>,
 554        cx: &mut ModelContext<Buffer>,
 555    ) {
 556        if file.is_some() {
 557            self.file = file;
 558        }
 559        if let Some(file) = &self.file {
 560            self.saved_mtime = file.mtime();
 561        }
 562        self.saved_version = version;
 563        cx.emit(Event::Saved);
 564    }
 565
 566    pub fn syntax_tree(&self) -> Option<Tree> {
 567        if let Some(syntax_tree) = self.syntax_tree.lock().as_mut() {
 568            let mut edited = false;
 569            let mut delta = 0_isize;
 570            for Edit {
 571                old_range,
 572                new_range,
 573                old_lines,
 574            } in self.edits_since(syntax_tree.version.clone())
 575            {
 576                let start_offset = (old_range.start as isize + delta) as usize;
 577                let start_point = self.visible_text.to_point(start_offset);
 578                let old_bytes = old_range.end - old_range.start;
 579                let new_bytes = new_range.end - new_range.start;
 580                syntax_tree.tree.edit(&InputEdit {
 581                    start_byte: start_offset,
 582                    old_end_byte: start_offset + old_bytes,
 583                    new_end_byte: start_offset + new_bytes,
 584                    start_position: start_point.into(),
 585                    old_end_position: (start_point + old_lines).into(),
 586                    new_end_position: self.visible_text.to_point(start_offset + new_bytes).into(),
 587                });
 588                delta += new_bytes as isize - old_bytes as isize;
 589                edited = true;
 590            }
 591            syntax_tree.parsed &= !edited;
 592            syntax_tree.version = self.version();
 593            Some(syntax_tree.tree.clone())
 594        } else {
 595            None
 596        }
 597    }
 598
 599    pub fn is_parsing(&self) -> bool {
 600        self.is_parsing
 601    }
 602
 603    fn should_reparse(&self) -> bool {
 604        if let Some(syntax_tree) = self.syntax_tree.lock().as_ref() {
 605            !syntax_tree.parsed || syntax_tree.version != self.version
 606        } else {
 607            self.language.is_some()
 608        }
 609    }
 610
 611    fn reparse(&mut self, cx: &mut ModelContext<Self>) {
 612        // Avoid spawning a new parsing task if the buffer is already being reparsed
 613        // due to an earlier edit.
 614        if self.is_parsing {
 615            return;
 616        }
 617
 618        if let Some(language) = self.language.clone() {
 619            self.is_parsing = true;
 620            cx.spawn(|handle, mut cx| async move {
 621                while handle.read_with(&cx, |this, _| this.should_reparse()) {
 622                    // The parse tree is out of date, so grab the syntax tree to synchronously
 623                    // splice all the edits that have happened since the last parse.
 624                    let new_tree = handle.update(&mut cx, |this, _| this.syntax_tree());
 625                    let (new_text, new_version) = handle
 626                        .read_with(&cx, |this, _| (this.visible_text.clone(), this.version()));
 627
 628                    // Parse the current text in a background thread.
 629                    let new_tree = cx
 630                        .background_executor()
 631                        .spawn({
 632                            let language = language.clone();
 633                            async move { Self::parse_text(&new_text, new_tree, &language) }
 634                        })
 635                        .await;
 636
 637                    handle.update(&mut cx, |this, cx| {
 638                        *this.syntax_tree.lock() = Some(SyntaxTree {
 639                            tree: new_tree,
 640                            parsed: true,
 641                            version: new_version,
 642                        });
 643                        cx.emit(Event::Reparsed);
 644                        cx.notify();
 645                    });
 646                }
 647                handle.update(&mut cx, |this, _| this.is_parsing = false);
 648            })
 649            .detach();
 650        }
 651    }
 652
 653    fn parse_text(text: &Rope, old_tree: Option<Tree>, language: &Language) -> Tree {
 654        PARSER.with(|parser| {
 655            let mut parser = parser.borrow_mut();
 656            parser
 657                .set_language(language.grammar)
 658                .expect("incompatible grammar");
 659            let mut chunks = text.chunks_in_range(0..text.len());
 660            let tree = parser
 661                .parse_with(
 662                    &mut move |offset, _| {
 663                        chunks.seek(offset);
 664                        chunks.next().unwrap_or("").as_bytes()
 665                    },
 666                    old_tree.as_ref(),
 667                )
 668                .unwrap();
 669            tree
 670        })
 671    }
 672
 673    pub fn range_for_syntax_ancestor<T: ToOffset>(&self, range: Range<T>) -> Option<Range<usize>> {
 674        if let Some(tree) = self.syntax_tree() {
 675            let root = tree.root_node();
 676            let range = range.start.to_offset(self)..range.end.to_offset(self);
 677            let mut node = root.descendant_for_byte_range(range.start, range.end);
 678            while node.map_or(false, |n| n.byte_range() == range) {
 679                node = node.unwrap().parent();
 680            }
 681            node.map(|n| n.byte_range())
 682        } else {
 683            None
 684        }
 685    }
 686
 687    pub fn enclosing_bracket_ranges<T: ToOffset>(
 688        &self,
 689        range: Range<T>,
 690    ) -> Option<(Range<usize>, Range<usize>)> {
 691        let (lang, tree) = self.language.as_ref().zip(self.syntax_tree())?;
 692        let open_capture_ix = lang.brackets_query.capture_index_for_name("open")?;
 693        let close_capture_ix = lang.brackets_query.capture_index_for_name("close")?;
 694
 695        // Find bracket pairs that *inclusively* contain the given range.
 696        let range = range.start.to_offset(self).saturating_sub(1)..range.end.to_offset(self) + 1;
 697        let mut cursor = QueryCursorHandle::new();
 698        let matches = cursor.set_byte_range(range).matches(
 699            &lang.brackets_query,
 700            tree.root_node(),
 701            TextProvider(&self.visible_text),
 702        );
 703
 704        // Get the ranges of the innermost pair of brackets.
 705        matches
 706            .filter_map(|mat| {
 707                let open = mat.nodes_for_capture_index(open_capture_ix).next()?;
 708                let close = mat.nodes_for_capture_index(close_capture_ix).next()?;
 709                Some((open.byte_range(), close.byte_range()))
 710            })
 711            .min_by_key(|(open_range, close_range)| close_range.end - open_range.start)
 712    }
 713
 714    fn diff(&self, new_text: Arc<str>, cx: &AppContext) -> Task<Diff> {
 715        // TODO: it would be nice to not allocate here.
 716        let old_text = self.text();
 717        let base_version = self.version();
 718        cx.background_executor().spawn(async move {
 719            let changes = TextDiff::from_lines(old_text.as_str(), new_text.as_ref())
 720                .iter_all_changes()
 721                .map(|c| (c.tag(), c.value().len()))
 722                .collect::<Vec<_>>();
 723            Diff {
 724                base_version,
 725                new_text,
 726                changes,
 727            }
 728        })
 729    }
 730
 731    fn set_text_via_diff(
 732        &mut self,
 733        diff: Diff,
 734        cx: &mut ModelContext<Self>,
 735    ) -> Option<Vec<Operation>> {
 736        if self.version == diff.base_version {
 737            self.start_transaction(None).unwrap();
 738            let mut operations = Vec::new();
 739            let mut offset = 0;
 740            for (tag, len) in diff.changes {
 741                let range = offset..(offset + len);
 742                match tag {
 743                    ChangeTag::Equal => offset += len,
 744                    ChangeTag::Delete => {
 745                        operations.push(self.edit(Some(range), "", Some(cx)).unwrap())
 746                    }
 747                    ChangeTag::Insert => {
 748                        operations.push(
 749                            self.edit(Some(offset..offset), &diff.new_text[range], Some(cx))
 750                                .unwrap(),
 751                        );
 752                        offset += len;
 753                    }
 754                }
 755            }
 756            self.end_transaction(None, Some(cx)).unwrap();
 757            Some(operations)
 758        } else {
 759            None
 760        }
 761    }
 762
 763    pub fn is_dirty(&self) -> bool {
 764        self.version > self.saved_version || self.file.as_ref().map_or(false, |f| f.is_deleted())
 765    }
 766
 767    pub fn has_conflict(&self) -> bool {
 768        self.version > self.saved_version
 769            && self
 770                .file
 771                .as_ref()
 772                .map_or(false, |f| f.mtime() > self.saved_mtime)
 773    }
 774
 775    pub fn version(&self) -> time::Global {
 776        self.version.clone()
 777    }
 778
 779    pub fn text_summary(&self) -> TextSummary {
 780        self.visible_text.summary()
 781    }
 782
 783    pub fn text_summary_for_range(&self, range: Range<usize>) -> TextSummary {
 784        self.visible_text.cursor(range.start).summary(range.end)
 785    }
 786
 787    pub fn len(&self) -> usize {
 788        self.fragments.extent::<usize>(&None)
 789    }
 790
 791    pub fn line_len(&self, row: u32) -> u32 {
 792        let row_start_offset = Point::new(row, 0).to_offset(self);
 793        let row_end_offset = if row >= self.max_point().row {
 794            self.len()
 795        } else {
 796            Point::new(row + 1, 0).to_offset(self) - 1
 797        };
 798        (row_end_offset - row_start_offset) as u32
 799    }
 800
 801    pub fn max_point(&self) -> Point {
 802        self.visible_text.max_point()
 803    }
 804
 805    pub fn row_count(&self) -> u32 {
 806        self.max_point().row + 1
 807    }
 808
 809    pub fn text(&self) -> String {
 810        self.text_for_range(0..self.len()).collect()
 811    }
 812
 813    pub fn text_for_range<'a, T: ToOffset>(&'a self, range: Range<T>) -> Chunks<'a> {
 814        let start = range.start.to_offset(self);
 815        let end = range.end.to_offset(self);
 816        self.visible_text.chunks_in_range(start..end)
 817    }
 818
 819    pub fn chars(&self) -> impl Iterator<Item = char> + '_ {
 820        self.chars_at(0)
 821    }
 822
 823    pub fn chars_at<T: ToOffset>(&self, position: T) -> impl Iterator<Item = char> + '_ {
 824        let offset = position.to_offset(self);
 825        self.visible_text.chars_at(offset)
 826    }
 827
 828    pub fn selections_changed_since(&self, since: SelectionsVersion) -> bool {
 829        self.selections_last_update != since
 830    }
 831
 832    pub fn edits_since<'a>(&'a self, since: time::Global) -> impl 'a + Iterator<Item = Edit> {
 833        let since_2 = since.clone();
 834        let cursor = self.fragments.filter(
 835            move |summary| summary.max_version.changed_since(&since_2),
 836            &None,
 837        );
 838
 839        Edits {
 840            deleted_text: &self.deleted_text,
 841            cursor,
 842            undos: &self.undo_map,
 843            since,
 844            delta: 0,
 845        }
 846    }
 847
 848    pub fn deferred_ops_len(&self) -> usize {
 849        self.deferred_ops.len()
 850    }
 851
 852    pub fn start_transaction(&mut self, set_id: Option<SelectionSetId>) -> Result<()> {
 853        self.start_transaction_at(set_id, Instant::now())
 854    }
 855
 856    fn start_transaction_at(&mut self, set_id: Option<SelectionSetId>, now: Instant) -> Result<()> {
 857        let selections = if let Some(set_id) = set_id {
 858            let selections = self
 859                .selections
 860                .get(&set_id)
 861                .ok_or_else(|| anyhow!("invalid selection set {:?}", set_id))?;
 862            Some((set_id, selections.clone()))
 863        } else {
 864            None
 865        };
 866        self.history
 867            .start_transaction(self.version.clone(), self.is_dirty(), selections, now);
 868        Ok(())
 869    }
 870
 871    pub fn end_transaction(
 872        &mut self,
 873        set_id: Option<SelectionSetId>,
 874        cx: Option<&mut ModelContext<Self>>,
 875    ) -> Result<()> {
 876        self.end_transaction_at(set_id, Instant::now(), cx)
 877    }
 878
 879    fn end_transaction_at(
 880        &mut self,
 881        set_id: Option<SelectionSetId>,
 882        now: Instant,
 883        cx: Option<&mut ModelContext<Self>>,
 884    ) -> Result<()> {
 885        let selections = if let Some(set_id) = set_id {
 886            let selections = self
 887                .selections
 888                .get(&set_id)
 889                .ok_or_else(|| anyhow!("invalid selection set {:?}", set_id))?;
 890            Some((set_id, selections.clone()))
 891        } else {
 892            None
 893        };
 894
 895        if let Some(transaction) = self.history.end_transaction(selections, now) {
 896            let since = transaction.start.clone();
 897            let was_dirty = transaction.buffer_was_dirty;
 898            self.history.group();
 899
 900            if let Some(cx) = cx {
 901                cx.notify();
 902
 903                if self.edits_since(since).next().is_some() {
 904                    self.did_edit(was_dirty, cx);
 905                    self.reparse(cx);
 906                }
 907            }
 908        }
 909
 910        Ok(())
 911    }
 912
 913    pub fn edit<I, S, T>(
 914        &mut self,
 915        ranges_iter: I,
 916        new_text: T,
 917        cx: Option<&mut ModelContext<Self>>,
 918    ) -> Option<Operation>
 919    where
 920        I: IntoIterator<Item = Range<S>>,
 921        S: ToOffset,
 922        T: Into<String>,
 923    {
 924        let new_text = new_text.into();
 925        let new_text = if new_text.len() > 0 {
 926            Some(new_text)
 927        } else {
 928            None
 929        };
 930        let has_new_text = new_text.is_some();
 931
 932        // Skip invalid ranges and coalesce contiguous ones.
 933        let mut ranges: Vec<Range<usize>> = Vec::new();
 934        for range in ranges_iter {
 935            let range = range.start.to_offset(self)..range.end.to_offset(self);
 936            if has_new_text || !range.is_empty() {
 937                if let Some(prev_range) = ranges.last_mut() {
 938                    if prev_range.end >= range.start {
 939                        prev_range.end = cmp::max(prev_range.end, range.end);
 940                    } else {
 941                        ranges.push(range);
 942                    }
 943                } else {
 944                    ranges.push(range);
 945                }
 946            }
 947        }
 948
 949        if ranges.is_empty() {
 950            None
 951        } else {
 952            self.start_transaction_at(None, Instant::now()).unwrap();
 953            let timestamp = InsertionTimestamp {
 954                replica_id: self.replica_id,
 955                local: self.local_clock.tick().value,
 956                lamport: self.lamport_clock.tick().value,
 957            };
 958            let edit = self.apply_local_edit(&ranges, new_text, timestamp);
 959
 960            self.history.push(edit.clone());
 961            self.history.push_undo(edit.timestamp.local());
 962            self.last_edit = edit.timestamp.local();
 963            self.version.observe(edit.timestamp.local());
 964
 965            self.end_transaction_at(None, Instant::now(), cx).unwrap();
 966
 967            Some(Operation::Edit(edit))
 968        }
 969    }
 970
 971    fn did_edit(&self, was_dirty: bool, cx: &mut ModelContext<Self>) {
 972        cx.emit(Event::Edited);
 973        if !was_dirty {
 974            cx.emit(Event::Dirtied);
 975        }
 976    }
 977
 978    pub fn add_selection_set(
 979        &mut self,
 980        selections: impl Into<Arc<[Selection]>>,
 981        cx: Option<&mut ModelContext<Self>>,
 982    ) -> (SelectionSetId, Operation) {
 983        let selections = selections.into();
 984        let lamport_timestamp = self.lamport_clock.tick();
 985        self.selections
 986            .insert(lamport_timestamp, Arc::clone(&selections));
 987        self.selections_last_update += 1;
 988
 989        if let Some(cx) = cx {
 990            cx.notify();
 991        }
 992
 993        (
 994            lamport_timestamp,
 995            Operation::UpdateSelections {
 996                set_id: lamport_timestamp,
 997                selections: Some(selections),
 998                lamport_timestamp,
 999            },
1000        )
1001    }
1002
1003    pub fn update_selection_set(
1004        &mut self,
1005        set_id: SelectionSetId,
1006        selections: impl Into<Arc<[Selection]>>,
1007        cx: Option<&mut ModelContext<Self>>,
1008    ) -> Result<Operation> {
1009        let selections = selections.into();
1010        self.selections.insert(set_id, selections.clone());
1011
1012        let lamport_timestamp = self.lamport_clock.tick();
1013        self.selections_last_update += 1;
1014
1015        if let Some(cx) = cx {
1016            cx.notify();
1017        }
1018
1019        Ok(Operation::UpdateSelections {
1020            set_id,
1021            selections: Some(selections),
1022            lamport_timestamp,
1023        })
1024    }
1025
1026    pub fn remove_selection_set(
1027        &mut self,
1028        set_id: SelectionSetId,
1029        cx: Option<&mut ModelContext<Self>>,
1030    ) -> Result<Operation> {
1031        self.selections
1032            .remove(&set_id)
1033            .ok_or_else(|| anyhow!("invalid selection set id {:?}", set_id))?;
1034        let lamport_timestamp = self.lamport_clock.tick();
1035        self.selections_last_update += 1;
1036
1037        if let Some(cx) = cx {
1038            cx.notify();
1039        }
1040
1041        Ok(Operation::UpdateSelections {
1042            set_id,
1043            selections: None,
1044            lamport_timestamp,
1045        })
1046    }
1047
1048    pub fn selections(&self, set_id: SelectionSetId) -> Result<&[Selection]> {
1049        self.selections
1050            .get(&set_id)
1051            .map(|s| s.as_ref())
1052            .ok_or_else(|| anyhow!("invalid selection set id {:?}", set_id))
1053    }
1054
1055    pub fn apply_ops<I: IntoIterator<Item = Operation>>(
1056        &mut self,
1057        ops: I,
1058        cx: Option<&mut ModelContext<Self>>,
1059    ) -> Result<()> {
1060        let was_dirty = self.is_dirty();
1061        let old_version = self.version.clone();
1062
1063        let mut deferred_ops = Vec::new();
1064        for op in ops {
1065            if self.can_apply_op(&op) {
1066                self.apply_op(op)?;
1067            } else {
1068                self.deferred_replicas.insert(op.replica_id());
1069                deferred_ops.push(op);
1070            }
1071        }
1072        self.deferred_ops.insert(deferred_ops);
1073        self.flush_deferred_ops()?;
1074
1075        if let Some(cx) = cx {
1076            cx.notify();
1077            if self.edits_since(old_version).next().is_some() {
1078                self.did_edit(was_dirty, cx);
1079                self.reparse(cx);
1080            }
1081        }
1082
1083        Ok(())
1084    }
1085
1086    fn apply_op(&mut self, op: Operation) -> Result<()> {
1087        match op {
1088            Operation::Edit(edit) => {
1089                if !self.version.observed(edit.timestamp.local()) {
1090                    self.apply_remote_edit(
1091                        &edit.version,
1092                        &edit.ranges,
1093                        edit.new_text.as_deref(),
1094                        edit.timestamp,
1095                    );
1096                    self.version.observe(edit.timestamp.local());
1097                    self.history.push(edit);
1098                }
1099            }
1100            Operation::Undo {
1101                undo,
1102                lamport_timestamp,
1103            } => {
1104                if !self.version.observed(undo.id) {
1105                    self.apply_undo(undo)?;
1106                    self.version.observe(undo.id);
1107                    self.lamport_clock.observe(lamport_timestamp);
1108                }
1109            }
1110            Operation::UpdateSelections {
1111                set_id,
1112                selections,
1113                lamport_timestamp,
1114            } => {
1115                if let Some(selections) = selections {
1116                    self.selections.insert(set_id, selections);
1117                } else {
1118                    self.selections.remove(&set_id);
1119                }
1120                self.lamport_clock.observe(lamport_timestamp);
1121                self.selections_last_update += 1;
1122            }
1123        }
1124        Ok(())
1125    }
1126
1127    fn apply_remote_edit(
1128        &mut self,
1129        version: &time::Global,
1130        ranges: &[Range<usize>],
1131        new_text: Option<&str>,
1132        timestamp: InsertionTimestamp,
1133    ) {
1134        if ranges.is_empty() {
1135            return;
1136        }
1137
1138        let cx = Some(version.clone());
1139        let mut new_ropes =
1140            RopeBuilder::new(self.visible_text.cursor(0), self.deleted_text.cursor(0));
1141        let mut old_fragments = self.fragments.cursor::<VersionedOffset, VersionedOffset>();
1142        let mut new_fragments =
1143            old_fragments.slice(&VersionedOffset::Offset(ranges[0].start), Bias::Left, &cx);
1144        new_ropes.push_tree(new_fragments.summary().text);
1145
1146        let mut fragment_start = old_fragments.start().offset();
1147        for range in ranges {
1148            let fragment_end = old_fragments.end(&cx).offset();
1149
1150            // If the current fragment ends before this range, then jump ahead to the first fragment
1151            // that extends past the start of this range, reusing any intervening fragments.
1152            if fragment_end < range.start {
1153                // If the current fragment has been partially consumed, then consume the rest of it
1154                // and advance to the next fragment before slicing.
1155                if fragment_start > old_fragments.start().offset() {
1156                    if fragment_end > fragment_start {
1157                        let mut suffix = old_fragments.item().unwrap().clone();
1158                        suffix.len = fragment_end - fragment_start;
1159                        new_ropes.push_fragment(&suffix, suffix.visible);
1160                        new_fragments.push(suffix, &None);
1161                    }
1162                    old_fragments.next(&cx);
1163                }
1164
1165                let slice =
1166                    old_fragments.slice(&VersionedOffset::Offset(range.start), Bias::Left, &cx);
1167                new_ropes.push_tree(slice.summary().text);
1168                new_fragments.push_tree(slice, &None);
1169                fragment_start = old_fragments.start().offset();
1170            }
1171
1172            // If we are at the end of a non-concurrent fragment, advance to the next one.
1173            let fragment_end = old_fragments.end(&cx).offset();
1174            if fragment_end == range.start && fragment_end > fragment_start {
1175                let mut fragment = old_fragments.item().unwrap().clone();
1176                fragment.len = fragment_end - fragment_start;
1177                new_ropes.push_fragment(&fragment, fragment.visible);
1178                new_fragments.push(fragment, &None);
1179                old_fragments.next(&cx);
1180                fragment_start = old_fragments.start().offset();
1181            }
1182
1183            // Skip over insertions that are concurrent to this edit, but have a lower lamport
1184            // timestamp.
1185            while let Some(fragment) = old_fragments.item() {
1186                if fragment_start == range.start
1187                    && fragment.timestamp.lamport() > timestamp.lamport()
1188                {
1189                    new_ropes.push_fragment(fragment, fragment.visible);
1190                    new_fragments.push(fragment.clone(), &None);
1191                    old_fragments.next(&cx);
1192                    debug_assert_eq!(fragment_start, range.start);
1193                } else {
1194                    break;
1195                }
1196            }
1197            debug_assert!(fragment_start <= range.start);
1198
1199            // Preserve any portion of the current fragment that precedes this range.
1200            if fragment_start < range.start {
1201                let mut prefix = old_fragments.item().unwrap().clone();
1202                prefix.len = range.start - fragment_start;
1203                fragment_start = range.start;
1204                new_ropes.push_fragment(&prefix, prefix.visible);
1205                new_fragments.push(prefix, &None);
1206            }
1207
1208            // Insert the new text before any existing fragments within the range.
1209            if let Some(new_text) = new_text {
1210                new_ropes.push_str(new_text);
1211                new_fragments.push(
1212                    Fragment {
1213                        timestamp,
1214                        len: new_text.len(),
1215                        deletions: Default::default(),
1216                        max_undos: Default::default(),
1217                        visible: true,
1218                    },
1219                    &None,
1220                );
1221            }
1222
1223            // Advance through every fragment that intersects this range, marking the intersecting
1224            // portions as deleted.
1225            while fragment_start < range.end {
1226                let fragment = old_fragments.item().unwrap();
1227                let fragment_end = old_fragments.end(&cx).offset();
1228                let mut intersection = fragment.clone();
1229                let intersection_end = cmp::min(range.end, fragment_end);
1230                if fragment.was_visible(version, &self.undo_map) {
1231                    intersection.len = intersection_end - fragment_start;
1232                    intersection.deletions.insert(timestamp.local());
1233                    intersection.visible = false;
1234                }
1235                if intersection.len > 0 {
1236                    new_ropes.push_fragment(&intersection, fragment.visible);
1237                    new_fragments.push(intersection, &None);
1238                    fragment_start = intersection_end;
1239                }
1240                if fragment_end <= range.end {
1241                    old_fragments.next(&cx);
1242                }
1243            }
1244        }
1245
1246        // If the current fragment has been partially consumed, then consume the rest of it
1247        // and advance to the next fragment before slicing.
1248        if fragment_start > old_fragments.start().offset() {
1249            let fragment_end = old_fragments.end(&cx).offset();
1250            if fragment_end > fragment_start {
1251                let mut suffix = old_fragments.item().unwrap().clone();
1252                suffix.len = fragment_end - fragment_start;
1253                new_ropes.push_fragment(&suffix, suffix.visible);
1254                new_fragments.push(suffix, &None);
1255            }
1256            old_fragments.next(&cx);
1257        }
1258
1259        let suffix = old_fragments.suffix(&cx);
1260        new_ropes.push_tree(suffix.summary().text);
1261        new_fragments.push_tree(suffix, &None);
1262        let (visible_text, deleted_text) = new_ropes.finish();
1263        drop(old_fragments);
1264
1265        self.fragments = new_fragments;
1266        self.visible_text = visible_text;
1267        self.deleted_text = deleted_text;
1268        self.local_clock.observe(timestamp.local());
1269        self.lamport_clock.observe(timestamp.lamport());
1270    }
1271
1272    pub fn undo(&mut self, mut cx: Option<&mut ModelContext<Self>>) -> Vec<Operation> {
1273        let was_dirty = self.is_dirty();
1274        let old_version = self.version.clone();
1275
1276        let mut ops = Vec::new();
1277        if let Some(transaction) = self.history.pop_undo() {
1278            let selections = transaction.selections_before.clone();
1279            for edit_id in transaction.edits.clone() {
1280                ops.push(self.undo_or_redo(edit_id).unwrap());
1281            }
1282
1283            if let Some((set_id, selections)) = selections {
1284                let _ = self.update_selection_set(set_id, selections, cx.as_deref_mut());
1285            }
1286        }
1287
1288        if let Some(cx) = cx {
1289            cx.notify();
1290            if self.edits_since(old_version).next().is_some() {
1291                self.did_edit(was_dirty, cx);
1292                self.reparse(cx);
1293            }
1294        }
1295
1296        ops
1297    }
1298
1299    pub fn redo(&mut self, mut cx: Option<&mut ModelContext<Self>>) -> Vec<Operation> {
1300        let was_dirty = self.is_dirty();
1301        let old_version = self.version.clone();
1302
1303        let mut ops = Vec::new();
1304        if let Some(transaction) = self.history.pop_redo() {
1305            let selections = transaction.selections_after.clone();
1306            for edit_id in transaction.edits.clone() {
1307                ops.push(self.undo_or_redo(edit_id).unwrap());
1308            }
1309
1310            if let Some((set_id, selections)) = selections {
1311                let _ = self.update_selection_set(set_id, selections, cx.as_deref_mut());
1312            }
1313        }
1314
1315        if let Some(cx) = cx {
1316            cx.notify();
1317            if self.edits_since(old_version).next().is_some() {
1318                self.did_edit(was_dirty, cx);
1319                self.reparse(cx);
1320            }
1321        }
1322
1323        ops
1324    }
1325
1326    fn undo_or_redo(&mut self, edit_id: time::Local) -> Result<Operation> {
1327        let undo = UndoOperation {
1328            id: self.local_clock.tick(),
1329            edit_id,
1330            count: self.undo_map.undo_count(edit_id) + 1,
1331        };
1332        self.apply_undo(undo)?;
1333        self.version.observe(undo.id);
1334
1335        Ok(Operation::Undo {
1336            undo,
1337            lamport_timestamp: self.lamport_clock.tick(),
1338        })
1339    }
1340
1341    fn apply_undo(&mut self, undo: UndoOperation) -> Result<()> {
1342        self.undo_map.insert(undo);
1343
1344        let edit = &self.history.ops[&undo.edit_id];
1345        let mut cx = edit.version.clone();
1346        cx.observe(undo.edit_id);
1347        let cx = Some(cx);
1348
1349        let mut old_fragments = self.fragments.cursor::<VersionedOffset, VersionedOffset>();
1350        let mut new_fragments = old_fragments.slice(
1351            &VersionedOffset::Offset(edit.ranges[0].start),
1352            Bias::Right,
1353            &cx,
1354        );
1355        let mut new_ropes =
1356            RopeBuilder::new(self.visible_text.cursor(0), self.deleted_text.cursor(0));
1357        new_ropes.push_tree(new_fragments.summary().text);
1358
1359        let insertion_len = edit.new_text.as_ref().map_or(0, |i| i.len());
1360        for (ix, range) in edit.ranges.iter().enumerate() {
1361            let delta = ix * insertion_len;
1362            let mut end_offset = old_fragments.end(&cx).offset();
1363
1364            if end_offset < range.start + delta {
1365                let preceding_fragments = old_fragments.slice(
1366                    &VersionedOffset::Offset(range.start + delta),
1367                    Bias::Right,
1368                    &cx,
1369                );
1370                new_ropes.push_tree(preceding_fragments.summary().text);
1371                new_fragments.push_tree(preceding_fragments, &None);
1372            }
1373
1374            while end_offset <= delta + range.end + insertion_len {
1375                if let Some(fragment) = old_fragments.item() {
1376                    let mut fragment = fragment.clone();
1377                    let fragment_was_visible = fragment.visible;
1378
1379                    if fragment.was_visible(&edit.version, &self.undo_map)
1380                        || fragment.timestamp.local() == edit.timestamp.local()
1381                    {
1382                        fragment.visible = fragment.is_visible(&self.undo_map);
1383                        fragment.max_undos.observe(undo.id);
1384                    }
1385                    new_ropes.push_fragment(&fragment, fragment_was_visible);
1386                    new_fragments.push(fragment, &None);
1387
1388                    old_fragments.next(&cx);
1389                    if end_offset == old_fragments.end(&cx).offset() {
1390                        let unseen_fragments = old_fragments.slice(
1391                            &VersionedOffset::Offset(end_offset),
1392                            Bias::Right,
1393                            &cx,
1394                        );
1395                        new_ropes.push_tree(unseen_fragments.summary().text);
1396                        new_fragments.push_tree(unseen_fragments, &None);
1397                    }
1398                    end_offset = old_fragments.end(&cx).offset();
1399                } else {
1400                    break;
1401                }
1402            }
1403        }
1404
1405        let suffix = old_fragments.suffix(&cx);
1406        new_ropes.push_tree(suffix.summary().text);
1407        new_fragments.push_tree(suffix, &None);
1408
1409        drop(old_fragments);
1410        let (visible_text, deleted_text) = new_ropes.finish();
1411        self.fragments = new_fragments;
1412        self.visible_text = visible_text;
1413        self.deleted_text = deleted_text;
1414        Ok(())
1415    }
1416
1417    fn flush_deferred_ops(&mut self) -> Result<()> {
1418        self.deferred_replicas.clear();
1419        let mut deferred_ops = Vec::new();
1420        for op in self.deferred_ops.drain().cursor().cloned() {
1421            if self.can_apply_op(&op) {
1422                self.apply_op(op)?;
1423            } else {
1424                self.deferred_replicas.insert(op.replica_id());
1425                deferred_ops.push(op);
1426            }
1427        }
1428        self.deferred_ops.insert(deferred_ops);
1429        Ok(())
1430    }
1431
1432    fn can_apply_op(&self, op: &Operation) -> bool {
1433        if self.deferred_replicas.contains(&op.replica_id()) {
1434            false
1435        } else {
1436            match op {
1437                Operation::Edit(edit) => self.version >= edit.version,
1438                Operation::Undo { undo, .. } => self.version.observed(undo.edit_id),
1439                Operation::UpdateSelections { selections, .. } => {
1440                    if let Some(selections) = selections {
1441                        selections.iter().all(|selection| {
1442                            let contains_start = match &selection.start {
1443                                Anchor::Middle { version, .. } => self.version >= *version,
1444                                _ => true,
1445                            };
1446                            let contains_end = match &selection.end {
1447                                Anchor::Middle { version, .. } => self.version >= *version,
1448                                _ => true,
1449                            };
1450                            contains_start && contains_end
1451                        })
1452                    } else {
1453                        true
1454                    }
1455                }
1456            }
1457        }
1458    }
1459
1460    fn apply_local_edit(
1461        &mut self,
1462        ranges: &[Range<usize>],
1463        new_text: Option<String>,
1464        timestamp: InsertionTimestamp,
1465    ) -> EditOperation {
1466        let mut edit = EditOperation {
1467            timestamp,
1468            version: self.version(),
1469            ranges: Vec::with_capacity(ranges.len()),
1470            new_text: None,
1471        };
1472
1473        let mut new_ropes =
1474            RopeBuilder::new(self.visible_text.cursor(0), self.deleted_text.cursor(0));
1475        let mut old_fragments = self.fragments.cursor::<usize, FragmentTextSummary>();
1476        let mut new_fragments = old_fragments.slice(&ranges[0].start, Bias::Right, &None);
1477        new_ropes.push_tree(new_fragments.summary().text);
1478
1479        let mut fragment_start = old_fragments.start().visible;
1480        for range in ranges {
1481            let fragment_end = old_fragments.end(&None).visible;
1482
1483            // If the current fragment ends before this range, then jump ahead to the first fragment
1484            // that extends past the start of this range, reusing any intervening fragments.
1485            if fragment_end < range.start {
1486                // If the current fragment has been partially consumed, then consume the rest of it
1487                // and advance to the next fragment before slicing.
1488                if fragment_start > old_fragments.start().visible {
1489                    if fragment_end > fragment_start {
1490                        let mut suffix = old_fragments.item().unwrap().clone();
1491                        suffix.len = fragment_end - fragment_start;
1492                        new_ropes.push_fragment(&suffix, suffix.visible);
1493                        new_fragments.push(suffix, &None);
1494                    }
1495                    old_fragments.next(&None);
1496                }
1497
1498                let slice = old_fragments.slice(&range.start, Bias::Right, &None);
1499                new_ropes.push_tree(slice.summary().text);
1500                new_fragments.push_tree(slice, &None);
1501                fragment_start = old_fragments.start().visible;
1502            }
1503
1504            let full_range_start = range.start + old_fragments.start().deleted;
1505
1506            // Preserve any portion of the current fragment that precedes this range.
1507            if fragment_start < range.start {
1508                let mut prefix = old_fragments.item().unwrap().clone();
1509                prefix.len = range.start - fragment_start;
1510                new_ropes.push_fragment(&prefix, prefix.visible);
1511                new_fragments.push(prefix, &None);
1512                fragment_start = range.start;
1513            }
1514
1515            // Insert the new text before any existing fragments within the range.
1516            if let Some(new_text) = new_text.as_deref() {
1517                new_ropes.push_str(new_text);
1518                new_fragments.push(
1519                    Fragment {
1520                        timestamp,
1521                        len: new_text.len(),
1522                        deletions: Default::default(),
1523                        max_undos: Default::default(),
1524                        visible: true,
1525                    },
1526                    &None,
1527                );
1528            }
1529
1530            // Advance through every fragment that intersects this range, marking the intersecting
1531            // portions as deleted.
1532            while fragment_start < range.end {
1533                let fragment = old_fragments.item().unwrap();
1534                let fragment_end = old_fragments.end(&None).visible;
1535                let mut intersection = fragment.clone();
1536                let intersection_end = cmp::min(range.end, fragment_end);
1537                if fragment.visible {
1538                    intersection.len = intersection_end - fragment_start;
1539                    intersection.deletions.insert(timestamp.local());
1540                    intersection.visible = false;
1541                }
1542                if intersection.len > 0 {
1543                    new_ropes.push_fragment(&intersection, fragment.visible);
1544                    new_fragments.push(intersection, &None);
1545                    fragment_start = intersection_end;
1546                }
1547                if fragment_end <= range.end {
1548                    old_fragments.next(&None);
1549                }
1550            }
1551
1552            let full_range_end = range.end + old_fragments.start().deleted;
1553            edit.ranges.push(full_range_start..full_range_end);
1554        }
1555
1556        // If the current fragment has been partially consumed, then consume the rest of it
1557        // and advance to the next fragment before slicing.
1558        if fragment_start > old_fragments.start().visible {
1559            let fragment_end = old_fragments.end(&None).visible;
1560            if fragment_end > fragment_start {
1561                let mut suffix = old_fragments.item().unwrap().clone();
1562                suffix.len = fragment_end - fragment_start;
1563                new_ropes.push_fragment(&suffix, suffix.visible);
1564                new_fragments.push(suffix, &None);
1565            }
1566            old_fragments.next(&None);
1567        }
1568
1569        let suffix = old_fragments.suffix(&None);
1570        new_ropes.push_tree(suffix.summary().text);
1571        new_fragments.push_tree(suffix, &None);
1572        let (visible_text, deleted_text) = new_ropes.finish();
1573        drop(old_fragments);
1574
1575        self.fragments = new_fragments;
1576        self.visible_text = visible_text;
1577        self.deleted_text = deleted_text;
1578        edit.new_text = new_text;
1579        edit
1580    }
1581
1582    pub fn anchor_before<T: ToOffset>(&self, position: T) -> Anchor {
1583        self.anchor_at(position, Bias::Left)
1584    }
1585
1586    pub fn anchor_after<T: ToOffset>(&self, position: T) -> Anchor {
1587        self.anchor_at(position, Bias::Right)
1588    }
1589
1590    pub fn anchor_at<T: ToOffset>(&self, position: T, bias: Bias) -> Anchor {
1591        let offset = position.to_offset(self);
1592        let max_offset = self.len();
1593        assert!(offset <= max_offset, "offset is out of range");
1594
1595        if offset == 0 && bias == Bias::Left {
1596            Anchor::Start
1597        } else if offset == max_offset && bias == Bias::Right {
1598            Anchor::End
1599        } else {
1600            let mut cursor = self.fragments.cursor::<usize, FragmentTextSummary>();
1601            cursor.seek(&offset, bias, &None);
1602            Anchor::Middle {
1603                offset: offset + cursor.start().deleted,
1604                bias,
1605                version: self.version(),
1606            }
1607        }
1608    }
1609
1610    fn summary_for_anchor(&self, anchor: &Anchor) -> TextSummary {
1611        match anchor {
1612            Anchor::Start => TextSummary::default(),
1613            Anchor::End => self.text_summary(),
1614            Anchor::Middle {
1615                offset,
1616                bias,
1617                version,
1618            } => {
1619                let mut cursor = self
1620                    .fragments
1621                    .cursor::<VersionedOffset, (VersionedOffset, usize)>();
1622                cursor.seek(
1623                    &VersionedOffset::Offset(*offset),
1624                    *bias,
1625                    &Some(version.clone()),
1626                );
1627                let fragment = cursor.item().unwrap();
1628                let overshoot = if fragment.visible {
1629                    offset - cursor.start().0.offset()
1630                } else {
1631                    0
1632                };
1633
1634                self.text_summary_for_range(0..cursor.start().1 + overshoot)
1635            }
1636        }
1637    }
1638
1639    fn full_offset_for_anchor(&self, anchor: &Anchor) -> usize {
1640        match anchor {
1641            Anchor::Start => 0,
1642            Anchor::End => {
1643                let summary = self.fragments.summary();
1644                summary.text.visible + summary.text.deleted
1645            }
1646            Anchor::Middle {
1647                offset,
1648                bias,
1649                version,
1650            } => {
1651                let mut cursor = self
1652                    .fragments
1653                    .cursor::<VersionedOffset, (VersionedOffset, FragmentTextSummary)>();
1654                cursor.seek(
1655                    &VersionedOffset::Offset(*offset),
1656                    *bias,
1657                    &Some(version.clone()),
1658                );
1659                let overshoot = offset - cursor.start().0.offset();
1660                let summary = cursor.start().1;
1661                summary.visible + summary.deleted + overshoot
1662            }
1663        }
1664    }
1665
1666    pub fn point_for_offset(&self, offset: usize) -> Result<Point> {
1667        if offset <= self.len() {
1668            Ok(self.text_summary_for_range(0..offset).lines)
1669        } else {
1670            Err(anyhow!("offset out of bounds"))
1671        }
1672    }
1673
1674    pub fn clip_point(&self, point: Point, bias: Bias) -> Point {
1675        self.visible_text.clip_point(point, bias)
1676    }
1677
1678    pub fn clip_offset(&self, offset: usize, bias: Bias) -> usize {
1679        self.visible_text.clip_offset(offset, bias)
1680    }
1681}
1682
1683impl Clone for Buffer {
1684    fn clone(&self) -> Self {
1685        Self {
1686            fragments: self.fragments.clone(),
1687            visible_text: self.visible_text.clone(),
1688            deleted_text: self.deleted_text.clone(),
1689            version: self.version.clone(),
1690            saved_version: self.saved_version.clone(),
1691            saved_mtime: self.saved_mtime,
1692            last_edit: self.last_edit.clone(),
1693            undo_map: self.undo_map.clone(),
1694            history: self.history.clone(),
1695            selections: self.selections.clone(),
1696            selections_last_update: self.selections_last_update.clone(),
1697            deferred_ops: self.deferred_ops.clone(),
1698            file: self.file.clone(),
1699            language: self.language.clone(),
1700            syntax_tree: Mutex::new(self.syntax_tree.lock().clone()),
1701            is_parsing: false,
1702            deferred_replicas: self.deferred_replicas.clone(),
1703            replica_id: self.replica_id,
1704            local_clock: self.local_clock.clone(),
1705            lamport_clock: self.lamport_clock.clone(),
1706        }
1707    }
1708}
1709
1710pub struct Snapshot {
1711    text: Rope,
1712    tree: Option<Tree>,
1713    language: Option<Arc<Language>>,
1714    query_cursor: QueryCursorHandle,
1715}
1716
1717impl Snapshot {
1718    pub fn len(&self) -> usize {
1719        self.text.len()
1720    }
1721
1722    pub fn text(&self) -> Rope {
1723        self.text.clone()
1724    }
1725
1726    pub fn text_for_range(&self, range: Range<usize>) -> Chunks {
1727        self.text.chunks_in_range(range)
1728    }
1729
1730    pub fn highlighted_text_for_range(&mut self, range: Range<usize>) -> HighlightedChunks {
1731        let chunks = self.text.chunks_in_range(range.clone());
1732        if let Some((language, tree)) = self.language.as_ref().zip(self.tree.as_ref()) {
1733            let captures = self.query_cursor.set_byte_range(range.clone()).captures(
1734                &language.highlight_query,
1735                tree.root_node(),
1736                TextProvider(&self.text),
1737            );
1738
1739            HighlightedChunks {
1740                range,
1741                chunks,
1742                highlights: Some(Highlights {
1743                    captures,
1744                    next_capture: None,
1745                    stack: Default::default(),
1746                    theme_mapping: language.theme_mapping(),
1747                }),
1748            }
1749        } else {
1750            HighlightedChunks {
1751                range,
1752                chunks,
1753                highlights: None,
1754            }
1755        }
1756    }
1757
1758    pub fn clip_offset(&self, offset: usize, bias: Bias) -> usize {
1759        self.text.clip_offset(offset, bias)
1760    }
1761
1762    pub fn clip_point(&self, point: Point, bias: Bias) -> Point {
1763        self.text.clip_point(point, bias)
1764    }
1765
1766    pub fn to_offset(&self, point: Point) -> usize {
1767        self.text.to_offset(point)
1768    }
1769
1770    pub fn to_point(&self, offset: usize) -> Point {
1771        self.text.to_point(offset)
1772    }
1773}
1774
1775struct RopeBuilder<'a> {
1776    old_visible_cursor: rope::Cursor<'a>,
1777    old_deleted_cursor: rope::Cursor<'a>,
1778    new_visible: Rope,
1779    new_deleted: Rope,
1780}
1781
1782impl<'a> RopeBuilder<'a> {
1783    fn new(old_visible_cursor: rope::Cursor<'a>, old_deleted_cursor: rope::Cursor<'a>) -> Self {
1784        Self {
1785            old_visible_cursor,
1786            old_deleted_cursor,
1787            new_visible: Rope::new(),
1788            new_deleted: Rope::new(),
1789        }
1790    }
1791
1792    fn push_tree(&mut self, len: FragmentTextSummary) {
1793        self.push(len.visible, true, true);
1794        self.push(len.deleted, false, false);
1795    }
1796
1797    fn push_fragment(&mut self, fragment: &Fragment, was_visible: bool) {
1798        debug_assert!(fragment.len > 0);
1799        self.push(fragment.len, was_visible, fragment.visible)
1800    }
1801
1802    fn push(&mut self, len: usize, was_visible: bool, is_visible: bool) {
1803        let text = if was_visible {
1804            self.old_visible_cursor
1805                .slice(self.old_visible_cursor.offset() + len)
1806        } else {
1807            self.old_deleted_cursor
1808                .slice(self.old_deleted_cursor.offset() + len)
1809        };
1810        if is_visible {
1811            self.new_visible.append(text);
1812        } else {
1813            self.new_deleted.append(text);
1814        }
1815    }
1816
1817    fn push_str(&mut self, text: &str) {
1818        self.new_visible.push(text);
1819    }
1820
1821    fn finish(mut self) -> (Rope, Rope) {
1822        self.new_visible.append(self.old_visible_cursor.suffix());
1823        self.new_deleted.append(self.old_deleted_cursor.suffix());
1824        (self.new_visible, self.new_deleted)
1825    }
1826}
1827
1828#[derive(Clone, Debug, Eq, PartialEq)]
1829pub enum Event {
1830    Edited,
1831    Dirtied,
1832    Saved,
1833    FileHandleChanged,
1834    Reloaded,
1835    Reparsed,
1836}
1837
1838impl Entity for Buffer {
1839    type Event = Event;
1840}
1841
1842impl<'a, F: Fn(&FragmentSummary) -> bool> Iterator for Edits<'a, F> {
1843    type Item = Edit;
1844
1845    fn next(&mut self) -> Option<Self::Item> {
1846        let mut change: Option<Edit> = None;
1847
1848        while let Some(fragment) = self.cursor.item() {
1849            let new_offset = self.cursor.start().visible;
1850            let old_offset = (new_offset as isize - self.delta) as usize;
1851
1852            if !fragment.was_visible(&self.since, &self.undos) && fragment.visible {
1853                if let Some(ref mut change) = change {
1854                    if change.new_range.end == new_offset {
1855                        change.new_range.end += fragment.len;
1856                        self.delta += fragment.len as isize;
1857                    } else {
1858                        break;
1859                    }
1860                } else {
1861                    change = Some(Edit {
1862                        old_range: old_offset..old_offset,
1863                        new_range: new_offset..new_offset + fragment.len,
1864                        old_lines: Point::zero(),
1865                    });
1866                    self.delta += fragment.len as isize;
1867                }
1868            } else if fragment.was_visible(&self.since, &self.undos) && !fragment.visible {
1869                let deleted_start = self.cursor.start().deleted;
1870                let old_lines = self.deleted_text.to_point(deleted_start + fragment.len)
1871                    - self.deleted_text.to_point(deleted_start);
1872                if let Some(ref mut change) = change {
1873                    if change.new_range.end == new_offset {
1874                        change.old_range.end += fragment.len;
1875                        change.old_lines += &old_lines;
1876                        self.delta -= fragment.len as isize;
1877                    } else {
1878                        break;
1879                    }
1880                } else {
1881                    change = Some(Edit {
1882                        old_range: old_offset..old_offset + fragment.len,
1883                        new_range: new_offset..new_offset,
1884                        old_lines,
1885                    });
1886                    self.delta -= fragment.len as isize;
1887                }
1888            }
1889
1890            self.cursor.next(&None);
1891        }
1892
1893        change
1894    }
1895}
1896
1897struct ByteChunks<'a>(rope::Chunks<'a>);
1898
1899impl<'a> Iterator for ByteChunks<'a> {
1900    type Item = &'a [u8];
1901
1902    fn next(&mut self) -> Option<Self::Item> {
1903        self.0.next().map(str::as_bytes)
1904    }
1905}
1906
1907struct TextProvider<'a>(&'a Rope);
1908
1909impl<'a> tree_sitter::TextProvider<'a> for TextProvider<'a> {
1910    type I = ByteChunks<'a>;
1911
1912    fn text(&mut self, node: tree_sitter::Node) -> Self::I {
1913        ByteChunks(self.0.chunks_in_range(node.byte_range()))
1914    }
1915}
1916
1917struct Highlights<'a> {
1918    captures: tree_sitter::QueryCaptures<'a, 'a, TextProvider<'a>>,
1919    next_capture: Option<(tree_sitter::QueryMatch<'a, 'a>, usize)>,
1920    stack: Vec<(usize, StyleId)>,
1921    theme_mapping: ThemeMap,
1922}
1923
1924pub struct HighlightedChunks<'a> {
1925    range: Range<usize>,
1926    chunks: Chunks<'a>,
1927    highlights: Option<Highlights<'a>>,
1928}
1929
1930impl<'a> HighlightedChunks<'a> {
1931    pub fn seek(&mut self, offset: usize) {
1932        self.range.start = offset;
1933        self.chunks.seek(self.range.start);
1934        if let Some(highlights) = self.highlights.as_mut() {
1935            highlights
1936                .stack
1937                .retain(|(end_offset, _)| *end_offset > offset);
1938            if let Some((mat, capture_ix)) = &highlights.next_capture {
1939                let capture = mat.captures[*capture_ix as usize];
1940                if offset >= capture.node.start_byte() {
1941                    let next_capture_end = capture.node.end_byte();
1942                    if offset < next_capture_end {
1943                        highlights.stack.push((
1944                            next_capture_end,
1945                            highlights.theme_mapping.get(capture.index),
1946                        ));
1947                    }
1948                    highlights.next_capture.take();
1949                }
1950            }
1951            highlights.captures.set_byte_range(self.range.clone());
1952        }
1953    }
1954
1955    pub fn offset(&self) -> usize {
1956        self.range.start
1957    }
1958}
1959
1960impl<'a> Iterator for HighlightedChunks<'a> {
1961    type Item = (&'a str, StyleId);
1962
1963    fn next(&mut self) -> Option<Self::Item> {
1964        let mut next_capture_start = usize::MAX;
1965
1966        if let Some(highlights) = self.highlights.as_mut() {
1967            while let Some((parent_capture_end, _)) = highlights.stack.last() {
1968                if *parent_capture_end <= self.range.start {
1969                    highlights.stack.pop();
1970                } else {
1971                    break;
1972                }
1973            }
1974
1975            if highlights.next_capture.is_none() {
1976                highlights.next_capture = highlights.captures.next();
1977            }
1978
1979            while let Some((mat, capture_ix)) = highlights.next_capture.as_ref() {
1980                let capture = mat.captures[*capture_ix as usize];
1981                if self.range.start < capture.node.start_byte() {
1982                    next_capture_start = capture.node.start_byte();
1983                    break;
1984                } else {
1985                    let style_id = highlights.theme_mapping.get(capture.index);
1986                    highlights.stack.push((capture.node.end_byte(), style_id));
1987                    highlights.next_capture = highlights.captures.next();
1988                }
1989            }
1990        }
1991
1992        if let Some(chunk) = self.chunks.peek() {
1993            let chunk_start = self.range.start;
1994            let mut chunk_end = (self.chunks.offset() + chunk.len()).min(next_capture_start);
1995            let mut style_id = StyleId::default();
1996            if let Some((parent_capture_end, parent_style_id)) =
1997                self.highlights.as_ref().and_then(|h| h.stack.last())
1998            {
1999                chunk_end = chunk_end.min(*parent_capture_end);
2000                style_id = *parent_style_id;
2001            }
2002
2003            let slice =
2004                &chunk[chunk_start - self.chunks.offset()..chunk_end - self.chunks.offset()];
2005            self.range.start = chunk_end;
2006            if self.range.start == self.chunks.offset() + chunk.len() {
2007                self.chunks.next().unwrap();
2008            }
2009
2010            Some((slice, style_id))
2011        } else {
2012            None
2013        }
2014    }
2015}
2016
2017impl Fragment {
2018    fn is_visible(&self, undos: &UndoMap) -> bool {
2019        !undos.is_undone(self.timestamp.local())
2020            && self.deletions.iter().all(|d| undos.is_undone(*d))
2021    }
2022
2023    fn was_visible(&self, version: &time::Global, undos: &UndoMap) -> bool {
2024        (version.observed(self.timestamp.local())
2025            && !undos.was_undone(self.timestamp.local(), version))
2026            && self
2027                .deletions
2028                .iter()
2029                .all(|d| !version.observed(*d) || undos.was_undone(*d, version))
2030    }
2031}
2032
2033impl sum_tree::Item for Fragment {
2034    type Summary = FragmentSummary;
2035
2036    fn summary(&self) -> Self::Summary {
2037        let mut max_version = time::Global::new();
2038        max_version.observe(self.timestamp.local());
2039        for deletion in &self.deletions {
2040            max_version.observe(*deletion);
2041        }
2042        max_version.join(&self.max_undos);
2043
2044        let mut min_insertion_version = time::Global::new();
2045        min_insertion_version.observe(self.timestamp.local());
2046        let max_insertion_version = min_insertion_version.clone();
2047        if self.visible {
2048            FragmentSummary {
2049                text: FragmentTextSummary {
2050                    visible: self.len,
2051                    deleted: 0,
2052                },
2053                max_version,
2054                min_insertion_version,
2055                max_insertion_version,
2056            }
2057        } else {
2058            FragmentSummary {
2059                text: FragmentTextSummary {
2060                    visible: 0,
2061                    deleted: self.len,
2062                },
2063                max_version,
2064                min_insertion_version,
2065                max_insertion_version,
2066            }
2067        }
2068    }
2069}
2070
2071impl sum_tree::Summary for FragmentSummary {
2072    type Context = Option<time::Global>;
2073
2074    fn add_summary(&mut self, other: &Self, _: &Self::Context) {
2075        self.text.visible += &other.text.visible;
2076        self.text.deleted += &other.text.deleted;
2077        self.max_version.join(&other.max_version);
2078        self.min_insertion_version
2079            .meet(&other.min_insertion_version);
2080        self.max_insertion_version
2081            .join(&other.max_insertion_version);
2082    }
2083}
2084
2085impl Default for FragmentSummary {
2086    fn default() -> Self {
2087        FragmentSummary {
2088            text: FragmentTextSummary::default(),
2089            max_version: time::Global::new(),
2090            min_insertion_version: time::Global::new(),
2091            max_insertion_version: time::Global::new(),
2092        }
2093    }
2094}
2095
2096impl<'a> sum_tree::Dimension<'a, FragmentSummary> for usize {
2097    fn add_summary(&mut self, summary: &FragmentSummary, _: &Option<time::Global>) {
2098        *self += summary.text.visible;
2099    }
2100}
2101
2102#[derive(Copy, Clone, Debug, Eq, PartialEq)]
2103enum VersionedOffset {
2104    Offset(usize),
2105    InvalidVersion,
2106}
2107
2108impl VersionedOffset {
2109    fn offset(&self) -> usize {
2110        if let Self::Offset(offset) = self {
2111            *offset
2112        } else {
2113            panic!("invalid version")
2114        }
2115    }
2116}
2117
2118impl Default for VersionedOffset {
2119    fn default() -> Self {
2120        Self::Offset(0)
2121    }
2122}
2123
2124impl<'a> sum_tree::Dimension<'a, FragmentSummary> for VersionedOffset {
2125    fn add_summary(&mut self, summary: &'a FragmentSummary, cx: &Option<time::Global>) {
2126        if let Self::Offset(offset) = self {
2127            let version = cx.as_ref().unwrap();
2128            if *version >= summary.max_insertion_version {
2129                *offset += summary.text.visible + summary.text.deleted;
2130            } else if !summary
2131                .min_insertion_version
2132                .iter()
2133                .all(|t| !version.observed(*t))
2134            {
2135                *self = Self::InvalidVersion;
2136            }
2137        }
2138    }
2139}
2140
2141impl<'a> sum_tree::SeekDimension<'a, FragmentSummary> for VersionedOffset {
2142    fn cmp(&self, other: &Self, _: &Option<time::Global>) -> cmp::Ordering {
2143        match (self, other) {
2144            (Self::Offset(a), Self::Offset(b)) => Ord::cmp(a, b),
2145            (Self::Offset(_), Self::InvalidVersion) => cmp::Ordering::Less,
2146            (Self::InvalidVersion, _) => unreachable!(),
2147        }
2148    }
2149}
2150
2151impl Operation {
2152    fn replica_id(&self) -> ReplicaId {
2153        self.lamport_timestamp().replica_id
2154    }
2155
2156    fn lamport_timestamp(&self) -> time::Lamport {
2157        match self {
2158            Operation::Edit(edit) => edit.timestamp.lamport(),
2159            Operation::Undo {
2160                lamport_timestamp, ..
2161            } => *lamport_timestamp,
2162            Operation::UpdateSelections {
2163                lamport_timestamp, ..
2164            } => *lamport_timestamp,
2165        }
2166    }
2167
2168    pub fn is_edit(&self) -> bool {
2169        match self {
2170            Operation::Edit { .. } => true,
2171            _ => false,
2172        }
2173    }
2174}
2175
2176impl operation_queue::Operation for Operation {
2177    fn timestamp(&self) -> time::Lamport {
2178        self.lamport_timestamp()
2179    }
2180}
2181
2182pub trait ToOffset {
2183    fn to_offset(&self, buffer: &Buffer) -> usize;
2184}
2185
2186impl ToOffset for Point {
2187    fn to_offset(&self, buffer: &Buffer) -> usize {
2188        buffer.visible_text.to_offset(*self)
2189    }
2190}
2191
2192impl ToOffset for usize {
2193    fn to_offset(&self, _: &Buffer) -> usize {
2194        *self
2195    }
2196}
2197
2198impl ToOffset for Anchor {
2199    fn to_offset(&self, buffer: &Buffer) -> usize {
2200        buffer.summary_for_anchor(self).bytes
2201    }
2202}
2203
2204impl<'a> ToOffset for &'a Anchor {
2205    fn to_offset(&self, buffer: &Buffer) -> usize {
2206        buffer.summary_for_anchor(self).bytes
2207    }
2208}
2209
2210pub trait ToPoint {
2211    fn to_point(&self, buffer: &Buffer) -> Point;
2212}
2213
2214impl ToPoint for Anchor {
2215    fn to_point(&self, buffer: &Buffer) -> Point {
2216        buffer.summary_for_anchor(self).lines
2217    }
2218}
2219
2220impl ToPoint for usize {
2221    fn to_point(&self, buffer: &Buffer) -> Point {
2222        buffer.visible_text.to_point(*self)
2223    }
2224}
2225
2226#[cfg(test)]
2227mod tests {
2228    use super::*;
2229    use crate::{
2230        test::{build_app_state, temp_tree},
2231        util::RandomCharIter,
2232        worktree::{Worktree, WorktreeHandle},
2233    };
2234    use gpui::{App, ModelHandle};
2235    use rand::prelude::*;
2236    use serde_json::json;
2237    use std::{
2238        cell::RefCell,
2239        cmp::Ordering,
2240        env, fs,
2241        iter::FromIterator,
2242        rc::Rc,
2243        sync::atomic::{self, AtomicUsize},
2244    };
2245
2246    #[gpui::test]
2247    fn test_edit(cx: &mut gpui::MutableAppContext) {
2248        cx.add_model(|cx| {
2249            let mut buffer = Buffer::new(0, "abc", cx);
2250            assert_eq!(buffer.text(), "abc");
2251            buffer.edit(vec![3..3], "def", None).unwrap();
2252            assert_eq!(buffer.text(), "abcdef");
2253            buffer.edit(vec![0..0], "ghi", None).unwrap();
2254            assert_eq!(buffer.text(), "ghiabcdef");
2255            buffer.edit(vec![5..5], "jkl", None).unwrap();
2256            assert_eq!(buffer.text(), "ghiabjklcdef");
2257            buffer.edit(vec![6..7], "", None).unwrap();
2258            assert_eq!(buffer.text(), "ghiabjlcdef");
2259            buffer.edit(vec![4..9], "mno", None).unwrap();
2260            assert_eq!(buffer.text(), "ghiamnoef");
2261            buffer
2262        });
2263    }
2264
2265    #[gpui::test]
2266    fn test_edit_events(cx: &mut gpui::MutableAppContext) {
2267        let mut now = Instant::now();
2268        let buffer_1_events = Rc::new(RefCell::new(Vec::new()));
2269        let buffer_2_events = Rc::new(RefCell::new(Vec::new()));
2270
2271        let buffer1 = cx.add_model(|cx| Buffer::new(0, "abcdef", cx));
2272        let buffer2 = cx.add_model(|cx| Buffer::new(1, "abcdef", cx));
2273        let mut buffer_ops = Vec::new();
2274        buffer1.update(cx, |buffer, cx| {
2275            let buffer_1_events = buffer_1_events.clone();
2276            cx.subscribe(&buffer1, move |_, event, _| {
2277                buffer_1_events.borrow_mut().push(event.clone())
2278            });
2279            let buffer_2_events = buffer_2_events.clone();
2280            cx.subscribe(&buffer2, move |_, event, _| {
2281                buffer_2_events.borrow_mut().push(event.clone())
2282            });
2283
2284            // An edit emits an edited event, followed by a dirtied event,
2285            // since the buffer was previously in a clean state.
2286            let op = buffer.edit(Some(2..4), "XYZ", Some(cx)).unwrap();
2287            buffer_ops.push(op);
2288
2289            // An empty transaction does not emit any events.
2290            buffer.start_transaction(None).unwrap();
2291            buffer.end_transaction(None, Some(cx)).unwrap();
2292
2293            // A transaction containing two edits emits one edited event.
2294            now += Duration::from_secs(1);
2295            buffer.start_transaction_at(None, now).unwrap();
2296            buffer_ops.push(buffer.edit(Some(5..5), "u", Some(cx)).unwrap());
2297            buffer_ops.push(buffer.edit(Some(6..6), "w", Some(cx)).unwrap());
2298            buffer.end_transaction_at(None, now, Some(cx)).unwrap();
2299
2300            // Undoing a transaction emits one edited event.
2301            let ops = buffer.undo(Some(cx));
2302            buffer_ops.extend_from_slice(&ops);
2303        });
2304
2305        // Incorporating a set of remote ops emits a single edited event,
2306        // followed by a dirtied event.
2307        buffer2.update(cx, |buffer, cx| {
2308            buffer.apply_ops(buffer_ops, Some(cx)).unwrap();
2309        });
2310
2311        let buffer_1_events = buffer_1_events.borrow();
2312        assert_eq!(
2313            *buffer_1_events,
2314            vec![Event::Edited, Event::Dirtied, Event::Edited, Event::Edited]
2315        );
2316
2317        let buffer_2_events = buffer_2_events.borrow();
2318        assert_eq!(*buffer_2_events, vec![Event::Edited, Event::Dirtied]);
2319    }
2320
2321    #[gpui::test]
2322    fn test_random_edits(cx: &mut gpui::MutableAppContext) {
2323        let iterations = env::var("ITERATIONS")
2324            .map(|i| i.parse().expect("invalid `ITERATIONS` variable"))
2325            .unwrap_or(100);
2326        let operations = env::var("OPERATIONS")
2327            .map(|i| i.parse().expect("invalid `OPERATIONS` variable"))
2328            .unwrap_or(10);
2329        let start_seed =
2330            env::var("SEED").map_or(0, |seed| seed.parse().expect("invalid `SEED` variable"));
2331
2332        for seed in start_seed..start_seed + iterations {
2333            println!("{:?}", seed);
2334            let mut rng = &mut StdRng::seed_from_u64(seed);
2335
2336            let reference_string_len = rng.gen_range(0..3);
2337            let mut reference_string = RandomCharIter::new(&mut rng)
2338                .take(reference_string_len)
2339                .collect::<String>();
2340            cx.add_model(|cx| {
2341                let mut buffer = Buffer::new(0, reference_string.as_str(), cx);
2342                let mut buffer_versions = Vec::new();
2343                log::info!(
2344                    "buffer text {:?}, version: {:?}",
2345                    buffer.text(),
2346                    buffer.version()
2347                );
2348
2349                for _i in 0..operations {
2350                    let (old_ranges, new_text, _) = buffer.randomly_mutate(rng, None);
2351                    for old_range in old_ranges.iter().rev() {
2352                        reference_string.replace_range(old_range.clone(), &new_text);
2353                    }
2354                    assert_eq!(buffer.text(), reference_string);
2355                    log::info!(
2356                        "buffer text {:?}, version: {:?}",
2357                        buffer.text(),
2358                        buffer.version()
2359                    );
2360
2361                    if rng.gen_bool(0.25) {
2362                        buffer.randomly_undo_redo(rng);
2363                        reference_string = buffer.text();
2364                    }
2365
2366                    let range = buffer.random_byte_range(0, rng);
2367                    assert_eq!(
2368                        buffer.text_summary_for_range(range.clone()),
2369                        TextSummary::from(&reference_string[range])
2370                    );
2371
2372                    if rng.gen_bool(0.3) {
2373                        buffer_versions.push(buffer.clone());
2374                    }
2375                }
2376
2377                for mut old_buffer in buffer_versions {
2378                    let edits = buffer
2379                        .edits_since(old_buffer.version.clone())
2380                        .collect::<Vec<_>>();
2381
2382                    log::info!(
2383                        "mutating old buffer version {:?}, text: {:?}, edits since: {:?}",
2384                        old_buffer.version(),
2385                        old_buffer.text(),
2386                        edits,
2387                    );
2388
2389                    let mut delta = 0_isize;
2390                    for Edit {
2391                        old_range,
2392                        new_range,
2393                        ..
2394                    } in edits
2395                    {
2396                        let old_len = old_range.end - old_range.start;
2397                        let new_len = new_range.end - new_range.start;
2398                        let old_start = (old_range.start as isize + delta) as usize;
2399                        let new_text: String = buffer.text_for_range(new_range).collect();
2400                        old_buffer.edit(Some(old_start..old_start + old_len), new_text, None);
2401
2402                        delta += new_len as isize - old_len as isize;
2403                    }
2404                    assert_eq!(old_buffer.text(), buffer.text());
2405                }
2406
2407                buffer
2408            });
2409        }
2410    }
2411
2412    #[gpui::test]
2413    fn test_line_len(cx: &mut gpui::MutableAppContext) {
2414        cx.add_model(|cx| {
2415            let mut buffer = Buffer::new(0, "", cx);
2416            buffer.edit(vec![0..0], "abcd\nefg\nhij", None).unwrap();
2417            buffer.edit(vec![12..12], "kl\nmno", None).unwrap();
2418            buffer.edit(vec![18..18], "\npqrs\n", None).unwrap();
2419            buffer.edit(vec![18..21], "\nPQ", None).unwrap();
2420
2421            assert_eq!(buffer.line_len(0), 4);
2422            assert_eq!(buffer.line_len(1), 3);
2423            assert_eq!(buffer.line_len(2), 5);
2424            assert_eq!(buffer.line_len(3), 3);
2425            assert_eq!(buffer.line_len(4), 4);
2426            assert_eq!(buffer.line_len(5), 0);
2427            buffer
2428        });
2429    }
2430
2431    #[gpui::test]
2432    fn test_text_summary_for_range(cx: &mut gpui::MutableAppContext) {
2433        cx.add_model(|cx| {
2434            let buffer = Buffer::new(0, "ab\nefg\nhklm\nnopqrs\ntuvwxyz", cx);
2435            assert_eq!(
2436                buffer.text_summary_for_range(1..3),
2437                TextSummary {
2438                    bytes: 2,
2439                    lines: Point::new(1, 0),
2440                    first_line_chars: 1,
2441                    last_line_chars: 0,
2442                    longest_row: 0,
2443                    longest_row_chars: 1,
2444                }
2445            );
2446            assert_eq!(
2447                buffer.text_summary_for_range(1..12),
2448                TextSummary {
2449                    bytes: 11,
2450                    lines: Point::new(3, 0),
2451                    first_line_chars: 1,
2452                    last_line_chars: 0,
2453                    longest_row: 2,
2454                    longest_row_chars: 4,
2455                }
2456            );
2457            assert_eq!(
2458                buffer.text_summary_for_range(0..20),
2459                TextSummary {
2460                    bytes: 20,
2461                    lines: Point::new(4, 1),
2462                    first_line_chars: 2,
2463                    last_line_chars: 1,
2464                    longest_row: 3,
2465                    longest_row_chars: 6,
2466                }
2467            );
2468            assert_eq!(
2469                buffer.text_summary_for_range(0..22),
2470                TextSummary {
2471                    bytes: 22,
2472                    lines: Point::new(4, 3),
2473                    first_line_chars: 2,
2474                    last_line_chars: 3,
2475                    longest_row: 3,
2476                    longest_row_chars: 6,
2477                }
2478            );
2479            assert_eq!(
2480                buffer.text_summary_for_range(7..22),
2481                TextSummary {
2482                    bytes: 15,
2483                    lines: Point::new(2, 3),
2484                    first_line_chars: 4,
2485                    last_line_chars: 3,
2486                    longest_row: 1,
2487                    longest_row_chars: 6,
2488                }
2489            );
2490            buffer
2491        });
2492    }
2493
2494    #[gpui::test]
2495    fn test_chars_at(cx: &mut gpui::MutableAppContext) {
2496        cx.add_model(|cx| {
2497            let mut buffer = Buffer::new(0, "", cx);
2498            buffer.edit(vec![0..0], "abcd\nefgh\nij", None).unwrap();
2499            buffer.edit(vec![12..12], "kl\nmno", None).unwrap();
2500            buffer.edit(vec![18..18], "\npqrs", None).unwrap();
2501            buffer.edit(vec![18..21], "\nPQ", None).unwrap();
2502
2503            let chars = buffer.chars_at(Point::new(0, 0));
2504            assert_eq!(chars.collect::<String>(), "abcd\nefgh\nijkl\nmno\nPQrs");
2505
2506            let chars = buffer.chars_at(Point::new(1, 0));
2507            assert_eq!(chars.collect::<String>(), "efgh\nijkl\nmno\nPQrs");
2508
2509            let chars = buffer.chars_at(Point::new(2, 0));
2510            assert_eq!(chars.collect::<String>(), "ijkl\nmno\nPQrs");
2511
2512            let chars = buffer.chars_at(Point::new(3, 0));
2513            assert_eq!(chars.collect::<String>(), "mno\nPQrs");
2514
2515            let chars = buffer.chars_at(Point::new(4, 0));
2516            assert_eq!(chars.collect::<String>(), "PQrs");
2517
2518            // Regression test:
2519            let mut buffer = Buffer::new(0, "", cx);
2520            buffer.edit(vec![0..0], "[workspace]\nmembers = [\n    \"xray_core\",\n    \"xray_server\",\n    \"xray_cli\",\n    \"xray_wasm\",\n]\n", None).unwrap();
2521            buffer.edit(vec![60..60], "\n", None).unwrap();
2522
2523            let chars = buffer.chars_at(Point::new(6, 0));
2524            assert_eq!(chars.collect::<String>(), "    \"xray_wasm\",\n]\n");
2525
2526            buffer
2527        });
2528    }
2529
2530    #[gpui::test]
2531    fn test_anchors(cx: &mut gpui::MutableAppContext) {
2532        cx.add_model(|cx| {
2533            let mut buffer = Buffer::new(0, "", cx);
2534            buffer.edit(vec![0..0], "abc", None).unwrap();
2535            let left_anchor = buffer.anchor_before(2);
2536            let right_anchor = buffer.anchor_after(2);
2537
2538            buffer.edit(vec![1..1], "def\n", None).unwrap();
2539            assert_eq!(buffer.text(), "adef\nbc");
2540            assert_eq!(left_anchor.to_offset(&buffer), 6);
2541            assert_eq!(right_anchor.to_offset(&buffer), 6);
2542            assert_eq!(left_anchor.to_point(&buffer), Point { row: 1, column: 1 });
2543            assert_eq!(right_anchor.to_point(&buffer), Point { row: 1, column: 1 });
2544
2545            buffer.edit(vec![2..3], "", None).unwrap();
2546            assert_eq!(buffer.text(), "adf\nbc");
2547            assert_eq!(left_anchor.to_offset(&buffer), 5);
2548            assert_eq!(right_anchor.to_offset(&buffer), 5);
2549            assert_eq!(left_anchor.to_point(&buffer), Point { row: 1, column: 1 });
2550            assert_eq!(right_anchor.to_point(&buffer), Point { row: 1, column: 1 });
2551
2552            buffer.edit(vec![5..5], "ghi\n", None).unwrap();
2553            assert_eq!(buffer.text(), "adf\nbghi\nc");
2554            assert_eq!(left_anchor.to_offset(&buffer), 5);
2555            assert_eq!(right_anchor.to_offset(&buffer), 9);
2556            assert_eq!(left_anchor.to_point(&buffer), Point { row: 1, column: 1 });
2557            assert_eq!(right_anchor.to_point(&buffer), Point { row: 2, column: 0 });
2558
2559            buffer.edit(vec![7..9], "", None).unwrap();
2560            assert_eq!(buffer.text(), "adf\nbghc");
2561            assert_eq!(left_anchor.to_offset(&buffer), 5);
2562            assert_eq!(right_anchor.to_offset(&buffer), 7);
2563            assert_eq!(left_anchor.to_point(&buffer), Point { row: 1, column: 1 },);
2564            assert_eq!(right_anchor.to_point(&buffer), Point { row: 1, column: 3 });
2565
2566            // Ensure anchoring to a point is equivalent to anchoring to an offset.
2567            assert_eq!(
2568                buffer.anchor_before(Point { row: 0, column: 0 }),
2569                buffer.anchor_before(0)
2570            );
2571            assert_eq!(
2572                buffer.anchor_before(Point { row: 0, column: 1 }),
2573                buffer.anchor_before(1)
2574            );
2575            assert_eq!(
2576                buffer.anchor_before(Point { row: 0, column: 2 }),
2577                buffer.anchor_before(2)
2578            );
2579            assert_eq!(
2580                buffer.anchor_before(Point { row: 0, column: 3 }),
2581                buffer.anchor_before(3)
2582            );
2583            assert_eq!(
2584                buffer.anchor_before(Point { row: 1, column: 0 }),
2585                buffer.anchor_before(4)
2586            );
2587            assert_eq!(
2588                buffer.anchor_before(Point { row: 1, column: 1 }),
2589                buffer.anchor_before(5)
2590            );
2591            assert_eq!(
2592                buffer.anchor_before(Point { row: 1, column: 2 }),
2593                buffer.anchor_before(6)
2594            );
2595            assert_eq!(
2596                buffer.anchor_before(Point { row: 1, column: 3 }),
2597                buffer.anchor_before(7)
2598            );
2599            assert_eq!(
2600                buffer.anchor_before(Point { row: 1, column: 4 }),
2601                buffer.anchor_before(8)
2602            );
2603
2604            // Comparison between anchors.
2605            let anchor_at_offset_0 = buffer.anchor_before(0);
2606            let anchor_at_offset_1 = buffer.anchor_before(1);
2607            let anchor_at_offset_2 = buffer.anchor_before(2);
2608
2609            assert_eq!(
2610                anchor_at_offset_0
2611                    .cmp(&anchor_at_offset_0, &buffer)
2612                    .unwrap(),
2613                Ordering::Equal
2614            );
2615            assert_eq!(
2616                anchor_at_offset_1
2617                    .cmp(&anchor_at_offset_1, &buffer)
2618                    .unwrap(),
2619                Ordering::Equal
2620            );
2621            assert_eq!(
2622                anchor_at_offset_2
2623                    .cmp(&anchor_at_offset_2, &buffer)
2624                    .unwrap(),
2625                Ordering::Equal
2626            );
2627
2628            assert_eq!(
2629                anchor_at_offset_0
2630                    .cmp(&anchor_at_offset_1, &buffer)
2631                    .unwrap(),
2632                Ordering::Less
2633            );
2634            assert_eq!(
2635                anchor_at_offset_1
2636                    .cmp(&anchor_at_offset_2, &buffer)
2637                    .unwrap(),
2638                Ordering::Less
2639            );
2640            assert_eq!(
2641                anchor_at_offset_0
2642                    .cmp(&anchor_at_offset_2, &buffer)
2643                    .unwrap(),
2644                Ordering::Less
2645            );
2646
2647            assert_eq!(
2648                anchor_at_offset_1
2649                    .cmp(&anchor_at_offset_0, &buffer)
2650                    .unwrap(),
2651                Ordering::Greater
2652            );
2653            assert_eq!(
2654                anchor_at_offset_2
2655                    .cmp(&anchor_at_offset_1, &buffer)
2656                    .unwrap(),
2657                Ordering::Greater
2658            );
2659            assert_eq!(
2660                anchor_at_offset_2
2661                    .cmp(&anchor_at_offset_0, &buffer)
2662                    .unwrap(),
2663                Ordering::Greater
2664            );
2665            buffer
2666        });
2667    }
2668
2669    #[gpui::test]
2670    fn test_anchors_at_start_and_end(cx: &mut gpui::MutableAppContext) {
2671        cx.add_model(|cx| {
2672            let mut buffer = Buffer::new(0, "", cx);
2673            let before_start_anchor = buffer.anchor_before(0);
2674            let after_end_anchor = buffer.anchor_after(0);
2675
2676            buffer.edit(vec![0..0], "abc", None).unwrap();
2677            assert_eq!(buffer.text(), "abc");
2678            assert_eq!(before_start_anchor.to_offset(&buffer), 0);
2679            assert_eq!(after_end_anchor.to_offset(&buffer), 3);
2680
2681            let after_start_anchor = buffer.anchor_after(0);
2682            let before_end_anchor = buffer.anchor_before(3);
2683
2684            buffer.edit(vec![3..3], "def", None).unwrap();
2685            buffer.edit(vec![0..0], "ghi", None).unwrap();
2686            assert_eq!(buffer.text(), "ghiabcdef");
2687            assert_eq!(before_start_anchor.to_offset(&buffer), 0);
2688            assert_eq!(after_start_anchor.to_offset(&buffer), 3);
2689            assert_eq!(before_end_anchor.to_offset(&buffer), 6);
2690            assert_eq!(after_end_anchor.to_offset(&buffer), 9);
2691            buffer
2692        });
2693    }
2694
2695    #[test]
2696    fn test_is_dirty() {
2697        App::test_async((), |mut cx| async move {
2698            let dir = temp_tree(json!({
2699                "file1": "",
2700                "file2": "",
2701                "file3": "",
2702            }));
2703            let tree = cx.add_model(|cx| Worktree::new(dir.path(), cx));
2704            tree.flush_fs_events(&cx).await;
2705            cx.read(|cx| tree.read(cx).scan_complete()).await;
2706
2707            let file1 = cx.update(|cx| tree.file("file1", cx)).await;
2708            let buffer1 = cx.add_model(|cx| {
2709                Buffer::from_history(0, History::new("abc".into()), Some(file1), None, cx)
2710            });
2711            let events = Rc::new(RefCell::new(Vec::new()));
2712
2713            // initially, the buffer isn't dirty.
2714            buffer1.update(&mut cx, |buffer, cx| {
2715                cx.subscribe(&buffer1, {
2716                    let events = events.clone();
2717                    move |_, event, _| events.borrow_mut().push(event.clone())
2718                });
2719
2720                assert!(!buffer.is_dirty());
2721                assert!(events.borrow().is_empty());
2722
2723                buffer.edit(vec![1..2], "", Some(cx)).unwrap();
2724            });
2725
2726            // after the first edit, the buffer is dirty, and emits a dirtied event.
2727            buffer1.update(&mut cx, |buffer, cx| {
2728                assert!(buffer.text() == "ac");
2729                assert!(buffer.is_dirty());
2730                assert_eq!(*events.borrow(), &[Event::Edited, Event::Dirtied]);
2731                events.borrow_mut().clear();
2732
2733                buffer.did_save(buffer.version(), None, cx);
2734            });
2735
2736            // after saving, the buffer is not dirty, and emits a saved event.
2737            buffer1.update(&mut cx, |buffer, cx| {
2738                assert!(!buffer.is_dirty());
2739                assert_eq!(*events.borrow(), &[Event::Saved]);
2740                events.borrow_mut().clear();
2741
2742                buffer.edit(vec![1..1], "B", Some(cx)).unwrap();
2743                buffer.edit(vec![2..2], "D", Some(cx)).unwrap();
2744            });
2745
2746            // after editing again, the buffer is dirty, and emits another dirty event.
2747            buffer1.update(&mut cx, |buffer, cx| {
2748                assert!(buffer.text() == "aBDc");
2749                assert!(buffer.is_dirty());
2750                assert_eq!(
2751                    *events.borrow(),
2752                    &[Event::Edited, Event::Dirtied, Event::Edited],
2753                );
2754                events.borrow_mut().clear();
2755
2756                // TODO - currently, after restoring the buffer to its
2757                // previously-saved state, the is still considered dirty.
2758                buffer.edit(vec![1..3], "", Some(cx)).unwrap();
2759                assert!(buffer.text() == "ac");
2760                assert!(buffer.is_dirty());
2761            });
2762
2763            assert_eq!(*events.borrow(), &[Event::Edited]);
2764
2765            // When a file is deleted, the buffer is considered dirty.
2766            let events = Rc::new(RefCell::new(Vec::new()));
2767            let file2 = cx.update(|cx| tree.file("file2", cx)).await;
2768            let buffer2 = cx.add_model(|cx: &mut ModelContext<Buffer>| {
2769                cx.subscribe(&cx.handle(), {
2770                    let events = events.clone();
2771                    move |_, event, _| events.borrow_mut().push(event.clone())
2772                });
2773
2774                Buffer::from_history(0, History::new("abc".into()), Some(file2), None, cx)
2775            });
2776
2777            fs::remove_file(dir.path().join("file2")).unwrap();
2778            buffer2.condition(&cx, |b, _| b.is_dirty()).await;
2779            assert_eq!(
2780                *events.borrow(),
2781                &[Event::Dirtied, Event::FileHandleChanged]
2782            );
2783
2784            // When a file is already dirty when deleted, we don't emit a Dirtied event.
2785            let events = Rc::new(RefCell::new(Vec::new()));
2786            let file3 = cx.update(|cx| tree.file("file3", cx)).await;
2787            let buffer3 = cx.add_model(|cx: &mut ModelContext<Buffer>| {
2788                cx.subscribe(&cx.handle(), {
2789                    let events = events.clone();
2790                    move |_, event, _| events.borrow_mut().push(event.clone())
2791                });
2792
2793                Buffer::from_history(0, History::new("abc".into()), Some(file3), None, cx)
2794            });
2795
2796            tree.flush_fs_events(&cx).await;
2797            buffer3.update(&mut cx, |buffer, cx| {
2798                buffer.edit(Some(0..0), "x", Some(cx)).unwrap();
2799            });
2800            events.borrow_mut().clear();
2801            fs::remove_file(dir.path().join("file3")).unwrap();
2802            buffer3
2803                .condition(&cx, |_, _| !events.borrow().is_empty())
2804                .await;
2805            assert_eq!(*events.borrow(), &[Event::FileHandleChanged]);
2806            cx.read(|cx| assert!(buffer3.read(cx).is_dirty()));
2807        });
2808    }
2809
2810    #[gpui::test]
2811    async fn test_file_changes_on_disk(mut cx: gpui::TestAppContext) {
2812        let initial_contents = "aaa\nbbbbb\nc\n";
2813        let dir = temp_tree(json!({ "the-file": initial_contents }));
2814        let tree = cx.add_model(|cx| Worktree::new(dir.path(), cx));
2815        cx.read(|cx| tree.read(cx).scan_complete()).await;
2816
2817        let abs_path = dir.path().join("the-file");
2818        let file = cx.update(|cx| tree.file("the-file", cx)).await;
2819        let buffer = cx.add_model(|cx| {
2820            Buffer::from_history(
2821                0,
2822                History::new(initial_contents.into()),
2823                Some(file),
2824                None,
2825                cx,
2826            )
2827        });
2828
2829        // Add a cursor at the start of each row.
2830        let (selection_set_id, _) = buffer.update(&mut cx, |buffer, cx| {
2831            assert!(!buffer.is_dirty());
2832            buffer.add_selection_set(
2833                (0..3)
2834                    .map(|row| {
2835                        let anchor = buffer.anchor_at(Point::new(row, 0), Bias::Right);
2836                        Selection {
2837                            id: row as usize,
2838                            start: anchor.clone(),
2839                            end: anchor,
2840                            reversed: false,
2841                            goal: SelectionGoal::None,
2842                        }
2843                    })
2844                    .collect::<Vec<_>>(),
2845                Some(cx),
2846            )
2847        });
2848
2849        // Change the file on disk, adding two new lines of text, and removing
2850        // one line.
2851        buffer.read_with(&cx, |buffer, _| {
2852            assert!(!buffer.is_dirty());
2853            assert!(!buffer.has_conflict());
2854        });
2855        let new_contents = "AAAA\naaa\nBB\nbbbbb\n";
2856        fs::write(&abs_path, new_contents).unwrap();
2857
2858        // Because the buffer was not modified, it is reloaded from disk. Its
2859        // contents are edited according to the diff between the old and new
2860        // file contents.
2861        buffer
2862            .condition(&cx, |buffer, _| buffer.text() != initial_contents)
2863            .await;
2864
2865        buffer.update(&mut cx, |buffer, _| {
2866            assert_eq!(buffer.text(), new_contents);
2867            assert!(!buffer.is_dirty());
2868            assert!(!buffer.has_conflict());
2869
2870            let selections = buffer.selections(selection_set_id).unwrap();
2871            let cursor_positions = selections
2872                .iter()
2873                .map(|selection| {
2874                    assert_eq!(selection.start, selection.end);
2875                    selection.start.to_point(&buffer)
2876                })
2877                .collect::<Vec<_>>();
2878            assert_eq!(
2879                cursor_positions,
2880                &[Point::new(1, 0), Point::new(3, 0), Point::new(4, 0),]
2881            );
2882        });
2883
2884        // Modify the buffer
2885        buffer.update(&mut cx, |buffer, cx| {
2886            buffer.edit(vec![0..0], " ", Some(cx)).unwrap();
2887            assert!(buffer.is_dirty());
2888        });
2889
2890        // Change the file on disk again, adding blank lines to the beginning.
2891        fs::write(&abs_path, "\n\n\nAAAA\naaa\nBB\nbbbbb\n").unwrap();
2892
2893        // Becaues the buffer is modified, it doesn't reload from disk, but is
2894        // marked as having a conflict.
2895        buffer
2896            .condition(&cx, |buffer, _| buffer.has_conflict())
2897            .await;
2898    }
2899
2900    #[gpui::test]
2901    async fn test_set_text_via_diff(mut cx: gpui::TestAppContext) {
2902        let text = "a\nbb\nccc\ndddd\neeeee\nffffff\n";
2903        let buffer = cx.add_model(|cx| Buffer::new(0, text, cx));
2904
2905        let text = "a\nccc\ndddd\nffffff\n";
2906        let diff = buffer.read_with(&cx, |b, cx| b.diff(text.into(), cx)).await;
2907        buffer.update(&mut cx, |b, cx| b.set_text_via_diff(diff, cx));
2908        cx.read(|cx| assert_eq!(buffer.read(cx).text(), text));
2909
2910        let text = "a\n1\n\nccc\ndd2dd\nffffff\n";
2911        let diff = buffer.read_with(&cx, |b, cx| b.diff(text.into(), cx)).await;
2912        buffer.update(&mut cx, |b, cx| b.set_text_via_diff(diff, cx));
2913        cx.read(|cx| assert_eq!(buffer.read(cx).text(), text));
2914    }
2915
2916    #[gpui::test]
2917    fn test_undo_redo(cx: &mut gpui::MutableAppContext) {
2918        cx.add_model(|cx| {
2919            let mut buffer = Buffer::new(0, "1234", cx);
2920
2921            let edit1 = buffer.edit(vec![1..1], "abx", None).unwrap();
2922            let edit2 = buffer.edit(vec![3..4], "yzef", None).unwrap();
2923            let edit3 = buffer.edit(vec![3..5], "cd", None).unwrap();
2924            assert_eq!(buffer.text(), "1abcdef234");
2925
2926            buffer.undo_or_redo(edit1.edit_id().unwrap()).unwrap();
2927            assert_eq!(buffer.text(), "1cdef234");
2928            buffer.undo_or_redo(edit1.edit_id().unwrap()).unwrap();
2929            assert_eq!(buffer.text(), "1abcdef234");
2930
2931            buffer.undo_or_redo(edit2.edit_id().unwrap()).unwrap();
2932            assert_eq!(buffer.text(), "1abcdx234");
2933            buffer.undo_or_redo(edit3.edit_id().unwrap()).unwrap();
2934            assert_eq!(buffer.text(), "1abx234");
2935            buffer.undo_or_redo(edit2.edit_id().unwrap()).unwrap();
2936            assert_eq!(buffer.text(), "1abyzef234");
2937            buffer.undo_or_redo(edit3.edit_id().unwrap()).unwrap();
2938            assert_eq!(buffer.text(), "1abcdef234");
2939
2940            buffer.undo_or_redo(edit3.edit_id().unwrap()).unwrap();
2941            assert_eq!(buffer.text(), "1abyzef234");
2942            buffer.undo_or_redo(edit1.edit_id().unwrap()).unwrap();
2943            assert_eq!(buffer.text(), "1yzef234");
2944            buffer.undo_or_redo(edit2.edit_id().unwrap()).unwrap();
2945            assert_eq!(buffer.text(), "1234");
2946
2947            buffer
2948        });
2949    }
2950
2951    #[gpui::test]
2952    fn test_history(cx: &mut gpui::MutableAppContext) {
2953        cx.add_model(|cx| {
2954            let mut now = Instant::now();
2955            let mut buffer = Buffer::new(0, "123456", cx);
2956
2957            let (set_id, _) =
2958                buffer.add_selection_set(buffer.selections_from_ranges(vec![4..4]).unwrap(), None);
2959            buffer.start_transaction_at(Some(set_id), now).unwrap();
2960            buffer.edit(vec![2..4], "cd", None).unwrap();
2961            buffer.end_transaction_at(Some(set_id), now, None).unwrap();
2962            assert_eq!(buffer.text(), "12cd56");
2963            assert_eq!(buffer.selection_ranges(set_id).unwrap(), vec![4..4]);
2964
2965            buffer.start_transaction_at(Some(set_id), now).unwrap();
2966            buffer
2967                .update_selection_set(
2968                    set_id,
2969                    buffer.selections_from_ranges(vec![1..3]).unwrap(),
2970                    None,
2971                )
2972                .unwrap();
2973            buffer.edit(vec![4..5], "e", None).unwrap();
2974            buffer.end_transaction_at(Some(set_id), now, None).unwrap();
2975            assert_eq!(buffer.text(), "12cde6");
2976            assert_eq!(buffer.selection_ranges(set_id).unwrap(), vec![1..3]);
2977
2978            now += UNDO_GROUP_INTERVAL + Duration::from_millis(1);
2979            buffer.start_transaction_at(Some(set_id), now).unwrap();
2980            buffer
2981                .update_selection_set(
2982                    set_id,
2983                    buffer.selections_from_ranges(vec![2..2]).unwrap(),
2984                    None,
2985                )
2986                .unwrap();
2987            buffer.edit(vec![0..1], "a", None).unwrap();
2988            buffer.edit(vec![1..1], "b", None).unwrap();
2989            buffer.end_transaction_at(Some(set_id), now, None).unwrap();
2990            assert_eq!(buffer.text(), "ab2cde6");
2991            assert_eq!(buffer.selection_ranges(set_id).unwrap(), vec![3..3]);
2992
2993            // Last transaction happened past the group interval, undo it on its
2994            // own.
2995            buffer.undo(None);
2996            assert_eq!(buffer.text(), "12cde6");
2997            assert_eq!(buffer.selection_ranges(set_id).unwrap(), vec![1..3]);
2998
2999            // First two transactions happened within the group interval, undo them
3000            // together.
3001            buffer.undo(None);
3002            assert_eq!(buffer.text(), "123456");
3003            assert_eq!(buffer.selection_ranges(set_id).unwrap(), vec![4..4]);
3004
3005            // Redo the first two transactions together.
3006            buffer.redo(None);
3007            assert_eq!(buffer.text(), "12cde6");
3008            assert_eq!(buffer.selection_ranges(set_id).unwrap(), vec![1..3]);
3009
3010            // Redo the last transaction on its own.
3011            buffer.redo(None);
3012            assert_eq!(buffer.text(), "ab2cde6");
3013            assert_eq!(buffer.selection_ranges(set_id).unwrap(), vec![3..3]);
3014
3015            buffer
3016        });
3017    }
3018
3019    #[gpui::test]
3020    fn test_concurrent_edits(cx: &mut gpui::MutableAppContext) {
3021        let text = "abcdef";
3022
3023        let buffer1 = cx.add_model(|cx| Buffer::new(1, text, cx));
3024        let buffer2 = cx.add_model(|cx| Buffer::new(2, text, cx));
3025        let buffer3 = cx.add_model(|cx| Buffer::new(3, text, cx));
3026
3027        let buf1_op = buffer1.update(cx, |buffer, cx| {
3028            let op = buffer.edit(vec![1..2], "12", Some(cx)).unwrap();
3029            assert_eq!(buffer.text(), "a12cdef");
3030            op
3031        });
3032        let buf2_op = buffer2.update(cx, |buffer, cx| {
3033            let op = buffer.edit(vec![3..4], "34", Some(cx)).unwrap();
3034            assert_eq!(buffer.text(), "abc34ef");
3035            op
3036        });
3037        let buf3_op = buffer3.update(cx, |buffer, cx| {
3038            let op = buffer.edit(vec![5..6], "56", Some(cx)).unwrap();
3039            assert_eq!(buffer.text(), "abcde56");
3040            op
3041        });
3042
3043        buffer1.update(cx, |buffer, _| {
3044            buffer.apply_op(buf2_op.clone()).unwrap();
3045            buffer.apply_op(buf3_op.clone()).unwrap();
3046        });
3047        buffer2.update(cx, |buffer, _| {
3048            buffer.apply_op(buf1_op.clone()).unwrap();
3049            buffer.apply_op(buf3_op.clone()).unwrap();
3050        });
3051        buffer3.update(cx, |buffer, _| {
3052            buffer.apply_op(buf1_op.clone()).unwrap();
3053            buffer.apply_op(buf2_op.clone()).unwrap();
3054        });
3055
3056        assert_eq!(buffer1.read(cx).text(), "a12c34e56");
3057        assert_eq!(buffer2.read(cx).text(), "a12c34e56");
3058        assert_eq!(buffer3.read(cx).text(), "a12c34e56");
3059    }
3060
3061    #[gpui::test]
3062    fn test_random_concurrent_edits(cx: &mut gpui::MutableAppContext) {
3063        use crate::test::Network;
3064
3065        let peers = env::var("PEERS")
3066            .map(|i| i.parse().expect("invalid `PEERS` variable"))
3067            .unwrap_or(5);
3068        let iterations = env::var("ITERATIONS")
3069            .map(|i| i.parse().expect("invalid `ITERATIONS` variable"))
3070            .unwrap_or(100);
3071        let operations = env::var("OPERATIONS")
3072            .map(|i| i.parse().expect("invalid `OPERATIONS` variable"))
3073            .unwrap_or(10);
3074        let start_seed =
3075            env::var("SEED").map_or(0, |seed| seed.parse().expect("invalid `SEED` variable"));
3076
3077        for seed in start_seed..start_seed + iterations {
3078            dbg!(seed);
3079            let mut rng = &mut StdRng::seed_from_u64(seed);
3080
3081            let base_text_len = rng.gen_range(0..10);
3082            let base_text = RandomCharIter::new(&mut rng)
3083                .take(base_text_len)
3084                .collect::<String>();
3085            let mut replica_ids = Vec::new();
3086            let mut buffers = Vec::new();
3087            let mut network = Network::new();
3088            for i in 0..peers {
3089                let buffer = cx.add_model(|cx| Buffer::new(i as ReplicaId, base_text.as_str(), cx));
3090                buffers.push(buffer);
3091                replica_ids.push(i as u16);
3092                network.add_peer(i as u16);
3093            }
3094
3095            log::info!("initial text: {:?}", base_text);
3096
3097            let mut mutation_count = operations;
3098            loop {
3099                let replica_index = rng.gen_range(0..peers);
3100                let replica_id = replica_ids[replica_index];
3101                buffers[replica_index].update(cx, |buffer, _| match rng.gen_range(0..=100) {
3102                    0..=50 if mutation_count != 0 => {
3103                        let (_, _, ops) = buffer.randomly_mutate(&mut rng, None);
3104                        log::info!("buffer {} text: {:?}", buffer.replica_id, buffer.text());
3105                        network.broadcast(replica_id, ops, &mut rng);
3106                        mutation_count -= 1;
3107                    }
3108                    51..=70 if mutation_count != 0 => {
3109                        let ops = buffer.randomly_undo_redo(&mut rng);
3110                        network.broadcast(replica_id, ops, &mut rng);
3111                        mutation_count -= 1;
3112                    }
3113                    71..=100 if network.has_unreceived(replica_id) => {
3114                        let ops = network.receive(replica_id, &mut rng);
3115                        if !ops.is_empty() {
3116                            log::info!(
3117                                "peer {} applying {} ops from the network.",
3118                                replica_id,
3119                                ops.len()
3120                            );
3121                            buffer.apply_ops(ops, None).unwrap();
3122                        }
3123                    }
3124                    _ => {}
3125                });
3126
3127                if mutation_count == 0 && network.is_idle() {
3128                    break;
3129                }
3130            }
3131
3132            let first_buffer = buffers[0].read(cx);
3133            for buffer in &buffers[1..] {
3134                let buffer = buffer.read(cx);
3135                assert_eq!(
3136                    buffer.text(),
3137                    first_buffer.text(),
3138                    "Replica {} text != Replica 0 text",
3139                    buffer.replica_id
3140                );
3141                assert_eq!(
3142                    buffer.all_selections().collect::<HashMap<_, _>>(),
3143                    first_buffer.all_selections().collect::<HashMap<_, _>>()
3144                );
3145                assert_eq!(
3146                    buffer.all_selection_ranges().collect::<HashMap<_, _>>(),
3147                    first_buffer
3148                        .all_selection_ranges()
3149                        .collect::<HashMap<_, _>>()
3150                );
3151            }
3152        }
3153    }
3154
3155    #[gpui::test]
3156    async fn test_reparse(mut cx: gpui::TestAppContext) {
3157        let app_state = cx.read(build_app_state);
3158        let rust_lang = app_state.language_registry.select_language("test.rs");
3159        assert!(rust_lang.is_some());
3160
3161        let buffer = cx.add_model(|cx| {
3162            let text = "fn a() {}".into();
3163            let buffer = Buffer::from_history(0, History::new(text), None, rust_lang.cloned(), cx);
3164            assert!(buffer.is_parsing());
3165            assert!(buffer.syntax_tree().is_none());
3166            buffer
3167        });
3168
3169        // Wait for the initial text to parse
3170        buffer
3171            .condition(&cx, |buffer, _| !buffer.is_parsing())
3172            .await;
3173        assert_eq!(
3174            get_tree_sexp(&buffer, &cx),
3175            concat!(
3176                "(source_file (function_item name: (identifier) ",
3177                "parameters: (parameters) ",
3178                "body: (block)))"
3179            )
3180        );
3181
3182        // Perform some edits (add parameter and variable reference)
3183        // Parsing doesn't begin until the transaction is complete
3184        buffer.update(&mut cx, |buf, cx| {
3185            buf.start_transaction(None).unwrap();
3186
3187            let offset = buf.text().find(")").unwrap();
3188            buf.edit(vec![offset..offset], "b: C", Some(cx)).unwrap();
3189            assert!(!buf.is_parsing());
3190
3191            let offset = buf.text().find("}").unwrap();
3192            buf.edit(vec![offset..offset], " d; ", Some(cx)).unwrap();
3193            assert!(!buf.is_parsing());
3194
3195            buf.end_transaction(None, Some(cx)).unwrap();
3196            assert_eq!(buf.text(), "fn a(b: C) { d; }");
3197            assert!(buf.is_parsing());
3198        });
3199        buffer
3200            .condition(&cx, |buffer, _| !buffer.is_parsing())
3201            .await;
3202        assert_eq!(
3203            get_tree_sexp(&buffer, &cx),
3204            concat!(
3205                "(source_file (function_item name: (identifier) ",
3206                    "parameters: (parameters (parameter pattern: (identifier) type: (type_identifier))) ",
3207                    "body: (block (identifier))))"
3208            )
3209        );
3210
3211        // Perform a series of edits without waiting for the current parse to complete:
3212        // * turn identifier into a field expression
3213        // * turn field expression into a method call
3214        // * add a turbofish to the method call
3215        buffer.update(&mut cx, |buf, cx| {
3216            let offset = buf.text().find(";").unwrap();
3217            buf.edit(vec![offset..offset], ".e", Some(cx)).unwrap();
3218            assert_eq!(buf.text(), "fn a(b: C) { d.e; }");
3219            assert!(buf.is_parsing());
3220        });
3221        buffer.update(&mut cx, |buf, cx| {
3222            let offset = buf.text().find(";").unwrap();
3223            buf.edit(vec![offset..offset], "(f)", Some(cx)).unwrap();
3224            assert_eq!(buf.text(), "fn a(b: C) { d.e(f); }");
3225            assert!(buf.is_parsing());
3226        });
3227        buffer.update(&mut cx, |buf, cx| {
3228            let offset = buf.text().find("(f)").unwrap();
3229            buf.edit(vec![offset..offset], "::<G>", Some(cx)).unwrap();
3230            assert_eq!(buf.text(), "fn a(b: C) { d.e::<G>(f); }");
3231            assert!(buf.is_parsing());
3232        });
3233        buffer
3234            .condition(&cx, |buffer, _| !buffer.is_parsing())
3235            .await;
3236        assert_eq!(
3237            get_tree_sexp(&buffer, &cx),
3238            concat!(
3239                "(source_file (function_item name: (identifier) ",
3240                    "parameters: (parameters (parameter pattern: (identifier) type: (type_identifier))) ",
3241                    "body: (block (call_expression ",
3242                        "function: (generic_function ",
3243                            "function: (field_expression value: (identifier) field: (field_identifier)) ",
3244                            "type_arguments: (type_arguments (type_identifier))) ",
3245                            "arguments: (arguments (identifier))))))",
3246            )
3247        );
3248
3249        buffer.update(&mut cx, |buf, cx| {
3250            buf.undo(Some(cx));
3251            assert_eq!(buf.text(), "fn a() {}");
3252            assert!(buf.is_parsing());
3253        });
3254        buffer
3255            .condition(&cx, |buffer, _| !buffer.is_parsing())
3256            .await;
3257        assert_eq!(
3258            get_tree_sexp(&buffer, &cx),
3259            concat!(
3260                "(source_file (function_item name: (identifier) ",
3261                "parameters: (parameters) ",
3262                "body: (block)))"
3263            )
3264        );
3265
3266        buffer.update(&mut cx, |buf, cx| {
3267            buf.redo(Some(cx));
3268            assert_eq!(buf.text(), "fn a(b: C) { d.e::<G>(f); }");
3269            assert!(buf.is_parsing());
3270        });
3271        buffer
3272            .condition(&cx, |buffer, _| !buffer.is_parsing())
3273            .await;
3274        assert_eq!(
3275            get_tree_sexp(&buffer, &cx),
3276            concat!(
3277                "(source_file (function_item name: (identifier) ",
3278                    "parameters: (parameters (parameter pattern: (identifier) type: (type_identifier))) ",
3279                    "body: (block (call_expression ",
3280                        "function: (generic_function ",
3281                            "function: (field_expression value: (identifier) field: (field_identifier)) ",
3282                            "type_arguments: (type_arguments (type_identifier))) ",
3283                            "arguments: (arguments (identifier))))))",
3284            )
3285        );
3286
3287        fn get_tree_sexp(buffer: &ModelHandle<Buffer>, cx: &gpui::TestAppContext) -> String {
3288            buffer.read_with(cx, |buffer, _| {
3289                buffer.syntax_tree().unwrap().root_node().to_sexp()
3290            })
3291        }
3292    }
3293
3294    #[gpui::test]
3295    async fn test_enclosing_bracket_ranges(mut cx: gpui::TestAppContext) {
3296        use unindent::Unindent as _;
3297
3298        let app_state = cx.read(build_app_state);
3299        let rust_lang = app_state.language_registry.select_language("test.rs");
3300        assert!(rust_lang.is_some());
3301
3302        let buffer = cx.add_model(|cx| {
3303            let text = "
3304                mod x {
3305                    mod y {
3306
3307                    }
3308                }
3309            "
3310            .unindent()
3311            .into();
3312            Buffer::from_history(0, History::new(text), None, rust_lang.cloned(), cx)
3313        });
3314        buffer
3315            .condition(&cx, |buffer, _| !buffer.is_parsing())
3316            .await;
3317        buffer.read_with(&cx, |buf, _| {
3318            assert_eq!(
3319                buf.enclosing_bracket_point_ranges(Point::new(1, 6)..Point::new(1, 6)),
3320                Some((
3321                    Point::new(0, 6)..Point::new(0, 7),
3322                    Point::new(4, 0)..Point::new(4, 1)
3323                ))
3324            );
3325            assert_eq!(
3326                buf.enclosing_bracket_point_ranges(Point::new(1, 10)..Point::new(1, 10)),
3327                Some((
3328                    Point::new(1, 10)..Point::new(1, 11),
3329                    Point::new(3, 4)..Point::new(3, 5)
3330                ))
3331            );
3332            assert_eq!(
3333                buf.enclosing_bracket_point_ranges(Point::new(3, 5)..Point::new(3, 5)),
3334                Some((
3335                    Point::new(1, 10)..Point::new(1, 11),
3336                    Point::new(3, 4)..Point::new(3, 5)
3337                ))
3338            );
3339        });
3340    }
3341
3342    impl Buffer {
3343        fn random_byte_range(&mut self, start_offset: usize, rng: &mut impl Rng) -> Range<usize> {
3344            let end = self.clip_offset(rng.gen_range(start_offset..=self.len()), Bias::Right);
3345            let start = self.clip_offset(rng.gen_range(start_offset..=end), Bias::Right);
3346            start..end
3347        }
3348
3349        pub fn randomly_edit<T>(
3350            &mut self,
3351            rng: &mut T,
3352            old_range_count: usize,
3353            cx: Option<&mut ModelContext<Self>>,
3354        ) -> (Vec<Range<usize>>, String, Option<Operation>)
3355        where
3356            T: Rng,
3357        {
3358            let mut old_ranges: Vec<Range<usize>> = Vec::new();
3359            for _ in 0..old_range_count {
3360                let last_end = old_ranges.last().map_or(0, |last_range| last_range.end + 1);
3361                if last_end > self.len() {
3362                    break;
3363                }
3364                old_ranges.push(self.random_byte_range(last_end, rng));
3365            }
3366            let new_text_len = rng.gen_range(0..10);
3367            let new_text: String = RandomCharIter::new(&mut *rng).take(new_text_len).collect();
3368            log::info!(
3369                "mutating buffer {} at {:?}: {:?}",
3370                self.replica_id,
3371                old_ranges,
3372                new_text
3373            );
3374            let operation = self.edit(old_ranges.iter().cloned(), new_text.as_str(), cx);
3375            (old_ranges, new_text, operation)
3376        }
3377
3378        pub fn randomly_mutate<T>(
3379            &mut self,
3380            rng: &mut T,
3381            mut cx: Option<&mut ModelContext<Self>>,
3382        ) -> (Vec<Range<usize>>, String, Vec<Operation>)
3383        where
3384            T: Rng,
3385        {
3386            let (old_ranges, new_text, operation) = self.randomly_edit(rng, 5, cx.as_deref_mut());
3387            let mut operations = Vec::from_iter(operation);
3388
3389            // Randomly add, remove or mutate selection sets.
3390            let replica_selection_sets = &self
3391                .all_selections()
3392                .map(|(set_id, _)| *set_id)
3393                .filter(|set_id| self.replica_id == set_id.replica_id)
3394                .collect::<Vec<_>>();
3395            let set_id = replica_selection_sets.choose(rng);
3396            if set_id.is_some() && rng.gen_bool(1.0 / 6.0) {
3397                let op = self.remove_selection_set(*set_id.unwrap(), None).unwrap();
3398                operations.push(op);
3399            } else {
3400                let mut ranges = Vec::new();
3401                for _ in 0..5 {
3402                    ranges.push(self.random_byte_range(0, rng));
3403                }
3404                let new_selections = self.selections_from_ranges(ranges).unwrap();
3405
3406                let op = if set_id.is_none() || rng.gen_bool(1.0 / 5.0) {
3407                    self.add_selection_set(new_selections, None).1
3408                } else {
3409                    self.update_selection_set(*set_id.unwrap(), new_selections, None)
3410                        .unwrap()
3411                };
3412                operations.push(op);
3413            }
3414
3415            (old_ranges, new_text, operations)
3416        }
3417
3418        pub fn randomly_undo_redo(&mut self, rng: &mut impl Rng) -> Vec<Operation> {
3419            let mut ops = Vec::new();
3420            for _ in 0..rng.gen_range(1..=5) {
3421                if let Some(edit_id) = self.history.ops.keys().choose(rng).copied() {
3422                    log::info!("undoing buffer {} operation {:?}", self.replica_id, edit_id);
3423                    ops.push(self.undo_or_redo(edit_id).unwrap());
3424                }
3425            }
3426            ops
3427        }
3428
3429        fn selections_from_ranges<I>(&self, ranges: I) -> Result<Vec<Selection>>
3430        where
3431            I: IntoIterator<Item = Range<usize>>,
3432        {
3433            static NEXT_SELECTION_ID: AtomicUsize = AtomicUsize::new(0);
3434
3435            let mut ranges = ranges.into_iter().collect::<Vec<_>>();
3436            ranges.sort_unstable_by_key(|range| range.start);
3437
3438            let mut selections = Vec::with_capacity(ranges.len());
3439            for range in ranges {
3440                if range.start > range.end {
3441                    selections.push(Selection {
3442                        id: NEXT_SELECTION_ID.fetch_add(1, atomic::Ordering::SeqCst),
3443                        start: self.anchor_before(range.end),
3444                        end: self.anchor_before(range.start),
3445                        reversed: true,
3446                        goal: SelectionGoal::None,
3447                    });
3448                } else {
3449                    selections.push(Selection {
3450                        id: NEXT_SELECTION_ID.fetch_add(1, atomic::Ordering::SeqCst),
3451                        start: self.anchor_after(range.start),
3452                        end: self.anchor_before(range.end),
3453                        reversed: false,
3454                        goal: SelectionGoal::None,
3455                    });
3456                }
3457            }
3458            Ok(selections)
3459        }
3460
3461        pub fn selection_ranges<'a>(&'a self, set_id: SelectionSetId) -> Result<Vec<Range<usize>>> {
3462            Ok(self
3463                .selections(set_id)?
3464                .iter()
3465                .map(move |selection| {
3466                    let start = selection.start.to_offset(self);
3467                    let end = selection.end.to_offset(self);
3468                    if selection.reversed {
3469                        end..start
3470                    } else {
3471                        start..end
3472                    }
3473                })
3474                .collect())
3475        }
3476
3477        pub fn all_selections(&self) -> impl Iterator<Item = (&SelectionSetId, &[Selection])> {
3478            self.selections
3479                .iter()
3480                .map(|(set_id, selections)| (set_id, selections.as_ref()))
3481        }
3482
3483        pub fn all_selection_ranges<'a>(
3484            &'a self,
3485        ) -> impl 'a + Iterator<Item = (SelectionSetId, Vec<Range<usize>>)> {
3486            self.selections
3487                .keys()
3488                .map(move |set_id| (*set_id, self.selection_ranges(*set_id).unwrap()))
3489        }
3490
3491        pub fn enclosing_bracket_point_ranges<T: ToOffset>(
3492            &self,
3493            range: Range<T>,
3494        ) -> Option<(Range<Point>, Range<Point>)> {
3495            self.enclosing_bracket_ranges(range).map(|(start, end)| {
3496                let point_start = start.start.to_point(self)..start.end.to_point(self);
3497                let point_end = end.start.to_point(self)..end.end.to_point(self);
3498                (point_start, point_end)
3499            })
3500        }
3501    }
3502
3503    impl Operation {
3504        fn edit_id(&self) -> Option<time::Local> {
3505            match self {
3506                Operation::Edit(edit) => Some(edit.timestamp.local()),
3507                Operation::Undo { undo, .. } => Some(undo.edit_id),
3508                Operation::UpdateSelections { .. } => None,
3509            }
3510        }
3511    }
3512}