buffer.rs

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