buffer.rs

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