buffer.rs

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