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