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