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