buffer.rs

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