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