buffer.rs

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