buffer.rs

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