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