buffer.rs

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