buffer.rs

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