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