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