buffer.rs

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