buffer.rs

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