buffer.rs

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