buffer.rs

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