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>(
3737        &self,
3738        range: Range<T>,
3739        language_aware: LanguageAwareStyling,
3740    ) -> BufferChunks<'_> {
3741        let range = range.start.to_offset(self)..range.end.to_offset(self);
3742
3743        let mut syntax = None;
3744        if language_aware.tree_sitter {
3745            syntax = Some(self.get_highlights(range.clone()));
3746        }
3747        BufferChunks::new(
3748            self.text.as_rope(),
3749            range,
3750            syntax,
3751            language_aware.diagnostics,
3752            Some(self),
3753        )
3754    }
3755
3756    pub fn highlighted_text_for_range<T: ToOffset>(
3757        &self,
3758        range: Range<T>,
3759        override_style: Option<HighlightStyle>,
3760        syntax_theme: &SyntaxTheme,
3761    ) -> HighlightedText {
3762        HighlightedText::from_buffer_range(
3763            range,
3764            &self.text,
3765            &self.syntax,
3766            override_style,
3767            syntax_theme,
3768        )
3769    }
3770
3771    /// Invokes the given callback for each line of text in the given range of the buffer.
3772    /// Uses callback to avoid allocating a string for each line.
3773    fn for_each_line(&self, range: Range<Point>, mut callback: impl FnMut(u32, &str)) {
3774        let mut line = String::new();
3775        let mut row = range.start.row;
3776        for chunk in self
3777            .as_rope()
3778            .chunks_in_range(range.to_offset(self))
3779            .chain(["\n"])
3780        {
3781            for (newline_ix, text) in chunk.split('\n').enumerate() {
3782                if newline_ix > 0 {
3783                    callback(row, &line);
3784                    row += 1;
3785                    line.clear();
3786                }
3787                line.push_str(text);
3788            }
3789        }
3790    }
3791
3792    /// Iterates over every [`SyntaxLayer`] in the buffer.
3793    pub fn syntax_layers(&self) -> impl Iterator<Item = SyntaxLayer<'_>> + '_ {
3794        self.syntax_layers_for_range(0..self.len(), true)
3795    }
3796
3797    pub fn syntax_layer_at<D: ToOffset>(&self, position: D) -> Option<SyntaxLayer<'_>> {
3798        let offset = position.to_offset(self);
3799        self.syntax_layers_for_range(offset..offset, false)
3800            .filter(|l| {
3801                if let Some(ranges) = l.included_sub_ranges {
3802                    ranges.iter().any(|range| {
3803                        let start = range.start.to_offset(self);
3804                        start <= offset && {
3805                            let end = range.end.to_offset(self);
3806                            offset < end
3807                        }
3808                    })
3809                } else {
3810                    l.node().start_byte() <= offset && l.node().end_byte() > offset
3811                }
3812            })
3813            .last()
3814    }
3815
3816    pub fn syntax_layers_for_range<D: ToOffset>(
3817        &self,
3818        range: Range<D>,
3819        include_hidden: bool,
3820    ) -> impl Iterator<Item = SyntaxLayer<'_>> + '_ {
3821        self.syntax
3822            .layers_for_range(range, &self.text, include_hidden)
3823    }
3824
3825    pub fn syntax_layers_languages(&self) -> impl Iterator<Item = &Arc<Language>> {
3826        self.syntax.languages(&self, true)
3827    }
3828
3829    pub fn smallest_syntax_layer_containing<D: ToOffset>(
3830        &self,
3831        range: Range<D>,
3832    ) -> Option<SyntaxLayer<'_>> {
3833        let range = range.to_offset(self);
3834        self.syntax
3835            .layers_for_range(range, &self.text, false)
3836            .max_by(|a, b| {
3837                if a.depth != b.depth {
3838                    a.depth.cmp(&b.depth)
3839                } else if a.offset.0 != b.offset.0 {
3840                    a.offset.0.cmp(&b.offset.0)
3841                } else {
3842                    a.node().end_byte().cmp(&b.node().end_byte()).reverse()
3843                }
3844            })
3845    }
3846
3847    /// Returns the [`ModelineSettings`].
3848    pub fn modeline(&self) -> Option<&Arc<ModelineSettings>> {
3849        self.modeline.as_ref()
3850    }
3851
3852    /// Returns the main [`Language`].
3853    pub fn language(&self) -> Option<&Arc<Language>> {
3854        self.language.as_ref()
3855    }
3856
3857    /// Returns the [`Language`] at the given location.
3858    pub fn language_at<D: ToOffset>(&self, position: D) -> Option<&Arc<Language>> {
3859        self.syntax_layer_at(position)
3860            .map(|info| info.language)
3861            .or(self.language.as_ref())
3862    }
3863
3864    /// Returns the settings for the language at the given location.
3865    pub fn settings_at<'a, D: ToOffset>(
3866        &'a self,
3867        position: D,
3868        cx: &'a App,
3869    ) -> Cow<'a, LanguageSettings> {
3870        LanguageSettings::for_buffer_snapshot(self, Some(position.to_offset(self)), cx)
3871    }
3872
3873    pub fn char_classifier_at<T: ToOffset>(&self, point: T) -> CharClassifier {
3874        CharClassifier::new(self.language_scope_at(point))
3875    }
3876
3877    /// Returns the [`LanguageScope`] at the given location.
3878    pub fn language_scope_at<D: ToOffset>(&self, position: D) -> Option<LanguageScope> {
3879        let offset = position.to_offset(self);
3880        let mut scope = None;
3881        let mut smallest_range_and_depth: Option<(Range<usize>, usize)> = None;
3882        let text: &TextBufferSnapshot = self;
3883
3884        // Use the layer that has the smallest node intersecting the given point.
3885        for layer in self
3886            .syntax
3887            .layers_for_range(offset..offset, &self.text, false)
3888        {
3889            if let Some(ranges) = layer.included_sub_ranges
3890                && !offset_in_sub_ranges(ranges, offset, text)
3891            {
3892                continue;
3893            }
3894
3895            let mut cursor = layer.node().walk();
3896
3897            let mut range = None;
3898            loop {
3899                let child_range = cursor.node().byte_range();
3900                if !child_range.contains(&offset) {
3901                    break;
3902                }
3903
3904                range = Some(child_range);
3905                if cursor.goto_first_child_for_byte(offset).is_none() {
3906                    break;
3907                }
3908            }
3909
3910            if let Some(range) = range
3911                && smallest_range_and_depth.as_ref().is_none_or(
3912                    |(smallest_range, smallest_range_depth)| {
3913                        if layer.depth > *smallest_range_depth {
3914                            true
3915                        } else if layer.depth == *smallest_range_depth {
3916                            range.len() < smallest_range.len()
3917                        } else {
3918                            false
3919                        }
3920                    },
3921                )
3922            {
3923                smallest_range_and_depth = Some((range, layer.depth));
3924                scope = Some(LanguageScope {
3925                    language: layer.language.clone(),
3926                    override_id: layer.override_id(offset, &self.text),
3927                });
3928            }
3929        }
3930
3931        scope.or_else(|| {
3932            self.language.clone().map(|language| LanguageScope {
3933                language,
3934                override_id: None,
3935            })
3936        })
3937    }
3938
3939    /// Returns a tuple of the range and character kind of the word
3940    /// surrounding the given position.
3941    pub fn surrounding_word<T: ToOffset>(
3942        &self,
3943        start: T,
3944        scope_context: Option<CharScopeContext>,
3945    ) -> (Range<usize>, Option<CharKind>) {
3946        let mut start = start.to_offset(self);
3947        let mut end = start;
3948        let mut next_chars = self.chars_at(start).take(128).peekable();
3949        let mut prev_chars = self.reversed_chars_at(start).take(128).peekable();
3950
3951        let classifier = self.char_classifier_at(start).scope_context(scope_context);
3952        let word_kind = cmp::max(
3953            prev_chars.peek().copied().map(|c| classifier.kind(c)),
3954            next_chars.peek().copied().map(|c| classifier.kind(c)),
3955        );
3956
3957        for ch in prev_chars {
3958            if Some(classifier.kind(ch)) == word_kind && ch != '\n' {
3959                start -= ch.len_utf8();
3960            } else {
3961                break;
3962            }
3963        }
3964
3965        for ch in next_chars {
3966            if Some(classifier.kind(ch)) == word_kind && ch != '\n' {
3967                end += ch.len_utf8();
3968            } else {
3969                break;
3970            }
3971        }
3972
3973        (start..end, word_kind)
3974    }
3975
3976    /// Moves the TreeCursor to the smallest descendant or ancestor syntax node enclosing the given
3977    /// range. When `require_larger` is true, the node found must be larger than the query range.
3978    ///
3979    /// Returns true if a node was found, and false otherwise. In the `false` case the cursor will
3980    /// be moved to the root of the tree.
3981    fn goto_node_enclosing_range(
3982        cursor: &mut tree_sitter::TreeCursor,
3983        query_range: &Range<usize>,
3984        require_larger: bool,
3985    ) -> bool {
3986        let mut ascending = false;
3987        loop {
3988            let mut range = cursor.node().byte_range();
3989            if query_range.is_empty() {
3990                // When the query range is empty and the current node starts after it, move to the
3991                // previous sibling to find the node the containing node.
3992                if range.start > query_range.start {
3993                    cursor.goto_previous_sibling();
3994                    range = cursor.node().byte_range();
3995                }
3996            } else {
3997                // When the query range is non-empty and the current node ends exactly at the start,
3998                // move to the next sibling to find a node that extends beyond the start.
3999                if range.end == query_range.start {
4000                    cursor.goto_next_sibling();
4001                    range = cursor.node().byte_range();
4002                }
4003            }
4004
4005            let encloses = range.contains_inclusive(query_range)
4006                && (!require_larger || range.len() > query_range.len());
4007            if !encloses {
4008                ascending = true;
4009                if !cursor.goto_parent() {
4010                    return false;
4011                }
4012                continue;
4013            } else if ascending {
4014                return true;
4015            }
4016
4017            // Descend into the current node.
4018            if cursor
4019                .goto_first_child_for_byte(query_range.start)
4020                .is_none()
4021            {
4022                return true;
4023            }
4024        }
4025    }
4026
4027    pub fn syntax_ancestor<'a, T: ToOffset>(
4028        &'a self,
4029        range: Range<T>,
4030    ) -> Option<tree_sitter::Node<'a>> {
4031        let range = range.start.to_offset(self)..range.end.to_offset(self);
4032        let mut result: Option<tree_sitter::Node<'a>> = None;
4033        for layer in self
4034            .syntax
4035            .layers_for_range(range.clone(), &self.text, true)
4036        {
4037            let mut cursor = layer.node().walk();
4038
4039            // Find the node that both contains the range and is larger than it.
4040            if !Self::goto_node_enclosing_range(&mut cursor, &range, true) {
4041                continue;
4042            }
4043
4044            let left_node = cursor.node();
4045            let mut layer_result = left_node;
4046
4047            // For an empty range, try to find another node immediately to the right of the range.
4048            if left_node.end_byte() == range.start {
4049                let mut right_node = None;
4050                while !cursor.goto_next_sibling() {
4051                    if !cursor.goto_parent() {
4052                        break;
4053                    }
4054                }
4055
4056                while cursor.node().start_byte() == range.start {
4057                    right_node = Some(cursor.node());
4058                    if !cursor.goto_first_child() {
4059                        break;
4060                    }
4061                }
4062
4063                // If there is a candidate node on both sides of the (empty) range, then
4064                // decide between the two by favoring a named node over an anonymous token.
4065                // If both nodes are the same in that regard, favor the right one.
4066                if let Some(right_node) = right_node
4067                    && (right_node.is_named() || !left_node.is_named())
4068                {
4069                    layer_result = right_node;
4070                }
4071            }
4072
4073            if let Some(previous_result) = &result
4074                && previous_result.byte_range().len() < layer_result.byte_range().len()
4075            {
4076                continue;
4077            }
4078            result = Some(layer_result);
4079        }
4080
4081        result
4082    }
4083
4084    /// Find the previous sibling syntax node at the given range.
4085    ///
4086    /// This function locates the syntax node that precedes the node containing
4087    /// the given range. It searches hierarchically by:
4088    /// 1. Finding the node that contains the given range
4089    /// 2. Looking for the previous sibling at the same tree level
4090    /// 3. If no sibling is found, moving up to parent levels and searching for siblings
4091    ///
4092    /// Returns `None` if there is no previous sibling at any ancestor level.
4093    pub fn syntax_prev_sibling<'a, T: ToOffset>(
4094        &'a self,
4095        range: Range<T>,
4096    ) -> Option<tree_sitter::Node<'a>> {
4097        let range = range.start.to_offset(self)..range.end.to_offset(self);
4098        let mut result: Option<tree_sitter::Node<'a>> = None;
4099
4100        for layer in self
4101            .syntax
4102            .layers_for_range(range.clone(), &self.text, true)
4103        {
4104            let mut cursor = layer.node().walk();
4105
4106            // Find the node that contains the range
4107            if !Self::goto_node_enclosing_range(&mut cursor, &range, false) {
4108                continue;
4109            }
4110
4111            // Look for the previous sibling, moving up ancestor levels if needed
4112            loop {
4113                if cursor.goto_previous_sibling() {
4114                    let layer_result = cursor.node();
4115
4116                    if let Some(previous_result) = &result {
4117                        if previous_result.byte_range().end < layer_result.byte_range().end {
4118                            continue;
4119                        }
4120                    }
4121                    result = Some(layer_result);
4122                    break;
4123                }
4124
4125                // No sibling found at this level, try moving up to parent
4126                if !cursor.goto_parent() {
4127                    break;
4128                }
4129            }
4130        }
4131
4132        result
4133    }
4134
4135    /// Find the next sibling syntax node at the given range.
4136    ///
4137    /// This function locates the syntax node that follows the node containing
4138    /// the given range. It searches hierarchically by:
4139    /// 1. Finding the node that contains the given range
4140    /// 2. Looking for the next sibling at the same tree level
4141    /// 3. If no sibling is found, moving up to parent levels and searching for siblings
4142    ///
4143    /// Returns `None` if there is no next sibling at any ancestor level.
4144    pub fn syntax_next_sibling<'a, T: ToOffset>(
4145        &'a self,
4146        range: Range<T>,
4147    ) -> Option<tree_sitter::Node<'a>> {
4148        let range = range.start.to_offset(self)..range.end.to_offset(self);
4149        let mut result: Option<tree_sitter::Node<'a>> = None;
4150
4151        for layer in self
4152            .syntax
4153            .layers_for_range(range.clone(), &self.text, true)
4154        {
4155            let mut cursor = layer.node().walk();
4156
4157            // Find the node that contains the range
4158            if !Self::goto_node_enclosing_range(&mut cursor, &range, false) {
4159                continue;
4160            }
4161
4162            // Look for the next sibling, moving up ancestor levels if needed
4163            loop {
4164                if cursor.goto_next_sibling() {
4165                    let layer_result = cursor.node();
4166
4167                    if let Some(previous_result) = &result {
4168                        if previous_result.byte_range().start > layer_result.byte_range().start {
4169                            continue;
4170                        }
4171                    }
4172                    result = Some(layer_result);
4173                    break;
4174                }
4175
4176                // No sibling found at this level, try moving up to parent
4177                if !cursor.goto_parent() {
4178                    break;
4179                }
4180            }
4181        }
4182
4183        result
4184    }
4185
4186    /// Returns the root syntax node within the given row
4187    pub fn syntax_root_ancestor(&self, position: Anchor) -> Option<tree_sitter::Node<'_>> {
4188        let start_offset = position.to_offset(self);
4189
4190        let row = self.summary_for_anchor::<text::PointUtf16>(&position).row as usize;
4191
4192        let layer = self
4193            .syntax
4194            .layers_for_range(start_offset..start_offset, &self.text, true)
4195            .next()?;
4196
4197        let mut cursor = layer.node().walk();
4198
4199        // Descend to the first leaf that touches the start of the range.
4200        while cursor.goto_first_child_for_byte(start_offset).is_some() {
4201            if cursor.node().end_byte() == start_offset {
4202                cursor.goto_next_sibling();
4203            }
4204        }
4205
4206        // Ascend to the root node within the same row.
4207        while cursor.goto_parent() {
4208            if cursor.node().start_position().row != row {
4209                break;
4210            }
4211        }
4212
4213        Some(cursor.node())
4214    }
4215
4216    /// Returns the outline for the buffer.
4217    ///
4218    /// This method allows passing an optional [`SyntaxTheme`] to
4219    /// syntax-highlight the returned symbols.
4220    pub fn outline(&self, theme: Option<&SyntaxTheme>) -> Outline<Anchor> {
4221        Outline::new(self.outline_items_containing(0..self.len(), true, theme))
4222    }
4223
4224    /// Returns all the symbols that contain the given position.
4225    ///
4226    /// This method allows passing an optional [`SyntaxTheme`] to
4227    /// syntax-highlight the returned symbols.
4228    pub fn symbols_containing<T: ToOffset>(
4229        &self,
4230        position: T,
4231        theme: Option<&SyntaxTheme>,
4232    ) -> Vec<OutlineItem<Anchor>> {
4233        let position = position.to_offset(self);
4234        let start = self.clip_offset(position.saturating_sub(1), Bias::Left);
4235        let end = self.clip_offset(position + 1, Bias::Right);
4236        let mut items = self.outline_items_containing(start..end, false, theme);
4237        let mut prev_depth = None;
4238        items.retain(|item| {
4239            let result = prev_depth.is_none_or(|prev_depth| item.depth > prev_depth);
4240            prev_depth = Some(item.depth);
4241            result
4242        });
4243        items
4244    }
4245
4246    pub fn outline_range_containing<T: ToOffset>(&self, range: Range<T>) -> Option<Range<Point>> {
4247        let range = range.to_offset(self);
4248        let mut matches = self.syntax.matches(range.clone(), &self.text, |grammar| {
4249            grammar.outline_config.as_ref().map(|c| &c.query)
4250        });
4251        let configs = matches
4252            .grammars()
4253            .iter()
4254            .map(|g| g.outline_config.as_ref().unwrap())
4255            .collect::<Vec<_>>();
4256
4257        while let Some(mat) = matches.peek() {
4258            let config = &configs[mat.grammar_index];
4259            let containing_item_node = maybe!({
4260                let item_node = mat.captures.iter().find_map(|cap| {
4261                    if cap.index == config.item_capture_ix {
4262                        Some(cap.node)
4263                    } else {
4264                        None
4265                    }
4266                })?;
4267
4268                let item_byte_range = item_node.byte_range();
4269                if item_byte_range.end < range.start || item_byte_range.start > range.end {
4270                    None
4271                } else {
4272                    Some(item_node)
4273                }
4274            });
4275
4276            if let Some(item_node) = containing_item_node {
4277                return Some(
4278                    Point::from_ts_point(item_node.start_position())
4279                        ..Point::from_ts_point(item_node.end_position()),
4280                );
4281            }
4282
4283            matches.advance();
4284        }
4285        None
4286    }
4287
4288    pub fn outline_items_containing<T: ToOffset>(
4289        &self,
4290        range: Range<T>,
4291        include_extra_context: bool,
4292        theme: Option<&SyntaxTheme>,
4293    ) -> Vec<OutlineItem<Anchor>> {
4294        self.outline_items_containing_internal(
4295            range,
4296            include_extra_context,
4297            theme,
4298            |this, range| this.anchor_after(range.start)..this.anchor_before(range.end),
4299        )
4300    }
4301
4302    pub fn outline_items_as_points_containing<T: ToOffset>(
4303        &self,
4304        range: Range<T>,
4305        include_extra_context: bool,
4306        theme: Option<&SyntaxTheme>,
4307    ) -> Vec<OutlineItem<Point>> {
4308        self.outline_items_containing_internal(range, include_extra_context, theme, |_, range| {
4309            range
4310        })
4311    }
4312
4313    pub fn outline_items_as_offsets_containing<T: ToOffset>(
4314        &self,
4315        range: Range<T>,
4316        include_extra_context: bool,
4317        theme: Option<&SyntaxTheme>,
4318    ) -> Vec<OutlineItem<usize>> {
4319        self.outline_items_containing_internal(
4320            range,
4321            include_extra_context,
4322            theme,
4323            |buffer, range| range.to_offset(buffer),
4324        )
4325    }
4326
4327    fn outline_items_containing_internal<T: ToOffset, U>(
4328        &self,
4329        range: Range<T>,
4330        include_extra_context: bool,
4331        theme: Option<&SyntaxTheme>,
4332        range_callback: fn(&Self, Range<Point>) -> Range<U>,
4333    ) -> Vec<OutlineItem<U>> {
4334        let range = range.to_offset(self);
4335        let mut matches = self.syntax.matches(range.clone(), &self.text, |grammar| {
4336            grammar.outline_config.as_ref().map(|c| &c.query)
4337        });
4338
4339        let mut items = Vec::new();
4340        let mut annotation_row_ranges: Vec<Range<u32>> = Vec::new();
4341        while let Some(mat) = matches.peek() {
4342            let config = matches.grammars()[mat.grammar_index]
4343                .outline_config
4344                .as_ref()
4345                .unwrap();
4346            if let Some(item) =
4347                self.next_outline_item(config, &mat, &range, include_extra_context, theme)
4348            {
4349                items.push(item);
4350            } else if let Some(capture) = mat
4351                .captures
4352                .iter()
4353                .find(|capture| Some(capture.index) == config.annotation_capture_ix)
4354            {
4355                let capture_range = capture.node.start_position()..capture.node.end_position();
4356                let mut capture_row_range =
4357                    capture_range.start.row as u32..capture_range.end.row as u32;
4358                if capture_range.end.row > capture_range.start.row && capture_range.end.column == 0
4359                {
4360                    capture_row_range.end -= 1;
4361                }
4362                if let Some(last_row_range) = annotation_row_ranges.last_mut() {
4363                    if last_row_range.end >= capture_row_range.start.saturating_sub(1) {
4364                        last_row_range.end = capture_row_range.end;
4365                    } else {
4366                        annotation_row_ranges.push(capture_row_range);
4367                    }
4368                } else {
4369                    annotation_row_ranges.push(capture_row_range);
4370                }
4371            }
4372            matches.advance();
4373        }
4374
4375        items.sort_by_key(|item| (item.range.start, Reverse(item.range.end)));
4376
4377        // Assign depths based on containment relationships and convert to anchors.
4378        let mut item_ends_stack = Vec::<Point>::new();
4379        let mut anchor_items = Vec::new();
4380        let mut annotation_row_ranges = annotation_row_ranges.into_iter().peekable();
4381        for item in items {
4382            while let Some(last_end) = item_ends_stack.last().copied() {
4383                if last_end < item.range.end {
4384                    item_ends_stack.pop();
4385                } else {
4386                    break;
4387                }
4388            }
4389
4390            let mut annotation_row_range = None;
4391            while let Some(next_annotation_row_range) = annotation_row_ranges.peek() {
4392                let row_preceding_item = item.range.start.row.saturating_sub(1);
4393                if next_annotation_row_range.end < row_preceding_item {
4394                    annotation_row_ranges.next();
4395                } else {
4396                    if next_annotation_row_range.end == row_preceding_item {
4397                        annotation_row_range = Some(next_annotation_row_range.clone());
4398                        annotation_row_ranges.next();
4399                    }
4400                    break;
4401                }
4402            }
4403
4404            anchor_items.push(OutlineItem {
4405                depth: item_ends_stack.len(),
4406                range: range_callback(self, item.range.clone()),
4407                source_range_for_text: range_callback(self, item.source_range_for_text.clone()),
4408                text: item.text,
4409                highlight_ranges: item.highlight_ranges,
4410                name_ranges: item.name_ranges,
4411                body_range: item.body_range.map(|r| range_callback(self, r)),
4412                annotation_range: annotation_row_range.map(|annotation_range| {
4413                    let point_range = Point::new(annotation_range.start, 0)
4414                        ..Point::new(annotation_range.end, self.line_len(annotation_range.end));
4415                    range_callback(self, point_range)
4416                }),
4417            });
4418            item_ends_stack.push(item.range.end);
4419        }
4420
4421        anchor_items
4422    }
4423
4424    fn next_outline_item(
4425        &self,
4426        config: &OutlineConfig,
4427        mat: &SyntaxMapMatch,
4428        range: &Range<usize>,
4429        include_extra_context: bool,
4430        theme: Option<&SyntaxTheme>,
4431    ) -> Option<OutlineItem<Point>> {
4432        let item_node = mat.captures.iter().find_map(|cap| {
4433            if cap.index == config.item_capture_ix {
4434                Some(cap.node)
4435            } else {
4436                None
4437            }
4438        })?;
4439
4440        let item_byte_range = item_node.byte_range();
4441        if item_byte_range.end < range.start || item_byte_range.start > range.end {
4442            return None;
4443        }
4444        let item_point_range = Point::from_ts_point(item_node.start_position())
4445            ..Point::from_ts_point(item_node.end_position());
4446
4447        let mut open_point = None;
4448        let mut close_point = None;
4449
4450        let mut buffer_ranges = Vec::new();
4451        let mut add_to_buffer_ranges = |node: tree_sitter::Node, node_is_name| {
4452            let mut range = node.start_byte()..node.end_byte();
4453            let start = node.start_position();
4454            if node.end_position().row > start.row {
4455                range.end = range.start + self.line_len(start.row as u32) as usize - start.column;
4456            }
4457
4458            if !range.is_empty() {
4459                buffer_ranges.push((range, node_is_name));
4460            }
4461        };
4462
4463        for capture in mat.captures {
4464            if capture.index == config.name_capture_ix {
4465                add_to_buffer_ranges(capture.node, true);
4466            } else if Some(capture.index) == config.context_capture_ix
4467                || (Some(capture.index) == config.extra_context_capture_ix && include_extra_context)
4468            {
4469                add_to_buffer_ranges(capture.node, false);
4470            } else {
4471                if Some(capture.index) == config.open_capture_ix {
4472                    open_point = Some(Point::from_ts_point(capture.node.end_position()));
4473                } else if Some(capture.index) == config.close_capture_ix {
4474                    close_point = Some(Point::from_ts_point(capture.node.start_position()));
4475                }
4476            }
4477        }
4478
4479        if buffer_ranges.is_empty() {
4480            return None;
4481        }
4482        let source_range_for_text =
4483            buffer_ranges.first().unwrap().0.start..buffer_ranges.last().unwrap().0.end;
4484
4485        let mut text = String::new();
4486        let mut highlight_ranges = Vec::new();
4487        let mut name_ranges = Vec::new();
4488        let mut chunks = self.chunks(
4489            source_range_for_text.clone(),
4490            LanguageAwareStyling {
4491                tree_sitter: true,
4492                diagnostics: true,
4493            },
4494        );
4495        let mut last_buffer_range_end = 0;
4496        for (buffer_range, is_name) in buffer_ranges {
4497            let space_added = !text.is_empty() && buffer_range.start > last_buffer_range_end;
4498            if space_added {
4499                text.push(' ');
4500            }
4501            let before_append_len = text.len();
4502            let mut offset = buffer_range.start;
4503            chunks.seek(buffer_range.clone());
4504            for mut chunk in chunks.by_ref() {
4505                if chunk.text.len() > buffer_range.end - offset {
4506                    chunk.text = &chunk.text[0..(buffer_range.end - offset)];
4507                    offset = buffer_range.end;
4508                } else {
4509                    offset += chunk.text.len();
4510                }
4511                let style = chunk
4512                    .syntax_highlight_id
4513                    .zip(theme)
4514                    .and_then(|(highlight, theme)| theme.get(highlight).cloned());
4515
4516                if let Some(style) = style {
4517                    let start = text.len();
4518                    let end = start + chunk.text.len();
4519                    highlight_ranges.push((start..end, style));
4520                }
4521                text.push_str(chunk.text);
4522                if offset >= buffer_range.end {
4523                    break;
4524                }
4525            }
4526            if is_name {
4527                let after_append_len = text.len();
4528                let start = if space_added && !name_ranges.is_empty() {
4529                    before_append_len - 1
4530                } else {
4531                    before_append_len
4532                };
4533                name_ranges.push(start..after_append_len);
4534            }
4535            last_buffer_range_end = buffer_range.end;
4536        }
4537
4538        Some(OutlineItem {
4539            depth: 0, // We'll calculate the depth later
4540            range: item_point_range,
4541            source_range_for_text: source_range_for_text.to_point(self),
4542            text,
4543            highlight_ranges,
4544            name_ranges,
4545            body_range: open_point.zip(close_point).map(|(start, end)| start..end),
4546            annotation_range: None,
4547        })
4548    }
4549
4550    pub fn function_body_fold_ranges<T: ToOffset>(
4551        &self,
4552        within: Range<T>,
4553    ) -> impl Iterator<Item = Range<usize>> + '_ {
4554        self.text_object_ranges(within, TreeSitterOptions::default())
4555            .filter_map(|(range, obj)| (obj == TextObject::InsideFunction).then_some(range))
4556    }
4557
4558    /// For each grammar in the language, runs the provided
4559    /// [`tree_sitter::Query`] against the given range.
4560    pub fn matches(
4561        &self,
4562        range: Range<usize>,
4563        query: fn(&Grammar) -> Option<&tree_sitter::Query>,
4564    ) -> SyntaxMapMatches<'_> {
4565        self.syntax.matches(range, self, query)
4566    }
4567
4568    /// Finds all [`RowChunks`] applicable to the given range, then returns all bracket pairs that intersect with those chunks.
4569    /// Hence, may return more bracket pairs than the range contains.
4570    ///
4571    /// Will omit known chunks.
4572    /// The resulting bracket match collections are not ordered.
4573    pub fn fetch_bracket_ranges(
4574        &self,
4575        range: Range<usize>,
4576        known_chunks: Option<&HashSet<Range<BufferRow>>>,
4577    ) -> HashMap<Range<BufferRow>, Vec<BracketMatch<usize>>> {
4578        let mut all_bracket_matches = HashMap::default();
4579
4580        for chunk in self
4581            .tree_sitter_data
4582            .chunks
4583            .applicable_chunks(&[range.to_point(self)])
4584        {
4585            if known_chunks.is_some_and(|chunks| chunks.contains(&chunk.row_range())) {
4586                continue;
4587            }
4588            let chunk_range = chunk.anchor_range();
4589            let chunk_range = chunk_range.to_offset(&self);
4590
4591            if let Some(cached_brackets) =
4592                &self.tree_sitter_data.brackets_by_chunks.lock()[chunk.id]
4593            {
4594                all_bracket_matches.insert(chunk.row_range(), cached_brackets.clone());
4595                continue;
4596            }
4597
4598            let mut all_brackets: Vec<(BracketMatch<usize>, usize, bool)> = Vec::new();
4599            let mut opens = Vec::new();
4600            let mut color_pairs = Vec::new();
4601
4602            let mut matches = self.syntax.matches_with_options(
4603                chunk_range.clone(),
4604                &self.text,
4605                TreeSitterOptions {
4606                    max_bytes_to_query: Some(MAX_BYTES_TO_QUERY),
4607                    max_start_depth: None,
4608                },
4609                |grammar| grammar.brackets_config.as_ref().map(|c| &c.query),
4610            );
4611            let configs = matches
4612                .grammars()
4613                .iter()
4614                .map(|grammar| grammar.brackets_config.as_ref().unwrap())
4615                .collect::<Vec<_>>();
4616
4617            // Group matches by open range so we can either trust grammar output
4618            // or repair it by picking a single closest close per open.
4619            let mut open_to_close_ranges = BTreeMap::new();
4620            while let Some(mat) = matches.peek() {
4621                let mut open = None;
4622                let mut close = None;
4623                let syntax_layer_depth = mat.depth;
4624                let pattern_index = mat.pattern_index;
4625                let config = configs[mat.grammar_index];
4626                let pattern = &config.patterns[pattern_index];
4627                for capture in mat.captures {
4628                    if capture.index == config.open_capture_ix {
4629                        open = Some(capture.node.byte_range());
4630                    } else if capture.index == config.close_capture_ix {
4631                        close = Some(capture.node.byte_range());
4632                    }
4633                }
4634
4635                matches.advance();
4636
4637                let Some((open_range, close_range)) = open.zip(close) else {
4638                    continue;
4639                };
4640
4641                let bracket_range = open_range.start..=close_range.end;
4642                if !bracket_range.overlaps(&chunk_range) {
4643                    continue;
4644                }
4645
4646                open_to_close_ranges
4647                    .entry((open_range.start, open_range.end, pattern_index))
4648                    .or_insert_with(BTreeMap::new)
4649                    .insert(
4650                        (close_range.start, close_range.end),
4651                        BracketMatch {
4652                            open_range: open_range.clone(),
4653                            close_range: close_range.clone(),
4654                            syntax_layer_depth,
4655                            newline_only: pattern.newline_only,
4656                            color_index: None,
4657                        },
4658                    );
4659
4660                all_brackets.push((
4661                    BracketMatch {
4662                        open_range,
4663                        close_range,
4664                        syntax_layer_depth,
4665                        newline_only: pattern.newline_only,
4666                        color_index: None,
4667                    },
4668                    pattern_index,
4669                    pattern.rainbow_exclude,
4670                ));
4671            }
4672
4673            let has_bogus_matches = open_to_close_ranges
4674                .iter()
4675                .any(|(_, end_ranges)| end_ranges.len() > 1);
4676            if has_bogus_matches {
4677                // Grammar is producing bogus matches where one open is paired with multiple
4678                // closes. Build a valid stack by walking through positions in order.
4679                // For each close, we know the expected open_len from tree-sitter matches.
4680
4681                // Map each close to its expected open length (for inferring opens)
4682                let close_to_open_len: HashMap<(usize, usize, usize), usize> = all_brackets
4683                    .iter()
4684                    .map(|(bracket_match, pattern_index, _)| {
4685                        (
4686                            (
4687                                bracket_match.close_range.start,
4688                                bracket_match.close_range.end,
4689                                *pattern_index,
4690                            ),
4691                            bracket_match.open_range.len(),
4692                        )
4693                    })
4694                    .collect();
4695
4696                // Collect unique opens and closes within this chunk
4697                let mut unique_opens: HashSet<(usize, usize, usize)> = all_brackets
4698                    .iter()
4699                    .map(|(bracket_match, pattern_index, _)| {
4700                        (
4701                            bracket_match.open_range.start,
4702                            bracket_match.open_range.end,
4703                            *pattern_index,
4704                        )
4705                    })
4706                    .filter(|(start, _, _)| chunk_range.contains(start))
4707                    .collect();
4708
4709                let mut unique_closes: Vec<(usize, usize, usize)> = all_brackets
4710                    .iter()
4711                    .map(|(bracket_match, pattern_index, _)| {
4712                        (
4713                            bracket_match.close_range.start,
4714                            bracket_match.close_range.end,
4715                            *pattern_index,
4716                        )
4717                    })
4718                    .filter(|(start, _, _)| chunk_range.contains(start))
4719                    .collect();
4720                unique_closes.sort();
4721                unique_closes.dedup();
4722
4723                // Build valid pairs by walking through closes in order
4724                let mut unique_opens_vec: Vec<_> = unique_opens.iter().copied().collect();
4725                unique_opens_vec.sort();
4726
4727                let mut valid_pairs: HashSet<((usize, usize, usize), (usize, usize, usize))> =
4728                    HashSet::default();
4729                let mut open_stacks: HashMap<usize, Vec<(usize, usize)>> = HashMap::default();
4730                let mut open_idx = 0;
4731
4732                for close in &unique_closes {
4733                    // Push all opens before this close onto stack
4734                    while open_idx < unique_opens_vec.len()
4735                        && unique_opens_vec[open_idx].0 < close.0
4736                    {
4737                        let (start, end, pattern_index) = unique_opens_vec[open_idx];
4738                        open_stacks
4739                            .entry(pattern_index)
4740                            .or_default()
4741                            .push((start, end));
4742                        open_idx += 1;
4743                    }
4744
4745                    // Try to match with most recent open
4746                    let (close_start, close_end, pattern_index) = *close;
4747                    if let Some(open) = open_stacks
4748                        .get_mut(&pattern_index)
4749                        .and_then(|open_stack| open_stack.pop())
4750                    {
4751                        valid_pairs.insert(((open.0, open.1, pattern_index), *close));
4752                    } else if let Some(&open_len) = close_to_open_len.get(close) {
4753                        // No open on stack - infer one based on expected open_len
4754                        if close_start >= open_len {
4755                            let inferred = (close_start - open_len, close_start, pattern_index);
4756                            unique_opens.insert(inferred);
4757                            valid_pairs.insert((inferred, *close));
4758                            all_brackets.push((
4759                                BracketMatch {
4760                                    open_range: inferred.0..inferred.1,
4761                                    close_range: close_start..close_end,
4762                                    newline_only: false,
4763                                    syntax_layer_depth: 0,
4764                                    color_index: None,
4765                                },
4766                                pattern_index,
4767                                false,
4768                            ));
4769                        }
4770                    }
4771                }
4772
4773                all_brackets.retain(|(bracket_match, pattern_index, _)| {
4774                    let open = (
4775                        bracket_match.open_range.start,
4776                        bracket_match.open_range.end,
4777                        *pattern_index,
4778                    );
4779                    let close = (
4780                        bracket_match.close_range.start,
4781                        bracket_match.close_range.end,
4782                        *pattern_index,
4783                    );
4784                    valid_pairs.contains(&(open, close))
4785                });
4786            }
4787
4788            let mut all_brackets = all_brackets
4789                .into_iter()
4790                .enumerate()
4791                .map(|(index, (bracket_match, _, rainbow_exclude))| {
4792                    // Certain languages have "brackets" that are not brackets, e.g. tags. and such
4793                    // bracket will match the entire tag with all text inside.
4794                    // For now, avoid highlighting any pair that has more than single char in each bracket.
4795                    // We need to  colorize `<Element/>` bracket pairs, so cannot make this check stricter.
4796                    let should_color = !rainbow_exclude
4797                        && (bracket_match.open_range.len() == 1
4798                            || bracket_match.close_range.len() == 1);
4799                    if should_color {
4800                        opens.push(bracket_match.open_range.clone());
4801                        color_pairs.push((
4802                            bracket_match.open_range.clone(),
4803                            bracket_match.close_range.clone(),
4804                            index,
4805                        ));
4806                    }
4807                    bracket_match
4808                })
4809                .collect::<Vec<_>>();
4810
4811            opens.sort_by_key(|r| (r.start, r.end));
4812            opens.dedup_by(|a, b| a.start == b.start && a.end == b.end);
4813            color_pairs.sort_by_key(|(_, close, _)| close.end);
4814
4815            let mut open_stack = Vec::new();
4816            let mut open_index = 0;
4817            for (open, close, index) in color_pairs {
4818                while open_index < opens.len() && opens[open_index].start < close.start {
4819                    open_stack.push(opens[open_index].clone());
4820                    open_index += 1;
4821                }
4822
4823                if open_stack.last() == Some(&open) {
4824                    let depth_index = open_stack.len() - 1;
4825                    all_brackets[index].color_index = Some(depth_index);
4826                    open_stack.pop();
4827                }
4828            }
4829
4830            all_brackets.sort_by_key(|bracket_match| {
4831                (bracket_match.open_range.start, bracket_match.open_range.end)
4832            });
4833
4834            if let empty_slot @ None =
4835                &mut self.tree_sitter_data.brackets_by_chunks.lock()[chunk.id]
4836            {
4837                *empty_slot = Some(all_brackets.clone());
4838            }
4839            all_bracket_matches.insert(chunk.row_range(), all_brackets);
4840        }
4841
4842        all_bracket_matches
4843    }
4844
4845    pub fn all_bracket_ranges(
4846        &self,
4847        range: Range<usize>,
4848    ) -> impl Iterator<Item = BracketMatch<usize>> {
4849        self.fetch_bracket_ranges(range.clone(), None)
4850            .into_values()
4851            .flatten()
4852            .filter(move |bracket_match| {
4853                let bracket_range = bracket_match.open_range.start..bracket_match.close_range.end;
4854                bracket_range.overlaps(&range)
4855            })
4856    }
4857
4858    /// Returns bracket range pairs overlapping or adjacent to `range`
4859    pub fn bracket_ranges<T: ToOffset>(
4860        &self,
4861        range: Range<T>,
4862    ) -> impl Iterator<Item = BracketMatch<usize>> + '_ {
4863        // Find bracket pairs that *inclusively* contain the given range.
4864        let range = range.start.to_previous_offset(self)..range.end.to_next_offset(self);
4865        self.all_bracket_ranges(range)
4866            .filter(|pair| !pair.newline_only)
4867    }
4868
4869    pub fn debug_variables_query<T: ToOffset>(
4870        &self,
4871        range: Range<T>,
4872    ) -> impl Iterator<Item = (Range<usize>, DebuggerTextObject)> + '_ {
4873        let range = range.start.to_previous_offset(self)..range.end.to_next_offset(self);
4874
4875        let mut matches = self.syntax.matches_with_options(
4876            range.clone(),
4877            &self.text,
4878            TreeSitterOptions::default(),
4879            |grammar| grammar.debug_variables_config.as_ref().map(|c| &c.query),
4880        );
4881
4882        let configs = matches
4883            .grammars()
4884            .iter()
4885            .map(|grammar| grammar.debug_variables_config.as_ref())
4886            .collect::<Vec<_>>();
4887
4888        let mut captures = Vec::<(Range<usize>, DebuggerTextObject)>::new();
4889
4890        iter::from_fn(move || {
4891            loop {
4892                while let Some(capture) = captures.pop() {
4893                    if capture.0.overlaps(&range) {
4894                        return Some(capture);
4895                    }
4896                }
4897
4898                let mat = matches.peek()?;
4899
4900                let Some(config) = configs[mat.grammar_index].as_ref() else {
4901                    matches.advance();
4902                    continue;
4903                };
4904
4905                for capture in mat.captures {
4906                    let Some(ix) = config
4907                        .objects_by_capture_ix
4908                        .binary_search_by_key(&capture.index, |e| e.0)
4909                        .ok()
4910                    else {
4911                        continue;
4912                    };
4913                    let text_object = config.objects_by_capture_ix[ix].1;
4914                    let byte_range = capture.node.byte_range();
4915
4916                    let mut found = false;
4917                    for (range, existing) in captures.iter_mut() {
4918                        if existing == &text_object {
4919                            range.start = range.start.min(byte_range.start);
4920                            range.end = range.end.max(byte_range.end);
4921                            found = true;
4922                            break;
4923                        }
4924                    }
4925
4926                    if !found {
4927                        captures.push((byte_range, text_object));
4928                    }
4929                }
4930
4931                matches.advance();
4932            }
4933        })
4934    }
4935
4936    pub fn text_object_ranges<T: ToOffset>(
4937        &self,
4938        range: Range<T>,
4939        options: TreeSitterOptions,
4940    ) -> impl Iterator<Item = (Range<usize>, TextObject)> + '_ {
4941        let range =
4942            range.start.to_previous_offset(self)..self.len().min(range.end.to_next_offset(self));
4943
4944        let mut matches =
4945            self.syntax
4946                .matches_with_options(range.clone(), &self.text, options, |grammar| {
4947                    grammar.text_object_config.as_ref().map(|c| &c.query)
4948                });
4949
4950        let configs = matches
4951            .grammars()
4952            .iter()
4953            .map(|grammar| grammar.text_object_config.as_ref())
4954            .collect::<Vec<_>>();
4955
4956        let mut captures = Vec::<(Range<usize>, TextObject)>::new();
4957
4958        iter::from_fn(move || {
4959            loop {
4960                while let Some(capture) = captures.pop() {
4961                    if capture.0.overlaps(&range) {
4962                        return Some(capture);
4963                    }
4964                }
4965
4966                let mat = matches.peek()?;
4967
4968                let Some(config) = configs[mat.grammar_index].as_ref() else {
4969                    matches.advance();
4970                    continue;
4971                };
4972
4973                for capture in mat.captures {
4974                    let Some(ix) = config
4975                        .text_objects_by_capture_ix
4976                        .binary_search_by_key(&capture.index, |e| e.0)
4977                        .ok()
4978                    else {
4979                        continue;
4980                    };
4981                    let text_object = config.text_objects_by_capture_ix[ix].1;
4982                    let byte_range = capture.node.byte_range();
4983
4984                    let mut found = false;
4985                    for (range, existing) in captures.iter_mut() {
4986                        if existing == &text_object {
4987                            range.start = range.start.min(byte_range.start);
4988                            range.end = range.end.max(byte_range.end);
4989                            found = true;
4990                            break;
4991                        }
4992                    }
4993
4994                    if !found {
4995                        captures.push((byte_range, text_object));
4996                    }
4997                }
4998
4999                matches.advance();
5000            }
5001        })
5002    }
5003
5004    /// Returns enclosing bracket ranges containing the given range
5005    pub fn enclosing_bracket_ranges<T: ToOffset>(
5006        &self,
5007        range: Range<T>,
5008    ) -> impl Iterator<Item = BracketMatch<usize>> + '_ {
5009        let range = range.start.to_offset(self)..range.end.to_offset(self);
5010
5011        let result: Vec<_> = self.bracket_ranges(range.clone()).collect();
5012        let max_depth = result
5013            .iter()
5014            .map(|mat| mat.syntax_layer_depth)
5015            .max()
5016            .unwrap_or(0);
5017        result.into_iter().filter(move |pair| {
5018            pair.open_range.start <= range.start
5019                && pair.close_range.end >= range.end
5020                && pair.syntax_layer_depth == max_depth
5021        })
5022    }
5023
5024    /// Returns the smallest enclosing bracket ranges containing the given range or None if no brackets contain range
5025    ///
5026    /// Can optionally pass a range_filter to filter the ranges of brackets to consider
5027    pub fn innermost_enclosing_bracket_ranges<T: ToOffset>(
5028        &self,
5029        range: Range<T>,
5030        range_filter: Option<&dyn Fn(Range<usize>, Range<usize>) -> bool>,
5031    ) -> Option<(Range<usize>, Range<usize>)> {
5032        let range = range.start.to_offset(self)..range.end.to_offset(self);
5033
5034        // Get the ranges of the innermost pair of brackets.
5035        let mut result: Option<(Range<usize>, Range<usize>)> = None;
5036
5037        for pair in self.enclosing_bracket_ranges(range) {
5038            if let Some(range_filter) = range_filter
5039                && !range_filter(pair.open_range.clone(), pair.close_range.clone())
5040            {
5041                continue;
5042            }
5043
5044            let len = pair.close_range.end - pair.open_range.start;
5045
5046            if let Some((existing_open, existing_close)) = &result {
5047                let existing_len = existing_close.end - existing_open.start;
5048                if len > existing_len {
5049                    continue;
5050                }
5051            }
5052
5053            result = Some((pair.open_range, pair.close_range));
5054        }
5055
5056        result
5057    }
5058
5059    /// Returns anchor ranges for any matches of the redaction query.
5060    /// The buffer can be associated with multiple languages, and the redaction query associated with each
5061    /// will be run on the relevant section of the buffer.
5062    pub fn redacted_ranges<T: ToOffset>(
5063        &self,
5064        range: Range<T>,
5065    ) -> impl Iterator<Item = Range<usize>> + '_ {
5066        let offset_range = range.start.to_offset(self)..range.end.to_offset(self);
5067        let mut syntax_matches = self.syntax.matches(offset_range, self, |grammar| {
5068            grammar
5069                .redactions_config
5070                .as_ref()
5071                .map(|config| &config.query)
5072        });
5073
5074        let configs = syntax_matches
5075            .grammars()
5076            .iter()
5077            .map(|grammar| grammar.redactions_config.as_ref())
5078            .collect::<Vec<_>>();
5079
5080        iter::from_fn(move || {
5081            let redacted_range = syntax_matches
5082                .peek()
5083                .and_then(|mat| {
5084                    configs[mat.grammar_index].and_then(|config| {
5085                        mat.captures
5086                            .iter()
5087                            .find(|capture| capture.index == config.redaction_capture_ix)
5088                    })
5089                })
5090                .map(|mat| mat.node.byte_range());
5091            syntax_matches.advance();
5092            redacted_range
5093        })
5094    }
5095
5096    pub fn injections_intersecting_range<T: ToOffset>(
5097        &self,
5098        range: Range<T>,
5099    ) -> impl Iterator<Item = (Range<usize>, &Arc<Language>)> + '_ {
5100        let offset_range = range.start.to_offset(self)..range.end.to_offset(self);
5101
5102        let mut syntax_matches = self.syntax.matches(offset_range, self, |grammar| {
5103            grammar
5104                .injection_config
5105                .as_ref()
5106                .map(|config| &config.query)
5107        });
5108
5109        let configs = syntax_matches
5110            .grammars()
5111            .iter()
5112            .map(|grammar| grammar.injection_config.as_ref())
5113            .collect::<Vec<_>>();
5114
5115        iter::from_fn(move || {
5116            let ranges = syntax_matches.peek().and_then(|mat| {
5117                let config = &configs[mat.grammar_index]?;
5118                let content_capture_range = mat.captures.iter().find_map(|capture| {
5119                    if capture.index == config.content_capture_ix {
5120                        Some(capture.node.byte_range())
5121                    } else {
5122                        None
5123                    }
5124                })?;
5125                let language = self.language_at(content_capture_range.start)?;
5126                Some((content_capture_range, language))
5127            });
5128            syntax_matches.advance();
5129            ranges
5130        })
5131    }
5132
5133    pub fn runnable_ranges(
5134        &self,
5135        offset_range: Range<usize>,
5136    ) -> impl Iterator<Item = RunnableRange> + '_ {
5137        let mut syntax_matches = self.syntax.matches(offset_range, self, |grammar| {
5138            grammar.runnable_config.as_ref().map(|config| &config.query)
5139        });
5140
5141        let test_configs = syntax_matches
5142            .grammars()
5143            .iter()
5144            .map(|grammar| grammar.runnable_config.as_ref())
5145            .collect::<Vec<_>>();
5146
5147        iter::from_fn(move || {
5148            loop {
5149                let mat = syntax_matches.peek()?;
5150
5151                let test_range = test_configs[mat.grammar_index].and_then(|test_configs| {
5152                    let mut run_range = None;
5153                    let full_range = mat.captures.iter().fold(
5154                        Range {
5155                            start: usize::MAX,
5156                            end: 0,
5157                        },
5158                        |mut acc, next| {
5159                            let byte_range = next.node.byte_range();
5160                            if acc.start > byte_range.start {
5161                                acc.start = byte_range.start;
5162                            }
5163                            if acc.end < byte_range.end {
5164                                acc.end = byte_range.end;
5165                            }
5166                            acc
5167                        },
5168                    );
5169                    if full_range.start > full_range.end {
5170                        // We did not find a full spanning range of this match.
5171                        return None;
5172                    }
5173                    let extra_captures: SmallVec<[_; 1]> =
5174                        SmallVec::from_iter(mat.captures.iter().filter_map(|capture| {
5175                            test_configs
5176                                .extra_captures
5177                                .get(capture.index as usize)
5178                                .cloned()
5179                                .and_then(|tag_name| match tag_name {
5180                                    RunnableCapture::Named(name) => {
5181                                        Some((capture.node.byte_range(), name))
5182                                    }
5183                                    RunnableCapture::Run => {
5184                                        let _ = run_range.insert(capture.node.byte_range());
5185                                        None
5186                                    }
5187                                })
5188                        }));
5189                    let run_range = run_range?;
5190                    let tags = test_configs
5191                        .query
5192                        .property_settings(mat.pattern_index)
5193                        .iter()
5194                        .filter_map(|property| {
5195                            if *property.key == *"tag" {
5196                                property
5197                                    .value
5198                                    .as_ref()
5199                                    .map(|value| RunnableTag(value.to_string().into()))
5200                            } else {
5201                                None
5202                            }
5203                        })
5204                        .collect();
5205                    let extra_captures = extra_captures
5206                        .into_iter()
5207                        .map(|(range, name)| {
5208                            (
5209                                name.to_string(),
5210                                self.text_for_range(range).collect::<String>(),
5211                            )
5212                        })
5213                        .collect();
5214                    // All tags should have the same range.
5215                    Some(RunnableRange {
5216                        run_range,
5217                        full_range,
5218                        runnable: Runnable {
5219                            tags,
5220                            language: mat.language,
5221                            buffer: self.remote_id(),
5222                        },
5223                        extra_captures,
5224                        buffer_id: self.remote_id(),
5225                    })
5226                });
5227
5228                syntax_matches.advance();
5229                if test_range.is_some() {
5230                    // It's fine for us to short-circuit on .peek()? returning None. We don't want to return None from this iter if we
5231                    // had a capture that did not contain a run marker, hence we'll just loop around for the next capture.
5232                    return test_range;
5233                }
5234            }
5235        })
5236    }
5237
5238    /// Returns selections for remote peers intersecting the given range.
5239    #[allow(clippy::type_complexity)]
5240    pub fn selections_in_range(
5241        &self,
5242        range: Range<Anchor>,
5243        include_local: bool,
5244    ) -> impl Iterator<
5245        Item = (
5246            ReplicaId,
5247            bool,
5248            CursorShape,
5249            impl Iterator<Item = &Selection<Anchor>> + '_,
5250        ),
5251    > + '_ {
5252        self.remote_selections
5253            .iter()
5254            .filter(move |(replica_id, set)| {
5255                (include_local || **replica_id != self.text.replica_id())
5256                    && !set.selections.is_empty()
5257            })
5258            .map(move |(replica_id, set)| {
5259                let start_ix = match set.selections.binary_search_by(|probe| {
5260                    probe.end.cmp(&range.start, self).then(Ordering::Greater)
5261                }) {
5262                    Ok(ix) | Err(ix) => ix,
5263                };
5264                let end_ix = match set.selections.binary_search_by(|probe| {
5265                    probe.start.cmp(&range.end, self).then(Ordering::Less)
5266                }) {
5267                    Ok(ix) | Err(ix) => ix,
5268                };
5269
5270                (
5271                    *replica_id,
5272                    set.line_mode,
5273                    set.cursor_shape,
5274                    set.selections[start_ix..end_ix].iter(),
5275                )
5276            })
5277    }
5278
5279    /// Returns if the buffer contains any diagnostics.
5280    pub fn has_diagnostics(&self) -> bool {
5281        !self.diagnostics.is_empty()
5282    }
5283
5284    /// Returns all the diagnostics intersecting the given range.
5285    pub fn diagnostics_in_range<'a, T, O>(
5286        &'a self,
5287        search_range: Range<T>,
5288        reversed: bool,
5289    ) -> impl 'a + Iterator<Item = DiagnosticEntryRef<'a, O>>
5290    where
5291        T: 'a + Clone + ToOffset,
5292        O: 'a + FromAnchor,
5293    {
5294        let mut iterators: Vec<_> = self
5295            .diagnostics
5296            .iter()
5297            .map(|(_, collection)| {
5298                collection
5299                    .range::<T, text::Anchor>(search_range.clone(), self, true, reversed)
5300                    .peekable()
5301            })
5302            .collect();
5303
5304        std::iter::from_fn(move || {
5305            let (next_ix, _) = iterators
5306                .iter_mut()
5307                .enumerate()
5308                .flat_map(|(ix, iter)| Some((ix, iter.peek()?)))
5309                .min_by(|(_, a), (_, b)| {
5310                    let cmp = a
5311                        .range
5312                        .start
5313                        .cmp(&b.range.start, self)
5314                        // when range is equal, sort by diagnostic severity
5315                        .then(a.diagnostic.severity.cmp(&b.diagnostic.severity))
5316                        // and stabilize order with group_id
5317                        .then(a.diagnostic.group_id.cmp(&b.diagnostic.group_id));
5318                    if reversed { cmp.reverse() } else { cmp }
5319                })?;
5320            iterators[next_ix]
5321                .next()
5322                .map(
5323                    |DiagnosticEntryRef { range, diagnostic }| DiagnosticEntryRef {
5324                        diagnostic,
5325                        range: FromAnchor::from_anchor(&range.start, self)
5326                            ..FromAnchor::from_anchor(&range.end, self),
5327                    },
5328                )
5329        })
5330    }
5331
5332    /// Returns all the diagnostic groups associated with the given
5333    /// language server ID. If no language server ID is provided,
5334    /// all diagnostics groups are returned.
5335    pub fn diagnostic_groups(
5336        &self,
5337        language_server_id: Option<LanguageServerId>,
5338    ) -> Vec<(LanguageServerId, DiagnosticGroup<'_, Anchor>)> {
5339        let mut groups = Vec::new();
5340
5341        if let Some(language_server_id) = language_server_id {
5342            if let Some(set) = self.diagnostics.get(&language_server_id) {
5343                set.groups(language_server_id, &mut groups, self);
5344            }
5345        } else {
5346            for (language_server_id, diagnostics) in self.diagnostics.iter() {
5347                diagnostics.groups(*language_server_id, &mut groups, self);
5348            }
5349        }
5350
5351        groups.sort_by(|(id_a, group_a), (id_b, group_b)| {
5352            let a_start = &group_a.entries[group_a.primary_ix].range.start;
5353            let b_start = &group_b.entries[group_b.primary_ix].range.start;
5354            a_start.cmp(b_start, self).then_with(|| id_a.cmp(id_b))
5355        });
5356
5357        groups
5358    }
5359
5360    /// Returns an iterator over the diagnostics for the given group.
5361    pub fn diagnostic_group<O>(
5362        &self,
5363        group_id: usize,
5364    ) -> impl Iterator<Item = DiagnosticEntryRef<'_, O>> + use<'_, O>
5365    where
5366        O: FromAnchor + 'static,
5367    {
5368        self.diagnostics
5369            .iter()
5370            .flat_map(move |(_, set)| set.group(group_id, self))
5371    }
5372
5373    /// An integer version number that accounts for all updates besides
5374    /// the buffer's text itself (which is versioned via a version vector).
5375    pub fn non_text_state_update_count(&self) -> usize {
5376        self.non_text_state_update_count
5377    }
5378
5379    /// An integer version that changes when the buffer's syntax changes.
5380    pub fn syntax_update_count(&self) -> usize {
5381        self.syntax.update_count()
5382    }
5383
5384    /// Returns a snapshot of underlying file.
5385    pub fn file(&self) -> Option<&Arc<dyn File>> {
5386        self.file.as_ref()
5387    }
5388
5389    pub fn resolve_file_path(&self, include_root: bool, cx: &App) -> Option<String> {
5390        if let Some(file) = self.file() {
5391            if file.path().file_name().is_none() || include_root {
5392                Some(file.full_path(cx).to_string_lossy().into_owned())
5393            } else {
5394                Some(file.path().display(file.path_style(cx)).to_string())
5395            }
5396        } else {
5397            None
5398        }
5399    }
5400
5401    pub fn words_in_range(&self, query: WordsQuery) -> BTreeMap<String, Range<Anchor>> {
5402        let query_str = query.fuzzy_contents;
5403        if query_str.is_some_and(|query| query.is_empty()) {
5404            return BTreeMap::default();
5405        }
5406
5407        let classifier = CharClassifier::new(self.language.clone().map(|language| LanguageScope {
5408            language,
5409            override_id: None,
5410        }));
5411
5412        let mut query_ix = 0;
5413        let query_chars = query_str.map(|query| query.chars().collect::<Vec<_>>());
5414        let query_len = query_chars.as_ref().map_or(0, |query| query.len());
5415
5416        let mut words = BTreeMap::default();
5417        let mut current_word_start_ix = None;
5418        let mut chunk_ix = query.range.start;
5419        for chunk in self.chunks(
5420            query.range,
5421            LanguageAwareStyling {
5422                tree_sitter: false,
5423                diagnostics: false,
5424            },
5425        ) {
5426            for (i, c) in chunk.text.char_indices() {
5427                let ix = chunk_ix + i;
5428                if classifier.is_word(c) {
5429                    if current_word_start_ix.is_none() {
5430                        current_word_start_ix = Some(ix);
5431                    }
5432
5433                    if let Some(query_chars) = &query_chars
5434                        && query_ix < query_len
5435                        && c.to_lowercase().eq(query_chars[query_ix].to_lowercase())
5436                    {
5437                        query_ix += 1;
5438                    }
5439                    continue;
5440                } else if let Some(word_start) = current_word_start_ix.take()
5441                    && query_ix == query_len
5442                {
5443                    let word_range = self.anchor_before(word_start)..self.anchor_after(ix);
5444                    let mut word_text = self.text_for_range(word_start..ix).peekable();
5445                    let first_char = word_text
5446                        .peek()
5447                        .and_then(|first_chunk| first_chunk.chars().next());
5448                    // Skip empty and "words" starting with digits as a heuristic to reduce useless completions
5449                    if !query.skip_digits
5450                        || first_char.is_none_or(|first_char| !first_char.is_digit(10))
5451                    {
5452                        words.insert(word_text.collect(), word_range);
5453                    }
5454                }
5455                query_ix = 0;
5456            }
5457            chunk_ix += chunk.text.len();
5458        }
5459
5460        words
5461    }
5462}
5463
5464/// A configuration to use when producing styled text chunks.
5465#[derive(Clone, Copy)]
5466pub struct LanguageAwareStyling {
5467    /// Whether to highlight text chunks using tree-sitter.
5468    pub tree_sitter: bool,
5469    /// Whether to highlight text chunks based on the diagnostics data.
5470    pub diagnostics: bool,
5471}
5472
5473pub struct WordsQuery<'a> {
5474    /// Only returns words with all chars from the fuzzy string in them.
5475    pub fuzzy_contents: Option<&'a str>,
5476    /// Skips words that start with a digit.
5477    pub skip_digits: bool,
5478    /// Buffer offset range, to look for words.
5479    pub range: Range<usize>,
5480}
5481
5482fn indent_size_for_line(text: &text::BufferSnapshot, row: u32) -> IndentSize {
5483    indent_size_for_text(text.chars_at(Point::new(row, 0)))
5484}
5485
5486fn indent_size_for_text(text: impl Iterator<Item = char>) -> IndentSize {
5487    let mut result = IndentSize::spaces(0);
5488    for c in text {
5489        let kind = match c {
5490            ' ' => IndentKind::Space,
5491            '\t' => IndentKind::Tab,
5492            _ => break,
5493        };
5494        if result.len == 0 {
5495            result.kind = kind;
5496        }
5497        result.len += 1;
5498    }
5499    result
5500}
5501
5502impl Clone for BufferSnapshot {
5503    fn clone(&self) -> Self {
5504        Self {
5505            text: self.text.clone(),
5506            syntax: self.syntax.clone(),
5507            file: self.file.clone(),
5508            remote_selections: self.remote_selections.clone(),
5509            diagnostics: self.diagnostics.clone(),
5510            language: self.language.clone(),
5511            tree_sitter_data: self.tree_sitter_data.clone(),
5512            non_text_state_update_count: self.non_text_state_update_count,
5513            capability: self.capability,
5514            modeline: self.modeline.clone(),
5515        }
5516    }
5517}
5518
5519impl Deref for BufferSnapshot {
5520    type Target = text::BufferSnapshot;
5521
5522    fn deref(&self) -> &Self::Target {
5523        &self.text
5524    }
5525}
5526
5527unsafe impl Send for BufferChunks<'_> {}
5528
5529impl<'a> BufferChunks<'a> {
5530    pub(crate) fn new(
5531        text: &'a Rope,
5532        range: Range<usize>,
5533        syntax: Option<(SyntaxMapCaptures<'a>, Vec<HighlightMap>)>,
5534        diagnostics: bool,
5535        buffer_snapshot: Option<&'a BufferSnapshot>,
5536    ) -> Self {
5537        let mut highlights = None;
5538        if let Some((captures, highlight_maps)) = syntax {
5539            highlights = Some(BufferChunkHighlights {
5540                captures,
5541                next_capture: None,
5542                stack: Default::default(),
5543                highlight_maps,
5544            })
5545        }
5546
5547        let diagnostic_endpoints = diagnostics.then(|| Vec::new().into_iter().peekable());
5548        let chunks = text.chunks_in_range(range.clone());
5549
5550        let mut this = BufferChunks {
5551            range,
5552            buffer_snapshot,
5553            chunks,
5554            diagnostic_endpoints,
5555            error_depth: 0,
5556            warning_depth: 0,
5557            information_depth: 0,
5558            hint_depth: 0,
5559            unnecessary_depth: 0,
5560            underline: true,
5561            highlights,
5562        };
5563        this.initialize_diagnostic_endpoints();
5564        this
5565    }
5566
5567    /// Seeks to the given byte offset in the buffer.
5568    pub fn seek(&mut self, range: Range<usize>) {
5569        let old_range = std::mem::replace(&mut self.range, range.clone());
5570        self.chunks.set_range(self.range.clone());
5571        if let Some(highlights) = self.highlights.as_mut() {
5572            if old_range.start <= self.range.start && old_range.end >= self.range.end {
5573                // Reuse existing highlights stack, as the new range is a subrange of the old one.
5574                highlights
5575                    .stack
5576                    .retain(|(end_offset, _)| *end_offset > range.start);
5577                if let Some(capture) = &highlights.next_capture
5578                    && range.start >= capture.node.start_byte()
5579                {
5580                    let next_capture_end = capture.node.end_byte();
5581                    if range.start < next_capture_end
5582                        && let Some(capture_id) =
5583                            highlights.highlight_maps[capture.grammar_index].get(capture.index)
5584                    {
5585                        highlights.stack.push((next_capture_end, capture_id));
5586                    }
5587                    highlights.next_capture.take();
5588                }
5589            } else if let Some(snapshot) = self.buffer_snapshot {
5590                let (captures, highlight_maps) = snapshot.get_highlights(self.range.clone());
5591                *highlights = BufferChunkHighlights {
5592                    captures,
5593                    next_capture: None,
5594                    stack: Default::default(),
5595                    highlight_maps,
5596                };
5597            } else {
5598                // We cannot obtain new highlights for a language-aware buffer iterator, as we don't have a buffer snapshot.
5599                // Seeking such BufferChunks is not supported.
5600                debug_assert!(
5601                    false,
5602                    "Attempted to seek on a language-aware buffer iterator without associated buffer snapshot"
5603                );
5604            }
5605
5606            highlights.captures.set_byte_range(self.range.clone());
5607            self.initialize_diagnostic_endpoints();
5608        }
5609    }
5610
5611    fn initialize_diagnostic_endpoints(&mut self) {
5612        if let Some(diagnostics) = self.diagnostic_endpoints.as_mut()
5613            && let Some(buffer) = self.buffer_snapshot
5614        {
5615            let mut diagnostic_endpoints = Vec::new();
5616            for entry in buffer.diagnostics_in_range::<_, usize>(self.range.clone(), false) {
5617                diagnostic_endpoints.push(DiagnosticEndpoint {
5618                    offset: entry.range.start,
5619                    is_start: true,
5620                    severity: entry.diagnostic.severity,
5621                    is_unnecessary: entry.diagnostic.is_unnecessary,
5622                    underline: entry.diagnostic.underline,
5623                });
5624                diagnostic_endpoints.push(DiagnosticEndpoint {
5625                    offset: entry.range.end,
5626                    is_start: false,
5627                    severity: entry.diagnostic.severity,
5628                    is_unnecessary: entry.diagnostic.is_unnecessary,
5629                    underline: entry.diagnostic.underline,
5630                });
5631            }
5632            diagnostic_endpoints
5633                .sort_unstable_by_key(|endpoint| (endpoint.offset, !endpoint.is_start));
5634            *diagnostics = diagnostic_endpoints.into_iter().peekable();
5635            self.hint_depth = 0;
5636            self.error_depth = 0;
5637            self.warning_depth = 0;
5638            self.information_depth = 0;
5639        }
5640    }
5641
5642    /// The current byte offset in the buffer.
5643    pub fn offset(&self) -> usize {
5644        self.range.start
5645    }
5646
5647    pub fn range(&self) -> Range<usize> {
5648        self.range.clone()
5649    }
5650
5651    fn update_diagnostic_depths(&mut self, endpoint: DiagnosticEndpoint) {
5652        let depth = match endpoint.severity {
5653            DiagnosticSeverity::ERROR => &mut self.error_depth,
5654            DiagnosticSeverity::WARNING => &mut self.warning_depth,
5655            DiagnosticSeverity::INFORMATION => &mut self.information_depth,
5656            DiagnosticSeverity::HINT => &mut self.hint_depth,
5657            _ => return,
5658        };
5659        if endpoint.is_start {
5660            *depth += 1;
5661        } else {
5662            *depth -= 1;
5663        }
5664
5665        if endpoint.is_unnecessary {
5666            if endpoint.is_start {
5667                self.unnecessary_depth += 1;
5668            } else {
5669                self.unnecessary_depth -= 1;
5670            }
5671        }
5672    }
5673
5674    fn current_diagnostic_severity(&self) -> Option<DiagnosticSeverity> {
5675        if self.error_depth > 0 {
5676            Some(DiagnosticSeverity::ERROR)
5677        } else if self.warning_depth > 0 {
5678            Some(DiagnosticSeverity::WARNING)
5679        } else if self.information_depth > 0 {
5680            Some(DiagnosticSeverity::INFORMATION)
5681        } else if self.hint_depth > 0 {
5682            Some(DiagnosticSeverity::HINT)
5683        } else {
5684            None
5685        }
5686    }
5687
5688    fn current_code_is_unnecessary(&self) -> bool {
5689        self.unnecessary_depth > 0
5690    }
5691}
5692
5693impl<'a> Iterator for BufferChunks<'a> {
5694    type Item = Chunk<'a>;
5695
5696    fn next(&mut self) -> Option<Self::Item> {
5697        let mut next_capture_start = usize::MAX;
5698        let mut next_diagnostic_endpoint = usize::MAX;
5699
5700        if let Some(highlights) = self.highlights.as_mut() {
5701            while let Some((parent_capture_end, _)) = highlights.stack.last() {
5702                if *parent_capture_end <= self.range.start {
5703                    highlights.stack.pop();
5704                } else {
5705                    break;
5706                }
5707            }
5708
5709            if highlights.next_capture.is_none() {
5710                highlights.next_capture = highlights.captures.next();
5711            }
5712
5713            while let Some(capture) = highlights.next_capture.as_ref() {
5714                if self.range.start < capture.node.start_byte() {
5715                    next_capture_start = capture.node.start_byte();
5716                    break;
5717                } else {
5718                    let highlight_id =
5719                        highlights.highlight_maps[capture.grammar_index].get(capture.index);
5720                    if let Some(highlight_id) = highlight_id {
5721                        highlights
5722                            .stack
5723                            .push((capture.node.end_byte(), highlight_id));
5724                    }
5725                    highlights.next_capture = highlights.captures.next();
5726                }
5727            }
5728        }
5729
5730        let mut diagnostic_endpoints = std::mem::take(&mut self.diagnostic_endpoints);
5731        if let Some(diagnostic_endpoints) = diagnostic_endpoints.as_mut() {
5732            while let Some(endpoint) = diagnostic_endpoints.peek().copied() {
5733                if endpoint.offset <= self.range.start {
5734                    self.update_diagnostic_depths(endpoint);
5735                    diagnostic_endpoints.next();
5736                    self.underline = endpoint.underline;
5737                } else {
5738                    next_diagnostic_endpoint = endpoint.offset;
5739                    break;
5740                }
5741            }
5742        }
5743        self.diagnostic_endpoints = diagnostic_endpoints;
5744
5745        if let Some(ChunkBitmaps {
5746            text: chunk,
5747            chars: chars_map,
5748            tabs,
5749            newlines,
5750        }) = self.chunks.peek_with_bitmaps()
5751        {
5752            let chunk_start = self.range.start;
5753            let mut chunk_end = (self.chunks.offset() + chunk.len())
5754                .min(next_capture_start)
5755                .min(next_diagnostic_endpoint);
5756            let mut highlight_id = None;
5757            if let Some(highlights) = self.highlights.as_ref()
5758                && let Some((parent_capture_end, parent_highlight_id)) = highlights.stack.last()
5759            {
5760                chunk_end = chunk_end.min(*parent_capture_end);
5761                highlight_id = Some(*parent_highlight_id);
5762            }
5763            let bit_start = chunk_start - self.chunks.offset();
5764            let bit_end = chunk_end - self.chunks.offset();
5765
5766            let slice = &chunk[bit_start..bit_end];
5767
5768            let mask = 1u128.unbounded_shl(bit_end as u32).wrapping_sub(1);
5769            let tabs = (tabs >> bit_start) & mask;
5770            let chars = (chars_map >> bit_start) & mask;
5771            let newlines = (newlines >> bit_start) & mask;
5772
5773            self.range.start = chunk_end;
5774            if self.range.start == self.chunks.offset() + chunk.len() {
5775                self.chunks.next().unwrap();
5776            }
5777
5778            Some(Chunk {
5779                text: slice,
5780                syntax_highlight_id: highlight_id,
5781                underline: self.underline,
5782                diagnostic_severity: self.current_diagnostic_severity(),
5783                is_unnecessary: self.current_code_is_unnecessary(),
5784                tabs,
5785                chars,
5786                newlines,
5787                ..Chunk::default()
5788            })
5789        } else {
5790            None
5791        }
5792    }
5793}
5794
5795impl operation_queue::Operation for Operation {
5796    fn lamport_timestamp(&self) -> clock::Lamport {
5797        match self {
5798            Operation::Buffer(_) => {
5799                unreachable!("buffer operations should never be deferred at this layer")
5800            }
5801            Operation::UpdateDiagnostics {
5802                lamport_timestamp, ..
5803            }
5804            | Operation::UpdateSelections {
5805                lamport_timestamp, ..
5806            }
5807            | Operation::UpdateCompletionTriggers {
5808                lamport_timestamp, ..
5809            }
5810            | Operation::UpdateLineEnding {
5811                lamport_timestamp, ..
5812            } => *lamport_timestamp,
5813        }
5814    }
5815}
5816
5817impl IndentSize {
5818    /// Returns an [`IndentSize`] representing the given spaces.
5819    pub fn spaces(len: u32) -> Self {
5820        Self {
5821            len,
5822            kind: IndentKind::Space,
5823        }
5824    }
5825
5826    /// Returns an [`IndentSize`] representing a tab.
5827    pub fn tab() -> Self {
5828        Self {
5829            len: 1,
5830            kind: IndentKind::Tab,
5831        }
5832    }
5833
5834    /// An iterator over the characters represented by this [`IndentSize`].
5835    pub fn chars(&self) -> impl Iterator<Item = char> {
5836        iter::repeat(self.char()).take(self.len as usize)
5837    }
5838
5839    /// The character representation of this [`IndentSize`].
5840    pub fn char(&self) -> char {
5841        match self.kind {
5842            IndentKind::Space => ' ',
5843            IndentKind::Tab => '\t',
5844        }
5845    }
5846
5847    /// Consumes the current [`IndentSize`] and returns a new one that has
5848    /// been shrunk or enlarged by the given size along the given direction.
5849    pub fn with_delta(mut self, direction: Ordering, size: IndentSize) -> Self {
5850        match direction {
5851            Ordering::Less => {
5852                if self.kind == size.kind && self.len >= size.len {
5853                    self.len -= size.len;
5854                }
5855            }
5856            Ordering::Equal => {}
5857            Ordering::Greater => {
5858                if self.len == 0 {
5859                    self = size;
5860                } else if self.kind == size.kind {
5861                    self.len += size.len;
5862                }
5863            }
5864        }
5865        self
5866    }
5867
5868    pub fn len_with_expanded_tabs(&self, tab_size: NonZeroU32) -> usize {
5869        match self.kind {
5870            IndentKind::Space => self.len as usize,
5871            IndentKind::Tab => self.len as usize * tab_size.get() as usize,
5872        }
5873    }
5874}
5875
5876#[cfg(any(test, feature = "test-support"))]
5877pub struct TestFile {
5878    pub path: Arc<RelPath>,
5879    pub root_name: String,
5880    pub local_root: Option<PathBuf>,
5881}
5882
5883#[cfg(any(test, feature = "test-support"))]
5884impl File for TestFile {
5885    fn path(&self) -> &Arc<RelPath> {
5886        &self.path
5887    }
5888
5889    fn full_path(&self, _: &gpui::App) -> PathBuf {
5890        PathBuf::from(self.root_name.clone()).join(self.path.as_std_path())
5891    }
5892
5893    fn as_local(&self) -> Option<&dyn LocalFile> {
5894        if self.local_root.is_some() {
5895            Some(self)
5896        } else {
5897            None
5898        }
5899    }
5900
5901    fn disk_state(&self) -> DiskState {
5902        unimplemented!()
5903    }
5904
5905    fn file_name<'a>(&'a self, _: &'a gpui::App) -> &'a str {
5906        self.path().file_name().unwrap_or(self.root_name.as_ref())
5907    }
5908
5909    fn worktree_id(&self, _: &App) -> WorktreeId {
5910        WorktreeId::from_usize(0)
5911    }
5912
5913    fn to_proto(&self, _: &App) -> rpc::proto::File {
5914        unimplemented!()
5915    }
5916
5917    fn is_private(&self) -> bool {
5918        false
5919    }
5920
5921    fn path_style(&self, _cx: &App) -> PathStyle {
5922        PathStyle::local()
5923    }
5924}
5925
5926#[cfg(any(test, feature = "test-support"))]
5927impl LocalFile for TestFile {
5928    fn abs_path(&self, _cx: &App) -> PathBuf {
5929        PathBuf::from(self.local_root.as_ref().unwrap())
5930            .join(&self.root_name)
5931            .join(self.path.as_std_path())
5932    }
5933
5934    fn load(&self, _cx: &App) -> Task<Result<String>> {
5935        unimplemented!()
5936    }
5937
5938    fn load_bytes(&self, _cx: &App) -> Task<Result<Vec<u8>>> {
5939        unimplemented!()
5940    }
5941}
5942
5943pub(crate) fn contiguous_ranges(
5944    values: impl Iterator<Item = u32>,
5945    max_len: usize,
5946) -> impl Iterator<Item = Range<u32>> {
5947    let mut values = values;
5948    let mut current_range: Option<Range<u32>> = None;
5949    std::iter::from_fn(move || {
5950        loop {
5951            if let Some(value) = values.next() {
5952                if let Some(range) = &mut current_range
5953                    && value == range.end
5954                    && range.len() < max_len
5955                {
5956                    range.end += 1;
5957                    continue;
5958                }
5959
5960                let prev_range = current_range.clone();
5961                current_range = Some(value..(value + 1));
5962                if prev_range.is_some() {
5963                    return prev_range;
5964                }
5965            } else {
5966                return current_range.take();
5967            }
5968        }
5969    })
5970}
5971
5972#[derive(Default, Debug)]
5973pub struct CharClassifier {
5974    scope: Option<LanguageScope>,
5975    scope_context: Option<CharScopeContext>,
5976    ignore_punctuation: bool,
5977}
5978
5979impl CharClassifier {
5980    pub fn new(scope: Option<LanguageScope>) -> Self {
5981        Self {
5982            scope,
5983            scope_context: None,
5984            ignore_punctuation: false,
5985        }
5986    }
5987
5988    pub fn scope_context(self, scope_context: Option<CharScopeContext>) -> Self {
5989        Self {
5990            scope_context,
5991            ..self
5992        }
5993    }
5994
5995    pub fn ignore_punctuation(self, ignore_punctuation: bool) -> Self {
5996        Self {
5997            ignore_punctuation,
5998            ..self
5999        }
6000    }
6001
6002    pub fn is_whitespace(&self, c: char) -> bool {
6003        self.kind(c) == CharKind::Whitespace
6004    }
6005
6006    pub fn is_word(&self, c: char) -> bool {
6007        self.kind(c) == CharKind::Word
6008    }
6009
6010    pub fn is_punctuation(&self, c: char) -> bool {
6011        self.kind(c) == CharKind::Punctuation
6012    }
6013
6014    pub fn kind_with(&self, c: char, ignore_punctuation: bool) -> CharKind {
6015        if c.is_alphanumeric() || c == '_' {
6016            return CharKind::Word;
6017        }
6018
6019        if let Some(scope) = &self.scope {
6020            let characters = match self.scope_context {
6021                Some(CharScopeContext::Completion) => scope.completion_query_characters(),
6022                Some(CharScopeContext::LinkedEdit) => scope.linked_edit_characters(),
6023                None => scope.word_characters(),
6024            };
6025            if let Some(characters) = characters
6026                && characters.contains(&c)
6027            {
6028                return CharKind::Word;
6029            }
6030        }
6031
6032        if c.is_whitespace() {
6033            return CharKind::Whitespace;
6034        }
6035
6036        if ignore_punctuation {
6037            CharKind::Word
6038        } else {
6039            CharKind::Punctuation
6040        }
6041    }
6042
6043    pub fn kind(&self, c: char) -> CharKind {
6044        self.kind_with(c, self.ignore_punctuation)
6045    }
6046}
6047
6048/// Find all of the ranges of whitespace that occur at the ends of lines
6049/// in the given rope.
6050///
6051/// This could also be done with a regex search, but this implementation
6052/// avoids copying text.
6053pub fn trailing_whitespace_ranges(rope: &Rope) -> Vec<Range<usize>> {
6054    let mut ranges = Vec::new();
6055
6056    let mut offset = 0;
6057    let mut prev_chunk_trailing_whitespace_range = 0..0;
6058    for chunk in rope.chunks() {
6059        let mut prev_line_trailing_whitespace_range = 0..0;
6060        for (i, line) in chunk.split('\n').enumerate() {
6061            let line_end_offset = offset + line.len();
6062            let trimmed_line_len = line.trim_end_matches([' ', '\t']).len();
6063            let mut trailing_whitespace_range = (offset + trimmed_line_len)..line_end_offset;
6064
6065            if i == 0 && trimmed_line_len == 0 {
6066                trailing_whitespace_range.start = prev_chunk_trailing_whitespace_range.start;
6067            }
6068            if !prev_line_trailing_whitespace_range.is_empty() {
6069                ranges.push(prev_line_trailing_whitespace_range);
6070            }
6071
6072            offset = line_end_offset + 1;
6073            prev_line_trailing_whitespace_range = trailing_whitespace_range;
6074        }
6075
6076        offset -= 1;
6077        prev_chunk_trailing_whitespace_range = prev_line_trailing_whitespace_range;
6078    }
6079
6080    if !prev_chunk_trailing_whitespace_range.is_empty() {
6081        ranges.push(prev_chunk_trailing_whitespace_range);
6082    }
6083
6084    ranges
6085}