multi_buffer.rs

   1mod anchor;
   2
   3pub use anchor::{Anchor, AnchorRangeExt};
   4use anyhow::Result;
   5use clock::ReplicaId;
   6use collections::{Bound, HashMap, HashSet};
   7use gpui::{AppContext, Entity, ModelContext, ModelHandle, Task};
   8pub use language::Completion;
   9use language::{
  10    char_kind, Buffer, BufferChunks, BufferSnapshot, CharKind, Chunk, DiagnosticEntry, Event, File,
  11    Language, Outline, OutlineItem, Selection, ToOffset as _, ToPoint as _, ToPointUtf16 as _,
  12    TransactionId,
  13};
  14use std::{
  15    cell::{Ref, RefCell},
  16    cmp, fmt, io,
  17    iter::{self, FromIterator},
  18    ops::{Range, RangeBounds, Sub},
  19    str,
  20    sync::Arc,
  21    time::{Duration, Instant},
  22};
  23use sum_tree::{Bias, Cursor, SumTree};
  24use text::{
  25    locator::Locator,
  26    rope::TextDimension,
  27    subscription::{Subscription, Topic},
  28    AnchorRangeExt as _, Edit, Point, PointUtf16, TextSummary,
  29};
  30use theme::SyntaxTheme;
  31
  32const NEWLINES: &'static [u8] = &[b'\n'; u8::MAX as usize];
  33
  34pub type ExcerptId = Locator;
  35
  36pub struct MultiBuffer {
  37    snapshot: RefCell<MultiBufferSnapshot>,
  38    buffers: RefCell<HashMap<usize, BufferState>>,
  39    subscriptions: Topic,
  40    singleton: bool,
  41    replica_id: ReplicaId,
  42    history: History,
  43    title: Option<String>,
  44}
  45
  46struct History {
  47    next_transaction_id: TransactionId,
  48    undo_stack: Vec<Transaction>,
  49    redo_stack: Vec<Transaction>,
  50    transaction_depth: usize,
  51    group_interval: Duration,
  52}
  53
  54#[derive(Clone)]
  55struct Transaction {
  56    id: TransactionId,
  57    buffer_transactions: HashMap<usize, text::TransactionId>,
  58    first_edit_at: Instant,
  59    last_edit_at: Instant,
  60    suppress_grouping: bool,
  61}
  62
  63pub trait ToOffset: 'static + fmt::Debug {
  64    fn to_offset(&self, snapshot: &MultiBufferSnapshot) -> usize;
  65}
  66
  67pub trait ToPoint: 'static + fmt::Debug {
  68    fn to_point(&self, snapshot: &MultiBufferSnapshot) -> Point;
  69}
  70
  71pub trait ToPointUtf16: 'static + fmt::Debug {
  72    fn to_point_utf16(&self, snapshot: &MultiBufferSnapshot) -> PointUtf16;
  73}
  74
  75struct BufferState {
  76    buffer: ModelHandle<Buffer>,
  77    last_version: clock::Global,
  78    last_parse_count: usize,
  79    last_selections_update_count: usize,
  80    last_diagnostics_update_count: usize,
  81    last_file_update_count: usize,
  82    excerpts: Vec<ExcerptId>,
  83    _subscriptions: [gpui::Subscription; 2],
  84}
  85
  86#[derive(Clone, Default)]
  87pub struct MultiBufferSnapshot {
  88    singleton: bool,
  89    excerpts: SumTree<Excerpt>,
  90    parse_count: usize,
  91    diagnostics_update_count: usize,
  92    trailing_excerpt_update_count: usize,
  93    is_dirty: bool,
  94    has_conflict: bool,
  95}
  96
  97pub struct ExcerptBoundary {
  98    pub id: ExcerptId,
  99    pub row: u32,
 100    pub buffer: BufferSnapshot,
 101    pub range: Range<text::Anchor>,
 102    pub starts_new_buffer: bool,
 103}
 104
 105#[derive(Clone)]
 106struct Excerpt {
 107    id: ExcerptId,
 108    buffer_id: usize,
 109    buffer: BufferSnapshot,
 110    range: Range<text::Anchor>,
 111    max_buffer_row: u32,
 112    text_summary: TextSummary,
 113    has_trailing_newline: bool,
 114}
 115
 116#[derive(Clone, Debug, Default)]
 117struct ExcerptSummary {
 118    excerpt_id: ExcerptId,
 119    max_buffer_row: u32,
 120    text: TextSummary,
 121}
 122
 123pub struct MultiBufferRows<'a> {
 124    buffer_row_range: Range<u32>,
 125    excerpts: Cursor<'a, Excerpt, Point>,
 126}
 127
 128pub struct MultiBufferChunks<'a> {
 129    range: Range<usize>,
 130    excerpts: Cursor<'a, Excerpt, usize>,
 131    excerpt_chunks: Option<ExcerptChunks<'a>>,
 132    language_aware: bool,
 133}
 134
 135pub struct MultiBufferBytes<'a> {
 136    range: Range<usize>,
 137    excerpts: Cursor<'a, Excerpt, usize>,
 138    excerpt_bytes: Option<ExcerptBytes<'a>>,
 139    chunk: &'a [u8],
 140}
 141
 142struct ExcerptChunks<'a> {
 143    content_chunks: BufferChunks<'a>,
 144    footer_height: usize,
 145}
 146
 147struct ExcerptBytes<'a> {
 148    content_bytes: language::rope::Bytes<'a>,
 149    footer_height: usize,
 150}
 151
 152impl MultiBuffer {
 153    pub fn new(replica_id: ReplicaId) -> Self {
 154        Self {
 155            snapshot: Default::default(),
 156            buffers: Default::default(),
 157            subscriptions: Default::default(),
 158            singleton: false,
 159            replica_id,
 160            history: History {
 161                next_transaction_id: Default::default(),
 162                undo_stack: Default::default(),
 163                redo_stack: Default::default(),
 164                transaction_depth: 0,
 165                group_interval: Duration::from_millis(300),
 166            },
 167            title: Default::default(),
 168        }
 169    }
 170
 171    pub fn with_title(mut self, title: String) -> Self {
 172        self.title = Some(title);
 173        self
 174    }
 175
 176    pub fn singleton(buffer: ModelHandle<Buffer>, cx: &mut ModelContext<Self>) -> Self {
 177        let mut this = Self::new(buffer.read(cx).replica_id());
 178        this.singleton = true;
 179        this.push_excerpts(buffer, [text::Anchor::min()..text::Anchor::max()], cx);
 180        this.snapshot.borrow_mut().singleton = true;
 181        this
 182    }
 183
 184    #[cfg(any(test, feature = "test-support"))]
 185    pub fn build_simple(text: &str, cx: &mut gpui::MutableAppContext) -> ModelHandle<Self> {
 186        let buffer = cx.add_model(|cx| Buffer::new(0, text, cx));
 187        cx.add_model(|cx| Self::singleton(buffer, cx))
 188    }
 189
 190    #[cfg(any(test, feature = "test-support"))]
 191    pub fn build_random(
 192        rng: &mut impl rand::Rng,
 193        cx: &mut gpui::MutableAppContext,
 194    ) -> ModelHandle<Self> {
 195        cx.add_model(|cx| {
 196            let mut multibuffer = MultiBuffer::new(0);
 197            let mutation_count = rng.gen_range(1..=5);
 198            multibuffer.randomly_edit_excerpts(rng, mutation_count, cx);
 199            multibuffer
 200        })
 201    }
 202
 203    pub fn replica_id(&self) -> ReplicaId {
 204        self.replica_id
 205    }
 206
 207    pub fn snapshot(&self, cx: &AppContext) -> MultiBufferSnapshot {
 208        self.sync(cx);
 209        self.snapshot.borrow().clone()
 210    }
 211
 212    pub fn read(&self, cx: &AppContext) -> Ref<MultiBufferSnapshot> {
 213        self.sync(cx);
 214        self.snapshot.borrow()
 215    }
 216
 217    pub fn as_singleton(&self) -> Option<ModelHandle<Buffer>> {
 218        if self.singleton {
 219            return Some(
 220                self.buffers
 221                    .borrow()
 222                    .values()
 223                    .next()
 224                    .unwrap()
 225                    .buffer
 226                    .clone(),
 227            );
 228        } else {
 229            None
 230        }
 231    }
 232
 233    pub fn is_singleton(&self) -> bool {
 234        self.singleton
 235    }
 236
 237    pub fn subscribe(&mut self) -> Subscription {
 238        self.subscriptions.subscribe()
 239    }
 240
 241    pub fn edit<I, S, T>(&mut self, ranges: I, new_text: T, cx: &mut ModelContext<Self>)
 242    where
 243        I: IntoIterator<Item = Range<S>>,
 244        S: ToOffset,
 245        T: Into<String>,
 246    {
 247        self.edit_internal(ranges, new_text, false, cx)
 248    }
 249
 250    pub fn edit_with_autoindent<I, S, T>(
 251        &mut self,
 252        ranges: I,
 253        new_text: T,
 254        cx: &mut ModelContext<Self>,
 255    ) where
 256        I: IntoIterator<Item = Range<S>>,
 257        S: ToOffset,
 258        T: Into<String>,
 259    {
 260        self.edit_internal(ranges, new_text, true, cx)
 261    }
 262
 263    pub fn edit_internal<I, S, T>(
 264        &mut self,
 265        ranges_iter: I,
 266        new_text: T,
 267        autoindent: bool,
 268        cx: &mut ModelContext<Self>,
 269    ) where
 270        I: IntoIterator<Item = Range<S>>,
 271        S: ToOffset,
 272        T: Into<String>,
 273    {
 274        if self.buffers.borrow().is_empty() {
 275            return;
 276        }
 277
 278        if let Some(buffer) = self.as_singleton() {
 279            let snapshot = self.read(cx);
 280            let ranges = ranges_iter
 281                .into_iter()
 282                .map(|range| range.start.to_offset(&snapshot)..range.end.to_offset(&snapshot));
 283            return buffer.update(cx, |buffer, cx| {
 284                if autoindent {
 285                    buffer.edit_with_autoindent(ranges, new_text, cx);
 286                } else {
 287                    buffer.edit(ranges, new_text, cx);
 288                }
 289            });
 290        }
 291
 292        let snapshot = self.read(cx);
 293        let mut buffer_edits: HashMap<usize, Vec<(Range<usize>, bool)>> = Default::default();
 294        let mut cursor = snapshot.excerpts.cursor::<usize>();
 295        for range in ranges_iter {
 296            let start = range.start.to_offset(&snapshot);
 297            let end = range.end.to_offset(&snapshot);
 298            cursor.seek(&start, Bias::Right, &());
 299            if cursor.item().is_none() && start == *cursor.start() {
 300                cursor.prev(&());
 301            }
 302            let start_excerpt = cursor.item().expect("start offset out of bounds");
 303            let start_overshoot = start - cursor.start();
 304            let buffer_start =
 305                start_excerpt.range.start.to_offset(&start_excerpt.buffer) + start_overshoot;
 306
 307            cursor.seek(&end, Bias::Right, &());
 308            if cursor.item().is_none() && end == *cursor.start() {
 309                cursor.prev(&());
 310            }
 311            let end_excerpt = cursor.item().expect("end offset out of bounds");
 312            let end_overshoot = end - cursor.start();
 313            let buffer_end = end_excerpt.range.start.to_offset(&end_excerpt.buffer) + end_overshoot;
 314
 315            if start_excerpt.id == end_excerpt.id {
 316                buffer_edits
 317                    .entry(start_excerpt.buffer_id)
 318                    .or_insert(Vec::new())
 319                    .push((buffer_start..buffer_end, true));
 320            } else {
 321                let start_excerpt_range =
 322                    buffer_start..start_excerpt.range.end.to_offset(&start_excerpt.buffer);
 323                let end_excerpt_range =
 324                    end_excerpt.range.start.to_offset(&end_excerpt.buffer)..buffer_end;
 325                buffer_edits
 326                    .entry(start_excerpt.buffer_id)
 327                    .or_insert(Vec::new())
 328                    .push((start_excerpt_range, true));
 329                buffer_edits
 330                    .entry(end_excerpt.buffer_id)
 331                    .or_insert(Vec::new())
 332                    .push((end_excerpt_range, false));
 333
 334                cursor.seek(&start, Bias::Right, &());
 335                cursor.next(&());
 336                while let Some(excerpt) = cursor.item() {
 337                    if excerpt.id == end_excerpt.id {
 338                        break;
 339                    }
 340                    buffer_edits
 341                        .entry(excerpt.buffer_id)
 342                        .or_insert(Vec::new())
 343                        .push((excerpt.range.to_offset(&excerpt.buffer), false));
 344                    cursor.next(&());
 345                }
 346            }
 347        }
 348
 349        let new_text = new_text.into();
 350        for (buffer_id, mut edits) in buffer_edits {
 351            edits.sort_unstable_by_key(|(range, _)| range.start);
 352            self.buffers.borrow()[&buffer_id]
 353                .buffer
 354                .update(cx, |buffer, cx| {
 355                    let mut edits = edits.into_iter().peekable();
 356                    let mut insertions = Vec::new();
 357                    let mut deletions = Vec::new();
 358                    while let Some((mut range, mut is_insertion)) = edits.next() {
 359                        while let Some((next_range, next_is_insertion)) = edits.peek() {
 360                            if range.end >= next_range.start {
 361                                range.end = cmp::max(next_range.end, range.end);
 362                                is_insertion |= *next_is_insertion;
 363                                edits.next();
 364                            } else {
 365                                break;
 366                            }
 367                        }
 368
 369                        if is_insertion {
 370                            insertions.push(
 371                                buffer.anchor_before(range.start)..buffer.anchor_before(range.end),
 372                            );
 373                        } else if !range.is_empty() {
 374                            deletions.push(
 375                                buffer.anchor_before(range.start)..buffer.anchor_before(range.end),
 376                            );
 377                        }
 378                    }
 379
 380                    if autoindent {
 381                        buffer.edit_with_autoindent(deletions, "", cx);
 382                        buffer.edit_with_autoindent(insertions, new_text.clone(), cx);
 383                    } else {
 384                        buffer.edit(deletions, "", cx);
 385                        buffer.edit(insertions, new_text.clone(), cx);
 386                    }
 387                })
 388        }
 389    }
 390
 391    pub fn start_transaction(&mut self, cx: &mut ModelContext<Self>) -> Option<TransactionId> {
 392        self.start_transaction_at(Instant::now(), cx)
 393    }
 394
 395    pub(crate) fn start_transaction_at(
 396        &mut self,
 397        now: Instant,
 398        cx: &mut ModelContext<Self>,
 399    ) -> Option<TransactionId> {
 400        if let Some(buffer) = self.as_singleton() {
 401            return buffer.update(cx, |buffer, _| buffer.start_transaction_at(now));
 402        }
 403
 404        for BufferState { buffer, .. } in self.buffers.borrow().values() {
 405            buffer.update(cx, |buffer, _| buffer.start_transaction_at(now));
 406        }
 407        self.history.start_transaction(now)
 408    }
 409
 410    pub fn end_transaction(&mut self, cx: &mut ModelContext<Self>) -> Option<TransactionId> {
 411        self.end_transaction_at(Instant::now(), cx)
 412    }
 413
 414    pub(crate) fn end_transaction_at(
 415        &mut self,
 416        now: Instant,
 417        cx: &mut ModelContext<Self>,
 418    ) -> Option<TransactionId> {
 419        if let Some(buffer) = self.as_singleton() {
 420            return buffer.update(cx, |buffer, cx| buffer.end_transaction_at(now, cx));
 421        }
 422
 423        let mut buffer_transactions = HashMap::default();
 424        for BufferState { buffer, .. } in self.buffers.borrow().values() {
 425            if let Some(transaction_id) =
 426                buffer.update(cx, |buffer, cx| buffer.end_transaction_at(now, cx))
 427            {
 428                buffer_transactions.insert(buffer.id(), transaction_id);
 429            }
 430        }
 431
 432        if self.history.end_transaction(now, buffer_transactions) {
 433            let transaction_id = self.history.group().unwrap();
 434            Some(transaction_id)
 435        } else {
 436            None
 437        }
 438    }
 439
 440    pub fn finalize_last_transaction(&mut self, cx: &mut ModelContext<Self>) {
 441        self.history.finalize_last_transaction();
 442        for BufferState { buffer, .. } in self.buffers.borrow().values() {
 443            buffer.update(cx, |buffer, _| {
 444                buffer.finalize_last_transaction();
 445            });
 446        }
 447    }
 448
 449    pub fn push_transaction<'a, T>(&mut self, buffer_transactions: T)
 450    where
 451        T: IntoIterator<Item = (&'a ModelHandle<Buffer>, &'a language::Transaction)>,
 452    {
 453        self.history
 454            .push_transaction(buffer_transactions, Instant::now());
 455        self.history.finalize_last_transaction();
 456    }
 457
 458    pub fn set_active_selections(
 459        &mut self,
 460        selections: &[Selection<Anchor>],
 461        cx: &mut ModelContext<Self>,
 462    ) {
 463        let mut selections_by_buffer: HashMap<usize, Vec<Selection<text::Anchor>>> =
 464            Default::default();
 465        let snapshot = self.read(cx);
 466        let mut cursor = snapshot.excerpts.cursor::<Option<&ExcerptId>>();
 467        for selection in selections {
 468            cursor.seek(&Some(&selection.start.excerpt_id), Bias::Left, &());
 469            while let Some(excerpt) = cursor.item() {
 470                if excerpt.id > selection.end.excerpt_id {
 471                    break;
 472                }
 473
 474                let mut start = excerpt.range.start.clone();
 475                let mut end = excerpt.range.end.clone();
 476                if excerpt.id == selection.start.excerpt_id {
 477                    start = selection.start.text_anchor.clone();
 478                }
 479                if excerpt.id == selection.end.excerpt_id {
 480                    end = selection.end.text_anchor.clone();
 481                }
 482                selections_by_buffer
 483                    .entry(excerpt.buffer_id)
 484                    .or_default()
 485                    .push(Selection {
 486                        id: selection.id,
 487                        start,
 488                        end,
 489                        reversed: selection.reversed,
 490                        goal: selection.goal,
 491                    });
 492
 493                cursor.next(&());
 494            }
 495        }
 496
 497        for (buffer_id, buffer_state) in self.buffers.borrow().iter() {
 498            if !selections_by_buffer.contains_key(buffer_id) {
 499                buffer_state
 500                    .buffer
 501                    .update(cx, |buffer, cx| buffer.remove_active_selections(cx));
 502            }
 503        }
 504
 505        for (buffer_id, mut selections) in selections_by_buffer {
 506            self.buffers.borrow()[&buffer_id]
 507                .buffer
 508                .update(cx, |buffer, cx| {
 509                    selections.sort_unstable_by(|a, b| a.start.cmp(&b.start, buffer).unwrap());
 510                    let mut selections = selections.into_iter().peekable();
 511                    let merged_selections = Arc::from_iter(iter::from_fn(|| {
 512                        let mut selection = selections.next()?;
 513                        while let Some(next_selection) = selections.peek() {
 514                            if selection
 515                                .end
 516                                .cmp(&next_selection.start, buffer)
 517                                .unwrap()
 518                                .is_ge()
 519                            {
 520                                let next_selection = selections.next().unwrap();
 521                                if next_selection
 522                                    .end
 523                                    .cmp(&selection.end, buffer)
 524                                    .unwrap()
 525                                    .is_ge()
 526                                {
 527                                    selection.end = next_selection.end;
 528                                }
 529                            } else {
 530                                break;
 531                            }
 532                        }
 533                        Some(selection)
 534                    }));
 535                    buffer.set_active_selections(merged_selections, cx);
 536                });
 537        }
 538    }
 539
 540    pub fn remove_active_selections(&mut self, cx: &mut ModelContext<Self>) {
 541        for buffer in self.buffers.borrow().values() {
 542            buffer
 543                .buffer
 544                .update(cx, |buffer, cx| buffer.remove_active_selections(cx));
 545        }
 546    }
 547
 548    pub fn undo(&mut self, cx: &mut ModelContext<Self>) -> Option<TransactionId> {
 549        if let Some(buffer) = self.as_singleton() {
 550            return buffer.update(cx, |buffer, cx| buffer.undo(cx));
 551        }
 552
 553        while let Some(transaction) = self.history.pop_undo() {
 554            let mut undone = false;
 555            for (buffer_id, buffer_transaction_id) in &mut transaction.buffer_transactions {
 556                if let Some(BufferState { buffer, .. }) = self.buffers.borrow().get(&buffer_id) {
 557                    undone |= buffer.update(cx, |buffer, cx| {
 558                        let undo_to = *buffer_transaction_id;
 559                        if let Some(entry) = buffer.peek_undo_stack() {
 560                            *buffer_transaction_id = entry.transaction_id();
 561                        }
 562                        buffer.undo_to_transaction(undo_to, cx)
 563                    });
 564                }
 565            }
 566
 567            if undone {
 568                return Some(transaction.id);
 569            }
 570        }
 571
 572        None
 573    }
 574
 575    pub fn redo(&mut self, cx: &mut ModelContext<Self>) -> Option<TransactionId> {
 576        if let Some(buffer) = self.as_singleton() {
 577            return buffer.update(cx, |buffer, cx| buffer.redo(cx));
 578        }
 579
 580        while let Some(transaction) = self.history.pop_redo() {
 581            let mut redone = false;
 582            for (buffer_id, buffer_transaction_id) in &mut transaction.buffer_transactions {
 583                if let Some(BufferState { buffer, .. }) = self.buffers.borrow().get(&buffer_id) {
 584                    redone |= buffer.update(cx, |buffer, cx| {
 585                        let redo_to = *buffer_transaction_id;
 586                        if let Some(entry) = buffer.peek_redo_stack() {
 587                            *buffer_transaction_id = entry.transaction_id();
 588                        }
 589                        buffer.redo_to_transaction(redo_to, cx)
 590                    });
 591                }
 592            }
 593
 594            if redone {
 595                return Some(transaction.id);
 596            }
 597        }
 598
 599        None
 600    }
 601
 602    pub fn push_excerpts<O>(
 603        &mut self,
 604        buffer: ModelHandle<Buffer>,
 605        ranges: impl IntoIterator<Item = Range<O>>,
 606        cx: &mut ModelContext<Self>,
 607    ) -> Vec<ExcerptId>
 608    where
 609        O: text::ToOffset,
 610    {
 611        self.insert_excerpts_after(&ExcerptId::max(), buffer, ranges, cx)
 612    }
 613
 614    pub fn push_excerpts_with_context_lines<O>(
 615        &mut self,
 616        buffer: ModelHandle<Buffer>,
 617        ranges: Vec<Range<O>>,
 618        context_line_count: u32,
 619        cx: &mut ModelContext<Self>,
 620    ) -> Vec<Range<Anchor>>
 621    where
 622        O: text::ToPoint + text::ToOffset,
 623    {
 624        let buffer_id = buffer.id();
 625        let buffer_snapshot = buffer.read(cx).snapshot();
 626        let max_point = buffer_snapshot.max_point();
 627
 628        let mut range_counts = Vec::new();
 629        let mut excerpt_ranges = Vec::new();
 630        let mut range_iter = ranges
 631            .iter()
 632            .map(|range| {
 633                range.start.to_point(&buffer_snapshot)..range.end.to_point(&buffer_snapshot)
 634            })
 635            .peekable();
 636        while let Some(range) = range_iter.next() {
 637            let excerpt_start = Point::new(range.start.row.saturating_sub(context_line_count), 0);
 638            let mut excerpt_end =
 639                Point::new(range.end.row + 1 + context_line_count, 0).min(max_point);
 640            let mut ranges_in_excerpt = 1;
 641
 642            while let Some(next_range) = range_iter.peek() {
 643                if next_range.start.row <= excerpt_end.row + context_line_count {
 644                    excerpt_end =
 645                        Point::new(next_range.end.row + 1 + context_line_count, 0).min(max_point);
 646                    ranges_in_excerpt += 1;
 647                    range_iter.next();
 648                } else {
 649                    break;
 650                }
 651            }
 652
 653            excerpt_ranges.push(excerpt_start..excerpt_end);
 654            range_counts.push(ranges_in_excerpt);
 655        }
 656
 657        let excerpt_ids = self.push_excerpts(buffer, excerpt_ranges, cx);
 658
 659        let mut anchor_ranges = Vec::new();
 660        let mut ranges = ranges.into_iter();
 661        for (excerpt_id, range_count) in excerpt_ids.into_iter().zip(range_counts.into_iter()) {
 662            anchor_ranges.extend(ranges.by_ref().take(range_count).map(|range| {
 663                let start = Anchor {
 664                    buffer_id: Some(buffer_id),
 665                    excerpt_id: excerpt_id.clone(),
 666                    text_anchor: buffer_snapshot.anchor_after(range.start),
 667                };
 668                let end = Anchor {
 669                    buffer_id: Some(buffer_id),
 670                    excerpt_id: excerpt_id.clone(),
 671                    text_anchor: buffer_snapshot.anchor_after(range.end),
 672                };
 673                start..end
 674            }))
 675        }
 676        anchor_ranges
 677    }
 678
 679    pub fn insert_excerpts_after<O>(
 680        &mut self,
 681        prev_excerpt_id: &ExcerptId,
 682        buffer: ModelHandle<Buffer>,
 683        ranges: impl IntoIterator<Item = Range<O>>,
 684        cx: &mut ModelContext<Self>,
 685    ) -> Vec<ExcerptId>
 686    where
 687        O: text::ToOffset,
 688    {
 689        assert_eq!(self.history.transaction_depth, 0);
 690        self.sync(cx);
 691
 692        let buffer_id = buffer.id();
 693        let buffer_snapshot = buffer.read(cx).snapshot();
 694
 695        let mut buffers = self.buffers.borrow_mut();
 696        let buffer_state = buffers.entry(buffer_id).or_insert_with(|| BufferState {
 697            last_version: buffer_snapshot.version().clone(),
 698            last_parse_count: buffer_snapshot.parse_count(),
 699            last_selections_update_count: buffer_snapshot.selections_update_count(),
 700            last_diagnostics_update_count: buffer_snapshot.diagnostics_update_count(),
 701            last_file_update_count: buffer_snapshot.file_update_count(),
 702            excerpts: Default::default(),
 703            _subscriptions: [
 704                cx.observe(&buffer, |_, _, cx| cx.notify()),
 705                cx.subscribe(&buffer, Self::on_buffer_event),
 706            ],
 707            buffer,
 708        });
 709
 710        let mut snapshot = self.snapshot.borrow_mut();
 711        let mut cursor = snapshot.excerpts.cursor::<Option<&ExcerptId>>();
 712        let mut new_excerpts = cursor.slice(&Some(prev_excerpt_id), Bias::Right, &());
 713
 714        let mut prev_id = ExcerptId::min();
 715        let edit_start = new_excerpts.summary().text.bytes;
 716        new_excerpts.update_last(
 717            |excerpt| {
 718                excerpt.has_trailing_newline = true;
 719                prev_id = excerpt.id.clone();
 720            },
 721            &(),
 722        );
 723
 724        let mut next_id = ExcerptId::max();
 725        if let Some(next_excerpt) = cursor.item() {
 726            next_id = next_excerpt.id.clone();
 727        }
 728
 729        let mut ids = Vec::new();
 730        let mut ranges = ranges.into_iter().peekable();
 731        while let Some(range) = ranges.next() {
 732            let id = ExcerptId::between(&prev_id, &next_id);
 733            if let Err(ix) = buffer_state.excerpts.binary_search(&id) {
 734                buffer_state.excerpts.insert(ix, id.clone());
 735            }
 736            let range = buffer_snapshot.anchor_before(&range.start)
 737                ..buffer_snapshot.anchor_after(&range.end);
 738            let excerpt = Excerpt::new(
 739                id.clone(),
 740                buffer_id,
 741                buffer_snapshot.clone(),
 742                range,
 743                ranges.peek().is_some() || cursor.item().is_some(),
 744            );
 745            new_excerpts.push(excerpt, &());
 746            prev_id = id.clone();
 747            ids.push(id);
 748        }
 749
 750        let edit_end = new_excerpts.summary().text.bytes;
 751
 752        let suffix = cursor.suffix(&());
 753        let changed_trailing_excerpt = suffix.is_empty();
 754        new_excerpts.push_tree(suffix, &());
 755        drop(cursor);
 756        snapshot.excerpts = new_excerpts;
 757        if changed_trailing_excerpt {
 758            snapshot.trailing_excerpt_update_count += 1;
 759        }
 760
 761        self.subscriptions.publish_mut([Edit {
 762            old: edit_start..edit_start,
 763            new: edit_start..edit_end,
 764        }]);
 765
 766        cx.notify();
 767        ids
 768    }
 769
 770    pub fn clear(&mut self, cx: &mut ModelContext<Self>) {
 771        self.buffers.borrow_mut().clear();
 772        let mut snapshot = self.snapshot.borrow_mut();
 773        let prev_len = snapshot.len();
 774        snapshot.excerpts = Default::default();
 775        snapshot.trailing_excerpt_update_count += 1;
 776        snapshot.is_dirty = false;
 777        snapshot.has_conflict = false;
 778        self.subscriptions.publish_mut([Edit {
 779            old: 0..prev_len,
 780            new: 0..0,
 781        }]);
 782        cx.notify();
 783    }
 784
 785    pub fn excerpt_ids_for_buffer(&self, buffer: &ModelHandle<Buffer>) -> Vec<ExcerptId> {
 786        self.buffers
 787            .borrow()
 788            .get(&buffer.id())
 789            .map_or(Vec::new(), |state| state.excerpts.clone())
 790    }
 791
 792    pub fn excerpt_containing(
 793        &self,
 794        position: impl ToOffset,
 795        cx: &AppContext,
 796    ) -> Option<(ModelHandle<Buffer>, Range<text::Anchor>)> {
 797        let snapshot = self.read(cx);
 798        let position = position.to_offset(&snapshot);
 799
 800        let mut cursor = snapshot.excerpts.cursor::<usize>();
 801        cursor.seek(&position, Bias::Right, &());
 802        cursor.item().map(|excerpt| {
 803            (
 804                self.buffers
 805                    .borrow()
 806                    .get(&excerpt.buffer_id)
 807                    .unwrap()
 808                    .buffer
 809                    .clone(),
 810                excerpt.range.clone(),
 811            )
 812        })
 813    }
 814
 815    pub fn range_to_buffer_ranges<'a, T: ToOffset>(
 816        &'a self,
 817        range: Range<T>,
 818        cx: &AppContext,
 819    ) -> Vec<(ModelHandle<Buffer>, Range<usize>)> {
 820        let snapshot = self.read(cx);
 821        let start = range.start.to_offset(&snapshot);
 822        let end = range.end.to_offset(&snapshot);
 823
 824        let mut result = Vec::new();
 825        let mut cursor = snapshot.excerpts.cursor::<usize>();
 826        cursor.seek(&start, Bias::Right, &());
 827        while let Some(excerpt) = cursor.item() {
 828            if *cursor.start() > end {
 829                break;
 830            }
 831
 832            let mut end_before_newline = cursor.end(&());
 833            if excerpt.has_trailing_newline {
 834                end_before_newline -= 1;
 835            }
 836            let excerpt_start = excerpt.range.start.to_offset(&excerpt.buffer);
 837            let start = excerpt_start + (cmp::max(start, *cursor.start()) - *cursor.start());
 838            let end = excerpt_start + (cmp::min(end, end_before_newline) - *cursor.start());
 839            let buffer = self.buffers.borrow()[&excerpt.buffer_id].buffer.clone();
 840            result.push((buffer, start..end));
 841            cursor.next(&());
 842        }
 843
 844        result
 845    }
 846
 847    pub fn remove_excerpts<'a>(
 848        &mut self,
 849        excerpt_ids: impl IntoIterator<Item = &'a ExcerptId>,
 850        cx: &mut ModelContext<Self>,
 851    ) {
 852        let mut buffers = self.buffers.borrow_mut();
 853        let mut snapshot = self.snapshot.borrow_mut();
 854        let mut new_excerpts = SumTree::new();
 855        let mut cursor = snapshot.excerpts.cursor::<(Option<&ExcerptId>, usize)>();
 856        let mut edits = Vec::new();
 857        let mut excerpt_ids = excerpt_ids.into_iter().peekable();
 858
 859        while let Some(mut excerpt_id) = excerpt_ids.next() {
 860            // Seek to the next excerpt to remove, preserving any preceding excerpts.
 861            new_excerpts.push_tree(cursor.slice(&Some(excerpt_id), Bias::Left, &()), &());
 862            if let Some(mut excerpt) = cursor.item() {
 863                if excerpt.id != *excerpt_id {
 864                    continue;
 865                }
 866                let mut old_start = cursor.start().1;
 867
 868                // Skip over the removed excerpt.
 869                loop {
 870                    if let Some(buffer_state) = buffers.get_mut(&excerpt.buffer_id) {
 871                        buffer_state.excerpts.retain(|id| id != excerpt_id);
 872                        if buffer_state.excerpts.is_empty() {
 873                            buffers.remove(&excerpt.buffer_id);
 874                        }
 875                    }
 876                    cursor.next(&());
 877
 878                    // Skip over any subsequent excerpts that are also removed.
 879                    if let Some(&next_excerpt_id) = excerpt_ids.peek() {
 880                        if let Some(next_excerpt) = cursor.item() {
 881                            if next_excerpt.id == *next_excerpt_id {
 882                                excerpt = next_excerpt;
 883                                excerpt_id = excerpt_ids.next().unwrap();
 884                                continue;
 885                            }
 886                        }
 887                    }
 888
 889                    break;
 890                }
 891
 892                // When removing the last excerpt, remove the trailing newline from
 893                // the previous excerpt.
 894                if cursor.item().is_none() && old_start > 0 {
 895                    old_start -= 1;
 896                    new_excerpts.update_last(|e| e.has_trailing_newline = false, &());
 897                }
 898
 899                // Push an edit for the removal of this run of excerpts.
 900                let old_end = cursor.start().1;
 901                let new_start = new_excerpts.summary().text.bytes;
 902                edits.push(Edit {
 903                    old: old_start..old_end,
 904                    new: new_start..new_start,
 905                });
 906            }
 907        }
 908        let suffix = cursor.suffix(&());
 909        let changed_trailing_excerpt = suffix.is_empty();
 910        new_excerpts.push_tree(suffix, &());
 911        drop(cursor);
 912        snapshot.excerpts = new_excerpts;
 913        if changed_trailing_excerpt {
 914            snapshot.trailing_excerpt_update_count += 1;
 915        }
 916
 917        self.subscriptions.publish_mut(edits);
 918        cx.notify();
 919    }
 920
 921    pub fn text_anchor_for_position<'a, T: ToOffset>(
 922        &'a self,
 923        position: T,
 924        cx: &AppContext,
 925    ) -> Option<(ModelHandle<Buffer>, language::Anchor)> {
 926        let snapshot = self.read(cx);
 927        let anchor = snapshot.anchor_before(position);
 928        Some((
 929            self.buffers.borrow()[&anchor.buffer_id?].buffer.clone(),
 930            anchor.text_anchor,
 931        ))
 932    }
 933
 934    fn on_buffer_event(
 935        &mut self,
 936        _: ModelHandle<Buffer>,
 937        event: &Event,
 938        cx: &mut ModelContext<Self>,
 939    ) {
 940        cx.emit(event.clone());
 941    }
 942
 943    pub fn all_buffers(&self) -> HashSet<ModelHandle<Buffer>> {
 944        self.buffers
 945            .borrow()
 946            .values()
 947            .map(|state| state.buffer.clone())
 948            .collect()
 949    }
 950
 951    pub fn save(&mut self, cx: &mut ModelContext<Self>) -> Task<Result<()>> {
 952        let mut save_tasks = Vec::new();
 953        for BufferState { buffer, .. } in self.buffers.borrow().values() {
 954            save_tasks.push(buffer.update(cx, |buffer, cx| buffer.save(cx)));
 955        }
 956
 957        cx.spawn(|_, _| async move {
 958            for save in save_tasks {
 959                save.await?;
 960            }
 961            Ok(())
 962        })
 963    }
 964
 965    pub fn is_completion_trigger<T>(&self, position: T, text: &str, cx: &AppContext) -> bool
 966    where
 967        T: ToOffset,
 968    {
 969        let mut chars = text.chars();
 970        let char = if let Some(char) = chars.next() {
 971            char
 972        } else {
 973            return false;
 974        };
 975        if chars.next().is_some() {
 976            return false;
 977        }
 978
 979        if char.is_alphanumeric() || char == '_' {
 980            return true;
 981        }
 982
 983        let snapshot = self.snapshot(cx);
 984        let anchor = snapshot.anchor_before(position);
 985        anchor.buffer_id.map_or(false, |buffer_id| {
 986            let buffer = self.buffers.borrow()[&buffer_id].buffer.clone();
 987            buffer
 988                .read(cx)
 989                .completion_triggers()
 990                .iter()
 991                .any(|string| string == text)
 992        })
 993    }
 994
 995    pub fn language<'a>(&self, cx: &'a AppContext) -> Option<&'a Arc<Language>> {
 996        self.buffers
 997            .borrow()
 998            .values()
 999            .next()
1000            .and_then(|state| state.buffer.read(cx).language())
1001    }
1002
1003    pub fn file<'a>(&self, cx: &'a AppContext) -> Option<&'a dyn File> {
1004        self.as_singleton()?.read(cx).file()
1005    }
1006
1007    pub fn title(&self, cx: &AppContext) -> String {
1008        if let Some(title) = self.title.clone() {
1009            title
1010        } else if let Some(file) = self.file(cx) {
1011            file.file_name(cx).to_string_lossy().into()
1012        } else {
1013            "untitled".into()
1014        }
1015    }
1016
1017    #[cfg(test)]
1018    pub fn is_parsing(&self, cx: &AppContext) -> bool {
1019        self.as_singleton().unwrap().read(cx).is_parsing()
1020    }
1021
1022    fn sync(&self, cx: &AppContext) {
1023        let mut snapshot = self.snapshot.borrow_mut();
1024        let mut excerpts_to_edit = Vec::new();
1025        let mut reparsed = false;
1026        let mut diagnostics_updated = false;
1027        let mut is_dirty = false;
1028        let mut has_conflict = false;
1029        let mut buffers = self.buffers.borrow_mut();
1030        for buffer_state in buffers.values_mut() {
1031            let buffer = buffer_state.buffer.read(cx);
1032            let version = buffer.version();
1033            let parse_count = buffer.parse_count();
1034            let selections_update_count = buffer.selections_update_count();
1035            let diagnostics_update_count = buffer.diagnostics_update_count();
1036            let file_update_count = buffer.file_update_count();
1037
1038            let buffer_edited = version.changed_since(&buffer_state.last_version);
1039            let buffer_reparsed = parse_count > buffer_state.last_parse_count;
1040            let buffer_selections_updated =
1041                selections_update_count > buffer_state.last_selections_update_count;
1042            let buffer_diagnostics_updated =
1043                diagnostics_update_count > buffer_state.last_diagnostics_update_count;
1044            let buffer_file_updated = file_update_count > buffer_state.last_file_update_count;
1045            if buffer_edited
1046                || buffer_reparsed
1047                || buffer_selections_updated
1048                || buffer_diagnostics_updated
1049                || buffer_file_updated
1050            {
1051                buffer_state.last_version = version;
1052                buffer_state.last_parse_count = parse_count;
1053                buffer_state.last_selections_update_count = selections_update_count;
1054                buffer_state.last_diagnostics_update_count = diagnostics_update_count;
1055                buffer_state.last_file_update_count = file_update_count;
1056                excerpts_to_edit.extend(
1057                    buffer_state
1058                        .excerpts
1059                        .iter()
1060                        .map(|excerpt_id| (excerpt_id, buffer_state.buffer.clone(), buffer_edited)),
1061                );
1062            }
1063
1064            reparsed |= buffer_reparsed;
1065            diagnostics_updated |= buffer_diagnostics_updated;
1066            is_dirty |= buffer.is_dirty();
1067            has_conflict |= buffer.has_conflict();
1068        }
1069        if reparsed {
1070            snapshot.parse_count += 1;
1071        }
1072        if diagnostics_updated {
1073            snapshot.diagnostics_update_count += 1;
1074        }
1075        snapshot.is_dirty = is_dirty;
1076        snapshot.has_conflict = has_conflict;
1077
1078        excerpts_to_edit.sort_unstable_by_key(|(excerpt_id, _, _)| *excerpt_id);
1079
1080        let mut edits = Vec::new();
1081        let mut new_excerpts = SumTree::new();
1082        let mut cursor = snapshot.excerpts.cursor::<(Option<&ExcerptId>, usize)>();
1083
1084        for (id, buffer, buffer_edited) in excerpts_to_edit {
1085            new_excerpts.push_tree(cursor.slice(&Some(id), Bias::Left, &()), &());
1086            let old_excerpt = cursor.item().unwrap();
1087            let buffer_id = buffer.id();
1088            let buffer = buffer.read(cx);
1089
1090            let mut new_excerpt;
1091            if buffer_edited {
1092                edits.extend(
1093                    buffer
1094                        .edits_since_in_range::<usize>(
1095                            old_excerpt.buffer.version(),
1096                            old_excerpt.range.clone(),
1097                        )
1098                        .map(|mut edit| {
1099                            let excerpt_old_start = cursor.start().1;
1100                            let excerpt_new_start = new_excerpts.summary().text.bytes;
1101                            edit.old.start += excerpt_old_start;
1102                            edit.old.end += excerpt_old_start;
1103                            edit.new.start += excerpt_new_start;
1104                            edit.new.end += excerpt_new_start;
1105                            edit
1106                        }),
1107                );
1108
1109                new_excerpt = Excerpt::new(
1110                    id.clone(),
1111                    buffer_id,
1112                    buffer.snapshot(),
1113                    old_excerpt.range.clone(),
1114                    old_excerpt.has_trailing_newline,
1115                );
1116            } else {
1117                new_excerpt = old_excerpt.clone();
1118                new_excerpt.buffer = buffer.snapshot();
1119            }
1120
1121            new_excerpts.push(new_excerpt, &());
1122            cursor.next(&());
1123        }
1124        new_excerpts.push_tree(cursor.suffix(&()), &());
1125
1126        drop(cursor);
1127        snapshot.excerpts = new_excerpts;
1128
1129        self.subscriptions.publish(edits);
1130    }
1131}
1132
1133#[cfg(any(test, feature = "test-support"))]
1134impl MultiBuffer {
1135    pub fn randomly_edit(
1136        &mut self,
1137        rng: &mut impl rand::Rng,
1138        count: usize,
1139        cx: &mut ModelContext<Self>,
1140    ) {
1141        use text::RandomCharIter;
1142
1143        let snapshot = self.read(cx);
1144        let mut old_ranges: Vec<Range<usize>> = Vec::new();
1145        for _ in 0..count {
1146            let last_end = old_ranges.last().map_or(0, |last_range| last_range.end + 1);
1147            if last_end > snapshot.len() {
1148                break;
1149            }
1150            let end_ix = snapshot.clip_offset(rng.gen_range(0..=last_end), Bias::Right);
1151            let start_ix = snapshot.clip_offset(rng.gen_range(0..=end_ix), Bias::Left);
1152            old_ranges.push(start_ix..end_ix);
1153        }
1154        let new_text_len = rng.gen_range(0..10);
1155        let new_text: String = RandomCharIter::new(&mut *rng).take(new_text_len).collect();
1156        log::info!("mutating multi-buffer at {:?}: {:?}", old_ranges, new_text);
1157        drop(snapshot);
1158
1159        self.edit(old_ranges.iter().cloned(), new_text.as_str(), cx);
1160    }
1161
1162    pub fn randomly_edit_excerpts(
1163        &mut self,
1164        rng: &mut impl rand::Rng,
1165        mutation_count: usize,
1166        cx: &mut ModelContext<Self>,
1167    ) {
1168        use rand::prelude::*;
1169        use std::env;
1170        use text::RandomCharIter;
1171
1172        let max_excerpts = env::var("MAX_EXCERPTS")
1173            .map(|i| i.parse().expect("invalid `MAX_EXCERPTS` variable"))
1174            .unwrap_or(5);
1175
1176        let mut buffers = Vec::new();
1177        for _ in 0..mutation_count {
1178            if rng.gen_bool(0.05) {
1179                log::info!("Clearing multi-buffer");
1180                self.clear(cx);
1181                continue;
1182            }
1183
1184            let excerpt_ids = self
1185                .buffers
1186                .borrow()
1187                .values()
1188                .flat_map(|b| &b.excerpts)
1189                .cloned()
1190                .collect::<Vec<_>>();
1191            if excerpt_ids.len() == 0 || (rng.gen() && excerpt_ids.len() < max_excerpts) {
1192                let buffer_handle = if rng.gen() || self.buffers.borrow().is_empty() {
1193                    let text = RandomCharIter::new(&mut *rng).take(10).collect::<String>();
1194                    buffers.push(cx.add_model(|cx| Buffer::new(0, text, cx)));
1195                    let buffer = buffers.last().unwrap();
1196                    log::info!(
1197                        "Creating new buffer {} with text: {:?}",
1198                        buffer.id(),
1199                        buffer.read(cx).text()
1200                    );
1201                    buffers.last().unwrap().clone()
1202                } else {
1203                    self.buffers
1204                        .borrow()
1205                        .values()
1206                        .choose(rng)
1207                        .unwrap()
1208                        .buffer
1209                        .clone()
1210                };
1211
1212                let buffer = buffer_handle.read(cx);
1213                let end_ix = buffer.clip_offset(rng.gen_range(0..=buffer.len()), Bias::Right);
1214                let start_ix = buffer.clip_offset(rng.gen_range(0..=end_ix), Bias::Left);
1215                log::info!(
1216                    "Inserting excerpt from buffer {} and range {:?}: {:?}",
1217                    buffer_handle.id(),
1218                    start_ix..end_ix,
1219                    &buffer.text()[start_ix..end_ix]
1220                );
1221
1222                let excerpt_id = self.push_excerpts(buffer_handle.clone(), [start_ix..end_ix], cx);
1223                log::info!("Inserted with id: {:?}", excerpt_id);
1224            } else {
1225                let remove_count = rng.gen_range(1..=excerpt_ids.len());
1226                let mut excerpts_to_remove = excerpt_ids
1227                    .choose_multiple(rng, remove_count)
1228                    .cloned()
1229                    .collect::<Vec<_>>();
1230                excerpts_to_remove.sort();
1231                log::info!("Removing excerpts {:?}", excerpts_to_remove);
1232                self.remove_excerpts(&excerpts_to_remove, cx);
1233            }
1234        }
1235    }
1236
1237    pub fn randomly_mutate(
1238        &mut self,
1239        rng: &mut impl rand::Rng,
1240        mutation_count: usize,
1241        cx: &mut ModelContext<Self>,
1242    ) {
1243        if rng.gen_bool(0.7) || self.singleton {
1244            self.randomly_edit(rng, mutation_count, cx);
1245        } else {
1246            self.randomly_edit_excerpts(rng, mutation_count, cx);
1247        }
1248    }
1249}
1250
1251impl Entity for MultiBuffer {
1252    type Event = language::Event;
1253}
1254
1255impl MultiBufferSnapshot {
1256    pub fn text(&self) -> String {
1257        self.chunks(0..self.len(), false)
1258            .map(|chunk| chunk.text)
1259            .collect()
1260    }
1261
1262    pub fn reversed_chars_at<'a, T: ToOffset>(
1263        &'a self,
1264        position: T,
1265    ) -> impl Iterator<Item = char> + 'a {
1266        let mut offset = position.to_offset(self);
1267        let mut cursor = self.excerpts.cursor::<usize>();
1268        cursor.seek(&offset, Bias::Left, &());
1269        let mut excerpt_chunks = cursor.item().map(|excerpt| {
1270            let end_before_footer = cursor.start() + excerpt.text_summary.bytes;
1271            let start = excerpt.range.start.to_offset(&excerpt.buffer);
1272            let end = start + (cmp::min(offset, end_before_footer) - cursor.start());
1273            excerpt.buffer.reversed_chunks_in_range(start..end)
1274        });
1275        iter::from_fn(move || {
1276            if offset == *cursor.start() {
1277                cursor.prev(&());
1278                let excerpt = cursor.item()?;
1279                excerpt_chunks = Some(
1280                    excerpt
1281                        .buffer
1282                        .reversed_chunks_in_range(excerpt.range.clone()),
1283                );
1284            }
1285
1286            let excerpt = cursor.item().unwrap();
1287            if offset == cursor.end(&()) && excerpt.has_trailing_newline {
1288                offset -= 1;
1289                Some("\n")
1290            } else {
1291                let chunk = excerpt_chunks.as_mut().unwrap().next().unwrap();
1292                offset -= chunk.len();
1293                Some(chunk)
1294            }
1295        })
1296        .flat_map(|c| c.chars().rev())
1297    }
1298
1299    pub fn chars_at<'a, T: ToOffset>(&'a self, position: T) -> impl Iterator<Item = char> + 'a {
1300        let offset = position.to_offset(self);
1301        self.text_for_range(offset..self.len())
1302            .flat_map(|chunk| chunk.chars())
1303    }
1304
1305    pub fn text_for_range<'a, T: ToOffset>(
1306        &'a self,
1307        range: Range<T>,
1308    ) -> impl Iterator<Item = &'a str> {
1309        self.chunks(range, false).map(|chunk| chunk.text)
1310    }
1311
1312    pub fn is_line_blank(&self, row: u32) -> bool {
1313        self.text_for_range(Point::new(row, 0)..Point::new(row, self.line_len(row)))
1314            .all(|chunk| chunk.matches(|c: char| !c.is_whitespace()).next().is_none())
1315    }
1316
1317    pub fn contains_str_at<T>(&self, position: T, needle: &str) -> bool
1318    where
1319        T: ToOffset,
1320    {
1321        let position = position.to_offset(self);
1322        position == self.clip_offset(position, Bias::Left)
1323            && self
1324                .bytes_in_range(position..self.len())
1325                .flatten()
1326                .copied()
1327                .take(needle.len())
1328                .eq(needle.bytes())
1329    }
1330
1331    pub fn surrounding_word<T: ToOffset>(&self, start: T) -> (Range<usize>, Option<CharKind>) {
1332        let mut start = start.to_offset(self);
1333        let mut end = start;
1334        let mut next_chars = self.chars_at(start).peekable();
1335        let mut prev_chars = self.reversed_chars_at(start).peekable();
1336        let word_kind = cmp::max(
1337            prev_chars.peek().copied().map(char_kind),
1338            next_chars.peek().copied().map(char_kind),
1339        );
1340
1341        for ch in prev_chars {
1342            if Some(char_kind(ch)) == word_kind {
1343                start -= ch.len_utf8();
1344            } else {
1345                break;
1346            }
1347        }
1348
1349        for ch in next_chars {
1350            if Some(char_kind(ch)) == word_kind {
1351                end += ch.len_utf8();
1352            } else {
1353                break;
1354            }
1355        }
1356
1357        (start..end, word_kind)
1358    }
1359
1360    pub fn as_singleton(&self) -> Option<(&ExcerptId, usize, &BufferSnapshot)> {
1361        if self.singleton {
1362            self.excerpts
1363                .iter()
1364                .next()
1365                .map(|e| (&e.id, e.buffer_id, &e.buffer))
1366        } else {
1367            None
1368        }
1369    }
1370
1371    pub fn len(&self) -> usize {
1372        self.excerpts.summary().text.bytes
1373    }
1374
1375    pub fn max_buffer_row(&self) -> u32 {
1376        self.excerpts.summary().max_buffer_row
1377    }
1378
1379    pub fn clip_offset(&self, offset: usize, bias: Bias) -> usize {
1380        if let Some((_, _, buffer)) = self.as_singleton() {
1381            return buffer.clip_offset(offset, bias);
1382        }
1383
1384        let mut cursor = self.excerpts.cursor::<usize>();
1385        cursor.seek(&offset, Bias::Right, &());
1386        let overshoot = if let Some(excerpt) = cursor.item() {
1387            let excerpt_start = excerpt.range.start.to_offset(&excerpt.buffer);
1388            let buffer_offset = excerpt
1389                .buffer
1390                .clip_offset(excerpt_start + (offset - cursor.start()), bias);
1391            buffer_offset.saturating_sub(excerpt_start)
1392        } else {
1393            0
1394        };
1395        cursor.start() + overshoot
1396    }
1397
1398    pub fn clip_point(&self, point: Point, bias: Bias) -> Point {
1399        if let Some((_, _, buffer)) = self.as_singleton() {
1400            return buffer.clip_point(point, bias);
1401        }
1402
1403        let mut cursor = self.excerpts.cursor::<Point>();
1404        cursor.seek(&point, Bias::Right, &());
1405        let overshoot = if let Some(excerpt) = cursor.item() {
1406            let excerpt_start = excerpt.range.start.to_point(&excerpt.buffer);
1407            let buffer_point = excerpt
1408                .buffer
1409                .clip_point(excerpt_start + (point - cursor.start()), bias);
1410            buffer_point.saturating_sub(excerpt_start)
1411        } else {
1412            Point::zero()
1413        };
1414        *cursor.start() + overshoot
1415    }
1416
1417    pub fn clip_point_utf16(&self, point: PointUtf16, bias: Bias) -> PointUtf16 {
1418        if let Some((_, _, buffer)) = self.as_singleton() {
1419            return buffer.clip_point_utf16(point, bias);
1420        }
1421
1422        let mut cursor = self.excerpts.cursor::<PointUtf16>();
1423        cursor.seek(&point, Bias::Right, &());
1424        let overshoot = if let Some(excerpt) = cursor.item() {
1425            let excerpt_start = excerpt
1426                .buffer
1427                .offset_to_point_utf16(excerpt.range.start.to_offset(&excerpt.buffer));
1428            let buffer_point = excerpt
1429                .buffer
1430                .clip_point_utf16(excerpt_start + (point - cursor.start()), bias);
1431            buffer_point.saturating_sub(excerpt_start)
1432        } else {
1433            PointUtf16::zero()
1434        };
1435        *cursor.start() + overshoot
1436    }
1437
1438    pub fn bytes_in_range<'a, T: ToOffset>(&'a self, range: Range<T>) -> MultiBufferBytes<'a> {
1439        let range = range.start.to_offset(self)..range.end.to_offset(self);
1440        let mut excerpts = self.excerpts.cursor::<usize>();
1441        excerpts.seek(&range.start, Bias::Right, &());
1442
1443        let mut chunk = &[][..];
1444        let excerpt_bytes = if let Some(excerpt) = excerpts.item() {
1445            let mut excerpt_bytes = excerpt
1446                .bytes_in_range(range.start - excerpts.start()..range.end - excerpts.start());
1447            chunk = excerpt_bytes.next().unwrap_or(&[][..]);
1448            Some(excerpt_bytes)
1449        } else {
1450            None
1451        };
1452
1453        MultiBufferBytes {
1454            range,
1455            excerpts,
1456            excerpt_bytes,
1457            chunk,
1458        }
1459    }
1460
1461    pub fn buffer_rows<'a>(&'a self, start_row: u32) -> MultiBufferRows<'a> {
1462        let mut result = MultiBufferRows {
1463            buffer_row_range: 0..0,
1464            excerpts: self.excerpts.cursor(),
1465        };
1466        result.seek(start_row);
1467        result
1468    }
1469
1470    pub fn chunks<'a, T: ToOffset>(
1471        &'a self,
1472        range: Range<T>,
1473        language_aware: bool,
1474    ) -> MultiBufferChunks<'a> {
1475        let range = range.start.to_offset(self)..range.end.to_offset(self);
1476        let mut chunks = MultiBufferChunks {
1477            range: range.clone(),
1478            excerpts: self.excerpts.cursor(),
1479            excerpt_chunks: None,
1480            language_aware,
1481        };
1482        chunks.seek(range.start);
1483        chunks
1484    }
1485
1486    pub fn offset_to_point(&self, offset: usize) -> Point {
1487        if let Some((_, _, buffer)) = self.as_singleton() {
1488            return buffer.offset_to_point(offset);
1489        }
1490
1491        let mut cursor = self.excerpts.cursor::<(usize, Point)>();
1492        cursor.seek(&offset, Bias::Right, &());
1493        if let Some(excerpt) = cursor.item() {
1494            let (start_offset, start_point) = cursor.start();
1495            let overshoot = offset - start_offset;
1496            let excerpt_start_offset = excerpt.range.start.to_offset(&excerpt.buffer);
1497            let excerpt_start_point = excerpt.range.start.to_point(&excerpt.buffer);
1498            let buffer_point = excerpt
1499                .buffer
1500                .offset_to_point(excerpt_start_offset + overshoot);
1501            *start_point + (buffer_point - excerpt_start_point)
1502        } else {
1503            self.excerpts.summary().text.lines
1504        }
1505    }
1506
1507    pub fn offset_to_point_utf16(&self, offset: usize) -> PointUtf16 {
1508        if let Some((_, _, buffer)) = self.as_singleton() {
1509            return buffer.offset_to_point_utf16(offset);
1510        }
1511
1512        let mut cursor = self.excerpts.cursor::<(usize, PointUtf16)>();
1513        cursor.seek(&offset, Bias::Right, &());
1514        if let Some(excerpt) = cursor.item() {
1515            let (start_offset, start_point) = cursor.start();
1516            let overshoot = offset - start_offset;
1517            let excerpt_start_offset = excerpt.range.start.to_offset(&excerpt.buffer);
1518            let excerpt_start_point = excerpt.range.start.to_point_utf16(&excerpt.buffer);
1519            let buffer_point = excerpt
1520                .buffer
1521                .offset_to_point_utf16(excerpt_start_offset + overshoot);
1522            *start_point + (buffer_point - excerpt_start_point)
1523        } else {
1524            self.excerpts.summary().text.lines_utf16
1525        }
1526    }
1527
1528    pub fn point_to_point_utf16(&self, point: Point) -> PointUtf16 {
1529        if let Some((_, _, buffer)) = self.as_singleton() {
1530            return buffer.point_to_point_utf16(point);
1531        }
1532
1533        let mut cursor = self.excerpts.cursor::<(Point, PointUtf16)>();
1534        cursor.seek(&point, Bias::Right, &());
1535        if let Some(excerpt) = cursor.item() {
1536            let (start_offset, start_point) = cursor.start();
1537            let overshoot = point - start_offset;
1538            let excerpt_start_point = excerpt.range.start.to_point(&excerpt.buffer);
1539            let excerpt_start_point_utf16 = excerpt.range.start.to_point_utf16(&excerpt.buffer);
1540            let buffer_point = excerpt
1541                .buffer
1542                .point_to_point_utf16(excerpt_start_point + overshoot);
1543            *start_point + (buffer_point - excerpt_start_point_utf16)
1544        } else {
1545            self.excerpts.summary().text.lines_utf16
1546        }
1547    }
1548
1549    pub fn point_to_offset(&self, point: Point) -> usize {
1550        if let Some((_, _, buffer)) = self.as_singleton() {
1551            return buffer.point_to_offset(point);
1552        }
1553
1554        let mut cursor = self.excerpts.cursor::<(Point, usize)>();
1555        cursor.seek(&point, Bias::Right, &());
1556        if let Some(excerpt) = cursor.item() {
1557            let (start_point, start_offset) = cursor.start();
1558            let overshoot = point - start_point;
1559            let excerpt_start_offset = excerpt.range.start.to_offset(&excerpt.buffer);
1560            let excerpt_start_point = excerpt.range.start.to_point(&excerpt.buffer);
1561            let buffer_offset = excerpt
1562                .buffer
1563                .point_to_offset(excerpt_start_point + overshoot);
1564            *start_offset + buffer_offset - excerpt_start_offset
1565        } else {
1566            self.excerpts.summary().text.bytes
1567        }
1568    }
1569
1570    pub fn point_utf16_to_offset(&self, point: PointUtf16) -> usize {
1571        if let Some((_, _, buffer)) = self.as_singleton() {
1572            return buffer.point_utf16_to_offset(point);
1573        }
1574
1575        let mut cursor = self.excerpts.cursor::<(PointUtf16, usize)>();
1576        cursor.seek(&point, Bias::Right, &());
1577        if let Some(excerpt) = cursor.item() {
1578            let (start_point, start_offset) = cursor.start();
1579            let overshoot = point - start_point;
1580            let excerpt_start_offset = excerpt.range.start.to_offset(&excerpt.buffer);
1581            let excerpt_start_point = excerpt
1582                .buffer
1583                .offset_to_point_utf16(excerpt.range.start.to_offset(&excerpt.buffer));
1584            let buffer_offset = excerpt
1585                .buffer
1586                .point_utf16_to_offset(excerpt_start_point + overshoot);
1587            *start_offset + (buffer_offset - excerpt_start_offset)
1588        } else {
1589            self.excerpts.summary().text.bytes
1590        }
1591    }
1592
1593    pub fn indent_column_for_line(&self, row: u32) -> u32 {
1594        if let Some((buffer, range)) = self.buffer_line_for_row(row) {
1595            buffer
1596                .indent_column_for_line(range.start.row)
1597                .min(range.end.column)
1598                .saturating_sub(range.start.column)
1599        } else {
1600            0
1601        }
1602    }
1603
1604    pub fn line_len(&self, row: u32) -> u32 {
1605        if let Some((_, range)) = self.buffer_line_for_row(row) {
1606            range.end.column - range.start.column
1607        } else {
1608            0
1609        }
1610    }
1611
1612    fn buffer_line_for_row(&self, row: u32) -> Option<(&BufferSnapshot, Range<Point>)> {
1613        let mut cursor = self.excerpts.cursor::<Point>();
1614        cursor.seek(&Point::new(row, 0), Bias::Right, &());
1615        if let Some(excerpt) = cursor.item() {
1616            let overshoot = row - cursor.start().row;
1617            let excerpt_start = excerpt.range.start.to_point(&excerpt.buffer);
1618            let excerpt_end = excerpt.range.end.to_point(&excerpt.buffer);
1619            let buffer_row = excerpt_start.row + overshoot;
1620            let line_start = Point::new(buffer_row, 0);
1621            let line_end = Point::new(buffer_row, excerpt.buffer.line_len(buffer_row));
1622            return Some((
1623                &excerpt.buffer,
1624                line_start.max(excerpt_start)..line_end.min(excerpt_end),
1625            ));
1626        }
1627        None
1628    }
1629
1630    pub fn max_point(&self) -> Point {
1631        self.text_summary().lines
1632    }
1633
1634    pub fn text_summary(&self) -> TextSummary {
1635        self.excerpts.summary().text
1636    }
1637
1638    pub fn text_summary_for_range<'a, D, O>(&'a self, range: Range<O>) -> D
1639    where
1640        D: TextDimension,
1641        O: ToOffset,
1642    {
1643        let mut summary = D::default();
1644        let mut range = range.start.to_offset(self)..range.end.to_offset(self);
1645        let mut cursor = self.excerpts.cursor::<usize>();
1646        cursor.seek(&range.start, Bias::Right, &());
1647        if let Some(excerpt) = cursor.item() {
1648            let mut end_before_newline = cursor.end(&());
1649            if excerpt.has_trailing_newline {
1650                end_before_newline -= 1;
1651            }
1652
1653            let excerpt_start = excerpt.range.start.to_offset(&excerpt.buffer);
1654            let start_in_excerpt = excerpt_start + (range.start - cursor.start());
1655            let end_in_excerpt =
1656                excerpt_start + (cmp::min(end_before_newline, range.end) - cursor.start());
1657            summary.add_assign(
1658                &excerpt
1659                    .buffer
1660                    .text_summary_for_range(start_in_excerpt..end_in_excerpt),
1661            );
1662
1663            if range.end > end_before_newline {
1664                summary.add_assign(&D::from_text_summary(&TextSummary {
1665                    bytes: 1,
1666                    lines: Point::new(1 as u32, 0),
1667                    lines_utf16: PointUtf16::new(1 as u32, 0),
1668                    first_line_chars: 0,
1669                    last_line_chars: 0,
1670                    longest_row: 0,
1671                    longest_row_chars: 0,
1672                }));
1673            }
1674
1675            cursor.next(&());
1676        }
1677
1678        if range.end > *cursor.start() {
1679            summary.add_assign(&D::from_text_summary(&cursor.summary::<_, TextSummary>(
1680                &range.end,
1681                Bias::Right,
1682                &(),
1683            )));
1684            if let Some(excerpt) = cursor.item() {
1685                range.end = cmp::max(*cursor.start(), range.end);
1686
1687                let excerpt_start = excerpt.range.start.to_offset(&excerpt.buffer);
1688                let end_in_excerpt = excerpt_start + (range.end - cursor.start());
1689                summary.add_assign(
1690                    &excerpt
1691                        .buffer
1692                        .text_summary_for_range(excerpt_start..end_in_excerpt),
1693                );
1694            }
1695        }
1696
1697        summary
1698    }
1699
1700    pub fn summary_for_anchor<D>(&self, anchor: &Anchor) -> D
1701    where
1702        D: TextDimension + Ord + Sub<D, Output = D>,
1703    {
1704        let mut cursor = self.excerpts.cursor::<ExcerptSummary>();
1705        cursor.seek(&Some(&anchor.excerpt_id), Bias::Left, &());
1706        if cursor.item().is_none() {
1707            cursor.next(&());
1708        }
1709
1710        let mut position = D::from_text_summary(&cursor.start().text);
1711        if let Some(excerpt) = cursor.item() {
1712            if excerpt.id == anchor.excerpt_id && Some(excerpt.buffer_id) == anchor.buffer_id {
1713                let excerpt_buffer_start = excerpt.range.start.summary::<D>(&excerpt.buffer);
1714                let excerpt_buffer_end = excerpt.range.end.summary::<D>(&excerpt.buffer);
1715                let buffer_position = cmp::min(
1716                    excerpt_buffer_end,
1717                    anchor.text_anchor.summary::<D>(&excerpt.buffer),
1718                );
1719                if buffer_position > excerpt_buffer_start {
1720                    position.add_assign(&(buffer_position - excerpt_buffer_start));
1721                }
1722            }
1723        }
1724        position
1725    }
1726
1727    pub fn summaries_for_anchors<'a, D, I>(&'a self, anchors: I) -> Vec<D>
1728    where
1729        D: TextDimension + Ord + Sub<D, Output = D>,
1730        I: 'a + IntoIterator<Item = &'a Anchor>,
1731    {
1732        if let Some((_, _, buffer)) = self.as_singleton() {
1733            return buffer
1734                .summaries_for_anchors(anchors.into_iter().map(|a| &a.text_anchor))
1735                .collect();
1736        }
1737
1738        let mut anchors = anchors.into_iter().peekable();
1739        let mut cursor = self.excerpts.cursor::<ExcerptSummary>();
1740        let mut summaries = Vec::new();
1741        while let Some(anchor) = anchors.peek() {
1742            let excerpt_id = &anchor.excerpt_id;
1743            let buffer_id = anchor.buffer_id;
1744            let excerpt_anchors = iter::from_fn(|| {
1745                let anchor = anchors.peek()?;
1746                if anchor.excerpt_id == *excerpt_id && anchor.buffer_id == buffer_id {
1747                    Some(&anchors.next().unwrap().text_anchor)
1748                } else {
1749                    None
1750                }
1751            });
1752
1753            cursor.seek_forward(&Some(excerpt_id), Bias::Left, &());
1754            if cursor.item().is_none() {
1755                cursor.next(&());
1756            }
1757
1758            let position = D::from_text_summary(&cursor.start().text);
1759            if let Some(excerpt) = cursor.item() {
1760                if excerpt.id == *excerpt_id && Some(excerpt.buffer_id) == buffer_id {
1761                    let excerpt_buffer_start = excerpt.range.start.summary::<D>(&excerpt.buffer);
1762                    let excerpt_buffer_end = excerpt.range.end.summary::<D>(&excerpt.buffer);
1763                    summaries.extend(
1764                        excerpt
1765                            .buffer
1766                            .summaries_for_anchors::<D, _>(excerpt_anchors)
1767                            .map(move |summary| {
1768                                let summary = cmp::min(excerpt_buffer_end.clone(), summary);
1769                                let mut position = position.clone();
1770                                let excerpt_buffer_start = excerpt_buffer_start.clone();
1771                                if summary > excerpt_buffer_start {
1772                                    position.add_assign(&(summary - excerpt_buffer_start));
1773                                }
1774                                position
1775                            }),
1776                    );
1777                    continue;
1778                }
1779            }
1780
1781            summaries.extend(excerpt_anchors.map(|_| position.clone()));
1782        }
1783
1784        summaries
1785    }
1786
1787    pub fn refresh_anchors<'a, I>(&'a self, anchors: I) -> Vec<(usize, Anchor, bool)>
1788    where
1789        I: 'a + IntoIterator<Item = &'a Anchor>,
1790    {
1791        let mut anchors = anchors.into_iter().enumerate().peekable();
1792        let mut cursor = self.excerpts.cursor::<Option<&ExcerptId>>();
1793        let mut result = Vec::new();
1794        while let Some((_, anchor)) = anchors.peek() {
1795            let old_excerpt_id = &anchor.excerpt_id;
1796
1797            // Find the location where this anchor's excerpt should be.
1798            cursor.seek_forward(&Some(old_excerpt_id), Bias::Left, &());
1799            if cursor.item().is_none() {
1800                cursor.next(&());
1801            }
1802
1803            let next_excerpt = cursor.item();
1804            let prev_excerpt = cursor.prev_item();
1805
1806            // Process all of the anchors for this excerpt.
1807            while let Some((_, anchor)) = anchors.peek() {
1808                if anchor.excerpt_id != *old_excerpt_id {
1809                    break;
1810                }
1811                let mut kept_position = false;
1812                let (anchor_ix, anchor) = anchors.next().unwrap();
1813                let mut anchor = anchor.clone();
1814
1815                // Leave min and max anchors unchanged.
1816                if *old_excerpt_id == ExcerptId::max() || *old_excerpt_id == ExcerptId::min() {
1817                    kept_position = true;
1818                }
1819                // If the old excerpt still exists at this location, then leave
1820                // the anchor unchanged.
1821                else if next_excerpt.map_or(false, |excerpt| {
1822                    excerpt.id == *old_excerpt_id && excerpt.contains(&anchor)
1823                }) {
1824                    kept_position = true;
1825                }
1826                // If the old excerpt no longer exists at this location, then attempt to
1827                // find an equivalent position for this anchor in an adjacent excerpt.
1828                else {
1829                    for excerpt in [next_excerpt, prev_excerpt].iter().filter_map(|e| *e) {
1830                        if excerpt.contains(&anchor) {
1831                            anchor.excerpt_id = excerpt.id.clone();
1832                            kept_position = true;
1833                            break;
1834                        }
1835                    }
1836                }
1837                // If there's no adjacent excerpt that contains the anchor's position,
1838                // then report that the anchor has lost its position.
1839                if !kept_position {
1840                    anchor = if let Some(excerpt) = next_excerpt {
1841                        let mut text_anchor = excerpt
1842                            .range
1843                            .start
1844                            .bias(anchor.text_anchor.bias, &excerpt.buffer);
1845                        if text_anchor
1846                            .cmp(&excerpt.range.end, &excerpt.buffer)
1847                            .unwrap()
1848                            .is_gt()
1849                        {
1850                            text_anchor = excerpt.range.end.clone();
1851                        }
1852                        Anchor {
1853                            buffer_id: Some(excerpt.buffer_id),
1854                            excerpt_id: excerpt.id.clone(),
1855                            text_anchor,
1856                        }
1857                    } else if let Some(excerpt) = prev_excerpt {
1858                        let mut text_anchor = excerpt
1859                            .range
1860                            .end
1861                            .bias(anchor.text_anchor.bias, &excerpt.buffer);
1862                        if text_anchor
1863                            .cmp(&excerpt.range.start, &excerpt.buffer)
1864                            .unwrap()
1865                            .is_lt()
1866                        {
1867                            text_anchor = excerpt.range.start.clone();
1868                        }
1869                        Anchor {
1870                            buffer_id: Some(excerpt.buffer_id),
1871                            excerpt_id: excerpt.id.clone(),
1872                            text_anchor,
1873                        }
1874                    } else if anchor.text_anchor.bias == Bias::Left {
1875                        Anchor::min()
1876                    } else {
1877                        Anchor::max()
1878                    };
1879                }
1880
1881                result.push((anchor_ix, anchor, kept_position));
1882            }
1883        }
1884        result.sort_unstable_by(|a, b| a.1.cmp(&b.1, self).unwrap());
1885        result
1886    }
1887
1888    pub fn anchor_before<T: ToOffset>(&self, position: T) -> Anchor {
1889        self.anchor_at(position, Bias::Left)
1890    }
1891
1892    pub fn anchor_after<T: ToOffset>(&self, position: T) -> Anchor {
1893        self.anchor_at(position, Bias::Right)
1894    }
1895
1896    pub fn anchor_at<T: ToOffset>(&self, position: T, mut bias: Bias) -> Anchor {
1897        let offset = position.to_offset(self);
1898        if let Some((excerpt_id, buffer_id, buffer)) = self.as_singleton() {
1899            return Anchor {
1900                buffer_id: Some(buffer_id),
1901                excerpt_id: excerpt_id.clone(),
1902                text_anchor: buffer.anchor_at(offset, bias),
1903            };
1904        }
1905
1906        let mut cursor = self.excerpts.cursor::<(usize, Option<&ExcerptId>)>();
1907        cursor.seek(&offset, Bias::Right, &());
1908        if cursor.item().is_none() && offset == cursor.start().0 && bias == Bias::Left {
1909            cursor.prev(&());
1910        }
1911        if let Some(excerpt) = cursor.item() {
1912            let mut overshoot = offset.saturating_sub(cursor.start().0);
1913            if excerpt.has_trailing_newline && offset == cursor.end(&()).0 {
1914                overshoot -= 1;
1915                bias = Bias::Right;
1916            }
1917
1918            let buffer_start = excerpt.range.start.to_offset(&excerpt.buffer);
1919            let text_anchor =
1920                excerpt.clip_anchor(excerpt.buffer.anchor_at(buffer_start + overshoot, bias));
1921            Anchor {
1922                buffer_id: Some(excerpt.buffer_id),
1923                excerpt_id: excerpt.id.clone(),
1924                text_anchor,
1925            }
1926        } else if offset == 0 && bias == Bias::Left {
1927            Anchor::min()
1928        } else {
1929            Anchor::max()
1930        }
1931    }
1932
1933    pub fn anchor_in_excerpt(&self, excerpt_id: ExcerptId, text_anchor: text::Anchor) -> Anchor {
1934        let mut cursor = self.excerpts.cursor::<Option<&ExcerptId>>();
1935        cursor.seek(&Some(&excerpt_id), Bias::Left, &());
1936        if let Some(excerpt) = cursor.item() {
1937            if excerpt.id == excerpt_id {
1938                let text_anchor = excerpt.clip_anchor(text_anchor);
1939                drop(cursor);
1940                return Anchor {
1941                    buffer_id: Some(excerpt.buffer_id),
1942                    excerpt_id,
1943                    text_anchor,
1944                };
1945            }
1946        }
1947        panic!("excerpt not found");
1948    }
1949
1950    pub fn can_resolve(&self, anchor: &Anchor) -> bool {
1951        if anchor.excerpt_id == ExcerptId::min() || anchor.excerpt_id == ExcerptId::max() {
1952            true
1953        } else if let Some((buffer_id, buffer_snapshot)) =
1954            self.buffer_snapshot_for_excerpt(&anchor.excerpt_id)
1955        {
1956            anchor.buffer_id == Some(buffer_id) && buffer_snapshot.can_resolve(&anchor.text_anchor)
1957        } else {
1958            false
1959        }
1960    }
1961
1962    pub fn excerpt_boundaries_in_range<'a, R, T>(
1963        &'a self,
1964        range: R,
1965    ) -> impl Iterator<Item = ExcerptBoundary> + 'a
1966    where
1967        R: RangeBounds<T>,
1968        T: ToOffset,
1969    {
1970        let start_offset;
1971        let start = match range.start_bound() {
1972            Bound::Included(start) => {
1973                start_offset = start.to_offset(self);
1974                Bound::Included(start_offset)
1975            }
1976            Bound::Excluded(start) => {
1977                start_offset = start.to_offset(self);
1978                Bound::Excluded(start_offset)
1979            }
1980            Bound::Unbounded => {
1981                start_offset = 0;
1982                Bound::Unbounded
1983            }
1984        };
1985        let end = match range.end_bound() {
1986            Bound::Included(end) => Bound::Included(end.to_offset(self)),
1987            Bound::Excluded(end) => Bound::Excluded(end.to_offset(self)),
1988            Bound::Unbounded => Bound::Unbounded,
1989        };
1990        let bounds = (start, end);
1991
1992        let mut cursor = self.excerpts.cursor::<(usize, Point)>();
1993        cursor.seek(&start_offset, Bias::Right, &());
1994        if cursor.item().is_none() {
1995            cursor.prev(&());
1996        }
1997        if !bounds.contains(&cursor.start().0) {
1998            cursor.next(&());
1999        }
2000
2001        let mut prev_buffer_id = cursor.prev_item().map(|excerpt| excerpt.buffer_id);
2002        std::iter::from_fn(move || {
2003            if self.singleton {
2004                None
2005            } else if bounds.contains(&cursor.start().0) {
2006                let excerpt = cursor.item()?;
2007                let starts_new_buffer = Some(excerpt.buffer_id) != prev_buffer_id;
2008                let boundary = ExcerptBoundary {
2009                    id: excerpt.id.clone(),
2010                    row: cursor.start().1.row,
2011                    buffer: excerpt.buffer.clone(),
2012                    range: excerpt.range.clone(),
2013                    starts_new_buffer,
2014                };
2015
2016                prev_buffer_id = Some(excerpt.buffer_id);
2017                cursor.next(&());
2018                Some(boundary)
2019            } else {
2020                None
2021            }
2022        })
2023    }
2024
2025    pub fn parse_count(&self) -> usize {
2026        self.parse_count
2027    }
2028
2029    pub fn enclosing_bracket_ranges<T: ToOffset>(
2030        &self,
2031        range: Range<T>,
2032    ) -> Option<(Range<usize>, Range<usize>)> {
2033        let range = range.start.to_offset(self)..range.end.to_offset(self);
2034
2035        let mut cursor = self.excerpts.cursor::<usize>();
2036        cursor.seek(&range.start, Bias::Right, &());
2037        let start_excerpt = cursor.item();
2038
2039        cursor.seek(&range.end, Bias::Right, &());
2040        let end_excerpt = cursor.item();
2041
2042        start_excerpt
2043            .zip(end_excerpt)
2044            .and_then(|(start_excerpt, end_excerpt)| {
2045                if start_excerpt.id != end_excerpt.id {
2046                    return None;
2047                }
2048
2049                let excerpt_buffer_start =
2050                    start_excerpt.range.start.to_offset(&start_excerpt.buffer);
2051                let excerpt_buffer_end = excerpt_buffer_start + start_excerpt.text_summary.bytes;
2052
2053                let start_in_buffer =
2054                    excerpt_buffer_start + range.start.saturating_sub(*cursor.start());
2055                let end_in_buffer =
2056                    excerpt_buffer_start + range.end.saturating_sub(*cursor.start());
2057                let (mut start_bracket_range, mut end_bracket_range) = start_excerpt
2058                    .buffer
2059                    .enclosing_bracket_ranges(start_in_buffer..end_in_buffer)?;
2060
2061                if start_bracket_range.start >= excerpt_buffer_start
2062                    && end_bracket_range.end < excerpt_buffer_end
2063                {
2064                    start_bracket_range.start =
2065                        cursor.start() + (start_bracket_range.start - excerpt_buffer_start);
2066                    start_bracket_range.end =
2067                        cursor.start() + (start_bracket_range.end - excerpt_buffer_start);
2068                    end_bracket_range.start =
2069                        cursor.start() + (end_bracket_range.start - excerpt_buffer_start);
2070                    end_bracket_range.end =
2071                        cursor.start() + (end_bracket_range.end - excerpt_buffer_start);
2072                    Some((start_bracket_range, end_bracket_range))
2073                } else {
2074                    None
2075                }
2076            })
2077    }
2078
2079    pub fn diagnostics_update_count(&self) -> usize {
2080        self.diagnostics_update_count
2081    }
2082
2083    pub fn trailing_excerpt_update_count(&self) -> usize {
2084        self.trailing_excerpt_update_count
2085    }
2086
2087    pub fn language(&self) -> Option<&Arc<Language>> {
2088        self.excerpts
2089            .iter()
2090            .next()
2091            .and_then(|excerpt| excerpt.buffer.language())
2092    }
2093
2094    pub fn is_dirty(&self) -> bool {
2095        self.is_dirty
2096    }
2097
2098    pub fn has_conflict(&self) -> bool {
2099        self.has_conflict
2100    }
2101
2102    pub fn diagnostic_group<'a, O>(
2103        &'a self,
2104        group_id: usize,
2105    ) -> impl Iterator<Item = DiagnosticEntry<O>> + 'a
2106    where
2107        O: text::FromAnchor + 'a,
2108    {
2109        self.as_singleton()
2110            .into_iter()
2111            .flat_map(move |(_, _, buffer)| buffer.diagnostic_group(group_id))
2112    }
2113
2114    pub fn diagnostics_in_range<'a, T, O>(
2115        &'a self,
2116        range: Range<T>,
2117    ) -> impl Iterator<Item = DiagnosticEntry<O>> + 'a
2118    where
2119        T: 'a + ToOffset,
2120        O: 'a + text::FromAnchor,
2121    {
2122        self.as_singleton()
2123            .into_iter()
2124            .flat_map(move |(_, _, buffer)| {
2125                buffer.diagnostics_in_range(range.start.to_offset(self)..range.end.to_offset(self))
2126            })
2127    }
2128
2129    pub fn range_for_syntax_ancestor<T: ToOffset>(&self, range: Range<T>) -> Option<Range<usize>> {
2130        let range = range.start.to_offset(self)..range.end.to_offset(self);
2131
2132        let mut cursor = self.excerpts.cursor::<usize>();
2133        cursor.seek(&range.start, Bias::Right, &());
2134        let start_excerpt = cursor.item();
2135
2136        cursor.seek(&range.end, Bias::Right, &());
2137        let end_excerpt = cursor.item();
2138
2139        start_excerpt
2140            .zip(end_excerpt)
2141            .and_then(|(start_excerpt, end_excerpt)| {
2142                if start_excerpt.id != end_excerpt.id {
2143                    return None;
2144                }
2145
2146                let excerpt_buffer_start =
2147                    start_excerpt.range.start.to_offset(&start_excerpt.buffer);
2148                let excerpt_buffer_end = excerpt_buffer_start + start_excerpt.text_summary.bytes;
2149
2150                let start_in_buffer =
2151                    excerpt_buffer_start + range.start.saturating_sub(*cursor.start());
2152                let end_in_buffer =
2153                    excerpt_buffer_start + range.end.saturating_sub(*cursor.start());
2154                let mut ancestor_buffer_range = start_excerpt
2155                    .buffer
2156                    .range_for_syntax_ancestor(start_in_buffer..end_in_buffer)?;
2157                ancestor_buffer_range.start =
2158                    cmp::max(ancestor_buffer_range.start, excerpt_buffer_start);
2159                ancestor_buffer_range.end = cmp::min(ancestor_buffer_range.end, excerpt_buffer_end);
2160
2161                let start = cursor.start() + (ancestor_buffer_range.start - excerpt_buffer_start);
2162                let end = cursor.start() + (ancestor_buffer_range.end - excerpt_buffer_start);
2163                Some(start..end)
2164            })
2165    }
2166
2167    pub fn outline(&self, theme: Option<&SyntaxTheme>) -> Option<Outline<Anchor>> {
2168        let (excerpt_id, _, buffer) = self.as_singleton()?;
2169        let outline = buffer.outline(theme)?;
2170        Some(Outline::new(
2171            outline
2172                .items
2173                .into_iter()
2174                .map(|item| OutlineItem {
2175                    depth: item.depth,
2176                    range: self.anchor_in_excerpt(excerpt_id.clone(), item.range.start)
2177                        ..self.anchor_in_excerpt(excerpt_id.clone(), item.range.end),
2178                    text: item.text,
2179                    highlight_ranges: item.highlight_ranges,
2180                    name_ranges: item.name_ranges,
2181                })
2182                .collect(),
2183        ))
2184    }
2185
2186    fn buffer_snapshot_for_excerpt<'a>(
2187        &'a self,
2188        excerpt_id: &'a ExcerptId,
2189    ) -> Option<(usize, &'a BufferSnapshot)> {
2190        let mut cursor = self.excerpts.cursor::<Option<&ExcerptId>>();
2191        cursor.seek(&Some(excerpt_id), Bias::Left, &());
2192        if let Some(excerpt) = cursor.item() {
2193            if excerpt.id == *excerpt_id {
2194                return Some((excerpt.buffer_id, &excerpt.buffer));
2195            }
2196        }
2197        None
2198    }
2199
2200    pub fn remote_selections_in_range<'a>(
2201        &'a self,
2202        range: &'a Range<Anchor>,
2203    ) -> impl 'a + Iterator<Item = (ReplicaId, Selection<Anchor>)> {
2204        let mut cursor = self.excerpts.cursor::<Option<&ExcerptId>>();
2205        cursor.seek(&Some(&range.start.excerpt_id), Bias::Left, &());
2206        cursor
2207            .take_while(move |excerpt| excerpt.id <= range.end.excerpt_id)
2208            .flat_map(move |excerpt| {
2209                let mut query_range = excerpt.range.start.clone()..excerpt.range.end.clone();
2210                if excerpt.id == range.start.excerpt_id {
2211                    query_range.start = range.start.text_anchor.clone();
2212                }
2213                if excerpt.id == range.end.excerpt_id {
2214                    query_range.end = range.end.text_anchor.clone();
2215                }
2216
2217                excerpt
2218                    .buffer
2219                    .remote_selections_in_range(query_range)
2220                    .flat_map(move |(replica_id, selections)| {
2221                        selections.map(move |selection| {
2222                            let mut start = Anchor {
2223                                buffer_id: Some(excerpt.buffer_id),
2224                                excerpt_id: excerpt.id.clone(),
2225                                text_anchor: selection.start.clone(),
2226                            };
2227                            let mut end = Anchor {
2228                                buffer_id: Some(excerpt.buffer_id),
2229                                excerpt_id: excerpt.id.clone(),
2230                                text_anchor: selection.end.clone(),
2231                            };
2232                            if range.start.cmp(&start, self).unwrap().is_gt() {
2233                                start = range.start.clone();
2234                            }
2235                            if range.end.cmp(&end, self).unwrap().is_lt() {
2236                                end = range.end.clone();
2237                            }
2238
2239                            (
2240                                replica_id,
2241                                Selection {
2242                                    id: selection.id,
2243                                    start,
2244                                    end,
2245                                    reversed: selection.reversed,
2246                                    goal: selection.goal,
2247                                },
2248                            )
2249                        })
2250                    })
2251            })
2252    }
2253}
2254
2255impl History {
2256    fn start_transaction(&mut self, now: Instant) -> Option<TransactionId> {
2257        self.transaction_depth += 1;
2258        if self.transaction_depth == 1 {
2259            let id = self.next_transaction_id.tick();
2260            self.undo_stack.push(Transaction {
2261                id,
2262                buffer_transactions: Default::default(),
2263                first_edit_at: now,
2264                last_edit_at: now,
2265                suppress_grouping: false,
2266            });
2267            Some(id)
2268        } else {
2269            None
2270        }
2271    }
2272
2273    fn end_transaction(
2274        &mut self,
2275        now: Instant,
2276        buffer_transactions: HashMap<usize, TransactionId>,
2277    ) -> bool {
2278        assert_ne!(self.transaction_depth, 0);
2279        self.transaction_depth -= 1;
2280        if self.transaction_depth == 0 {
2281            if buffer_transactions.is_empty() {
2282                self.undo_stack.pop();
2283                false
2284            } else {
2285                let transaction = self.undo_stack.last_mut().unwrap();
2286                transaction.last_edit_at = now;
2287                for (buffer_id, transaction_id) in buffer_transactions {
2288                    transaction
2289                        .buffer_transactions
2290                        .entry(buffer_id)
2291                        .or_insert(transaction_id);
2292                }
2293                true
2294            }
2295        } else {
2296            false
2297        }
2298    }
2299
2300    fn push_transaction<'a, T>(&mut self, buffer_transactions: T, now: Instant)
2301    where
2302        T: IntoIterator<Item = (&'a ModelHandle<Buffer>, &'a language::Transaction)>,
2303    {
2304        assert_eq!(self.transaction_depth, 0);
2305        let transaction = Transaction {
2306            id: self.next_transaction_id.tick(),
2307            buffer_transactions: buffer_transactions
2308                .into_iter()
2309                .map(|(buffer, transaction)| (buffer.id(), transaction.id))
2310                .collect(),
2311            first_edit_at: now,
2312            last_edit_at: now,
2313            suppress_grouping: false,
2314        };
2315        if !transaction.buffer_transactions.is_empty() {
2316            self.undo_stack.push(transaction);
2317        }
2318    }
2319
2320    fn finalize_last_transaction(&mut self) {
2321        if let Some(transaction) = self.undo_stack.last_mut() {
2322            transaction.suppress_grouping = true;
2323        }
2324    }
2325
2326    fn pop_undo(&mut self) -> Option<&mut Transaction> {
2327        assert_eq!(self.transaction_depth, 0);
2328        if let Some(transaction) = self.undo_stack.pop() {
2329            self.redo_stack.push(transaction);
2330            self.redo_stack.last_mut()
2331        } else {
2332            None
2333        }
2334    }
2335
2336    fn pop_redo(&mut self) -> Option<&mut Transaction> {
2337        assert_eq!(self.transaction_depth, 0);
2338        if let Some(transaction) = self.redo_stack.pop() {
2339            self.undo_stack.push(transaction);
2340            self.undo_stack.last_mut()
2341        } else {
2342            None
2343        }
2344    }
2345
2346    fn group(&mut self) -> Option<TransactionId> {
2347        let mut new_len = self.undo_stack.len();
2348        let mut transactions = self.undo_stack.iter_mut();
2349
2350        if let Some(mut transaction) = transactions.next_back() {
2351            while let Some(prev_transaction) = transactions.next_back() {
2352                if !prev_transaction.suppress_grouping
2353                    && transaction.first_edit_at - prev_transaction.last_edit_at
2354                        <= self.group_interval
2355                {
2356                    transaction = prev_transaction;
2357                    new_len -= 1;
2358                } else {
2359                    break;
2360                }
2361            }
2362        }
2363
2364        let (transactions_to_keep, transactions_to_merge) = self.undo_stack.split_at_mut(new_len);
2365        if let Some(last_transaction) = transactions_to_keep.last_mut() {
2366            if let Some(transaction) = transactions_to_merge.last() {
2367                last_transaction.last_edit_at = transaction.last_edit_at;
2368            }
2369            for to_merge in transactions_to_merge {
2370                for (buffer_id, transaction_id) in &to_merge.buffer_transactions {
2371                    last_transaction
2372                        .buffer_transactions
2373                        .entry(*buffer_id)
2374                        .or_insert(*transaction_id);
2375                }
2376            }
2377        }
2378
2379        self.undo_stack.truncate(new_len);
2380        self.undo_stack.last().map(|t| t.id)
2381    }
2382}
2383
2384impl Excerpt {
2385    fn new(
2386        id: ExcerptId,
2387        buffer_id: usize,
2388        buffer: BufferSnapshot,
2389        range: Range<text::Anchor>,
2390        has_trailing_newline: bool,
2391    ) -> Self {
2392        Excerpt {
2393            id,
2394            max_buffer_row: range.end.to_point(&buffer).row,
2395            text_summary: buffer.text_summary_for_range::<TextSummary, _>(range.to_offset(&buffer)),
2396            buffer_id,
2397            buffer,
2398            range,
2399            has_trailing_newline,
2400        }
2401    }
2402
2403    fn chunks_in_range<'a>(
2404        &'a self,
2405        range: Range<usize>,
2406        language_aware: bool,
2407    ) -> ExcerptChunks<'a> {
2408        let content_start = self.range.start.to_offset(&self.buffer);
2409        let chunks_start = content_start + range.start;
2410        let chunks_end = content_start + cmp::min(range.end, self.text_summary.bytes);
2411
2412        let footer_height = if self.has_trailing_newline
2413            && range.start <= self.text_summary.bytes
2414            && range.end > self.text_summary.bytes
2415        {
2416            1
2417        } else {
2418            0
2419        };
2420
2421        let content_chunks = self.buffer.chunks(chunks_start..chunks_end, language_aware);
2422
2423        ExcerptChunks {
2424            content_chunks,
2425            footer_height,
2426        }
2427    }
2428
2429    fn bytes_in_range(&self, range: Range<usize>) -> ExcerptBytes {
2430        let content_start = self.range.start.to_offset(&self.buffer);
2431        let bytes_start = content_start + range.start;
2432        let bytes_end = content_start + cmp::min(range.end, self.text_summary.bytes);
2433        let footer_height = if self.has_trailing_newline
2434            && range.start <= self.text_summary.bytes
2435            && range.end > self.text_summary.bytes
2436        {
2437            1
2438        } else {
2439            0
2440        };
2441        let content_bytes = self.buffer.bytes_in_range(bytes_start..bytes_end);
2442
2443        ExcerptBytes {
2444            content_bytes,
2445            footer_height,
2446        }
2447    }
2448
2449    fn clip_anchor(&self, text_anchor: text::Anchor) -> text::Anchor {
2450        if text_anchor
2451            .cmp(&self.range.start, &self.buffer)
2452            .unwrap()
2453            .is_lt()
2454        {
2455            self.range.start.clone()
2456        } else if text_anchor
2457            .cmp(&self.range.end, &self.buffer)
2458            .unwrap()
2459            .is_gt()
2460        {
2461            self.range.end.clone()
2462        } else {
2463            text_anchor
2464        }
2465    }
2466
2467    fn contains(&self, anchor: &Anchor) -> bool {
2468        Some(self.buffer_id) == anchor.buffer_id
2469            && self
2470                .range
2471                .start
2472                .cmp(&anchor.text_anchor, &self.buffer)
2473                .unwrap()
2474                .is_le()
2475            && self
2476                .range
2477                .end
2478                .cmp(&anchor.text_anchor, &self.buffer)
2479                .unwrap()
2480                .is_ge()
2481    }
2482}
2483
2484impl fmt::Debug for Excerpt {
2485    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
2486        f.debug_struct("Excerpt")
2487            .field("id", &self.id)
2488            .field("buffer_id", &self.buffer_id)
2489            .field("range", &self.range)
2490            .field("text_summary", &self.text_summary)
2491            .field("has_trailing_newline", &self.has_trailing_newline)
2492            .finish()
2493    }
2494}
2495
2496impl sum_tree::Item for Excerpt {
2497    type Summary = ExcerptSummary;
2498
2499    fn summary(&self) -> Self::Summary {
2500        let mut text = self.text_summary.clone();
2501        if self.has_trailing_newline {
2502            text += TextSummary::from("\n");
2503        }
2504        ExcerptSummary {
2505            excerpt_id: self.id.clone(),
2506            max_buffer_row: self.max_buffer_row,
2507            text,
2508        }
2509    }
2510}
2511
2512impl sum_tree::Summary for ExcerptSummary {
2513    type Context = ();
2514
2515    fn add_summary(&mut self, summary: &Self, _: &()) {
2516        debug_assert!(summary.excerpt_id > self.excerpt_id);
2517        self.excerpt_id = summary.excerpt_id.clone();
2518        self.text.add_summary(&summary.text, &());
2519        self.max_buffer_row = cmp::max(self.max_buffer_row, summary.max_buffer_row);
2520    }
2521}
2522
2523impl<'a> sum_tree::Dimension<'a, ExcerptSummary> for TextSummary {
2524    fn add_summary(&mut self, summary: &'a ExcerptSummary, _: &()) {
2525        *self += &summary.text;
2526    }
2527}
2528
2529impl<'a> sum_tree::Dimension<'a, ExcerptSummary> for usize {
2530    fn add_summary(&mut self, summary: &'a ExcerptSummary, _: &()) {
2531        *self += summary.text.bytes;
2532    }
2533}
2534
2535impl<'a> sum_tree::SeekTarget<'a, ExcerptSummary, ExcerptSummary> for usize {
2536    fn cmp(&self, cursor_location: &ExcerptSummary, _: &()) -> cmp::Ordering {
2537        Ord::cmp(self, &cursor_location.text.bytes)
2538    }
2539}
2540
2541impl<'a> sum_tree::SeekTarget<'a, ExcerptSummary, ExcerptSummary> for Option<&'a ExcerptId> {
2542    fn cmp(&self, cursor_location: &ExcerptSummary, _: &()) -> cmp::Ordering {
2543        Ord::cmp(self, &Some(&cursor_location.excerpt_id))
2544    }
2545}
2546
2547impl<'a> sum_tree::Dimension<'a, ExcerptSummary> for Point {
2548    fn add_summary(&mut self, summary: &'a ExcerptSummary, _: &()) {
2549        *self += summary.text.lines;
2550    }
2551}
2552
2553impl<'a> sum_tree::Dimension<'a, ExcerptSummary> for PointUtf16 {
2554    fn add_summary(&mut self, summary: &'a ExcerptSummary, _: &()) {
2555        *self += summary.text.lines_utf16
2556    }
2557}
2558
2559impl<'a> sum_tree::Dimension<'a, ExcerptSummary> for Option<&'a ExcerptId> {
2560    fn add_summary(&mut self, summary: &'a ExcerptSummary, _: &()) {
2561        *self = Some(&summary.excerpt_id);
2562    }
2563}
2564
2565impl<'a> MultiBufferRows<'a> {
2566    pub fn seek(&mut self, row: u32) {
2567        self.buffer_row_range = 0..0;
2568
2569        self.excerpts
2570            .seek_forward(&Point::new(row, 0), Bias::Right, &());
2571        if self.excerpts.item().is_none() {
2572            self.excerpts.prev(&());
2573
2574            if self.excerpts.item().is_none() && row == 0 {
2575                self.buffer_row_range = 0..1;
2576                return;
2577            }
2578        }
2579
2580        if let Some(excerpt) = self.excerpts.item() {
2581            let overshoot = row - self.excerpts.start().row;
2582            let excerpt_start = excerpt.range.start.to_point(&excerpt.buffer).row;
2583            self.buffer_row_range.start = excerpt_start + overshoot;
2584            self.buffer_row_range.end = excerpt_start + excerpt.text_summary.lines.row + 1;
2585        }
2586    }
2587}
2588
2589impl<'a> Iterator for MultiBufferRows<'a> {
2590    type Item = Option<u32>;
2591
2592    fn next(&mut self) -> Option<Self::Item> {
2593        loop {
2594            if !self.buffer_row_range.is_empty() {
2595                let row = Some(self.buffer_row_range.start);
2596                self.buffer_row_range.start += 1;
2597                return Some(row);
2598            }
2599            self.excerpts.item()?;
2600            self.excerpts.next(&());
2601            let excerpt = self.excerpts.item()?;
2602            self.buffer_row_range.start = excerpt.range.start.to_point(&excerpt.buffer).row;
2603            self.buffer_row_range.end =
2604                self.buffer_row_range.start + excerpt.text_summary.lines.row + 1;
2605        }
2606    }
2607}
2608
2609impl<'a> MultiBufferChunks<'a> {
2610    pub fn offset(&self) -> usize {
2611        self.range.start
2612    }
2613
2614    pub fn seek(&mut self, offset: usize) {
2615        self.range.start = offset;
2616        self.excerpts.seek(&offset, Bias::Right, &());
2617        if let Some(excerpt) = self.excerpts.item() {
2618            self.excerpt_chunks = Some(excerpt.chunks_in_range(
2619                self.range.start - self.excerpts.start()..self.range.end - self.excerpts.start(),
2620                self.language_aware,
2621            ));
2622        } else {
2623            self.excerpt_chunks = None;
2624        }
2625    }
2626}
2627
2628impl<'a> Iterator for MultiBufferChunks<'a> {
2629    type Item = Chunk<'a>;
2630
2631    fn next(&mut self) -> Option<Self::Item> {
2632        if self.range.is_empty() {
2633            None
2634        } else if let Some(chunk) = self.excerpt_chunks.as_mut()?.next() {
2635            self.range.start += chunk.text.len();
2636            Some(chunk)
2637        } else {
2638            self.excerpts.next(&());
2639            let excerpt = self.excerpts.item()?;
2640            self.excerpt_chunks = Some(excerpt.chunks_in_range(
2641                0..self.range.end - self.excerpts.start(),
2642                self.language_aware,
2643            ));
2644            self.next()
2645        }
2646    }
2647}
2648
2649impl<'a> MultiBufferBytes<'a> {
2650    fn consume(&mut self, len: usize) {
2651        self.range.start += len;
2652        self.chunk = &self.chunk[len..];
2653
2654        if !self.range.is_empty() && self.chunk.is_empty() {
2655            if let Some(chunk) = self.excerpt_bytes.as_mut().and_then(|bytes| bytes.next()) {
2656                self.chunk = chunk;
2657            } else {
2658                self.excerpts.next(&());
2659                if let Some(excerpt) = self.excerpts.item() {
2660                    let mut excerpt_bytes =
2661                        excerpt.bytes_in_range(0..self.range.end - self.excerpts.start());
2662                    self.chunk = excerpt_bytes.next().unwrap();
2663                    self.excerpt_bytes = Some(excerpt_bytes);
2664                }
2665            }
2666        }
2667    }
2668}
2669
2670impl<'a> Iterator for MultiBufferBytes<'a> {
2671    type Item = &'a [u8];
2672
2673    fn next(&mut self) -> Option<Self::Item> {
2674        let chunk = self.chunk;
2675        if chunk.is_empty() {
2676            None
2677        } else {
2678            self.consume(chunk.len());
2679            Some(chunk)
2680        }
2681    }
2682}
2683
2684impl<'a> io::Read for MultiBufferBytes<'a> {
2685    fn read(&mut self, buf: &mut [u8]) -> io::Result<usize> {
2686        let len = cmp::min(buf.len(), self.chunk.len());
2687        buf[..len].copy_from_slice(&self.chunk[..len]);
2688        if len > 0 {
2689            self.consume(len);
2690        }
2691        Ok(len)
2692    }
2693}
2694
2695impl<'a> Iterator for ExcerptBytes<'a> {
2696    type Item = &'a [u8];
2697
2698    fn next(&mut self) -> Option<Self::Item> {
2699        if let Some(chunk) = self.content_bytes.next() {
2700            if !chunk.is_empty() {
2701                return Some(chunk);
2702            }
2703        }
2704
2705        if self.footer_height > 0 {
2706            let result = &NEWLINES[..self.footer_height];
2707            self.footer_height = 0;
2708            return Some(result);
2709        }
2710
2711        None
2712    }
2713}
2714
2715impl<'a> Iterator for ExcerptChunks<'a> {
2716    type Item = Chunk<'a>;
2717
2718    fn next(&mut self) -> Option<Self::Item> {
2719        if let Some(chunk) = self.content_chunks.next() {
2720            return Some(chunk);
2721        }
2722
2723        if self.footer_height > 0 {
2724            let text = unsafe { str::from_utf8_unchecked(&NEWLINES[..self.footer_height]) };
2725            self.footer_height = 0;
2726            return Some(Chunk {
2727                text,
2728                ..Default::default()
2729            });
2730        }
2731
2732        None
2733    }
2734}
2735
2736impl ToOffset for Point {
2737    fn to_offset<'a>(&self, snapshot: &MultiBufferSnapshot) -> usize {
2738        snapshot.point_to_offset(*self)
2739    }
2740}
2741
2742impl ToOffset for PointUtf16 {
2743    fn to_offset<'a>(&self, snapshot: &MultiBufferSnapshot) -> usize {
2744        snapshot.point_utf16_to_offset(*self)
2745    }
2746}
2747
2748impl ToOffset for usize {
2749    fn to_offset<'a>(&self, snapshot: &MultiBufferSnapshot) -> usize {
2750        assert!(*self <= snapshot.len(), "offset is out of range");
2751        *self
2752    }
2753}
2754
2755impl ToPoint for usize {
2756    fn to_point<'a>(&self, snapshot: &MultiBufferSnapshot) -> Point {
2757        snapshot.offset_to_point(*self)
2758    }
2759}
2760
2761impl ToPoint for Point {
2762    fn to_point<'a>(&self, _: &MultiBufferSnapshot) -> Point {
2763        *self
2764    }
2765}
2766
2767impl ToPointUtf16 for usize {
2768    fn to_point_utf16<'a>(&self, snapshot: &MultiBufferSnapshot) -> PointUtf16 {
2769        snapshot.offset_to_point_utf16(*self)
2770    }
2771}
2772
2773impl ToPointUtf16 for Point {
2774    fn to_point_utf16<'a>(&self, snapshot: &MultiBufferSnapshot) -> PointUtf16 {
2775        snapshot.point_to_point_utf16(*self)
2776    }
2777}
2778
2779impl ToPointUtf16 for PointUtf16 {
2780    fn to_point_utf16<'a>(&self, _: &MultiBufferSnapshot) -> PointUtf16 {
2781        *self
2782    }
2783}
2784
2785#[cfg(test)]
2786mod tests {
2787    use super::*;
2788    use gpui::MutableAppContext;
2789    use language::{Buffer, Rope};
2790    use rand::prelude::*;
2791    use std::env;
2792    use text::{Point, RandomCharIter};
2793    use util::test::sample_text;
2794
2795    #[gpui::test]
2796    fn test_singleton_multibuffer(cx: &mut MutableAppContext) {
2797        let buffer = cx.add_model(|cx| Buffer::new(0, sample_text(6, 6, 'a'), cx));
2798        let multibuffer = cx.add_model(|cx| MultiBuffer::singleton(buffer.clone(), cx));
2799
2800        let snapshot = multibuffer.read(cx).snapshot(cx);
2801        assert_eq!(snapshot.text(), buffer.read(cx).text());
2802
2803        assert_eq!(
2804            snapshot.buffer_rows(0).collect::<Vec<_>>(),
2805            (0..buffer.read(cx).row_count())
2806                .map(Some)
2807                .collect::<Vec<_>>()
2808        );
2809
2810        buffer.update(cx, |buffer, cx| buffer.edit([1..3], "XXX\n", cx));
2811        let snapshot = multibuffer.read(cx).snapshot(cx);
2812
2813        assert_eq!(snapshot.text(), buffer.read(cx).text());
2814        assert_eq!(
2815            snapshot.buffer_rows(0).collect::<Vec<_>>(),
2816            (0..buffer.read(cx).row_count())
2817                .map(Some)
2818                .collect::<Vec<_>>()
2819        );
2820    }
2821
2822    #[gpui::test]
2823    fn test_remote_multibuffer(cx: &mut MutableAppContext) {
2824        let host_buffer = cx.add_model(|cx| Buffer::new(0, "a", cx));
2825        let guest_buffer = cx.add_model(|cx| {
2826            let message = host_buffer.read(cx).to_proto();
2827            Buffer::from_proto(1, message, None, cx).unwrap()
2828        });
2829        let multibuffer = cx.add_model(|cx| MultiBuffer::singleton(guest_buffer.clone(), cx));
2830        let snapshot = multibuffer.read(cx).snapshot(cx);
2831        assert_eq!(snapshot.text(), "a");
2832
2833        guest_buffer.update(cx, |buffer, cx| buffer.edit([1..1], "b", cx));
2834        let snapshot = multibuffer.read(cx).snapshot(cx);
2835        assert_eq!(snapshot.text(), "ab");
2836
2837        guest_buffer.update(cx, |buffer, cx| buffer.edit([2..2], "c", cx));
2838        let snapshot = multibuffer.read(cx).snapshot(cx);
2839        assert_eq!(snapshot.text(), "abc");
2840    }
2841
2842    #[gpui::test]
2843    fn test_excerpt_buffer(cx: &mut MutableAppContext) {
2844        let buffer_1 = cx.add_model(|cx| Buffer::new(0, sample_text(6, 6, 'a'), cx));
2845        let buffer_2 = cx.add_model(|cx| Buffer::new(0, sample_text(6, 6, 'g'), cx));
2846        let multibuffer = cx.add_model(|_| MultiBuffer::new(0));
2847
2848        let subscription = multibuffer.update(cx, |multibuffer, cx| {
2849            let subscription = multibuffer.subscribe();
2850            multibuffer.push_excerpts(buffer_1.clone(), [Point::new(1, 2)..Point::new(2, 5)], cx);
2851            assert_eq!(
2852                subscription.consume().into_inner(),
2853                [Edit {
2854                    old: 0..0,
2855                    new: 0..10
2856                }]
2857            );
2858
2859            multibuffer.push_excerpts(buffer_1.clone(), [Point::new(3, 3)..Point::new(4, 4)], cx);
2860            multibuffer.push_excerpts(buffer_2.clone(), [Point::new(3, 1)..Point::new(3, 3)], cx);
2861            assert_eq!(
2862                subscription.consume().into_inner(),
2863                [Edit {
2864                    old: 10..10,
2865                    new: 10..22
2866                }]
2867            );
2868
2869            subscription
2870        });
2871
2872        let snapshot = multibuffer.read(cx).snapshot(cx);
2873        assert_eq!(
2874            snapshot.text(),
2875            concat!(
2876                "bbbb\n",  // Preserve newlines
2877                "ccccc\n", //
2878                "ddd\n",   //
2879                "eeee\n",  //
2880                "jj"       //
2881            )
2882        );
2883        assert_eq!(
2884            snapshot.buffer_rows(0).collect::<Vec<_>>(),
2885            [Some(1), Some(2), Some(3), Some(4), Some(3)]
2886        );
2887        assert_eq!(
2888            snapshot.buffer_rows(2).collect::<Vec<_>>(),
2889            [Some(3), Some(4), Some(3)]
2890        );
2891        assert_eq!(snapshot.buffer_rows(4).collect::<Vec<_>>(), [Some(3)]);
2892        assert_eq!(snapshot.buffer_rows(5).collect::<Vec<_>>(), []);
2893
2894        assert_eq!(
2895            boundaries_in_range(Point::new(0, 0)..Point::new(4, 2), &snapshot),
2896            &[
2897                (0, "bbbb\nccccc".to_string(), true),
2898                (2, "ddd\neeee".to_string(), false),
2899                (4, "jj".to_string(), true),
2900            ]
2901        );
2902        assert_eq!(
2903            boundaries_in_range(Point::new(0, 0)..Point::new(2, 0), &snapshot),
2904            &[(0, "bbbb\nccccc".to_string(), true)]
2905        );
2906        assert_eq!(
2907            boundaries_in_range(Point::new(1, 0)..Point::new(1, 5), &snapshot),
2908            &[]
2909        );
2910        assert_eq!(
2911            boundaries_in_range(Point::new(1, 0)..Point::new(2, 0), &snapshot),
2912            &[]
2913        );
2914        assert_eq!(
2915            boundaries_in_range(Point::new(1, 0)..Point::new(4, 0), &snapshot),
2916            &[(2, "ddd\neeee".to_string(), false)]
2917        );
2918        assert_eq!(
2919            boundaries_in_range(Point::new(1, 0)..Point::new(4, 0), &snapshot),
2920            &[(2, "ddd\neeee".to_string(), false)]
2921        );
2922        assert_eq!(
2923            boundaries_in_range(Point::new(2, 0)..Point::new(3, 0), &snapshot),
2924            &[(2, "ddd\neeee".to_string(), false)]
2925        );
2926        assert_eq!(
2927            boundaries_in_range(Point::new(4, 0)..Point::new(4, 2), &snapshot),
2928            &[(4, "jj".to_string(), true)]
2929        );
2930        assert_eq!(
2931            boundaries_in_range(Point::new(4, 2)..Point::new(4, 2), &snapshot),
2932            &[]
2933        );
2934
2935        buffer_1.update(cx, |buffer, cx| {
2936            buffer.edit(
2937                [
2938                    Point::new(0, 0)..Point::new(0, 0),
2939                    Point::new(2, 1)..Point::new(2, 3),
2940                ],
2941                "\n",
2942                cx,
2943            );
2944        });
2945
2946        let snapshot = multibuffer.read(cx).snapshot(cx);
2947        assert_eq!(
2948            snapshot.text(),
2949            concat!(
2950                "bbbb\n", // Preserve newlines
2951                "c\n",    //
2952                "cc\n",   //
2953                "ddd\n",  //
2954                "eeee\n", //
2955                "jj"      //
2956            )
2957        );
2958
2959        assert_eq!(
2960            subscription.consume().into_inner(),
2961            [Edit {
2962                old: 6..8,
2963                new: 6..7
2964            }]
2965        );
2966
2967        let snapshot = multibuffer.read(cx).snapshot(cx);
2968        assert_eq!(
2969            snapshot.clip_point(Point::new(0, 5), Bias::Left),
2970            Point::new(0, 4)
2971        );
2972        assert_eq!(
2973            snapshot.clip_point(Point::new(0, 5), Bias::Right),
2974            Point::new(0, 4)
2975        );
2976        assert_eq!(
2977            snapshot.clip_point(Point::new(5, 1), Bias::Right),
2978            Point::new(5, 1)
2979        );
2980        assert_eq!(
2981            snapshot.clip_point(Point::new(5, 2), Bias::Right),
2982            Point::new(5, 2)
2983        );
2984        assert_eq!(
2985            snapshot.clip_point(Point::new(5, 3), Bias::Right),
2986            Point::new(5, 2)
2987        );
2988
2989        let snapshot = multibuffer.update(cx, |multibuffer, cx| {
2990            let buffer_2_excerpt_id = multibuffer.excerpt_ids_for_buffer(&buffer_2)[0].clone();
2991            multibuffer.remove_excerpts(&[buffer_2_excerpt_id], cx);
2992            multibuffer.snapshot(cx)
2993        });
2994
2995        assert_eq!(
2996            snapshot.text(),
2997            concat!(
2998                "bbbb\n", // Preserve newlines
2999                "c\n",    //
3000                "cc\n",   //
3001                "ddd\n",  //
3002                "eeee",   //
3003            )
3004        );
3005
3006        fn boundaries_in_range(
3007            range: Range<Point>,
3008            snapshot: &MultiBufferSnapshot,
3009        ) -> Vec<(u32, String, bool)> {
3010            snapshot
3011                .excerpt_boundaries_in_range(range)
3012                .map(|boundary| {
3013                    (
3014                        boundary.row,
3015                        boundary
3016                            .buffer
3017                            .text_for_range(boundary.range)
3018                            .collect::<String>(),
3019                        boundary.starts_new_buffer,
3020                    )
3021                })
3022                .collect::<Vec<_>>()
3023        }
3024    }
3025
3026    #[gpui::test]
3027    fn test_excerpts_with_context_lines(cx: &mut MutableAppContext) {
3028        let buffer = cx.add_model(|cx| Buffer::new(0, sample_text(20, 3, 'a'), cx));
3029        let multibuffer = cx.add_model(|_| MultiBuffer::new(0));
3030        let anchor_ranges = multibuffer.update(cx, |multibuffer, cx| {
3031            multibuffer.push_excerpts_with_context_lines(
3032                buffer.clone(),
3033                vec![
3034                    Point::new(3, 2)..Point::new(4, 2),
3035                    Point::new(7, 1)..Point::new(7, 3),
3036                    Point::new(15, 0)..Point::new(15, 0),
3037                ],
3038                2,
3039                cx,
3040            )
3041        });
3042
3043        let snapshot = multibuffer.read(cx).snapshot(cx);
3044        assert_eq!(
3045            snapshot.text(),
3046            "bbb\nccc\nddd\neee\nfff\nggg\nhhh\niii\njjj\n\nnnn\nooo\nppp\nqqq\nrrr\n"
3047        );
3048
3049        assert_eq!(
3050            anchor_ranges
3051                .iter()
3052                .map(|range| range.to_point(&snapshot))
3053                .collect::<Vec<_>>(),
3054            vec![
3055                Point::new(2, 2)..Point::new(3, 2),
3056                Point::new(6, 1)..Point::new(6, 3),
3057                Point::new(12, 0)..Point::new(12, 0)
3058            ]
3059        );
3060    }
3061
3062    #[gpui::test]
3063    fn test_empty_excerpt_buffer(cx: &mut MutableAppContext) {
3064        let multibuffer = cx.add_model(|_| MultiBuffer::new(0));
3065
3066        let snapshot = multibuffer.read(cx).snapshot(cx);
3067        assert_eq!(snapshot.text(), "");
3068        assert_eq!(snapshot.buffer_rows(0).collect::<Vec<_>>(), &[Some(0)]);
3069        assert_eq!(snapshot.buffer_rows(1).collect::<Vec<_>>(), &[]);
3070    }
3071
3072    #[gpui::test]
3073    fn test_singleton_multibuffer_anchors(cx: &mut MutableAppContext) {
3074        let buffer = cx.add_model(|cx| Buffer::new(0, "abcd", cx));
3075        let multibuffer = cx.add_model(|cx| MultiBuffer::singleton(buffer.clone(), cx));
3076        let old_snapshot = multibuffer.read(cx).snapshot(cx);
3077        buffer.update(cx, |buffer, cx| {
3078            buffer.edit([0..0], "X", cx);
3079            buffer.edit([5..5], "Y", cx);
3080        });
3081        let new_snapshot = multibuffer.read(cx).snapshot(cx);
3082
3083        assert_eq!(old_snapshot.text(), "abcd");
3084        assert_eq!(new_snapshot.text(), "XabcdY");
3085
3086        assert_eq!(old_snapshot.anchor_before(0).to_offset(&new_snapshot), 0);
3087        assert_eq!(old_snapshot.anchor_after(0).to_offset(&new_snapshot), 1);
3088        assert_eq!(old_snapshot.anchor_before(4).to_offset(&new_snapshot), 5);
3089        assert_eq!(old_snapshot.anchor_after(4).to_offset(&new_snapshot), 6);
3090    }
3091
3092    #[gpui::test]
3093    fn test_multibuffer_anchors(cx: &mut MutableAppContext) {
3094        let buffer_1 = cx.add_model(|cx| Buffer::new(0, "abcd", cx));
3095        let buffer_2 = cx.add_model(|cx| Buffer::new(0, "efghi", cx));
3096        let multibuffer = cx.add_model(|cx| {
3097            let mut multibuffer = MultiBuffer::new(0);
3098            multibuffer.push_excerpts(buffer_1.clone(), [0..4], cx);
3099            multibuffer.push_excerpts(buffer_2.clone(), [0..5], cx);
3100            multibuffer
3101        });
3102        let old_snapshot = multibuffer.read(cx).snapshot(cx);
3103
3104        assert_eq!(old_snapshot.anchor_before(0).to_offset(&old_snapshot), 0);
3105        assert_eq!(old_snapshot.anchor_after(0).to_offset(&old_snapshot), 0);
3106        assert_eq!(Anchor::min().to_offset(&old_snapshot), 0);
3107        assert_eq!(Anchor::min().to_offset(&old_snapshot), 0);
3108        assert_eq!(Anchor::max().to_offset(&old_snapshot), 10);
3109        assert_eq!(Anchor::max().to_offset(&old_snapshot), 10);
3110
3111        buffer_1.update(cx, |buffer, cx| {
3112            buffer.edit([0..0], "W", cx);
3113            buffer.edit([5..5], "X", cx);
3114        });
3115        buffer_2.update(cx, |buffer, cx| {
3116            buffer.edit([0..0], "Y", cx);
3117            buffer.edit([6..0], "Z", cx);
3118        });
3119        let new_snapshot = multibuffer.read(cx).snapshot(cx);
3120
3121        assert_eq!(old_snapshot.text(), "abcd\nefghi");
3122        assert_eq!(new_snapshot.text(), "WabcdX\nYefghiZ");
3123
3124        assert_eq!(old_snapshot.anchor_before(0).to_offset(&new_snapshot), 0);
3125        assert_eq!(old_snapshot.anchor_after(0).to_offset(&new_snapshot), 1);
3126        assert_eq!(old_snapshot.anchor_before(1).to_offset(&new_snapshot), 2);
3127        assert_eq!(old_snapshot.anchor_after(1).to_offset(&new_snapshot), 2);
3128        assert_eq!(old_snapshot.anchor_before(2).to_offset(&new_snapshot), 3);
3129        assert_eq!(old_snapshot.anchor_after(2).to_offset(&new_snapshot), 3);
3130        assert_eq!(old_snapshot.anchor_before(5).to_offset(&new_snapshot), 7);
3131        assert_eq!(old_snapshot.anchor_after(5).to_offset(&new_snapshot), 8);
3132        assert_eq!(old_snapshot.anchor_before(10).to_offset(&new_snapshot), 13);
3133        assert_eq!(old_snapshot.anchor_after(10).to_offset(&new_snapshot), 14);
3134    }
3135
3136    #[gpui::test]
3137    fn test_multibuffer_resolving_anchors_after_replacing_their_excerpts(
3138        cx: &mut MutableAppContext,
3139    ) {
3140        let buffer_1 = cx.add_model(|cx| Buffer::new(0, "abcd", cx));
3141        let buffer_2 = cx.add_model(|cx| Buffer::new(0, "ABCDEFGHIJKLMNOP", cx));
3142        let multibuffer = cx.add_model(|_| MultiBuffer::new(0));
3143
3144        // Create an insertion id in buffer 1 that doesn't exist in buffer 2.
3145        // Add an excerpt from buffer 1 that spans this new insertion.
3146        buffer_1.update(cx, |buffer, cx| buffer.edit([4..4], "123", cx));
3147        let excerpt_id_1 = multibuffer.update(cx, |multibuffer, cx| {
3148            multibuffer
3149                .push_excerpts(buffer_1.clone(), [0..7], cx)
3150                .pop()
3151                .unwrap()
3152        });
3153
3154        let snapshot_1 = multibuffer.read(cx).snapshot(cx);
3155        assert_eq!(snapshot_1.text(), "abcd123");
3156
3157        // Replace the buffer 1 excerpt with new excerpts from buffer 2.
3158        let (excerpt_id_2, excerpt_id_3) = multibuffer.update(cx, |multibuffer, cx| {
3159            multibuffer.remove_excerpts([&excerpt_id_1], cx);
3160            let mut ids = multibuffer
3161                .push_excerpts(buffer_2.clone(), [0..4, 6..10, 12..16], cx)
3162                .into_iter();
3163            (ids.next().unwrap(), ids.next().unwrap())
3164        });
3165        let snapshot_2 = multibuffer.read(cx).snapshot(cx);
3166        assert_eq!(snapshot_2.text(), "ABCD\nGHIJ\nMNOP");
3167
3168        // The old excerpt id has been reused.
3169        assert_eq!(excerpt_id_2, excerpt_id_1);
3170
3171        // Resolve some anchors from the previous snapshot in the new snapshot.
3172        // Although there is still an excerpt with the same id, it is for
3173        // a different buffer, so we don't attempt to resolve the old text
3174        // anchor in the new buffer.
3175        assert_eq!(
3176            snapshot_2.summary_for_anchor::<usize>(&snapshot_1.anchor_before(2)),
3177            0
3178        );
3179        assert_eq!(
3180            snapshot_2.summaries_for_anchors::<usize, _>(&[
3181                snapshot_1.anchor_before(2),
3182                snapshot_1.anchor_after(3)
3183            ]),
3184            vec![0, 0]
3185        );
3186        let refresh =
3187            snapshot_2.refresh_anchors(&[snapshot_1.anchor_before(2), snapshot_1.anchor_after(3)]);
3188        assert_eq!(
3189            refresh,
3190            &[
3191                (0, snapshot_2.anchor_before(0), false),
3192                (1, snapshot_2.anchor_after(0), false),
3193            ]
3194        );
3195
3196        // Replace the middle excerpt with a smaller excerpt in buffer 2,
3197        // that intersects the old excerpt.
3198        let excerpt_id_5 = multibuffer.update(cx, |multibuffer, cx| {
3199            multibuffer.remove_excerpts([&excerpt_id_3], cx);
3200            multibuffer
3201                .insert_excerpts_after(&excerpt_id_3, buffer_2.clone(), [5..8], cx)
3202                .pop()
3203                .unwrap()
3204        });
3205
3206        let snapshot_3 = multibuffer.read(cx).snapshot(cx);
3207        assert_eq!(snapshot_3.text(), "ABCD\nFGH\nMNOP");
3208        assert_ne!(excerpt_id_5, excerpt_id_3);
3209
3210        // Resolve some anchors from the previous snapshot in the new snapshot.
3211        // The anchor in the middle excerpt snaps to the beginning of the
3212        // excerpt, since it is not
3213        let anchors = [
3214            snapshot_2.anchor_before(0),
3215            snapshot_2.anchor_after(2),
3216            snapshot_2.anchor_after(6),
3217            snapshot_2.anchor_after(14),
3218        ];
3219        assert_eq!(
3220            snapshot_3.summaries_for_anchors::<usize, _>(&anchors),
3221            &[0, 2, 9, 13]
3222        );
3223
3224        let new_anchors = snapshot_3.refresh_anchors(&anchors);
3225        assert_eq!(
3226            new_anchors.iter().map(|a| (a.0, a.2)).collect::<Vec<_>>(),
3227            &[(0, true), (1, true), (2, true), (3, true)]
3228        );
3229        assert_eq!(
3230            snapshot_3.summaries_for_anchors::<usize, _>(new_anchors.iter().map(|a| &a.1)),
3231            &[0, 2, 7, 13]
3232        );
3233    }
3234
3235    #[gpui::test(iterations = 100)]
3236    fn test_random_multibuffer(cx: &mut MutableAppContext, mut rng: StdRng) {
3237        let operations = env::var("OPERATIONS")
3238            .map(|i| i.parse().expect("invalid `OPERATIONS` variable"))
3239            .unwrap_or(10);
3240
3241        let mut buffers: Vec<ModelHandle<Buffer>> = Vec::new();
3242        let multibuffer = cx.add_model(|_| MultiBuffer::new(0));
3243        let mut excerpt_ids = Vec::new();
3244        let mut expected_excerpts = Vec::<(ModelHandle<Buffer>, Range<text::Anchor>)>::new();
3245        let mut anchors = Vec::new();
3246        let mut old_versions = Vec::new();
3247
3248        for _ in 0..operations {
3249            match rng.gen_range(0..100) {
3250                0..=19 if !buffers.is_empty() => {
3251                    let buffer = buffers.choose(&mut rng).unwrap();
3252                    buffer.update(cx, |buf, cx| buf.randomly_edit(&mut rng, 5, cx));
3253                }
3254                20..=29 if !expected_excerpts.is_empty() => {
3255                    let mut ids_to_remove = vec![];
3256                    for _ in 0..rng.gen_range(1..=3) {
3257                        if expected_excerpts.is_empty() {
3258                            break;
3259                        }
3260
3261                        let ix = rng.gen_range(0..expected_excerpts.len());
3262                        ids_to_remove.push(excerpt_ids.remove(ix));
3263                        let (buffer, range) = expected_excerpts.remove(ix);
3264                        let buffer = buffer.read(cx);
3265                        log::info!(
3266                            "Removing excerpt {}: {:?}",
3267                            ix,
3268                            buffer
3269                                .text_for_range(range.to_offset(&buffer))
3270                                .collect::<String>(),
3271                        );
3272                    }
3273                    ids_to_remove.sort_unstable();
3274                    multibuffer.update(cx, |multibuffer, cx| {
3275                        multibuffer.remove_excerpts(&ids_to_remove, cx)
3276                    });
3277                }
3278                30..=39 if !expected_excerpts.is_empty() => {
3279                    let multibuffer = multibuffer.read(cx).read(cx);
3280                    let offset =
3281                        multibuffer.clip_offset(rng.gen_range(0..=multibuffer.len()), Bias::Left);
3282                    let bias = if rng.gen() { Bias::Left } else { Bias::Right };
3283                    log::info!("Creating anchor at {} with bias {:?}", offset, bias);
3284                    anchors.push(multibuffer.anchor_at(offset, bias));
3285                    anchors.sort_by(|a, b| a.cmp(&b, &multibuffer).unwrap());
3286                }
3287                40..=44 if !anchors.is_empty() => {
3288                    let multibuffer = multibuffer.read(cx).read(cx);
3289
3290                    anchors = multibuffer
3291                        .refresh_anchors(&anchors)
3292                        .into_iter()
3293                        .map(|a| a.1)
3294                        .collect();
3295
3296                    // Ensure the newly-refreshed anchors point to a valid excerpt and don't
3297                    // overshoot its boundaries.
3298                    let mut cursor = multibuffer.excerpts.cursor::<Option<&ExcerptId>>();
3299                    for anchor in &anchors {
3300                        if anchor.excerpt_id == ExcerptId::min()
3301                            || anchor.excerpt_id == ExcerptId::max()
3302                        {
3303                            continue;
3304                        }
3305
3306                        cursor.seek_forward(&Some(&anchor.excerpt_id), Bias::Left, &());
3307                        let excerpt = cursor.item().unwrap();
3308                        assert_eq!(excerpt.id, anchor.excerpt_id);
3309                        assert!(excerpt.contains(anchor));
3310                    }
3311                }
3312                _ => {
3313                    let buffer_handle = if buffers.is_empty() || rng.gen_bool(0.4) {
3314                        let base_text = RandomCharIter::new(&mut rng).take(10).collect::<String>();
3315                        buffers.push(cx.add_model(|cx| Buffer::new(0, base_text, cx)));
3316                        buffers.last().unwrap()
3317                    } else {
3318                        buffers.choose(&mut rng).unwrap()
3319                    };
3320
3321                    let buffer = buffer_handle.read(cx);
3322                    let end_ix = buffer.clip_offset(rng.gen_range(0..=buffer.len()), Bias::Right);
3323                    let start_ix = buffer.clip_offset(rng.gen_range(0..=end_ix), Bias::Left);
3324                    let anchor_range = buffer.anchor_before(start_ix)..buffer.anchor_after(end_ix);
3325                    let prev_excerpt_ix = rng.gen_range(0..=expected_excerpts.len());
3326                    let prev_excerpt_id = excerpt_ids
3327                        .get(prev_excerpt_ix)
3328                        .cloned()
3329                        .unwrap_or(ExcerptId::max());
3330                    let excerpt_ix = (prev_excerpt_ix + 1).min(expected_excerpts.len());
3331
3332                    log::info!(
3333                        "Inserting excerpt at {} of {} for buffer {}: {:?}[{:?}] = {:?}",
3334                        excerpt_ix,
3335                        expected_excerpts.len(),
3336                        buffer_handle.id(),
3337                        buffer.text(),
3338                        start_ix..end_ix,
3339                        &buffer.text()[start_ix..end_ix]
3340                    );
3341
3342                    let excerpt_id = multibuffer.update(cx, |multibuffer, cx| {
3343                        multibuffer
3344                            .insert_excerpts_after(
3345                                &prev_excerpt_id,
3346                                buffer_handle.clone(),
3347                                [start_ix..end_ix],
3348                                cx,
3349                            )
3350                            .pop()
3351                            .unwrap()
3352                    });
3353
3354                    excerpt_ids.insert(excerpt_ix, excerpt_id);
3355                    expected_excerpts.insert(excerpt_ix, (buffer_handle.clone(), anchor_range));
3356                }
3357            }
3358
3359            if rng.gen_bool(0.3) {
3360                multibuffer.update(cx, |multibuffer, cx| {
3361                    old_versions.push((multibuffer.snapshot(cx), multibuffer.subscribe()));
3362                })
3363            }
3364
3365            let snapshot = multibuffer.read(cx).snapshot(cx);
3366
3367            let mut excerpt_starts = Vec::new();
3368            let mut expected_text = String::new();
3369            let mut expected_buffer_rows = Vec::new();
3370            for (buffer, range) in &expected_excerpts {
3371                let buffer = buffer.read(cx);
3372                let buffer_range = range.to_offset(buffer);
3373
3374                excerpt_starts.push(TextSummary::from(expected_text.as_str()));
3375                expected_text.extend(buffer.text_for_range(buffer_range.clone()));
3376                expected_text.push('\n');
3377
3378                let buffer_row_range = buffer.offset_to_point(buffer_range.start).row
3379                    ..=buffer.offset_to_point(buffer_range.end).row;
3380                for row in buffer_row_range {
3381                    expected_buffer_rows.push(Some(row));
3382                }
3383            }
3384            // Remove final trailing newline.
3385            if !expected_excerpts.is_empty() {
3386                expected_text.pop();
3387            }
3388
3389            // Always report one buffer row
3390            if expected_buffer_rows.is_empty() {
3391                expected_buffer_rows.push(Some(0));
3392            }
3393
3394            assert_eq!(snapshot.text(), expected_text);
3395            log::info!("MultiBuffer text: {:?}", expected_text);
3396
3397            assert_eq!(
3398                snapshot.buffer_rows(0).collect::<Vec<_>>(),
3399                expected_buffer_rows,
3400            );
3401
3402            for _ in 0..5 {
3403                let start_row = rng.gen_range(0..=expected_buffer_rows.len());
3404                assert_eq!(
3405                    snapshot.buffer_rows(start_row as u32).collect::<Vec<_>>(),
3406                    &expected_buffer_rows[start_row..],
3407                    "buffer_rows({})",
3408                    start_row
3409                );
3410            }
3411
3412            assert_eq!(
3413                snapshot.max_buffer_row(),
3414                expected_buffer_rows
3415                    .into_iter()
3416                    .filter_map(|r| r)
3417                    .max()
3418                    .unwrap()
3419            );
3420
3421            let mut excerpt_starts = excerpt_starts.into_iter();
3422            for (buffer, range) in &expected_excerpts {
3423                let buffer_id = buffer.id();
3424                let buffer = buffer.read(cx);
3425                let buffer_range = range.to_offset(buffer);
3426                let buffer_start_point = buffer.offset_to_point(buffer_range.start);
3427                let buffer_start_point_utf16 =
3428                    buffer.text_summary_for_range::<PointUtf16, _>(0..buffer_range.start);
3429
3430                let excerpt_start = excerpt_starts.next().unwrap();
3431                let mut offset = excerpt_start.bytes;
3432                let mut buffer_offset = buffer_range.start;
3433                let mut point = excerpt_start.lines;
3434                let mut buffer_point = buffer_start_point;
3435                let mut point_utf16 = excerpt_start.lines_utf16;
3436                let mut buffer_point_utf16 = buffer_start_point_utf16;
3437                for ch in buffer
3438                    .snapshot()
3439                    .chunks(buffer_range.clone(), false)
3440                    .flat_map(|c| c.text.chars())
3441                {
3442                    for _ in 0..ch.len_utf8() {
3443                        let left_offset = snapshot.clip_offset(offset, Bias::Left);
3444                        let right_offset = snapshot.clip_offset(offset, Bias::Right);
3445                        let buffer_left_offset = buffer.clip_offset(buffer_offset, Bias::Left);
3446                        let buffer_right_offset = buffer.clip_offset(buffer_offset, Bias::Right);
3447                        assert_eq!(
3448                            left_offset,
3449                            excerpt_start.bytes + (buffer_left_offset - buffer_range.start),
3450                            "clip_offset({:?}, Left). buffer: {:?}, buffer offset: {:?}",
3451                            offset,
3452                            buffer_id,
3453                            buffer_offset,
3454                        );
3455                        assert_eq!(
3456                            right_offset,
3457                            excerpt_start.bytes + (buffer_right_offset - buffer_range.start),
3458                            "clip_offset({:?}, Right). buffer: {:?}, buffer offset: {:?}",
3459                            offset,
3460                            buffer_id,
3461                            buffer_offset,
3462                        );
3463
3464                        let left_point = snapshot.clip_point(point, Bias::Left);
3465                        let right_point = snapshot.clip_point(point, Bias::Right);
3466                        let buffer_left_point = buffer.clip_point(buffer_point, Bias::Left);
3467                        let buffer_right_point = buffer.clip_point(buffer_point, Bias::Right);
3468                        assert_eq!(
3469                            left_point,
3470                            excerpt_start.lines + (buffer_left_point - buffer_start_point),
3471                            "clip_point({:?}, Left). buffer: {:?}, buffer point: {:?}",
3472                            point,
3473                            buffer_id,
3474                            buffer_point,
3475                        );
3476                        assert_eq!(
3477                            right_point,
3478                            excerpt_start.lines + (buffer_right_point - buffer_start_point),
3479                            "clip_point({:?}, Right). buffer: {:?}, buffer point: {:?}",
3480                            point,
3481                            buffer_id,
3482                            buffer_point,
3483                        );
3484
3485                        assert_eq!(
3486                            snapshot.point_to_offset(left_point),
3487                            left_offset,
3488                            "point_to_offset({:?})",
3489                            left_point,
3490                        );
3491                        assert_eq!(
3492                            snapshot.offset_to_point(left_offset),
3493                            left_point,
3494                            "offset_to_point({:?})",
3495                            left_offset,
3496                        );
3497
3498                        offset += 1;
3499                        buffer_offset += 1;
3500                        if ch == '\n' {
3501                            point += Point::new(1, 0);
3502                            buffer_point += Point::new(1, 0);
3503                        } else {
3504                            point += Point::new(0, 1);
3505                            buffer_point += Point::new(0, 1);
3506                        }
3507                    }
3508
3509                    for _ in 0..ch.len_utf16() {
3510                        let left_point_utf16 = snapshot.clip_point_utf16(point_utf16, Bias::Left);
3511                        let right_point_utf16 = snapshot.clip_point_utf16(point_utf16, Bias::Right);
3512                        let buffer_left_point_utf16 =
3513                            buffer.clip_point_utf16(buffer_point_utf16, Bias::Left);
3514                        let buffer_right_point_utf16 =
3515                            buffer.clip_point_utf16(buffer_point_utf16, Bias::Right);
3516                        assert_eq!(
3517                            left_point_utf16,
3518                            excerpt_start.lines_utf16
3519                                + (buffer_left_point_utf16 - buffer_start_point_utf16),
3520                            "clip_point_utf16({:?}, Left). buffer: {:?}, buffer point_utf16: {:?}",
3521                            point_utf16,
3522                            buffer_id,
3523                            buffer_point_utf16,
3524                        );
3525                        assert_eq!(
3526                            right_point_utf16,
3527                            excerpt_start.lines_utf16
3528                                + (buffer_right_point_utf16 - buffer_start_point_utf16),
3529                            "clip_point_utf16({:?}, Right). buffer: {:?}, buffer point_utf16: {:?}",
3530                            point_utf16,
3531                            buffer_id,
3532                            buffer_point_utf16,
3533                        );
3534
3535                        if ch == '\n' {
3536                            point_utf16 += PointUtf16::new(1, 0);
3537                            buffer_point_utf16 += PointUtf16::new(1, 0);
3538                        } else {
3539                            point_utf16 += PointUtf16::new(0, 1);
3540                            buffer_point_utf16 += PointUtf16::new(0, 1);
3541                        }
3542                    }
3543                }
3544            }
3545
3546            for (row, line) in expected_text.split('\n').enumerate() {
3547                assert_eq!(
3548                    snapshot.line_len(row as u32),
3549                    line.len() as u32,
3550                    "line_len({}).",
3551                    row
3552                );
3553            }
3554
3555            let text_rope = Rope::from(expected_text.as_str());
3556            for _ in 0..10 {
3557                let end_ix = text_rope.clip_offset(rng.gen_range(0..=text_rope.len()), Bias::Right);
3558                let start_ix = text_rope.clip_offset(rng.gen_range(0..=end_ix), Bias::Left);
3559
3560                let text_for_range = snapshot
3561                    .text_for_range(start_ix..end_ix)
3562                    .collect::<String>();
3563                assert_eq!(
3564                    text_for_range,
3565                    &expected_text[start_ix..end_ix],
3566                    "incorrect text for range {:?}",
3567                    start_ix..end_ix
3568                );
3569
3570                let excerpted_buffer_ranges = multibuffer
3571                    .read(cx)
3572                    .range_to_buffer_ranges(start_ix..end_ix, cx);
3573                let excerpted_buffers_text = excerpted_buffer_ranges
3574                    .into_iter()
3575                    .map(|(buffer, buffer_range)| {
3576                        buffer
3577                            .read(cx)
3578                            .text_for_range(buffer_range)
3579                            .collect::<String>()
3580                    })
3581                    .collect::<Vec<_>>()
3582                    .join("\n");
3583                assert_eq!(excerpted_buffers_text, text_for_range);
3584
3585                let expected_summary = TextSummary::from(&expected_text[start_ix..end_ix]);
3586                assert_eq!(
3587                    snapshot.text_summary_for_range::<TextSummary, _>(start_ix..end_ix),
3588                    expected_summary,
3589                    "incorrect summary for range {:?}",
3590                    start_ix..end_ix
3591                );
3592            }
3593
3594            // Anchor resolution
3595            for (anchor, resolved_offset) in anchors
3596                .iter()
3597                .zip(snapshot.summaries_for_anchors::<usize, _>(&anchors))
3598            {
3599                assert!(resolved_offset <= snapshot.len());
3600                assert_eq!(
3601                    snapshot.summary_for_anchor::<usize>(anchor),
3602                    resolved_offset
3603                );
3604            }
3605
3606            for _ in 0..10 {
3607                let end_ix = text_rope.clip_offset(rng.gen_range(0..=text_rope.len()), Bias::Right);
3608                assert_eq!(
3609                    snapshot.reversed_chars_at(end_ix).collect::<String>(),
3610                    expected_text[..end_ix].chars().rev().collect::<String>(),
3611                );
3612            }
3613
3614            for _ in 0..10 {
3615                let end_ix = rng.gen_range(0..=text_rope.len());
3616                let start_ix = rng.gen_range(0..=end_ix);
3617                assert_eq!(
3618                    snapshot
3619                        .bytes_in_range(start_ix..end_ix)
3620                        .flatten()
3621                        .copied()
3622                        .collect::<Vec<_>>(),
3623                    expected_text.as_bytes()[start_ix..end_ix].to_vec(),
3624                    "bytes_in_range({:?})",
3625                    start_ix..end_ix,
3626                );
3627            }
3628        }
3629
3630        let snapshot = multibuffer.read(cx).snapshot(cx);
3631        for (old_snapshot, subscription) in old_versions {
3632            let edits = subscription.consume().into_inner();
3633
3634            log::info!(
3635                "applying subscription edits to old text: {:?}: {:?}",
3636                old_snapshot.text(),
3637                edits,
3638            );
3639
3640            let mut text = old_snapshot.text();
3641            for edit in edits {
3642                let new_text: String = snapshot.text_for_range(edit.new.clone()).collect();
3643                text.replace_range(edit.new.start..edit.new.start + edit.old.len(), &new_text);
3644            }
3645            assert_eq!(text.to_string(), snapshot.text());
3646        }
3647    }
3648
3649    #[gpui::test]
3650    fn test_history(cx: &mut MutableAppContext) {
3651        let buffer_1 = cx.add_model(|cx| Buffer::new(0, "1234", cx));
3652        let buffer_2 = cx.add_model(|cx| Buffer::new(0, "5678", cx));
3653        let multibuffer = cx.add_model(|_| MultiBuffer::new(0));
3654        let group_interval = multibuffer.read(cx).history.group_interval;
3655        multibuffer.update(cx, |multibuffer, cx| {
3656            multibuffer.push_excerpts(buffer_1.clone(), [0..buffer_1.read(cx).len()], cx);
3657            multibuffer.push_excerpts(buffer_2.clone(), [0..buffer_2.read(cx).len()], cx);
3658        });
3659
3660        let mut now = Instant::now();
3661
3662        multibuffer.update(cx, |multibuffer, cx| {
3663            multibuffer.start_transaction_at(now, cx);
3664            multibuffer.edit(
3665                [
3666                    Point::new(0, 0)..Point::new(0, 0),
3667                    Point::new(1, 0)..Point::new(1, 0),
3668                ],
3669                "A",
3670                cx,
3671            );
3672            multibuffer.edit(
3673                [
3674                    Point::new(0, 1)..Point::new(0, 1),
3675                    Point::new(1, 1)..Point::new(1, 1),
3676                ],
3677                "B",
3678                cx,
3679            );
3680            multibuffer.end_transaction_at(now, cx);
3681            assert_eq!(multibuffer.read(cx).text(), "AB1234\nAB5678");
3682
3683            // Edit buffer 1 through the multibuffer
3684            now += 2 * group_interval;
3685            multibuffer.start_transaction_at(now, cx);
3686            multibuffer.edit([2..2], "C", cx);
3687            multibuffer.end_transaction_at(now, cx);
3688            assert_eq!(multibuffer.read(cx).text(), "ABC1234\nAB5678");
3689
3690            // Edit buffer 1 independently
3691            buffer_1.update(cx, |buffer_1, cx| {
3692                buffer_1.start_transaction_at(now);
3693                buffer_1.edit([3..3], "D", cx);
3694                buffer_1.end_transaction_at(now, cx);
3695
3696                now += 2 * group_interval;
3697                buffer_1.start_transaction_at(now);
3698                buffer_1.edit([4..4], "E", cx);
3699                buffer_1.end_transaction_at(now, cx);
3700            });
3701            assert_eq!(multibuffer.read(cx).text(), "ABCDE1234\nAB5678");
3702
3703            // An undo in the multibuffer undoes the multibuffer transaction
3704            // and also any individual buffer edits that have occured since
3705            // that transaction.
3706            multibuffer.undo(cx);
3707            assert_eq!(multibuffer.read(cx).text(), "AB1234\nAB5678");
3708
3709            multibuffer.undo(cx);
3710            assert_eq!(multibuffer.read(cx).text(), "1234\n5678");
3711
3712            multibuffer.redo(cx);
3713            assert_eq!(multibuffer.read(cx).text(), "AB1234\nAB5678");
3714
3715            multibuffer.redo(cx);
3716            assert_eq!(multibuffer.read(cx).text(), "ABCDE1234\nAB5678");
3717
3718            // Undo buffer 2 independently.
3719            buffer_2.update(cx, |buffer_2, cx| buffer_2.undo(cx));
3720            assert_eq!(multibuffer.read(cx).text(), "ABCDE1234\n5678");
3721
3722            // An undo in the multibuffer undoes the components of the
3723            // the last multibuffer transaction that are not already undone.
3724            multibuffer.undo(cx);
3725            assert_eq!(multibuffer.read(cx).text(), "AB1234\n5678");
3726
3727            multibuffer.undo(cx);
3728            assert_eq!(multibuffer.read(cx).text(), "1234\n5678");
3729
3730            multibuffer.redo(cx);
3731            assert_eq!(multibuffer.read(cx).text(), "AB1234\nAB5678");
3732
3733            buffer_1.update(cx, |buffer_1, cx| buffer_1.redo(cx));
3734            assert_eq!(multibuffer.read(cx).text(), "ABCD1234\nAB5678");
3735
3736            multibuffer.undo(cx);
3737            assert_eq!(multibuffer.read(cx).text(), "1234\n5678");
3738        });
3739    }
3740}