buffer.rs

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