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