buffer.rs

   1pub use crate::{
   2    diagnostic_set::DiagnosticSet,
   3    highlight_map::{HighlightId, HighlightMap},
   4    markdown::ParsedMarkdown,
   5    proto, Grammar, Language, LanguageRegistry,
   6};
   7use crate::{
   8    diagnostic_set::{DiagnosticEntry, DiagnosticGroup},
   9    language_settings::{language_settings, LanguageSettings},
  10    markdown::parse_markdown,
  11    outline::OutlineItem,
  12    syntax_map::{
  13        SyntaxLayer, SyntaxMap, SyntaxMapCapture, SyntaxMapCaptures, SyntaxMapMatches,
  14        SyntaxSnapshot, ToTreeSitterPoint,
  15    },
  16    CodeLabel, LanguageScope, Outline,
  17};
  18use anyhow::{anyhow, Context, Result};
  19pub use clock::ReplicaId;
  20use futures::channel::oneshot;
  21use gpui::{AppContext, EventEmitter, HighlightStyle, ModelContext, Task, TaskLabel};
  22use lazy_static::lazy_static;
  23use lsp::LanguageServerId;
  24use parking_lot::Mutex;
  25use similar::{ChangeTag, TextDiff};
  26use smallvec::SmallVec;
  27use smol::future::yield_now;
  28use std::{
  29    any::Any,
  30    cmp::{self, Ordering},
  31    collections::BTreeMap,
  32    ffi::OsStr,
  33    future::Future,
  34    iter::{self, Iterator, Peekable},
  35    mem,
  36    ops::{Deref, Range},
  37    path::{Path, PathBuf},
  38    str,
  39    sync::Arc,
  40    time::{Duration, Instant, SystemTime},
  41    vec,
  42};
  43use sum_tree::TreeMap;
  44use text::operation_queue::OperationQueue;
  45use text::*;
  46pub use text::{
  47    Anchor, Bias, Buffer as TextBuffer, BufferId, BufferSnapshot as TextBufferSnapshot, Edit,
  48    OffsetRangeExt, OffsetUtf16, Patch, Point, PointUtf16, Rope, RopeFingerprint, Selection,
  49    SelectionGoal, Subscription, TextDimension, TextSummary, ToOffset, ToOffsetUtf16, ToPoint,
  50    ToPointUtf16, Transaction, TransactionId, Unclipped,
  51};
  52use theme::SyntaxTheme;
  53#[cfg(any(test, feature = "test-support"))]
  54use util::RandomCharIter;
  55use util::RangeExt;
  56
  57#[cfg(any(test, feature = "test-support"))]
  58pub use {tree_sitter_rust, tree_sitter_typescript};
  59
  60pub use lsp::DiagnosticSeverity;
  61
  62lazy_static! {
  63    /// A label for the background task spawned by the buffer to compute
  64    /// a diff against the contents of its file.
  65    pub static ref BUFFER_DIFF_TASK: TaskLabel = TaskLabel::new();
  66}
  67
  68/// Indicate whether a [Buffer] has permissions to edit.
  69#[derive(PartialEq, Clone, Copy, Debug)]
  70pub enum Capability {
  71    /// The buffer is a mutable replica.
  72    ReadWrite,
  73    /// The buffer is a read-only replica.
  74    ReadOnly,
  75}
  76
  77/// An in-memory representation of a source code file, including its text,
  78/// syntax trees, git status, and diagnostics.
  79pub struct Buffer {
  80    text: TextBuffer,
  81    diff_base: Option<String>,
  82    git_diff: git::diff::BufferDiff,
  83    file: Option<Arc<dyn File>>,
  84    /// The mtime of the file when this buffer was last loaded from
  85    /// or saved to disk.
  86    saved_mtime: Option<SystemTime>,
  87    /// The version vector when this buffer was last loaded from
  88    /// or saved to disk.
  89    saved_version: clock::Global,
  90    /// A hash of the current contents of the buffer's file.
  91    file_fingerprint: RopeFingerprint,
  92    transaction_depth: usize,
  93    was_dirty_before_starting_transaction: Option<bool>,
  94    reload_task: Option<Task<Result<()>>>,
  95    language: Option<Arc<Language>>,
  96    autoindent_requests: Vec<Arc<AutoindentRequest>>,
  97    pending_autoindent: Option<Task<()>>,
  98    sync_parse_timeout: Duration,
  99    syntax_map: Mutex<SyntaxMap>,
 100    parsing_in_background: bool,
 101    parse_count: usize,
 102    diagnostics: SmallVec<[(LanguageServerId, DiagnosticSet); 2]>,
 103    remote_selections: TreeMap<ReplicaId, SelectionSet>,
 104    selections_update_count: usize,
 105    diagnostics_update_count: usize,
 106    diagnostics_timestamp: clock::Lamport,
 107    file_update_count: usize,
 108    git_diff_update_count: usize,
 109    completion_triggers: Vec<String>,
 110    completion_triggers_timestamp: clock::Lamport,
 111    deferred_ops: OperationQueue<Operation>,
 112    capability: Capability,
 113    has_conflict: bool,
 114}
 115
 116/// An immutable, cheaply cloneable representation of a fixed
 117/// state of a buffer.
 118pub struct BufferSnapshot {
 119    text: text::BufferSnapshot,
 120    git_diff: git::diff::BufferDiff,
 121    pub(crate) syntax: SyntaxSnapshot,
 122    file: Option<Arc<dyn File>>,
 123    diagnostics: SmallVec<[(LanguageServerId, DiagnosticSet); 2]>,
 124    diagnostics_update_count: usize,
 125    file_update_count: usize,
 126    git_diff_update_count: usize,
 127    remote_selections: TreeMap<ReplicaId, SelectionSet>,
 128    selections_update_count: usize,
 129    language: Option<Arc<Language>>,
 130    parse_count: usize,
 131}
 132
 133/// The kind and amount of indentation in a particular line. For now,
 134/// assumes that indentation is all the same character.
 135#[derive(Clone, Copy, Debug, PartialEq, Eq, Default)]
 136pub struct IndentSize {
 137    /// The number of bytes that comprise the indentation.
 138    pub len: u32,
 139    /// The kind of whitespace used for indentation.
 140    pub kind: IndentKind,
 141}
 142
 143/// A whitespace character that's used for indentation.
 144#[derive(Clone, Copy, Debug, PartialEq, Eq, Default)]
 145pub enum IndentKind {
 146    /// An ASCII space character.
 147    #[default]
 148    Space,
 149    /// An ASCII tab character.
 150    Tab,
 151}
 152
 153/// The shape of a selection cursor.
 154#[derive(Copy, Clone, PartialEq, Eq, Debug, Default)]
 155pub enum CursorShape {
 156    /// A vertical bar
 157    #[default]
 158    Bar,
 159    /// A block that surrounds the following character
 160    Block,
 161    /// An underline that runs along the following character
 162    Underscore,
 163    /// A box drawn around the following character
 164    Hollow,
 165}
 166
 167#[derive(Clone, Debug)]
 168struct SelectionSet {
 169    line_mode: bool,
 170    cursor_shape: CursorShape,
 171    selections: Arc<[Selection<Anchor>]>,
 172    lamport_timestamp: clock::Lamport,
 173}
 174
 175/// A diagnostic associated with a certain range of a buffer.
 176#[derive(Clone, Debug, PartialEq, Eq)]
 177pub struct Diagnostic {
 178    /// The name of the service that produced this diagnostic.
 179    pub source: Option<String>,
 180    /// A machine-readable code that identifies this diagnostic.
 181    pub code: Option<String>,
 182    /// Whether this diagnostic is a hint, warning, or error.
 183    pub severity: DiagnosticSeverity,
 184    /// The human-readable message associated with this diagnostic.
 185    pub message: String,
 186    /// An id that identifies the group to which this diagnostic belongs.
 187    ///
 188    /// When a language server produces a diagnostic with
 189    /// one or more associated diagnostics, those diagnostics are all
 190    /// assigned a single group id.
 191    pub group_id: usize,
 192    /// Whether this diagnostic is the primary diagnostic for its group.
 193    ///
 194    /// In a given group, the primary diagnostic is the top-level diagnostic
 195    /// returned by the language server. The non-primary diagnostics are the
 196    /// associated diagnostics.
 197    pub is_primary: bool,
 198    /// Whether this diagnostic is considered to originate from an analysis of
 199    /// files on disk, as opposed to any unsaved buffer contents. This is a
 200    /// property of a given diagnostic source, and is configured for a given
 201    /// language server via the [`LspAdapter::disk_based_diagnostic_sources`](crate::LspAdapter::disk_based_diagnostic_sources) method
 202    /// for the language server.
 203    pub is_disk_based: bool,
 204    /// Whether this diagnostic marks unnecessary code.
 205    pub is_unnecessary: bool,
 206}
 207
 208/// TODO - move this into the `project` crate and make it private.
 209pub async fn prepare_completion_documentation(
 210    documentation: &lsp::Documentation,
 211    language_registry: &Arc<LanguageRegistry>,
 212    language: Option<Arc<Language>>,
 213) -> Documentation {
 214    match documentation {
 215        lsp::Documentation::String(text) => {
 216            if text.lines().count() <= 1 {
 217                Documentation::SingleLine(text.clone())
 218            } else {
 219                Documentation::MultiLinePlainText(text.clone())
 220            }
 221        }
 222
 223        lsp::Documentation::MarkupContent(lsp::MarkupContent { kind, value }) => match kind {
 224            lsp::MarkupKind::PlainText => {
 225                if value.lines().count() <= 1 {
 226                    Documentation::SingleLine(value.clone())
 227                } else {
 228                    Documentation::MultiLinePlainText(value.clone())
 229                }
 230            }
 231
 232            lsp::MarkupKind::Markdown => {
 233                let parsed = parse_markdown(value, language_registry, language).await;
 234                Documentation::MultiLineMarkdown(parsed)
 235            }
 236        },
 237    }
 238}
 239
 240/// Documentation associated with a [`Completion`].
 241#[derive(Clone, Debug)]
 242pub enum Documentation {
 243    /// There is no documentation for this completion.
 244    Undocumented,
 245    /// A single line of documentation.
 246    SingleLine(String),
 247    /// Multiple lines of plain text documentation.
 248    MultiLinePlainText(String),
 249    /// Markdown documentation.
 250    MultiLineMarkdown(ParsedMarkdown),
 251}
 252
 253/// A completion provided by a language server
 254#[derive(Clone, Debug)]
 255pub struct Completion {
 256    /// The range of the buffer that will be replaced.
 257    pub old_range: Range<Anchor>,
 258    /// The new text that will be inserted.
 259    pub new_text: String,
 260    /// A label for this completion that is shown in the menu.
 261    pub label: CodeLabel,
 262    /// The id of the language server that produced this completion.
 263    pub server_id: LanguageServerId,
 264    /// The documentation for this completion.
 265    pub documentation: Option<Documentation>,
 266    /// The raw completion provided by the language server.
 267    pub lsp_completion: lsp::CompletionItem,
 268}
 269
 270/// A code action provided by a language server.
 271#[derive(Clone, Debug)]
 272pub struct CodeAction {
 273    /// The id of the language server that produced this code action.
 274    pub server_id: LanguageServerId,
 275    /// The range of the buffer where this code action is applicable.
 276    pub range: Range<Anchor>,
 277    /// The raw code action provided by the language server.
 278    pub lsp_action: lsp::CodeAction,
 279}
 280
 281/// An operation used to synchronize this buffer with its other replicas.
 282#[derive(Clone, Debug, PartialEq)]
 283pub enum Operation {
 284    /// A text operation.
 285    Buffer(text::Operation),
 286
 287    /// An update to the buffer's diagnostics.
 288    UpdateDiagnostics {
 289        /// The id of the language server that produced the new diagnostics.
 290        server_id: LanguageServerId,
 291        /// The diagnostics.
 292        diagnostics: Arc<[DiagnosticEntry<Anchor>]>,
 293        /// The buffer's lamport timestamp.
 294        lamport_timestamp: clock::Lamport,
 295    },
 296
 297    /// An update to the most recent selections in this buffer.
 298    UpdateSelections {
 299        /// The selections.
 300        selections: Arc<[Selection<Anchor>]>,
 301        /// The buffer's lamport timestamp.
 302        lamport_timestamp: clock::Lamport,
 303        /// Whether the selections are in 'line mode'.
 304        line_mode: bool,
 305        /// The [`CursorShape`] associated with these selections.
 306        cursor_shape: CursorShape,
 307    },
 308
 309    /// An update to the characters that should trigger autocompletion
 310    /// for this buffer.
 311    UpdateCompletionTriggers {
 312        /// The characters that trigger autocompletion.
 313        triggers: Vec<String>,
 314        /// The buffer's lamport timestamp.
 315        lamport_timestamp: clock::Lamport,
 316    },
 317}
 318
 319/// An event that occurs in a buffer.
 320#[derive(Clone, Debug, PartialEq)]
 321pub enum Event {
 322    /// The buffer was changed in a way that must be
 323    /// propagated to its other replicas.
 324    Operation(Operation),
 325    /// The buffer was edited.
 326    Edited,
 327    /// The buffer's `dirty` bit changed.
 328    DirtyChanged,
 329    /// The buffer was saved.
 330    Saved,
 331    /// The buffer's file was changed on disk.
 332    FileHandleChanged,
 333    /// The buffer was reloaded.
 334    Reloaded,
 335    /// The buffer's diff_base changed.
 336    DiffBaseChanged,
 337    /// The buffer's language was changed.
 338    LanguageChanged,
 339    /// The buffer's syntax trees were updated.
 340    Reparsed,
 341    /// The buffer's diagnostics were updated.
 342    DiagnosticsUpdated,
 343    /// The buffer gained or lost editing capabilities.
 344    CapabilityChanged,
 345    /// The buffer was explicitly requested to close.
 346    Closed,
 347}
 348
 349/// The file associated with a buffer.
 350pub trait File: Send + Sync {
 351    /// Returns the [`LocalFile`] associated with this file, if the
 352    /// file is local.
 353    fn as_local(&self) -> Option<&dyn LocalFile>;
 354
 355    /// Returns whether this file is local.
 356    fn is_local(&self) -> bool {
 357        self.as_local().is_some()
 358    }
 359
 360    /// Returns the file's mtime.
 361    fn mtime(&self) -> Option<SystemTime>;
 362
 363    /// Returns the path of this file relative to the worktree's root directory.
 364    fn path(&self) -> &Arc<Path>;
 365
 366    /// Returns the path of this file relative to the worktree's parent directory (this means it
 367    /// includes the name of the worktree's root folder).
 368    fn full_path(&self, cx: &AppContext) -> PathBuf;
 369
 370    /// Returns the last component of this handle's absolute path. If this handle refers to the root
 371    /// of its worktree, then this method will return the name of the worktree itself.
 372    fn file_name<'a>(&'a self, cx: &'a AppContext) -> &'a OsStr;
 373
 374    /// Returns the id of the worktree to which this file belongs.
 375    ///
 376    /// This is needed for looking up project-specific settings.
 377    fn worktree_id(&self) -> usize;
 378
 379    /// Returns whether the file has been deleted.
 380    fn is_deleted(&self) -> bool;
 381
 382    /// Returns whether the file existed on disk at one point
 383    fn is_created(&self) -> bool {
 384        self.mtime().is_some()
 385    }
 386
 387    /// Converts this file into an [`Any`] trait object.
 388    fn as_any(&self) -> &dyn Any;
 389
 390    /// Converts this file into a protobuf message.
 391    fn to_proto(&self) -> rpc::proto::File;
 392
 393    /// Return whether Zed considers this to be a private file.
 394    fn is_private(&self) -> bool;
 395}
 396
 397/// The file associated with a buffer, in the case where the file is on the local disk.
 398pub trait LocalFile: File {
 399    /// Returns the absolute path of this file.
 400    fn abs_path(&self, cx: &AppContext) -> PathBuf;
 401
 402    /// Loads the file's contents from disk.
 403    fn load(&self, cx: &AppContext) -> Task<Result<String>>;
 404
 405    /// Called when the buffer is reloaded from disk.
 406    fn buffer_reloaded(
 407        &self,
 408        buffer_id: BufferId,
 409        version: &clock::Global,
 410        fingerprint: RopeFingerprint,
 411        line_ending: LineEnding,
 412        mtime: Option<SystemTime>,
 413        cx: &mut AppContext,
 414    );
 415
 416    /// Returns true if the file should not be shared with collaborators.
 417    fn is_private(&self, _: &AppContext) -> bool {
 418        false
 419    }
 420}
 421
 422/// The auto-indent behavior associated with an editing operation.
 423/// For some editing operations, each affected line of text has its
 424/// indentation recomputed. For other operations, the entire block
 425/// of edited text is adjusted uniformly.
 426#[derive(Clone, Debug)]
 427pub enum AutoindentMode {
 428    /// Indent each line of inserted text.
 429    EachLine,
 430    /// Apply the same indentation adjustment to all of the lines
 431    /// in a given insertion.
 432    Block {
 433        /// The original indentation level of the first line of each
 434        /// insertion, if it has been copied.
 435        original_indent_columns: Vec<u32>,
 436    },
 437}
 438
 439#[derive(Clone)]
 440struct AutoindentRequest {
 441    before_edit: BufferSnapshot,
 442    entries: Vec<AutoindentRequestEntry>,
 443    is_block_mode: bool,
 444}
 445
 446#[derive(Clone)]
 447struct AutoindentRequestEntry {
 448    /// A range of the buffer whose indentation should be adjusted.
 449    range: Range<Anchor>,
 450    /// Whether or not these lines should be considered brand new, for the
 451    /// purpose of auto-indent. When text is not new, its indentation will
 452    /// only be adjusted if the suggested indentation level has *changed*
 453    /// since the edit was made.
 454    first_line_is_new: bool,
 455    indent_size: IndentSize,
 456    original_indent_column: Option<u32>,
 457}
 458
 459#[derive(Debug)]
 460struct IndentSuggestion {
 461    basis_row: u32,
 462    delta: Ordering,
 463    within_error: bool,
 464}
 465
 466struct BufferChunkHighlights<'a> {
 467    captures: SyntaxMapCaptures<'a>,
 468    next_capture: Option<SyntaxMapCapture<'a>>,
 469    stack: Vec<(usize, HighlightId)>,
 470    highlight_maps: Vec<HighlightMap>,
 471}
 472
 473/// An iterator that yields chunks of a buffer's text, along with their
 474/// syntax highlights and diagnostic status.
 475pub struct BufferChunks<'a> {
 476    range: Range<usize>,
 477    chunks: text::Chunks<'a>,
 478    diagnostic_endpoints: Peekable<vec::IntoIter<DiagnosticEndpoint>>,
 479    error_depth: usize,
 480    warning_depth: usize,
 481    information_depth: usize,
 482    hint_depth: usize,
 483    unnecessary_depth: usize,
 484    highlights: Option<BufferChunkHighlights<'a>>,
 485}
 486
 487/// A chunk of a buffer's text, along with its syntax highlight and
 488/// diagnostic status.
 489#[derive(Clone, Copy, Debug, Default)]
 490pub struct Chunk<'a> {
 491    /// The text of the chunk.
 492    pub text: &'a str,
 493    /// The syntax highlighting style of the chunk.
 494    pub syntax_highlight_id: Option<HighlightId>,
 495    /// The highlight style that has been applied to this chunk in
 496    /// the editor.
 497    pub highlight_style: Option<HighlightStyle>,
 498    /// The severity of diagnostic associated with this chunk, if any.
 499    pub diagnostic_severity: Option<DiagnosticSeverity>,
 500    /// Whether this chunk of text is marked as unnecessary.
 501    pub is_unnecessary: bool,
 502    /// Whether this chunk of text was originally a tab character.
 503    pub is_tab: bool,
 504}
 505
 506/// A set of edits to a given version of a buffer, computed asynchronously.
 507pub struct Diff {
 508    pub(crate) base_version: clock::Global,
 509    line_ending: LineEnding,
 510    edits: Vec<(Range<usize>, Arc<str>)>,
 511}
 512
 513#[derive(Clone, Copy)]
 514pub(crate) struct DiagnosticEndpoint {
 515    offset: usize,
 516    is_start: bool,
 517    severity: DiagnosticSeverity,
 518    is_unnecessary: bool,
 519}
 520
 521/// A class of characters, used for characterizing a run of text.
 522#[derive(Copy, Clone, Eq, PartialEq, PartialOrd, Ord, Debug)]
 523pub enum CharKind {
 524    /// Whitespace.
 525    Whitespace,
 526    /// Punctuation.
 527    Punctuation,
 528    /// Word.
 529    Word,
 530}
 531
 532impl Buffer {
 533    /// Create a new buffer with the given base text.
 534    pub fn new<T: Into<String>>(replica_id: ReplicaId, id: BufferId, base_text: T) -> Self {
 535        Self::build(
 536            TextBuffer::new(replica_id, id, base_text.into()),
 537            None,
 538            None,
 539            Capability::ReadWrite,
 540        )
 541    }
 542
 543    /// Create a new buffer that is a replica of a remote buffer.
 544    pub fn remote(
 545        remote_id: BufferId,
 546        replica_id: ReplicaId,
 547        capability: Capability,
 548        base_text: String,
 549    ) -> Self {
 550        Self::build(
 551            TextBuffer::new(replica_id, remote_id, base_text),
 552            None,
 553            None,
 554            capability,
 555        )
 556    }
 557
 558    /// Create a new buffer that is a replica of a remote buffer, populating its
 559    /// state from the given protobuf message.
 560    pub fn from_proto(
 561        replica_id: ReplicaId,
 562        capability: Capability,
 563        message: proto::BufferState,
 564        file: Option<Arc<dyn File>>,
 565    ) -> Result<Self> {
 566        let buffer_id = BufferId::new(message.id)
 567            .with_context(|| anyhow!("Could not deserialize buffer_id"))?;
 568        let buffer = TextBuffer::new(replica_id, buffer_id, message.base_text);
 569        let mut this = Self::build(
 570            buffer,
 571            message.diff_base.map(|text| text.into_boxed_str().into()),
 572            file,
 573            capability,
 574        );
 575        this.text.set_line_ending(proto::deserialize_line_ending(
 576            rpc::proto::LineEnding::from_i32(message.line_ending)
 577                .ok_or_else(|| anyhow!("missing line_ending"))?,
 578        ));
 579        this.saved_version = proto::deserialize_version(&message.saved_version);
 580        this.saved_mtime = message.saved_mtime.map(|time| time.into());
 581        Ok(this)
 582    }
 583
 584    /// Serialize the buffer's state to a protobuf message.
 585    pub fn to_proto(&self) -> proto::BufferState {
 586        proto::BufferState {
 587            id: self.remote_id().into(),
 588            file: self.file.as_ref().map(|f| f.to_proto()),
 589            base_text: self.base_text().to_string(),
 590            diff_base: self.diff_base.as_ref().map(|h| h.to_string()),
 591            line_ending: proto::serialize_line_ending(self.line_ending()) as i32,
 592            saved_version: proto::serialize_version(&self.saved_version),
 593            saved_version_fingerprint: proto::serialize_fingerprint(self.file_fingerprint),
 594            saved_mtime: self.saved_mtime.map(|time| time.into()),
 595        }
 596    }
 597
 598    /// Serialize as protobufs all of the changes to the buffer since the given version.
 599    pub fn serialize_ops(
 600        &self,
 601        since: Option<clock::Global>,
 602        cx: &AppContext,
 603    ) -> Task<Vec<proto::Operation>> {
 604        let mut operations = Vec::new();
 605        operations.extend(self.deferred_ops.iter().map(proto::serialize_operation));
 606
 607        operations.extend(self.remote_selections.iter().map(|(_, set)| {
 608            proto::serialize_operation(&Operation::UpdateSelections {
 609                selections: set.selections.clone(),
 610                lamport_timestamp: set.lamport_timestamp,
 611                line_mode: set.line_mode,
 612                cursor_shape: set.cursor_shape,
 613            })
 614        }));
 615
 616        for (server_id, diagnostics) in &self.diagnostics {
 617            operations.push(proto::serialize_operation(&Operation::UpdateDiagnostics {
 618                lamport_timestamp: self.diagnostics_timestamp,
 619                server_id: *server_id,
 620                diagnostics: diagnostics.iter().cloned().collect(),
 621            }));
 622        }
 623
 624        operations.push(proto::serialize_operation(
 625            &Operation::UpdateCompletionTriggers {
 626                triggers: self.completion_triggers.clone(),
 627                lamport_timestamp: self.completion_triggers_timestamp,
 628            },
 629        ));
 630
 631        let text_operations = self.text.operations().clone();
 632        cx.background_executor().spawn(async move {
 633            let since = since.unwrap_or_default();
 634            operations.extend(
 635                text_operations
 636                    .iter()
 637                    .filter(|(_, op)| !since.observed(op.timestamp()))
 638                    .map(|(_, op)| proto::serialize_operation(&Operation::Buffer(op.clone()))),
 639            );
 640            operations.sort_unstable_by_key(proto::lamport_timestamp_for_operation);
 641            operations
 642        })
 643    }
 644
 645    /// Assign a language to the buffer, returning the buffer.
 646    pub fn with_language(mut self, language: Arc<Language>, cx: &mut ModelContext<Self>) -> Self {
 647        self.set_language(Some(language), cx);
 648        self
 649    }
 650
 651    /// Returns the [Capability] of this buffer.
 652    pub fn capability(&self) -> Capability {
 653        self.capability
 654    }
 655
 656    /// Whether this buffer can only be read.
 657    pub fn read_only(&self) -> bool {
 658        self.capability == Capability::ReadOnly
 659    }
 660
 661    /// Builds a [Buffer] with the given underlying [TextBuffer], diff base, [File] and [Capability].
 662    pub fn build(
 663        buffer: TextBuffer,
 664        diff_base: Option<String>,
 665        file: Option<Arc<dyn File>>,
 666        capability: Capability,
 667    ) -> Self {
 668        let saved_mtime = file.as_ref().and_then(|file| file.mtime());
 669
 670        Self {
 671            saved_mtime,
 672            saved_version: buffer.version(),
 673            file_fingerprint: buffer.as_rope().fingerprint(),
 674            reload_task: None,
 675            transaction_depth: 0,
 676            was_dirty_before_starting_transaction: None,
 677            text: buffer,
 678            diff_base,
 679            git_diff: git::diff::BufferDiff::new(),
 680            file,
 681            capability,
 682            syntax_map: Mutex::new(SyntaxMap::new()),
 683            parsing_in_background: false,
 684            parse_count: 0,
 685            sync_parse_timeout: Duration::from_millis(1),
 686            autoindent_requests: Default::default(),
 687            pending_autoindent: Default::default(),
 688            language: None,
 689            remote_selections: Default::default(),
 690            selections_update_count: 0,
 691            diagnostics: Default::default(),
 692            diagnostics_update_count: 0,
 693            diagnostics_timestamp: Default::default(),
 694            file_update_count: 0,
 695            git_diff_update_count: 0,
 696            completion_triggers: Default::default(),
 697            completion_triggers_timestamp: Default::default(),
 698            deferred_ops: OperationQueue::new(),
 699            has_conflict: false,
 700        }
 701    }
 702
 703    /// Retrieve a snapshot of the buffer's current state. This is computationally
 704    /// cheap, and allows reading from the buffer on a background thread.
 705    pub fn snapshot(&self) -> BufferSnapshot {
 706        let text = self.text.snapshot();
 707        let mut syntax_map = self.syntax_map.lock();
 708        syntax_map.interpolate(&text);
 709        let syntax = syntax_map.snapshot();
 710
 711        BufferSnapshot {
 712            text,
 713            syntax,
 714            git_diff: self.git_diff.clone(),
 715            file: self.file.clone(),
 716            remote_selections: self.remote_selections.clone(),
 717            diagnostics: self.diagnostics.clone(),
 718            diagnostics_update_count: self.diagnostics_update_count,
 719            file_update_count: self.file_update_count,
 720            git_diff_update_count: self.git_diff_update_count,
 721            language: self.language.clone(),
 722            parse_count: self.parse_count,
 723            selections_update_count: self.selections_update_count,
 724        }
 725    }
 726
 727    #[cfg(test)]
 728    pub(crate) fn as_text_snapshot(&self) -> &text::BufferSnapshot {
 729        &self.text
 730    }
 731
 732    /// Retrieve a snapshot of the buffer's raw text, without any
 733    /// language-related state like the syntax tree or diagnostics.
 734    pub fn text_snapshot(&self) -> text::BufferSnapshot {
 735        self.text.snapshot()
 736    }
 737
 738    /// The file associated with the buffer, if any.
 739    pub fn file(&self) -> Option<&Arc<dyn File>> {
 740        self.file.as_ref()
 741    }
 742
 743    /// The version of the buffer that was last saved or reloaded from disk.
 744    pub fn saved_version(&self) -> &clock::Global {
 745        &self.saved_version
 746    }
 747
 748    /// The fingerprint of the buffer's text when the buffer was last saved or reloaded from disk.
 749    pub fn saved_version_fingerprint(&self) -> RopeFingerprint {
 750        self.file_fingerprint
 751    }
 752
 753    /// The mtime of the buffer's file when the buffer was last saved or reloaded from disk.
 754    pub fn saved_mtime(&self) -> Option<SystemTime> {
 755        self.saved_mtime
 756    }
 757
 758    /// Assign a language to the buffer.
 759    pub fn set_language(&mut self, language: Option<Arc<Language>>, cx: &mut ModelContext<Self>) {
 760        self.parse_count += 1;
 761        self.syntax_map.lock().clear();
 762        self.language = language;
 763        self.reparse(cx);
 764        cx.emit(Event::LanguageChanged);
 765    }
 766
 767    /// Assign a language registry to the buffer. This allows the buffer to retrieve
 768    /// other languages if parts of the buffer are written in different languages.
 769    pub fn set_language_registry(&mut self, language_registry: Arc<LanguageRegistry>) {
 770        self.syntax_map
 771            .lock()
 772            .set_language_registry(language_registry);
 773    }
 774
 775    /// Assign the buffer a new [Capability].
 776    pub fn set_capability(&mut self, capability: Capability, cx: &mut ModelContext<Self>) {
 777        self.capability = capability;
 778        cx.emit(Event::CapabilityChanged)
 779    }
 780
 781    /// This method is called to signal that the buffer has been saved.
 782    pub fn did_save(
 783        &mut self,
 784        version: clock::Global,
 785        fingerprint: RopeFingerprint,
 786        mtime: Option<SystemTime>,
 787        cx: &mut ModelContext<Self>,
 788    ) {
 789        self.saved_version = version;
 790        self.has_conflict = false;
 791        self.file_fingerprint = fingerprint;
 792        self.saved_mtime = mtime;
 793        cx.emit(Event::Saved);
 794        cx.notify();
 795    }
 796
 797    /// Reloads the contents of the buffer from disk.
 798    pub fn reload(
 799        &mut self,
 800        cx: &mut ModelContext<Self>,
 801    ) -> oneshot::Receiver<Option<Transaction>> {
 802        let (tx, rx) = futures::channel::oneshot::channel();
 803        let prev_version = self.text.version();
 804        self.reload_task = Some(cx.spawn(|this, mut cx| async move {
 805            let Some((new_mtime, new_text)) = this.update(&mut cx, |this, cx| {
 806                let file = this.file.as_ref()?.as_local()?;
 807                Some((file.mtime(), file.load(cx)))
 808            })?
 809            else {
 810                return Ok(());
 811            };
 812
 813            let new_text = new_text.await?;
 814            let diff = this
 815                .update(&mut cx, |this, cx| this.diff(new_text.clone(), cx))?
 816                .await;
 817            this.update(&mut cx, |this, cx| {
 818                if this.version() == diff.base_version {
 819                    this.finalize_last_transaction();
 820                    this.apply_diff(diff, cx);
 821                    tx.send(this.finalize_last_transaction().cloned()).ok();
 822                    this.has_conflict = false;
 823                    this.did_reload(
 824                        this.version(),
 825                        this.as_rope().fingerprint(),
 826                        this.line_ending(),
 827                        new_mtime,
 828                        cx,
 829                    );
 830                } else {
 831                    if !diff.edits.is_empty()
 832                        || this
 833                            .edits_since::<usize>(&diff.base_version)
 834                            .next()
 835                            .is_some()
 836                    {
 837                        this.has_conflict = true;
 838                    }
 839
 840                    this.did_reload(
 841                        prev_version,
 842                        Rope::text_fingerprint(&new_text),
 843                        this.line_ending(),
 844                        this.saved_mtime,
 845                        cx,
 846                    );
 847                }
 848
 849                this.reload_task.take();
 850            })
 851        }));
 852        rx
 853    }
 854
 855    /// This method is called to signal that the buffer has been reloaded.
 856    pub fn did_reload(
 857        &mut self,
 858        version: clock::Global,
 859        fingerprint: RopeFingerprint,
 860        line_ending: LineEnding,
 861        mtime: Option<SystemTime>,
 862        cx: &mut ModelContext<Self>,
 863    ) {
 864        self.saved_version = version;
 865        self.file_fingerprint = fingerprint;
 866        self.text.set_line_ending(line_ending);
 867        self.saved_mtime = mtime;
 868        if let Some(file) = self.file.as_ref().and_then(|f| f.as_local()) {
 869            file.buffer_reloaded(
 870                self.remote_id(),
 871                &self.saved_version,
 872                self.file_fingerprint,
 873                self.line_ending(),
 874                self.saved_mtime,
 875                cx,
 876            );
 877        }
 878        cx.emit(Event::Reloaded);
 879        cx.notify();
 880    }
 881
 882    /// Updates the [File] backing this buffer. This should be called when
 883    /// the file has changed or has been deleted.
 884    pub fn file_updated(&mut self, new_file: Arc<dyn File>, cx: &mut ModelContext<Self>) {
 885        let mut file_changed = false;
 886
 887        if let Some(old_file) = self.file.as_ref() {
 888            if new_file.path() != old_file.path() {
 889                file_changed = true;
 890            }
 891
 892            if new_file.is_deleted() {
 893                if !old_file.is_deleted() {
 894                    file_changed = true;
 895                    if !self.is_dirty() {
 896                        cx.emit(Event::DirtyChanged);
 897                    }
 898                }
 899            } else {
 900                let new_mtime = new_file.mtime();
 901                if new_mtime != old_file.mtime() {
 902                    file_changed = true;
 903
 904                    if !self.is_dirty() {
 905                        self.reload(cx).close();
 906                    }
 907                }
 908            }
 909        } else {
 910            file_changed = true;
 911        };
 912
 913        self.file = Some(new_file);
 914        if file_changed {
 915            self.file_update_count += 1;
 916            cx.emit(Event::FileHandleChanged);
 917            cx.notify();
 918        }
 919    }
 920
 921    /// Returns the current diff base, see [Buffer::set_diff_base].
 922    pub fn diff_base(&self) -> Option<&str> {
 923        self.diff_base.as_deref()
 924    }
 925
 926    /// Sets the text that will be used to compute a Git diff
 927    /// against the buffer text.
 928    pub fn set_diff_base(&mut self, diff_base: Option<String>, cx: &mut ModelContext<Self>) {
 929        self.diff_base = diff_base;
 930        if let Some(recalc_task) = self.git_diff_recalc(cx) {
 931            cx.spawn(|buffer, mut cx| async move {
 932                recalc_task.await;
 933                buffer
 934                    .update(&mut cx, |_, cx| {
 935                        cx.emit(Event::DiffBaseChanged);
 936                    })
 937                    .ok();
 938            })
 939            .detach();
 940        }
 941    }
 942
 943    /// Recomputes the Git diff status.
 944    pub fn git_diff_recalc(&mut self, cx: &mut ModelContext<Self>) -> Option<Task<()>> {
 945        let diff_base = self.diff_base.clone()?; // TODO: Make this an Arc
 946        let snapshot = self.snapshot();
 947
 948        let mut diff = self.git_diff.clone();
 949        let diff = cx.background_executor().spawn(async move {
 950            diff.update(&diff_base, &snapshot).await;
 951            diff
 952        });
 953
 954        Some(cx.spawn(|this, mut cx| async move {
 955            let buffer_diff = diff.await;
 956            this.update(&mut cx, |this, _| {
 957                this.git_diff = buffer_diff;
 958                this.git_diff_update_count += 1;
 959            })
 960            .ok();
 961        }))
 962    }
 963
 964    /// Returns the primary [Language] assigned to this [Buffer].
 965    pub fn language(&self) -> Option<&Arc<Language>> {
 966        self.language.as_ref()
 967    }
 968
 969    /// Returns the [Language] at the given location.
 970    pub fn language_at<D: ToOffset>(&self, position: D) -> Option<Arc<Language>> {
 971        let offset = position.to_offset(self);
 972        self.syntax_map
 973            .lock()
 974            .layers_for_range(offset..offset, &self.text)
 975            .last()
 976            .map(|info| info.language.clone())
 977            .or_else(|| self.language.clone())
 978    }
 979
 980    /// The number of times the buffer was parsed.
 981    pub fn parse_count(&self) -> usize {
 982        self.parse_count
 983    }
 984
 985    /// The number of times selections were updated.
 986    pub fn selections_update_count(&self) -> usize {
 987        self.selections_update_count
 988    }
 989
 990    /// The number of times diagnostics were updated.
 991    pub fn diagnostics_update_count(&self) -> usize {
 992        self.diagnostics_update_count
 993    }
 994
 995    /// The number of times the underlying file was updated.
 996    pub fn file_update_count(&self) -> usize {
 997        self.file_update_count
 998    }
 999
1000    /// The number of times the git diff status was updated.
1001    pub fn git_diff_update_count(&self) -> usize {
1002        self.git_diff_update_count
1003    }
1004
1005    /// Whether the buffer is being parsed in the background.
1006    #[cfg(any(test, feature = "test-support"))]
1007    pub fn is_parsing(&self) -> bool {
1008        self.parsing_in_background
1009    }
1010
1011    /// Indicates whether the buffer contains any regions that may be
1012    /// written in a language that hasn't been loaded yet.
1013    pub fn contains_unknown_injections(&self) -> bool {
1014        self.syntax_map.lock().contains_unknown_injections()
1015    }
1016
1017    #[cfg(test)]
1018    pub fn set_sync_parse_timeout(&mut self, timeout: Duration) {
1019        self.sync_parse_timeout = timeout;
1020    }
1021
1022    /// Called after an edit to synchronize the buffer's main parse tree with
1023    /// the buffer's new underlying state.
1024    ///
1025    /// Locks the syntax map and interpolates the edits since the last reparse
1026    /// into the foreground syntax tree.
1027    ///
1028    /// Then takes a stable snapshot of the syntax map before unlocking it.
1029    /// The snapshot with the interpolated edits is sent to a background thread,
1030    /// where we ask Tree-sitter to perform an incremental parse.
1031    ///
1032    /// Meanwhile, in the foreground, we block the main thread for up to 1ms
1033    /// waiting on the parse to complete. As soon as it completes, we proceed
1034    /// synchronously, unless a 1ms timeout elapses.
1035    ///
1036    /// If we time out waiting on the parse, we spawn a second task waiting
1037    /// until the parse does complete and return with the interpolated tree still
1038    /// in the foreground. When the background parse completes, call back into
1039    /// the main thread and assign the foreground parse state.
1040    ///
1041    /// If the buffer or grammar changed since the start of the background parse,
1042    /// initiate an additional reparse recursively. To avoid concurrent parses
1043    /// for the same buffer, we only initiate a new parse if we are not already
1044    /// parsing in the background.
1045    pub fn reparse(&mut self, cx: &mut ModelContext<Self>) {
1046        if self.parsing_in_background {
1047            return;
1048        }
1049        let language = if let Some(language) = self.language.clone() {
1050            language
1051        } else {
1052            return;
1053        };
1054
1055        let text = self.text_snapshot();
1056        let parsed_version = self.version();
1057
1058        let mut syntax_map = self.syntax_map.lock();
1059        syntax_map.interpolate(&text);
1060        let language_registry = syntax_map.language_registry();
1061        let mut syntax_snapshot = syntax_map.snapshot();
1062        drop(syntax_map);
1063
1064        let parse_task = cx.background_executor().spawn({
1065            let language = language.clone();
1066            let language_registry = language_registry.clone();
1067            async move {
1068                syntax_snapshot.reparse(&text, language_registry, language);
1069                syntax_snapshot
1070            }
1071        });
1072
1073        match cx
1074            .background_executor()
1075            .block_with_timeout(self.sync_parse_timeout, parse_task)
1076        {
1077            Ok(new_syntax_snapshot) => {
1078                self.did_finish_parsing(new_syntax_snapshot, cx);
1079                return;
1080            }
1081            Err(parse_task) => {
1082                self.parsing_in_background = true;
1083                cx.spawn(move |this, mut cx| async move {
1084                    let new_syntax_map = parse_task.await;
1085                    this.update(&mut cx, move |this, cx| {
1086                        let grammar_changed =
1087                            this.language.as_ref().map_or(true, |current_language| {
1088                                !Arc::ptr_eq(&language, current_language)
1089                            });
1090                        let language_registry_changed = new_syntax_map
1091                            .contains_unknown_injections()
1092                            && language_registry.map_or(false, |registry| {
1093                                registry.version() != new_syntax_map.language_registry_version()
1094                            });
1095                        let parse_again = language_registry_changed
1096                            || grammar_changed
1097                            || this.version.changed_since(&parsed_version);
1098                        this.did_finish_parsing(new_syntax_map, cx);
1099                        this.parsing_in_background = false;
1100                        if parse_again {
1101                            this.reparse(cx);
1102                        }
1103                    })
1104                    .ok();
1105                })
1106                .detach();
1107            }
1108        }
1109    }
1110
1111    fn did_finish_parsing(&mut self, syntax_snapshot: SyntaxSnapshot, cx: &mut ModelContext<Self>) {
1112        self.parse_count += 1;
1113        self.syntax_map.lock().did_parse(syntax_snapshot);
1114        self.request_autoindent(cx);
1115        cx.emit(Event::Reparsed);
1116        cx.notify();
1117    }
1118
1119    /// Assign to the buffer a set of diagnostics created by a given language server.
1120    pub fn update_diagnostics(
1121        &mut self,
1122        server_id: LanguageServerId,
1123        diagnostics: DiagnosticSet,
1124        cx: &mut ModelContext<Self>,
1125    ) {
1126        let lamport_timestamp = self.text.lamport_clock.tick();
1127        let op = Operation::UpdateDiagnostics {
1128            server_id,
1129            diagnostics: diagnostics.iter().cloned().collect(),
1130            lamport_timestamp,
1131        };
1132        self.apply_diagnostic_update(server_id, diagnostics, lamport_timestamp, cx);
1133        self.send_operation(op, cx);
1134    }
1135
1136    fn request_autoindent(&mut self, cx: &mut ModelContext<Self>) {
1137        if let Some(indent_sizes) = self.compute_autoindents() {
1138            let indent_sizes = cx.background_executor().spawn(indent_sizes);
1139            match cx
1140                .background_executor()
1141                .block_with_timeout(Duration::from_micros(500), indent_sizes)
1142            {
1143                Ok(indent_sizes) => self.apply_autoindents(indent_sizes, cx),
1144                Err(indent_sizes) => {
1145                    self.pending_autoindent = Some(cx.spawn(|this, mut cx| async move {
1146                        let indent_sizes = indent_sizes.await;
1147                        this.update(&mut cx, |this, cx| {
1148                            this.apply_autoindents(indent_sizes, cx);
1149                        })
1150                        .ok();
1151                    }));
1152                }
1153            }
1154        } else {
1155            self.autoindent_requests.clear();
1156        }
1157    }
1158
1159    fn compute_autoindents(&self) -> Option<impl Future<Output = BTreeMap<u32, IndentSize>>> {
1160        let max_rows_between_yields = 100;
1161        let snapshot = self.snapshot();
1162        if snapshot.syntax.is_empty() || self.autoindent_requests.is_empty() {
1163            return None;
1164        }
1165
1166        let autoindent_requests = self.autoindent_requests.clone();
1167        Some(async move {
1168            let mut indent_sizes = BTreeMap::new();
1169            for request in autoindent_requests {
1170                // Resolve each edited range to its row in the current buffer and in the
1171                // buffer before this batch of edits.
1172                let mut row_ranges = Vec::new();
1173                let mut old_to_new_rows = BTreeMap::new();
1174                let mut language_indent_sizes_by_new_row = Vec::new();
1175                for entry in &request.entries {
1176                    let position = entry.range.start;
1177                    let new_row = position.to_point(&snapshot).row;
1178                    let new_end_row = entry.range.end.to_point(&snapshot).row + 1;
1179                    language_indent_sizes_by_new_row.push((new_row, entry.indent_size));
1180
1181                    if !entry.first_line_is_new {
1182                        let old_row = position.to_point(&request.before_edit).row;
1183                        old_to_new_rows.insert(old_row, new_row);
1184                    }
1185                    row_ranges.push((new_row..new_end_row, entry.original_indent_column));
1186                }
1187
1188                // Build a map containing the suggested indentation for each of the edited lines
1189                // with respect to the state of the buffer before these edits. This map is keyed
1190                // by the rows for these lines in the current state of the buffer.
1191                let mut old_suggestions = BTreeMap::<u32, (IndentSize, bool)>::default();
1192                let old_edited_ranges =
1193                    contiguous_ranges(old_to_new_rows.keys().copied(), max_rows_between_yields);
1194                let mut language_indent_sizes = language_indent_sizes_by_new_row.iter().peekable();
1195                let mut language_indent_size = IndentSize::default();
1196                for old_edited_range in old_edited_ranges {
1197                    let suggestions = request
1198                        .before_edit
1199                        .suggest_autoindents(old_edited_range.clone())
1200                        .into_iter()
1201                        .flatten();
1202                    for (old_row, suggestion) in old_edited_range.zip(suggestions) {
1203                        if let Some(suggestion) = suggestion {
1204                            let new_row = *old_to_new_rows.get(&old_row).unwrap();
1205
1206                            // Find the indent size based on the language for this row.
1207                            while let Some((row, size)) = language_indent_sizes.peek() {
1208                                if *row > new_row {
1209                                    break;
1210                                }
1211                                language_indent_size = *size;
1212                                language_indent_sizes.next();
1213                            }
1214
1215                            let suggested_indent = old_to_new_rows
1216                                .get(&suggestion.basis_row)
1217                                .and_then(|from_row| {
1218                                    Some(old_suggestions.get(from_row).copied()?.0)
1219                                })
1220                                .unwrap_or_else(|| {
1221                                    request
1222                                        .before_edit
1223                                        .indent_size_for_line(suggestion.basis_row)
1224                                })
1225                                .with_delta(suggestion.delta, language_indent_size);
1226                            old_suggestions
1227                                .insert(new_row, (suggested_indent, suggestion.within_error));
1228                        }
1229                    }
1230                    yield_now().await;
1231                }
1232
1233                // In block mode, only compute indentation suggestions for the first line
1234                // of each insertion. Otherwise, compute suggestions for every inserted line.
1235                let new_edited_row_ranges = contiguous_ranges(
1236                    row_ranges.iter().flat_map(|(range, _)| {
1237                        if request.is_block_mode {
1238                            range.start..range.start + 1
1239                        } else {
1240                            range.clone()
1241                        }
1242                    }),
1243                    max_rows_between_yields,
1244                );
1245
1246                // Compute new suggestions for each line, but only include them in the result
1247                // if they differ from the old suggestion for that line.
1248                let mut language_indent_sizes = language_indent_sizes_by_new_row.iter().peekable();
1249                let mut language_indent_size = IndentSize::default();
1250                for new_edited_row_range in new_edited_row_ranges {
1251                    let suggestions = snapshot
1252                        .suggest_autoindents(new_edited_row_range.clone())
1253                        .into_iter()
1254                        .flatten();
1255                    for (new_row, suggestion) in new_edited_row_range.zip(suggestions) {
1256                        if let Some(suggestion) = suggestion {
1257                            // Find the indent size based on the language for this row.
1258                            while let Some((row, size)) = language_indent_sizes.peek() {
1259                                if *row > new_row {
1260                                    break;
1261                                }
1262                                language_indent_size = *size;
1263                                language_indent_sizes.next();
1264                            }
1265
1266                            let suggested_indent = indent_sizes
1267                                .get(&suggestion.basis_row)
1268                                .copied()
1269                                .unwrap_or_else(|| {
1270                                    snapshot.indent_size_for_line(suggestion.basis_row)
1271                                })
1272                                .with_delta(suggestion.delta, language_indent_size);
1273                            if old_suggestions.get(&new_row).map_or(
1274                                true,
1275                                |(old_indentation, was_within_error)| {
1276                                    suggested_indent != *old_indentation
1277                                        && (!suggestion.within_error || *was_within_error)
1278                                },
1279                            ) {
1280                                indent_sizes.insert(new_row, suggested_indent);
1281                            }
1282                        }
1283                    }
1284                    yield_now().await;
1285                }
1286
1287                // For each block of inserted text, adjust the indentation of the remaining
1288                // lines of the block by the same amount as the first line was adjusted.
1289                if request.is_block_mode {
1290                    for (row_range, original_indent_column) in
1291                        row_ranges
1292                            .into_iter()
1293                            .filter_map(|(range, original_indent_column)| {
1294                                if range.len() > 1 {
1295                                    Some((range, original_indent_column?))
1296                                } else {
1297                                    None
1298                                }
1299                            })
1300                    {
1301                        let new_indent = indent_sizes
1302                            .get(&row_range.start)
1303                            .copied()
1304                            .unwrap_or_else(|| snapshot.indent_size_for_line(row_range.start));
1305                        let delta = new_indent.len as i64 - original_indent_column as i64;
1306                        if delta != 0 {
1307                            for row in row_range.skip(1) {
1308                                indent_sizes.entry(row).or_insert_with(|| {
1309                                    let mut size = snapshot.indent_size_for_line(row);
1310                                    if size.kind == new_indent.kind {
1311                                        match delta.cmp(&0) {
1312                                            Ordering::Greater => size.len += delta as u32,
1313                                            Ordering::Less => {
1314                                                size.len = size.len.saturating_sub(-delta as u32)
1315                                            }
1316                                            Ordering::Equal => {}
1317                                        }
1318                                    }
1319                                    size
1320                                });
1321                            }
1322                        }
1323                    }
1324                }
1325            }
1326
1327            indent_sizes
1328        })
1329    }
1330
1331    fn apply_autoindents(
1332        &mut self,
1333        indent_sizes: BTreeMap<u32, IndentSize>,
1334        cx: &mut ModelContext<Self>,
1335    ) {
1336        self.autoindent_requests.clear();
1337
1338        let edits: Vec<_> = indent_sizes
1339            .into_iter()
1340            .filter_map(|(row, indent_size)| {
1341                let current_size = indent_size_for_line(self, row);
1342                Self::edit_for_indent_size_adjustment(row, current_size, indent_size)
1343            })
1344            .collect();
1345
1346        self.edit(edits, None, cx);
1347    }
1348
1349    /// Create a minimal edit that will cause the given row to be indented
1350    /// with the given size. After applying this edit, the length of the line
1351    /// will always be at least `new_size.len`.
1352    pub fn edit_for_indent_size_adjustment(
1353        row: u32,
1354        current_size: IndentSize,
1355        new_size: IndentSize,
1356    ) -> Option<(Range<Point>, String)> {
1357        if new_size.kind != current_size.kind {
1358            Some((
1359                Point::new(row, 0)..Point::new(row, current_size.len),
1360                iter::repeat(new_size.char())
1361                    .take(new_size.len as usize)
1362                    .collect::<String>(),
1363            ))
1364        } else {
1365            match new_size.len.cmp(&current_size.len) {
1366                Ordering::Greater => {
1367                    let point = Point::new(row, 0);
1368                    Some((
1369                        point..point,
1370                        iter::repeat(new_size.char())
1371                            .take((new_size.len - current_size.len) as usize)
1372                            .collect::<String>(),
1373                    ))
1374                }
1375
1376                Ordering::Less => Some((
1377                    Point::new(row, 0)..Point::new(row, current_size.len - new_size.len),
1378                    String::new(),
1379                )),
1380
1381                Ordering::Equal => None,
1382            }
1383        }
1384    }
1385
1386    /// Spawns a background task that asynchronously computes a `Diff` between the buffer's text
1387    /// and the given new text.
1388    pub fn diff(&self, mut new_text: String, cx: &AppContext) -> Task<Diff> {
1389        let old_text = self.as_rope().clone();
1390        let base_version = self.version();
1391        cx.background_executor()
1392            .spawn_labeled(*BUFFER_DIFF_TASK, async move {
1393                let old_text = old_text.to_string();
1394                let line_ending = LineEnding::detect(&new_text);
1395                LineEnding::normalize(&mut new_text);
1396
1397                let diff = TextDiff::from_chars(old_text.as_str(), new_text.as_str());
1398                let empty: Arc<str> = "".into();
1399
1400                let mut edits = Vec::new();
1401                let mut old_offset = 0;
1402                let mut new_offset = 0;
1403                let mut last_edit: Option<(Range<usize>, Range<usize>)> = None;
1404                for change in diff.iter_all_changes().map(Some).chain([None]) {
1405                    if let Some(change) = &change {
1406                        let len = change.value().len();
1407                        match change.tag() {
1408                            ChangeTag::Equal => {
1409                                old_offset += len;
1410                                new_offset += len;
1411                            }
1412                            ChangeTag::Delete => {
1413                                let old_end_offset = old_offset + len;
1414                                if let Some((last_old_range, _)) = &mut last_edit {
1415                                    last_old_range.end = old_end_offset;
1416                                } else {
1417                                    last_edit =
1418                                        Some((old_offset..old_end_offset, new_offset..new_offset));
1419                                }
1420                                old_offset = old_end_offset;
1421                            }
1422                            ChangeTag::Insert => {
1423                                let new_end_offset = new_offset + len;
1424                                if let Some((_, last_new_range)) = &mut last_edit {
1425                                    last_new_range.end = new_end_offset;
1426                                } else {
1427                                    last_edit =
1428                                        Some((old_offset..old_offset, new_offset..new_end_offset));
1429                                }
1430                                new_offset = new_end_offset;
1431                            }
1432                        }
1433                    }
1434
1435                    if let Some((old_range, new_range)) = &last_edit {
1436                        if old_offset > old_range.end
1437                            || new_offset > new_range.end
1438                            || change.is_none()
1439                        {
1440                            let text = if new_range.is_empty() {
1441                                empty.clone()
1442                            } else {
1443                                new_text[new_range.clone()].into()
1444                            };
1445                            edits.push((old_range.clone(), text));
1446                            last_edit.take();
1447                        }
1448                    }
1449                }
1450
1451                Diff {
1452                    base_version,
1453                    line_ending,
1454                    edits,
1455                }
1456            })
1457    }
1458
1459    /// Spawns a background task that searches the buffer for any whitespace
1460    /// at the ends of a lines, and returns a `Diff` that removes that whitespace.
1461    pub fn remove_trailing_whitespace(&self, cx: &AppContext) -> Task<Diff> {
1462        let old_text = self.as_rope().clone();
1463        let line_ending = self.line_ending();
1464        let base_version = self.version();
1465        cx.background_executor().spawn(async move {
1466            let ranges = trailing_whitespace_ranges(&old_text);
1467            let empty = Arc::<str>::from("");
1468            Diff {
1469                base_version,
1470                line_ending,
1471                edits: ranges
1472                    .into_iter()
1473                    .map(|range| (range, empty.clone()))
1474                    .collect(),
1475            }
1476        })
1477    }
1478
1479    /// Ensures that the buffer ends with a single newline character, and
1480    /// no other whitespace.
1481    pub fn ensure_final_newline(&mut self, cx: &mut ModelContext<Self>) {
1482        let len = self.len();
1483        let mut offset = len;
1484        for chunk in self.as_rope().reversed_chunks_in_range(0..len) {
1485            let non_whitespace_len = chunk
1486                .trim_end_matches(|c: char| c.is_ascii_whitespace())
1487                .len();
1488            offset -= chunk.len();
1489            offset += non_whitespace_len;
1490            if non_whitespace_len != 0 {
1491                if offset == len - 1 && chunk.get(non_whitespace_len..) == Some("\n") {
1492                    return;
1493                }
1494                break;
1495            }
1496        }
1497        self.edit([(offset..len, "\n")], None, cx);
1498    }
1499
1500    /// Applies a diff to the buffer. If the buffer has changed since the given diff was
1501    /// calculated, then adjust the diff to account for those changes, and discard any
1502    /// parts of the diff that conflict with those changes.
1503    pub fn apply_diff(&mut self, diff: Diff, cx: &mut ModelContext<Self>) -> Option<TransactionId> {
1504        // Check for any edits to the buffer that have occurred since this diff
1505        // was computed.
1506        let snapshot = self.snapshot();
1507        let mut edits_since = snapshot.edits_since::<usize>(&diff.base_version).peekable();
1508        let mut delta = 0;
1509        let adjusted_edits = diff.edits.into_iter().filter_map(|(range, new_text)| {
1510            while let Some(edit_since) = edits_since.peek() {
1511                // If the edit occurs after a diff hunk, then it does not
1512                // affect that hunk.
1513                if edit_since.old.start > range.end {
1514                    break;
1515                }
1516                // If the edit precedes the diff hunk, then adjust the hunk
1517                // to reflect the edit.
1518                else if edit_since.old.end < range.start {
1519                    delta += edit_since.new_len() as i64 - edit_since.old_len() as i64;
1520                    edits_since.next();
1521                }
1522                // If the edit intersects a diff hunk, then discard that hunk.
1523                else {
1524                    return None;
1525                }
1526            }
1527
1528            let start = (range.start as i64 + delta) as usize;
1529            let end = (range.end as i64 + delta) as usize;
1530            Some((start..end, new_text))
1531        });
1532
1533        self.start_transaction();
1534        self.text.set_line_ending(diff.line_ending);
1535        self.edit(adjusted_edits, None, cx);
1536        self.end_transaction(cx)
1537    }
1538
1539    fn changed_since_saved_version(&self) -> bool {
1540        self.edits_since::<usize>(&self.saved_version)
1541            .next()
1542            .is_some()
1543    }
1544    /// Checks if the buffer has unsaved changes.
1545    pub fn is_dirty(&self) -> bool {
1546        (self.has_conflict || self.changed_since_saved_version())
1547            || self
1548                .file
1549                .as_ref()
1550                .map_or(false, |file| file.is_deleted() || !file.is_created())
1551    }
1552
1553    /// Checks if the buffer and its file have both changed since the buffer
1554    /// was last saved or reloaded.
1555    pub fn has_conflict(&self) -> bool {
1556        (self.has_conflict || self.changed_since_saved_version())
1557            && self
1558                .file
1559                .as_ref()
1560                .map_or(false, |file| file.mtime() > self.saved_mtime)
1561    }
1562
1563    /// Gets a [`Subscription`] that tracks all of the changes to the buffer's text.
1564    pub fn subscribe(&mut self) -> Subscription {
1565        self.text.subscribe()
1566    }
1567
1568    /// Starts a transaction, if one is not already in-progress. When undoing or
1569    /// redoing edits, all of the edits performed within a transaction are undone
1570    /// or redone together.
1571    pub fn start_transaction(&mut self) -> Option<TransactionId> {
1572        self.start_transaction_at(Instant::now())
1573    }
1574
1575    /// Starts a transaction, providing the current time. Subsequent transactions
1576    /// that occur within a short period of time will be grouped together. This
1577    /// is controlled by the buffer's undo grouping duration.
1578    pub fn start_transaction_at(&mut self, now: Instant) -> Option<TransactionId> {
1579        self.transaction_depth += 1;
1580        if self.was_dirty_before_starting_transaction.is_none() {
1581            self.was_dirty_before_starting_transaction = Some(self.is_dirty());
1582        }
1583        self.text.start_transaction_at(now)
1584    }
1585
1586    /// Terminates the current transaction, if this is the outermost transaction.
1587    pub fn end_transaction(&mut self, cx: &mut ModelContext<Self>) -> Option<TransactionId> {
1588        self.end_transaction_at(Instant::now(), cx)
1589    }
1590
1591    /// Terminates the current transaction, providing the current time. Subsequent transactions
1592    /// that occur within a short period of time will be grouped together. This
1593    /// is controlled by the buffer's undo grouping duration.
1594    pub fn end_transaction_at(
1595        &mut self,
1596        now: Instant,
1597        cx: &mut ModelContext<Self>,
1598    ) -> Option<TransactionId> {
1599        assert!(self.transaction_depth > 0);
1600        self.transaction_depth -= 1;
1601        let was_dirty = if self.transaction_depth == 0 {
1602            self.was_dirty_before_starting_transaction.take().unwrap()
1603        } else {
1604            false
1605        };
1606        if let Some((transaction_id, start_version)) = self.text.end_transaction_at(now) {
1607            self.did_edit(&start_version, was_dirty, cx);
1608            Some(transaction_id)
1609        } else {
1610            None
1611        }
1612    }
1613
1614    /// Manually add a transaction to the buffer's undo history.
1615    pub fn push_transaction(&mut self, transaction: Transaction, now: Instant) {
1616        self.text.push_transaction(transaction, now);
1617    }
1618
1619    /// Prevent the last transaction from being grouped with any subsequent transactions,
1620    /// even if they occur with the buffer's undo grouping duration.
1621    pub fn finalize_last_transaction(&mut self) -> Option<&Transaction> {
1622        self.text.finalize_last_transaction()
1623    }
1624
1625    /// Manually group all changes since a given transaction.
1626    pub fn group_until_transaction(&mut self, transaction_id: TransactionId) {
1627        self.text.group_until_transaction(transaction_id);
1628    }
1629
1630    /// Manually remove a transaction from the buffer's undo history
1631    pub fn forget_transaction(&mut self, transaction_id: TransactionId) {
1632        self.text.forget_transaction(transaction_id);
1633    }
1634
1635    /// Manually merge two adjacent transactions in the buffer's undo history.
1636    pub fn merge_transactions(&mut self, transaction: TransactionId, destination: TransactionId) {
1637        self.text.merge_transactions(transaction, destination);
1638    }
1639
1640    /// Waits for the buffer to receive operations with the given timestamps.
1641    pub fn wait_for_edits(
1642        &mut self,
1643        edit_ids: impl IntoIterator<Item = clock::Lamport>,
1644    ) -> impl Future<Output = Result<()>> {
1645        self.text.wait_for_edits(edit_ids)
1646    }
1647
1648    /// Waits for the buffer to receive the operations necessary for resolving the given anchors.
1649    pub fn wait_for_anchors(
1650        &mut self,
1651        anchors: impl IntoIterator<Item = Anchor>,
1652    ) -> impl 'static + Future<Output = Result<()>> {
1653        self.text.wait_for_anchors(anchors)
1654    }
1655
1656    /// Waits for the buffer to receive operations up to the given version.
1657    pub fn wait_for_version(&mut self, version: clock::Global) -> impl Future<Output = Result<()>> {
1658        self.text.wait_for_version(version)
1659    }
1660
1661    /// Forces all futures returned by [`Buffer::wait_for_version`], [`Buffer::wait_for_edits`], or
1662    /// [`Buffer::wait_for_version`] to resolve with an error.
1663    pub fn give_up_waiting(&mut self) {
1664        self.text.give_up_waiting();
1665    }
1666
1667    /// Stores a set of selections that should be broadcasted to all of the buffer's replicas.
1668    pub fn set_active_selections(
1669        &mut self,
1670        selections: Arc<[Selection<Anchor>]>,
1671        line_mode: bool,
1672        cursor_shape: CursorShape,
1673        cx: &mut ModelContext<Self>,
1674    ) {
1675        let lamport_timestamp = self.text.lamport_clock.tick();
1676        self.remote_selections.insert(
1677            self.text.replica_id(),
1678            SelectionSet {
1679                selections: selections.clone(),
1680                lamport_timestamp,
1681                line_mode,
1682                cursor_shape,
1683            },
1684        );
1685        self.send_operation(
1686            Operation::UpdateSelections {
1687                selections,
1688                line_mode,
1689                lamport_timestamp,
1690                cursor_shape,
1691            },
1692            cx,
1693        );
1694    }
1695
1696    /// Clears the selections, so that other replicas of the buffer do not see any selections for
1697    /// this replica.
1698    pub fn remove_active_selections(&mut self, cx: &mut ModelContext<Self>) {
1699        if self
1700            .remote_selections
1701            .get(&self.text.replica_id())
1702            .map_or(true, |set| !set.selections.is_empty())
1703        {
1704            self.set_active_selections(Arc::from([]), false, Default::default(), cx);
1705        }
1706    }
1707
1708    /// Replaces the buffer's entire text.
1709    pub fn set_text<T>(&mut self, text: T, cx: &mut ModelContext<Self>) -> Option<clock::Lamport>
1710    where
1711        T: Into<Arc<str>>,
1712    {
1713        self.autoindent_requests.clear();
1714        self.edit([(0..self.len(), text)], None, cx)
1715    }
1716
1717    /// Applies the given edits to the buffer. Each edit is specified as a range of text to
1718    /// delete, and a string of text to insert at that location.
1719    ///
1720    /// If an [`AutoindentMode`] is provided, then the buffer will enqueue an auto-indent
1721    /// request for the edited ranges, which will be processed when the buffer finishes
1722    /// parsing.
1723    ///
1724    /// Parsing takes place at the end of a transaction, and may compute synchronously
1725    /// or asynchronously, depending on the changes.
1726    pub fn edit<I, S, T>(
1727        &mut self,
1728        edits_iter: I,
1729        autoindent_mode: Option<AutoindentMode>,
1730        cx: &mut ModelContext<Self>,
1731    ) -> Option<clock::Lamport>
1732    where
1733        I: IntoIterator<Item = (Range<S>, T)>,
1734        S: ToOffset,
1735        T: Into<Arc<str>>,
1736    {
1737        // Skip invalid edits and coalesce contiguous ones.
1738        let mut edits: Vec<(Range<usize>, Arc<str>)> = Vec::new();
1739        for (range, new_text) in edits_iter {
1740            let mut range = range.start.to_offset(self)..range.end.to_offset(self);
1741            if range.start > range.end {
1742                mem::swap(&mut range.start, &mut range.end);
1743            }
1744            let new_text = new_text.into();
1745            if !new_text.is_empty() || !range.is_empty() {
1746                if let Some((prev_range, prev_text)) = edits.last_mut() {
1747                    if prev_range.end >= range.start {
1748                        prev_range.end = cmp::max(prev_range.end, range.end);
1749                        *prev_text = format!("{prev_text}{new_text}").into();
1750                    } else {
1751                        edits.push((range, new_text));
1752                    }
1753                } else {
1754                    edits.push((range, new_text));
1755                }
1756            }
1757        }
1758        if edits.is_empty() {
1759            return None;
1760        }
1761
1762        self.start_transaction();
1763        self.pending_autoindent.take();
1764        let autoindent_request = autoindent_mode
1765            .and_then(|mode| self.language.as_ref().map(|_| (self.snapshot(), mode)));
1766
1767        let edit_operation = self.text.edit(edits.iter().cloned());
1768        let edit_id = edit_operation.timestamp();
1769
1770        if let Some((before_edit, mode)) = autoindent_request {
1771            let mut delta = 0isize;
1772            let entries = edits
1773                .into_iter()
1774                .enumerate()
1775                .zip(&edit_operation.as_edit().unwrap().new_text)
1776                .map(|((ix, (range, _)), new_text)| {
1777                    let new_text_length = new_text.len();
1778                    let old_start = range.start.to_point(&before_edit);
1779                    let new_start = (delta + range.start as isize) as usize;
1780                    delta += new_text_length as isize - (range.end as isize - range.start as isize);
1781
1782                    let mut range_of_insertion_to_indent = 0..new_text_length;
1783                    let mut first_line_is_new = false;
1784                    let mut original_indent_column = None;
1785
1786                    // When inserting an entire line at the beginning of an existing line,
1787                    // treat the insertion as new.
1788                    if new_text.contains('\n')
1789                        && old_start.column <= before_edit.indent_size_for_line(old_start.row).len
1790                    {
1791                        first_line_is_new = true;
1792                    }
1793
1794                    // When inserting text starting with a newline, avoid auto-indenting the
1795                    // previous line.
1796                    if new_text.starts_with('\n') {
1797                        range_of_insertion_to_indent.start += 1;
1798                        first_line_is_new = true;
1799                    }
1800
1801                    // Avoid auto-indenting after the insertion.
1802                    if let AutoindentMode::Block {
1803                        original_indent_columns,
1804                    } = &mode
1805                    {
1806                        original_indent_column =
1807                            Some(original_indent_columns.get(ix).copied().unwrap_or_else(|| {
1808                                indent_size_for_text(
1809                                    new_text[range_of_insertion_to_indent.clone()].chars(),
1810                                )
1811                                .len
1812                            }));
1813                        if new_text[range_of_insertion_to_indent.clone()].ends_with('\n') {
1814                            range_of_insertion_to_indent.end -= 1;
1815                        }
1816                    }
1817
1818                    AutoindentRequestEntry {
1819                        first_line_is_new,
1820                        original_indent_column,
1821                        indent_size: before_edit.language_indent_size_at(range.start, cx),
1822                        range: self.anchor_before(new_start + range_of_insertion_to_indent.start)
1823                            ..self.anchor_after(new_start + range_of_insertion_to_indent.end),
1824                    }
1825                })
1826                .collect();
1827
1828            self.autoindent_requests.push(Arc::new(AutoindentRequest {
1829                before_edit,
1830                entries,
1831                is_block_mode: matches!(mode, AutoindentMode::Block { .. }),
1832            }));
1833        }
1834
1835        self.end_transaction(cx);
1836        self.send_operation(Operation::Buffer(edit_operation), cx);
1837        Some(edit_id)
1838    }
1839
1840    fn did_edit(
1841        &mut self,
1842        old_version: &clock::Global,
1843        was_dirty: bool,
1844        cx: &mut ModelContext<Self>,
1845    ) {
1846        if self.edits_since::<usize>(old_version).next().is_none() {
1847            return;
1848        }
1849
1850        self.reparse(cx);
1851
1852        cx.emit(Event::Edited);
1853        if was_dirty != self.is_dirty() {
1854            cx.emit(Event::DirtyChanged);
1855        }
1856        cx.notify();
1857    }
1858
1859    /// Applies the given remote operations to the buffer.
1860    pub fn apply_ops<I: IntoIterator<Item = Operation>>(
1861        &mut self,
1862        ops: I,
1863        cx: &mut ModelContext<Self>,
1864    ) -> Result<()> {
1865        self.pending_autoindent.take();
1866        let was_dirty = self.is_dirty();
1867        let old_version = self.version.clone();
1868        let mut deferred_ops = Vec::new();
1869        let buffer_ops = ops
1870            .into_iter()
1871            .filter_map(|op| match op {
1872                Operation::Buffer(op) => Some(op),
1873                _ => {
1874                    if self.can_apply_op(&op) {
1875                        self.apply_op(op, cx);
1876                    } else {
1877                        deferred_ops.push(op);
1878                    }
1879                    None
1880                }
1881            })
1882            .collect::<Vec<_>>();
1883        self.text.apply_ops(buffer_ops)?;
1884        self.deferred_ops.insert(deferred_ops);
1885        self.flush_deferred_ops(cx);
1886        self.did_edit(&old_version, was_dirty, cx);
1887        // Notify independently of whether the buffer was edited as the operations could include a
1888        // selection update.
1889        cx.notify();
1890        Ok(())
1891    }
1892
1893    fn flush_deferred_ops(&mut self, cx: &mut ModelContext<Self>) {
1894        let mut deferred_ops = Vec::new();
1895        for op in self.deferred_ops.drain().iter().cloned() {
1896            if self.can_apply_op(&op) {
1897                self.apply_op(op, cx);
1898            } else {
1899                deferred_ops.push(op);
1900            }
1901        }
1902        self.deferred_ops.insert(deferred_ops);
1903    }
1904
1905    fn can_apply_op(&self, operation: &Operation) -> bool {
1906        match operation {
1907            Operation::Buffer(_) => {
1908                unreachable!("buffer operations should never be applied at this layer")
1909            }
1910            Operation::UpdateDiagnostics {
1911                diagnostics: diagnostic_set,
1912                ..
1913            } => diagnostic_set.iter().all(|diagnostic| {
1914                self.text.can_resolve(&diagnostic.range.start)
1915                    && self.text.can_resolve(&diagnostic.range.end)
1916            }),
1917            Operation::UpdateSelections { selections, .. } => selections
1918                .iter()
1919                .all(|s| self.can_resolve(&s.start) && self.can_resolve(&s.end)),
1920            Operation::UpdateCompletionTriggers { .. } => true,
1921        }
1922    }
1923
1924    fn apply_op(&mut self, operation: Operation, cx: &mut ModelContext<Self>) {
1925        match operation {
1926            Operation::Buffer(_) => {
1927                unreachable!("buffer operations should never be applied at this layer")
1928            }
1929            Operation::UpdateDiagnostics {
1930                server_id,
1931                diagnostics: diagnostic_set,
1932                lamport_timestamp,
1933            } => {
1934                let snapshot = self.snapshot();
1935                self.apply_diagnostic_update(
1936                    server_id,
1937                    DiagnosticSet::from_sorted_entries(diagnostic_set.iter().cloned(), &snapshot),
1938                    lamport_timestamp,
1939                    cx,
1940                );
1941            }
1942            Operation::UpdateSelections {
1943                selections,
1944                lamport_timestamp,
1945                line_mode,
1946                cursor_shape,
1947            } => {
1948                if let Some(set) = self.remote_selections.get(&lamport_timestamp.replica_id) {
1949                    if set.lamport_timestamp > lamport_timestamp {
1950                        return;
1951                    }
1952                }
1953
1954                self.remote_selections.insert(
1955                    lamport_timestamp.replica_id,
1956                    SelectionSet {
1957                        selections,
1958                        lamport_timestamp,
1959                        line_mode,
1960                        cursor_shape,
1961                    },
1962                );
1963                self.text.lamport_clock.observe(lamport_timestamp);
1964                self.selections_update_count += 1;
1965            }
1966            Operation::UpdateCompletionTriggers {
1967                triggers,
1968                lamport_timestamp,
1969            } => {
1970                self.completion_triggers = triggers;
1971                self.text.lamport_clock.observe(lamport_timestamp);
1972            }
1973        }
1974    }
1975
1976    fn apply_diagnostic_update(
1977        &mut self,
1978        server_id: LanguageServerId,
1979        diagnostics: DiagnosticSet,
1980        lamport_timestamp: clock::Lamport,
1981        cx: &mut ModelContext<Self>,
1982    ) {
1983        if lamport_timestamp > self.diagnostics_timestamp {
1984            let ix = self.diagnostics.binary_search_by_key(&server_id, |e| e.0);
1985            if diagnostics.len() == 0 {
1986                if let Ok(ix) = ix {
1987                    self.diagnostics.remove(ix);
1988                }
1989            } else {
1990                match ix {
1991                    Err(ix) => self.diagnostics.insert(ix, (server_id, diagnostics)),
1992                    Ok(ix) => self.diagnostics[ix].1 = diagnostics,
1993                };
1994            }
1995            self.diagnostics_timestamp = lamport_timestamp;
1996            self.diagnostics_update_count += 1;
1997            self.text.lamport_clock.observe(lamport_timestamp);
1998            cx.notify();
1999            cx.emit(Event::DiagnosticsUpdated);
2000        }
2001    }
2002
2003    fn send_operation(&mut self, operation: Operation, cx: &mut ModelContext<Self>) {
2004        cx.emit(Event::Operation(operation));
2005    }
2006
2007    /// Removes the selections for a given peer.
2008    pub fn remove_peer(&mut self, replica_id: ReplicaId, cx: &mut ModelContext<Self>) {
2009        self.remote_selections.remove(&replica_id);
2010        cx.notify();
2011    }
2012
2013    /// Undoes the most recent transaction.
2014    pub fn undo(&mut self, cx: &mut ModelContext<Self>) -> Option<TransactionId> {
2015        let was_dirty = self.is_dirty();
2016        let old_version = self.version.clone();
2017
2018        if let Some((transaction_id, operation)) = self.text.undo() {
2019            self.send_operation(Operation::Buffer(operation), cx);
2020            self.did_edit(&old_version, was_dirty, cx);
2021            Some(transaction_id)
2022        } else {
2023            None
2024        }
2025    }
2026
2027    /// Manually undoes a specific transaction in the buffer's undo history.
2028    pub fn undo_transaction(
2029        &mut self,
2030        transaction_id: TransactionId,
2031        cx: &mut ModelContext<Self>,
2032    ) -> bool {
2033        let was_dirty = self.is_dirty();
2034        let old_version = self.version.clone();
2035        if let Some(operation) = self.text.undo_transaction(transaction_id) {
2036            self.send_operation(Operation::Buffer(operation), cx);
2037            self.did_edit(&old_version, was_dirty, cx);
2038            true
2039        } else {
2040            false
2041        }
2042    }
2043
2044    /// Manually undoes all changes after a given transaction in the buffer's undo history.
2045    pub fn undo_to_transaction(
2046        &mut self,
2047        transaction_id: TransactionId,
2048        cx: &mut ModelContext<Self>,
2049    ) -> bool {
2050        let was_dirty = self.is_dirty();
2051        let old_version = self.version.clone();
2052
2053        let operations = self.text.undo_to_transaction(transaction_id);
2054        let undone = !operations.is_empty();
2055        for operation in operations {
2056            self.send_operation(Operation::Buffer(operation), cx);
2057        }
2058        if undone {
2059            self.did_edit(&old_version, was_dirty, cx)
2060        }
2061        undone
2062    }
2063
2064    /// Manually redoes a specific transaction in the buffer's redo history.
2065    pub fn redo(&mut self, cx: &mut ModelContext<Self>) -> Option<TransactionId> {
2066        let was_dirty = self.is_dirty();
2067        let old_version = self.version.clone();
2068
2069        if let Some((transaction_id, operation)) = self.text.redo() {
2070            self.send_operation(Operation::Buffer(operation), cx);
2071            self.did_edit(&old_version, was_dirty, cx);
2072            Some(transaction_id)
2073        } else {
2074            None
2075        }
2076    }
2077
2078    /// Manually undoes all changes until a given transaction in the buffer's redo history.
2079    pub fn redo_to_transaction(
2080        &mut self,
2081        transaction_id: TransactionId,
2082        cx: &mut ModelContext<Self>,
2083    ) -> bool {
2084        let was_dirty = self.is_dirty();
2085        let old_version = self.version.clone();
2086
2087        let operations = self.text.redo_to_transaction(transaction_id);
2088        let redone = !operations.is_empty();
2089        for operation in operations {
2090            self.send_operation(Operation::Buffer(operation), cx);
2091        }
2092        if redone {
2093            self.did_edit(&old_version, was_dirty, cx)
2094        }
2095        redone
2096    }
2097
2098    /// Override current completion triggers with the user-provided completion triggers.
2099    pub fn set_completion_triggers(&mut self, triggers: Vec<String>, cx: &mut ModelContext<Self>) {
2100        self.completion_triggers = triggers.clone();
2101        self.completion_triggers_timestamp = self.text.lamport_clock.tick();
2102        self.send_operation(
2103            Operation::UpdateCompletionTriggers {
2104                triggers,
2105                lamport_timestamp: self.completion_triggers_timestamp,
2106            },
2107            cx,
2108        );
2109        cx.notify();
2110    }
2111
2112    /// Returns a list of strings which trigger a completion menu for this language.
2113    /// Usually this is driven by LSP server which returns a list of trigger characters for completions.
2114    pub fn completion_triggers(&self) -> &[String] {
2115        &self.completion_triggers
2116    }
2117}
2118
2119#[doc(hidden)]
2120#[cfg(any(test, feature = "test-support"))]
2121impl Buffer {
2122    pub fn edit_via_marked_text(
2123        &mut self,
2124        marked_string: &str,
2125        autoindent_mode: Option<AutoindentMode>,
2126        cx: &mut ModelContext<Self>,
2127    ) {
2128        let edits = self.edits_for_marked_text(marked_string);
2129        self.edit(edits, autoindent_mode, cx);
2130    }
2131
2132    pub fn set_group_interval(&mut self, group_interval: Duration) {
2133        self.text.set_group_interval(group_interval);
2134    }
2135
2136    pub fn randomly_edit<T>(
2137        &mut self,
2138        rng: &mut T,
2139        old_range_count: usize,
2140        cx: &mut ModelContext<Self>,
2141    ) where
2142        T: rand::Rng,
2143    {
2144        let mut edits: Vec<(Range<usize>, String)> = Vec::new();
2145        let mut last_end = None;
2146        for _ in 0..old_range_count {
2147            if last_end.map_or(false, |last_end| last_end >= self.len()) {
2148                break;
2149            }
2150
2151            let new_start = last_end.map_or(0, |last_end| last_end + 1);
2152            let mut range = self.random_byte_range(new_start, rng);
2153            if rng.gen_bool(0.2) {
2154                mem::swap(&mut range.start, &mut range.end);
2155            }
2156            last_end = Some(range.end);
2157
2158            let new_text_len = rng.gen_range(0..10);
2159            let new_text: String = RandomCharIter::new(&mut *rng).take(new_text_len).collect();
2160
2161            edits.push((range, new_text));
2162        }
2163        log::info!("mutating buffer {} with {:?}", self.replica_id(), edits);
2164        self.edit(edits, None, cx);
2165    }
2166
2167    pub fn randomly_undo_redo(&mut self, rng: &mut impl rand::Rng, cx: &mut ModelContext<Self>) {
2168        let was_dirty = self.is_dirty();
2169        let old_version = self.version.clone();
2170
2171        let ops = self.text.randomly_undo_redo(rng);
2172        if !ops.is_empty() {
2173            for op in ops {
2174                self.send_operation(Operation::Buffer(op), cx);
2175                self.did_edit(&old_version, was_dirty, cx);
2176            }
2177        }
2178    }
2179}
2180
2181impl EventEmitter<Event> for Buffer {}
2182
2183impl Deref for Buffer {
2184    type Target = TextBuffer;
2185
2186    fn deref(&self) -> &Self::Target {
2187        &self.text
2188    }
2189}
2190
2191impl BufferSnapshot {
2192    /// Returns [`IndentSize`] for a given line that respects user settings and /// language preferences.
2193    pub fn indent_size_for_line(&self, row: u32) -> IndentSize {
2194        indent_size_for_line(self, row)
2195    }
2196    /// Returns [`IndentSize`] for a given position that respects user settings
2197    /// and language preferences.
2198    pub fn language_indent_size_at<T: ToOffset>(&self, position: T, cx: &AppContext) -> IndentSize {
2199        let settings = language_settings(self.language_at(position), self.file(), cx);
2200        if settings.hard_tabs {
2201            IndentSize::tab()
2202        } else {
2203            IndentSize::spaces(settings.tab_size.get())
2204        }
2205    }
2206
2207    /// Retrieve the suggested indent size for all of the given rows. The unit of indentation
2208    /// is passed in as `single_indent_size`.
2209    pub fn suggested_indents(
2210        &self,
2211        rows: impl Iterator<Item = u32>,
2212        single_indent_size: IndentSize,
2213    ) -> BTreeMap<u32, IndentSize> {
2214        let mut result = BTreeMap::new();
2215
2216        for row_range in contiguous_ranges(rows, 10) {
2217            let suggestions = match self.suggest_autoindents(row_range.clone()) {
2218                Some(suggestions) => suggestions,
2219                _ => break,
2220            };
2221
2222            for (row, suggestion) in row_range.zip(suggestions) {
2223                let indent_size = if let Some(suggestion) = suggestion {
2224                    result
2225                        .get(&suggestion.basis_row)
2226                        .copied()
2227                        .unwrap_or_else(|| self.indent_size_for_line(suggestion.basis_row))
2228                        .with_delta(suggestion.delta, single_indent_size)
2229                } else {
2230                    self.indent_size_for_line(row)
2231                };
2232
2233                result.insert(row, indent_size);
2234            }
2235        }
2236
2237        result
2238    }
2239
2240    fn suggest_autoindents(
2241        &self,
2242        row_range: Range<u32>,
2243    ) -> Option<impl Iterator<Item = Option<IndentSuggestion>> + '_> {
2244        let config = &self.language.as_ref()?.config;
2245        let prev_non_blank_row = self.prev_non_blank_row(row_range.start);
2246
2247        // Find the suggested indentation ranges based on the syntax tree.
2248        let start = Point::new(prev_non_blank_row.unwrap_or(row_range.start), 0);
2249        let end = Point::new(row_range.end, 0);
2250        let range = (start..end).to_offset(&self.text);
2251        let mut matches = self.syntax.matches(range.clone(), &self.text, |grammar| {
2252            Some(&grammar.indents_config.as_ref()?.query)
2253        });
2254        let indent_configs = matches
2255            .grammars()
2256            .iter()
2257            .map(|grammar| grammar.indents_config.as_ref().unwrap())
2258            .collect::<Vec<_>>();
2259
2260        let mut indent_ranges = Vec::<Range<Point>>::new();
2261        let mut outdent_positions = Vec::<Point>::new();
2262        while let Some(mat) = matches.peek() {
2263            let mut start: Option<Point> = None;
2264            let mut end: Option<Point> = None;
2265
2266            let config = &indent_configs[mat.grammar_index];
2267            for capture in mat.captures {
2268                if capture.index == config.indent_capture_ix {
2269                    start.get_or_insert(Point::from_ts_point(capture.node.start_position()));
2270                    end.get_or_insert(Point::from_ts_point(capture.node.end_position()));
2271                } else if Some(capture.index) == config.start_capture_ix {
2272                    start = Some(Point::from_ts_point(capture.node.end_position()));
2273                } else if Some(capture.index) == config.end_capture_ix {
2274                    end = Some(Point::from_ts_point(capture.node.start_position()));
2275                } else if Some(capture.index) == config.outdent_capture_ix {
2276                    outdent_positions.push(Point::from_ts_point(capture.node.start_position()));
2277                }
2278            }
2279
2280            matches.advance();
2281            if let Some((start, end)) = start.zip(end) {
2282                if start.row == end.row {
2283                    continue;
2284                }
2285
2286                let range = start..end;
2287                match indent_ranges.binary_search_by_key(&range.start, |r| r.start) {
2288                    Err(ix) => indent_ranges.insert(ix, range),
2289                    Ok(ix) => {
2290                        let prev_range = &mut indent_ranges[ix];
2291                        prev_range.end = prev_range.end.max(range.end);
2292                    }
2293                }
2294            }
2295        }
2296
2297        let mut error_ranges = Vec::<Range<Point>>::new();
2298        let mut matches = self.syntax.matches(range.clone(), &self.text, |grammar| {
2299            Some(&grammar.error_query)
2300        });
2301        while let Some(mat) = matches.peek() {
2302            let node = mat.captures[0].node;
2303            let start = Point::from_ts_point(node.start_position());
2304            let end = Point::from_ts_point(node.end_position());
2305            let range = start..end;
2306            let ix = match error_ranges.binary_search_by_key(&range.start, |r| r.start) {
2307                Ok(ix) | Err(ix) => ix,
2308            };
2309            let mut end_ix = ix;
2310            while let Some(existing_range) = error_ranges.get(end_ix) {
2311                if existing_range.end < end {
2312                    end_ix += 1;
2313                } else {
2314                    break;
2315                }
2316            }
2317            error_ranges.splice(ix..end_ix, [range]);
2318            matches.advance();
2319        }
2320
2321        outdent_positions.sort();
2322        for outdent_position in outdent_positions {
2323            // find the innermost indent range containing this outdent_position
2324            // set its end to the outdent position
2325            if let Some(range_to_truncate) = indent_ranges
2326                .iter_mut()
2327                .filter(|indent_range| indent_range.contains(&outdent_position))
2328                .last()
2329            {
2330                range_to_truncate.end = outdent_position;
2331            }
2332        }
2333
2334        // Find the suggested indentation increases and decreased based on regexes.
2335        let mut indent_change_rows = Vec::<(u32, Ordering)>::new();
2336        self.for_each_line(
2337            Point::new(prev_non_blank_row.unwrap_or(row_range.start), 0)
2338                ..Point::new(row_range.end, 0),
2339            |row, line| {
2340                if config
2341                    .decrease_indent_pattern
2342                    .as_ref()
2343                    .map_or(false, |regex| regex.is_match(line))
2344                {
2345                    indent_change_rows.push((row, Ordering::Less));
2346                }
2347                if config
2348                    .increase_indent_pattern
2349                    .as_ref()
2350                    .map_or(false, |regex| regex.is_match(line))
2351                {
2352                    indent_change_rows.push((row + 1, Ordering::Greater));
2353                }
2354            },
2355        );
2356
2357        let mut indent_changes = indent_change_rows.into_iter().peekable();
2358        let mut prev_row = if config.auto_indent_using_last_non_empty_line {
2359            prev_non_blank_row.unwrap_or(0)
2360        } else {
2361            row_range.start.saturating_sub(1)
2362        };
2363        let mut prev_row_start = Point::new(prev_row, self.indent_size_for_line(prev_row).len);
2364        Some(row_range.map(move |row| {
2365            let row_start = Point::new(row, self.indent_size_for_line(row).len);
2366
2367            let mut indent_from_prev_row = false;
2368            let mut outdent_from_prev_row = false;
2369            let mut outdent_to_row = u32::MAX;
2370
2371            while let Some((indent_row, delta)) = indent_changes.peek() {
2372                match indent_row.cmp(&row) {
2373                    Ordering::Equal => match delta {
2374                        Ordering::Less => outdent_from_prev_row = true,
2375                        Ordering::Greater => indent_from_prev_row = true,
2376                        _ => {}
2377                    },
2378
2379                    Ordering::Greater => break,
2380                    Ordering::Less => {}
2381                }
2382
2383                indent_changes.next();
2384            }
2385
2386            for range in &indent_ranges {
2387                if range.start.row >= row {
2388                    break;
2389                }
2390                if range.start.row == prev_row && range.end > row_start {
2391                    indent_from_prev_row = true;
2392                }
2393                if range.end > prev_row_start && range.end <= row_start {
2394                    outdent_to_row = outdent_to_row.min(range.start.row);
2395                }
2396            }
2397
2398            let within_error = error_ranges
2399                .iter()
2400                .any(|e| e.start.row < row && e.end > row_start);
2401
2402            let suggestion = if outdent_to_row == prev_row
2403                || (outdent_from_prev_row && indent_from_prev_row)
2404            {
2405                Some(IndentSuggestion {
2406                    basis_row: prev_row,
2407                    delta: Ordering::Equal,
2408                    within_error,
2409                })
2410            } else if indent_from_prev_row {
2411                Some(IndentSuggestion {
2412                    basis_row: prev_row,
2413                    delta: Ordering::Greater,
2414                    within_error,
2415                })
2416            } else if outdent_to_row < prev_row {
2417                Some(IndentSuggestion {
2418                    basis_row: outdent_to_row,
2419                    delta: Ordering::Equal,
2420                    within_error,
2421                })
2422            } else if outdent_from_prev_row {
2423                Some(IndentSuggestion {
2424                    basis_row: prev_row,
2425                    delta: Ordering::Less,
2426                    within_error,
2427                })
2428            } else if config.auto_indent_using_last_non_empty_line || !self.is_line_blank(prev_row)
2429            {
2430                Some(IndentSuggestion {
2431                    basis_row: prev_row,
2432                    delta: Ordering::Equal,
2433                    within_error,
2434                })
2435            } else {
2436                None
2437            };
2438
2439            prev_row = row;
2440            prev_row_start = row_start;
2441            suggestion
2442        }))
2443    }
2444
2445    fn prev_non_blank_row(&self, mut row: u32) -> Option<u32> {
2446        while row > 0 {
2447            row -= 1;
2448            if !self.is_line_blank(row) {
2449                return Some(row);
2450            }
2451        }
2452        None
2453    }
2454
2455    /// Iterates over chunks of text in the given range of the buffer. Text is chunked
2456    /// in an arbitrary way due to being stored in a [`Rope`](text::Rope). The text is also
2457    /// returned in chunks where each chunk has a single syntax highlighting style and
2458    /// diagnostic status.
2459    pub fn chunks<T: ToOffset>(&self, range: Range<T>, language_aware: bool) -> BufferChunks {
2460        let range = range.start.to_offset(self)..range.end.to_offset(self);
2461
2462        let mut syntax = None;
2463        let mut diagnostic_endpoints = Vec::new();
2464        if language_aware {
2465            let captures = self.syntax.captures(range.clone(), &self.text, |grammar| {
2466                grammar.highlights_query.as_ref()
2467            });
2468            let highlight_maps = captures
2469                .grammars()
2470                .into_iter()
2471                .map(|grammar| grammar.highlight_map())
2472                .collect();
2473            syntax = Some((captures, highlight_maps));
2474            for entry in self.diagnostics_in_range::<_, usize>(range.clone(), false) {
2475                diagnostic_endpoints.push(DiagnosticEndpoint {
2476                    offset: entry.range.start,
2477                    is_start: true,
2478                    severity: entry.diagnostic.severity,
2479                    is_unnecessary: entry.diagnostic.is_unnecessary,
2480                });
2481                diagnostic_endpoints.push(DiagnosticEndpoint {
2482                    offset: entry.range.end,
2483                    is_start: false,
2484                    severity: entry.diagnostic.severity,
2485                    is_unnecessary: entry.diagnostic.is_unnecessary,
2486                });
2487            }
2488            diagnostic_endpoints
2489                .sort_unstable_by_key(|endpoint| (endpoint.offset, !endpoint.is_start));
2490        }
2491
2492        BufferChunks::new(self.text.as_rope(), range, syntax, diagnostic_endpoints)
2493    }
2494
2495    /// Invokes the given callback for each line of text in the given range of the buffer.
2496    /// Uses callback to avoid allocating a string for each line.
2497    fn for_each_line(&self, range: Range<Point>, mut callback: impl FnMut(u32, &str)) {
2498        let mut line = String::new();
2499        let mut row = range.start.row;
2500        for chunk in self
2501            .as_rope()
2502            .chunks_in_range(range.to_offset(self))
2503            .chain(["\n"])
2504        {
2505            for (newline_ix, text) in chunk.split('\n').enumerate() {
2506                if newline_ix > 0 {
2507                    callback(row, &line);
2508                    row += 1;
2509                    line.clear();
2510                }
2511                line.push_str(text);
2512            }
2513        }
2514    }
2515
2516    /// Iterates over every [`SyntaxLayer`] in the buffer.
2517    pub fn syntax_layers(&self) -> impl Iterator<Item = SyntaxLayer> + '_ {
2518        self.syntax.layers_for_range(0..self.len(), &self.text)
2519    }
2520
2521    pub fn syntax_layer_at<D: ToOffset>(&self, position: D) -> Option<SyntaxLayer> {
2522        let offset = position.to_offset(self);
2523        self.syntax
2524            .layers_for_range(offset..offset, &self.text)
2525            .filter(|l| l.node().end_byte() > offset)
2526            .last()
2527    }
2528
2529    /// Returns the [Language] at the given location.
2530    pub fn language_at<D: ToOffset>(&self, position: D) -> Option<&Arc<Language>> {
2531        self.syntax_layer_at(position)
2532            .map(|info| info.language)
2533            .or(self.language.as_ref())
2534    }
2535
2536    /// Returns the settings for the language at the given location.
2537    pub fn settings_at<'a, D: ToOffset>(
2538        &self,
2539        position: D,
2540        cx: &'a AppContext,
2541    ) -> &'a LanguageSettings {
2542        language_settings(self.language_at(position), self.file.as_ref(), cx)
2543    }
2544
2545    /// Returns the [LanguageScope] at the given location.
2546    pub fn language_scope_at<D: ToOffset>(&self, position: D) -> Option<LanguageScope> {
2547        let offset = position.to_offset(self);
2548        let mut scope = None;
2549        let mut smallest_range: Option<Range<usize>> = None;
2550
2551        // Use the layer that has the smallest node intersecting the given point.
2552        for layer in self.syntax.layers_for_range(offset..offset, &self.text) {
2553            let mut cursor = layer.node().walk();
2554
2555            let mut range = None;
2556            loop {
2557                let child_range = cursor.node().byte_range();
2558                if !child_range.to_inclusive().contains(&offset) {
2559                    break;
2560                }
2561
2562                range = Some(child_range);
2563                if cursor.goto_first_child_for_byte(offset).is_none() {
2564                    break;
2565                }
2566            }
2567
2568            if let Some(range) = range {
2569                if smallest_range
2570                    .as_ref()
2571                    .map_or(true, |smallest_range| range.len() < smallest_range.len())
2572                {
2573                    smallest_range = Some(range);
2574                    scope = Some(LanguageScope {
2575                        language: layer.language.clone(),
2576                        override_id: layer.override_id(offset, &self.text),
2577                    });
2578                }
2579            }
2580        }
2581
2582        scope.or_else(|| {
2583            self.language.clone().map(|language| LanguageScope {
2584                language,
2585                override_id: None,
2586            })
2587        })
2588    }
2589
2590    /// Returns a tuple of the range and character kind of the word
2591    /// surrounding the given position.
2592    pub fn surrounding_word<T: ToOffset>(&self, start: T) -> (Range<usize>, Option<CharKind>) {
2593        let mut start = start.to_offset(self);
2594        let mut end = start;
2595        let mut next_chars = self.chars_at(start).peekable();
2596        let mut prev_chars = self.reversed_chars_at(start).peekable();
2597
2598        let scope = self.language_scope_at(start);
2599        let kind = |c| char_kind(&scope, c);
2600        let word_kind = cmp::max(
2601            prev_chars.peek().copied().map(kind),
2602            next_chars.peek().copied().map(kind),
2603        );
2604
2605        for ch in prev_chars {
2606            if Some(kind(ch)) == word_kind && ch != '\n' {
2607                start -= ch.len_utf8();
2608            } else {
2609                break;
2610            }
2611        }
2612
2613        for ch in next_chars {
2614            if Some(kind(ch)) == word_kind && ch != '\n' {
2615                end += ch.len_utf8();
2616            } else {
2617                break;
2618            }
2619        }
2620
2621        (start..end, word_kind)
2622    }
2623
2624    /// Returns the range for the closes syntax node enclosing the given range.
2625    pub fn range_for_syntax_ancestor<T: ToOffset>(&self, range: Range<T>) -> Option<Range<usize>> {
2626        let range = range.start.to_offset(self)..range.end.to_offset(self);
2627        let mut result: Option<Range<usize>> = None;
2628        'outer: for layer in self.syntax.layers_for_range(range.clone(), &self.text) {
2629            let mut cursor = layer.node().walk();
2630
2631            // Descend to the first leaf that touches the start of the range,
2632            // and if the range is non-empty, extends beyond the start.
2633            while cursor.goto_first_child_for_byte(range.start).is_some() {
2634                if !range.is_empty() && cursor.node().end_byte() == range.start {
2635                    cursor.goto_next_sibling();
2636                }
2637            }
2638
2639            // Ascend to the smallest ancestor that strictly contains the range.
2640            loop {
2641                let node_range = cursor.node().byte_range();
2642                if node_range.start <= range.start
2643                    && node_range.end >= range.end
2644                    && node_range.len() > range.len()
2645                {
2646                    break;
2647                }
2648                if !cursor.goto_parent() {
2649                    continue 'outer;
2650                }
2651            }
2652
2653            let left_node = cursor.node();
2654            let mut layer_result = left_node.byte_range();
2655
2656            // For an empty range, try to find another node immediately to the right of the range.
2657            if left_node.end_byte() == range.start {
2658                let mut right_node = None;
2659                while !cursor.goto_next_sibling() {
2660                    if !cursor.goto_parent() {
2661                        break;
2662                    }
2663                }
2664
2665                while cursor.node().start_byte() == range.start {
2666                    right_node = Some(cursor.node());
2667                    if !cursor.goto_first_child() {
2668                        break;
2669                    }
2670                }
2671
2672                // If there is a candidate node on both sides of the (empty) range, then
2673                // decide between the two by favoring a named node over an anonymous token.
2674                // If both nodes are the same in that regard, favor the right one.
2675                if let Some(right_node) = right_node {
2676                    if right_node.is_named() || !left_node.is_named() {
2677                        layer_result = right_node.byte_range();
2678                    }
2679                }
2680            }
2681
2682            if let Some(previous_result) = &result {
2683                if previous_result.len() < layer_result.len() {
2684                    continue;
2685                }
2686            }
2687            result = Some(layer_result);
2688        }
2689
2690        result
2691    }
2692
2693    /// Returns the outline for the buffer.
2694    ///
2695    /// This method allows passing an optional [SyntaxTheme] to
2696    /// syntax-highlight the returned symbols.
2697    pub fn outline(&self, theme: Option<&SyntaxTheme>) -> Option<Outline<Anchor>> {
2698        self.outline_items_containing(0..self.len(), true, theme)
2699            .map(Outline::new)
2700    }
2701
2702    /// Returns all the symbols that contain the given position.
2703    ///
2704    /// This method allows passing an optional [SyntaxTheme] to
2705    /// syntax-highlight the returned symbols.
2706    pub fn symbols_containing<T: ToOffset>(
2707        &self,
2708        position: T,
2709        theme: Option<&SyntaxTheme>,
2710    ) -> Option<Vec<OutlineItem<Anchor>>> {
2711        let position = position.to_offset(self);
2712        let mut items = self.outline_items_containing(
2713            position.saturating_sub(1)..self.len().min(position + 1),
2714            false,
2715            theme,
2716        )?;
2717        let mut prev_depth = None;
2718        items.retain(|item| {
2719            let result = prev_depth.map_or(true, |prev_depth| item.depth > prev_depth);
2720            prev_depth = Some(item.depth);
2721            result
2722        });
2723        Some(items)
2724    }
2725
2726    fn outline_items_containing(
2727        &self,
2728        range: Range<usize>,
2729        include_extra_context: bool,
2730        theme: Option<&SyntaxTheme>,
2731    ) -> Option<Vec<OutlineItem<Anchor>>> {
2732        let mut matches = self.syntax.matches(range.clone(), &self.text, |grammar| {
2733            grammar.outline_config.as_ref().map(|c| &c.query)
2734        });
2735        let configs = matches
2736            .grammars()
2737            .iter()
2738            .map(|g| g.outline_config.as_ref().unwrap())
2739            .collect::<Vec<_>>();
2740
2741        let mut stack = Vec::<Range<usize>>::new();
2742        let mut items = Vec::new();
2743        while let Some(mat) = matches.peek() {
2744            let config = &configs[mat.grammar_index];
2745            let item_node = mat.captures.iter().find_map(|cap| {
2746                if cap.index == config.item_capture_ix {
2747                    Some(cap.node)
2748                } else {
2749                    None
2750                }
2751            })?;
2752
2753            let item_range = item_node.byte_range();
2754            if item_range.end < range.start || item_range.start > range.end {
2755                matches.advance();
2756                continue;
2757            }
2758
2759            let mut buffer_ranges = Vec::new();
2760            for capture in mat.captures {
2761                let node_is_name;
2762                if capture.index == config.name_capture_ix {
2763                    node_is_name = true;
2764                } else if Some(capture.index) == config.context_capture_ix
2765                    || (Some(capture.index) == config.extra_context_capture_ix
2766                        && include_extra_context)
2767                {
2768                    node_is_name = false;
2769                } else {
2770                    continue;
2771                }
2772
2773                let mut range = capture.node.start_byte()..capture.node.end_byte();
2774                let start = capture.node.start_position();
2775                if capture.node.end_position().row > start.row {
2776                    range.end =
2777                        range.start + self.line_len(start.row as u32) as usize - start.column;
2778                }
2779
2780                if !range.is_empty() {
2781                    buffer_ranges.push((range, node_is_name));
2782                }
2783            }
2784
2785            if buffer_ranges.is_empty() {
2786                matches.advance();
2787                continue;
2788            }
2789
2790            let mut text = String::new();
2791            let mut highlight_ranges = Vec::new();
2792            let mut name_ranges = Vec::new();
2793            let mut chunks = self.chunks(
2794                buffer_ranges.first().unwrap().0.start..buffer_ranges.last().unwrap().0.end,
2795                true,
2796            );
2797            let mut last_buffer_range_end = 0;
2798            for (buffer_range, is_name) in buffer_ranges {
2799                if !text.is_empty() && buffer_range.start > last_buffer_range_end {
2800                    text.push(' ');
2801                }
2802                last_buffer_range_end = buffer_range.end;
2803                if is_name {
2804                    let mut start = text.len();
2805                    let end = start + buffer_range.len();
2806
2807                    // When multiple names are captured, then the matcheable text
2808                    // includes the whitespace in between the names.
2809                    if !name_ranges.is_empty() {
2810                        start -= 1;
2811                    }
2812
2813                    name_ranges.push(start..end);
2814                }
2815
2816                let mut offset = buffer_range.start;
2817                chunks.seek(offset);
2818                for mut chunk in chunks.by_ref() {
2819                    if chunk.text.len() > buffer_range.end - offset {
2820                        chunk.text = &chunk.text[0..(buffer_range.end - offset)];
2821                        offset = buffer_range.end;
2822                    } else {
2823                        offset += chunk.text.len();
2824                    }
2825                    let style = chunk
2826                        .syntax_highlight_id
2827                        .zip(theme)
2828                        .and_then(|(highlight, theme)| highlight.style(theme));
2829                    if let Some(style) = style {
2830                        let start = text.len();
2831                        let end = start + chunk.text.len();
2832                        highlight_ranges.push((start..end, style));
2833                    }
2834                    text.push_str(chunk.text);
2835                    if offset >= buffer_range.end {
2836                        break;
2837                    }
2838                }
2839            }
2840
2841            matches.advance();
2842            while stack.last().map_or(false, |prev_range| {
2843                prev_range.start > item_range.start || prev_range.end < item_range.end
2844            }) {
2845                stack.pop();
2846            }
2847            stack.push(item_range.clone());
2848
2849            items.push(OutlineItem {
2850                depth: stack.len() - 1,
2851                range: self.anchor_after(item_range.start)..self.anchor_before(item_range.end),
2852                text,
2853                highlight_ranges,
2854                name_ranges,
2855            })
2856        }
2857        Some(items)
2858    }
2859
2860    /// For each grammar in the language, runs the provided
2861    /// [tree_sitter::Query] against the given range.
2862    pub fn matches(
2863        &self,
2864        range: Range<usize>,
2865        query: fn(&Grammar) -> Option<&tree_sitter::Query>,
2866    ) -> SyntaxMapMatches {
2867        self.syntax.matches(range, self, query)
2868    }
2869
2870    /// Returns bracket range pairs overlapping or adjacent to `range`
2871    pub fn bracket_ranges<T: ToOffset>(
2872        &self,
2873        range: Range<T>,
2874    ) -> impl Iterator<Item = (Range<usize>, Range<usize>)> + '_ {
2875        // Find bracket pairs that *inclusively* contain the given range.
2876        let range = range.start.to_offset(self).saturating_sub(1)
2877            ..self.len().min(range.end.to_offset(self) + 1);
2878
2879        let mut matches = self.syntax.matches(range.clone(), &self.text, |grammar| {
2880            grammar.brackets_config.as_ref().map(|c| &c.query)
2881        });
2882        let configs = matches
2883            .grammars()
2884            .iter()
2885            .map(|grammar| grammar.brackets_config.as_ref().unwrap())
2886            .collect::<Vec<_>>();
2887
2888        iter::from_fn(move || {
2889            while let Some(mat) = matches.peek() {
2890                let mut open = None;
2891                let mut close = None;
2892                let config = &configs[mat.grammar_index];
2893                for capture in mat.captures {
2894                    if capture.index == config.open_capture_ix {
2895                        open = Some(capture.node.byte_range());
2896                    } else if capture.index == config.close_capture_ix {
2897                        close = Some(capture.node.byte_range());
2898                    }
2899                }
2900
2901                matches.advance();
2902
2903                let Some((open, close)) = open.zip(close) else {
2904                    continue;
2905                };
2906
2907                let bracket_range = open.start..=close.end;
2908                if !bracket_range.overlaps(&range) {
2909                    continue;
2910                }
2911
2912                return Some((open, close));
2913            }
2914            None
2915        })
2916    }
2917
2918    /// Returns enclosing bracket ranges containing the given range
2919    pub fn enclosing_bracket_ranges<T: ToOffset>(
2920        &self,
2921        range: Range<T>,
2922    ) -> impl Iterator<Item = (Range<usize>, Range<usize>)> + '_ {
2923        let range = range.start.to_offset(self)..range.end.to_offset(self);
2924
2925        self.bracket_ranges(range.clone())
2926            .filter(move |(open, close)| open.start <= range.start && close.end >= range.end)
2927    }
2928
2929    /// Returns the smallest enclosing bracket ranges containing the given range or None if no brackets contain range
2930    ///
2931    /// Can optionally pass a range_filter to filter the ranges of brackets to consider
2932    pub fn innermost_enclosing_bracket_ranges<T: ToOffset>(
2933        &self,
2934        range: Range<T>,
2935        range_filter: Option<&dyn Fn(Range<usize>, Range<usize>) -> bool>,
2936    ) -> Option<(Range<usize>, Range<usize>)> {
2937        let range = range.start.to_offset(self)..range.end.to_offset(self);
2938
2939        // Get the ranges of the innermost pair of brackets.
2940        let mut result: Option<(Range<usize>, Range<usize>)> = None;
2941
2942        for (open, close) in self.enclosing_bracket_ranges(range.clone()) {
2943            if let Some(range_filter) = range_filter {
2944                if !range_filter(open.clone(), close.clone()) {
2945                    continue;
2946                }
2947            }
2948
2949            let len = close.end - open.start;
2950
2951            if let Some((existing_open, existing_close)) = &result {
2952                let existing_len = existing_close.end - existing_open.start;
2953                if len > existing_len {
2954                    continue;
2955                }
2956            }
2957
2958            result = Some((open, close));
2959        }
2960
2961        result
2962    }
2963
2964    /// Returns anchor ranges for any matches of the redaction query.
2965    /// The buffer can be associated with multiple languages, and the redaction query associated with each
2966    /// will be run on the relevant section of the buffer.
2967    pub fn redacted_ranges<T: ToOffset>(
2968        &self,
2969        range: Range<T>,
2970    ) -> impl Iterator<Item = Range<usize>> + '_ {
2971        let offset_range = range.start.to_offset(self)..range.end.to_offset(self);
2972        let mut syntax_matches = self.syntax.matches(offset_range, self, |grammar| {
2973            grammar
2974                .redactions_config
2975                .as_ref()
2976                .map(|config| &config.query)
2977        });
2978
2979        let configs = syntax_matches
2980            .grammars()
2981            .iter()
2982            .map(|grammar| grammar.redactions_config.as_ref())
2983            .collect::<Vec<_>>();
2984
2985        iter::from_fn(move || {
2986            let redacted_range = syntax_matches
2987                .peek()
2988                .and_then(|mat| {
2989                    configs[mat.grammar_index].and_then(|config| {
2990                        mat.captures
2991                            .iter()
2992                            .find(|capture| capture.index == config.redaction_capture_ix)
2993                    })
2994                })
2995                .map(|mat| mat.node.byte_range());
2996            syntax_matches.advance();
2997            redacted_range
2998        })
2999    }
3000
3001    /// Returns selections for remote peers intersecting the given range.
3002    #[allow(clippy::type_complexity)]
3003    pub fn remote_selections_in_range(
3004        &self,
3005        range: Range<Anchor>,
3006    ) -> impl Iterator<
3007        Item = (
3008            ReplicaId,
3009            bool,
3010            CursorShape,
3011            impl Iterator<Item = &Selection<Anchor>> + '_,
3012        ),
3013    > + '_ {
3014        self.remote_selections
3015            .iter()
3016            .filter(|(replica_id, set)| {
3017                **replica_id != self.text.replica_id() && !set.selections.is_empty()
3018            })
3019            .map(move |(replica_id, set)| {
3020                let start_ix = match set.selections.binary_search_by(|probe| {
3021                    probe.end.cmp(&range.start, self).then(Ordering::Greater)
3022                }) {
3023                    Ok(ix) | Err(ix) => ix,
3024                };
3025                let end_ix = match set.selections.binary_search_by(|probe| {
3026                    probe.start.cmp(&range.end, self).then(Ordering::Less)
3027                }) {
3028                    Ok(ix) | Err(ix) => ix,
3029                };
3030
3031                (
3032                    *replica_id,
3033                    set.line_mode,
3034                    set.cursor_shape,
3035                    set.selections[start_ix..end_ix].iter(),
3036                )
3037            })
3038    }
3039
3040    /// Whether the buffer contains any git changes.
3041    pub fn has_git_diff(&self) -> bool {
3042        !self.git_diff.is_empty()
3043    }
3044
3045    /// Returns all the Git diff hunks intersecting the given
3046    /// row range.
3047    pub fn git_diff_hunks_in_row_range(
3048        &self,
3049        range: Range<u32>,
3050    ) -> impl '_ + Iterator<Item = git::diff::DiffHunk<u32>> {
3051        self.git_diff.hunks_in_row_range(range, self)
3052    }
3053
3054    /// Returns all the Git diff hunks intersecting the given
3055    /// range.
3056    pub fn git_diff_hunks_intersecting_range(
3057        &self,
3058        range: Range<Anchor>,
3059    ) -> impl '_ + Iterator<Item = git::diff::DiffHunk<u32>> {
3060        self.git_diff.hunks_intersecting_range(range, self)
3061    }
3062
3063    /// Returns all the Git diff hunks intersecting the given
3064    /// range, in reverse order.
3065    pub fn git_diff_hunks_intersecting_range_rev(
3066        &self,
3067        range: Range<Anchor>,
3068    ) -> impl '_ + Iterator<Item = git::diff::DiffHunk<u32>> {
3069        self.git_diff.hunks_intersecting_range_rev(range, self)
3070    }
3071
3072    /// Returns if the buffer contains any diagnostics.
3073    pub fn has_diagnostics(&self) -> bool {
3074        !self.diagnostics.is_empty()
3075    }
3076
3077    /// Returns all the diagnostics intersecting the given range.
3078    pub fn diagnostics_in_range<'a, T, O>(
3079        &'a self,
3080        search_range: Range<T>,
3081        reversed: bool,
3082    ) -> impl 'a + Iterator<Item = DiagnosticEntry<O>>
3083    where
3084        T: 'a + Clone + ToOffset,
3085        O: 'a + FromAnchor + Ord,
3086    {
3087        let mut iterators: Vec<_> = self
3088            .diagnostics
3089            .iter()
3090            .map(|(_, collection)| {
3091                collection
3092                    .range::<T, O>(search_range.clone(), self, true, reversed)
3093                    .peekable()
3094            })
3095            .collect();
3096
3097        std::iter::from_fn(move || {
3098            let (next_ix, _) = iterators
3099                .iter_mut()
3100                .enumerate()
3101                .flat_map(|(ix, iter)| Some((ix, iter.peek()?)))
3102                .min_by(|(_, a), (_, b)| a.range.start.cmp(&b.range.start))?;
3103            iterators[next_ix].next()
3104        })
3105    }
3106
3107    /// Returns all the diagnostic groups associated with the given
3108    /// language server id. If no language server id is provided,
3109    /// all diagnostics groups are returned.
3110    pub fn diagnostic_groups(
3111        &self,
3112        language_server_id: Option<LanguageServerId>,
3113    ) -> Vec<(LanguageServerId, DiagnosticGroup<Anchor>)> {
3114        let mut groups = Vec::new();
3115
3116        if let Some(language_server_id) = language_server_id {
3117            if let Ok(ix) = self
3118                .diagnostics
3119                .binary_search_by_key(&language_server_id, |e| e.0)
3120            {
3121                self.diagnostics[ix]
3122                    .1
3123                    .groups(language_server_id, &mut groups, self);
3124            }
3125        } else {
3126            for (language_server_id, diagnostics) in self.diagnostics.iter() {
3127                diagnostics.groups(*language_server_id, &mut groups, self);
3128            }
3129        }
3130
3131        groups.sort_by(|(id_a, group_a), (id_b, group_b)| {
3132            let a_start = &group_a.entries[group_a.primary_ix].range.start;
3133            let b_start = &group_b.entries[group_b.primary_ix].range.start;
3134            a_start.cmp(b_start, self).then_with(|| id_a.cmp(id_b))
3135        });
3136
3137        groups
3138    }
3139
3140    /// Returns an iterator over the diagnostics for the given group.
3141    pub fn diagnostic_group<'a, O>(
3142        &'a self,
3143        group_id: usize,
3144    ) -> impl 'a + Iterator<Item = DiagnosticEntry<O>>
3145    where
3146        O: 'a + FromAnchor,
3147    {
3148        self.diagnostics
3149            .iter()
3150            .flat_map(move |(_, set)| set.group(group_id, self))
3151    }
3152
3153    /// The number of times diagnostics were updated.
3154    pub fn diagnostics_update_count(&self) -> usize {
3155        self.diagnostics_update_count
3156    }
3157
3158    /// The number of times the buffer was parsed.
3159    pub fn parse_count(&self) -> usize {
3160        self.parse_count
3161    }
3162
3163    /// The number of times selections were updated.
3164    pub fn selections_update_count(&self) -> usize {
3165        self.selections_update_count
3166    }
3167
3168    /// Returns a snapshot of underlying file.
3169    pub fn file(&self) -> Option<&Arc<dyn File>> {
3170        self.file.as_ref()
3171    }
3172
3173    /// Resolves the file path (relative to the worktree root) associated with the underlying file.
3174    pub fn resolve_file_path(&self, cx: &AppContext, include_root: bool) -> Option<PathBuf> {
3175        if let Some(file) = self.file() {
3176            if file.path().file_name().is_none() || include_root {
3177                Some(file.full_path(cx))
3178            } else {
3179                Some(file.path().to_path_buf())
3180            }
3181        } else {
3182            None
3183        }
3184    }
3185
3186    /// The number of times the underlying file was updated.
3187    pub fn file_update_count(&self) -> usize {
3188        self.file_update_count
3189    }
3190
3191    /// The number of times the git diff status was updated.
3192    pub fn git_diff_update_count(&self) -> usize {
3193        self.git_diff_update_count
3194    }
3195}
3196
3197fn indent_size_for_line(text: &text::BufferSnapshot, row: u32) -> IndentSize {
3198    indent_size_for_text(text.chars_at(Point::new(row, 0)))
3199}
3200
3201fn indent_size_for_text(text: impl Iterator<Item = char>) -> IndentSize {
3202    let mut result = IndentSize::spaces(0);
3203    for c in text {
3204        let kind = match c {
3205            ' ' => IndentKind::Space,
3206            '\t' => IndentKind::Tab,
3207            _ => break,
3208        };
3209        if result.len == 0 {
3210            result.kind = kind;
3211        }
3212        result.len += 1;
3213    }
3214    result
3215}
3216
3217impl Clone for BufferSnapshot {
3218    fn clone(&self) -> Self {
3219        Self {
3220            text: self.text.clone(),
3221            git_diff: self.git_diff.clone(),
3222            syntax: self.syntax.clone(),
3223            file: self.file.clone(),
3224            remote_selections: self.remote_selections.clone(),
3225            diagnostics: self.diagnostics.clone(),
3226            selections_update_count: self.selections_update_count,
3227            diagnostics_update_count: self.diagnostics_update_count,
3228            file_update_count: self.file_update_count,
3229            git_diff_update_count: self.git_diff_update_count,
3230            language: self.language.clone(),
3231            parse_count: self.parse_count,
3232        }
3233    }
3234}
3235
3236impl Deref for BufferSnapshot {
3237    type Target = text::BufferSnapshot;
3238
3239    fn deref(&self) -> &Self::Target {
3240        &self.text
3241    }
3242}
3243
3244unsafe impl<'a> Send for BufferChunks<'a> {}
3245
3246impl<'a> BufferChunks<'a> {
3247    pub(crate) fn new(
3248        text: &'a Rope,
3249        range: Range<usize>,
3250        syntax: Option<(SyntaxMapCaptures<'a>, Vec<HighlightMap>)>,
3251        diagnostic_endpoints: Vec<DiagnosticEndpoint>,
3252    ) -> Self {
3253        let mut highlights = None;
3254        if let Some((captures, highlight_maps)) = syntax {
3255            highlights = Some(BufferChunkHighlights {
3256                captures,
3257                next_capture: None,
3258                stack: Default::default(),
3259                highlight_maps,
3260            })
3261        }
3262
3263        let diagnostic_endpoints = diagnostic_endpoints.into_iter().peekable();
3264        let chunks = text.chunks_in_range(range.clone());
3265
3266        BufferChunks {
3267            range,
3268            chunks,
3269            diagnostic_endpoints,
3270            error_depth: 0,
3271            warning_depth: 0,
3272            information_depth: 0,
3273            hint_depth: 0,
3274            unnecessary_depth: 0,
3275            highlights,
3276        }
3277    }
3278
3279    /// Seeks to the given byte offset in the buffer.
3280    pub fn seek(&mut self, offset: usize) {
3281        self.range.start = offset;
3282        self.chunks.seek(self.range.start);
3283        if let Some(highlights) = self.highlights.as_mut() {
3284            highlights
3285                .stack
3286                .retain(|(end_offset, _)| *end_offset > offset);
3287            if let Some(capture) = &highlights.next_capture {
3288                if offset >= capture.node.start_byte() {
3289                    let next_capture_end = capture.node.end_byte();
3290                    if offset < next_capture_end {
3291                        highlights.stack.push((
3292                            next_capture_end,
3293                            highlights.highlight_maps[capture.grammar_index].get(capture.index),
3294                        ));
3295                    }
3296                    highlights.next_capture.take();
3297                }
3298            }
3299            highlights.captures.set_byte_range(self.range.clone());
3300        }
3301    }
3302
3303    /// The current byte offset in the buffer.
3304    pub fn offset(&self) -> usize {
3305        self.range.start
3306    }
3307
3308    fn update_diagnostic_depths(&mut self, endpoint: DiagnosticEndpoint) {
3309        let depth = match endpoint.severity {
3310            DiagnosticSeverity::ERROR => &mut self.error_depth,
3311            DiagnosticSeverity::WARNING => &mut self.warning_depth,
3312            DiagnosticSeverity::INFORMATION => &mut self.information_depth,
3313            DiagnosticSeverity::HINT => &mut self.hint_depth,
3314            _ => return,
3315        };
3316        if endpoint.is_start {
3317            *depth += 1;
3318        } else {
3319            *depth -= 1;
3320        }
3321
3322        if endpoint.is_unnecessary {
3323            if endpoint.is_start {
3324                self.unnecessary_depth += 1;
3325            } else {
3326                self.unnecessary_depth -= 1;
3327            }
3328        }
3329    }
3330
3331    fn current_diagnostic_severity(&self) -> Option<DiagnosticSeverity> {
3332        if self.error_depth > 0 {
3333            Some(DiagnosticSeverity::ERROR)
3334        } else if self.warning_depth > 0 {
3335            Some(DiagnosticSeverity::WARNING)
3336        } else if self.information_depth > 0 {
3337            Some(DiagnosticSeverity::INFORMATION)
3338        } else if self.hint_depth > 0 {
3339            Some(DiagnosticSeverity::HINT)
3340        } else {
3341            None
3342        }
3343    }
3344
3345    fn current_code_is_unnecessary(&self) -> bool {
3346        self.unnecessary_depth > 0
3347    }
3348}
3349
3350impl<'a> Iterator for BufferChunks<'a> {
3351    type Item = Chunk<'a>;
3352
3353    fn next(&mut self) -> Option<Self::Item> {
3354        let mut next_capture_start = usize::MAX;
3355        let mut next_diagnostic_endpoint = usize::MAX;
3356
3357        if let Some(highlights) = self.highlights.as_mut() {
3358            while let Some((parent_capture_end, _)) = highlights.stack.last() {
3359                if *parent_capture_end <= self.range.start {
3360                    highlights.stack.pop();
3361                } else {
3362                    break;
3363                }
3364            }
3365
3366            if highlights.next_capture.is_none() {
3367                highlights.next_capture = highlights.captures.next();
3368            }
3369
3370            while let Some(capture) = highlights.next_capture.as_ref() {
3371                if self.range.start < capture.node.start_byte() {
3372                    next_capture_start = capture.node.start_byte();
3373                    break;
3374                } else {
3375                    let highlight_id =
3376                        highlights.highlight_maps[capture.grammar_index].get(capture.index);
3377                    highlights
3378                        .stack
3379                        .push((capture.node.end_byte(), highlight_id));
3380                    highlights.next_capture = highlights.captures.next();
3381                }
3382            }
3383        }
3384
3385        while let Some(endpoint) = self.diagnostic_endpoints.peek().copied() {
3386            if endpoint.offset <= self.range.start {
3387                self.update_diagnostic_depths(endpoint);
3388                self.diagnostic_endpoints.next();
3389            } else {
3390                next_diagnostic_endpoint = endpoint.offset;
3391                break;
3392            }
3393        }
3394
3395        if let Some(chunk) = self.chunks.peek() {
3396            let chunk_start = self.range.start;
3397            let mut chunk_end = (self.chunks.offset() + chunk.len())
3398                .min(next_capture_start)
3399                .min(next_diagnostic_endpoint);
3400            let mut highlight_id = None;
3401            if let Some(highlights) = self.highlights.as_ref() {
3402                if let Some((parent_capture_end, parent_highlight_id)) = highlights.stack.last() {
3403                    chunk_end = chunk_end.min(*parent_capture_end);
3404                    highlight_id = Some(*parent_highlight_id);
3405                }
3406            }
3407
3408            let slice =
3409                &chunk[chunk_start - self.chunks.offset()..chunk_end - self.chunks.offset()];
3410            self.range.start = chunk_end;
3411            if self.range.start == self.chunks.offset() + chunk.len() {
3412                self.chunks.next().unwrap();
3413            }
3414
3415            Some(Chunk {
3416                text: slice,
3417                syntax_highlight_id: highlight_id,
3418                diagnostic_severity: self.current_diagnostic_severity(),
3419                is_unnecessary: self.current_code_is_unnecessary(),
3420                ..Default::default()
3421            })
3422        } else {
3423            None
3424        }
3425    }
3426}
3427
3428impl operation_queue::Operation for Operation {
3429    fn lamport_timestamp(&self) -> clock::Lamport {
3430        match self {
3431            Operation::Buffer(_) => {
3432                unreachable!("buffer operations should never be deferred at this layer")
3433            }
3434            Operation::UpdateDiagnostics {
3435                lamport_timestamp, ..
3436            }
3437            | Operation::UpdateSelections {
3438                lamport_timestamp, ..
3439            }
3440            | Operation::UpdateCompletionTriggers {
3441                lamport_timestamp, ..
3442            } => *lamport_timestamp,
3443        }
3444    }
3445}
3446
3447impl Default for Diagnostic {
3448    fn default() -> Self {
3449        Self {
3450            source: Default::default(),
3451            code: None,
3452            severity: DiagnosticSeverity::ERROR,
3453            message: Default::default(),
3454            group_id: 0,
3455            is_primary: false,
3456            is_disk_based: false,
3457            is_unnecessary: false,
3458        }
3459    }
3460}
3461
3462impl IndentSize {
3463    /// Returns an [IndentSize] representing the given spaces.
3464    pub fn spaces(len: u32) -> Self {
3465        Self {
3466            len,
3467            kind: IndentKind::Space,
3468        }
3469    }
3470
3471    /// Returns an [IndentSize] representing a tab.
3472    pub fn tab() -> Self {
3473        Self {
3474            len: 1,
3475            kind: IndentKind::Tab,
3476        }
3477    }
3478
3479    /// An iterator over the characters represented by this [IndentSize].
3480    pub fn chars(&self) -> impl Iterator<Item = char> {
3481        iter::repeat(self.char()).take(self.len as usize)
3482    }
3483
3484    /// The character representation of this [IndentSize].
3485    pub fn char(&self) -> char {
3486        match self.kind {
3487            IndentKind::Space => ' ',
3488            IndentKind::Tab => '\t',
3489        }
3490    }
3491
3492    /// Consumes the current [IndentSize] and returns a new one that has
3493    /// been shrunk or enlarged by the given size along the given direction.
3494    pub fn with_delta(mut self, direction: Ordering, size: IndentSize) -> Self {
3495        match direction {
3496            Ordering::Less => {
3497                if self.kind == size.kind && self.len >= size.len {
3498                    self.len -= size.len;
3499                }
3500            }
3501            Ordering::Equal => {}
3502            Ordering::Greater => {
3503                if self.len == 0 {
3504                    self = size;
3505                } else if self.kind == size.kind {
3506                    self.len += size.len;
3507                }
3508            }
3509        }
3510        self
3511    }
3512}
3513
3514impl Completion {
3515    /// A key that can be used to sort completions when displaying
3516    /// them to the user.
3517    pub fn sort_key(&self) -> (usize, &str) {
3518        let kind_key = match self.lsp_completion.kind {
3519            Some(lsp::CompletionItemKind::KEYWORD) => 0,
3520            Some(lsp::CompletionItemKind::VARIABLE) => 1,
3521            _ => 2,
3522        };
3523        (kind_key, &self.label.text[self.label.filter_range.clone()])
3524    }
3525
3526    /// Whether this completion is a snippet.
3527    pub fn is_snippet(&self) -> bool {
3528        self.lsp_completion.insert_text_format == Some(lsp::InsertTextFormat::SNIPPET)
3529    }
3530}
3531
3532#[cfg(any(test, feature = "test-support"))]
3533pub struct TestFile {
3534    pub path: Arc<Path>,
3535    pub root_name: String,
3536}
3537
3538#[cfg(any(test, feature = "test-support"))]
3539impl File for TestFile {
3540    fn path(&self) -> &Arc<Path> {
3541        &self.path
3542    }
3543
3544    fn full_path(&self, _: &gpui::AppContext) -> PathBuf {
3545        PathBuf::from(&self.root_name).join(self.path.as_ref())
3546    }
3547
3548    fn as_local(&self) -> Option<&dyn LocalFile> {
3549        None
3550    }
3551
3552    fn mtime(&self) -> Option<SystemTime> {
3553        unimplemented!()
3554    }
3555
3556    fn file_name<'a>(&'a self, _: &'a gpui::AppContext) -> &'a std::ffi::OsStr {
3557        self.path().file_name().unwrap_or(self.root_name.as_ref())
3558    }
3559
3560    fn worktree_id(&self) -> usize {
3561        0
3562    }
3563
3564    fn is_deleted(&self) -> bool {
3565        unimplemented!()
3566    }
3567
3568    fn as_any(&self) -> &dyn std::any::Any {
3569        unimplemented!()
3570    }
3571
3572    fn to_proto(&self) -> rpc::proto::File {
3573        unimplemented!()
3574    }
3575
3576    fn is_private(&self) -> bool {
3577        false
3578    }
3579}
3580
3581pub(crate) fn contiguous_ranges(
3582    values: impl Iterator<Item = u32>,
3583    max_len: usize,
3584) -> impl Iterator<Item = Range<u32>> {
3585    let mut values = values;
3586    let mut current_range: Option<Range<u32>> = None;
3587    std::iter::from_fn(move || loop {
3588        if let Some(value) = values.next() {
3589            if let Some(range) = &mut current_range {
3590                if value == range.end && range.len() < max_len {
3591                    range.end += 1;
3592                    continue;
3593                }
3594            }
3595
3596            let prev_range = current_range.clone();
3597            current_range = Some(value..(value + 1));
3598            if prev_range.is_some() {
3599                return prev_range;
3600            }
3601        } else {
3602            return current_range.take();
3603        }
3604    })
3605}
3606
3607/// Returns the [CharKind] for the given character. When a scope is provided,
3608/// the function checks if the character is considered a word character
3609/// based on the language scope's word character settings.
3610pub fn char_kind(scope: &Option<LanguageScope>, c: char) -> CharKind {
3611    if c.is_whitespace() {
3612        return CharKind::Whitespace;
3613    } else if c.is_alphanumeric() || c == '_' {
3614        return CharKind::Word;
3615    }
3616
3617    if let Some(scope) = scope {
3618        if let Some(characters) = scope.word_characters() {
3619            if characters.contains(&c) {
3620                return CharKind::Word;
3621            }
3622        }
3623    }
3624
3625    CharKind::Punctuation
3626}
3627
3628/// Find all of the ranges of whitespace that occur at the ends of lines
3629/// in the given rope.
3630///
3631/// This could also be done with a regex search, but this implementation
3632/// avoids copying text.
3633pub fn trailing_whitespace_ranges(rope: &Rope) -> Vec<Range<usize>> {
3634    let mut ranges = Vec::new();
3635
3636    let mut offset = 0;
3637    let mut prev_chunk_trailing_whitespace_range = 0..0;
3638    for chunk in rope.chunks() {
3639        let mut prev_line_trailing_whitespace_range = 0..0;
3640        for (i, line) in chunk.split('\n').enumerate() {
3641            let line_end_offset = offset + line.len();
3642            let trimmed_line_len = line.trim_end_matches(|c| matches!(c, ' ' | '\t')).len();
3643            let mut trailing_whitespace_range = (offset + trimmed_line_len)..line_end_offset;
3644
3645            if i == 0 && trimmed_line_len == 0 {
3646                trailing_whitespace_range.start = prev_chunk_trailing_whitespace_range.start;
3647            }
3648            if !prev_line_trailing_whitespace_range.is_empty() {
3649                ranges.push(prev_line_trailing_whitespace_range);
3650            }
3651
3652            offset = line_end_offset + 1;
3653            prev_line_trailing_whitespace_range = trailing_whitespace_range;
3654        }
3655
3656        offset -= 1;
3657        prev_chunk_trailing_whitespace_range = prev_line_trailing_whitespace_range;
3658    }
3659
3660    if !prev_chunk_trailing_whitespace_range.is_empty() {
3661        ranges.push(prev_chunk_trailing_whitespace_range);
3662    }
3663
3664    ranges
3665}