buffer.rs

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