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