buffer.rs

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