buffer.rs

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