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