buffer.rs

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