buffer.rs

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