buffer.rs

   1pub mod row_chunk;
   2
   3use crate::{
   4    DebuggerTextObject, LanguageScope, ModelineSettings, Outline, OutlineConfig, PLAIN_TEXT,
   5    RunnableCapture, RunnableTag, TextObject, TreeSitterOptions,
   6    diagnostic_set::{DiagnosticEntry, DiagnosticEntryRef, DiagnosticGroup},
   7    language_settings::{AutoIndentMode, LanguageSettings},
   8    outline::OutlineItem,
   9    row_chunk::RowChunks,
  10    syntax_map::{
  11        MAX_BYTES_TO_QUERY, SyntaxLayer, SyntaxMap, SyntaxMapCapture, SyntaxMapCaptures,
  12        SyntaxMapMatch, SyntaxMapMatches, SyntaxSnapshot, ToTreeSitterPoint,
  13    },
  14    task_context::RunnableRange,
  15    text_diff::text_diff,
  16    unified_diff_with_offsets,
  17};
  18pub use crate::{
  19    Grammar, HighlightId, HighlightMap, Language, LanguageRegistry, diagnostic_set::DiagnosticSet,
  20    proto,
  21};
  22
  23use anyhow::{Context as _, Result};
  24use clock::Lamport;
  25pub use clock::ReplicaId;
  26use collections::{HashMap, HashSet};
  27use encoding_rs::Encoding;
  28use fs::MTime;
  29use futures::channel::oneshot;
  30use gpui::{
  31    App, AppContext as _, Context, Entity, EventEmitter, HighlightStyle, SharedString, StyledText,
  32    Task, TextStyle,
  33};
  34
  35use lsp::LanguageServerId;
  36use parking_lot::Mutex;
  37use settings::WorktreeId;
  38use smallvec::SmallVec;
  39use smol::future::yield_now;
  40use std::{
  41    any::Any,
  42    borrow::Cow,
  43    cell::Cell,
  44    cmp::{self, Ordering, Reverse},
  45    collections::{BTreeMap, BTreeSet},
  46    future::Future,
  47    iter::{self, Iterator, Peekable},
  48    mem,
  49    num::NonZeroU32,
  50    ops::{Deref, Range},
  51    path::PathBuf,
  52    rc,
  53    sync::Arc,
  54    time::{Duration, Instant},
  55    vec,
  56};
  57use sum_tree::TreeMap;
  58use text::operation_queue::OperationQueue;
  59use text::*;
  60pub use text::{
  61    Anchor, Bias, Buffer as TextBuffer, BufferId, BufferSnapshot as TextBufferSnapshot, Edit,
  62    LineIndent, OffsetRangeExt, OffsetUtf16, Patch, Point, PointUtf16, Rope, Selection,
  63    SelectionGoal, Subscription, TextDimension, TextSummary, ToOffset, ToOffsetUtf16, ToPoint,
  64    ToPointUtf16, Transaction, TransactionId, Unclipped,
  65};
  66use theme::{ActiveTheme as _, SyntaxTheme};
  67#[cfg(any(test, feature = "test-support"))]
  68use util::RandomCharIter;
  69use util::{RangeExt, debug_panic, maybe, paths::PathStyle, rel_path::RelPath};
  70
  71#[cfg(any(test, feature = "test-support"))]
  72pub use {tree_sitter_python, tree_sitter_rust, tree_sitter_typescript};
  73
  74pub use lsp::DiagnosticSeverity;
  75
  76/// Indicate whether a [`Buffer`] has permissions to edit.
  77#[derive(PartialEq, Clone, Copy, Debug)]
  78pub enum Capability {
  79    /// The buffer is a mutable replica.
  80    ReadWrite,
  81    /// The buffer is a mutable replica, but toggled to be only readable.
  82    Read,
  83    /// The buffer is a read-only replica.
  84    ReadOnly,
  85}
  86
  87impl Capability {
  88    /// Returns `true` if the capability is `ReadWrite`.
  89    pub fn editable(self) -> bool {
  90        matches!(self, Capability::ReadWrite)
  91    }
  92}
  93
  94pub type BufferRow = u32;
  95
  96/// An in-memory representation of a source code file, including its text,
  97/// syntax trees, git status, and diagnostics.
  98pub struct Buffer {
  99    text: TextBuffer,
 100    branch_state: Option<BufferBranchState>,
 101    /// Filesystem state, `None` when there is no path.
 102    file: Option<Arc<dyn File>>,
 103    /// The mtime of the file when this buffer was last loaded from
 104    /// or saved to disk.
 105    saved_mtime: Option<MTime>,
 106    /// The version vector when this buffer was last loaded from
 107    /// or saved to disk.
 108    saved_version: clock::Global,
 109    preview_version: clock::Global,
 110    transaction_depth: usize,
 111    was_dirty_before_starting_transaction: Option<bool>,
 112    reload_task: Option<Task<Result<()>>>,
 113    language: Option<Arc<Language>>,
 114    autoindent_requests: Vec<Arc<AutoindentRequest>>,
 115    wait_for_autoindent_txs: Vec<oneshot::Sender<()>>,
 116    pending_autoindent: Option<Task<()>>,
 117    sync_parse_timeout: Option<Duration>,
 118    syntax_map: Mutex<SyntaxMap>,
 119    reparse: Option<Task<()>>,
 120    parse_status: (watch::Sender<ParseStatus>, watch::Receiver<ParseStatus>),
 121    non_text_state_update_count: usize,
 122    diagnostics: TreeMap<LanguageServerId, DiagnosticSet>,
 123    remote_selections: TreeMap<ReplicaId, SelectionSet>,
 124    diagnostics_timestamp: clock::Lamport,
 125    completion_triggers: BTreeSet<String>,
 126    completion_triggers_per_language_server: HashMap<LanguageServerId, BTreeSet<String>>,
 127    completion_triggers_timestamp: clock::Lamport,
 128    deferred_ops: OperationQueue<Operation>,
 129    capability: Capability,
 130    has_conflict: bool,
 131    /// Memoize calls to has_changes_since(saved_version).
 132    /// The contents of a cell are (self.version, has_changes) at the time of a last call.
 133    has_unsaved_edits: Cell<(clock::Global, bool)>,
 134    change_bits: Vec<rc::Weak<Cell<bool>>>,
 135    modeline: Option<Arc<ModelineSettings>>,
 136    _subscriptions: Vec<gpui::Subscription>,
 137    tree_sitter_data: Arc<TreeSitterData>,
 138    encoding: &'static Encoding,
 139    has_bom: bool,
 140    reload_with_encoding_txns: HashMap<TransactionId, (&'static Encoding, bool)>,
 141}
 142
 143#[derive(Debug)]
 144pub struct TreeSitterData {
 145    chunks: RowChunks,
 146    brackets_by_chunks: Mutex<Vec<Option<Vec<BracketMatch<usize>>>>>,
 147}
 148
 149const MAX_ROWS_IN_A_CHUNK: u32 = 50;
 150
 151impl TreeSitterData {
 152    fn clear(&mut self, snapshot: &text::BufferSnapshot) {
 153        self.chunks = RowChunks::new(&snapshot, MAX_ROWS_IN_A_CHUNK);
 154        self.brackets_by_chunks.get_mut().clear();
 155        self.brackets_by_chunks
 156            .get_mut()
 157            .resize(self.chunks.len(), None);
 158    }
 159
 160    fn new(snapshot: &text::BufferSnapshot) -> Self {
 161        let chunks = RowChunks::new(&snapshot, MAX_ROWS_IN_A_CHUNK);
 162        Self {
 163            brackets_by_chunks: Mutex::new(vec![None; chunks.len()]),
 164            chunks,
 165        }
 166    }
 167
 168    fn version(&self) -> &clock::Global {
 169        self.chunks.version()
 170    }
 171}
 172
 173#[derive(Copy, Clone, Debug, PartialEq, Eq)]
 174pub enum ParseStatus {
 175    Idle,
 176    Parsing,
 177}
 178
 179struct BufferBranchState {
 180    base_buffer: Entity<Buffer>,
 181    merged_operations: Vec<Lamport>,
 182}
 183
 184/// An immutable, cheaply cloneable representation of a fixed
 185/// state of a buffer.
 186pub struct BufferSnapshot {
 187    pub text: text::BufferSnapshot,
 188    pub(crate) syntax: SyntaxSnapshot,
 189    tree_sitter_data: Arc<TreeSitterData>,
 190    diagnostics: TreeMap<LanguageServerId, DiagnosticSet>,
 191    remote_selections: TreeMap<ReplicaId, SelectionSet>,
 192    language: Option<Arc<Language>>,
 193    file: Option<Arc<dyn File>>,
 194    non_text_state_update_count: usize,
 195    pub capability: Capability,
 196    modeline: Option<Arc<ModelineSettings>>,
 197}
 198
 199/// The kind and amount of indentation in a particular line. For now,
 200/// assumes that indentation is all the same character.
 201#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash, Default)]
 202pub struct IndentSize {
 203    /// The number of bytes that comprise the indentation.
 204    pub len: u32,
 205    /// The kind of whitespace used for indentation.
 206    pub kind: IndentKind,
 207}
 208
 209/// A whitespace character that's used for indentation.
 210#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash, Default)]
 211pub enum IndentKind {
 212    /// An ASCII space character.
 213    #[default]
 214    Space,
 215    /// An ASCII tab character.
 216    Tab,
 217}
 218
 219/// The shape of a selection cursor.
 220#[derive(Copy, Clone, Debug, Default, PartialEq, Eq)]
 221pub enum CursorShape {
 222    /// A vertical bar
 223    #[default]
 224    Bar,
 225    /// A block that surrounds the following character
 226    Block,
 227    /// An underline that runs along the following character
 228    Underline,
 229    /// A box drawn around the following character
 230    Hollow,
 231}
 232
 233impl From<settings::CursorShape> for CursorShape {
 234    fn from(shape: settings::CursorShape) -> Self {
 235        match shape {
 236            settings::CursorShape::Bar => CursorShape::Bar,
 237            settings::CursorShape::Block => CursorShape::Block,
 238            settings::CursorShape::Underline => CursorShape::Underline,
 239            settings::CursorShape::Hollow => CursorShape::Hollow,
 240        }
 241    }
 242}
 243
 244#[derive(Clone, Debug)]
 245struct SelectionSet {
 246    line_mode: bool,
 247    cursor_shape: CursorShape,
 248    selections: Arc<[Selection<Anchor>]>,
 249    lamport_timestamp: clock::Lamport,
 250}
 251
 252/// An operation used to synchronize this buffer with its other replicas.
 253#[derive(Clone, Debug, PartialEq)]
 254pub enum Operation {
 255    /// A text operation.
 256    Buffer(text::Operation),
 257
 258    /// An update to the buffer's diagnostics.
 259    UpdateDiagnostics {
 260        /// The id of the language server that produced the new diagnostics.
 261        server_id: LanguageServerId,
 262        /// The diagnostics.
 263        diagnostics: Arc<[DiagnosticEntry<Anchor>]>,
 264        /// The buffer's lamport timestamp.
 265        lamport_timestamp: clock::Lamport,
 266    },
 267
 268    /// An update to the most recent selections in this buffer.
 269    UpdateSelections {
 270        /// The selections.
 271        selections: Arc<[Selection<Anchor>]>,
 272        /// The buffer's lamport timestamp.
 273        lamport_timestamp: clock::Lamport,
 274        /// Whether the selections are in 'line mode'.
 275        line_mode: bool,
 276        /// The [`CursorShape`] associated with these selections.
 277        cursor_shape: CursorShape,
 278    },
 279
 280    /// An update to the characters that should trigger autocompletion
 281    /// for this buffer.
 282    UpdateCompletionTriggers {
 283        /// The characters that trigger autocompletion.
 284        triggers: Vec<String>,
 285        /// The buffer's lamport timestamp.
 286        lamport_timestamp: clock::Lamport,
 287        /// The language server ID.
 288        server_id: LanguageServerId,
 289    },
 290
 291    /// An update to the line ending type of this buffer.
 292    UpdateLineEnding {
 293        /// The line ending type.
 294        line_ending: LineEnding,
 295        /// The buffer's lamport timestamp.
 296        lamport_timestamp: clock::Lamport,
 297    },
 298}
 299
 300/// An event that occurs in a buffer.
 301#[derive(Clone, Debug, PartialEq)]
 302pub enum BufferEvent {
 303    /// The buffer was changed in a way that must be
 304    /// propagated to its other replicas.
 305    Operation {
 306        operation: Operation,
 307        is_local: bool,
 308    },
 309    /// The buffer was edited.
 310    Edited { is_local: bool },
 311    /// The buffer's `dirty` bit changed.
 312    DirtyChanged,
 313    /// The buffer was saved.
 314    Saved,
 315    /// The buffer's file was changed on disk.
 316    FileHandleChanged,
 317    /// The buffer was reloaded.
 318    Reloaded,
 319    /// The buffer is in need of a reload
 320    ReloadNeeded,
 321    /// The buffer's language was changed.
 322    /// The boolean indicates whether this buffer did not have a language before, but does now.
 323    LanguageChanged(bool),
 324    /// The buffer's syntax trees were updated.
 325    Reparsed,
 326    /// The buffer's diagnostics were updated.
 327    DiagnosticsUpdated,
 328    /// The buffer gained or lost editing capabilities.
 329    CapabilityChanged,
 330}
 331
 332/// The file associated with a buffer.
 333pub trait File: Send + Sync + Any {
 334    /// Returns the [`LocalFile`] associated with this file, if the
 335    /// file is local.
 336    fn as_local(&self) -> Option<&dyn LocalFile>;
 337
 338    /// Returns whether this file is local.
 339    fn is_local(&self) -> bool {
 340        self.as_local().is_some()
 341    }
 342
 343    /// Returns whether the file is new, exists in storage, or has been deleted. Includes metadata
 344    /// only available in some states, such as modification time.
 345    fn disk_state(&self) -> DiskState;
 346
 347    /// Returns the path of this file relative to the worktree's root directory.
 348    fn path(&self) -> &Arc<RelPath>;
 349
 350    /// Returns the path of this file relative to the worktree's parent directory (this means it
 351    /// includes the name of the worktree's root folder).
 352    fn full_path(&self, cx: &App) -> PathBuf;
 353
 354    /// Returns the path style of this file.
 355    fn path_style(&self, cx: &App) -> PathStyle;
 356
 357    /// Returns the last component of this handle's absolute path. If this handle refers to the root
 358    /// of its worktree, then this method will return the name of the worktree itself.
 359    fn file_name<'a>(&'a self, cx: &'a App) -> &'a str;
 360
 361    /// Returns the id of the worktree to which this file belongs.
 362    ///
 363    /// This is needed for looking up project-specific settings.
 364    fn worktree_id(&self, cx: &App) -> WorktreeId;
 365
 366    /// Converts this file into a protobuf message.
 367    fn to_proto(&self, cx: &App) -> rpc::proto::File;
 368
 369    /// Return whether Zed considers this to be a private file.
 370    fn is_private(&self) -> bool;
 371
 372    fn can_open(&self) -> bool {
 373        !self.is_local()
 374    }
 375}
 376
 377/// The file's storage status - whether it's stored (`Present`), and if so when it was last
 378/// modified. In the case where the file is not stored, it can be either `New` or `Deleted`. In the
 379/// UI these two states are distinguished. For example, the buffer tab does not display a deletion
 380/// indicator for new files.
 381#[derive(Copy, Clone, Debug, PartialEq)]
 382pub enum DiskState {
 383    /// File created in Zed that has not been saved.
 384    New,
 385    /// File present on the filesystem.
 386    Present { mtime: MTime, size: u64 },
 387    /// Deleted file that was previously present.
 388    Deleted,
 389    /// An old version of a file that was previously present
 390    /// usually from a version control system. e.g. A git blob
 391    Historic { was_deleted: bool },
 392}
 393
 394impl DiskState {
 395    /// Returns the file's last known modification time on disk.
 396    pub fn mtime(self) -> Option<MTime> {
 397        match self {
 398            DiskState::New => None,
 399            DiskState::Present { mtime, .. } => Some(mtime),
 400            DiskState::Deleted => None,
 401            DiskState::Historic { .. } => None,
 402        }
 403    }
 404
 405    /// Returns the file's size on disk in bytes.
 406    pub fn size(self) -> Option<u64> {
 407        match self {
 408            DiskState::New => None,
 409            DiskState::Present { size, .. } => Some(size),
 410            DiskState::Deleted => None,
 411            DiskState::Historic { .. } => None,
 412        }
 413    }
 414
 415    pub fn exists(&self) -> bool {
 416        match self {
 417            DiskState::New => false,
 418            DiskState::Present { .. } => true,
 419            DiskState::Deleted => false,
 420            DiskState::Historic { .. } => false,
 421        }
 422    }
 423
 424    /// Returns true if this state represents a deleted file.
 425    pub fn is_deleted(&self) -> bool {
 426        match self {
 427            DiskState::Deleted => true,
 428            DiskState::Historic { was_deleted } => *was_deleted,
 429            _ => false,
 430        }
 431    }
 432}
 433
 434/// The file associated with a buffer, in the case where the file is on the local disk.
 435pub trait LocalFile: File {
 436    /// Returns the absolute path of this file
 437    fn abs_path(&self, cx: &App) -> PathBuf;
 438
 439    /// Loads the file contents from disk and returns them as a UTF-8 encoded string.
 440    fn load(&self, cx: &App) -> Task<Result<String>>;
 441
 442    /// Loads the file's contents from disk.
 443    fn load_bytes(&self, cx: &App) -> Task<Result<Vec<u8>>>;
 444}
 445
 446/// The auto-indent behavior associated with an editing operation.
 447/// For some editing operations, each affected line of text has its
 448/// indentation recomputed. For other operations, the entire block
 449/// of edited text is adjusted uniformly.
 450#[derive(Clone, Debug)]
 451pub enum AutoindentMode {
 452    /// Indent each line of inserted text.
 453    EachLine,
 454    /// Apply the same indentation adjustment to all of the lines
 455    /// in a given insertion.
 456    Block {
 457        /// The original indentation column of the first line of each
 458        /// insertion, if it has been copied.
 459        ///
 460        /// Knowing this makes it possible to preserve the relative indentation
 461        /// of every line in the insertion from when it was copied.
 462        ///
 463        /// If the original indent column is `a`, and the first line of insertion
 464        /// is then auto-indented to column `b`, then every other line of
 465        /// the insertion will be auto-indented to column `b - a`
 466        original_indent_columns: Vec<Option<u32>>,
 467    },
 468}
 469
 470#[derive(Clone)]
 471struct AutoindentRequest {
 472    before_edit: BufferSnapshot,
 473    entries: Vec<AutoindentRequestEntry>,
 474    is_block_mode: bool,
 475    ignore_empty_lines: bool,
 476}
 477
 478#[derive(Debug, Clone)]
 479struct AutoindentRequestEntry {
 480    /// A range of the buffer whose indentation should be adjusted.
 481    range: Range<Anchor>,
 482    /// The row of the edit start in the buffer before the edit was applied.
 483    /// This is stored here because the anchor in range is created after
 484    /// the edit, so it cannot be used with the before_edit snapshot.
 485    old_row: Option<u32>,
 486    indent_size: IndentSize,
 487    original_indent_column: Option<u32>,
 488}
 489
 490#[derive(Debug)]
 491struct IndentSuggestion {
 492    basis_row: u32,
 493    delta: Ordering,
 494    within_error: bool,
 495}
 496
 497struct BufferChunkHighlights<'a> {
 498    captures: SyntaxMapCaptures<'a>,
 499    next_capture: Option<SyntaxMapCapture<'a>>,
 500    stack: Vec<(usize, HighlightId)>,
 501    highlight_maps: Vec<HighlightMap>,
 502}
 503
 504/// An iterator that yields chunks of a buffer's text, along with their
 505/// syntax highlights and diagnostic status.
 506pub struct BufferChunks<'a> {
 507    buffer_snapshot: Option<&'a BufferSnapshot>,
 508    range: Range<usize>,
 509    chunks: text::Chunks<'a>,
 510    diagnostic_endpoints: Option<Peekable<vec::IntoIter<DiagnosticEndpoint>>>,
 511    error_depth: usize,
 512    warning_depth: usize,
 513    information_depth: usize,
 514    hint_depth: usize,
 515    unnecessary_depth: usize,
 516    underline: bool,
 517    highlights: Option<BufferChunkHighlights<'a>>,
 518}
 519
 520/// A chunk of a buffer's text, along with its syntax highlight and
 521/// diagnostic status.
 522#[derive(Clone, Debug, Default)]
 523pub struct Chunk<'a> {
 524    /// The text of the chunk.
 525    pub text: &'a str,
 526    /// The syntax highlighting style of the chunk.
 527    pub syntax_highlight_id: Option<HighlightId>,
 528    /// The highlight style that has been applied to this chunk in
 529    /// the editor.
 530    pub highlight_style: Option<HighlightStyle>,
 531    /// The severity of diagnostic associated with this chunk, if any.
 532    pub diagnostic_severity: Option<DiagnosticSeverity>,
 533    /// A bitset of which characters are tabs in this string.
 534    pub tabs: u128,
 535    /// Bitmap of character indices in this chunk
 536    pub chars: u128,
 537    /// Bitmap of newline indices in this chunk
 538    pub newlines: u128,
 539    /// Whether this chunk of text is marked as unnecessary.
 540    pub is_unnecessary: bool,
 541    /// Whether this chunk of text was originally a tab character.
 542    pub is_tab: bool,
 543    /// Whether this chunk of text was originally an inlay.
 544    pub is_inlay: bool,
 545    /// Whether to underline the corresponding text range in the editor.
 546    pub underline: bool,
 547}
 548
 549/// A set of edits to a given version of a buffer, computed asynchronously.
 550#[derive(Debug, Clone)]
 551pub struct Diff {
 552    pub base_version: clock::Global,
 553    pub line_ending: LineEnding,
 554    pub edits: Vec<(Range<usize>, Arc<str>)>,
 555}
 556
 557#[derive(Debug, Clone, Copy)]
 558pub(crate) struct DiagnosticEndpoint {
 559    offset: usize,
 560    is_start: bool,
 561    underline: bool,
 562    severity: DiagnosticSeverity,
 563    is_unnecessary: bool,
 564}
 565
 566/// A class of characters, used for characterizing a run of text.
 567#[derive(Copy, Clone, Eq, PartialEq, PartialOrd, Ord, Debug)]
 568pub enum CharKind {
 569    /// Whitespace.
 570    Whitespace,
 571    /// Punctuation.
 572    Punctuation,
 573    /// Word.
 574    Word,
 575}
 576
 577/// Context for character classification within a specific scope.
 578#[derive(Copy, Clone, Eq, PartialEq, Debug)]
 579pub enum CharScopeContext {
 580    /// Character classification for completion queries.
 581    ///
 582    /// This context treats certain characters as word constituents that would
 583    /// normally be considered punctuation, such as '-' in Tailwind classes
 584    /// ("bg-yellow-100") or '.' in import paths ("foo.ts").
 585    Completion,
 586    /// Character classification for linked edits.
 587    ///
 588    /// This context handles characters that should be treated as part of
 589    /// identifiers during linked editing operations, such as '.' in JSX
 590    /// component names like `<Animated.View>`.
 591    LinkedEdit,
 592}
 593
 594/// A runnable is a set of data about a region that could be resolved into a task
 595pub struct Runnable {
 596    pub tags: SmallVec<[RunnableTag; 1]>,
 597    pub language: Arc<Language>,
 598    pub buffer: BufferId,
 599}
 600
 601#[derive(Default, Clone, Debug)]
 602pub struct HighlightedText {
 603    pub text: SharedString,
 604    pub highlights: Vec<(Range<usize>, HighlightStyle)>,
 605}
 606
 607#[derive(Default, Debug)]
 608struct HighlightedTextBuilder {
 609    pub text: String,
 610    highlights: Vec<(Range<usize>, HighlightStyle)>,
 611}
 612
 613impl HighlightedText {
 614    pub fn from_buffer_range<T: ToOffset>(
 615        range: Range<T>,
 616        snapshot: &text::BufferSnapshot,
 617        syntax_snapshot: &SyntaxSnapshot,
 618        override_style: Option<HighlightStyle>,
 619        syntax_theme: &SyntaxTheme,
 620    ) -> Self {
 621        let mut highlighted_text = HighlightedTextBuilder::default();
 622        highlighted_text.add_text_from_buffer_range(
 623            range,
 624            snapshot,
 625            syntax_snapshot,
 626            override_style,
 627            syntax_theme,
 628        );
 629        highlighted_text.build()
 630    }
 631
 632    pub fn to_styled_text(&self, default_style: &TextStyle) -> StyledText {
 633        gpui::StyledText::new(self.text.clone())
 634            .with_default_highlights(default_style, self.highlights.iter().cloned())
 635    }
 636
 637    /// Returns the first line without leading whitespace unless highlighted
 638    /// and a boolean indicating if there are more lines after
 639    pub fn first_line_preview(self) -> (Self, bool) {
 640        let newline_ix = self.text.find('\n').unwrap_or(self.text.len());
 641        let first_line = &self.text[..newline_ix];
 642
 643        // Trim leading whitespace, unless an edit starts prior to it.
 644        let mut preview_start_ix = first_line.len() - first_line.trim_start().len();
 645        if let Some((first_highlight_range, _)) = self.highlights.first() {
 646            preview_start_ix = preview_start_ix.min(first_highlight_range.start);
 647        }
 648
 649        let preview_text = &first_line[preview_start_ix..];
 650        let preview_highlights = self
 651            .highlights
 652            .into_iter()
 653            .skip_while(|(range, _)| range.end <= preview_start_ix)
 654            .take_while(|(range, _)| range.start < newline_ix)
 655            .filter_map(|(mut range, highlight)| {
 656                range.start = range.start.saturating_sub(preview_start_ix);
 657                range.end = range.end.min(newline_ix).saturating_sub(preview_start_ix);
 658                if range.is_empty() {
 659                    None
 660                } else {
 661                    Some((range, highlight))
 662                }
 663            });
 664
 665        let preview = Self {
 666            text: SharedString::new(preview_text),
 667            highlights: preview_highlights.collect(),
 668        };
 669
 670        (preview, self.text.len() > newline_ix)
 671    }
 672}
 673
 674impl HighlightedTextBuilder {
 675    pub fn build(self) -> HighlightedText {
 676        HighlightedText {
 677            text: self.text.into(),
 678            highlights: self.highlights,
 679        }
 680    }
 681
 682    pub fn add_text_from_buffer_range<T: ToOffset>(
 683        &mut self,
 684        range: Range<T>,
 685        snapshot: &text::BufferSnapshot,
 686        syntax_snapshot: &SyntaxSnapshot,
 687        override_style: Option<HighlightStyle>,
 688        syntax_theme: &SyntaxTheme,
 689    ) {
 690        let range = range.to_offset(snapshot);
 691        for chunk in Self::highlighted_chunks(range, snapshot, syntax_snapshot) {
 692            let start = self.text.len();
 693            self.text.push_str(chunk.text);
 694            let end = self.text.len();
 695
 696            if let Some(highlight_style) = chunk
 697                .syntax_highlight_id
 698                .and_then(|id| syntax_theme.get(id).cloned())
 699            {
 700                let highlight_style = override_style.map_or(highlight_style, |override_style| {
 701                    highlight_style.highlight(override_style)
 702                });
 703                self.highlights.push((start..end, highlight_style));
 704            } else if let Some(override_style) = override_style {
 705                self.highlights.push((start..end, override_style));
 706            }
 707        }
 708    }
 709
 710    fn highlighted_chunks<'a>(
 711        range: Range<usize>,
 712        snapshot: &'a text::BufferSnapshot,
 713        syntax_snapshot: &'a SyntaxSnapshot,
 714    ) -> BufferChunks<'a> {
 715        let captures = syntax_snapshot.captures(range.clone(), snapshot, |grammar| {
 716            grammar
 717                .highlights_config
 718                .as_ref()
 719                .map(|config| &config.query)
 720        });
 721
 722        let highlight_maps = captures
 723            .grammars()
 724            .iter()
 725            .map(|grammar| grammar.highlight_map())
 726            .collect();
 727
 728        BufferChunks::new(
 729            snapshot.as_rope(),
 730            range,
 731            Some((captures, highlight_maps)),
 732            false,
 733            None,
 734        )
 735    }
 736}
 737
 738#[derive(Clone)]
 739pub struct EditPreview {
 740    old_snapshot: text::BufferSnapshot,
 741    applied_edits_snapshot: text::BufferSnapshot,
 742    syntax_snapshot: SyntaxSnapshot,
 743}
 744
 745impl EditPreview {
 746    pub fn as_unified_diff(
 747        &self,
 748        file: Option<&Arc<dyn File>>,
 749        edits: &[(Range<Anchor>, impl AsRef<str>)],
 750    ) -> Option<String> {
 751        let (first, _) = edits.first()?;
 752        let (last, _) = edits.last()?;
 753
 754        let start = first.start.to_point(&self.old_snapshot);
 755        let old_end = last.end.to_point(&self.old_snapshot);
 756        let new_end = last
 757            .end
 758            .bias_right(&self.old_snapshot)
 759            .to_point(&self.applied_edits_snapshot);
 760
 761        let start = Point::new(start.row.saturating_sub(3), 0);
 762        let old_end = Point::new(old_end.row + 4, 0).min(self.old_snapshot.max_point());
 763        let new_end = Point::new(new_end.row + 4, 0).min(self.applied_edits_snapshot.max_point());
 764
 765        let diff_body = unified_diff_with_offsets(
 766            &self
 767                .old_snapshot
 768                .text_for_range(start..old_end)
 769                .collect::<String>(),
 770            &self
 771                .applied_edits_snapshot
 772                .text_for_range(start..new_end)
 773                .collect::<String>(),
 774            start.row,
 775            start.row,
 776        );
 777
 778        let path = file.map(|f| f.path().as_unix_str());
 779        let header = match path {
 780            Some(p) => format!("--- a/{}\n+++ b/{}\n", p, p),
 781            None => String::new(),
 782        };
 783
 784        Some(format!("{}{}", header, diff_body))
 785    }
 786
 787    pub fn highlight_edits(
 788        &self,
 789        current_snapshot: &BufferSnapshot,
 790        edits: &[(Range<Anchor>, impl AsRef<str>)],
 791        include_deletions: bool,
 792        cx: &App,
 793    ) -> HighlightedText {
 794        let Some(visible_range_in_preview_snapshot) = self.compute_visible_range(edits) else {
 795            return HighlightedText::default();
 796        };
 797
 798        let mut highlighted_text = HighlightedTextBuilder::default();
 799
 800        let visible_range_in_preview_snapshot =
 801            visible_range_in_preview_snapshot.to_offset(&self.applied_edits_snapshot);
 802        let mut offset_in_preview_snapshot = visible_range_in_preview_snapshot.start;
 803
 804        let insertion_highlight_style = HighlightStyle {
 805            background_color: Some(cx.theme().status().created_background),
 806            ..Default::default()
 807        };
 808        let deletion_highlight_style = HighlightStyle {
 809            background_color: Some(cx.theme().status().deleted_background),
 810            ..Default::default()
 811        };
 812        let syntax_theme = cx.theme().syntax();
 813
 814        for (range, edit_text) in edits {
 815            let edit_new_end_in_preview_snapshot = range
 816                .end
 817                .bias_right(&self.old_snapshot)
 818                .to_offset(&self.applied_edits_snapshot);
 819            let edit_start_in_preview_snapshot =
 820                edit_new_end_in_preview_snapshot - edit_text.as_ref().len();
 821
 822            let unchanged_range_in_preview_snapshot =
 823                offset_in_preview_snapshot..edit_start_in_preview_snapshot;
 824            if !unchanged_range_in_preview_snapshot.is_empty() {
 825                highlighted_text.add_text_from_buffer_range(
 826                    unchanged_range_in_preview_snapshot,
 827                    &self.applied_edits_snapshot,
 828                    &self.syntax_snapshot,
 829                    None,
 830                    syntax_theme,
 831                );
 832            }
 833
 834            let range_in_current_snapshot = range.to_offset(current_snapshot);
 835            if include_deletions && !range_in_current_snapshot.is_empty() {
 836                highlighted_text.add_text_from_buffer_range(
 837                    range_in_current_snapshot,
 838                    &current_snapshot.text,
 839                    &current_snapshot.syntax,
 840                    Some(deletion_highlight_style),
 841                    syntax_theme,
 842                );
 843            }
 844
 845            if !edit_text.as_ref().is_empty() {
 846                highlighted_text.add_text_from_buffer_range(
 847                    edit_start_in_preview_snapshot..edit_new_end_in_preview_snapshot,
 848                    &self.applied_edits_snapshot,
 849                    &self.syntax_snapshot,
 850                    Some(insertion_highlight_style),
 851                    syntax_theme,
 852                );
 853            }
 854
 855            offset_in_preview_snapshot = edit_new_end_in_preview_snapshot;
 856        }
 857
 858        highlighted_text.add_text_from_buffer_range(
 859            offset_in_preview_snapshot..visible_range_in_preview_snapshot.end,
 860            &self.applied_edits_snapshot,
 861            &self.syntax_snapshot,
 862            None,
 863            syntax_theme,
 864        );
 865
 866        highlighted_text.build()
 867    }
 868
 869    pub fn build_result_buffer(&self, cx: &mut App) -> Entity<Buffer> {
 870        cx.new(|cx| {
 871            let mut buffer = Buffer::local_normalized(
 872                self.applied_edits_snapshot.as_rope().clone(),
 873                self.applied_edits_snapshot.line_ending(),
 874                cx,
 875            );
 876            buffer.set_language_async(self.syntax_snapshot.root_language(), cx);
 877            buffer
 878        })
 879    }
 880
 881    pub fn result_text_snapshot(&self) -> &text::BufferSnapshot {
 882        &self.applied_edits_snapshot
 883    }
 884
 885    pub fn result_syntax_snapshot(&self) -> &SyntaxSnapshot {
 886        &self.syntax_snapshot
 887    }
 888
 889    pub fn anchor_to_offset_in_result(&self, anchor: Anchor) -> usize {
 890        anchor
 891            .bias_right(&self.old_snapshot)
 892            .to_offset(&self.applied_edits_snapshot)
 893    }
 894
 895    pub fn compute_visible_range<T>(&self, edits: &[(Range<Anchor>, T)]) -> Option<Range<Point>> {
 896        let (first, _) = edits.first()?;
 897        let (last, _) = edits.last()?;
 898
 899        let start = first
 900            .start
 901            .bias_left(&self.old_snapshot)
 902            .to_point(&self.applied_edits_snapshot);
 903        let end = last
 904            .end
 905            .bias_right(&self.old_snapshot)
 906            .to_point(&self.applied_edits_snapshot);
 907
 908        // Ensure that the first line of the first edit and the last line of the last edit are always fully visible
 909        let range = Point::new(start.row, 0)
 910            ..Point::new(end.row, self.applied_edits_snapshot.line_len(end.row));
 911
 912        Some(range)
 913    }
 914}
 915
 916#[derive(Clone, Debug, PartialEq, Eq)]
 917pub struct BracketMatch<T> {
 918    pub open_range: Range<T>,
 919    pub close_range: Range<T>,
 920    pub newline_only: bool,
 921    pub syntax_layer_depth: usize,
 922    pub color_index: Option<usize>,
 923}
 924
 925impl<T> BracketMatch<T> {
 926    pub fn bracket_ranges(self) -> (Range<T>, Range<T>) {
 927        (self.open_range, self.close_range)
 928    }
 929}
 930
 931impl Buffer {
 932    /// Create a new buffer with the given base text.
 933    pub fn local<T: Into<String>>(base_text: T, cx: &Context<Self>) -> Self {
 934        Self::build(
 935            TextBuffer::new(
 936                ReplicaId::LOCAL,
 937                cx.entity_id().as_non_zero_u64().into(),
 938                base_text.into(),
 939            ),
 940            None,
 941            Capability::ReadWrite,
 942        )
 943    }
 944
 945    /// Create a new buffer with the given base text that has proper line endings and other normalization applied.
 946    pub fn local_normalized(
 947        base_text_normalized: Rope,
 948        line_ending: LineEnding,
 949        cx: &Context<Self>,
 950    ) -> Self {
 951        Self::build(
 952            TextBuffer::new_normalized(
 953                ReplicaId::LOCAL,
 954                cx.entity_id().as_non_zero_u64().into(),
 955                line_ending,
 956                base_text_normalized,
 957            ),
 958            None,
 959            Capability::ReadWrite,
 960        )
 961    }
 962
 963    /// Create a new buffer that is a replica of a remote buffer.
 964    pub fn remote(
 965        remote_id: BufferId,
 966        replica_id: ReplicaId,
 967        capability: Capability,
 968        base_text: impl Into<String>,
 969    ) -> Self {
 970        Self::build(
 971            TextBuffer::new(replica_id, remote_id, base_text.into()),
 972            None,
 973            capability,
 974        )
 975    }
 976
 977    /// Create a new buffer that is a replica of a remote buffer, populating its
 978    /// state from the given protobuf message.
 979    pub fn from_proto(
 980        replica_id: ReplicaId,
 981        capability: Capability,
 982        message: proto::BufferState,
 983        file: Option<Arc<dyn File>>,
 984    ) -> Result<Self> {
 985        let buffer_id = BufferId::new(message.id).context("Could not deserialize buffer_id")?;
 986        let buffer = TextBuffer::new(replica_id, buffer_id, message.base_text);
 987        let mut this = Self::build(buffer, file, capability);
 988        this.text.set_line_ending(proto::deserialize_line_ending(
 989            rpc::proto::LineEnding::from_i32(message.line_ending).context("missing line_ending")?,
 990        ));
 991        this.saved_version = proto::deserialize_version(&message.saved_version);
 992        this.saved_mtime = message.saved_mtime.map(|time| time.into());
 993        Ok(this)
 994    }
 995
 996    /// Serialize the buffer's state to a protobuf message.
 997    pub fn to_proto(&self, cx: &App) -> proto::BufferState {
 998        proto::BufferState {
 999            id: self.remote_id().into(),
1000            file: self.file.as_ref().map(|f| f.to_proto(cx)),
1001            base_text: self.base_text().to_string(),
1002            line_ending: proto::serialize_line_ending(self.line_ending()) as i32,
1003            saved_version: proto::serialize_version(&self.saved_version),
1004            saved_mtime: self.saved_mtime.map(|time| time.into()),
1005        }
1006    }
1007
1008    /// Serialize as protobufs all of the changes to the buffer since the given version.
1009    pub fn serialize_ops(
1010        &self,
1011        since: Option<clock::Global>,
1012        cx: &App,
1013    ) -> Task<Vec<proto::Operation>> {
1014        let mut operations = Vec::new();
1015        operations.extend(self.deferred_ops.iter().map(proto::serialize_operation));
1016
1017        operations.extend(self.remote_selections.iter().map(|(_, set)| {
1018            proto::serialize_operation(&Operation::UpdateSelections {
1019                selections: set.selections.clone(),
1020                lamport_timestamp: set.lamport_timestamp,
1021                line_mode: set.line_mode,
1022                cursor_shape: set.cursor_shape,
1023            })
1024        }));
1025
1026        for (server_id, diagnostics) in self.diagnostics.iter() {
1027            operations.push(proto::serialize_operation(&Operation::UpdateDiagnostics {
1028                lamport_timestamp: self.diagnostics_timestamp,
1029                server_id: *server_id,
1030                diagnostics: diagnostics.iter().cloned().collect(),
1031            }));
1032        }
1033
1034        for (server_id, completions) in &self.completion_triggers_per_language_server {
1035            operations.push(proto::serialize_operation(
1036                &Operation::UpdateCompletionTriggers {
1037                    triggers: completions.iter().cloned().collect(),
1038                    lamport_timestamp: self.completion_triggers_timestamp,
1039                    server_id: *server_id,
1040                },
1041            ));
1042        }
1043
1044        let text_operations = self.text.operations().clone();
1045        cx.background_spawn(async move {
1046            let since = since.unwrap_or_default();
1047            operations.extend(
1048                text_operations
1049                    .iter()
1050                    .filter(|(_, op)| !since.observed(op.timestamp()))
1051                    .map(|(_, op)| proto::serialize_operation(&Operation::Buffer(op.clone()))),
1052            );
1053            operations.sort_unstable_by_key(proto::lamport_timestamp_for_operation);
1054            operations
1055        })
1056    }
1057
1058    /// Assign a language to the buffer, returning the buffer.
1059    pub fn with_language_async(mut self, language: Arc<Language>, cx: &mut Context<Self>) -> Self {
1060        self.set_language_async(Some(language), cx);
1061        self
1062    }
1063
1064    /// Assign a language to the buffer, blocking for up to 1ms to reparse the buffer, returning the buffer.
1065    #[ztracing::instrument(skip_all, fields(lang = language.config.name.0.as_str()))]
1066    pub fn with_language(mut self, language: Arc<Language>, cx: &mut Context<Self>) -> Self {
1067        self.set_language(Some(language), cx);
1068        self
1069    }
1070
1071    /// Returns the [`Capability`] of this buffer.
1072    pub fn capability(&self) -> Capability {
1073        self.capability
1074    }
1075
1076    /// Whether this buffer can only be read.
1077    pub fn read_only(&self) -> bool {
1078        !self.capability.editable()
1079    }
1080
1081    /// Builds a [`Buffer`] with the given underlying [`TextBuffer`], diff base, [`File`] and [`Capability`].
1082    pub fn build(buffer: TextBuffer, file: Option<Arc<dyn File>>, capability: Capability) -> Self {
1083        let saved_mtime = file.as_ref().and_then(|file| file.disk_state().mtime());
1084        let snapshot = buffer.snapshot();
1085        let syntax_map = Mutex::new(SyntaxMap::new(&snapshot));
1086        let tree_sitter_data = TreeSitterData::new(snapshot);
1087        Self {
1088            saved_mtime,
1089            tree_sitter_data: Arc::new(tree_sitter_data),
1090            saved_version: buffer.version(),
1091            preview_version: buffer.version(),
1092            reload_task: None,
1093            transaction_depth: 0,
1094            was_dirty_before_starting_transaction: None,
1095            has_unsaved_edits: Cell::new((buffer.version(), false)),
1096            text: buffer,
1097            branch_state: None,
1098            file,
1099            capability,
1100            syntax_map,
1101            reparse: None,
1102            non_text_state_update_count: 0,
1103            sync_parse_timeout: if cfg!(any(test, feature = "test-support")) {
1104                Some(Duration::from_millis(10))
1105            } else {
1106                Some(Duration::from_millis(1))
1107            },
1108            parse_status: watch::channel(ParseStatus::Idle),
1109            autoindent_requests: Default::default(),
1110            wait_for_autoindent_txs: Default::default(),
1111            pending_autoindent: Default::default(),
1112            language: None,
1113            remote_selections: Default::default(),
1114            diagnostics: Default::default(),
1115            diagnostics_timestamp: Lamport::MIN,
1116            completion_triggers: Default::default(),
1117            completion_triggers_per_language_server: Default::default(),
1118            completion_triggers_timestamp: Lamport::MIN,
1119            deferred_ops: OperationQueue::new(),
1120            has_conflict: false,
1121            change_bits: Default::default(),
1122            modeline: None,
1123            _subscriptions: Vec::new(),
1124            encoding: encoding_rs::UTF_8,
1125            has_bom: false,
1126            reload_with_encoding_txns: HashMap::default(),
1127        }
1128    }
1129
1130    #[ztracing::instrument(skip_all)]
1131    pub fn build_snapshot(
1132        text: Rope,
1133        language: Option<Arc<Language>>,
1134        language_registry: Option<Arc<LanguageRegistry>>,
1135        modeline: Option<Arc<ModelineSettings>>,
1136        cx: &mut App,
1137    ) -> impl Future<Output = BufferSnapshot> + use<> {
1138        let entity_id = cx.reserve_entity::<Self>().entity_id();
1139        let buffer_id = entity_id.as_non_zero_u64().into();
1140        async move {
1141            let text =
1142                TextBuffer::new_normalized(ReplicaId::LOCAL, buffer_id, Default::default(), text);
1143            let text = text.into_snapshot();
1144            let mut syntax = SyntaxMap::new(&text).snapshot();
1145            if let Some(language) = language.clone() {
1146                let language_registry = language_registry.clone();
1147                syntax.reparse(&text, language_registry, language);
1148            }
1149            let tree_sitter_data = TreeSitterData::new(&text);
1150            BufferSnapshot {
1151                text,
1152                syntax,
1153                file: None,
1154                diagnostics: Default::default(),
1155                remote_selections: Default::default(),
1156                tree_sitter_data: Arc::new(tree_sitter_data),
1157                language,
1158                non_text_state_update_count: 0,
1159                capability: Capability::ReadOnly,
1160                modeline,
1161            }
1162        }
1163    }
1164
1165    pub fn build_empty_snapshot(cx: &mut App) -> BufferSnapshot {
1166        let entity_id = cx.reserve_entity::<Self>().entity_id();
1167        let buffer_id = entity_id.as_non_zero_u64().into();
1168        let text = TextBuffer::new_normalized(
1169            ReplicaId::LOCAL,
1170            buffer_id,
1171            Default::default(),
1172            Rope::new(),
1173        );
1174        let text = text.into_snapshot();
1175        let syntax = SyntaxMap::new(&text).snapshot();
1176        let tree_sitter_data = TreeSitterData::new(&text);
1177        BufferSnapshot {
1178            text,
1179            syntax,
1180            tree_sitter_data: Arc::new(tree_sitter_data),
1181            file: None,
1182            diagnostics: Default::default(),
1183            remote_selections: Default::default(),
1184            language: None,
1185            non_text_state_update_count: 0,
1186            capability: Capability::ReadOnly,
1187            modeline: None,
1188        }
1189    }
1190
1191    #[cfg(any(test, feature = "test-support"))]
1192    pub fn build_snapshot_sync(
1193        text: Rope,
1194        language: Option<Arc<Language>>,
1195        language_registry: Option<Arc<LanguageRegistry>>,
1196        cx: &mut App,
1197    ) -> BufferSnapshot {
1198        let entity_id = cx.reserve_entity::<Self>().entity_id();
1199        let buffer_id = entity_id.as_non_zero_u64().into();
1200        let text =
1201            TextBuffer::new_normalized(ReplicaId::LOCAL, buffer_id, Default::default(), text)
1202                .into_snapshot();
1203        let mut syntax = SyntaxMap::new(&text).snapshot();
1204        if let Some(language) = language.clone() {
1205            syntax.reparse(&text, language_registry, language);
1206        }
1207        let tree_sitter_data = TreeSitterData::new(&text);
1208        BufferSnapshot {
1209            text,
1210            syntax,
1211            tree_sitter_data: Arc::new(tree_sitter_data),
1212            file: None,
1213            diagnostics: Default::default(),
1214            remote_selections: Default::default(),
1215            language,
1216            non_text_state_update_count: 0,
1217            capability: Capability::ReadOnly,
1218            modeline: None,
1219        }
1220    }
1221
1222    /// Retrieve a snapshot of the buffer's current state. This is computationally
1223    /// cheap, and allows reading from the buffer on a background thread.
1224    pub fn snapshot(&self) -> BufferSnapshot {
1225        let text = self.text.snapshot();
1226
1227        let syntax = {
1228            let mut syntax_map = self.syntax_map.lock();
1229            syntax_map.interpolate(text);
1230            syntax_map.snapshot()
1231        };
1232
1233        let tree_sitter_data = if self.text.version() != *self.tree_sitter_data.version() {
1234            Arc::new(TreeSitterData::new(text))
1235        } else {
1236            self.tree_sitter_data.clone()
1237        };
1238
1239        BufferSnapshot {
1240            text: text.clone(),
1241            syntax,
1242            tree_sitter_data,
1243            file: self.file.clone(),
1244            remote_selections: self.remote_selections.clone(),
1245            diagnostics: self.diagnostics.clone(),
1246            language: self.language.clone(),
1247            non_text_state_update_count: self.non_text_state_update_count,
1248            capability: self.capability,
1249            modeline: self.modeline.clone(),
1250        }
1251    }
1252
1253    pub fn branch(&mut self, cx: &mut Context<Self>) -> Entity<Self> {
1254        let this = cx.entity();
1255        cx.new(|cx| {
1256            let mut branch = Self {
1257                branch_state: Some(BufferBranchState {
1258                    base_buffer: this.clone(),
1259                    merged_operations: Default::default(),
1260                }),
1261                language: self.language.clone(),
1262                has_conflict: self.has_conflict,
1263                has_unsaved_edits: Cell::new(self.has_unsaved_edits.get_mut().clone()),
1264                _subscriptions: vec![cx.subscribe(&this, Self::on_base_buffer_event)],
1265                ..Self::build(self.text.branch(), self.file.clone(), self.capability())
1266            };
1267            if let Some(language_registry) = self.language_registry() {
1268                branch.set_language_registry(language_registry);
1269            }
1270
1271            // Reparse the branch buffer so that we get syntax highlighting immediately.
1272            branch.reparse(cx, true);
1273
1274            branch
1275        })
1276    }
1277
1278    #[ztracing::instrument(skip_all)]
1279    pub fn preview_edits(
1280        &self,
1281        edits: Arc<[(Range<Anchor>, Arc<str>)]>,
1282        cx: &App,
1283    ) -> Task<EditPreview> {
1284        let registry = self.language_registry();
1285        let language = self.language().cloned();
1286        let old_snapshot = self.text.snapshot().clone();
1287        let mut branch_buffer = self.text.branch();
1288        let mut syntax_snapshot = self.syntax_map.lock().snapshot();
1289        cx.background_spawn(async move {
1290            if !edits.is_empty() {
1291                if let Some(language) = language.clone() {
1292                    syntax_snapshot.reparse(&old_snapshot, registry.clone(), language);
1293                }
1294
1295                branch_buffer.edit(edits.iter().cloned());
1296                let snapshot = branch_buffer.snapshot();
1297                syntax_snapshot.interpolate(&snapshot);
1298
1299                if let Some(language) = language {
1300                    syntax_snapshot.reparse(&snapshot, registry, language);
1301                }
1302            }
1303            EditPreview {
1304                old_snapshot,
1305                applied_edits_snapshot: branch_buffer.into_snapshot(),
1306                syntax_snapshot,
1307            }
1308        })
1309    }
1310
1311    /// Applies all of the changes in this buffer that intersect any of the
1312    /// given `ranges` to its base buffer.
1313    ///
1314    /// If `ranges` is empty, then all changes will be applied. This buffer must
1315    /// be a branch buffer to call this method.
1316    pub fn merge_into_base(&mut self, ranges: Vec<Range<usize>>, cx: &mut Context<Self>) {
1317        let Some(base_buffer) = self.base_buffer() else {
1318            debug_panic!("not a branch buffer");
1319            return;
1320        };
1321
1322        let mut ranges = if ranges.is_empty() {
1323            &[0..usize::MAX]
1324        } else {
1325            ranges.as_slice()
1326        }
1327        .iter()
1328        .peekable();
1329
1330        let mut edits = Vec::new();
1331        for edit in self.edits_since::<usize>(&base_buffer.read(cx).version()) {
1332            let mut is_included = false;
1333            while let Some(range) = ranges.peek() {
1334                if range.end < edit.new.start {
1335                    ranges.next().unwrap();
1336                } else {
1337                    if range.start <= edit.new.end {
1338                        is_included = true;
1339                    }
1340                    break;
1341                }
1342            }
1343
1344            if is_included {
1345                edits.push((
1346                    edit.old.clone(),
1347                    self.text_for_range(edit.new.clone()).collect::<String>(),
1348                ));
1349            }
1350        }
1351
1352        let operation = base_buffer.update(cx, |base_buffer, cx| {
1353            // cx.emit(BufferEvent::DiffBaseChanged);
1354            base_buffer.edit(edits, None, cx)
1355        });
1356
1357        if let Some(operation) = operation
1358            && let Some(BufferBranchState {
1359                merged_operations, ..
1360            }) = &mut self.branch_state
1361        {
1362            merged_operations.push(operation);
1363        }
1364    }
1365
1366    fn on_base_buffer_event(
1367        &mut self,
1368        _: Entity<Buffer>,
1369        event: &BufferEvent,
1370        cx: &mut Context<Self>,
1371    ) {
1372        let BufferEvent::Operation { operation, .. } = event else {
1373            return;
1374        };
1375        let Some(BufferBranchState {
1376            merged_operations, ..
1377        }) = &mut self.branch_state
1378        else {
1379            return;
1380        };
1381
1382        let mut operation_to_undo = None;
1383        if let Operation::Buffer(text::Operation::Edit(operation)) = &operation
1384            && let Ok(ix) = merged_operations.binary_search(&operation.timestamp)
1385        {
1386            merged_operations.remove(ix);
1387            operation_to_undo = Some(operation.timestamp);
1388        }
1389
1390        self.apply_ops([operation.clone()], cx);
1391
1392        if let Some(timestamp) = operation_to_undo {
1393            let counts = [(timestamp, u32::MAX)].into_iter().collect();
1394            self.undo_operations(counts, cx);
1395        }
1396    }
1397
1398    pub fn as_text_snapshot(&self) -> &text::BufferSnapshot {
1399        &self.text
1400    }
1401
1402    /// Retrieve a snapshot of the buffer's raw text, without any
1403    /// language-related state like the syntax tree or diagnostics.
1404    #[ztracing::instrument(skip_all)]
1405    pub fn text_snapshot(&self) -> text::BufferSnapshot {
1406        // todo lw
1407        self.text.snapshot().clone()
1408    }
1409
1410    /// The file associated with the buffer, if any.
1411    pub fn file(&self) -> Option<&Arc<dyn File>> {
1412        self.file.as_ref()
1413    }
1414
1415    /// The version of the buffer that was last saved or reloaded from disk.
1416    pub fn saved_version(&self) -> &clock::Global {
1417        &self.saved_version
1418    }
1419
1420    /// The mtime of the buffer's file when the buffer was last saved or reloaded from disk.
1421    pub fn saved_mtime(&self) -> Option<MTime> {
1422        self.saved_mtime
1423    }
1424
1425    /// Returns the character encoding of the buffer's file.
1426    pub fn encoding(&self) -> &'static Encoding {
1427        self.encoding
1428    }
1429
1430    /// Sets the character encoding of the buffer.
1431    pub fn set_encoding(&mut self, encoding: &'static Encoding) {
1432        self.encoding = encoding;
1433    }
1434
1435    /// Returns whether the buffer has a Byte Order Mark.
1436    pub fn has_bom(&self) -> bool {
1437        self.has_bom
1438    }
1439
1440    /// Sets whether the buffer has a Byte Order Mark.
1441    pub fn set_has_bom(&mut self, has_bom: bool) {
1442        self.has_bom = has_bom;
1443    }
1444
1445    /// Assign a language to the buffer.
1446    pub fn set_language_async(&mut self, language: Option<Arc<Language>>, cx: &mut Context<Self>) {
1447        self.set_language_(language, cfg!(any(test, feature = "test-support")), cx);
1448    }
1449
1450    /// Assign a language to the buffer, blocking for up to 1ms to reparse the buffer.
1451    pub fn set_language(&mut self, language: Option<Arc<Language>>, cx: &mut Context<Self>) {
1452        self.set_language_(language, true, cx);
1453    }
1454
1455    #[ztracing::instrument(skip_all)]
1456    fn set_language_(
1457        &mut self,
1458        language: Option<Arc<Language>>,
1459        may_block: bool,
1460        cx: &mut Context<Self>,
1461    ) {
1462        if language == self.language {
1463            return;
1464        }
1465        self.non_text_state_update_count += 1;
1466        self.syntax_map.lock().clear(&self.text);
1467        let old_language = std::mem::replace(&mut self.language, language);
1468        self.was_changed();
1469        self.reparse(cx, may_block);
1470        let has_fresh_language =
1471            self.language.is_some() && old_language.is_none_or(|old| old == *PLAIN_TEXT);
1472        cx.emit(BufferEvent::LanguageChanged(has_fresh_language));
1473    }
1474
1475    /// Assign a language registry to the buffer. This allows the buffer to retrieve
1476    /// other languages if parts of the buffer are written in different languages.
1477    pub fn set_language_registry(&self, language_registry: Arc<LanguageRegistry>) {
1478        self.syntax_map
1479            .lock()
1480            .set_language_registry(language_registry);
1481    }
1482
1483    pub fn language_registry(&self) -> Option<Arc<LanguageRegistry>> {
1484        self.syntax_map.lock().language_registry()
1485    }
1486
1487    /// Assign the line ending type to the buffer.
1488    pub fn set_line_ending(&mut self, line_ending: LineEnding, cx: &mut Context<Self>) {
1489        self.text.set_line_ending(line_ending);
1490
1491        let lamport_timestamp = self.text.lamport_clock.tick();
1492        self.send_operation(
1493            Operation::UpdateLineEnding {
1494                line_ending,
1495                lamport_timestamp,
1496            },
1497            true,
1498            cx,
1499        );
1500    }
1501
1502    /// Assign the buffer [`ModelineSettings`].
1503    pub fn set_modeline(&mut self, modeline: Option<ModelineSettings>) -> bool {
1504        if modeline.as_ref() != self.modeline.as_deref() {
1505            self.modeline = modeline.map(Arc::new);
1506            true
1507        } else {
1508            false
1509        }
1510    }
1511
1512    /// Returns the [`ModelineSettings`].
1513    pub fn modeline(&self) -> Option<&Arc<ModelineSettings>> {
1514        self.modeline.as_ref()
1515    }
1516
1517    /// Assign the buffer a new [`Capability`].
1518    pub fn set_capability(&mut self, capability: Capability, cx: &mut Context<Self>) {
1519        if self.capability != capability {
1520            self.capability = capability;
1521            cx.emit(BufferEvent::CapabilityChanged)
1522        }
1523    }
1524
1525    /// This method is called to signal that the buffer has been saved.
1526    pub fn did_save(
1527        &mut self,
1528        version: clock::Global,
1529        mtime: Option<MTime>,
1530        cx: &mut Context<Self>,
1531    ) {
1532        self.saved_version = version.clone();
1533        self.has_unsaved_edits.set((version, false));
1534        self.has_conflict = false;
1535        self.saved_mtime = mtime;
1536        self.was_changed();
1537        cx.emit(BufferEvent::Saved);
1538        cx.notify();
1539    }
1540
1541    /// Reloads the contents of the buffer from disk.
1542    pub fn reload(&mut self, cx: &Context<Self>) -> oneshot::Receiver<Option<Transaction>> {
1543        self.reload_impl(None, cx)
1544    }
1545
1546    /// Reloads the contents of the buffer from disk using the specified encoding.
1547    ///
1548    /// This bypasses automatic encoding detection heuristics (like BOM checks) for non-Unicode encodings,
1549    /// allowing users to force a specific interpretation of the bytes.
1550    pub fn reload_with_encoding(
1551        &mut self,
1552        encoding: &'static Encoding,
1553        cx: &Context<Self>,
1554    ) -> oneshot::Receiver<Option<Transaction>> {
1555        self.reload_impl(Some(encoding), cx)
1556    }
1557
1558    fn reload_impl(
1559        &mut self,
1560        force_encoding: Option<&'static Encoding>,
1561        cx: &Context<Self>,
1562    ) -> oneshot::Receiver<Option<Transaction>> {
1563        let (tx, rx) = futures::channel::oneshot::channel();
1564        let prev_version = self.text.version();
1565
1566        self.reload_task = Some(cx.spawn(async move |this, cx| {
1567            let Some((new_mtime, load_bytes_task, current_encoding)) =
1568                this.update(cx, |this, cx| {
1569                    let file = this.file.as_ref()?.as_local()?;
1570                    Some((
1571                        file.disk_state().mtime(),
1572                        file.load_bytes(cx),
1573                        this.encoding,
1574                    ))
1575                })?
1576            else {
1577                return Ok(());
1578            };
1579
1580            let target_encoding = force_encoding.unwrap_or(current_encoding);
1581
1582            let is_unicode = target_encoding == encoding_rs::UTF_8
1583                || target_encoding == encoding_rs::UTF_16LE
1584                || target_encoding == encoding_rs::UTF_16BE;
1585
1586            let (new_text, has_bom, encoding_used) = if force_encoding.is_some() && !is_unicode {
1587                let bytes = load_bytes_task.await?;
1588                let (cow, _had_errors) = target_encoding.decode_without_bom_handling(&bytes);
1589                (cow.into_owned(), false, target_encoding)
1590            } else {
1591                let bytes = load_bytes_task.await?;
1592                let (cow, used_enc, _had_errors) = target_encoding.decode(&bytes);
1593
1594                let actual_has_bom = if used_enc == encoding_rs::UTF_8 {
1595                    bytes.starts_with(&[0xEF, 0xBB, 0xBF])
1596                } else if used_enc == encoding_rs::UTF_16LE {
1597                    bytes.starts_with(&[0xFF, 0xFE])
1598                } else if used_enc == encoding_rs::UTF_16BE {
1599                    bytes.starts_with(&[0xFE, 0xFF])
1600                } else {
1601                    false
1602                };
1603                (cow.into_owned(), actual_has_bom, used_enc)
1604            };
1605
1606            let diff = this.update(cx, |this, cx| this.diff(new_text, cx))?.await;
1607            this.update(cx, |this, cx| {
1608                if this.version() == diff.base_version {
1609                    this.finalize_last_transaction();
1610                    let old_encoding = this.encoding;
1611                    let old_has_bom = this.has_bom;
1612                    this.apply_diff(diff, cx);
1613                    this.encoding = encoding_used;
1614                    this.has_bom = has_bom;
1615                    let transaction = this.finalize_last_transaction().cloned();
1616                    if let Some(ref txn) = transaction {
1617                        if old_encoding != encoding_used || old_has_bom != has_bom {
1618                            this.reload_with_encoding_txns
1619                                .insert(txn.id, (old_encoding, old_has_bom));
1620                        }
1621                    }
1622                    tx.send(transaction).ok();
1623                    this.has_conflict = false;
1624                    this.did_reload(this.version(), this.line_ending(), new_mtime, cx);
1625                } else {
1626                    if !diff.edits.is_empty()
1627                        || this
1628                            .edits_since::<usize>(&diff.base_version)
1629                            .next()
1630                            .is_some()
1631                    {
1632                        this.has_conflict = true;
1633                    }
1634
1635                    this.did_reload(prev_version, this.line_ending(), this.saved_mtime, cx);
1636                }
1637
1638                this.reload_task.take();
1639            })
1640        }));
1641        rx
1642    }
1643
1644    /// This method is called to signal that the buffer has been reloaded.
1645    pub fn did_reload(
1646        &mut self,
1647        version: clock::Global,
1648        line_ending: LineEnding,
1649        mtime: Option<MTime>,
1650        cx: &mut Context<Self>,
1651    ) {
1652        self.saved_version = version;
1653        self.has_unsaved_edits
1654            .set((self.saved_version.clone(), false));
1655        self.text.set_line_ending(line_ending);
1656        self.saved_mtime = mtime;
1657        cx.emit(BufferEvent::Reloaded);
1658        cx.notify();
1659    }
1660
1661    /// Updates the [`File`] backing this buffer. This should be called when
1662    /// the file has changed or has been deleted.
1663    pub fn file_updated(&mut self, new_file: Arc<dyn File>, cx: &mut Context<Self>) {
1664        let was_dirty = self.is_dirty();
1665        let mut file_changed = false;
1666
1667        if let Some(old_file) = self.file.as_ref() {
1668            if new_file.path() != old_file.path() {
1669                file_changed = true;
1670            }
1671
1672            let old_state = old_file.disk_state();
1673            let new_state = new_file.disk_state();
1674            if old_state != new_state {
1675                file_changed = true;
1676                if !was_dirty && matches!(new_state, DiskState::Present { .. }) {
1677                    cx.emit(BufferEvent::ReloadNeeded)
1678                }
1679            }
1680        } else {
1681            file_changed = true;
1682        };
1683
1684        self.file = Some(new_file);
1685        if file_changed {
1686            self.was_changed();
1687            self.non_text_state_update_count += 1;
1688            if was_dirty != self.is_dirty() {
1689                cx.emit(BufferEvent::DirtyChanged);
1690            }
1691            cx.emit(BufferEvent::FileHandleChanged);
1692            cx.notify();
1693        }
1694    }
1695
1696    pub fn base_buffer(&self) -> Option<Entity<Self>> {
1697        Some(self.branch_state.as_ref()?.base_buffer.clone())
1698    }
1699
1700    /// Returns the primary [`Language`] assigned to this [`Buffer`].
1701    pub fn language(&self) -> Option<&Arc<Language>> {
1702        self.language.as_ref()
1703    }
1704
1705    /// Returns the [`Language`] at the given location.
1706    pub fn language_at<D: ToOffset>(&self, position: D) -> Option<Arc<Language>> {
1707        let offset = position.to_offset(self);
1708        let text: &TextBufferSnapshot = &self.text;
1709        self.syntax_map
1710            .lock()
1711            .layers_for_range(offset..offset, text, false)
1712            .filter(|layer| {
1713                layer
1714                    .included_sub_ranges
1715                    .is_none_or(|ranges| offset_in_sub_ranges(ranges, offset, text))
1716            })
1717            .last()
1718            .map(|info| info.language.clone())
1719            .or_else(|| self.language.clone())
1720    }
1721
1722    /// Returns each [`Language`] for the active syntax layers at the given location.
1723    pub fn languages_at<D: ToOffset>(&self, position: D) -> Vec<Arc<Language>> {
1724        let offset = position.to_offset(self);
1725        let text: &TextBufferSnapshot = &self.text;
1726        let mut languages: Vec<Arc<Language>> = self
1727            .syntax_map
1728            .lock()
1729            .layers_for_range(offset..offset, text, false)
1730            .filter(|layer| {
1731                // For combined injections, check if offset is within the actual sub-ranges.
1732                layer
1733                    .included_sub_ranges
1734                    .is_none_or(|ranges| offset_in_sub_ranges(ranges, offset, text))
1735            })
1736            .map(|info| info.language.clone())
1737            .collect();
1738
1739        if languages.is_empty()
1740            && let Some(buffer_language) = self.language()
1741        {
1742            languages.push(buffer_language.clone());
1743        }
1744
1745        languages
1746    }
1747
1748    /// An integer version number that accounts for all updates besides
1749    /// the buffer's text itself (which is versioned via a version vector).
1750    pub fn non_text_state_update_count(&self) -> usize {
1751        self.non_text_state_update_count
1752    }
1753
1754    /// Whether the buffer is being parsed in the background.
1755    #[cfg(any(test, feature = "test-support"))]
1756    pub fn is_parsing(&self) -> bool {
1757        self.reparse.is_some()
1758    }
1759
1760    /// Indicates whether the buffer contains any regions that may be
1761    /// written in a language that hasn't been loaded yet.
1762    pub fn contains_unknown_injections(&self) -> bool {
1763        self.syntax_map.lock().contains_unknown_injections()
1764    }
1765
1766    /// Sets the sync parse timeout for this buffer.
1767    ///
1768    /// Setting this to `None` disables sync parsing entirely.
1769    pub fn set_sync_parse_timeout(&mut self, timeout: Option<Duration>) {
1770        self.sync_parse_timeout = timeout;
1771    }
1772
1773    fn invalidate_tree_sitter_data(
1774        tree_sitter_data: &mut Arc<TreeSitterData>,
1775        snapshot: &text::BufferSnapshot,
1776    ) {
1777        match Arc::get_mut(tree_sitter_data) {
1778            Some(tree_sitter_data) => tree_sitter_data.clear(snapshot),
1779            None => {
1780                let new_tree_sitter_data = TreeSitterData::new(snapshot);
1781                *tree_sitter_data = Arc::new(new_tree_sitter_data)
1782            }
1783        }
1784    }
1785
1786    /// Called after an edit to synchronize the buffer's main parse tree with
1787    /// the buffer's new underlying state.
1788    ///
1789    /// Locks the syntax map and interpolates the edits since the last reparse
1790    /// into the foreground syntax tree.
1791    ///
1792    /// Then takes a stable snapshot of the syntax map before unlocking it.
1793    /// The snapshot with the interpolated edits is sent to a background thread,
1794    /// where we ask Tree-sitter to perform an incremental parse.
1795    ///
1796    /// Meanwhile, in the foreground if `may_block` is true, we block the main
1797    /// thread for up to 1ms waiting on the parse to complete. As soon as it
1798    /// completes, we proceed synchronously, unless a 1ms timeout elapses.
1799    ///
1800    /// If we time out waiting on the parse, we spawn a second task waiting
1801    /// until the parse does complete and return with the interpolated tree still
1802    /// in the foreground. When the background parse completes, call back into
1803    /// the main thread and assign the foreground parse state.
1804    ///
1805    /// If the buffer or grammar changed since the start of the background parse,
1806    /// initiate an additional reparse recursively. To avoid concurrent parses
1807    /// for the same buffer, we only initiate a new parse if we are not already
1808    /// parsing in the background.
1809    #[ztracing::instrument(skip_all)]
1810    pub fn reparse(&mut self, cx: &mut Context<Self>, may_block: bool) {
1811        if self.text.version() != *self.tree_sitter_data.version() {
1812            Self::invalidate_tree_sitter_data(&mut self.tree_sitter_data, self.text.snapshot());
1813        }
1814        if self.reparse.is_some() {
1815            return;
1816        }
1817        let language = if let Some(language) = self.language.clone() {
1818            language
1819        } else {
1820            return;
1821        };
1822
1823        let text = self.text_snapshot();
1824        let parsed_version = self.version();
1825
1826        let mut syntax_map = self.syntax_map.lock();
1827        syntax_map.interpolate(&text);
1828        let language_registry = syntax_map.language_registry();
1829        let mut syntax_snapshot = syntax_map.snapshot();
1830        drop(syntax_map);
1831
1832        self.parse_status.0.send(ParseStatus::Parsing).unwrap();
1833        if may_block && let Some(sync_parse_timeout) = self.sync_parse_timeout {
1834            if let Ok(()) = syntax_snapshot.reparse_with_timeout(
1835                &text,
1836                language_registry.clone(),
1837                language.clone(),
1838                sync_parse_timeout,
1839            ) {
1840                self.did_finish_parsing(syntax_snapshot, Some(Duration::from_millis(300)), cx);
1841                self.reparse = None;
1842                return;
1843            }
1844        }
1845
1846        let parse_task = cx.background_spawn({
1847            let language = language.clone();
1848            let language_registry = language_registry.clone();
1849            async move {
1850                syntax_snapshot.reparse(&text, language_registry, language);
1851                syntax_snapshot
1852            }
1853        });
1854
1855        self.reparse = Some(cx.spawn(async move |this, cx| {
1856            let new_syntax_map = parse_task.await;
1857            this.update(cx, move |this, cx| {
1858                let grammar_changed = || {
1859                    this.language
1860                        .as_ref()
1861                        .is_none_or(|current_language| !Arc::ptr_eq(&language, current_language))
1862                };
1863                let language_registry_changed = || {
1864                    new_syntax_map.contains_unknown_injections()
1865                        && language_registry.is_some_and(|registry| {
1866                            registry.version() != new_syntax_map.language_registry_version()
1867                        })
1868                };
1869                let parse_again = this.version.changed_since(&parsed_version)
1870                    || language_registry_changed()
1871                    || grammar_changed();
1872                this.did_finish_parsing(new_syntax_map, None, cx);
1873                this.reparse = None;
1874                if parse_again {
1875                    this.reparse(cx, false);
1876                }
1877            })
1878            .ok();
1879        }));
1880    }
1881
1882    fn did_finish_parsing(
1883        &mut self,
1884        syntax_snapshot: SyntaxSnapshot,
1885        block_budget: Option<Duration>,
1886        cx: &mut Context<Self>,
1887    ) {
1888        self.non_text_state_update_count += 1;
1889        self.syntax_map.lock().did_parse(syntax_snapshot);
1890        self.was_changed();
1891        self.request_autoindent(cx, block_budget);
1892        self.parse_status.0.send(ParseStatus::Idle).unwrap();
1893        Self::invalidate_tree_sitter_data(&mut self.tree_sitter_data, &self.text.snapshot());
1894        cx.emit(BufferEvent::Reparsed);
1895        cx.notify();
1896    }
1897
1898    pub fn parse_status(&self) -> watch::Receiver<ParseStatus> {
1899        self.parse_status.1.clone()
1900    }
1901
1902    /// Wait until the buffer is no longer parsing
1903    pub fn parsing_idle(&self) -> impl Future<Output = ()> + use<> {
1904        let mut parse_status = self.parse_status();
1905        async move {
1906            while *parse_status.borrow() != ParseStatus::Idle {
1907                if parse_status.changed().await.is_err() {
1908                    break;
1909                }
1910            }
1911        }
1912    }
1913
1914    /// Assign to the buffer a set of diagnostics created by a given language server.
1915    pub fn update_diagnostics(
1916        &mut self,
1917        server_id: LanguageServerId,
1918        diagnostics: DiagnosticSet,
1919        cx: &mut Context<Self>,
1920    ) {
1921        let lamport_timestamp = self.text.lamport_clock.tick();
1922        let op = Operation::UpdateDiagnostics {
1923            server_id,
1924            diagnostics: diagnostics.iter().cloned().collect(),
1925            lamport_timestamp,
1926        };
1927
1928        self.apply_diagnostic_update(server_id, diagnostics, lamport_timestamp, cx);
1929        self.send_operation(op, true, cx);
1930    }
1931
1932    pub fn buffer_diagnostics(
1933        &self,
1934        for_server: Option<LanguageServerId>,
1935    ) -> Vec<&DiagnosticEntry<Anchor>> {
1936        match for_server {
1937            Some(server_id) => self
1938                .diagnostics
1939                .get(&server_id)
1940                .map_or_else(Vec::new, |diagnostics| diagnostics.iter().collect()),
1941            None => self
1942                .diagnostics
1943                .iter()
1944                .flat_map(|(_, diagnostic_set)| diagnostic_set.iter())
1945                .collect(),
1946        }
1947    }
1948
1949    fn request_autoindent(&mut self, cx: &mut Context<Self>, block_budget: Option<Duration>) {
1950        if let Some(indent_sizes) = self.compute_autoindents() {
1951            let indent_sizes = cx.background_spawn(indent_sizes);
1952            let Some(block_budget) = block_budget else {
1953                self.pending_autoindent = Some(cx.spawn(async move |this, cx| {
1954                    let indent_sizes = indent_sizes.await;
1955                    this.update(cx, |this, cx| {
1956                        this.apply_autoindents(indent_sizes, cx);
1957                    })
1958                    .ok();
1959                }));
1960                return;
1961            };
1962            match cx
1963                .foreground_executor()
1964                .block_with_timeout(block_budget, indent_sizes)
1965            {
1966                Ok(indent_sizes) => self.apply_autoindents(indent_sizes, cx),
1967                Err(indent_sizes) => {
1968                    self.pending_autoindent = Some(cx.spawn(async move |this, cx| {
1969                        let indent_sizes = indent_sizes.await;
1970                        this.update(cx, |this, cx| {
1971                            this.apply_autoindents(indent_sizes, cx);
1972                        })
1973                        .ok();
1974                    }));
1975                }
1976            }
1977        } else {
1978            self.autoindent_requests.clear();
1979            for tx in self.wait_for_autoindent_txs.drain(..) {
1980                tx.send(()).ok();
1981            }
1982        }
1983    }
1984
1985    fn compute_autoindents(
1986        &self,
1987    ) -> Option<impl Future<Output = BTreeMap<u32, IndentSize>> + use<>> {
1988        let max_rows_between_yields = 100;
1989        let snapshot = self.snapshot();
1990        if snapshot.syntax.is_empty() || self.autoindent_requests.is_empty() {
1991            return None;
1992        }
1993
1994        let autoindent_requests = self.autoindent_requests.clone();
1995        Some(async move {
1996            let mut indent_sizes = BTreeMap::<u32, (IndentSize, bool)>::new();
1997            for request in autoindent_requests {
1998                // Resolve each edited range to its row in the current buffer and in the
1999                // buffer before this batch of edits.
2000                let mut row_ranges = Vec::new();
2001                let mut old_to_new_rows = BTreeMap::new();
2002                let mut language_indent_sizes_by_new_row = Vec::new();
2003                for entry in &request.entries {
2004                    let position = entry.range.start;
2005                    let new_row = position.to_point(&snapshot).row;
2006                    let new_end_row = entry.range.end.to_point(&snapshot).row + 1;
2007                    language_indent_sizes_by_new_row.push((new_row, entry.indent_size));
2008
2009                    if let Some(old_row) = entry.old_row {
2010                        old_to_new_rows.insert(old_row, new_row);
2011                    }
2012                    row_ranges.push((new_row..new_end_row, entry.original_indent_column));
2013                }
2014
2015                // Build a map containing the suggested indentation for each of the edited lines
2016                // with respect to the state of the buffer before these edits. This map is keyed
2017                // by the rows for these lines in the current state of the buffer.
2018                let mut old_suggestions = BTreeMap::<u32, (IndentSize, bool)>::default();
2019                let old_edited_ranges =
2020                    contiguous_ranges(old_to_new_rows.keys().copied(), max_rows_between_yields);
2021                let mut language_indent_sizes = language_indent_sizes_by_new_row.iter().peekable();
2022                let mut language_indent_size = IndentSize::default();
2023                for old_edited_range in old_edited_ranges {
2024                    let suggestions = request
2025                        .before_edit
2026                        .suggest_autoindents(old_edited_range.clone())
2027                        .into_iter()
2028                        .flatten();
2029                    for (old_row, suggestion) in old_edited_range.zip(suggestions) {
2030                        if let Some(suggestion) = suggestion {
2031                            let new_row = *old_to_new_rows.get(&old_row).unwrap();
2032
2033                            // Find the indent size based on the language for this row.
2034                            while let Some((row, size)) = language_indent_sizes.peek() {
2035                                if *row > new_row {
2036                                    break;
2037                                }
2038                                language_indent_size = *size;
2039                                language_indent_sizes.next();
2040                            }
2041
2042                            let suggested_indent = old_to_new_rows
2043                                .get(&suggestion.basis_row)
2044                                .and_then(|from_row| {
2045                                    Some(old_suggestions.get(from_row).copied()?.0)
2046                                })
2047                                .unwrap_or_else(|| {
2048                                    request
2049                                        .before_edit
2050                                        .indent_size_for_line(suggestion.basis_row)
2051                                })
2052                                .with_delta(suggestion.delta, language_indent_size);
2053                            old_suggestions
2054                                .insert(new_row, (suggested_indent, suggestion.within_error));
2055                        }
2056                    }
2057                    yield_now().await;
2058                }
2059
2060                // Compute new suggestions for each line, but only include them in the result
2061                // if they differ from the old suggestion for that line.
2062                let mut language_indent_sizes = language_indent_sizes_by_new_row.iter().peekable();
2063                let mut language_indent_size = IndentSize::default();
2064                for (row_range, original_indent_column) in row_ranges {
2065                    let new_edited_row_range = if request.is_block_mode {
2066                        row_range.start..row_range.start + 1
2067                    } else {
2068                        row_range.clone()
2069                    };
2070
2071                    let suggestions = snapshot
2072                        .suggest_autoindents(new_edited_row_range.clone())
2073                        .into_iter()
2074                        .flatten();
2075                    for (new_row, suggestion) in new_edited_row_range.zip(suggestions) {
2076                        if let Some(suggestion) = suggestion {
2077                            // Find the indent size based on the language for this row.
2078                            while let Some((row, size)) = language_indent_sizes.peek() {
2079                                if *row > new_row {
2080                                    break;
2081                                }
2082                                language_indent_size = *size;
2083                                language_indent_sizes.next();
2084                            }
2085
2086                            let suggested_indent = indent_sizes
2087                                .get(&suggestion.basis_row)
2088                                .copied()
2089                                .map(|e| e.0)
2090                                .unwrap_or_else(|| {
2091                                    snapshot.indent_size_for_line(suggestion.basis_row)
2092                                })
2093                                .with_delta(suggestion.delta, language_indent_size);
2094
2095                            if old_suggestions.get(&new_row).is_none_or(
2096                                |(old_indentation, was_within_error)| {
2097                                    suggested_indent != *old_indentation
2098                                        && (!suggestion.within_error || *was_within_error)
2099                                },
2100                            ) {
2101                                indent_sizes.insert(
2102                                    new_row,
2103                                    (suggested_indent, request.ignore_empty_lines),
2104                                );
2105                            }
2106                        }
2107                    }
2108
2109                    if let (true, Some(original_indent_column)) =
2110                        (request.is_block_mode, original_indent_column)
2111                    {
2112                        let new_indent =
2113                            if let Some((indent, _)) = indent_sizes.get(&row_range.start) {
2114                                *indent
2115                            } else {
2116                                snapshot.indent_size_for_line(row_range.start)
2117                            };
2118                        let delta = new_indent.len as i64 - original_indent_column as i64;
2119                        if delta != 0 {
2120                            for row in row_range.skip(1) {
2121                                indent_sizes.entry(row).or_insert_with(|| {
2122                                    let mut size = snapshot.indent_size_for_line(row);
2123                                    if size.kind == new_indent.kind {
2124                                        match delta.cmp(&0) {
2125                                            Ordering::Greater => size.len += delta as u32,
2126                                            Ordering::Less => {
2127                                                size.len = size.len.saturating_sub(-delta as u32)
2128                                            }
2129                                            Ordering::Equal => {}
2130                                        }
2131                                    }
2132                                    (size, request.ignore_empty_lines)
2133                                });
2134                            }
2135                        }
2136                    }
2137
2138                    yield_now().await;
2139                }
2140            }
2141
2142            indent_sizes
2143                .into_iter()
2144                .filter_map(|(row, (indent, ignore_empty_lines))| {
2145                    if ignore_empty_lines && snapshot.line_len(row) == 0 {
2146                        None
2147                    } else {
2148                        Some((row, indent))
2149                    }
2150                })
2151                .collect()
2152        })
2153    }
2154
2155    fn apply_autoindents(
2156        &mut self,
2157        indent_sizes: BTreeMap<u32, IndentSize>,
2158        cx: &mut Context<Self>,
2159    ) {
2160        self.autoindent_requests.clear();
2161        for tx in self.wait_for_autoindent_txs.drain(..) {
2162            tx.send(()).ok();
2163        }
2164
2165        let edits: Vec<_> = indent_sizes
2166            .into_iter()
2167            .filter_map(|(row, indent_size)| {
2168                let current_size = indent_size_for_line(self, row);
2169                Self::edit_for_indent_size_adjustment(row, current_size, indent_size)
2170            })
2171            .collect();
2172
2173        let preserve_preview = self.preserve_preview();
2174        self.edit(edits, None, cx);
2175        if preserve_preview {
2176            self.refresh_preview();
2177        }
2178    }
2179
2180    /// Create a minimal edit that will cause the given row to be indented
2181    /// with the given size. After applying this edit, the length of the line
2182    /// will always be at least `new_size.len`.
2183    pub fn edit_for_indent_size_adjustment(
2184        row: u32,
2185        current_size: IndentSize,
2186        new_size: IndentSize,
2187    ) -> Option<(Range<Point>, String)> {
2188        if new_size.kind == current_size.kind {
2189            match new_size.len.cmp(&current_size.len) {
2190                Ordering::Greater => {
2191                    let point = Point::new(row, 0);
2192                    Some((
2193                        point..point,
2194                        iter::repeat(new_size.char())
2195                            .take((new_size.len - current_size.len) as usize)
2196                            .collect::<String>(),
2197                    ))
2198                }
2199
2200                Ordering::Less => Some((
2201                    Point::new(row, 0)..Point::new(row, current_size.len - new_size.len),
2202                    String::new(),
2203                )),
2204
2205                Ordering::Equal => None,
2206            }
2207        } else {
2208            Some((
2209                Point::new(row, 0)..Point::new(row, current_size.len),
2210                iter::repeat(new_size.char())
2211                    .take(new_size.len as usize)
2212                    .collect::<String>(),
2213            ))
2214        }
2215    }
2216
2217    /// Spawns a background task that asynchronously computes a `Diff` between the buffer's text
2218    /// and the given new text.
2219    pub fn diff<T>(&self, new_text: T, cx: &App) -> Task<Diff>
2220    where
2221        T: AsRef<str> + Send + 'static,
2222    {
2223        let old_text = self.as_rope().clone();
2224        let base_version = self.version();
2225        cx.background_spawn(async move {
2226            let old_text = old_text.to_string();
2227            let mut new_text = new_text.as_ref().to_owned();
2228            let line_ending = LineEnding::detect(&new_text);
2229            LineEnding::normalize(&mut new_text);
2230            let edits = text_diff(&old_text, &new_text);
2231            Diff {
2232                base_version,
2233                line_ending,
2234                edits,
2235            }
2236        })
2237    }
2238
2239    /// Spawns a background task that searches the buffer for any whitespace
2240    /// at the ends of a lines, and returns a `Diff` that removes that whitespace.
2241    pub fn remove_trailing_whitespace(&self, cx: &App) -> Task<Diff> {
2242        let old_text = self.as_rope().clone();
2243        let line_ending = self.line_ending();
2244        let base_version = self.version();
2245        cx.background_spawn(async move {
2246            let ranges = trailing_whitespace_ranges(&old_text);
2247            let empty = Arc::<str>::from("");
2248            Diff {
2249                base_version,
2250                line_ending,
2251                edits: ranges
2252                    .into_iter()
2253                    .map(|range| (range, empty.clone()))
2254                    .collect(),
2255            }
2256        })
2257    }
2258
2259    /// Ensures that the buffer ends with a single newline character, and
2260    /// no other whitespace. Skips if the buffer is empty.
2261    pub fn ensure_final_newline(&mut self, cx: &mut Context<Self>) {
2262        let len = self.len();
2263        if len == 0 {
2264            return;
2265        }
2266        let mut offset = len;
2267        for chunk in self.as_rope().reversed_chunks_in_range(0..len) {
2268            let non_whitespace_len = chunk
2269                .trim_end_matches(|c: char| c.is_ascii_whitespace())
2270                .len();
2271            offset -= chunk.len();
2272            offset += non_whitespace_len;
2273            if non_whitespace_len != 0 {
2274                if offset == len - 1 && chunk.get(non_whitespace_len..) == Some("\n") {
2275                    return;
2276                }
2277                break;
2278            }
2279        }
2280        self.edit([(offset..len, "\n")], None, cx);
2281    }
2282
2283    /// Applies a diff to the buffer. If the buffer has changed since the given diff was
2284    /// calculated, then adjust the diff to account for those changes, and discard any
2285    /// parts of the diff that conflict with those changes.
2286    pub fn apply_diff(&mut self, diff: Diff, cx: &mut Context<Self>) -> Option<TransactionId> {
2287        let snapshot = self.snapshot();
2288        let mut edits_since = snapshot.edits_since::<usize>(&diff.base_version).peekable();
2289        let mut delta = 0;
2290        let adjusted_edits = diff.edits.into_iter().filter_map(|(range, new_text)| {
2291            while let Some(edit_since) = edits_since.peek() {
2292                // If the edit occurs after a diff hunk, then it does not
2293                // affect that hunk.
2294                if edit_since.old.start > range.end {
2295                    break;
2296                }
2297                // If the edit precedes the diff hunk, then adjust the hunk
2298                // to reflect the edit.
2299                else if edit_since.old.end < range.start {
2300                    delta += edit_since.new_len() as i64 - edit_since.old_len() as i64;
2301                    edits_since.next();
2302                }
2303                // If the edit intersects a diff hunk, then discard that hunk.
2304                else {
2305                    return None;
2306                }
2307            }
2308
2309            let start = (range.start as i64 + delta) as usize;
2310            let end = (range.end as i64 + delta) as usize;
2311            Some((start..end, new_text))
2312        });
2313
2314        self.start_transaction();
2315        self.text.set_line_ending(diff.line_ending);
2316        self.edit(adjusted_edits, None, cx);
2317        self.end_transaction(cx)
2318    }
2319
2320    pub fn has_unsaved_edits(&self) -> bool {
2321        let (last_version, has_unsaved_edits) = self.has_unsaved_edits.take();
2322
2323        if last_version == self.version {
2324            self.has_unsaved_edits
2325                .set((last_version, has_unsaved_edits));
2326            return has_unsaved_edits;
2327        }
2328
2329        let has_edits = self.has_edits_since(&self.saved_version);
2330        self.has_unsaved_edits
2331            .set((self.version.clone(), has_edits));
2332        has_edits
2333    }
2334
2335    /// Checks if the buffer has unsaved changes.
2336    pub fn is_dirty(&self) -> bool {
2337        if self.capability == Capability::ReadOnly {
2338            return false;
2339        }
2340        if self.has_conflict {
2341            return true;
2342        }
2343        match self.file.as_ref().map(|f| f.disk_state()) {
2344            Some(DiskState::New) | Some(DiskState::Deleted) => {
2345                !self.is_empty() && self.has_unsaved_edits()
2346            }
2347            _ => self.has_unsaved_edits(),
2348        }
2349    }
2350
2351    /// Marks the buffer as having a conflict regardless of current buffer state.
2352    pub fn set_conflict(&mut self) {
2353        self.has_conflict = true;
2354    }
2355
2356    /// Checks if the buffer and its file have both changed since the buffer
2357    /// was last saved or reloaded.
2358    pub fn has_conflict(&self) -> bool {
2359        if self.has_conflict {
2360            return true;
2361        }
2362        let Some(file) = self.file.as_ref() else {
2363            return false;
2364        };
2365        match file.disk_state() {
2366            DiskState::New => false,
2367            DiskState::Present { mtime, .. } => match self.saved_mtime {
2368                Some(saved_mtime) => {
2369                    mtime.bad_is_greater_than(saved_mtime) && self.has_unsaved_edits()
2370                }
2371                None => true,
2372            },
2373            DiskState::Deleted => false,
2374            DiskState::Historic { .. } => false,
2375        }
2376    }
2377
2378    /// Gets a [`Subscription`] that tracks all of the changes to the buffer's text.
2379    pub fn subscribe(&mut self) -> Subscription<usize> {
2380        self.text.subscribe()
2381    }
2382
2383    /// Adds a bit to the list of bits that are set when the buffer's text changes.
2384    ///
2385    /// This allows downstream code to check if the buffer's text has changed without
2386    /// waiting for an effect cycle, which would be required if using eents.
2387    pub fn record_changes(&mut self, bit: rc::Weak<Cell<bool>>) {
2388        if let Err(ix) = self
2389            .change_bits
2390            .binary_search_by_key(&rc::Weak::as_ptr(&bit), rc::Weak::as_ptr)
2391        {
2392            self.change_bits.insert(ix, bit);
2393        }
2394    }
2395
2396    /// Set the change bit for all "listeners".
2397    fn was_changed(&mut self) {
2398        self.change_bits.retain(|change_bit| {
2399            change_bit
2400                .upgrade()
2401                .inspect(|bit| {
2402                    _ = bit.replace(true);
2403                })
2404                .is_some()
2405        });
2406    }
2407
2408    /// Starts a transaction, if one is not already in-progress. When undoing or
2409    /// redoing edits, all of the edits performed within a transaction are undone
2410    /// or redone together.
2411    pub fn start_transaction(&mut self) -> Option<TransactionId> {
2412        self.start_transaction_at(Instant::now())
2413    }
2414
2415    /// Starts a transaction, providing the current time. Subsequent transactions
2416    /// that occur within a short period of time will be grouped together. This
2417    /// is controlled by the buffer's undo grouping duration.
2418    pub fn start_transaction_at(&mut self, now: Instant) -> Option<TransactionId> {
2419        self.transaction_depth += 1;
2420        if self.was_dirty_before_starting_transaction.is_none() {
2421            self.was_dirty_before_starting_transaction = Some(self.is_dirty());
2422        }
2423        self.text.start_transaction_at(now)
2424    }
2425
2426    /// Terminates the current transaction, if this is the outermost transaction.
2427    pub fn end_transaction(&mut self, cx: &mut Context<Self>) -> Option<TransactionId> {
2428        self.end_transaction_at(Instant::now(), cx)
2429    }
2430
2431    /// Terminates the current transaction, providing the current time. Subsequent transactions
2432    /// that occur within a short period of time will be grouped together. This
2433    /// is controlled by the buffer's undo grouping duration.
2434    pub fn end_transaction_at(
2435        &mut self,
2436        now: Instant,
2437        cx: &mut Context<Self>,
2438    ) -> Option<TransactionId> {
2439        assert!(self.transaction_depth > 0);
2440        self.transaction_depth -= 1;
2441        let was_dirty = if self.transaction_depth == 0 {
2442            self.was_dirty_before_starting_transaction.take().unwrap()
2443        } else {
2444            false
2445        };
2446        if let Some((transaction_id, start_version)) = self.text.end_transaction_at(now) {
2447            self.did_edit(&start_version, was_dirty, true, cx);
2448            Some(transaction_id)
2449        } else {
2450            None
2451        }
2452    }
2453
2454    /// Manually add a transaction to the buffer's undo history.
2455    pub fn push_transaction(&mut self, transaction: Transaction, now: Instant) {
2456        self.text.push_transaction(transaction, now);
2457    }
2458
2459    /// Differs from `push_transaction` in that it does not clear the redo
2460    /// stack. Intended to be used to create a parent transaction to merge
2461    /// potential child transactions into.
2462    ///
2463    /// The caller is responsible for removing it from the undo history using
2464    /// `forget_transaction` if no edits are merged into it. Otherwise, if edits
2465    /// are merged into this transaction, the caller is responsible for ensuring
2466    /// the redo stack is cleared. The easiest way to ensure the redo stack is
2467    /// cleared is to create transactions with the usual `start_transaction` and
2468    /// `end_transaction` methods and merging the resulting transactions into
2469    /// the transaction created by this method
2470    pub fn push_empty_transaction(&mut self, now: Instant) -> TransactionId {
2471        self.text.push_empty_transaction(now)
2472    }
2473
2474    /// Prevent the last transaction from being grouped with any subsequent transactions,
2475    /// even if they occur with the buffer's undo grouping duration.
2476    pub fn finalize_last_transaction(&mut self) -> Option<&Transaction> {
2477        self.text.finalize_last_transaction()
2478    }
2479
2480    /// Manually group all changes since a given transaction.
2481    pub fn group_until_transaction(&mut self, transaction_id: TransactionId) {
2482        self.text.group_until_transaction(transaction_id);
2483    }
2484
2485    /// Manually remove a transaction from the buffer's undo history
2486    pub fn forget_transaction(&mut self, transaction_id: TransactionId) -> Option<Transaction> {
2487        self.text.forget_transaction(transaction_id)
2488    }
2489
2490    /// Retrieve a transaction from the buffer's undo history
2491    pub fn get_transaction(&self, transaction_id: TransactionId) -> Option<&Transaction> {
2492        self.text.get_transaction(transaction_id)
2493    }
2494
2495    /// Manually merge two transactions in the buffer's undo history.
2496    pub fn merge_transactions(&mut self, transaction: TransactionId, destination: TransactionId) {
2497        self.text.merge_transactions(transaction, destination);
2498    }
2499
2500    /// Waits for the buffer to receive operations with the given timestamps.
2501    pub fn wait_for_edits<It: IntoIterator<Item = clock::Lamport>>(
2502        &mut self,
2503        edit_ids: It,
2504    ) -> impl Future<Output = Result<()>> + use<It> {
2505        self.text.wait_for_edits(edit_ids)
2506    }
2507
2508    /// Waits for the buffer to receive the operations necessary for resolving the given anchors.
2509    pub fn wait_for_anchors<It: IntoIterator<Item = Anchor>>(
2510        &mut self,
2511        anchors: It,
2512    ) -> impl 'static + Future<Output = Result<()>> + use<It> {
2513        self.text.wait_for_anchors(anchors)
2514    }
2515
2516    /// Waits for the buffer to receive operations up to the given version.
2517    pub fn wait_for_version(
2518        &mut self,
2519        version: clock::Global,
2520    ) -> impl Future<Output = Result<()>> + use<> {
2521        self.text.wait_for_version(version)
2522    }
2523
2524    /// Forces all futures returned by [`Buffer::wait_for_version`], [`Buffer::wait_for_edits`], or
2525    /// [`Buffer::wait_for_version`] to resolve with an error.
2526    pub fn give_up_waiting(&mut self) {
2527        self.text.give_up_waiting();
2528    }
2529
2530    pub fn wait_for_autoindent_applied(&mut self) -> Option<oneshot::Receiver<()>> {
2531        let mut rx = None;
2532        if !self.autoindent_requests.is_empty() {
2533            let channel = oneshot::channel();
2534            self.wait_for_autoindent_txs.push(channel.0);
2535            rx = Some(channel.1);
2536        }
2537        rx
2538    }
2539
2540    /// Stores a set of selections that should be broadcasted to all of the buffer's replicas.
2541    pub fn set_active_selections(
2542        &mut self,
2543        selections: Arc<[Selection<Anchor>]>,
2544        line_mode: bool,
2545        cursor_shape: CursorShape,
2546        cx: &mut Context<Self>,
2547    ) {
2548        let lamport_timestamp = self.text.lamport_clock.tick();
2549        self.remote_selections.insert(
2550            self.text.replica_id(),
2551            SelectionSet {
2552                selections: selections.clone(),
2553                lamport_timestamp,
2554                line_mode,
2555                cursor_shape,
2556            },
2557        );
2558        self.send_operation(
2559            Operation::UpdateSelections {
2560                selections,
2561                line_mode,
2562                lamport_timestamp,
2563                cursor_shape,
2564            },
2565            true,
2566            cx,
2567        );
2568        self.non_text_state_update_count += 1;
2569        cx.notify();
2570    }
2571
2572    /// Clears the selections, so that other replicas of the buffer do not see any selections for
2573    /// this replica.
2574    pub fn remove_active_selections(&mut self, cx: &mut Context<Self>) {
2575        if self
2576            .remote_selections
2577            .get(&self.text.replica_id())
2578            .is_none_or(|set| !set.selections.is_empty())
2579        {
2580            self.set_active_selections(Arc::default(), false, Default::default(), cx);
2581        }
2582    }
2583
2584    pub fn set_agent_selections(
2585        &mut self,
2586        selections: Arc<[Selection<Anchor>]>,
2587        line_mode: bool,
2588        cursor_shape: CursorShape,
2589        cx: &mut Context<Self>,
2590    ) {
2591        let lamport_timestamp = self.text.lamport_clock.tick();
2592        self.remote_selections.insert(
2593            ReplicaId::AGENT,
2594            SelectionSet {
2595                selections,
2596                lamport_timestamp,
2597                line_mode,
2598                cursor_shape,
2599            },
2600        );
2601        self.non_text_state_update_count += 1;
2602        cx.notify();
2603    }
2604
2605    pub fn remove_agent_selections(&mut self, cx: &mut Context<Self>) {
2606        self.set_agent_selections(Arc::default(), false, Default::default(), cx);
2607    }
2608
2609    /// Replaces the buffer's entire text.
2610    pub fn set_text<T>(&mut self, text: T, cx: &mut Context<Self>) -> Option<clock::Lamport>
2611    where
2612        T: Into<Arc<str>>,
2613    {
2614        self.autoindent_requests.clear();
2615        self.edit([(0..self.len(), text)], None, cx)
2616    }
2617
2618    /// Appends the given text to the end of the buffer.
2619    pub fn append<T>(&mut self, text: T, cx: &mut Context<Self>) -> Option<clock::Lamport>
2620    where
2621        T: Into<Arc<str>>,
2622    {
2623        self.edit([(self.len()..self.len(), text)], None, cx)
2624    }
2625
2626    /// Applies the given edits to the buffer. Each edit is specified as a range of text to
2627    /// delete, and a string of text to insert at that location. Adjacent edits are coalesced.
2628    ///
2629    /// If an [`AutoindentMode`] is provided, then the buffer will enqueue an auto-indent
2630    /// request for the edited ranges, which will be processed when the buffer finishes
2631    /// parsing.
2632    ///
2633    /// Parsing takes place at the end of a transaction, and may compute synchronously
2634    /// or asynchronously, depending on the changes.
2635    pub fn edit<I, S, T>(
2636        &mut self,
2637        edits_iter: I,
2638        autoindent_mode: Option<AutoindentMode>,
2639        cx: &mut Context<Self>,
2640    ) -> Option<clock::Lamport>
2641    where
2642        I: IntoIterator<Item = (Range<S>, T)>,
2643        S: ToOffset,
2644        T: Into<Arc<str>>,
2645    {
2646        self.edit_internal(edits_iter, autoindent_mode, true, cx)
2647    }
2648
2649    /// Like [`edit`](Self::edit), but does not coalesce adjacent edits.
2650    pub fn edit_non_coalesce<I, S, T>(
2651        &mut self,
2652        edits_iter: I,
2653        autoindent_mode: Option<AutoindentMode>,
2654        cx: &mut Context<Self>,
2655    ) -> Option<clock::Lamport>
2656    where
2657        I: IntoIterator<Item = (Range<S>, T)>,
2658        S: ToOffset,
2659        T: Into<Arc<str>>,
2660    {
2661        self.edit_internal(edits_iter, autoindent_mode, false, cx)
2662    }
2663
2664    fn edit_internal<I, S, T>(
2665        &mut self,
2666        edits_iter: I,
2667        autoindent_mode: Option<AutoindentMode>,
2668        coalesce_adjacent: bool,
2669        cx: &mut Context<Self>,
2670    ) -> Option<clock::Lamport>
2671    where
2672        I: IntoIterator<Item = (Range<S>, T)>,
2673        S: ToOffset,
2674        T: Into<Arc<str>>,
2675    {
2676        // Skip invalid edits and coalesce contiguous ones.
2677        let mut edits: Vec<(Range<usize>, Arc<str>)> = Vec::new();
2678
2679        for (range, new_text) in edits_iter {
2680            let mut range = range.start.to_offset(self)..range.end.to_offset(self);
2681
2682            if range.start > range.end {
2683                mem::swap(&mut range.start, &mut range.end);
2684            }
2685            let new_text = new_text.into();
2686            if !new_text.is_empty() || !range.is_empty() {
2687                let prev_edit = edits.last_mut();
2688                let should_coalesce = prev_edit.as_ref().is_some_and(|(prev_range, _)| {
2689                    if coalesce_adjacent {
2690                        prev_range.end >= range.start
2691                    } else {
2692                        prev_range.end > range.start
2693                    }
2694                });
2695
2696                if let Some((prev_range, prev_text)) = prev_edit
2697                    && should_coalesce
2698                {
2699                    prev_range.end = cmp::max(prev_range.end, range.end);
2700                    *prev_text = format!("{prev_text}{new_text}").into();
2701                } else {
2702                    edits.push((range, new_text));
2703                }
2704            }
2705        }
2706        if edits.is_empty() {
2707            return None;
2708        }
2709
2710        self.start_transaction();
2711        self.pending_autoindent.take();
2712        let autoindent_request = autoindent_mode
2713            .and_then(|mode| self.language.as_ref().map(|_| (self.snapshot(), mode)));
2714
2715        let edit_operation = self.text.edit(edits.iter().cloned());
2716        let edit_id = edit_operation.timestamp();
2717
2718        if let Some((before_edit, mode)) = autoindent_request {
2719            let mut delta = 0isize;
2720            let mut previous_setting = None;
2721            let entries: Vec<_> = edits
2722                .into_iter()
2723                .enumerate()
2724                .zip(&edit_operation.as_edit().unwrap().new_text)
2725                .filter(|((_, (range, _)), _)| {
2726                    let language = before_edit.language_at(range.start);
2727                    let language_id = language.map(|l| l.id());
2728                    if let Some((cached_language_id, apply_syntax_indent)) = previous_setting
2729                        && cached_language_id == language_id
2730                    {
2731                        apply_syntax_indent
2732                    } else {
2733                        // The auto-indent setting is not present in editorconfigs, hence
2734                        // we can avoid passing the file here.
2735                        let auto_indent_mode = LanguageSettings::resolve(
2736                            None,
2737                            language.map(|l| l.name()).as_ref(),
2738                            cx,
2739                        )
2740                        .auto_indent;
2741                        let apply_syntax_indent = auto_indent_mode == AutoIndentMode::SyntaxAware;
2742                        previous_setting = Some((language_id, apply_syntax_indent));
2743                        apply_syntax_indent
2744                    }
2745                })
2746                .map(|((ix, (range, _)), new_text)| {
2747                    let new_text_length = new_text.len();
2748                    let old_start = range.start.to_point(&before_edit);
2749                    let new_start = (delta + range.start as isize) as usize;
2750                    let range_len = range.end - range.start;
2751                    delta += new_text_length as isize - range_len as isize;
2752
2753                    // Decide what range of the insertion to auto-indent, and whether
2754                    // the first line of the insertion should be considered a newly-inserted line
2755                    // or an edit to an existing line.
2756                    let mut range_of_insertion_to_indent = 0..new_text_length;
2757                    let mut first_line_is_new = true;
2758
2759                    let old_line_start = before_edit.indent_size_for_line(old_start.row).len;
2760                    let old_line_end = before_edit.line_len(old_start.row);
2761
2762                    if old_start.column > old_line_start {
2763                        first_line_is_new = false;
2764                    }
2765
2766                    if !new_text.contains('\n')
2767                        && (old_start.column + (range_len as u32) < old_line_end
2768                            || old_line_end == old_line_start)
2769                    {
2770                        first_line_is_new = false;
2771                    }
2772
2773                    // When inserting text starting with a newline, avoid auto-indenting the
2774                    // previous line.
2775                    if new_text.starts_with('\n') {
2776                        range_of_insertion_to_indent.start += 1;
2777                        first_line_is_new = true;
2778                    }
2779
2780                    let mut original_indent_column = None;
2781                    if let AutoindentMode::Block {
2782                        original_indent_columns,
2783                    } = &mode
2784                    {
2785                        original_indent_column = Some(if new_text.starts_with('\n') {
2786                            indent_size_for_text(
2787                                new_text[range_of_insertion_to_indent.clone()].chars(),
2788                            )
2789                            .len
2790                        } else {
2791                            original_indent_columns
2792                                .get(ix)
2793                                .copied()
2794                                .flatten()
2795                                .unwrap_or_else(|| {
2796                                    indent_size_for_text(
2797                                        new_text[range_of_insertion_to_indent.clone()].chars(),
2798                                    )
2799                                    .len
2800                                })
2801                        });
2802
2803                        // Avoid auto-indenting the line after the edit.
2804                        if new_text[range_of_insertion_to_indent.clone()].ends_with('\n') {
2805                            range_of_insertion_to_indent.end -= 1;
2806                        }
2807                    }
2808
2809                    AutoindentRequestEntry {
2810                        original_indent_column,
2811                        old_row: if first_line_is_new {
2812                            None
2813                        } else {
2814                            Some(old_start.row)
2815                        },
2816                        indent_size: before_edit.language_indent_size_at(range.start, cx),
2817                        range: self.anchor_before(new_start + range_of_insertion_to_indent.start)
2818                            ..self.anchor_after(new_start + range_of_insertion_to_indent.end),
2819                    }
2820                })
2821                .collect();
2822
2823            if !entries.is_empty() {
2824                self.autoindent_requests.push(Arc::new(AutoindentRequest {
2825                    before_edit,
2826                    entries,
2827                    is_block_mode: matches!(mode, AutoindentMode::Block { .. }),
2828                    ignore_empty_lines: false,
2829                }));
2830            }
2831        }
2832
2833        self.end_transaction(cx);
2834        self.send_operation(Operation::Buffer(edit_operation), true, cx);
2835        Some(edit_id)
2836    }
2837
2838    fn did_edit(
2839        &mut self,
2840        old_version: &clock::Global,
2841        was_dirty: bool,
2842        is_local: bool,
2843        cx: &mut Context<Self>,
2844    ) {
2845        self.was_changed();
2846
2847        if self.edits_since::<usize>(old_version).next().is_none() {
2848            return;
2849        }
2850
2851        self.reparse(cx, true);
2852        cx.emit(BufferEvent::Edited { is_local });
2853        let is_dirty = self.is_dirty();
2854        if was_dirty != is_dirty {
2855            cx.emit(BufferEvent::DirtyChanged);
2856        }
2857        if was_dirty && !is_dirty {
2858            if let Some(file) = self.file.as_ref() {
2859                if matches!(file.disk_state(), DiskState::Present { .. })
2860                    && file.disk_state().mtime() != self.saved_mtime
2861                {
2862                    cx.emit(BufferEvent::ReloadNeeded);
2863                }
2864            }
2865        }
2866        cx.notify();
2867    }
2868
2869    pub fn autoindent_ranges<I, T>(&mut self, ranges: I, cx: &mut Context<Self>)
2870    where
2871        I: IntoIterator<Item = Range<T>>,
2872        T: ToOffset + Copy,
2873    {
2874        let before_edit = self.snapshot();
2875        let entries = ranges
2876            .into_iter()
2877            .map(|range| AutoindentRequestEntry {
2878                range: before_edit.anchor_before(range.start)..before_edit.anchor_after(range.end),
2879                old_row: None,
2880                indent_size: before_edit.language_indent_size_at(range.start, cx),
2881                original_indent_column: None,
2882            })
2883            .collect();
2884        self.autoindent_requests.push(Arc::new(AutoindentRequest {
2885            before_edit,
2886            entries,
2887            is_block_mode: false,
2888            ignore_empty_lines: true,
2889        }));
2890        self.request_autoindent(cx, Some(Duration::from_micros(300)));
2891    }
2892
2893    // Inserts newlines at the given position to create an empty line, returning the start of the new line.
2894    // You can also request the insertion of empty lines above and below the line starting at the returned point.
2895    pub fn insert_empty_line(
2896        &mut self,
2897        position: impl ToPoint,
2898        space_above: bool,
2899        space_below: bool,
2900        cx: &mut Context<Self>,
2901    ) -> Point {
2902        let mut position = position.to_point(self);
2903
2904        self.start_transaction();
2905
2906        self.edit(
2907            [(position..position, "\n")],
2908            Some(AutoindentMode::EachLine),
2909            cx,
2910        );
2911
2912        if position.column > 0 {
2913            position += Point::new(1, 0);
2914        }
2915
2916        if !self.is_line_blank(position.row) {
2917            self.edit(
2918                [(position..position, "\n")],
2919                Some(AutoindentMode::EachLine),
2920                cx,
2921            );
2922        }
2923
2924        if space_above && position.row > 0 && !self.is_line_blank(position.row - 1) {
2925            self.edit(
2926                [(position..position, "\n")],
2927                Some(AutoindentMode::EachLine),
2928                cx,
2929            );
2930            position.row += 1;
2931        }
2932
2933        if space_below
2934            && (position.row == self.max_point().row || !self.is_line_blank(position.row + 1))
2935        {
2936            self.edit(
2937                [(position..position, "\n")],
2938                Some(AutoindentMode::EachLine),
2939                cx,
2940            );
2941        }
2942
2943        self.end_transaction(cx);
2944
2945        position
2946    }
2947
2948    /// Applies the given remote operations to the buffer.
2949    pub fn apply_ops<I: IntoIterator<Item = Operation>>(&mut self, ops: I, cx: &mut Context<Self>) {
2950        self.pending_autoindent.take();
2951        let was_dirty = self.is_dirty();
2952        let old_version = self.version.clone();
2953        let mut deferred_ops = Vec::new();
2954        let buffer_ops = ops
2955            .into_iter()
2956            .filter_map(|op| match op {
2957                Operation::Buffer(op) => Some(op),
2958                _ => {
2959                    if self.can_apply_op(&op) {
2960                        self.apply_op(op, cx);
2961                    } else {
2962                        deferred_ops.push(op);
2963                    }
2964                    None
2965                }
2966            })
2967            .collect::<Vec<_>>();
2968        for operation in buffer_ops.iter() {
2969            self.send_operation(Operation::Buffer(operation.clone()), false, cx);
2970        }
2971        self.text.apply_ops(buffer_ops);
2972        self.deferred_ops.insert(deferred_ops);
2973        self.flush_deferred_ops(cx);
2974        self.did_edit(&old_version, was_dirty, false, cx);
2975        // Notify independently of whether the buffer was edited as the operations could include a
2976        // selection update.
2977        cx.notify();
2978    }
2979
2980    fn flush_deferred_ops(&mut self, cx: &mut Context<Self>) {
2981        let mut deferred_ops = Vec::new();
2982        for op in self.deferred_ops.drain().iter().cloned() {
2983            if self.can_apply_op(&op) {
2984                self.apply_op(op, cx);
2985            } else {
2986                deferred_ops.push(op);
2987            }
2988        }
2989        self.deferred_ops.insert(deferred_ops);
2990    }
2991
2992    pub fn has_deferred_ops(&self) -> bool {
2993        !self.deferred_ops.is_empty() || self.text.has_deferred_ops()
2994    }
2995
2996    fn can_apply_op(&self, operation: &Operation) -> bool {
2997        match operation {
2998            Operation::Buffer(_) => {
2999                unreachable!("buffer operations should never be applied at this layer")
3000            }
3001            Operation::UpdateDiagnostics {
3002                diagnostics: diagnostic_set,
3003                ..
3004            } => diagnostic_set.iter().all(|diagnostic| {
3005                self.text.can_resolve(&diagnostic.range.start)
3006                    && self.text.can_resolve(&diagnostic.range.end)
3007            }),
3008            Operation::UpdateSelections { selections, .. } => selections
3009                .iter()
3010                .all(|s| self.can_resolve(&s.start) && self.can_resolve(&s.end)),
3011            Operation::UpdateCompletionTriggers { .. } | Operation::UpdateLineEnding { .. } => true,
3012        }
3013    }
3014
3015    fn apply_op(&mut self, operation: Operation, cx: &mut Context<Self>) {
3016        match operation {
3017            Operation::Buffer(_) => {
3018                unreachable!("buffer operations should never be applied at this layer")
3019            }
3020            Operation::UpdateDiagnostics {
3021                server_id,
3022                diagnostics: diagnostic_set,
3023                lamport_timestamp,
3024            } => {
3025                let snapshot = self.snapshot();
3026                self.apply_diagnostic_update(
3027                    server_id,
3028                    DiagnosticSet::from_sorted_entries(diagnostic_set.iter().cloned(), &snapshot),
3029                    lamport_timestamp,
3030                    cx,
3031                );
3032            }
3033            Operation::UpdateSelections {
3034                selections,
3035                lamport_timestamp,
3036                line_mode,
3037                cursor_shape,
3038            } => {
3039                if let Some(set) = self.remote_selections.get(&lamport_timestamp.replica_id)
3040                    && set.lamport_timestamp > lamport_timestamp
3041                {
3042                    return;
3043                }
3044
3045                self.remote_selections.insert(
3046                    lamport_timestamp.replica_id,
3047                    SelectionSet {
3048                        selections,
3049                        lamport_timestamp,
3050                        line_mode,
3051                        cursor_shape,
3052                    },
3053                );
3054                self.text.lamport_clock.observe(lamport_timestamp);
3055                self.non_text_state_update_count += 1;
3056            }
3057            Operation::UpdateCompletionTriggers {
3058                triggers,
3059                lamport_timestamp,
3060                server_id,
3061            } => {
3062                if triggers.is_empty() {
3063                    self.completion_triggers_per_language_server
3064                        .remove(&server_id);
3065                    self.completion_triggers = self
3066                        .completion_triggers_per_language_server
3067                        .values()
3068                        .flat_map(|triggers| triggers.iter().cloned())
3069                        .collect();
3070                } else {
3071                    self.completion_triggers_per_language_server
3072                        .insert(server_id, triggers.iter().cloned().collect());
3073                    self.completion_triggers.extend(triggers);
3074                }
3075                self.text.lamport_clock.observe(lamport_timestamp);
3076            }
3077            Operation::UpdateLineEnding {
3078                line_ending,
3079                lamport_timestamp,
3080            } => {
3081                self.text.set_line_ending(line_ending);
3082                self.text.lamport_clock.observe(lamport_timestamp);
3083            }
3084        }
3085    }
3086
3087    fn apply_diagnostic_update(
3088        &mut self,
3089        server_id: LanguageServerId,
3090        diagnostics: DiagnosticSet,
3091        lamport_timestamp: clock::Lamport,
3092        cx: &mut Context<Self>,
3093    ) {
3094        if lamport_timestamp > self.diagnostics_timestamp {
3095            if diagnostics.is_empty() {
3096                self.diagnostics.remove(&server_id);
3097            } else {
3098                self.diagnostics.insert(server_id, diagnostics);
3099            }
3100            self.diagnostics_timestamp = lamport_timestamp;
3101            self.non_text_state_update_count += 1;
3102            self.text.lamport_clock.observe(lamport_timestamp);
3103            cx.notify();
3104            cx.emit(BufferEvent::DiagnosticsUpdated);
3105        }
3106    }
3107
3108    fn send_operation(&mut self, operation: Operation, is_local: bool, cx: &mut Context<Self>) {
3109        self.was_changed();
3110        cx.emit(BufferEvent::Operation {
3111            operation,
3112            is_local,
3113        });
3114    }
3115
3116    /// Removes the selections for a given peer.
3117    pub fn remove_peer(&mut self, replica_id: ReplicaId, cx: &mut Context<Self>) {
3118        self.remote_selections.remove(&replica_id);
3119        cx.notify();
3120    }
3121
3122    /// Undoes the most recent transaction.
3123    pub fn undo(&mut self, cx: &mut Context<Self>) -> Option<TransactionId> {
3124        let was_dirty = self.is_dirty();
3125        let old_version = self.version.clone();
3126
3127        if let Some((transaction_id, operation)) = self.text.undo() {
3128            self.send_operation(Operation::Buffer(operation), true, cx);
3129            self.did_edit(&old_version, was_dirty, true, cx);
3130            self.restore_encoding_for_transaction(transaction_id, was_dirty);
3131            Some(transaction_id)
3132        } else {
3133            None
3134        }
3135    }
3136
3137    /// Manually undoes a specific transaction in the buffer's undo history.
3138    pub fn undo_transaction(
3139        &mut self,
3140        transaction_id: TransactionId,
3141        cx: &mut Context<Self>,
3142    ) -> bool {
3143        let was_dirty = self.is_dirty();
3144        let old_version = self.version.clone();
3145        if let Some(operation) = self.text.undo_transaction(transaction_id) {
3146            self.send_operation(Operation::Buffer(operation), true, cx);
3147            self.did_edit(&old_version, was_dirty, true, cx);
3148            true
3149        } else {
3150            false
3151        }
3152    }
3153
3154    /// Manually undoes all changes after a given transaction in the buffer's undo history.
3155    pub fn undo_to_transaction(
3156        &mut self,
3157        transaction_id: TransactionId,
3158        cx: &mut Context<Self>,
3159    ) -> bool {
3160        let was_dirty = self.is_dirty();
3161        let old_version = self.version.clone();
3162
3163        let operations = self.text.undo_to_transaction(transaction_id);
3164        let undone = !operations.is_empty();
3165        for operation in operations {
3166            self.send_operation(Operation::Buffer(operation), true, cx);
3167        }
3168        if undone {
3169            self.did_edit(&old_version, was_dirty, true, cx)
3170        }
3171        undone
3172    }
3173
3174    pub fn undo_operations(&mut self, counts: HashMap<Lamport, u32>, cx: &mut Context<Buffer>) {
3175        let was_dirty = self.is_dirty();
3176        let operation = self.text.undo_operations(counts);
3177        let old_version = self.version.clone();
3178        self.send_operation(Operation::Buffer(operation), true, cx);
3179        self.did_edit(&old_version, was_dirty, true, cx);
3180    }
3181
3182    /// Manually redoes a specific transaction in the buffer's redo history.
3183    pub fn redo(&mut self, cx: &mut Context<Self>) -> Option<TransactionId> {
3184        let was_dirty = self.is_dirty();
3185        let old_version = self.version.clone();
3186
3187        if let Some((transaction_id, operation)) = self.text.redo() {
3188            self.send_operation(Operation::Buffer(operation), true, cx);
3189            self.did_edit(&old_version, was_dirty, true, cx);
3190            self.restore_encoding_for_transaction(transaction_id, was_dirty);
3191            Some(transaction_id)
3192        } else {
3193            None
3194        }
3195    }
3196
3197    fn restore_encoding_for_transaction(&mut self, transaction_id: TransactionId, was_dirty: bool) {
3198        if let Some((old_encoding, old_has_bom)) =
3199            self.reload_with_encoding_txns.get(&transaction_id)
3200        {
3201            let current_encoding = self.encoding;
3202            let current_has_bom = self.has_bom;
3203            self.encoding = *old_encoding;
3204            self.has_bom = *old_has_bom;
3205            if !was_dirty {
3206                self.saved_version = self.version.clone();
3207                self.has_unsaved_edits
3208                    .set((self.saved_version.clone(), false));
3209            }
3210            self.reload_with_encoding_txns
3211                .insert(transaction_id, (current_encoding, current_has_bom));
3212        }
3213    }
3214
3215    /// Manually undoes all changes until a given transaction in the buffer's redo history.
3216    pub fn redo_to_transaction(
3217        &mut self,
3218        transaction_id: TransactionId,
3219        cx: &mut Context<Self>,
3220    ) -> bool {
3221        let was_dirty = self.is_dirty();
3222        let old_version = self.version.clone();
3223
3224        let operations = self.text.redo_to_transaction(transaction_id);
3225        let redone = !operations.is_empty();
3226        for operation in operations {
3227            self.send_operation(Operation::Buffer(operation), true, cx);
3228        }
3229        if redone {
3230            self.did_edit(&old_version, was_dirty, true, cx)
3231        }
3232        redone
3233    }
3234
3235    /// Override current completion triggers with the user-provided completion triggers.
3236    pub fn set_completion_triggers(
3237        &mut self,
3238        server_id: LanguageServerId,
3239        triggers: BTreeSet<String>,
3240        cx: &mut Context<Self>,
3241    ) {
3242        self.completion_triggers_timestamp = self.text.lamport_clock.tick();
3243        if triggers.is_empty() {
3244            self.completion_triggers_per_language_server
3245                .remove(&server_id);
3246            self.completion_triggers = self
3247                .completion_triggers_per_language_server
3248                .values()
3249                .flat_map(|triggers| triggers.iter().cloned())
3250                .collect();
3251        } else {
3252            self.completion_triggers_per_language_server
3253                .insert(server_id, triggers.clone());
3254            self.completion_triggers.extend(triggers.iter().cloned());
3255        }
3256        self.send_operation(
3257            Operation::UpdateCompletionTriggers {
3258                triggers: triggers.into_iter().collect(),
3259                lamport_timestamp: self.completion_triggers_timestamp,
3260                server_id,
3261            },
3262            true,
3263            cx,
3264        );
3265        cx.notify();
3266    }
3267
3268    /// Returns a list of strings which trigger a completion menu for this language.
3269    /// Usually this is driven by LSP server which returns a list of trigger characters for completions.
3270    pub fn completion_triggers(&self) -> &BTreeSet<String> {
3271        &self.completion_triggers
3272    }
3273
3274    /// Call this directly after performing edits to prevent the preview tab
3275    /// from being dismissed by those edits. It causes `should_dismiss_preview`
3276    /// to return false until there are additional edits.
3277    pub fn refresh_preview(&mut self) {
3278        self.preview_version = self.version.clone();
3279    }
3280
3281    /// Whether we should preserve the preview status of a tab containing this buffer.
3282    pub fn preserve_preview(&self) -> bool {
3283        !self.has_edits_since(&self.preview_version)
3284    }
3285
3286    pub fn set_group_interval(&mut self, group_interval: Duration) {
3287        self.text.set_group_interval(group_interval);
3288    }
3289}
3290
3291#[doc(hidden)]
3292#[cfg(any(test, feature = "test-support"))]
3293impl Buffer {
3294    pub fn edit_via_marked_text(
3295        &mut self,
3296        marked_string: &str,
3297        autoindent_mode: Option<AutoindentMode>,
3298        cx: &mut Context<Self>,
3299    ) {
3300        let edits = self.edits_for_marked_text(marked_string);
3301        self.edit(edits, autoindent_mode, cx);
3302    }
3303
3304    pub fn randomly_edit<T>(&mut self, rng: &mut T, old_range_count: usize, cx: &mut Context<Self>)
3305    where
3306        T: rand::Rng,
3307    {
3308        let mut edits: Vec<(Range<usize>, String)> = Vec::new();
3309        let mut last_end = None;
3310        for _ in 0..old_range_count {
3311            if last_end.is_some_and(|last_end| last_end >= self.len()) {
3312                break;
3313            }
3314
3315            let new_start = last_end.map_or(0, |last_end| last_end + 1);
3316            let mut range = self.random_byte_range(new_start, rng);
3317            if rng.random_bool(0.2) {
3318                mem::swap(&mut range.start, &mut range.end);
3319            }
3320            last_end = Some(range.end);
3321
3322            let new_text_len = rng.random_range(0..10);
3323            let mut new_text: String = RandomCharIter::new(&mut *rng).take(new_text_len).collect();
3324            new_text = new_text.to_uppercase();
3325
3326            edits.push((range, new_text));
3327        }
3328        log::info!("mutating buffer {:?} with {:?}", self.replica_id(), edits);
3329        self.edit(edits, None, cx);
3330    }
3331
3332    pub fn randomly_undo_redo(&mut self, rng: &mut impl rand::Rng, cx: &mut Context<Self>) {
3333        let was_dirty = self.is_dirty();
3334        let old_version = self.version.clone();
3335
3336        let ops = self.text.randomly_undo_redo(rng);
3337        if !ops.is_empty() {
3338            for op in ops {
3339                self.send_operation(Operation::Buffer(op), true, cx);
3340                self.did_edit(&old_version, was_dirty, true, cx);
3341            }
3342        }
3343    }
3344}
3345
3346impl EventEmitter<BufferEvent> for Buffer {}
3347
3348fn offset_in_sub_ranges(
3349    sub_ranges: &[Range<Anchor>],
3350    offset: usize,
3351    snapshot: &TextBufferSnapshot,
3352) -> bool {
3353    let start_anchor = snapshot.anchor_before(offset);
3354    let end_anchor = snapshot.anchor_after(offset);
3355
3356    sub_ranges.iter().any(|sub_range| {
3357        let is_before_start = sub_range.end.cmp(&start_anchor, snapshot).is_lt();
3358        let is_after_end = sub_range.start.cmp(&end_anchor, snapshot).is_gt();
3359        !is_before_start && !is_after_end
3360    })
3361}
3362
3363impl Deref for Buffer {
3364    type Target = TextBuffer;
3365
3366    fn deref(&self) -> &Self::Target {
3367        &self.text
3368    }
3369}
3370
3371impl BufferSnapshot {
3372    /// Returns [`IndentSize`] for a given line that respects user settings and
3373    /// language preferences.
3374    pub fn indent_size_for_line(&self, row: u32) -> IndentSize {
3375        indent_size_for_line(self, row)
3376    }
3377
3378    /// Returns [`IndentSize`] for a given position that respects user settings
3379    /// and language preferences.
3380    pub fn language_indent_size_at<T: ToOffset>(&self, position: T, cx: &App) -> IndentSize {
3381        let settings = self.settings_at(position, cx);
3382        if settings.hard_tabs {
3383            IndentSize::tab()
3384        } else {
3385            IndentSize::spaces(settings.tab_size.get())
3386        }
3387    }
3388
3389    /// Retrieve the suggested indent size for all of the given rows. The unit of indentation
3390    /// is passed in as `single_indent_size`.
3391    pub fn suggested_indents(
3392        &self,
3393        rows: impl Iterator<Item = u32>,
3394        single_indent_size: IndentSize,
3395    ) -> BTreeMap<u32, IndentSize> {
3396        let mut result = BTreeMap::new();
3397
3398        for row_range in contiguous_ranges(rows, 10) {
3399            let suggestions = match self.suggest_autoindents(row_range.clone()) {
3400                Some(suggestions) => suggestions,
3401                _ => break,
3402            };
3403
3404            for (row, suggestion) in row_range.zip(suggestions) {
3405                let indent_size = if let Some(suggestion) = suggestion {
3406                    result
3407                        .get(&suggestion.basis_row)
3408                        .copied()
3409                        .unwrap_or_else(|| self.indent_size_for_line(suggestion.basis_row))
3410                        .with_delta(suggestion.delta, single_indent_size)
3411                } else {
3412                    self.indent_size_for_line(row)
3413                };
3414
3415                result.insert(row, indent_size);
3416            }
3417        }
3418
3419        result
3420    }
3421
3422    fn suggest_autoindents(
3423        &self,
3424        row_range: Range<u32>,
3425    ) -> Option<impl Iterator<Item = Option<IndentSuggestion>> + '_> {
3426        let config = &self.language.as_ref()?.config;
3427        let prev_non_blank_row = self.prev_non_blank_row(row_range.start);
3428
3429        #[derive(Debug, Clone)]
3430        struct StartPosition {
3431            start: Point,
3432            suffix: SharedString,
3433            language: Arc<Language>,
3434        }
3435
3436        // Find the suggested indentation ranges based on the syntax tree.
3437        let start = Point::new(prev_non_blank_row.unwrap_or(row_range.start), 0);
3438        let end = Point::new(row_range.end, 0);
3439        let range = (start..end).to_offset(&self.text);
3440        let mut matches = self.syntax.matches_with_options(
3441            range.clone(),
3442            &self.text,
3443            TreeSitterOptions {
3444                max_bytes_to_query: Some(MAX_BYTES_TO_QUERY),
3445                max_start_depth: None,
3446            },
3447            |grammar| Some(&grammar.indents_config.as_ref()?.query),
3448        );
3449        let indent_configs = matches
3450            .grammars()
3451            .iter()
3452            .map(|grammar| grammar.indents_config.as_ref().unwrap())
3453            .collect::<Vec<_>>();
3454
3455        let mut indent_ranges = Vec::<Range<Point>>::new();
3456        let mut start_positions = Vec::<StartPosition>::new();
3457        let mut outdent_positions = Vec::<Point>::new();
3458        while let Some(mat) = matches.peek() {
3459            let mut start: Option<Point> = None;
3460            let mut end: Option<Point> = None;
3461
3462            let config = indent_configs[mat.grammar_index];
3463            for capture in mat.captures {
3464                if capture.index == config.indent_capture_ix {
3465                    start.get_or_insert(Point::from_ts_point(capture.node.start_position()));
3466                    end.get_or_insert(Point::from_ts_point(capture.node.end_position()));
3467                } else if Some(capture.index) == config.start_capture_ix {
3468                    start = Some(Point::from_ts_point(capture.node.end_position()));
3469                } else if Some(capture.index) == config.end_capture_ix {
3470                    end = Some(Point::from_ts_point(capture.node.start_position()));
3471                } else if Some(capture.index) == config.outdent_capture_ix {
3472                    outdent_positions.push(Point::from_ts_point(capture.node.start_position()));
3473                } else if let Some(suffix) = config.suffixed_start_captures.get(&capture.index) {
3474                    start_positions.push(StartPosition {
3475                        start: Point::from_ts_point(capture.node.start_position()),
3476                        suffix: suffix.clone(),
3477                        language: mat.language.clone(),
3478                    });
3479                }
3480            }
3481
3482            matches.advance();
3483            if let Some((start, end)) = start.zip(end) {
3484                if start.row == end.row {
3485                    continue;
3486                }
3487                let range = start..end;
3488                match indent_ranges.binary_search_by_key(&range.start, |r| r.start) {
3489                    Err(ix) => indent_ranges.insert(ix, range),
3490                    Ok(ix) => {
3491                        let prev_range = &mut indent_ranges[ix];
3492                        prev_range.end = prev_range.end.max(range.end);
3493                    }
3494                }
3495            }
3496        }
3497
3498        let mut error_ranges = Vec::<Range<Point>>::new();
3499        let mut matches = self
3500            .syntax
3501            .matches(range, &self.text, |grammar| grammar.error_query.as_ref());
3502        while let Some(mat) = matches.peek() {
3503            let node = mat.captures[0].node;
3504            let start = Point::from_ts_point(node.start_position());
3505            let end = Point::from_ts_point(node.end_position());
3506            let range = start..end;
3507            let ix = match error_ranges.binary_search_by_key(&range.start, |r| r.start) {
3508                Ok(ix) | Err(ix) => ix,
3509            };
3510            let mut end_ix = ix;
3511            while let Some(existing_range) = error_ranges.get(end_ix) {
3512                if existing_range.end < end {
3513                    end_ix += 1;
3514                } else {
3515                    break;
3516                }
3517            }
3518            error_ranges.splice(ix..end_ix, [range]);
3519            matches.advance();
3520        }
3521
3522        outdent_positions.sort();
3523        for outdent_position in outdent_positions {
3524            // find the innermost indent range containing this outdent_position
3525            // set its end to the outdent position
3526            if let Some(range_to_truncate) = indent_ranges
3527                .iter_mut()
3528                .rfind(|indent_range| indent_range.contains(&outdent_position))
3529            {
3530                range_to_truncate.end = outdent_position;
3531            }
3532        }
3533
3534        start_positions.sort_by_key(|b| b.start);
3535
3536        // Find the suggested indentation increases and decreased based on regexes.
3537        let mut regex_outdent_map = HashMap::default();
3538        let mut last_seen_suffix: HashMap<String, Vec<StartPosition>> = HashMap::default();
3539        let mut start_positions_iter = start_positions.iter().peekable();
3540
3541        let mut indent_change_rows = Vec::<(u32, Ordering)>::new();
3542        self.for_each_line(
3543            Point::new(prev_non_blank_row.unwrap_or(row_range.start), 0)
3544                ..Point::new(row_range.end, 0),
3545            |row, line| {
3546                let indent_len = self.indent_size_for_line(row).len;
3547                let row_language = self.language_at(Point::new(row, indent_len)).cloned();
3548                let row_language_config = row_language
3549                    .as_ref()
3550                    .map(|lang| lang.config())
3551                    .unwrap_or(config);
3552
3553                if row_language_config
3554                    .decrease_indent_pattern
3555                    .as_ref()
3556                    .is_some_and(|regex| regex.is_match(line))
3557                {
3558                    indent_change_rows.push((row, Ordering::Less));
3559                }
3560                if row_language_config
3561                    .increase_indent_pattern
3562                    .as_ref()
3563                    .is_some_and(|regex| regex.is_match(line))
3564                {
3565                    indent_change_rows.push((row + 1, Ordering::Greater));
3566                }
3567                while let Some(pos) = start_positions_iter.peek() {
3568                    if pos.start.row < row {
3569                        let pos = start_positions_iter.next().unwrap().clone();
3570                        last_seen_suffix
3571                            .entry(pos.suffix.to_string())
3572                            .or_default()
3573                            .push(pos);
3574                    } else {
3575                        break;
3576                    }
3577                }
3578                for rule in &row_language_config.decrease_indent_patterns {
3579                    if rule.pattern.as_ref().is_some_and(|r| r.is_match(line)) {
3580                        let row_start_column = self.indent_size_for_line(row).len;
3581                        let basis_row = rule
3582                            .valid_after
3583                            .iter()
3584                            .filter_map(|valid_suffix| last_seen_suffix.get(valid_suffix))
3585                            .flatten()
3586                            .filter(|pos| {
3587                                row_language
3588                                    .as_ref()
3589                                    .or(self.language.as_ref())
3590                                    .is_some_and(|lang| Arc::ptr_eq(lang, &pos.language))
3591                            })
3592                            .filter(|pos| pos.start.column <= row_start_column)
3593                            .max_by_key(|pos| pos.start.row);
3594                        if let Some(outdent_to) = basis_row {
3595                            regex_outdent_map.insert(row, outdent_to.start.row);
3596                        }
3597                        break;
3598                    }
3599                }
3600            },
3601        );
3602
3603        let mut indent_changes = indent_change_rows.into_iter().peekable();
3604        let mut prev_row = if config.auto_indent_using_last_non_empty_line {
3605            prev_non_blank_row.unwrap_or(0)
3606        } else {
3607            row_range.start.saturating_sub(1)
3608        };
3609
3610        let mut prev_row_start = Point::new(prev_row, self.indent_size_for_line(prev_row).len);
3611        Some(row_range.map(move |row| {
3612            let row_start = Point::new(row, self.indent_size_for_line(row).len);
3613
3614            let mut indent_from_prev_row = false;
3615            let mut outdent_from_prev_row = false;
3616            let mut outdent_to_row = u32::MAX;
3617            let mut from_regex = false;
3618
3619            while let Some((indent_row, delta)) = indent_changes.peek() {
3620                match indent_row.cmp(&row) {
3621                    Ordering::Equal => match delta {
3622                        Ordering::Less => {
3623                            from_regex = true;
3624                            outdent_from_prev_row = true
3625                        }
3626                        Ordering::Greater => {
3627                            indent_from_prev_row = true;
3628                            from_regex = true
3629                        }
3630                        _ => {}
3631                    },
3632
3633                    Ordering::Greater => break,
3634                    Ordering::Less => {}
3635                }
3636
3637                indent_changes.next();
3638            }
3639
3640            for range in &indent_ranges {
3641                if range.start.row >= row {
3642                    break;
3643                }
3644                if range.start.row == prev_row && range.end > row_start {
3645                    indent_from_prev_row = true;
3646                }
3647                if range.end > prev_row_start && range.end <= row_start {
3648                    outdent_to_row = outdent_to_row.min(range.start.row);
3649                }
3650            }
3651
3652            if let Some(basis_row) = regex_outdent_map.get(&row) {
3653                indent_from_prev_row = false;
3654                outdent_to_row = *basis_row;
3655                from_regex = true;
3656            }
3657
3658            let within_error = error_ranges
3659                .iter()
3660                .any(|e| e.start.row < row && e.end > row_start);
3661
3662            let suggestion = if outdent_to_row == prev_row
3663                || (outdent_from_prev_row && indent_from_prev_row)
3664            {
3665                Some(IndentSuggestion {
3666                    basis_row: prev_row,
3667                    delta: Ordering::Equal,
3668                    within_error: within_error && !from_regex,
3669                })
3670            } else if indent_from_prev_row {
3671                Some(IndentSuggestion {
3672                    basis_row: prev_row,
3673                    delta: Ordering::Greater,
3674                    within_error: within_error && !from_regex,
3675                })
3676            } else if outdent_to_row < prev_row {
3677                Some(IndentSuggestion {
3678                    basis_row: outdent_to_row,
3679                    delta: Ordering::Equal,
3680                    within_error: within_error && !from_regex,
3681                })
3682            } else if outdent_from_prev_row {
3683                Some(IndentSuggestion {
3684                    basis_row: prev_row,
3685                    delta: Ordering::Less,
3686                    within_error: within_error && !from_regex,
3687                })
3688            } else if config.auto_indent_using_last_non_empty_line || !self.is_line_blank(prev_row)
3689            {
3690                Some(IndentSuggestion {
3691                    basis_row: prev_row,
3692                    delta: Ordering::Equal,
3693                    within_error: within_error && !from_regex,
3694                })
3695            } else {
3696                None
3697            };
3698
3699            prev_row = row;
3700            prev_row_start = row_start;
3701            suggestion
3702        }))
3703    }
3704
3705    fn prev_non_blank_row(&self, mut row: u32) -> Option<u32> {
3706        while row > 0 {
3707            row -= 1;
3708            if !self.is_line_blank(row) {
3709                return Some(row);
3710            }
3711        }
3712        None
3713    }
3714
3715    pub fn captures(
3716        &self,
3717        range: Range<usize>,
3718        query: fn(&Grammar) -> Option<&tree_sitter::Query>,
3719    ) -> SyntaxMapCaptures<'_> {
3720        self.syntax.captures(range, &self.text, query)
3721    }
3722
3723    #[ztracing::instrument(skip_all)]
3724    fn get_highlights(&self, range: Range<usize>) -> (SyntaxMapCaptures<'_>, Vec<HighlightMap>) {
3725        let captures = self.syntax.captures(range, &self.text, |grammar| {
3726            grammar
3727                .highlights_config
3728                .as_ref()
3729                .map(|config| &config.query)
3730        });
3731        let highlight_maps = captures
3732            .grammars()
3733            .iter()
3734            .map(|grammar| grammar.highlight_map())
3735            .collect();
3736        (captures, highlight_maps)
3737    }
3738
3739    /// Iterates over chunks of text in the given range of the buffer. Text is chunked
3740    /// in an arbitrary way due to being stored in a [`Rope`](text::Rope). The text is also
3741    /// returned in chunks where each chunk has a single syntax highlighting style and
3742    /// diagnostic status.
3743    #[ztracing::instrument(skip_all)]
3744    pub fn chunks<T: ToOffset>(
3745        &self,
3746        range: Range<T>,
3747        language_aware: LanguageAwareStyling,
3748    ) -> BufferChunks<'_> {
3749        let range = range.start.to_offset(self)..range.end.to_offset(self);
3750
3751        let mut syntax = None;
3752        if language_aware.tree_sitter {
3753            syntax = Some(self.get_highlights(range.clone()));
3754        }
3755        BufferChunks::new(
3756            self.text.as_rope(),
3757            range,
3758            syntax,
3759            language_aware.diagnostics,
3760            Some(self),
3761        )
3762    }
3763
3764    pub fn highlighted_text_for_range<T: ToOffset>(
3765        &self,
3766        range: Range<T>,
3767        override_style: Option<HighlightStyle>,
3768        syntax_theme: &SyntaxTheme,
3769    ) -> HighlightedText {
3770        HighlightedText::from_buffer_range(
3771            range,
3772            &self.text,
3773            &self.syntax,
3774            override_style,
3775            syntax_theme,
3776        )
3777    }
3778
3779    /// Invokes the given callback for each line of text in the given range of the buffer.
3780    /// Uses callback to avoid allocating a string for each line.
3781    fn for_each_line(&self, range: Range<Point>, mut callback: impl FnMut(u32, &str)) {
3782        let mut line = String::new();
3783        let mut row = range.start.row;
3784        for chunk in self
3785            .as_rope()
3786            .chunks_in_range(range.to_offset(self))
3787            .chain(["\n"])
3788        {
3789            for (newline_ix, text) in chunk.split('\n').enumerate() {
3790                if newline_ix > 0 {
3791                    callback(row, &line);
3792                    row += 1;
3793                    line.clear();
3794                }
3795                line.push_str(text);
3796            }
3797        }
3798    }
3799
3800    /// Iterates over every [`SyntaxLayer`] in the buffer.
3801    pub fn syntax_layers(&self) -> impl Iterator<Item = SyntaxLayer<'_>> + '_ {
3802        self.syntax_layers_for_range(0..self.len(), true)
3803    }
3804
3805    pub fn syntax_layer_at<D: ToOffset>(&self, position: D) -> Option<SyntaxLayer<'_>> {
3806        let offset = position.to_offset(self);
3807        self.syntax_layers_for_range(offset..offset, false)
3808            .filter(|l| {
3809                if let Some(ranges) = l.included_sub_ranges {
3810                    ranges.iter().any(|range| {
3811                        let start = range.start.to_offset(self);
3812                        start <= offset && {
3813                            let end = range.end.to_offset(self);
3814                            offset < end
3815                        }
3816                    })
3817                } else {
3818                    l.node().start_byte() <= offset && l.node().end_byte() > offset
3819                }
3820            })
3821            .last()
3822    }
3823
3824    pub fn syntax_layers_for_range<D: ToOffset>(
3825        &self,
3826        range: Range<D>,
3827        include_hidden: bool,
3828    ) -> impl Iterator<Item = SyntaxLayer<'_>> + '_ {
3829        self.syntax
3830            .layers_for_range(range, &self.text, include_hidden)
3831    }
3832
3833    pub fn syntax_layers_languages(&self) -> impl Iterator<Item = &Arc<Language>> {
3834        self.syntax.languages(&self, true)
3835    }
3836
3837    pub fn smallest_syntax_layer_containing<D: ToOffset>(
3838        &self,
3839        range: Range<D>,
3840    ) -> Option<SyntaxLayer<'_>> {
3841        let range = range.to_offset(self);
3842        self.syntax
3843            .layers_for_range(range, &self.text, false)
3844            .max_by(|a, b| {
3845                if a.depth != b.depth {
3846                    a.depth.cmp(&b.depth)
3847                } else if a.offset.0 != b.offset.0 {
3848                    a.offset.0.cmp(&b.offset.0)
3849                } else {
3850                    a.node().end_byte().cmp(&b.node().end_byte()).reverse()
3851                }
3852            })
3853    }
3854
3855    /// Returns the [`ModelineSettings`].
3856    pub fn modeline(&self) -> Option<&Arc<ModelineSettings>> {
3857        self.modeline.as_ref()
3858    }
3859
3860    /// Returns the main [`Language`].
3861    pub fn language(&self) -> Option<&Arc<Language>> {
3862        self.language.as_ref()
3863    }
3864
3865    /// Returns the [`Language`] at the given location.
3866    pub fn language_at<D: ToOffset>(&self, position: D) -> Option<&Arc<Language>> {
3867        self.syntax_layer_at(position)
3868            .map(|info| info.language)
3869            .or(self.language.as_ref())
3870    }
3871
3872    /// Returns the settings for the language at the given location.
3873    pub fn settings_at<'a, D: ToOffset>(
3874        &'a self,
3875        position: D,
3876        cx: &'a App,
3877    ) -> Cow<'a, LanguageSettings> {
3878        LanguageSettings::for_buffer_snapshot(self, Some(position.to_offset(self)), cx)
3879    }
3880
3881    pub fn char_classifier_at<T: ToOffset>(&self, point: T) -> CharClassifier {
3882        CharClassifier::new(self.language_scope_at(point))
3883    }
3884
3885    /// Returns the [`LanguageScope`] at the given location.
3886    pub fn language_scope_at<D: ToOffset>(&self, position: D) -> Option<LanguageScope> {
3887        let offset = position.to_offset(self);
3888        let mut scope = None;
3889        let mut smallest_range_and_depth: Option<(Range<usize>, usize)> = None;
3890        let text: &TextBufferSnapshot = self;
3891
3892        // Use the layer that has the smallest node intersecting the given point.
3893        for layer in self
3894            .syntax
3895            .layers_for_range(offset..offset, &self.text, false)
3896        {
3897            if let Some(ranges) = layer.included_sub_ranges
3898                && !offset_in_sub_ranges(ranges, offset, text)
3899            {
3900                continue;
3901            }
3902
3903            let mut cursor = layer.node().walk();
3904
3905            let mut range = None;
3906            loop {
3907                let child_range = cursor.node().byte_range();
3908                if !child_range.contains(&offset) {
3909                    break;
3910                }
3911
3912                range = Some(child_range);
3913                if cursor.goto_first_child_for_byte(offset).is_none() {
3914                    break;
3915                }
3916            }
3917
3918            if let Some(range) = range
3919                && smallest_range_and_depth.as_ref().is_none_or(
3920                    |(smallest_range, smallest_range_depth)| {
3921                        if layer.depth > *smallest_range_depth {
3922                            true
3923                        } else if layer.depth == *smallest_range_depth {
3924                            range.len() < smallest_range.len()
3925                        } else {
3926                            false
3927                        }
3928                    },
3929                )
3930            {
3931                smallest_range_and_depth = Some((range, layer.depth));
3932                scope = Some(LanguageScope {
3933                    language: layer.language.clone(),
3934                    override_id: layer.override_id(offset, &self.text),
3935                });
3936            }
3937        }
3938
3939        scope.or_else(|| {
3940            self.language.clone().map(|language| LanguageScope {
3941                language,
3942                override_id: None,
3943            })
3944        })
3945    }
3946
3947    /// Returns a tuple of the range and character kind of the word
3948    /// surrounding the given position.
3949    pub fn surrounding_word<T: ToOffset>(
3950        &self,
3951        start: T,
3952        scope_context: Option<CharScopeContext>,
3953    ) -> (Range<usize>, Option<CharKind>) {
3954        let mut start = start.to_offset(self);
3955        let mut end = start;
3956        let mut next_chars = self.chars_at(start).take(128).peekable();
3957        let mut prev_chars = self.reversed_chars_at(start).take(128).peekable();
3958
3959        let classifier = self.char_classifier_at(start).scope_context(scope_context);
3960        let word_kind = cmp::max(
3961            prev_chars.peek().copied().map(|c| classifier.kind(c)),
3962            next_chars.peek().copied().map(|c| classifier.kind(c)),
3963        );
3964
3965        for ch in prev_chars {
3966            if Some(classifier.kind(ch)) == word_kind && ch != '\n' {
3967                start -= ch.len_utf8();
3968            } else {
3969                break;
3970            }
3971        }
3972
3973        for ch in next_chars {
3974            if Some(classifier.kind(ch)) == word_kind && ch != '\n' {
3975                end += ch.len_utf8();
3976            } else {
3977                break;
3978            }
3979        }
3980
3981        (start..end, word_kind)
3982    }
3983
3984    /// Moves the TreeCursor to the smallest descendant or ancestor syntax node enclosing the given
3985    /// range. When `require_larger` is true, the node found must be larger than the query range.
3986    ///
3987    /// Returns true if a node was found, and false otherwise. In the `false` case the cursor will
3988    /// be moved to the root of the tree.
3989    fn goto_node_enclosing_range(
3990        cursor: &mut tree_sitter::TreeCursor,
3991        query_range: &Range<usize>,
3992        require_larger: bool,
3993    ) -> bool {
3994        let mut ascending = false;
3995        loop {
3996            let mut range = cursor.node().byte_range();
3997            if query_range.is_empty() {
3998                // When the query range is empty and the current node starts after it, move to the
3999                // previous sibling to find the node the containing node.
4000                if range.start > query_range.start {
4001                    cursor.goto_previous_sibling();
4002                    range = cursor.node().byte_range();
4003                }
4004            } else {
4005                // When the query range is non-empty and the current node ends exactly at the start,
4006                // move to the next sibling to find a node that extends beyond the start.
4007                if range.end == query_range.start {
4008                    cursor.goto_next_sibling();
4009                    range = cursor.node().byte_range();
4010                }
4011            }
4012
4013            let encloses = range.contains_inclusive(query_range)
4014                && (!require_larger || range.len() > query_range.len());
4015            if !encloses {
4016                ascending = true;
4017                if !cursor.goto_parent() {
4018                    return false;
4019                }
4020                continue;
4021            } else if ascending {
4022                return true;
4023            }
4024
4025            // Descend into the current node.
4026            if cursor
4027                .goto_first_child_for_byte(query_range.start)
4028                .is_none()
4029            {
4030                return true;
4031            }
4032        }
4033    }
4034
4035    pub fn syntax_ancestor<'a, T: ToOffset>(
4036        &'a self,
4037        range: Range<T>,
4038    ) -> Option<tree_sitter::Node<'a>> {
4039        let range = range.start.to_offset(self)..range.end.to_offset(self);
4040        let mut result: Option<tree_sitter::Node<'a>> = None;
4041        for layer in self
4042            .syntax
4043            .layers_for_range(range.clone(), &self.text, true)
4044        {
4045            let mut cursor = layer.node().walk();
4046
4047            // Find the node that both contains the range and is larger than it.
4048            if !Self::goto_node_enclosing_range(&mut cursor, &range, true) {
4049                continue;
4050            }
4051
4052            let left_node = cursor.node();
4053            let mut layer_result = left_node;
4054
4055            // For an empty range, try to find another node immediately to the right of the range.
4056            if left_node.end_byte() == range.start {
4057                let mut right_node = None;
4058                while !cursor.goto_next_sibling() {
4059                    if !cursor.goto_parent() {
4060                        break;
4061                    }
4062                }
4063
4064                while cursor.node().start_byte() == range.start {
4065                    right_node = Some(cursor.node());
4066                    if !cursor.goto_first_child() {
4067                        break;
4068                    }
4069                }
4070
4071                // If there is a candidate node on both sides of the (empty) range, then
4072                // decide between the two by favoring a named node over an anonymous token.
4073                // If both nodes are the same in that regard, favor the right one.
4074                if let Some(right_node) = right_node
4075                    && (right_node.is_named() || !left_node.is_named())
4076                {
4077                    layer_result = right_node;
4078                }
4079            }
4080
4081            if let Some(previous_result) = &result
4082                && previous_result.byte_range().len() < layer_result.byte_range().len()
4083            {
4084                continue;
4085            }
4086            result = Some(layer_result);
4087        }
4088
4089        result
4090    }
4091
4092    /// Find the previous sibling syntax node at the given range.
4093    ///
4094    /// This function locates the syntax node that precedes the node containing
4095    /// the given range. It searches hierarchically by:
4096    /// 1. Finding the node that contains the given range
4097    /// 2. Looking for the previous sibling at the same tree level
4098    /// 3. If no sibling is found, moving up to parent levels and searching for siblings
4099    ///
4100    /// Returns `None` if there is no previous sibling at any ancestor level.
4101    pub fn syntax_prev_sibling<'a, T: ToOffset>(
4102        &'a self,
4103        range: Range<T>,
4104    ) -> Option<tree_sitter::Node<'a>> {
4105        let range = range.start.to_offset(self)..range.end.to_offset(self);
4106        let mut result: Option<tree_sitter::Node<'a>> = None;
4107
4108        for layer in self
4109            .syntax
4110            .layers_for_range(range.clone(), &self.text, true)
4111        {
4112            let mut cursor = layer.node().walk();
4113
4114            // Find the node that contains the range
4115            if !Self::goto_node_enclosing_range(&mut cursor, &range, false) {
4116                continue;
4117            }
4118
4119            // Look for the previous sibling, moving up ancestor levels if needed
4120            loop {
4121                if cursor.goto_previous_sibling() {
4122                    let layer_result = cursor.node();
4123
4124                    if let Some(previous_result) = &result {
4125                        if previous_result.byte_range().end < layer_result.byte_range().end {
4126                            continue;
4127                        }
4128                    }
4129                    result = Some(layer_result);
4130                    break;
4131                }
4132
4133                // No sibling found at this level, try moving up to parent
4134                if !cursor.goto_parent() {
4135                    break;
4136                }
4137            }
4138        }
4139
4140        result
4141    }
4142
4143    /// Find the next sibling syntax node at the given range.
4144    ///
4145    /// This function locates the syntax node that follows the node containing
4146    /// the given range. It searches hierarchically by:
4147    /// 1. Finding the node that contains the given range
4148    /// 2. Looking for the next sibling at the same tree level
4149    /// 3. If no sibling is found, moving up to parent levels and searching for siblings
4150    ///
4151    /// Returns `None` if there is no next sibling at any ancestor level.
4152    pub fn syntax_next_sibling<'a, T: ToOffset>(
4153        &'a self,
4154        range: Range<T>,
4155    ) -> Option<tree_sitter::Node<'a>> {
4156        let range = range.start.to_offset(self)..range.end.to_offset(self);
4157        let mut result: Option<tree_sitter::Node<'a>> = None;
4158
4159        for layer in self
4160            .syntax
4161            .layers_for_range(range.clone(), &self.text, true)
4162        {
4163            let mut cursor = layer.node().walk();
4164
4165            // Find the node that contains the range
4166            if !Self::goto_node_enclosing_range(&mut cursor, &range, false) {
4167                continue;
4168            }
4169
4170            // Look for the next sibling, moving up ancestor levels if needed
4171            loop {
4172                if cursor.goto_next_sibling() {
4173                    let layer_result = cursor.node();
4174
4175                    if let Some(previous_result) = &result {
4176                        if previous_result.byte_range().start > layer_result.byte_range().start {
4177                            continue;
4178                        }
4179                    }
4180                    result = Some(layer_result);
4181                    break;
4182                }
4183
4184                // No sibling found at this level, try moving up to parent
4185                if !cursor.goto_parent() {
4186                    break;
4187                }
4188            }
4189        }
4190
4191        result
4192    }
4193
4194    /// Returns the root syntax node within the given row
4195    pub fn syntax_root_ancestor(&self, position: Anchor) -> Option<tree_sitter::Node<'_>> {
4196        let start_offset = position.to_offset(self);
4197
4198        let row = self.summary_for_anchor::<text::PointUtf16>(&position).row as usize;
4199
4200        let layer = self
4201            .syntax
4202            .layers_for_range(start_offset..start_offset, &self.text, true)
4203            .next()?;
4204
4205        let mut cursor = layer.node().walk();
4206
4207        // Descend to the first leaf that touches the start of the range.
4208        while cursor.goto_first_child_for_byte(start_offset).is_some() {
4209            if cursor.node().end_byte() == start_offset {
4210                cursor.goto_next_sibling();
4211            }
4212        }
4213
4214        // Ascend to the root node within the same row.
4215        while cursor.goto_parent() {
4216            if cursor.node().start_position().row != row {
4217                break;
4218            }
4219        }
4220
4221        Some(cursor.node())
4222    }
4223
4224    /// Returns the outline for the buffer.
4225    ///
4226    /// This method allows passing an optional [`SyntaxTheme`] to
4227    /// syntax-highlight the returned symbols.
4228    pub fn outline(&self, theme: Option<&SyntaxTheme>) -> Outline<Anchor> {
4229        Outline::new(self.outline_items_containing(0..self.len(), true, theme))
4230    }
4231
4232    /// Returns all the symbols that contain the given position.
4233    ///
4234    /// This method allows passing an optional [`SyntaxTheme`] to
4235    /// syntax-highlight the returned symbols.
4236    pub fn symbols_containing<T: ToOffset>(
4237        &self,
4238        position: T,
4239        theme: Option<&SyntaxTheme>,
4240    ) -> Vec<OutlineItem<Anchor>> {
4241        let position = position.to_offset(self);
4242        let start = self.clip_offset(position.saturating_sub(1), Bias::Left);
4243        let end = self.clip_offset(position + 1, Bias::Right);
4244        let mut items = self.outline_items_containing(start..end, false, theme);
4245        let mut prev_depth = None;
4246        items.retain(|item| {
4247            let result = prev_depth.is_none_or(|prev_depth| item.depth > prev_depth);
4248            prev_depth = Some(item.depth);
4249            result
4250        });
4251        items
4252    }
4253
4254    pub fn outline_range_containing<T: ToOffset>(&self, range: Range<T>) -> Option<Range<Point>> {
4255        let range = range.to_offset(self);
4256        let mut matches = self.syntax.matches(range.clone(), &self.text, |grammar| {
4257            grammar.outline_config.as_ref().map(|c| &c.query)
4258        });
4259        let configs = matches
4260            .grammars()
4261            .iter()
4262            .map(|g| g.outline_config.as_ref().unwrap())
4263            .collect::<Vec<_>>();
4264
4265        while let Some(mat) = matches.peek() {
4266            let config = &configs[mat.grammar_index];
4267            let containing_item_node = maybe!({
4268                let item_node = mat.captures.iter().find_map(|cap| {
4269                    if cap.index == config.item_capture_ix {
4270                        Some(cap.node)
4271                    } else {
4272                        None
4273                    }
4274                })?;
4275
4276                let item_byte_range = item_node.byte_range();
4277                if item_byte_range.end < range.start || item_byte_range.start > range.end {
4278                    None
4279                } else {
4280                    Some(item_node)
4281                }
4282            });
4283
4284            if let Some(item_node) = containing_item_node {
4285                return Some(
4286                    Point::from_ts_point(item_node.start_position())
4287                        ..Point::from_ts_point(item_node.end_position()),
4288                );
4289            }
4290
4291            matches.advance();
4292        }
4293        None
4294    }
4295
4296    pub fn outline_items_containing<T: ToOffset>(
4297        &self,
4298        range: Range<T>,
4299        include_extra_context: bool,
4300        theme: Option<&SyntaxTheme>,
4301    ) -> Vec<OutlineItem<Anchor>> {
4302        self.outline_items_containing_internal(
4303            range,
4304            include_extra_context,
4305            theme,
4306            |this, range| this.anchor_after(range.start)..this.anchor_before(range.end),
4307        )
4308    }
4309
4310    pub fn outline_items_as_points_containing<T: ToOffset>(
4311        &self,
4312        range: Range<T>,
4313        include_extra_context: bool,
4314        theme: Option<&SyntaxTheme>,
4315    ) -> Vec<OutlineItem<Point>> {
4316        self.outline_items_containing_internal(range, include_extra_context, theme, |_, range| {
4317            range
4318        })
4319    }
4320
4321    pub fn outline_items_as_offsets_containing<T: ToOffset>(
4322        &self,
4323        range: Range<T>,
4324        include_extra_context: bool,
4325        theme: Option<&SyntaxTheme>,
4326    ) -> Vec<OutlineItem<usize>> {
4327        self.outline_items_containing_internal(
4328            range,
4329            include_extra_context,
4330            theme,
4331            |buffer, range| range.to_offset(buffer),
4332        )
4333    }
4334
4335    fn outline_items_containing_internal<T: ToOffset, U>(
4336        &self,
4337        range: Range<T>,
4338        include_extra_context: bool,
4339        theme: Option<&SyntaxTheme>,
4340        range_callback: fn(&Self, Range<Point>) -> Range<U>,
4341    ) -> Vec<OutlineItem<U>> {
4342        let range = range.to_offset(self);
4343        let mut matches = self.syntax.matches(range.clone(), &self.text, |grammar| {
4344            grammar.outline_config.as_ref().map(|c| &c.query)
4345        });
4346
4347        let mut items = Vec::new();
4348        let mut annotation_row_ranges: Vec<Range<u32>> = Vec::new();
4349        while let Some(mat) = matches.peek() {
4350            let config = matches.grammars()[mat.grammar_index]
4351                .outline_config
4352                .as_ref()
4353                .unwrap();
4354            if let Some(item) =
4355                self.next_outline_item(config, &mat, &range, include_extra_context, theme)
4356            {
4357                items.push(item);
4358            } else if let Some(capture) = mat
4359                .captures
4360                .iter()
4361                .find(|capture| Some(capture.index) == config.annotation_capture_ix)
4362            {
4363                let capture_range = capture.node.start_position()..capture.node.end_position();
4364                let mut capture_row_range =
4365                    capture_range.start.row as u32..capture_range.end.row as u32;
4366                if capture_range.end.row > capture_range.start.row && capture_range.end.column == 0
4367                {
4368                    capture_row_range.end -= 1;
4369                }
4370                if let Some(last_row_range) = annotation_row_ranges.last_mut() {
4371                    if last_row_range.end >= capture_row_range.start.saturating_sub(1) {
4372                        last_row_range.end = capture_row_range.end;
4373                    } else {
4374                        annotation_row_ranges.push(capture_row_range);
4375                    }
4376                } else {
4377                    annotation_row_ranges.push(capture_row_range);
4378                }
4379            }
4380            matches.advance();
4381        }
4382
4383        items.sort_by_key(|item| (item.range.start, Reverse(item.range.end)));
4384
4385        // Assign depths based on containment relationships and convert to anchors.
4386        let mut item_ends_stack = Vec::<Point>::new();
4387        let mut anchor_items = Vec::new();
4388        let mut annotation_row_ranges = annotation_row_ranges.into_iter().peekable();
4389        for item in items {
4390            while let Some(last_end) = item_ends_stack.last().copied() {
4391                if last_end < item.range.end {
4392                    item_ends_stack.pop();
4393                } else {
4394                    break;
4395                }
4396            }
4397
4398            let mut annotation_row_range = None;
4399            while let Some(next_annotation_row_range) = annotation_row_ranges.peek() {
4400                let row_preceding_item = item.range.start.row.saturating_sub(1);
4401                if next_annotation_row_range.end < row_preceding_item {
4402                    annotation_row_ranges.next();
4403                } else {
4404                    if next_annotation_row_range.end == row_preceding_item {
4405                        annotation_row_range = Some(next_annotation_row_range.clone());
4406                        annotation_row_ranges.next();
4407                    }
4408                    break;
4409                }
4410            }
4411
4412            anchor_items.push(OutlineItem {
4413                depth: item_ends_stack.len(),
4414                range: range_callback(self, item.range.clone()),
4415                source_range_for_text: range_callback(self, item.source_range_for_text.clone()),
4416                text: item.text,
4417                highlight_ranges: item.highlight_ranges,
4418                name_ranges: item.name_ranges,
4419                body_range: item.body_range.map(|r| range_callback(self, r)),
4420                annotation_range: annotation_row_range.map(|annotation_range| {
4421                    let point_range = Point::new(annotation_range.start, 0)
4422                        ..Point::new(annotation_range.end, self.line_len(annotation_range.end));
4423                    range_callback(self, point_range)
4424                }),
4425            });
4426            item_ends_stack.push(item.range.end);
4427        }
4428
4429        anchor_items
4430    }
4431
4432    fn next_outline_item(
4433        &self,
4434        config: &OutlineConfig,
4435        mat: &SyntaxMapMatch,
4436        range: &Range<usize>,
4437        include_extra_context: bool,
4438        theme: Option<&SyntaxTheme>,
4439    ) -> Option<OutlineItem<Point>> {
4440        let item_node = mat.captures.iter().find_map(|cap| {
4441            if cap.index == config.item_capture_ix {
4442                Some(cap.node)
4443            } else {
4444                None
4445            }
4446        })?;
4447
4448        let item_byte_range = item_node.byte_range();
4449        if item_byte_range.end < range.start || item_byte_range.start > range.end {
4450            return None;
4451        }
4452        let item_point_range = Point::from_ts_point(item_node.start_position())
4453            ..Point::from_ts_point(item_node.end_position());
4454
4455        let mut open_point = None;
4456        let mut close_point = None;
4457
4458        let mut buffer_ranges = Vec::new();
4459        let mut add_to_buffer_ranges = |node: tree_sitter::Node, node_is_name| {
4460            let mut range = node.start_byte()..node.end_byte();
4461            let start = node.start_position();
4462            if node.end_position().row > start.row {
4463                range.end = range.start + self.line_len(start.row as u32) as usize - start.column;
4464            }
4465
4466            if !range.is_empty() {
4467                buffer_ranges.push((range, node_is_name));
4468            }
4469        };
4470
4471        for capture in mat.captures {
4472            if capture.index == config.name_capture_ix {
4473                add_to_buffer_ranges(capture.node, true);
4474            } else if Some(capture.index) == config.context_capture_ix
4475                || (Some(capture.index) == config.extra_context_capture_ix && include_extra_context)
4476            {
4477                add_to_buffer_ranges(capture.node, false);
4478            } else {
4479                if Some(capture.index) == config.open_capture_ix {
4480                    open_point = Some(Point::from_ts_point(capture.node.end_position()));
4481                } else if Some(capture.index) == config.close_capture_ix {
4482                    close_point = Some(Point::from_ts_point(capture.node.start_position()));
4483                }
4484            }
4485        }
4486
4487        if buffer_ranges.is_empty() {
4488            return None;
4489        }
4490        let source_range_for_text =
4491            buffer_ranges.first().unwrap().0.start..buffer_ranges.last().unwrap().0.end;
4492
4493        let mut text = String::new();
4494        let mut highlight_ranges = Vec::new();
4495        let mut name_ranges = Vec::new();
4496        let mut chunks = self.chunks(
4497            source_range_for_text.clone(),
4498            LanguageAwareStyling {
4499                tree_sitter: true,
4500                diagnostics: true,
4501            },
4502        );
4503        let mut last_buffer_range_end = 0;
4504        for (buffer_range, is_name) in buffer_ranges {
4505            let space_added = !text.is_empty() && buffer_range.start > last_buffer_range_end;
4506            if space_added {
4507                text.push(' ');
4508            }
4509            let before_append_len = text.len();
4510            let mut offset = buffer_range.start;
4511            chunks.seek(buffer_range.clone());
4512            for mut chunk in chunks.by_ref() {
4513                if chunk.text.len() > buffer_range.end - offset {
4514                    chunk.text = &chunk.text[0..(buffer_range.end - offset)];
4515                    offset = buffer_range.end;
4516                } else {
4517                    offset += chunk.text.len();
4518                }
4519                let style = chunk
4520                    .syntax_highlight_id
4521                    .zip(theme)
4522                    .and_then(|(highlight, theme)| theme.get(highlight).cloned());
4523
4524                if let Some(style) = style {
4525                    let start = text.len();
4526                    let end = start + chunk.text.len();
4527                    highlight_ranges.push((start..end, style));
4528                }
4529                text.push_str(chunk.text);
4530                if offset >= buffer_range.end {
4531                    break;
4532                }
4533            }
4534            if is_name {
4535                let after_append_len = text.len();
4536                let start = if space_added && !name_ranges.is_empty() {
4537                    before_append_len - 1
4538                } else {
4539                    before_append_len
4540                };
4541                name_ranges.push(start..after_append_len);
4542            }
4543            last_buffer_range_end = buffer_range.end;
4544        }
4545
4546        Some(OutlineItem {
4547            depth: 0, // We'll calculate the depth later
4548            range: item_point_range,
4549            source_range_for_text: source_range_for_text.to_point(self),
4550            text,
4551            highlight_ranges,
4552            name_ranges,
4553            body_range: open_point.zip(close_point).map(|(start, end)| start..end),
4554            annotation_range: None,
4555        })
4556    }
4557
4558    pub fn function_body_fold_ranges<T: ToOffset>(
4559        &self,
4560        within: Range<T>,
4561    ) -> impl Iterator<Item = Range<usize>> + '_ {
4562        self.text_object_ranges(within, TreeSitterOptions::default())
4563            .filter_map(|(range, obj)| (obj == TextObject::InsideFunction).then_some(range))
4564    }
4565
4566    /// For each grammar in the language, runs the provided
4567    /// [`tree_sitter::Query`] against the given range.
4568    pub fn matches(
4569        &self,
4570        range: Range<usize>,
4571        query: fn(&Grammar) -> Option<&tree_sitter::Query>,
4572    ) -> SyntaxMapMatches<'_> {
4573        self.syntax.matches(range, self, query)
4574    }
4575
4576    /// Finds all [`RowChunks`] applicable to the given range, then returns all bracket pairs that intersect with those chunks.
4577    /// Hence, may return more bracket pairs than the range contains.
4578    ///
4579    /// Will omit known chunks.
4580    /// The resulting bracket match collections are not ordered.
4581    pub fn fetch_bracket_ranges(
4582        &self,
4583        range: Range<usize>,
4584        known_chunks: Option<&HashSet<Range<BufferRow>>>,
4585    ) -> HashMap<Range<BufferRow>, Vec<BracketMatch<usize>>> {
4586        let mut all_bracket_matches = HashMap::default();
4587
4588        for chunk in self
4589            .tree_sitter_data
4590            .chunks
4591            .applicable_chunks(&[range.to_point(self)])
4592        {
4593            if known_chunks.is_some_and(|chunks| chunks.contains(&chunk.row_range())) {
4594                continue;
4595            }
4596            let chunk_range = chunk.anchor_range();
4597            let chunk_range = chunk_range.to_offset(&self);
4598
4599            if let Some(cached_brackets) =
4600                &self.tree_sitter_data.brackets_by_chunks.lock()[chunk.id]
4601            {
4602                all_bracket_matches.insert(chunk.row_range(), cached_brackets.clone());
4603                continue;
4604            }
4605
4606            let mut all_brackets: Vec<(BracketMatch<usize>, usize, bool)> = Vec::new();
4607            let mut opens = Vec::new();
4608            let mut color_pairs = Vec::new();
4609
4610            let mut matches = self.syntax.matches_with_options(
4611                chunk_range.clone(),
4612                &self.text,
4613                TreeSitterOptions {
4614                    max_bytes_to_query: Some(MAX_BYTES_TO_QUERY),
4615                    max_start_depth: None,
4616                },
4617                |grammar| grammar.brackets_config.as_ref().map(|c| &c.query),
4618            );
4619            let configs = matches
4620                .grammars()
4621                .iter()
4622                .map(|grammar| grammar.brackets_config.as_ref().unwrap())
4623                .collect::<Vec<_>>();
4624
4625            // Group matches by open range so we can either trust grammar output
4626            // or repair it by picking a single closest close per open.
4627            let mut open_to_close_ranges = BTreeMap::new();
4628            while let Some(mat) = matches.peek() {
4629                let mut open = None;
4630                let mut close = None;
4631                let syntax_layer_depth = mat.depth;
4632                let pattern_index = mat.pattern_index;
4633                let config = configs[mat.grammar_index];
4634                let pattern = &config.patterns[pattern_index];
4635                for capture in mat.captures {
4636                    if capture.index == config.open_capture_ix {
4637                        open = Some(capture.node.byte_range());
4638                    } else if capture.index == config.close_capture_ix {
4639                        close = Some(capture.node.byte_range());
4640                    }
4641                }
4642
4643                matches.advance();
4644
4645                let Some((open_range, close_range)) = open.zip(close) else {
4646                    continue;
4647                };
4648
4649                let bracket_range = open_range.start..=close_range.end;
4650                if !bracket_range.overlaps(&chunk_range) {
4651                    continue;
4652                }
4653
4654                open_to_close_ranges
4655                    .entry((open_range.start, open_range.end, pattern_index))
4656                    .or_insert_with(BTreeMap::new)
4657                    .insert(
4658                        (close_range.start, close_range.end),
4659                        BracketMatch {
4660                            open_range: open_range.clone(),
4661                            close_range: close_range.clone(),
4662                            syntax_layer_depth,
4663                            newline_only: pattern.newline_only,
4664                            color_index: None,
4665                        },
4666                    );
4667
4668                all_brackets.push((
4669                    BracketMatch {
4670                        open_range,
4671                        close_range,
4672                        syntax_layer_depth,
4673                        newline_only: pattern.newline_only,
4674                        color_index: None,
4675                    },
4676                    pattern_index,
4677                    pattern.rainbow_exclude,
4678                ));
4679            }
4680
4681            let has_bogus_matches = open_to_close_ranges
4682                .iter()
4683                .any(|(_, end_ranges)| end_ranges.len() > 1);
4684            if has_bogus_matches {
4685                // Grammar is producing bogus matches where one open is paired with multiple
4686                // closes. Build a valid stack by walking through positions in order.
4687                // For each close, we know the expected open_len from tree-sitter matches.
4688
4689                // Map each close to its expected open length (for inferring opens)
4690                let close_to_open_len: HashMap<(usize, usize, usize), usize> = all_brackets
4691                    .iter()
4692                    .map(|(bracket_match, pattern_index, _)| {
4693                        (
4694                            (
4695                                bracket_match.close_range.start,
4696                                bracket_match.close_range.end,
4697                                *pattern_index,
4698                            ),
4699                            bracket_match.open_range.len(),
4700                        )
4701                    })
4702                    .collect();
4703
4704                // Collect unique opens and closes within this chunk
4705                let mut unique_opens: HashSet<(usize, usize, usize)> = all_brackets
4706                    .iter()
4707                    .map(|(bracket_match, pattern_index, _)| {
4708                        (
4709                            bracket_match.open_range.start,
4710                            bracket_match.open_range.end,
4711                            *pattern_index,
4712                        )
4713                    })
4714                    .filter(|(start, _, _)| chunk_range.contains(start))
4715                    .collect();
4716
4717                let mut unique_closes: Vec<(usize, usize, usize)> = all_brackets
4718                    .iter()
4719                    .map(|(bracket_match, pattern_index, _)| {
4720                        (
4721                            bracket_match.close_range.start,
4722                            bracket_match.close_range.end,
4723                            *pattern_index,
4724                        )
4725                    })
4726                    .filter(|(start, _, _)| chunk_range.contains(start))
4727                    .collect();
4728                unique_closes.sort();
4729                unique_closes.dedup();
4730
4731                // Build valid pairs by walking through closes in order
4732                let mut unique_opens_vec: Vec<_> = unique_opens.iter().copied().collect();
4733                unique_opens_vec.sort();
4734
4735                let mut valid_pairs: HashSet<((usize, usize, usize), (usize, usize, usize))> =
4736                    HashSet::default();
4737                let mut open_stacks: HashMap<usize, Vec<(usize, usize)>> = HashMap::default();
4738                let mut open_idx = 0;
4739
4740                for close in &unique_closes {
4741                    // Push all opens before this close onto stack
4742                    while open_idx < unique_opens_vec.len()
4743                        && unique_opens_vec[open_idx].0 < close.0
4744                    {
4745                        let (start, end, pattern_index) = unique_opens_vec[open_idx];
4746                        open_stacks
4747                            .entry(pattern_index)
4748                            .or_default()
4749                            .push((start, end));
4750                        open_idx += 1;
4751                    }
4752
4753                    // Try to match with most recent open
4754                    let (close_start, close_end, pattern_index) = *close;
4755                    if let Some(open) = open_stacks
4756                        .get_mut(&pattern_index)
4757                        .and_then(|open_stack| open_stack.pop())
4758                    {
4759                        valid_pairs.insert(((open.0, open.1, pattern_index), *close));
4760                    } else if let Some(&open_len) = close_to_open_len.get(close) {
4761                        // No open on stack - infer one based on expected open_len
4762                        if close_start >= open_len {
4763                            let inferred = (close_start - open_len, close_start, pattern_index);
4764                            unique_opens.insert(inferred);
4765                            valid_pairs.insert((inferred, *close));
4766                            all_brackets.push((
4767                                BracketMatch {
4768                                    open_range: inferred.0..inferred.1,
4769                                    close_range: close_start..close_end,
4770                                    newline_only: false,
4771                                    syntax_layer_depth: 0,
4772                                    color_index: None,
4773                                },
4774                                pattern_index,
4775                                false,
4776                            ));
4777                        }
4778                    }
4779                }
4780
4781                all_brackets.retain(|(bracket_match, pattern_index, _)| {
4782                    let open = (
4783                        bracket_match.open_range.start,
4784                        bracket_match.open_range.end,
4785                        *pattern_index,
4786                    );
4787                    let close = (
4788                        bracket_match.close_range.start,
4789                        bracket_match.close_range.end,
4790                        *pattern_index,
4791                    );
4792                    valid_pairs.contains(&(open, close))
4793                });
4794            }
4795
4796            let mut all_brackets = all_brackets
4797                .into_iter()
4798                .enumerate()
4799                .map(|(index, (bracket_match, _, rainbow_exclude))| {
4800                    // Certain languages have "brackets" that are not brackets, e.g. tags. and such
4801                    // bracket will match the entire tag with all text inside.
4802                    // For now, avoid highlighting any pair that has more than single char in each bracket.
4803                    // We need to  colorize `<Element/>` bracket pairs, so cannot make this check stricter.
4804                    let should_color = !rainbow_exclude
4805                        && (bracket_match.open_range.len() == 1
4806                            || bracket_match.close_range.len() == 1);
4807                    if should_color {
4808                        opens.push(bracket_match.open_range.clone());
4809                        color_pairs.push((
4810                            bracket_match.open_range.clone(),
4811                            bracket_match.close_range.clone(),
4812                            index,
4813                        ));
4814                    }
4815                    bracket_match
4816                })
4817                .collect::<Vec<_>>();
4818
4819            opens.sort_by_key(|r| (r.start, r.end));
4820            opens.dedup_by(|a, b| a.start == b.start && a.end == b.end);
4821            color_pairs.sort_by_key(|(_, close, _)| close.end);
4822
4823            let mut open_stack = Vec::new();
4824            let mut open_index = 0;
4825            for (open, close, index) in color_pairs {
4826                while open_index < opens.len() && opens[open_index].start < close.start {
4827                    open_stack.push(opens[open_index].clone());
4828                    open_index += 1;
4829                }
4830
4831                if open_stack.last() == Some(&open) {
4832                    let depth_index = open_stack.len() - 1;
4833                    all_brackets[index].color_index = Some(depth_index);
4834                    open_stack.pop();
4835                }
4836            }
4837
4838            all_brackets.sort_by_key(|bracket_match| {
4839                (bracket_match.open_range.start, bracket_match.open_range.end)
4840            });
4841
4842            if let empty_slot @ None =
4843                &mut self.tree_sitter_data.brackets_by_chunks.lock()[chunk.id]
4844            {
4845                *empty_slot = Some(all_brackets.clone());
4846            }
4847            all_bracket_matches.insert(chunk.row_range(), all_brackets);
4848        }
4849
4850        all_bracket_matches
4851    }
4852
4853    pub fn all_bracket_ranges(
4854        &self,
4855        range: Range<usize>,
4856    ) -> impl Iterator<Item = BracketMatch<usize>> {
4857        self.fetch_bracket_ranges(range.clone(), None)
4858            .into_values()
4859            .flatten()
4860            .filter(move |bracket_match| {
4861                let bracket_range = bracket_match.open_range.start..bracket_match.close_range.end;
4862                bracket_range.overlaps(&range)
4863            })
4864    }
4865
4866    /// Returns bracket range pairs overlapping or adjacent to `range`
4867    pub fn bracket_ranges<T: ToOffset>(
4868        &self,
4869        range: Range<T>,
4870    ) -> impl Iterator<Item = BracketMatch<usize>> + '_ {
4871        // Find bracket pairs that *inclusively* contain the given range.
4872        let range = range.start.to_previous_offset(self)..range.end.to_next_offset(self);
4873        self.all_bracket_ranges(range)
4874            .filter(|pair| !pair.newline_only)
4875    }
4876
4877    pub fn debug_variables_query<T: ToOffset>(
4878        &self,
4879        range: Range<T>,
4880    ) -> impl Iterator<Item = (Range<usize>, DebuggerTextObject)> + '_ {
4881        let range = range.start.to_previous_offset(self)..range.end.to_next_offset(self);
4882
4883        let mut matches = self.syntax.matches_with_options(
4884            range.clone(),
4885            &self.text,
4886            TreeSitterOptions::default(),
4887            |grammar| grammar.debug_variables_config.as_ref().map(|c| &c.query),
4888        );
4889
4890        let configs = matches
4891            .grammars()
4892            .iter()
4893            .map(|grammar| grammar.debug_variables_config.as_ref())
4894            .collect::<Vec<_>>();
4895
4896        let mut captures = Vec::<(Range<usize>, DebuggerTextObject)>::new();
4897
4898        iter::from_fn(move || {
4899            loop {
4900                while let Some(capture) = captures.pop() {
4901                    if capture.0.overlaps(&range) {
4902                        return Some(capture);
4903                    }
4904                }
4905
4906                let mat = matches.peek()?;
4907
4908                let Some(config) = configs[mat.grammar_index].as_ref() else {
4909                    matches.advance();
4910                    continue;
4911                };
4912
4913                for capture in mat.captures {
4914                    let Some(ix) = config
4915                        .objects_by_capture_ix
4916                        .binary_search_by_key(&capture.index, |e| e.0)
4917                        .ok()
4918                    else {
4919                        continue;
4920                    };
4921                    let text_object = config.objects_by_capture_ix[ix].1;
4922                    let byte_range = capture.node.byte_range();
4923
4924                    let mut found = false;
4925                    for (range, existing) in captures.iter_mut() {
4926                        if existing == &text_object {
4927                            range.start = range.start.min(byte_range.start);
4928                            range.end = range.end.max(byte_range.end);
4929                            found = true;
4930                            break;
4931                        }
4932                    }
4933
4934                    if !found {
4935                        captures.push((byte_range, text_object));
4936                    }
4937                }
4938
4939                matches.advance();
4940            }
4941        })
4942    }
4943
4944    pub fn text_object_ranges<T: ToOffset>(
4945        &self,
4946        range: Range<T>,
4947        options: TreeSitterOptions,
4948    ) -> impl Iterator<Item = (Range<usize>, TextObject)> + '_ {
4949        let range =
4950            range.start.to_previous_offset(self)..self.len().min(range.end.to_next_offset(self));
4951
4952        let mut matches =
4953            self.syntax
4954                .matches_with_options(range.clone(), &self.text, options, |grammar| {
4955                    grammar.text_object_config.as_ref().map(|c| &c.query)
4956                });
4957
4958        let configs = matches
4959            .grammars()
4960            .iter()
4961            .map(|grammar| grammar.text_object_config.as_ref())
4962            .collect::<Vec<_>>();
4963
4964        let mut captures = Vec::<(Range<usize>, TextObject)>::new();
4965
4966        iter::from_fn(move || {
4967            loop {
4968                while let Some(capture) = captures.pop() {
4969                    if capture.0.overlaps(&range) {
4970                        return Some(capture);
4971                    }
4972                }
4973
4974                let mat = matches.peek()?;
4975
4976                let Some(config) = configs[mat.grammar_index].as_ref() else {
4977                    matches.advance();
4978                    continue;
4979                };
4980
4981                for capture in mat.captures {
4982                    let Some(ix) = config
4983                        .text_objects_by_capture_ix
4984                        .binary_search_by_key(&capture.index, |e| e.0)
4985                        .ok()
4986                    else {
4987                        continue;
4988                    };
4989                    let text_object = config.text_objects_by_capture_ix[ix].1;
4990                    let byte_range = capture.node.byte_range();
4991
4992                    let mut found = false;
4993                    for (range, existing) in captures.iter_mut() {
4994                        if existing == &text_object {
4995                            range.start = range.start.min(byte_range.start);
4996                            range.end = range.end.max(byte_range.end);
4997                            found = true;
4998                            break;
4999                        }
5000                    }
5001
5002                    if !found {
5003                        captures.push((byte_range, text_object));
5004                    }
5005                }
5006
5007                matches.advance();
5008            }
5009        })
5010    }
5011
5012    /// Returns enclosing bracket ranges containing the given range
5013    pub fn enclosing_bracket_ranges<T: ToOffset>(
5014        &self,
5015        range: Range<T>,
5016    ) -> impl Iterator<Item = BracketMatch<usize>> + '_ {
5017        let range = range.start.to_offset(self)..range.end.to_offset(self);
5018
5019        let result: Vec<_> = self.bracket_ranges(range.clone()).collect();
5020        let max_depth = result
5021            .iter()
5022            .map(|mat| mat.syntax_layer_depth)
5023            .max()
5024            .unwrap_or(0);
5025        result.into_iter().filter(move |pair| {
5026            pair.open_range.start <= range.start
5027                && pair.close_range.end >= range.end
5028                && pair.syntax_layer_depth == max_depth
5029        })
5030    }
5031
5032    /// Returns the smallest enclosing bracket ranges containing the given range or None if no brackets contain range
5033    ///
5034    /// Can optionally pass a range_filter to filter the ranges of brackets to consider
5035    pub fn innermost_enclosing_bracket_ranges<T: ToOffset>(
5036        &self,
5037        range: Range<T>,
5038        range_filter: Option<&dyn Fn(Range<usize>, Range<usize>) -> bool>,
5039    ) -> Option<(Range<usize>, Range<usize>)> {
5040        let range = range.start.to_offset(self)..range.end.to_offset(self);
5041
5042        // Get the ranges of the innermost pair of brackets.
5043        let mut result: Option<(Range<usize>, Range<usize>)> = None;
5044
5045        for pair in self.enclosing_bracket_ranges(range) {
5046            if let Some(range_filter) = range_filter
5047                && !range_filter(pair.open_range.clone(), pair.close_range.clone())
5048            {
5049                continue;
5050            }
5051
5052            let len = pair.close_range.end - pair.open_range.start;
5053
5054            if let Some((existing_open, existing_close)) = &result {
5055                let existing_len = existing_close.end - existing_open.start;
5056                if len > existing_len {
5057                    continue;
5058                }
5059            }
5060
5061            result = Some((pair.open_range, pair.close_range));
5062        }
5063
5064        result
5065    }
5066
5067    /// Returns anchor ranges for any matches of the redaction query.
5068    /// The buffer can be associated with multiple languages, and the redaction query associated with each
5069    /// will be run on the relevant section of the buffer.
5070    pub fn redacted_ranges<T: ToOffset>(
5071        &self,
5072        range: Range<T>,
5073    ) -> impl Iterator<Item = Range<usize>> + '_ {
5074        let offset_range = range.start.to_offset(self)..range.end.to_offset(self);
5075        let mut syntax_matches = self.syntax.matches(offset_range, self, |grammar| {
5076            grammar
5077                .redactions_config
5078                .as_ref()
5079                .map(|config| &config.query)
5080        });
5081
5082        let configs = syntax_matches
5083            .grammars()
5084            .iter()
5085            .map(|grammar| grammar.redactions_config.as_ref())
5086            .collect::<Vec<_>>();
5087
5088        iter::from_fn(move || {
5089            let redacted_range = syntax_matches
5090                .peek()
5091                .and_then(|mat| {
5092                    configs[mat.grammar_index].and_then(|config| {
5093                        mat.captures
5094                            .iter()
5095                            .find(|capture| capture.index == config.redaction_capture_ix)
5096                    })
5097                })
5098                .map(|mat| mat.node.byte_range());
5099            syntax_matches.advance();
5100            redacted_range
5101        })
5102    }
5103
5104    pub fn injections_intersecting_range<T: ToOffset>(
5105        &self,
5106        range: Range<T>,
5107    ) -> impl Iterator<Item = (Range<usize>, &Arc<Language>)> + '_ {
5108        let offset_range = range.start.to_offset(self)..range.end.to_offset(self);
5109
5110        let mut syntax_matches = self.syntax.matches(offset_range, self, |grammar| {
5111            grammar
5112                .injection_config
5113                .as_ref()
5114                .map(|config| &config.query)
5115        });
5116
5117        let configs = syntax_matches
5118            .grammars()
5119            .iter()
5120            .map(|grammar| grammar.injection_config.as_ref())
5121            .collect::<Vec<_>>();
5122
5123        iter::from_fn(move || {
5124            let ranges = syntax_matches.peek().and_then(|mat| {
5125                let config = &configs[mat.grammar_index]?;
5126                let content_capture_range = mat.captures.iter().find_map(|capture| {
5127                    if capture.index == config.content_capture_ix {
5128                        Some(capture.node.byte_range())
5129                    } else {
5130                        None
5131                    }
5132                })?;
5133                let language = self.language_at(content_capture_range.start)?;
5134                Some((content_capture_range, language))
5135            });
5136            syntax_matches.advance();
5137            ranges
5138        })
5139    }
5140
5141    pub fn runnable_ranges(
5142        &self,
5143        offset_range: Range<usize>,
5144    ) -> impl Iterator<Item = RunnableRange> + '_ {
5145        let mut syntax_matches = self.syntax.matches(offset_range, self, |grammar| {
5146            grammar.runnable_config.as_ref().map(|config| &config.query)
5147        });
5148
5149        let test_configs = syntax_matches
5150            .grammars()
5151            .iter()
5152            .map(|grammar| grammar.runnable_config.as_ref())
5153            .collect::<Vec<_>>();
5154
5155        iter::from_fn(move || {
5156            loop {
5157                let mat = syntax_matches.peek()?;
5158
5159                let test_range = test_configs[mat.grammar_index].and_then(|test_configs| {
5160                    let mut run_range = None;
5161                    let full_range = mat.captures.iter().fold(
5162                        Range {
5163                            start: usize::MAX,
5164                            end: 0,
5165                        },
5166                        |mut acc, next| {
5167                            let byte_range = next.node.byte_range();
5168                            if acc.start > byte_range.start {
5169                                acc.start = byte_range.start;
5170                            }
5171                            if acc.end < byte_range.end {
5172                                acc.end = byte_range.end;
5173                            }
5174                            acc
5175                        },
5176                    );
5177                    if full_range.start > full_range.end {
5178                        // We did not find a full spanning range of this match.
5179                        return None;
5180                    }
5181                    let extra_captures: SmallVec<[_; 1]> =
5182                        SmallVec::from_iter(mat.captures.iter().filter_map(|capture| {
5183                            test_configs
5184                                .extra_captures
5185                                .get(capture.index as usize)
5186                                .cloned()
5187                                .and_then(|tag_name| match tag_name {
5188                                    RunnableCapture::Named(name) => {
5189                                        Some((capture.node.byte_range(), name))
5190                                    }
5191                                    RunnableCapture::Run => {
5192                                        let _ = run_range.insert(capture.node.byte_range());
5193                                        None
5194                                    }
5195                                })
5196                        }));
5197                    let run_range = run_range?;
5198                    let tags = test_configs
5199                        .query
5200                        .property_settings(mat.pattern_index)
5201                        .iter()
5202                        .filter_map(|property| {
5203                            if *property.key == *"tag" {
5204                                property
5205                                    .value
5206                                    .as_ref()
5207                                    .map(|value| RunnableTag(value.to_string().into()))
5208                            } else {
5209                                None
5210                            }
5211                        })
5212                        .collect();
5213                    let extra_captures = extra_captures
5214                        .into_iter()
5215                        .map(|(range, name)| {
5216                            (
5217                                name.to_string(),
5218                                self.text_for_range(range).collect::<String>(),
5219                            )
5220                        })
5221                        .collect();
5222                    // All tags should have the same range.
5223                    Some(RunnableRange {
5224                        run_range,
5225                        full_range,
5226                        runnable: Runnable {
5227                            tags,
5228                            language: mat.language,
5229                            buffer: self.remote_id(),
5230                        },
5231                        extra_captures,
5232                        buffer_id: self.remote_id(),
5233                    })
5234                });
5235
5236                syntax_matches.advance();
5237                if test_range.is_some() {
5238                    // It's fine for us to short-circuit on .peek()? returning None. We don't want to return None from this iter if we
5239                    // had a capture that did not contain a run marker, hence we'll just loop around for the next capture.
5240                    return test_range;
5241                }
5242            }
5243        })
5244    }
5245
5246    /// Returns selections for remote peers intersecting the given range.
5247    #[allow(clippy::type_complexity)]
5248    pub fn selections_in_range(
5249        &self,
5250        range: Range<Anchor>,
5251        include_local: bool,
5252    ) -> impl Iterator<
5253        Item = (
5254            ReplicaId,
5255            bool,
5256            CursorShape,
5257            impl Iterator<Item = &Selection<Anchor>> + '_,
5258        ),
5259    > + '_ {
5260        self.remote_selections
5261            .iter()
5262            .filter(move |(replica_id, set)| {
5263                (include_local || **replica_id != self.text.replica_id())
5264                    && !set.selections.is_empty()
5265            })
5266            .map(move |(replica_id, set)| {
5267                let start_ix = match set.selections.binary_search_by(|probe| {
5268                    probe.end.cmp(&range.start, self).then(Ordering::Greater)
5269                }) {
5270                    Ok(ix) | Err(ix) => ix,
5271                };
5272                let end_ix = match set.selections.binary_search_by(|probe| {
5273                    probe.start.cmp(&range.end, self).then(Ordering::Less)
5274                }) {
5275                    Ok(ix) | Err(ix) => ix,
5276                };
5277
5278                (
5279                    *replica_id,
5280                    set.line_mode,
5281                    set.cursor_shape,
5282                    set.selections[start_ix..end_ix].iter(),
5283                )
5284            })
5285    }
5286
5287    /// Returns if the buffer contains any diagnostics.
5288    pub fn has_diagnostics(&self) -> bool {
5289        !self.diagnostics.is_empty()
5290    }
5291
5292    /// Returns all the diagnostics intersecting the given range.
5293    pub fn diagnostics_in_range<'a, T, O>(
5294        &'a self,
5295        search_range: Range<T>,
5296        reversed: bool,
5297    ) -> impl 'a + Iterator<Item = DiagnosticEntryRef<'a, O>>
5298    where
5299        T: 'a + Clone + ToOffset,
5300        O: 'a + FromAnchor,
5301    {
5302        let mut iterators: Vec<_> = self
5303            .diagnostics
5304            .iter()
5305            .map(|(_, collection)| {
5306                collection
5307                    .range::<T, text::Anchor>(search_range.clone(), self, true, reversed)
5308                    .peekable()
5309            })
5310            .collect();
5311
5312        std::iter::from_fn(move || {
5313            let (next_ix, _) = iterators
5314                .iter_mut()
5315                .enumerate()
5316                .flat_map(|(ix, iter)| Some((ix, iter.peek()?)))
5317                .min_by(|(_, a), (_, b)| {
5318                    let cmp = a
5319                        .range
5320                        .start
5321                        .cmp(&b.range.start, self)
5322                        // when range is equal, sort by diagnostic severity
5323                        .then(a.diagnostic.severity.cmp(&b.diagnostic.severity))
5324                        // and stabilize order with group_id
5325                        .then(a.diagnostic.group_id.cmp(&b.diagnostic.group_id));
5326                    if reversed { cmp.reverse() } else { cmp }
5327                })?;
5328            iterators[next_ix]
5329                .next()
5330                .map(
5331                    |DiagnosticEntryRef { range, diagnostic }| DiagnosticEntryRef {
5332                        diagnostic,
5333                        range: FromAnchor::from_anchor(&range.start, self)
5334                            ..FromAnchor::from_anchor(&range.end, self),
5335                    },
5336                )
5337        })
5338    }
5339
5340    /// Returns all the diagnostic groups associated with the given
5341    /// language server ID. If no language server ID is provided,
5342    /// all diagnostics groups are returned.
5343    pub fn diagnostic_groups(
5344        &self,
5345        language_server_id: Option<LanguageServerId>,
5346    ) -> Vec<(LanguageServerId, DiagnosticGroup<'_, Anchor>)> {
5347        let mut groups = Vec::new();
5348
5349        if let Some(language_server_id) = language_server_id {
5350            if let Some(set) = self.diagnostics.get(&language_server_id) {
5351                set.groups(language_server_id, &mut groups, self);
5352            }
5353        } else {
5354            for (language_server_id, diagnostics) in self.diagnostics.iter() {
5355                diagnostics.groups(*language_server_id, &mut groups, self);
5356            }
5357        }
5358
5359        groups.sort_by(|(id_a, group_a), (id_b, group_b)| {
5360            let a_start = &group_a.entries[group_a.primary_ix].range.start;
5361            let b_start = &group_b.entries[group_b.primary_ix].range.start;
5362            a_start.cmp(b_start, self).then_with(|| id_a.cmp(id_b))
5363        });
5364
5365        groups
5366    }
5367
5368    /// Returns an iterator over the diagnostics for the given group.
5369    pub fn diagnostic_group<O>(
5370        &self,
5371        group_id: usize,
5372    ) -> impl Iterator<Item = DiagnosticEntryRef<'_, O>> + use<'_, O>
5373    where
5374        O: FromAnchor + 'static,
5375    {
5376        self.diagnostics
5377            .iter()
5378            .flat_map(move |(_, set)| set.group(group_id, self))
5379    }
5380
5381    /// An integer version number that accounts for all updates besides
5382    /// the buffer's text itself (which is versioned via a version vector).
5383    pub fn non_text_state_update_count(&self) -> usize {
5384        self.non_text_state_update_count
5385    }
5386
5387    /// An integer version that changes when the buffer's syntax changes.
5388    pub fn syntax_update_count(&self) -> usize {
5389        self.syntax.update_count()
5390    }
5391
5392    /// Returns a snapshot of underlying file.
5393    pub fn file(&self) -> Option<&Arc<dyn File>> {
5394        self.file.as_ref()
5395    }
5396
5397    pub fn resolve_file_path(&self, include_root: bool, cx: &App) -> Option<String> {
5398        if let Some(file) = self.file() {
5399            if file.path().file_name().is_none() || include_root {
5400                Some(file.full_path(cx).to_string_lossy().into_owned())
5401            } else {
5402                Some(file.path().display(file.path_style(cx)).to_string())
5403            }
5404        } else {
5405            None
5406        }
5407    }
5408
5409    pub fn words_in_range(&self, query: WordsQuery) -> BTreeMap<String, Range<Anchor>> {
5410        let query_str = query.fuzzy_contents;
5411        if query_str.is_some_and(|query| query.is_empty()) {
5412            return BTreeMap::default();
5413        }
5414
5415        let classifier = CharClassifier::new(self.language.clone().map(|language| LanguageScope {
5416            language,
5417            override_id: None,
5418        }));
5419
5420        let mut query_ix = 0;
5421        let query_chars = query_str.map(|query| query.chars().collect::<Vec<_>>());
5422        let query_len = query_chars.as_ref().map_or(0, |query| query.len());
5423
5424        let mut words = BTreeMap::default();
5425        let mut current_word_start_ix = None;
5426        let mut chunk_ix = query.range.start;
5427        for chunk in self.chunks(
5428            query.range,
5429            LanguageAwareStyling {
5430                tree_sitter: false,
5431                diagnostics: false,
5432            },
5433        ) {
5434            for (i, c) in chunk.text.char_indices() {
5435                let ix = chunk_ix + i;
5436                if classifier.is_word(c) {
5437                    if current_word_start_ix.is_none() {
5438                        current_word_start_ix = Some(ix);
5439                    }
5440
5441                    if let Some(query_chars) = &query_chars
5442                        && query_ix < query_len
5443                        && c.to_lowercase().eq(query_chars[query_ix].to_lowercase())
5444                    {
5445                        query_ix += 1;
5446                    }
5447                    continue;
5448                } else if let Some(word_start) = current_word_start_ix.take()
5449                    && query_ix == query_len
5450                {
5451                    let word_range = self.anchor_before(word_start)..self.anchor_after(ix);
5452                    let mut word_text = self.text_for_range(word_start..ix).peekable();
5453                    let first_char = word_text
5454                        .peek()
5455                        .and_then(|first_chunk| first_chunk.chars().next());
5456                    // Skip empty and "words" starting with digits as a heuristic to reduce useless completions
5457                    if !query.skip_digits
5458                        || first_char.is_none_or(|first_char| !first_char.is_digit(10))
5459                    {
5460                        words.insert(word_text.collect(), word_range);
5461                    }
5462                }
5463                query_ix = 0;
5464            }
5465            chunk_ix += chunk.text.len();
5466        }
5467
5468        words
5469    }
5470}
5471
5472/// A configuration to use when producing styled text chunks.
5473#[derive(Clone, Copy)]
5474pub struct LanguageAwareStyling {
5475    /// Whether to highlight text chunks using tree-sitter.
5476    pub tree_sitter: bool,
5477    /// Whether to highlight text chunks based on the diagnostics data.
5478    pub diagnostics: bool,
5479}
5480
5481pub struct WordsQuery<'a> {
5482    /// Only returns words with all chars from the fuzzy string in them.
5483    pub fuzzy_contents: Option<&'a str>,
5484    /// Skips words that start with a digit.
5485    pub skip_digits: bool,
5486    /// Buffer offset range, to look for words.
5487    pub range: Range<usize>,
5488}
5489
5490fn indent_size_for_line(text: &text::BufferSnapshot, row: u32) -> IndentSize {
5491    indent_size_for_text(text.chars_at(Point::new(row, 0)))
5492}
5493
5494fn indent_size_for_text(text: impl Iterator<Item = char>) -> IndentSize {
5495    let mut result = IndentSize::spaces(0);
5496    for c in text {
5497        let kind = match c {
5498            ' ' => IndentKind::Space,
5499            '\t' => IndentKind::Tab,
5500            _ => break,
5501        };
5502        if result.len == 0 {
5503            result.kind = kind;
5504        }
5505        result.len += 1;
5506    }
5507    result
5508}
5509
5510impl Clone for BufferSnapshot {
5511    fn clone(&self) -> Self {
5512        Self {
5513            text: self.text.clone(),
5514            syntax: self.syntax.clone(),
5515            file: self.file.clone(),
5516            remote_selections: self.remote_selections.clone(),
5517            diagnostics: self.diagnostics.clone(),
5518            language: self.language.clone(),
5519            tree_sitter_data: self.tree_sitter_data.clone(),
5520            non_text_state_update_count: self.non_text_state_update_count,
5521            capability: self.capability,
5522            modeline: self.modeline.clone(),
5523        }
5524    }
5525}
5526
5527impl Deref for BufferSnapshot {
5528    type Target = text::BufferSnapshot;
5529
5530    fn deref(&self) -> &Self::Target {
5531        &self.text
5532    }
5533}
5534
5535unsafe impl Send for BufferChunks<'_> {}
5536
5537impl<'a> BufferChunks<'a> {
5538    pub(crate) fn new(
5539        text: &'a Rope,
5540        range: Range<usize>,
5541        syntax: Option<(SyntaxMapCaptures<'a>, Vec<HighlightMap>)>,
5542        diagnostics: bool,
5543        buffer_snapshot: Option<&'a BufferSnapshot>,
5544    ) -> Self {
5545        let mut highlights = None;
5546        if let Some((captures, highlight_maps)) = syntax {
5547            highlights = Some(BufferChunkHighlights {
5548                captures,
5549                next_capture: None,
5550                stack: Default::default(),
5551                highlight_maps,
5552            })
5553        }
5554
5555        let diagnostic_endpoints = diagnostics.then(|| Vec::new().into_iter().peekable());
5556        let chunks = text.chunks_in_range(range.clone());
5557
5558        let mut this = BufferChunks {
5559            range,
5560            buffer_snapshot,
5561            chunks,
5562            diagnostic_endpoints,
5563            error_depth: 0,
5564            warning_depth: 0,
5565            information_depth: 0,
5566            hint_depth: 0,
5567            unnecessary_depth: 0,
5568            underline: true,
5569            highlights,
5570        };
5571        this.initialize_diagnostic_endpoints();
5572        this
5573    }
5574
5575    /// Seeks to the given byte offset in the buffer.
5576    pub fn seek(&mut self, range: Range<usize>) {
5577        let old_range = std::mem::replace(&mut self.range, range.clone());
5578        self.chunks.set_range(self.range.clone());
5579        if let Some(highlights) = self.highlights.as_mut() {
5580            if old_range.start <= self.range.start && old_range.end >= self.range.end {
5581                // Reuse existing highlights stack, as the new range is a subrange of the old one.
5582                highlights
5583                    .stack
5584                    .retain(|(end_offset, _)| *end_offset > range.start);
5585                if let Some(capture) = &highlights.next_capture
5586                    && range.start >= capture.node.start_byte()
5587                {
5588                    let next_capture_end = capture.node.end_byte();
5589                    if range.start < next_capture_end
5590                        && let Some(capture_id) =
5591                            highlights.highlight_maps[capture.grammar_index].get(capture.index)
5592                    {
5593                        highlights.stack.push((next_capture_end, capture_id));
5594                    }
5595                    highlights.next_capture.take();
5596                }
5597            } else if let Some(snapshot) = self.buffer_snapshot {
5598                let (captures, highlight_maps) = snapshot.get_highlights(self.range.clone());
5599                *highlights = BufferChunkHighlights {
5600                    captures,
5601                    next_capture: None,
5602                    stack: Default::default(),
5603                    highlight_maps,
5604                };
5605            } else {
5606                // We cannot obtain new highlights for a language-aware buffer iterator, as we don't have a buffer snapshot.
5607                // Seeking such BufferChunks is not supported.
5608                debug_assert!(
5609                    false,
5610                    "Attempted to seek on a language-aware buffer iterator without associated buffer snapshot"
5611                );
5612            }
5613
5614            highlights.captures.set_byte_range(self.range.clone());
5615            self.initialize_diagnostic_endpoints();
5616        }
5617    }
5618
5619    fn initialize_diagnostic_endpoints(&mut self) {
5620        if let Some(diagnostics) = self.diagnostic_endpoints.as_mut()
5621            && let Some(buffer) = self.buffer_snapshot
5622        {
5623            let mut diagnostic_endpoints = Vec::new();
5624            for entry in buffer.diagnostics_in_range::<_, usize>(self.range.clone(), false) {
5625                diagnostic_endpoints.push(DiagnosticEndpoint {
5626                    offset: entry.range.start,
5627                    is_start: true,
5628                    severity: entry.diagnostic.severity,
5629                    is_unnecessary: entry.diagnostic.is_unnecessary,
5630                    underline: entry.diagnostic.underline,
5631                });
5632                diagnostic_endpoints.push(DiagnosticEndpoint {
5633                    offset: entry.range.end,
5634                    is_start: false,
5635                    severity: entry.diagnostic.severity,
5636                    is_unnecessary: entry.diagnostic.is_unnecessary,
5637                    underline: entry.diagnostic.underline,
5638                });
5639            }
5640            diagnostic_endpoints
5641                .sort_unstable_by_key(|endpoint| (endpoint.offset, !endpoint.is_start));
5642            *diagnostics = diagnostic_endpoints.into_iter().peekable();
5643            self.hint_depth = 0;
5644            self.error_depth = 0;
5645            self.warning_depth = 0;
5646            self.information_depth = 0;
5647        }
5648    }
5649
5650    /// The current byte offset in the buffer.
5651    pub fn offset(&self) -> usize {
5652        self.range.start
5653    }
5654
5655    pub fn range(&self) -> Range<usize> {
5656        self.range.clone()
5657    }
5658
5659    fn update_diagnostic_depths(&mut self, endpoint: DiagnosticEndpoint) {
5660        let depth = match endpoint.severity {
5661            DiagnosticSeverity::ERROR => &mut self.error_depth,
5662            DiagnosticSeverity::WARNING => &mut self.warning_depth,
5663            DiagnosticSeverity::INFORMATION => &mut self.information_depth,
5664            DiagnosticSeverity::HINT => &mut self.hint_depth,
5665            _ => return,
5666        };
5667        if endpoint.is_start {
5668            *depth += 1;
5669        } else {
5670            *depth -= 1;
5671        }
5672
5673        if endpoint.is_unnecessary {
5674            if endpoint.is_start {
5675                self.unnecessary_depth += 1;
5676            } else {
5677                self.unnecessary_depth -= 1;
5678            }
5679        }
5680    }
5681
5682    fn current_diagnostic_severity(&self) -> Option<DiagnosticSeverity> {
5683        if self.error_depth > 0 {
5684            Some(DiagnosticSeverity::ERROR)
5685        } else if self.warning_depth > 0 {
5686            Some(DiagnosticSeverity::WARNING)
5687        } else if self.information_depth > 0 {
5688            Some(DiagnosticSeverity::INFORMATION)
5689        } else if self.hint_depth > 0 {
5690            Some(DiagnosticSeverity::HINT)
5691        } else {
5692            None
5693        }
5694    }
5695
5696    fn current_code_is_unnecessary(&self) -> bool {
5697        self.unnecessary_depth > 0
5698    }
5699}
5700
5701impl<'a> Iterator for BufferChunks<'a> {
5702    type Item = Chunk<'a>;
5703
5704    fn next(&mut self) -> Option<Self::Item> {
5705        let mut next_capture_start = usize::MAX;
5706        let mut next_diagnostic_endpoint = usize::MAX;
5707
5708        if let Some(highlights) = self.highlights.as_mut() {
5709            while let Some((parent_capture_end, _)) = highlights.stack.last() {
5710                if *parent_capture_end <= self.range.start {
5711                    highlights.stack.pop();
5712                } else {
5713                    break;
5714                }
5715            }
5716
5717            if highlights.next_capture.is_none() {
5718                highlights.next_capture = highlights.captures.next();
5719            }
5720
5721            while let Some(capture) = highlights.next_capture.as_ref() {
5722                if self.range.start < capture.node.start_byte() {
5723                    next_capture_start = capture.node.start_byte();
5724                    break;
5725                } else {
5726                    let highlight_id =
5727                        highlights.highlight_maps[capture.grammar_index].get(capture.index);
5728                    if let Some(highlight_id) = highlight_id {
5729                        highlights
5730                            .stack
5731                            .push((capture.node.end_byte(), highlight_id));
5732                    }
5733                    highlights.next_capture = highlights.captures.next();
5734                }
5735            }
5736        }
5737
5738        let mut diagnostic_endpoints = std::mem::take(&mut self.diagnostic_endpoints);
5739        if let Some(diagnostic_endpoints) = diagnostic_endpoints.as_mut() {
5740            while let Some(endpoint) = diagnostic_endpoints.peek().copied() {
5741                if endpoint.offset <= self.range.start {
5742                    self.update_diagnostic_depths(endpoint);
5743                    diagnostic_endpoints.next();
5744                    self.underline = endpoint.underline;
5745                } else {
5746                    next_diagnostic_endpoint = endpoint.offset;
5747                    break;
5748                }
5749            }
5750        }
5751        self.diagnostic_endpoints = diagnostic_endpoints;
5752
5753        if let Some(ChunkBitmaps {
5754            text: chunk,
5755            chars: chars_map,
5756            tabs,
5757            newlines,
5758        }) = self.chunks.peek_with_bitmaps()
5759        {
5760            let chunk_start = self.range.start;
5761            let mut chunk_end = (self.chunks.offset() + chunk.len())
5762                .min(next_capture_start)
5763                .min(next_diagnostic_endpoint);
5764            let mut highlight_id = None;
5765            if let Some(highlights) = self.highlights.as_ref()
5766                && let Some((parent_capture_end, parent_highlight_id)) = highlights.stack.last()
5767            {
5768                chunk_end = chunk_end.min(*parent_capture_end);
5769                highlight_id = Some(*parent_highlight_id);
5770            }
5771            let bit_start = chunk_start - self.chunks.offset();
5772            let bit_end = chunk_end - self.chunks.offset();
5773
5774            let slice = &chunk[bit_start..bit_end];
5775
5776            let mask = 1u128.unbounded_shl(bit_end as u32).wrapping_sub(1);
5777            let tabs = (tabs >> bit_start) & mask;
5778            let chars = (chars_map >> bit_start) & mask;
5779            let newlines = (newlines >> bit_start) & mask;
5780
5781            self.range.start = chunk_end;
5782            if self.range.start == self.chunks.offset() + chunk.len() {
5783                self.chunks.next().unwrap();
5784            }
5785
5786            Some(Chunk {
5787                text: slice,
5788                syntax_highlight_id: highlight_id,
5789                underline: self.underline,
5790                diagnostic_severity: self.current_diagnostic_severity(),
5791                is_unnecessary: self.current_code_is_unnecessary(),
5792                tabs,
5793                chars,
5794                newlines,
5795                ..Chunk::default()
5796            })
5797        } else {
5798            None
5799        }
5800    }
5801}
5802
5803impl operation_queue::Operation for Operation {
5804    fn lamport_timestamp(&self) -> clock::Lamport {
5805        match self {
5806            Operation::Buffer(_) => {
5807                unreachable!("buffer operations should never be deferred at this layer")
5808            }
5809            Operation::UpdateDiagnostics {
5810                lamport_timestamp, ..
5811            }
5812            | Operation::UpdateSelections {
5813                lamport_timestamp, ..
5814            }
5815            | Operation::UpdateCompletionTriggers {
5816                lamport_timestamp, ..
5817            }
5818            | Operation::UpdateLineEnding {
5819                lamport_timestamp, ..
5820            } => *lamport_timestamp,
5821        }
5822    }
5823}
5824
5825impl IndentSize {
5826    /// Returns an [`IndentSize`] representing the given spaces.
5827    pub fn spaces(len: u32) -> Self {
5828        Self {
5829            len,
5830            kind: IndentKind::Space,
5831        }
5832    }
5833
5834    /// Returns an [`IndentSize`] representing a tab.
5835    pub fn tab() -> Self {
5836        Self {
5837            len: 1,
5838            kind: IndentKind::Tab,
5839        }
5840    }
5841
5842    /// An iterator over the characters represented by this [`IndentSize`].
5843    pub fn chars(&self) -> impl Iterator<Item = char> {
5844        iter::repeat(self.char()).take(self.len as usize)
5845    }
5846
5847    /// The character representation of this [`IndentSize`].
5848    pub fn char(&self) -> char {
5849        match self.kind {
5850            IndentKind::Space => ' ',
5851            IndentKind::Tab => '\t',
5852        }
5853    }
5854
5855    /// Consumes the current [`IndentSize`] and returns a new one that has
5856    /// been shrunk or enlarged by the given size along the given direction.
5857    pub fn with_delta(mut self, direction: Ordering, size: IndentSize) -> Self {
5858        match direction {
5859            Ordering::Less => {
5860                if self.kind == size.kind && self.len >= size.len {
5861                    self.len -= size.len;
5862                }
5863            }
5864            Ordering::Equal => {}
5865            Ordering::Greater => {
5866                if self.len == 0 {
5867                    self = size;
5868                } else if self.kind == size.kind {
5869                    self.len += size.len;
5870                }
5871            }
5872        }
5873        self
5874    }
5875
5876    pub fn len_with_expanded_tabs(&self, tab_size: NonZeroU32) -> usize {
5877        match self.kind {
5878            IndentKind::Space => self.len as usize,
5879            IndentKind::Tab => self.len as usize * tab_size.get() as usize,
5880        }
5881    }
5882}
5883
5884#[cfg(any(test, feature = "test-support"))]
5885pub struct TestFile {
5886    pub path: Arc<RelPath>,
5887    pub root_name: String,
5888    pub local_root: Option<PathBuf>,
5889}
5890
5891#[cfg(any(test, feature = "test-support"))]
5892impl File for TestFile {
5893    fn path(&self) -> &Arc<RelPath> {
5894        &self.path
5895    }
5896
5897    fn full_path(&self, _: &gpui::App) -> PathBuf {
5898        PathBuf::from(self.root_name.clone()).join(self.path.as_std_path())
5899    }
5900
5901    fn as_local(&self) -> Option<&dyn LocalFile> {
5902        if self.local_root.is_some() {
5903            Some(self)
5904        } else {
5905            None
5906        }
5907    }
5908
5909    fn disk_state(&self) -> DiskState {
5910        unimplemented!()
5911    }
5912
5913    fn file_name<'a>(&'a self, _: &'a gpui::App) -> &'a str {
5914        self.path().file_name().unwrap_or(self.root_name.as_ref())
5915    }
5916
5917    fn worktree_id(&self, _: &App) -> WorktreeId {
5918        WorktreeId::from_usize(0)
5919    }
5920
5921    fn to_proto(&self, _: &App) -> rpc::proto::File {
5922        unimplemented!()
5923    }
5924
5925    fn is_private(&self) -> bool {
5926        false
5927    }
5928
5929    fn path_style(&self, _cx: &App) -> PathStyle {
5930        PathStyle::local()
5931    }
5932}
5933
5934#[cfg(any(test, feature = "test-support"))]
5935impl LocalFile for TestFile {
5936    fn abs_path(&self, _cx: &App) -> PathBuf {
5937        PathBuf::from(self.local_root.as_ref().unwrap())
5938            .join(&self.root_name)
5939            .join(self.path.as_std_path())
5940    }
5941
5942    fn load(&self, _cx: &App) -> Task<Result<String>> {
5943        unimplemented!()
5944    }
5945
5946    fn load_bytes(&self, _cx: &App) -> Task<Result<Vec<u8>>> {
5947        unimplemented!()
5948    }
5949}
5950
5951pub(crate) fn contiguous_ranges(
5952    values: impl Iterator<Item = u32>,
5953    max_len: usize,
5954) -> impl Iterator<Item = Range<u32>> {
5955    let mut values = values;
5956    let mut current_range: Option<Range<u32>> = None;
5957    std::iter::from_fn(move || {
5958        loop {
5959            if let Some(value) = values.next() {
5960                if let Some(range) = &mut current_range
5961                    && value == range.end
5962                    && range.len() < max_len
5963                {
5964                    range.end += 1;
5965                    continue;
5966                }
5967
5968                let prev_range = current_range.clone();
5969                current_range = Some(value..(value + 1));
5970                if prev_range.is_some() {
5971                    return prev_range;
5972                }
5973            } else {
5974                return current_range.take();
5975            }
5976        }
5977    })
5978}
5979
5980#[derive(Default, Debug)]
5981pub struct CharClassifier {
5982    scope: Option<LanguageScope>,
5983    scope_context: Option<CharScopeContext>,
5984    ignore_punctuation: bool,
5985}
5986
5987impl CharClassifier {
5988    pub fn new(scope: Option<LanguageScope>) -> Self {
5989        Self {
5990            scope,
5991            scope_context: None,
5992            ignore_punctuation: false,
5993        }
5994    }
5995
5996    pub fn scope_context(self, scope_context: Option<CharScopeContext>) -> Self {
5997        Self {
5998            scope_context,
5999            ..self
6000        }
6001    }
6002
6003    pub fn ignore_punctuation(self, ignore_punctuation: bool) -> Self {
6004        Self {
6005            ignore_punctuation,
6006            ..self
6007        }
6008    }
6009
6010    pub fn is_whitespace(&self, c: char) -> bool {
6011        self.kind(c) == CharKind::Whitespace
6012    }
6013
6014    pub fn is_word(&self, c: char) -> bool {
6015        self.kind(c) == CharKind::Word
6016    }
6017
6018    pub fn is_punctuation(&self, c: char) -> bool {
6019        self.kind(c) == CharKind::Punctuation
6020    }
6021
6022    pub fn kind_with(&self, c: char, ignore_punctuation: bool) -> CharKind {
6023        if c.is_alphanumeric() || c == '_' {
6024            return CharKind::Word;
6025        }
6026
6027        if let Some(scope) = &self.scope {
6028            let characters = match self.scope_context {
6029                Some(CharScopeContext::Completion) => scope.completion_query_characters(),
6030                Some(CharScopeContext::LinkedEdit) => scope.linked_edit_characters(),
6031                None => scope.word_characters(),
6032            };
6033            if let Some(characters) = characters
6034                && characters.contains(&c)
6035            {
6036                return CharKind::Word;
6037            }
6038        }
6039
6040        if c.is_whitespace() {
6041            return CharKind::Whitespace;
6042        }
6043
6044        if ignore_punctuation {
6045            CharKind::Word
6046        } else {
6047            CharKind::Punctuation
6048        }
6049    }
6050
6051    pub fn kind(&self, c: char) -> CharKind {
6052        self.kind_with(c, self.ignore_punctuation)
6053    }
6054}
6055
6056/// Find all of the ranges of whitespace that occur at the ends of lines
6057/// in the given rope.
6058///
6059/// This could also be done with a regex search, but this implementation
6060/// avoids copying text.
6061pub fn trailing_whitespace_ranges(rope: &Rope) -> Vec<Range<usize>> {
6062    let mut ranges = Vec::new();
6063
6064    let mut offset = 0;
6065    let mut prev_chunk_trailing_whitespace_range = 0..0;
6066    for chunk in rope.chunks() {
6067        let mut prev_line_trailing_whitespace_range = 0..0;
6068        for (i, line) in chunk.split('\n').enumerate() {
6069            let line_end_offset = offset + line.len();
6070            let trimmed_line_len = line.trim_end_matches([' ', '\t']).len();
6071            let mut trailing_whitespace_range = (offset + trimmed_line_len)..line_end_offset;
6072
6073            if i == 0 && trimmed_line_len == 0 {
6074                trailing_whitespace_range.start = prev_chunk_trailing_whitespace_range.start;
6075            }
6076            if !prev_line_trailing_whitespace_range.is_empty() {
6077                ranges.push(prev_line_trailing_whitespace_range);
6078            }
6079
6080            offset = line_end_offset + 1;
6081            prev_line_trailing_whitespace_range = trailing_whitespace_range;
6082        }
6083
6084        offset -= 1;
6085        prev_chunk_trailing_whitespace_range = prev_line_trailing_whitespace_range;
6086    }
6087
6088    if !prev_chunk_trailing_whitespace_range.is_empty() {
6089        ranges.push(prev_chunk_trailing_whitespace_range);
6090    }
6091
6092    ranges
6093}