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