buffer.rs

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