buffer.rs

   1pub use crate::{
   2    diagnostic_set::DiagnosticSet,
   3    highlight_map::{HighlightId, HighlightMap},
   4    proto, BracketPair, Grammar, Language, LanguageConfig, LanguageRegistry, PLAIN_TEXT,
   5};
   6use crate::{
   7    diagnostic_set::{DiagnosticEntry, DiagnosticGroup},
   8    outline::OutlineItem,
   9    CodeLabel, Outline,
  10};
  11use anyhow::{anyhow, Result};
  12use clock::ReplicaId;
  13use futures::FutureExt as _;
  14use gpui::{fonts::HighlightStyle, AppContext, Entity, ModelContext, MutableAppContext, Task};
  15use lazy_static::lazy_static;
  16use parking_lot::Mutex;
  17use settings::Settings;
  18use similar::{ChangeTag, TextDiff};
  19use smol::future::yield_now;
  20use std::{
  21    any::Any,
  22    cmp::{self, Ordering},
  23    collections::BTreeMap,
  24    ffi::OsStr,
  25    future::Future,
  26    iter::{self, Iterator, Peekable},
  27    mem,
  28    ops::{Deref, DerefMut, Range},
  29    path::{Path, PathBuf},
  30    str,
  31    sync::Arc,
  32    time::{Duration, Instant, SystemTime, UNIX_EPOCH},
  33    vec,
  34};
  35use sum_tree::TreeMap;
  36use text::operation_queue::OperationQueue;
  37pub use text::{Buffer as TextBuffer, BufferSnapshot as TextBufferSnapshot, Operation as _, *};
  38use theme::SyntaxTheme;
  39use tree_sitter::{InputEdit, QueryCursor, Tree};
  40use util::TryFutureExt as _;
  41
  42#[cfg(any(test, feature = "test-support"))]
  43pub use {tree_sitter_rust, tree_sitter_typescript};
  44
  45pub use lsp::DiagnosticSeverity;
  46
  47lazy_static! {
  48    static ref QUERY_CURSORS: Mutex<Vec<QueryCursor>> = Default::default();
  49}
  50
  51pub struct Buffer {
  52    text: TextBuffer,
  53    file: Option<Arc<dyn File>>,
  54    saved_version: clock::Global,
  55    saved_version_fingerprint: String,
  56    saved_mtime: SystemTime,
  57    transaction_depth: usize,
  58    was_dirty_before_starting_transaction: Option<bool>,
  59    language: Option<Arc<Language>>,
  60    autoindent_requests: Vec<Arc<AutoindentRequest>>,
  61    pending_autoindent: Option<Task<()>>,
  62    sync_parse_timeout: Duration,
  63    syntax_tree: Mutex<Option<SyntaxTree>>,
  64    parsing_in_background: bool,
  65    parse_count: usize,
  66    diagnostics: DiagnosticSet,
  67    remote_selections: TreeMap<ReplicaId, SelectionSet>,
  68    selections_update_count: usize,
  69    diagnostics_update_count: usize,
  70    diagnostics_timestamp: clock::Lamport,
  71    file_update_count: usize,
  72    completion_triggers: Vec<String>,
  73    deferred_ops: OperationQueue<Operation>,
  74}
  75
  76pub struct BufferSnapshot {
  77    text: text::BufferSnapshot,
  78    tree: Option<Tree>,
  79    file: Option<Arc<dyn File>>,
  80    diagnostics: DiagnosticSet,
  81    diagnostics_update_count: usize,
  82    file_update_count: usize,
  83    remote_selections: TreeMap<ReplicaId, SelectionSet>,
  84    selections_update_count: usize,
  85    language: Option<Arc<Language>>,
  86    parse_count: usize,
  87}
  88
  89#[derive(Clone, Copy, Debug, PartialEq, Eq)]
  90pub struct IndentSize {
  91    pub len: u32,
  92    pub kind: IndentKind,
  93}
  94
  95#[derive(Clone, Copy, Debug, PartialEq, Eq)]
  96pub enum IndentKind {
  97    Space,
  98    Tab,
  99}
 100
 101#[derive(Clone, Debug)]
 102struct SelectionSet {
 103    line_mode: bool,
 104    selections: Arc<[Selection<Anchor>]>,
 105    lamport_timestamp: clock::Lamport,
 106}
 107
 108#[derive(Clone, Debug, PartialEq, Eq)]
 109pub struct GroupId {
 110    source: Arc<str>,
 111    id: usize,
 112}
 113
 114#[derive(Clone, Debug, PartialEq, Eq)]
 115pub struct Diagnostic {
 116    pub code: Option<String>,
 117    pub severity: DiagnosticSeverity,
 118    pub message: String,
 119    pub group_id: usize,
 120    pub is_valid: bool,
 121    pub is_primary: bool,
 122    pub is_disk_based: bool,
 123    pub is_unnecessary: bool,
 124}
 125
 126#[derive(Clone, Debug)]
 127pub struct Completion {
 128    pub old_range: Range<Anchor>,
 129    pub new_text: String,
 130    pub label: CodeLabel,
 131    pub lsp_completion: lsp::CompletionItem,
 132}
 133
 134#[derive(Clone, Debug)]
 135pub struct CodeAction {
 136    pub range: Range<Anchor>,
 137    pub lsp_action: lsp::CodeAction,
 138}
 139
 140#[derive(Clone, Debug, PartialEq, Eq)]
 141pub enum Operation {
 142    Buffer(text::Operation),
 143    UpdateDiagnostics {
 144        diagnostics: Arc<[DiagnosticEntry<Anchor>]>,
 145        lamport_timestamp: clock::Lamport,
 146    },
 147    UpdateSelections {
 148        selections: Arc<[Selection<Anchor>]>,
 149        lamport_timestamp: clock::Lamport,
 150        line_mode: bool,
 151    },
 152    UpdateCompletionTriggers {
 153        triggers: Vec<String>,
 154        lamport_timestamp: clock::Lamport,
 155    },
 156}
 157
 158#[derive(Clone, Debug, PartialEq, Eq)]
 159pub enum Event {
 160    Operation(Operation),
 161    Edited,
 162    DirtyChanged,
 163    Saved,
 164    FileHandleChanged,
 165    Reloaded,
 166    Reparsed,
 167    DiagnosticsUpdated,
 168    Closed,
 169}
 170
 171pub trait File: Send + Sync {
 172    fn as_local(&self) -> Option<&dyn LocalFile>;
 173
 174    fn is_local(&self) -> bool {
 175        self.as_local().is_some()
 176    }
 177
 178    fn mtime(&self) -> SystemTime;
 179
 180    /// Returns the path of this file relative to the worktree's root directory.
 181    fn path(&self) -> &Arc<Path>;
 182
 183    /// Returns the path of this file relative to the worktree's parent directory (this means it
 184    /// includes the name of the worktree's root folder).
 185    fn full_path(&self, cx: &AppContext) -> PathBuf;
 186
 187    /// Returns the last component of this handle's absolute path. If this handle refers to the root
 188    /// of its worktree, then this method will return the name of the worktree itself.
 189    fn file_name<'a>(&'a self, cx: &'a AppContext) -> &'a OsStr;
 190
 191    fn is_deleted(&self) -> bool;
 192
 193    fn save(
 194        &self,
 195        buffer_id: u64,
 196        text: Rope,
 197        version: clock::Global,
 198        line_ending: LineEnding,
 199        cx: &mut MutableAppContext,
 200    ) -> Task<Result<(clock::Global, String, SystemTime)>>;
 201
 202    fn as_any(&self) -> &dyn Any;
 203
 204    fn to_proto(&self) -> rpc::proto::File;
 205}
 206
 207pub trait LocalFile: File {
 208    /// Returns the absolute path of this file.
 209    fn abs_path(&self, cx: &AppContext) -> PathBuf;
 210
 211    fn load(&self, cx: &AppContext) -> Task<Result<String>>;
 212
 213    fn buffer_reloaded(
 214        &self,
 215        buffer_id: u64,
 216        version: &clock::Global,
 217        fingerprint: String,
 218        line_ending: LineEnding,
 219        mtime: SystemTime,
 220        cx: &mut MutableAppContext,
 221    );
 222}
 223
 224pub(crate) struct QueryCursorHandle(Option<QueryCursor>);
 225
 226#[derive(Clone)]
 227struct SyntaxTree {
 228    tree: Tree,
 229    version: clock::Global,
 230}
 231
 232#[derive(Clone, Debug)]
 233pub enum AutoindentMode {
 234    /// Indent each line of inserted text.
 235    EachLine,
 236    /// Apply the same indentation adjustment to all of the lines
 237    /// in a given insertion.
 238    Block {
 239        /// The original indentation level of the first line of each
 240        /// insertion, if it has been copied.
 241        original_indent_columns: Vec<u32>,
 242    },
 243}
 244
 245#[derive(Clone)]
 246struct AutoindentRequest {
 247    before_edit: BufferSnapshot,
 248    entries: Vec<AutoindentRequestEntry>,
 249    indent_size: IndentSize,
 250    is_block_mode: bool,
 251}
 252
 253#[derive(Clone)]
 254struct AutoindentRequestEntry {
 255    /// A range of the buffer whose indentation should be adjusted.
 256    range: Range<Anchor>,
 257    /// Whether or not these lines should be considered brand new, for the
 258    /// purpose of auto-indent. When text is not new, its indentation will
 259    /// only be adjusted if the suggested indentation level has *changed*
 260    /// since the edit was made.
 261    first_line_is_new: bool,
 262    original_indent_column: Option<u32>,
 263}
 264
 265#[derive(Debug)]
 266struct IndentSuggestion {
 267    basis_row: u32,
 268    delta: Ordering,
 269}
 270
 271pub(crate) struct TextProvider<'a>(pub(crate) &'a Rope);
 272
 273struct BufferChunkHighlights<'a> {
 274    captures: tree_sitter::QueryCaptures<'a, 'a, TextProvider<'a>>,
 275    next_capture: Option<(tree_sitter::QueryMatch<'a, 'a>, usize)>,
 276    stack: Vec<(usize, HighlightId)>,
 277    highlight_map: HighlightMap,
 278    _query_cursor: QueryCursorHandle,
 279}
 280
 281pub struct BufferChunks<'a> {
 282    range: Range<usize>,
 283    chunks: rope::Chunks<'a>,
 284    diagnostic_endpoints: Peekable<vec::IntoIter<DiagnosticEndpoint>>,
 285    error_depth: usize,
 286    warning_depth: usize,
 287    information_depth: usize,
 288    hint_depth: usize,
 289    unnecessary_depth: usize,
 290    highlights: Option<BufferChunkHighlights<'a>>,
 291}
 292
 293#[derive(Clone, Copy, Debug, Default)]
 294pub struct Chunk<'a> {
 295    pub text: &'a str,
 296    pub syntax_highlight_id: Option<HighlightId>,
 297    pub highlight_style: Option<HighlightStyle>,
 298    pub diagnostic_severity: Option<DiagnosticSeverity>,
 299    pub is_unnecessary: bool,
 300}
 301
 302pub struct Diff {
 303    base_version: clock::Global,
 304    new_text: Arc<str>,
 305    changes: Vec<(ChangeTag, usize)>,
 306    line_ending: LineEnding,
 307    start_offset: usize,
 308}
 309
 310#[derive(Clone, Copy)]
 311pub(crate) struct DiagnosticEndpoint {
 312    offset: usize,
 313    is_start: bool,
 314    severity: DiagnosticSeverity,
 315    is_unnecessary: bool,
 316}
 317
 318#[derive(Copy, Clone, Eq, PartialEq, PartialOrd, Ord, Debug)]
 319pub enum CharKind {
 320    Punctuation,
 321    Whitespace,
 322    Word,
 323}
 324
 325impl CharKind {
 326    pub fn coerce_punctuation(self, treat_punctuation_as_word: bool) -> Self {
 327        if treat_punctuation_as_word && self == CharKind::Punctuation {
 328            CharKind::Word
 329        } else {
 330            self
 331        }
 332    }
 333}
 334
 335impl Buffer {
 336    pub fn new<T: Into<String>>(
 337        replica_id: ReplicaId,
 338        base_text: T,
 339        cx: &mut ModelContext<Self>,
 340    ) -> Self {
 341        Self::build(
 342            TextBuffer::new(replica_id, cx.model_id() as u64, base_text.into()),
 343            None,
 344        )
 345    }
 346
 347    pub fn from_file<T: Into<String>>(
 348        replica_id: ReplicaId,
 349        base_text: T,
 350        file: Arc<dyn File>,
 351        cx: &mut ModelContext<Self>,
 352    ) -> Self {
 353        Self::build(
 354            TextBuffer::new(replica_id, cx.model_id() as u64, base_text.into()),
 355            Some(file),
 356        )
 357    }
 358
 359    pub fn from_proto(
 360        replica_id: ReplicaId,
 361        message: proto::BufferState,
 362        file: Option<Arc<dyn File>>,
 363        cx: &mut ModelContext<Self>,
 364    ) -> Result<Self> {
 365        let buffer = TextBuffer::new(replica_id, message.id, message.base_text);
 366        let mut this = Self::build(buffer, file);
 367        this.text.set_line_ending(proto::deserialize_line_ending(
 368            proto::LineEnding::from_i32(message.line_ending)
 369                .ok_or_else(|| anyhow!("missing line_ending"))?,
 370        ));
 371        let ops = message
 372            .operations
 373            .into_iter()
 374            .map(proto::deserialize_operation)
 375            .collect::<Result<Vec<_>>>()?;
 376        this.apply_ops(ops, cx)?;
 377
 378        for selection_set in message.selections {
 379            let lamport_timestamp = clock::Lamport {
 380                replica_id: selection_set.replica_id as ReplicaId,
 381                value: selection_set.lamport_timestamp,
 382            };
 383            this.remote_selections.insert(
 384                selection_set.replica_id as ReplicaId,
 385                SelectionSet {
 386                    line_mode: selection_set.line_mode,
 387                    selections: proto::deserialize_selections(selection_set.selections),
 388                    lamport_timestamp,
 389                },
 390            );
 391            this.text.lamport_clock.observe(lamport_timestamp);
 392        }
 393        let snapshot = this.snapshot();
 394        let entries = proto::deserialize_diagnostics(message.diagnostics);
 395        this.apply_diagnostic_update(
 396            DiagnosticSet::from_sorted_entries(entries.iter().cloned(), &snapshot),
 397            clock::Lamport {
 398                replica_id: 0,
 399                value: message.diagnostics_timestamp,
 400            },
 401            cx,
 402        );
 403
 404        this.completion_triggers = message.completion_triggers;
 405
 406        Ok(this)
 407    }
 408
 409    pub fn to_proto(&self) -> proto::BufferState {
 410        let mut operations = self
 411            .text
 412            .history()
 413            .map(|op| proto::serialize_operation(&Operation::Buffer(op.clone())))
 414            .chain(self.deferred_ops.iter().map(proto::serialize_operation))
 415            .collect::<Vec<_>>();
 416        operations.sort_unstable_by_key(proto::lamport_timestamp_for_operation);
 417        proto::BufferState {
 418            id: self.remote_id(),
 419            file: self.file.as_ref().map(|f| f.to_proto()),
 420            base_text: self.base_text().to_string(),
 421            operations,
 422            selections: self
 423                .remote_selections
 424                .iter()
 425                .map(|(replica_id, set)| proto::SelectionSet {
 426                    replica_id: *replica_id as u32,
 427                    selections: proto::serialize_selections(&set.selections),
 428                    lamport_timestamp: set.lamport_timestamp.value,
 429                    line_mode: set.line_mode,
 430                })
 431                .collect(),
 432            diagnostics: proto::serialize_diagnostics(self.diagnostics.iter()),
 433            diagnostics_timestamp: self.diagnostics_timestamp.value,
 434            completion_triggers: self.completion_triggers.clone(),
 435            line_ending: proto::serialize_line_ending(self.line_ending()) as i32,
 436        }
 437    }
 438
 439    pub fn with_language(mut self, language: Arc<Language>, cx: &mut ModelContext<Self>) -> Self {
 440        self.set_language(Some(language), cx);
 441        self
 442    }
 443
 444    fn build(buffer: TextBuffer, file: Option<Arc<dyn File>>) -> Self {
 445        let saved_mtime = if let Some(file) = file.as_ref() {
 446            file.mtime()
 447        } else {
 448            UNIX_EPOCH
 449        };
 450
 451        Self {
 452            saved_mtime,
 453            saved_version: buffer.version(),
 454            saved_version_fingerprint: buffer.as_rope().fingerprint(),
 455            transaction_depth: 0,
 456            was_dirty_before_starting_transaction: None,
 457            text: buffer,
 458            file,
 459            syntax_tree: Mutex::new(None),
 460            parsing_in_background: false,
 461            parse_count: 0,
 462            sync_parse_timeout: Duration::from_millis(1),
 463            autoindent_requests: Default::default(),
 464            pending_autoindent: Default::default(),
 465            language: None,
 466            remote_selections: Default::default(),
 467            selections_update_count: 0,
 468            diagnostics: Default::default(),
 469            diagnostics_update_count: 0,
 470            diagnostics_timestamp: Default::default(),
 471            file_update_count: 0,
 472            completion_triggers: Default::default(),
 473            deferred_ops: OperationQueue::new(),
 474        }
 475    }
 476
 477    pub fn snapshot(&self) -> BufferSnapshot {
 478        BufferSnapshot {
 479            text: self.text.snapshot(),
 480            tree: self.syntax_tree(),
 481            file: self.file.clone(),
 482            remote_selections: self.remote_selections.clone(),
 483            diagnostics: self.diagnostics.clone(),
 484            diagnostics_update_count: self.diagnostics_update_count,
 485            file_update_count: self.file_update_count,
 486            language: self.language.clone(),
 487            parse_count: self.parse_count,
 488            selections_update_count: self.selections_update_count,
 489        }
 490    }
 491
 492    pub fn as_text_snapshot(&self) -> &text::BufferSnapshot {
 493        &self.text
 494    }
 495
 496    pub fn text_snapshot(&self) -> text::BufferSnapshot {
 497        self.text.snapshot()
 498    }
 499
 500    pub fn file(&self) -> Option<&dyn File> {
 501        self.file.as_deref()
 502    }
 503
 504    pub fn save(
 505        &mut self,
 506        cx: &mut ModelContext<Self>,
 507    ) -> Task<Result<(clock::Global, String, SystemTime)>> {
 508        let file = if let Some(file) = self.file.as_ref() {
 509            file
 510        } else {
 511            return Task::ready(Err(anyhow!("buffer has no file")));
 512        };
 513        let text = self.as_rope().clone();
 514        let version = self.version();
 515        let save = file.save(
 516            self.remote_id(),
 517            text,
 518            version,
 519            self.line_ending(),
 520            cx.as_mut(),
 521        );
 522        cx.spawn(|this, mut cx| async move {
 523            let (version, fingerprint, mtime) = save.await?;
 524            this.update(&mut cx, |this, cx| {
 525                this.did_save(version.clone(), fingerprint.clone(), mtime, None, cx);
 526            });
 527            Ok((version, fingerprint, mtime))
 528        })
 529    }
 530
 531    pub fn saved_version(&self) -> &clock::Global {
 532        &self.saved_version
 533    }
 534
 535    pub fn set_language(&mut self, language: Option<Arc<Language>>, cx: &mut ModelContext<Self>) {
 536        *self.syntax_tree.lock() = None;
 537        self.language = language;
 538        self.reparse(cx);
 539    }
 540
 541    pub fn did_save(
 542        &mut self,
 543        version: clock::Global,
 544        fingerprint: String,
 545        mtime: SystemTime,
 546        new_file: Option<Arc<dyn File>>,
 547        cx: &mut ModelContext<Self>,
 548    ) {
 549        self.saved_version = version;
 550        self.saved_version_fingerprint = fingerprint;
 551        self.saved_mtime = mtime;
 552        if let Some(new_file) = new_file {
 553            self.file = Some(new_file);
 554            self.file_update_count += 1;
 555        }
 556        cx.emit(Event::Saved);
 557        cx.notify();
 558    }
 559
 560    pub fn reload(&mut self, cx: &mut ModelContext<Self>) -> Task<Result<Option<Transaction>>> {
 561        cx.spawn(|this, mut cx| async move {
 562            if let Some((new_mtime, new_text)) = this.read_with(&cx, |this, cx| {
 563                let file = this.file.as_ref()?.as_local()?;
 564                Some((file.mtime(), file.load(cx)))
 565            }) {
 566                let new_text = new_text.await?;
 567                let diff = this
 568                    .read_with(&cx, |this, cx| this.diff(new_text, cx))
 569                    .await;
 570                this.update(&mut cx, |this, cx| {
 571                    if let Some(transaction) = this.apply_diff(diff, cx).cloned() {
 572                        this.did_reload(
 573                            this.version(),
 574                            this.as_rope().fingerprint(),
 575                            this.line_ending(),
 576                            new_mtime,
 577                            cx,
 578                        );
 579                        Ok(Some(transaction))
 580                    } else {
 581                        Ok(None)
 582                    }
 583                })
 584            } else {
 585                Ok(None)
 586            }
 587        })
 588    }
 589
 590    pub fn did_reload(
 591        &mut self,
 592        version: clock::Global,
 593        fingerprint: String,
 594        line_ending: LineEnding,
 595        mtime: SystemTime,
 596        cx: &mut ModelContext<Self>,
 597    ) {
 598        self.saved_version = version;
 599        self.saved_version_fingerprint = fingerprint;
 600        self.text.set_line_ending(line_ending);
 601        self.saved_mtime = mtime;
 602        if let Some(file) = self.file.as_ref().and_then(|f| f.as_local()) {
 603            file.buffer_reloaded(
 604                self.remote_id(),
 605                &self.saved_version,
 606                self.saved_version_fingerprint.clone(),
 607                self.line_ending(),
 608                self.saved_mtime,
 609                cx,
 610            );
 611        }
 612        cx.emit(Event::Reloaded);
 613        cx.notify();
 614    }
 615
 616    pub fn file_updated(
 617        &mut self,
 618        new_file: Arc<dyn File>,
 619        cx: &mut ModelContext<Self>,
 620    ) -> Task<()> {
 621        let old_file = if let Some(file) = self.file.as_ref() {
 622            file
 623        } else {
 624            return Task::ready(());
 625        };
 626        let mut file_changed = false;
 627        let mut task = Task::ready(());
 628
 629        if new_file.path() != old_file.path() {
 630            file_changed = true;
 631        }
 632
 633        if new_file.is_deleted() {
 634            if !old_file.is_deleted() {
 635                file_changed = true;
 636                if !self.is_dirty() {
 637                    cx.emit(Event::DirtyChanged);
 638                }
 639            }
 640        } else {
 641            let new_mtime = new_file.mtime();
 642            if new_mtime != old_file.mtime() {
 643                file_changed = true;
 644
 645                if !self.is_dirty() {
 646                    let reload = self.reload(cx).log_err().map(drop);
 647                    task = cx.foreground().spawn(reload);
 648                }
 649            }
 650        }
 651
 652        if file_changed {
 653            self.file_update_count += 1;
 654            cx.emit(Event::FileHandleChanged);
 655            cx.notify();
 656        }
 657        self.file = Some(new_file);
 658        task
 659    }
 660
 661    pub fn close(&mut self, cx: &mut ModelContext<Self>) {
 662        cx.emit(Event::Closed);
 663    }
 664
 665    pub fn language(&self) -> Option<&Arc<Language>> {
 666        self.language.as_ref()
 667    }
 668
 669    pub fn parse_count(&self) -> usize {
 670        self.parse_count
 671    }
 672
 673    pub fn selections_update_count(&self) -> usize {
 674        self.selections_update_count
 675    }
 676
 677    pub fn diagnostics_update_count(&self) -> usize {
 678        self.diagnostics_update_count
 679    }
 680
 681    pub fn file_update_count(&self) -> usize {
 682        self.file_update_count
 683    }
 684
 685    pub(crate) fn syntax_tree(&self) -> Option<Tree> {
 686        if let Some(syntax_tree) = self.syntax_tree.lock().as_mut() {
 687            self.interpolate_tree(syntax_tree);
 688            Some(syntax_tree.tree.clone())
 689        } else {
 690            None
 691        }
 692    }
 693
 694    #[cfg(any(test, feature = "test-support"))]
 695    pub fn is_parsing(&self) -> bool {
 696        self.parsing_in_background
 697    }
 698
 699    #[cfg(test)]
 700    pub fn set_sync_parse_timeout(&mut self, timeout: Duration) {
 701        self.sync_parse_timeout = timeout;
 702    }
 703
 704    fn reparse(&mut self, cx: &mut ModelContext<Self>) -> bool {
 705        if self.parsing_in_background {
 706            return false;
 707        }
 708
 709        if let Some(grammar) = self.grammar().cloned() {
 710            let old_tree = self.syntax_tree();
 711            let text = self.as_rope().clone();
 712            let parsed_version = self.version();
 713            let parse_task = cx.background().spawn({
 714                let grammar = grammar.clone();
 715                async move { grammar.parse_text(&text, old_tree) }
 716            });
 717
 718            match cx
 719                .background()
 720                .block_with_timeout(self.sync_parse_timeout, parse_task)
 721            {
 722                Ok(new_tree) => {
 723                    self.did_finish_parsing(new_tree, parsed_version, cx);
 724                    return true;
 725                }
 726                Err(parse_task) => {
 727                    self.parsing_in_background = true;
 728                    cx.spawn(move |this, mut cx| async move {
 729                        let new_tree = parse_task.await;
 730                        this.update(&mut cx, move |this, cx| {
 731                            let grammar_changed = this
 732                                .grammar()
 733                                .map_or(true, |curr_grammar| !Arc::ptr_eq(&grammar, curr_grammar));
 734                            let parse_again =
 735                                this.version.changed_since(&parsed_version) || grammar_changed;
 736                            this.parsing_in_background = false;
 737                            this.did_finish_parsing(new_tree, parsed_version, cx);
 738
 739                            if parse_again && this.reparse(cx) {}
 740                        });
 741                    })
 742                    .detach();
 743                }
 744            }
 745        }
 746        false
 747    }
 748
 749    fn interpolate_tree(&self, tree: &mut SyntaxTree) {
 750        for edit in self.edits_since::<(usize, Point)>(&tree.version) {
 751            let (bytes, lines) = edit.flatten();
 752            tree.tree.edit(&InputEdit {
 753                start_byte: bytes.new.start,
 754                old_end_byte: bytes.new.start + bytes.old.len(),
 755                new_end_byte: bytes.new.end,
 756                start_position: lines.new.start.to_ts_point(),
 757                old_end_position: (lines.new.start + (lines.old.end - lines.old.start))
 758                    .to_ts_point(),
 759                new_end_position: lines.new.end.to_ts_point(),
 760            });
 761        }
 762        tree.version = self.version();
 763    }
 764
 765    fn did_finish_parsing(
 766        &mut self,
 767        tree: Tree,
 768        version: clock::Global,
 769        cx: &mut ModelContext<Self>,
 770    ) {
 771        self.parse_count += 1;
 772        *self.syntax_tree.lock() = Some(SyntaxTree { tree, version });
 773        self.request_autoindent(cx);
 774        cx.emit(Event::Reparsed);
 775        cx.notify();
 776    }
 777
 778    pub fn update_diagnostics(&mut self, diagnostics: DiagnosticSet, cx: &mut ModelContext<Self>) {
 779        let lamport_timestamp = self.text.lamport_clock.tick();
 780        let op = Operation::UpdateDiagnostics {
 781            diagnostics: diagnostics.iter().cloned().collect(),
 782            lamport_timestamp,
 783        };
 784        self.apply_diagnostic_update(diagnostics, lamport_timestamp, cx);
 785        self.send_operation(op, cx);
 786    }
 787
 788    fn request_autoindent(&mut self, cx: &mut ModelContext<Self>) {
 789        if let Some(indent_sizes) = self.compute_autoindents() {
 790            let indent_sizes = cx.background().spawn(indent_sizes);
 791            match cx
 792                .background()
 793                .block_with_timeout(Duration::from_micros(500), indent_sizes)
 794            {
 795                Ok(indent_sizes) => self.apply_autoindents(indent_sizes, cx),
 796                Err(indent_sizes) => {
 797                    self.pending_autoindent = Some(cx.spawn(|this, mut cx| async move {
 798                        let indent_sizes = indent_sizes.await;
 799                        this.update(&mut cx, |this, cx| {
 800                            this.apply_autoindents(indent_sizes, cx);
 801                        });
 802                    }));
 803                }
 804            }
 805        }
 806    }
 807
 808    fn compute_autoindents(&self) -> Option<impl Future<Output = BTreeMap<u32, IndentSize>>> {
 809        let max_rows_between_yields = 100;
 810        let snapshot = self.snapshot();
 811        if snapshot.language.is_none()
 812            || snapshot.tree.is_none()
 813            || self.autoindent_requests.is_empty()
 814        {
 815            return None;
 816        }
 817
 818        let autoindent_requests = self.autoindent_requests.clone();
 819        Some(async move {
 820            let mut indent_sizes = BTreeMap::new();
 821            for request in autoindent_requests {
 822                // Resolve each edited range to its row in the current buffer and in the
 823                // buffer before this batch of edits.
 824                let mut row_ranges = Vec::new();
 825                let mut old_to_new_rows = BTreeMap::new();
 826                for entry in &request.entries {
 827                    let position = entry.range.start;
 828                    let new_row = position.to_point(&snapshot).row;
 829                    let new_end_row = entry.range.end.to_point(&snapshot).row + 1;
 830                    if !entry.first_line_is_new {
 831                        let old_row = position.to_point(&request.before_edit).row;
 832                        old_to_new_rows.insert(old_row, new_row);
 833                    }
 834                    row_ranges.push((new_row..new_end_row, entry.original_indent_column));
 835                }
 836
 837                // Build a map containing the suggested indentation for each of the edited lines
 838                // with respect to the state of the buffer before these edits. This map is keyed
 839                // by the rows for these lines in the current state of the buffer.
 840                let mut old_suggestions = BTreeMap::<u32, IndentSize>::default();
 841                let old_edited_ranges =
 842                    contiguous_ranges(old_to_new_rows.keys().copied(), max_rows_between_yields);
 843                for old_edited_range in old_edited_ranges {
 844                    let suggestions = request
 845                        .before_edit
 846                        .suggest_autoindents(old_edited_range.clone())
 847                        .into_iter()
 848                        .flatten();
 849                    for (old_row, suggestion) in old_edited_range.zip(suggestions) {
 850                        if let Some(suggestion) = suggestion {
 851                            let suggested_indent = old_to_new_rows
 852                                .get(&suggestion.basis_row)
 853                                .and_then(|from_row| old_suggestions.get(from_row).copied())
 854                                .unwrap_or_else(|| {
 855                                    request
 856                                        .before_edit
 857                                        .indent_size_for_line(suggestion.basis_row)
 858                                })
 859                                .with_delta(suggestion.delta, request.indent_size);
 860                            old_suggestions
 861                                .insert(*old_to_new_rows.get(&old_row).unwrap(), suggested_indent);
 862                        }
 863                    }
 864                    yield_now().await;
 865                }
 866
 867                // In block mode, only compute indentation suggestions for the first line
 868                // of each insertion. Otherwise, compute suggestions for every inserted line.
 869                let new_edited_row_ranges = contiguous_ranges(
 870                    row_ranges.iter().flat_map(|(range, _)| {
 871                        if request.is_block_mode {
 872                            range.start..range.start + 1
 873                        } else {
 874                            range.clone()
 875                        }
 876                    }),
 877                    max_rows_between_yields,
 878                );
 879
 880                // Compute new suggestions for each line, but only include them in the result
 881                // if they differ from the old suggestion for that line.
 882                for new_edited_row_range in new_edited_row_ranges {
 883                    let suggestions = snapshot
 884                        .suggest_autoindents(new_edited_row_range.clone())
 885                        .into_iter()
 886                        .flatten();
 887                    for (new_row, suggestion) in new_edited_row_range.zip(suggestions) {
 888                        if let Some(suggestion) = suggestion {
 889                            let suggested_indent = indent_sizes
 890                                .get(&suggestion.basis_row)
 891                                .copied()
 892                                .unwrap_or_else(|| {
 893                                    snapshot.indent_size_for_line(suggestion.basis_row)
 894                                })
 895                                .with_delta(suggestion.delta, request.indent_size);
 896                            if old_suggestions
 897                                .get(&new_row)
 898                                .map_or(true, |old_indentation| {
 899                                    suggested_indent != *old_indentation
 900                                })
 901                            {
 902                                indent_sizes.insert(new_row, suggested_indent);
 903                            }
 904                        }
 905                    }
 906                    yield_now().await;
 907                }
 908
 909                // For each block of inserted text, adjust the indentation of the remaining
 910                // lines of the block by the same amount as the first line was adjusted.
 911                if request.is_block_mode {
 912                    for (row_range, original_indent_column) in
 913                        row_ranges
 914                            .into_iter()
 915                            .filter_map(|(range, original_indent_column)| {
 916                                if range.len() > 1 {
 917                                    Some((range, original_indent_column?))
 918                                } else {
 919                                    None
 920                                }
 921                            })
 922                    {
 923                        let new_indent = indent_sizes
 924                            .get(&row_range.start)
 925                            .copied()
 926                            .unwrap_or_else(|| snapshot.indent_size_for_line(row_range.start));
 927                        let delta = new_indent.len as i64 - original_indent_column as i64;
 928                        if delta != 0 {
 929                            for row in row_range.skip(1) {
 930                                indent_sizes.entry(row).or_insert_with(|| {
 931                                    let mut size = snapshot.indent_size_for_line(row);
 932                                    if size.kind == new_indent.kind {
 933                                        match delta.cmp(&0) {
 934                                            Ordering::Greater => size.len += delta as u32,
 935                                            Ordering::Less => {
 936                                                size.len = size.len.saturating_sub(-delta as u32)
 937                                            }
 938                                            Ordering::Equal => {}
 939                                        }
 940                                    }
 941                                    size
 942                                });
 943                            }
 944                        }
 945                    }
 946                }
 947            }
 948
 949            indent_sizes
 950        })
 951    }
 952
 953    fn apply_autoindents(
 954        &mut self,
 955        indent_sizes: BTreeMap<u32, IndentSize>,
 956        cx: &mut ModelContext<Self>,
 957    ) {
 958        self.autoindent_requests.clear();
 959
 960        let edits: Vec<_> = indent_sizes
 961            .into_iter()
 962            .filter_map(|(row, indent_size)| {
 963                let current_size = indent_size_for_line(self, row);
 964                Self::edit_for_indent_size_adjustment(row, current_size, indent_size)
 965            })
 966            .collect();
 967
 968        self.edit(edits, None, cx);
 969    }
 970
 971    pub fn edit_for_indent_size_adjustment(
 972        row: u32,
 973        current_size: IndentSize,
 974        new_size: IndentSize,
 975    ) -> Option<(Range<Point>, String)> {
 976        if new_size.kind != current_size.kind && current_size.len > 0 {
 977            return None;
 978        }
 979
 980        match new_size.len.cmp(&current_size.len) {
 981            Ordering::Greater => {
 982                let point = Point::new(row, 0);
 983                Some((
 984                    point..point,
 985                    iter::repeat(new_size.char())
 986                        .take((new_size.len - current_size.len) as usize)
 987                        .collect::<String>(),
 988                ))
 989            }
 990
 991            Ordering::Less => Some((
 992                Point::new(row, 0)..Point::new(row, current_size.len - new_size.len),
 993                String::new(),
 994            )),
 995
 996            Ordering::Equal => None,
 997        }
 998    }
 999
1000    pub fn diff(&self, mut new_text: String, cx: &AppContext) -> Task<Diff> {
1001        let old_text = self.as_rope().clone();
1002        let base_version = self.version();
1003        cx.background().spawn(async move {
1004            let old_text = old_text.to_string();
1005            let line_ending = LineEnding::detect(&new_text);
1006            LineEnding::normalize(&mut new_text);
1007            let changes = TextDiff::from_chars(old_text.as_str(), new_text.as_str())
1008                .iter_all_changes()
1009                .map(|c| (c.tag(), c.value().len()))
1010                .collect::<Vec<_>>();
1011            Diff {
1012                base_version,
1013                new_text: new_text.into(),
1014                changes,
1015                line_ending,
1016                start_offset: 0,
1017            }
1018        })
1019    }
1020
1021    pub fn apply_diff(&mut self, diff: Diff, cx: &mut ModelContext<Self>) -> Option<&Transaction> {
1022        if self.version == diff.base_version {
1023            self.finalize_last_transaction();
1024            self.start_transaction();
1025            self.text.set_line_ending(diff.line_ending);
1026            let mut offset = diff.start_offset;
1027            for (tag, len) in diff.changes {
1028                let range = offset..(offset + len);
1029                match tag {
1030                    ChangeTag::Equal => offset += len,
1031                    ChangeTag::Delete => {
1032                        self.edit([(range, "")], None, cx);
1033                    }
1034                    ChangeTag::Insert => {
1035                        self.edit(
1036                            [(
1037                                offset..offset,
1038                                &diff.new_text[range.start - diff.start_offset
1039                                    ..range.end - diff.start_offset],
1040                            )],
1041                            None,
1042                            cx,
1043                        );
1044                        offset += len;
1045                    }
1046                }
1047            }
1048            if self.end_transaction(cx).is_some() {
1049                self.finalize_last_transaction()
1050            } else {
1051                None
1052            }
1053        } else {
1054            None
1055        }
1056    }
1057
1058    pub fn is_dirty(&self) -> bool {
1059        self.saved_version_fingerprint != self.as_rope().fingerprint()
1060            || self.file.as_ref().map_or(false, |file| file.is_deleted())
1061    }
1062
1063    pub fn has_conflict(&self) -> bool {
1064        self.saved_version_fingerprint != self.as_rope().fingerprint()
1065            && self
1066                .file
1067                .as_ref()
1068                .map_or(false, |file| file.mtime() > self.saved_mtime)
1069    }
1070
1071    pub fn subscribe(&mut self) -> Subscription {
1072        self.text.subscribe()
1073    }
1074
1075    pub fn start_transaction(&mut self) -> Option<TransactionId> {
1076        self.start_transaction_at(Instant::now())
1077    }
1078
1079    pub fn start_transaction_at(&mut self, now: Instant) -> Option<TransactionId> {
1080        self.transaction_depth += 1;
1081        if self.was_dirty_before_starting_transaction.is_none() {
1082            self.was_dirty_before_starting_transaction = Some(self.is_dirty());
1083        }
1084        self.text.start_transaction_at(now)
1085    }
1086
1087    pub fn end_transaction(&mut self, cx: &mut ModelContext<Self>) -> Option<TransactionId> {
1088        self.end_transaction_at(Instant::now(), cx)
1089    }
1090
1091    pub fn end_transaction_at(
1092        &mut self,
1093        now: Instant,
1094        cx: &mut ModelContext<Self>,
1095    ) -> Option<TransactionId> {
1096        assert!(self.transaction_depth > 0);
1097        self.transaction_depth -= 1;
1098        let was_dirty = if self.transaction_depth == 0 {
1099            self.was_dirty_before_starting_transaction.take().unwrap()
1100        } else {
1101            false
1102        };
1103        if let Some((transaction_id, start_version)) = self.text.end_transaction_at(now) {
1104            self.did_edit(&start_version, was_dirty, cx);
1105            Some(transaction_id)
1106        } else {
1107            None
1108        }
1109    }
1110
1111    pub fn push_transaction(&mut self, transaction: Transaction, now: Instant) {
1112        self.text.push_transaction(transaction, now);
1113    }
1114
1115    pub fn finalize_last_transaction(&mut self) -> Option<&Transaction> {
1116        self.text.finalize_last_transaction()
1117    }
1118
1119    pub fn group_until_transaction(&mut self, transaction_id: TransactionId) {
1120        self.text.group_until_transaction(transaction_id);
1121    }
1122
1123    pub fn forget_transaction(&mut self, transaction_id: TransactionId) {
1124        self.text.forget_transaction(transaction_id);
1125    }
1126
1127    pub fn wait_for_edits(
1128        &mut self,
1129        edit_ids: impl IntoIterator<Item = clock::Local>,
1130    ) -> impl Future<Output = ()> {
1131        self.text.wait_for_edits(edit_ids)
1132    }
1133
1134    pub fn wait_for_anchors<'a>(
1135        &mut self,
1136        anchors: impl IntoIterator<Item = &'a Anchor>,
1137    ) -> impl Future<Output = ()> {
1138        self.text.wait_for_anchors(anchors)
1139    }
1140
1141    pub fn wait_for_version(&mut self, version: clock::Global) -> impl Future<Output = ()> {
1142        self.text.wait_for_version(version)
1143    }
1144
1145    pub fn set_active_selections(
1146        &mut self,
1147        selections: Arc<[Selection<Anchor>]>,
1148        line_mode: bool,
1149        cx: &mut ModelContext<Self>,
1150    ) {
1151        let lamport_timestamp = self.text.lamport_clock.tick();
1152        self.remote_selections.insert(
1153            self.text.replica_id(),
1154            SelectionSet {
1155                selections: selections.clone(),
1156                lamport_timestamp,
1157                line_mode,
1158            },
1159        );
1160        self.send_operation(
1161            Operation::UpdateSelections {
1162                selections,
1163                line_mode,
1164                lamport_timestamp,
1165            },
1166            cx,
1167        );
1168    }
1169
1170    pub fn remove_active_selections(&mut self, cx: &mut ModelContext<Self>) {
1171        self.set_active_selections(Arc::from([]), false, cx);
1172    }
1173
1174    pub fn set_text<T>(&mut self, text: T, cx: &mut ModelContext<Self>) -> Option<clock::Local>
1175    where
1176        T: Into<Arc<str>>,
1177    {
1178        self.edit([(0..self.len(), text)], None, cx)
1179    }
1180
1181    pub fn edit<I, S, T>(
1182        &mut self,
1183        edits_iter: I,
1184        autoindent_mode: Option<AutoindentMode>,
1185        cx: &mut ModelContext<Self>,
1186    ) -> Option<clock::Local>
1187    where
1188        I: IntoIterator<Item = (Range<S>, T)>,
1189        S: ToOffset,
1190        T: Into<Arc<str>>,
1191    {
1192        // Skip invalid edits and coalesce contiguous ones.
1193        let mut edits: Vec<(Range<usize>, Arc<str>)> = Vec::new();
1194        for (range, new_text) in edits_iter {
1195            let mut range = range.start.to_offset(self)..range.end.to_offset(self);
1196            if range.start > range.end {
1197                mem::swap(&mut range.start, &mut range.end);
1198            }
1199            let new_text = new_text.into();
1200            if !new_text.is_empty() || !range.is_empty() {
1201                if let Some((prev_range, prev_text)) = edits.last_mut() {
1202                    if prev_range.end >= range.start {
1203                        prev_range.end = cmp::max(prev_range.end, range.end);
1204                        *prev_text = format!("{prev_text}{new_text}").into();
1205                    } else {
1206                        edits.push((range, new_text));
1207                    }
1208                } else {
1209                    edits.push((range, new_text));
1210                }
1211            }
1212        }
1213        if edits.is_empty() {
1214            return None;
1215        }
1216
1217        self.start_transaction();
1218        self.pending_autoindent.take();
1219        let autoindent_request = autoindent_mode
1220            .and_then(|mode| self.language.as_ref().map(|_| (self.snapshot(), mode)));
1221
1222        let edit_operation = self.text.edit(edits.iter().cloned());
1223        let edit_id = edit_operation.local_timestamp();
1224
1225        if let Some((before_edit, mode)) = autoindent_request {
1226            let indent_size = before_edit.single_indent_size(cx);
1227            let (start_columns, is_block_mode) = match mode {
1228                AutoindentMode::Block {
1229                    original_indent_columns: start_columns,
1230                } => (start_columns, true),
1231                AutoindentMode::EachLine => (Default::default(), false),
1232            };
1233
1234            let mut delta = 0isize;
1235            let entries = edits
1236                .into_iter()
1237                .enumerate()
1238                .zip(&edit_operation.as_edit().unwrap().new_text)
1239                .map(|((ix, (range, _)), new_text)| {
1240                    let new_text_len = new_text.len();
1241                    let old_start = range.start.to_point(&before_edit);
1242                    let new_start = (delta + range.start as isize) as usize;
1243                    delta += new_text_len as isize - (range.end as isize - range.start as isize);
1244
1245                    let mut range_of_insertion_to_indent = 0..new_text_len;
1246                    let mut first_line_is_new = false;
1247                    let mut start_column = None;
1248
1249                    // When inserting an entire line at the beginning of an existing line,
1250                    // treat the insertion as new.
1251                    if new_text.contains('\n')
1252                        && old_start.column <= before_edit.indent_size_for_line(old_start.row).len
1253                    {
1254                        first_line_is_new = true;
1255                    }
1256
1257                    // When inserting text starting with a newline, avoid auto-indenting the
1258                    // previous line.
1259                    if new_text[range_of_insertion_to_indent.clone()].starts_with('\n') {
1260                        range_of_insertion_to_indent.start += 1;
1261                        first_line_is_new = true;
1262                    }
1263
1264                    // Avoid auto-indenting after the insertion.
1265                    if is_block_mode {
1266                        start_column = start_columns.get(ix).copied();
1267                        if new_text[range_of_insertion_to_indent.clone()].ends_with('\n') {
1268                            range_of_insertion_to_indent.end -= 1;
1269                        }
1270                    }
1271
1272                    AutoindentRequestEntry {
1273                        first_line_is_new,
1274                        original_indent_column: start_column,
1275                        range: self.anchor_before(new_start + range_of_insertion_to_indent.start)
1276                            ..self.anchor_after(new_start + range_of_insertion_to_indent.end),
1277                    }
1278                })
1279                .collect();
1280
1281            self.autoindent_requests.push(Arc::new(AutoindentRequest {
1282                before_edit,
1283                entries,
1284                indent_size,
1285                is_block_mode,
1286            }));
1287        }
1288
1289        self.end_transaction(cx);
1290        self.send_operation(Operation::Buffer(edit_operation), cx);
1291        Some(edit_id)
1292    }
1293
1294    fn did_edit(
1295        &mut self,
1296        old_version: &clock::Global,
1297        was_dirty: bool,
1298        cx: &mut ModelContext<Self>,
1299    ) {
1300        if self.edits_since::<usize>(old_version).next().is_none() {
1301            return;
1302        }
1303
1304        self.reparse(cx);
1305
1306        cx.emit(Event::Edited);
1307        if was_dirty != self.is_dirty() {
1308            cx.emit(Event::DirtyChanged);
1309        }
1310        cx.notify();
1311    }
1312
1313    fn grammar(&self) -> Option<&Arc<Grammar>> {
1314        self.language.as_ref().and_then(|l| l.grammar.as_ref())
1315    }
1316
1317    pub fn apply_ops<I: IntoIterator<Item = Operation>>(
1318        &mut self,
1319        ops: I,
1320        cx: &mut ModelContext<Self>,
1321    ) -> Result<()> {
1322        self.pending_autoindent.take();
1323        let was_dirty = self.is_dirty();
1324        let old_version = self.version.clone();
1325        let mut deferred_ops = Vec::new();
1326        let buffer_ops = ops
1327            .into_iter()
1328            .filter_map(|op| match op {
1329                Operation::Buffer(op) => Some(op),
1330                _ => {
1331                    if self.can_apply_op(&op) {
1332                        self.apply_op(op, cx);
1333                    } else {
1334                        deferred_ops.push(op);
1335                    }
1336                    None
1337                }
1338            })
1339            .collect::<Vec<_>>();
1340        self.text.apply_ops(buffer_ops)?;
1341        self.deferred_ops.insert(deferred_ops);
1342        self.flush_deferred_ops(cx);
1343        self.did_edit(&old_version, was_dirty, cx);
1344        // Notify independently of whether the buffer was edited as the operations could include a
1345        // selection update.
1346        cx.notify();
1347        Ok(())
1348    }
1349
1350    fn flush_deferred_ops(&mut self, cx: &mut ModelContext<Self>) {
1351        let mut deferred_ops = Vec::new();
1352        for op in self.deferred_ops.drain().iter().cloned() {
1353            if self.can_apply_op(&op) {
1354                self.apply_op(op, cx);
1355            } else {
1356                deferred_ops.push(op);
1357            }
1358        }
1359        self.deferred_ops.insert(deferred_ops);
1360    }
1361
1362    fn can_apply_op(&self, operation: &Operation) -> bool {
1363        match operation {
1364            Operation::Buffer(_) => {
1365                unreachable!("buffer operations should never be applied at this layer")
1366            }
1367            Operation::UpdateDiagnostics {
1368                diagnostics: diagnostic_set,
1369                ..
1370            } => diagnostic_set.iter().all(|diagnostic| {
1371                self.text.can_resolve(&diagnostic.range.start)
1372                    && self.text.can_resolve(&diagnostic.range.end)
1373            }),
1374            Operation::UpdateSelections { selections, .. } => selections
1375                .iter()
1376                .all(|s| self.can_resolve(&s.start) && self.can_resolve(&s.end)),
1377            Operation::UpdateCompletionTriggers { .. } => true,
1378        }
1379    }
1380
1381    fn apply_op(&mut self, operation: Operation, cx: &mut ModelContext<Self>) {
1382        match operation {
1383            Operation::Buffer(_) => {
1384                unreachable!("buffer operations should never be applied at this layer")
1385            }
1386            Operation::UpdateDiagnostics {
1387                diagnostics: diagnostic_set,
1388                lamport_timestamp,
1389            } => {
1390                let snapshot = self.snapshot();
1391                self.apply_diagnostic_update(
1392                    DiagnosticSet::from_sorted_entries(diagnostic_set.iter().cloned(), &snapshot),
1393                    lamport_timestamp,
1394                    cx,
1395                );
1396            }
1397            Operation::UpdateSelections {
1398                selections,
1399                lamport_timestamp,
1400                line_mode,
1401            } => {
1402                if let Some(set) = self.remote_selections.get(&lamport_timestamp.replica_id) {
1403                    if set.lamport_timestamp > lamport_timestamp {
1404                        return;
1405                    }
1406                }
1407
1408                self.remote_selections.insert(
1409                    lamport_timestamp.replica_id,
1410                    SelectionSet {
1411                        selections,
1412                        lamport_timestamp,
1413                        line_mode,
1414                    },
1415                );
1416                self.text.lamport_clock.observe(lamport_timestamp);
1417                self.selections_update_count += 1;
1418            }
1419            Operation::UpdateCompletionTriggers {
1420                triggers,
1421                lamport_timestamp,
1422            } => {
1423                self.completion_triggers = triggers;
1424                self.text.lamport_clock.observe(lamport_timestamp);
1425            }
1426        }
1427    }
1428
1429    fn apply_diagnostic_update(
1430        &mut self,
1431        diagnostics: DiagnosticSet,
1432        lamport_timestamp: clock::Lamport,
1433        cx: &mut ModelContext<Self>,
1434    ) {
1435        if lamport_timestamp > self.diagnostics_timestamp {
1436            self.diagnostics = diagnostics;
1437            self.diagnostics_timestamp = lamport_timestamp;
1438            self.diagnostics_update_count += 1;
1439            self.text.lamport_clock.observe(lamport_timestamp);
1440            cx.notify();
1441            cx.emit(Event::DiagnosticsUpdated);
1442        }
1443    }
1444
1445    fn send_operation(&mut self, operation: Operation, cx: &mut ModelContext<Self>) {
1446        cx.emit(Event::Operation(operation));
1447    }
1448
1449    pub fn remove_peer(&mut self, replica_id: ReplicaId, cx: &mut ModelContext<Self>) {
1450        self.remote_selections.remove(&replica_id);
1451        cx.notify();
1452    }
1453
1454    pub fn undo(&mut self, cx: &mut ModelContext<Self>) -> Option<TransactionId> {
1455        let was_dirty = self.is_dirty();
1456        let old_version = self.version.clone();
1457
1458        if let Some((transaction_id, operation)) = self.text.undo() {
1459            self.send_operation(Operation::Buffer(operation), cx);
1460            self.did_edit(&old_version, was_dirty, cx);
1461            Some(transaction_id)
1462        } else {
1463            None
1464        }
1465    }
1466
1467    pub fn undo_to_transaction(
1468        &mut self,
1469        transaction_id: TransactionId,
1470        cx: &mut ModelContext<Self>,
1471    ) -> bool {
1472        let was_dirty = self.is_dirty();
1473        let old_version = self.version.clone();
1474
1475        let operations = self.text.undo_to_transaction(transaction_id);
1476        let undone = !operations.is_empty();
1477        for operation in operations {
1478            self.send_operation(Operation::Buffer(operation), cx);
1479        }
1480        if undone {
1481            self.did_edit(&old_version, was_dirty, cx)
1482        }
1483        undone
1484    }
1485
1486    pub fn redo(&mut self, cx: &mut ModelContext<Self>) -> Option<TransactionId> {
1487        let was_dirty = self.is_dirty();
1488        let old_version = self.version.clone();
1489
1490        if let Some((transaction_id, operation)) = self.text.redo() {
1491            self.send_operation(Operation::Buffer(operation), cx);
1492            self.did_edit(&old_version, was_dirty, cx);
1493            Some(transaction_id)
1494        } else {
1495            None
1496        }
1497    }
1498
1499    pub fn redo_to_transaction(
1500        &mut self,
1501        transaction_id: TransactionId,
1502        cx: &mut ModelContext<Self>,
1503    ) -> bool {
1504        let was_dirty = self.is_dirty();
1505        let old_version = self.version.clone();
1506
1507        let operations = self.text.redo_to_transaction(transaction_id);
1508        let redone = !operations.is_empty();
1509        for operation in operations {
1510            self.send_operation(Operation::Buffer(operation), cx);
1511        }
1512        if redone {
1513            self.did_edit(&old_version, was_dirty, cx)
1514        }
1515        redone
1516    }
1517
1518    pub fn set_completion_triggers(&mut self, triggers: Vec<String>, cx: &mut ModelContext<Self>) {
1519        self.completion_triggers = triggers.clone();
1520        let lamport_timestamp = self.text.lamport_clock.tick();
1521        self.send_operation(
1522            Operation::UpdateCompletionTriggers {
1523                triggers,
1524                lamport_timestamp,
1525            },
1526            cx,
1527        );
1528        cx.notify();
1529    }
1530
1531    pub fn completion_triggers(&self) -> &[String] {
1532        &self.completion_triggers
1533    }
1534}
1535
1536#[cfg(any(test, feature = "test-support"))]
1537impl Buffer {
1538    pub fn set_group_interval(&mut self, group_interval: Duration) {
1539        self.text.set_group_interval(group_interval);
1540    }
1541
1542    pub fn randomly_edit<T>(
1543        &mut self,
1544        rng: &mut T,
1545        old_range_count: usize,
1546        cx: &mut ModelContext<Self>,
1547    ) where
1548        T: rand::Rng,
1549    {
1550        let mut edits: Vec<(Range<usize>, String)> = Vec::new();
1551        let mut last_end = None;
1552        for _ in 0..old_range_count {
1553            if last_end.map_or(false, |last_end| last_end >= self.len()) {
1554                break;
1555            }
1556
1557            let new_start = last_end.map_or(0, |last_end| last_end + 1);
1558            let mut range = self.random_byte_range(new_start, rng);
1559            if rng.gen_bool(0.2) {
1560                mem::swap(&mut range.start, &mut range.end);
1561            }
1562            last_end = Some(range.end);
1563
1564            let new_text_len = rng.gen_range(0..10);
1565            let new_text: String = crate::random_char_iter::RandomCharIter::new(&mut *rng)
1566                .take(new_text_len)
1567                .collect();
1568
1569            edits.push((range, new_text));
1570        }
1571        log::info!("mutating buffer {} with {:?}", self.replica_id(), edits);
1572        self.edit(edits, None, cx);
1573    }
1574
1575    pub fn randomly_undo_redo(&mut self, rng: &mut impl rand::Rng, cx: &mut ModelContext<Self>) {
1576        let was_dirty = self.is_dirty();
1577        let old_version = self.version.clone();
1578
1579        let ops = self.text.randomly_undo_redo(rng);
1580        if !ops.is_empty() {
1581            for op in ops {
1582                self.send_operation(Operation::Buffer(op), cx);
1583                self.did_edit(&old_version, was_dirty, cx);
1584            }
1585        }
1586    }
1587}
1588
1589impl Entity for Buffer {
1590    type Event = Event;
1591}
1592
1593impl Deref for Buffer {
1594    type Target = TextBuffer;
1595
1596    fn deref(&self) -> &Self::Target {
1597        &self.text
1598    }
1599}
1600
1601impl BufferSnapshot {
1602    pub fn indent_size_for_line(&self, row: u32) -> IndentSize {
1603        indent_size_for_line(self, row)
1604    }
1605
1606    pub fn single_indent_size(&self, cx: &AppContext) -> IndentSize {
1607        let language_name = self.language().map(|language| language.name());
1608        let settings = cx.global::<Settings>();
1609        if settings.hard_tabs(language_name.as_deref()) {
1610            IndentSize::tab()
1611        } else {
1612            IndentSize::spaces(settings.tab_size(language_name.as_deref()).get())
1613        }
1614    }
1615
1616    pub fn suggested_indents(
1617        &self,
1618        rows: impl Iterator<Item = u32>,
1619        single_indent_size: IndentSize,
1620    ) -> BTreeMap<u32, IndentSize> {
1621        let mut result = BTreeMap::new();
1622
1623        for row_range in contiguous_ranges(rows, 10) {
1624            let suggestions = match self.suggest_autoindents(row_range.clone()) {
1625                Some(suggestions) => suggestions,
1626                _ => break,
1627            };
1628
1629            for (row, suggestion) in row_range.zip(suggestions) {
1630                let indent_size = if let Some(suggestion) = suggestion {
1631                    result
1632                        .get(&suggestion.basis_row)
1633                        .copied()
1634                        .unwrap_or_else(|| self.indent_size_for_line(suggestion.basis_row))
1635                        .with_delta(suggestion.delta, single_indent_size)
1636                } else {
1637                    self.indent_size_for_line(row)
1638                };
1639
1640                result.insert(row, indent_size);
1641            }
1642        }
1643
1644        result
1645    }
1646
1647    fn suggest_autoindents(
1648        &self,
1649        row_range: Range<u32>,
1650    ) -> Option<impl Iterator<Item = Option<IndentSuggestion>> + '_> {
1651        let language = self.language.as_ref()?;
1652        let grammar = language.grammar.as_ref()?;
1653        let config = &language.config;
1654        let prev_non_blank_row = self.prev_non_blank_row(row_range.start);
1655
1656        // Find the suggested indentation ranges based on the syntax tree.
1657        let indents_query = grammar.indents_query.as_ref()?;
1658        let mut query_cursor = QueryCursorHandle::new();
1659        let indent_capture_ix = indents_query.capture_index_for_name("indent");
1660        let end_capture_ix = indents_query.capture_index_for_name("end");
1661        query_cursor.set_point_range(
1662            Point::new(prev_non_blank_row.unwrap_or(row_range.start), 0).to_ts_point()
1663                ..Point::new(row_range.end, 0).to_ts_point(),
1664        );
1665
1666        let mut indent_ranges = Vec::<Range<Point>>::new();
1667        for mat in query_cursor.matches(
1668            indents_query,
1669            self.tree.as_ref()?.root_node(),
1670            TextProvider(self.as_rope()),
1671        ) {
1672            let mut start: Option<Point> = None;
1673            let mut end: Option<Point> = None;
1674            for capture in mat.captures {
1675                if Some(capture.index) == indent_capture_ix {
1676                    start.get_or_insert(Point::from_ts_point(capture.node.start_position()));
1677                    end.get_or_insert(Point::from_ts_point(capture.node.end_position()));
1678                } else if Some(capture.index) == end_capture_ix {
1679                    end = Some(Point::from_ts_point(capture.node.start_position()));
1680                }
1681            }
1682
1683            if let Some((start, end)) = start.zip(end) {
1684                if start.row == end.row {
1685                    continue;
1686                }
1687
1688                let range = start..end;
1689                match indent_ranges.binary_search_by_key(&range.start, |r| r.start) {
1690                    Err(ix) => indent_ranges.insert(ix, range),
1691                    Ok(ix) => {
1692                        let prev_range = &mut indent_ranges[ix];
1693                        prev_range.end = prev_range.end.max(range.end);
1694                    }
1695                }
1696            }
1697        }
1698
1699        // Find the suggested indentation increases and decreased based on regexes.
1700        let mut indent_change_rows = Vec::<(u32, Ordering)>::new();
1701        self.for_each_line(
1702            Point::new(prev_non_blank_row.unwrap_or(row_range.start), 0)
1703                ..Point::new(row_range.end, 0),
1704            |row, line| {
1705                if config
1706                    .decrease_indent_pattern
1707                    .as_ref()
1708                    .map_or(false, |regex| regex.is_match(line))
1709                {
1710                    indent_change_rows.push((row, Ordering::Less));
1711                }
1712                if config
1713                    .increase_indent_pattern
1714                    .as_ref()
1715                    .map_or(false, |regex| regex.is_match(line))
1716                {
1717                    indent_change_rows.push((row + 1, Ordering::Greater));
1718                }
1719            },
1720        );
1721
1722        let mut indent_changes = indent_change_rows.into_iter().peekable();
1723        let mut prev_row = if config.auto_indent_using_last_non_empty_line {
1724            prev_non_blank_row.unwrap_or(0)
1725        } else {
1726            row_range.start.saturating_sub(1)
1727        };
1728        let mut prev_row_start = Point::new(prev_row, self.indent_size_for_line(prev_row).len);
1729        Some(row_range.map(move |row| {
1730            let row_start = Point::new(row, self.indent_size_for_line(row).len);
1731
1732            let mut indent_from_prev_row = false;
1733            let mut outdent_from_prev_row = false;
1734            let mut outdent_to_row = u32::MAX;
1735
1736            while let Some((indent_row, delta)) = indent_changes.peek() {
1737                match indent_row.cmp(&row) {
1738                    Ordering::Equal => match delta {
1739                        Ordering::Less => outdent_from_prev_row = true,
1740                        Ordering::Greater => indent_from_prev_row = true,
1741                        _ => {}
1742                    },
1743
1744                    Ordering::Greater => break,
1745                    Ordering::Less => {}
1746                }
1747
1748                indent_changes.next();
1749            }
1750
1751            for range in &indent_ranges {
1752                if range.start.row >= row {
1753                    break;
1754                }
1755                if range.start.row == prev_row && range.end > row_start {
1756                    indent_from_prev_row = true;
1757                }
1758                if range.end > prev_row_start && range.end <= row_start {
1759                    outdent_to_row = outdent_to_row.min(range.start.row);
1760                }
1761            }
1762
1763            let suggestion = if outdent_to_row == prev_row
1764                || (outdent_from_prev_row && indent_from_prev_row)
1765            {
1766                Some(IndentSuggestion {
1767                    basis_row: prev_row,
1768                    delta: Ordering::Equal,
1769                })
1770            } else if indent_from_prev_row {
1771                Some(IndentSuggestion {
1772                    basis_row: prev_row,
1773                    delta: Ordering::Greater,
1774                })
1775            } else if outdent_to_row < prev_row {
1776                Some(IndentSuggestion {
1777                    basis_row: outdent_to_row,
1778                    delta: Ordering::Equal,
1779                })
1780            } else if outdent_from_prev_row {
1781                Some(IndentSuggestion {
1782                    basis_row: prev_row,
1783                    delta: Ordering::Less,
1784                })
1785            } else if config.auto_indent_using_last_non_empty_line || !self.is_line_blank(prev_row)
1786            {
1787                Some(IndentSuggestion {
1788                    basis_row: prev_row,
1789                    delta: Ordering::Equal,
1790                })
1791            } else {
1792                None
1793            };
1794
1795            prev_row = row;
1796            prev_row_start = row_start;
1797            suggestion
1798        }))
1799    }
1800
1801    fn prev_non_blank_row(&self, mut row: u32) -> Option<u32> {
1802        while row > 0 {
1803            row -= 1;
1804            if !self.is_line_blank(row) {
1805                return Some(row);
1806            }
1807        }
1808        None
1809    }
1810
1811    pub fn chunks<T: ToOffset>(&self, range: Range<T>, language_aware: bool) -> BufferChunks {
1812        let range = range.start.to_offset(self)..range.end.to_offset(self);
1813
1814        let mut tree = None;
1815        let mut diagnostic_endpoints = Vec::new();
1816        if language_aware {
1817            tree = self.tree.as_ref();
1818            for entry in self.diagnostics_in_range::<_, usize>(range.clone(), false) {
1819                diagnostic_endpoints.push(DiagnosticEndpoint {
1820                    offset: entry.range.start,
1821                    is_start: true,
1822                    severity: entry.diagnostic.severity,
1823                    is_unnecessary: entry.diagnostic.is_unnecessary,
1824                });
1825                diagnostic_endpoints.push(DiagnosticEndpoint {
1826                    offset: entry.range.end,
1827                    is_start: false,
1828                    severity: entry.diagnostic.severity,
1829                    is_unnecessary: entry.diagnostic.is_unnecessary,
1830                });
1831            }
1832            diagnostic_endpoints
1833                .sort_unstable_by_key(|endpoint| (endpoint.offset, !endpoint.is_start));
1834        }
1835
1836        BufferChunks::new(
1837            self.text.as_rope(),
1838            range,
1839            tree,
1840            self.grammar(),
1841            diagnostic_endpoints,
1842        )
1843    }
1844
1845    pub fn for_each_line(&self, range: Range<Point>, mut callback: impl FnMut(u32, &str)) {
1846        let mut line = String::new();
1847        let mut row = range.start.row;
1848        for chunk in self
1849            .as_rope()
1850            .chunks_in_range(range.to_offset(self))
1851            .chain(["\n"])
1852        {
1853            for (newline_ix, text) in chunk.split('\n').enumerate() {
1854                if newline_ix > 0 {
1855                    callback(row, &line);
1856                    row += 1;
1857                    line.clear();
1858                }
1859                line.push_str(text);
1860            }
1861        }
1862    }
1863
1864    pub fn language(&self) -> Option<&Arc<Language>> {
1865        self.language.as_ref()
1866    }
1867
1868    fn grammar(&self) -> Option<&Arc<Grammar>> {
1869        self.language
1870            .as_ref()
1871            .and_then(|language| language.grammar.as_ref())
1872    }
1873
1874    pub fn surrounding_word<T: ToOffset>(&self, start: T) -> (Range<usize>, Option<CharKind>) {
1875        let mut start = start.to_offset(self);
1876        let mut end = start;
1877        let mut next_chars = self.chars_at(start).peekable();
1878        let mut prev_chars = self.reversed_chars_at(start).peekable();
1879        let word_kind = cmp::max(
1880            prev_chars.peek().copied().map(char_kind),
1881            next_chars.peek().copied().map(char_kind),
1882        );
1883
1884        for ch in prev_chars {
1885            if Some(char_kind(ch)) == word_kind && ch != '\n' {
1886                start -= ch.len_utf8();
1887            } else {
1888                break;
1889            }
1890        }
1891
1892        for ch in next_chars {
1893            if Some(char_kind(ch)) == word_kind && ch != '\n' {
1894                end += ch.len_utf8();
1895            } else {
1896                break;
1897            }
1898        }
1899
1900        (start..end, word_kind)
1901    }
1902
1903    pub fn range_for_syntax_ancestor<T: ToOffset>(&self, range: Range<T>) -> Option<Range<usize>> {
1904        let tree = self.tree.as_ref()?;
1905        let range = range.start.to_offset(self)..range.end.to_offset(self);
1906        let mut cursor = tree.root_node().walk();
1907
1908        // Descend to the first leaf that touches the start of the range,
1909        // and if the range is non-empty, extends beyond the start.
1910        while cursor.goto_first_child_for_byte(range.start).is_some() {
1911            if !range.is_empty() && cursor.node().end_byte() == range.start {
1912                cursor.goto_next_sibling();
1913            }
1914        }
1915
1916        // Ascend to the smallest ancestor that strictly contains the range.
1917        loop {
1918            let node_range = cursor.node().byte_range();
1919            if node_range.start <= range.start
1920                && node_range.end >= range.end
1921                && node_range.len() > range.len()
1922            {
1923                break;
1924            }
1925            if !cursor.goto_parent() {
1926                break;
1927            }
1928        }
1929
1930        let left_node = cursor.node();
1931
1932        // For an empty range, try to find another node immediately to the right of the range.
1933        if left_node.end_byte() == range.start {
1934            let mut right_node = None;
1935            while !cursor.goto_next_sibling() {
1936                if !cursor.goto_parent() {
1937                    break;
1938                }
1939            }
1940
1941            while cursor.node().start_byte() == range.start {
1942                right_node = Some(cursor.node());
1943                if !cursor.goto_first_child() {
1944                    break;
1945                }
1946            }
1947
1948            // If there is a candidate node on both sides of the (empty) range, then
1949            // decide between the two by favoring a named node over an anonymous token.
1950            // If both nodes are the same in that regard, favor the right one.
1951            if let Some(right_node) = right_node {
1952                if right_node.is_named() || !left_node.is_named() {
1953                    return Some(right_node.byte_range());
1954                }
1955            }
1956        }
1957
1958        Some(left_node.byte_range())
1959    }
1960
1961    pub fn outline(&self, theme: Option<&SyntaxTheme>) -> Option<Outline<Anchor>> {
1962        self.outline_items_containing(0..self.len(), theme)
1963            .map(Outline::new)
1964    }
1965
1966    pub fn symbols_containing<T: ToOffset>(
1967        &self,
1968        position: T,
1969        theme: Option<&SyntaxTheme>,
1970    ) -> Option<Vec<OutlineItem<Anchor>>> {
1971        let position = position.to_offset(self);
1972        let mut items =
1973            self.outline_items_containing(position.saturating_sub(1)..position + 1, theme)?;
1974        let mut prev_depth = None;
1975        items.retain(|item| {
1976            let result = prev_depth.map_or(true, |prev_depth| item.depth > prev_depth);
1977            prev_depth = Some(item.depth);
1978            result
1979        });
1980        Some(items)
1981    }
1982
1983    fn outline_items_containing(
1984        &self,
1985        range: Range<usize>,
1986        theme: Option<&SyntaxTheme>,
1987    ) -> Option<Vec<OutlineItem<Anchor>>> {
1988        let tree = self.tree.as_ref()?;
1989        let grammar = self
1990            .language
1991            .as_ref()
1992            .and_then(|language| language.grammar.as_ref())?;
1993
1994        let outline_query = grammar.outline_query.as_ref()?;
1995        let mut cursor = QueryCursorHandle::new();
1996        cursor.set_byte_range(range.clone());
1997        let matches = cursor.matches(
1998            outline_query,
1999            tree.root_node(),
2000            TextProvider(self.as_rope()),
2001        );
2002
2003        let mut chunks = self.chunks(0..self.len(), true);
2004
2005        let item_capture_ix = outline_query.capture_index_for_name("item")?;
2006        let name_capture_ix = outline_query.capture_index_for_name("name")?;
2007        let context_capture_ix = outline_query
2008            .capture_index_for_name("context")
2009            .unwrap_or(u32::MAX);
2010
2011        let mut stack = Vec::<Range<usize>>::new();
2012        let items = matches
2013            .filter_map(|mat| {
2014                let item_node = mat.nodes_for_capture_index(item_capture_ix).next()?;
2015                let item_range = item_node.start_byte()..item_node.end_byte();
2016                if item_range.end < range.start || item_range.start > range.end {
2017                    return None;
2018                }
2019                let mut text = String::new();
2020                let mut name_ranges = Vec::new();
2021                let mut highlight_ranges = Vec::new();
2022
2023                for capture in mat.captures {
2024                    let node_is_name;
2025                    if capture.index == name_capture_ix {
2026                        node_is_name = true;
2027                    } else if capture.index == context_capture_ix {
2028                        node_is_name = false;
2029                    } else {
2030                        continue;
2031                    }
2032
2033                    let range = capture.node.start_byte()..capture.node.end_byte();
2034                    if !text.is_empty() {
2035                        text.push(' ');
2036                    }
2037                    if node_is_name {
2038                        let mut start = text.len();
2039                        let end = start + range.len();
2040
2041                        // When multiple names are captured, then the matcheable text
2042                        // includes the whitespace in between the names.
2043                        if !name_ranges.is_empty() {
2044                            start -= 1;
2045                        }
2046
2047                        name_ranges.push(start..end);
2048                    }
2049
2050                    let mut offset = range.start;
2051                    chunks.seek(offset);
2052                    for mut chunk in chunks.by_ref() {
2053                        if chunk.text.len() > range.end - offset {
2054                            chunk.text = &chunk.text[0..(range.end - offset)];
2055                            offset = range.end;
2056                        } else {
2057                            offset += chunk.text.len();
2058                        }
2059                        let style = chunk
2060                            .syntax_highlight_id
2061                            .zip(theme)
2062                            .and_then(|(highlight, theme)| highlight.style(theme));
2063                        if let Some(style) = style {
2064                            let start = text.len();
2065                            let end = start + chunk.text.len();
2066                            highlight_ranges.push((start..end, style));
2067                        }
2068                        text.push_str(chunk.text);
2069                        if offset >= range.end {
2070                            break;
2071                        }
2072                    }
2073                }
2074
2075                while stack.last().map_or(false, |prev_range| {
2076                    prev_range.start > item_range.start || prev_range.end < item_range.end
2077                }) {
2078                    stack.pop();
2079                }
2080                stack.push(item_range.clone());
2081
2082                Some(OutlineItem {
2083                    depth: stack.len() - 1,
2084                    range: self.anchor_after(item_range.start)..self.anchor_before(item_range.end),
2085                    text,
2086                    highlight_ranges,
2087                    name_ranges,
2088                })
2089            })
2090            .collect::<Vec<_>>();
2091        Some(items)
2092    }
2093
2094    pub fn enclosing_bracket_ranges<T: ToOffset>(
2095        &self,
2096        range: Range<T>,
2097    ) -> Option<(Range<usize>, Range<usize>)> {
2098        let (grammar, tree) = self.grammar().zip(self.tree.as_ref())?;
2099        let brackets_query = grammar.brackets_query.as_ref()?;
2100        let open_capture_ix = brackets_query.capture_index_for_name("open")?;
2101        let close_capture_ix = brackets_query.capture_index_for_name("close")?;
2102
2103        // Find bracket pairs that *inclusively* contain the given range.
2104        let range = range.start.to_offset(self).saturating_sub(1)..range.end.to_offset(self) + 1;
2105        let mut cursor = QueryCursorHandle::new();
2106        let matches = cursor.set_byte_range(range).matches(
2107            brackets_query,
2108            tree.root_node(),
2109            TextProvider(self.as_rope()),
2110        );
2111
2112        // Get the ranges of the innermost pair of brackets.
2113        matches
2114            .filter_map(|mat| {
2115                let open = mat.nodes_for_capture_index(open_capture_ix).next()?;
2116                let close = mat.nodes_for_capture_index(close_capture_ix).next()?;
2117                Some((open.byte_range(), close.byte_range()))
2118            })
2119            .min_by_key(|(open_range, close_range)| close_range.end - open_range.start)
2120    }
2121
2122    #[allow(clippy::type_complexity)]
2123    pub fn remote_selections_in_range(
2124        &self,
2125        range: Range<Anchor>,
2126    ) -> impl Iterator<
2127        Item = (
2128            ReplicaId,
2129            bool,
2130            impl Iterator<Item = &Selection<Anchor>> + '_,
2131        ),
2132    > + '_ {
2133        self.remote_selections
2134            .iter()
2135            .filter(|(replica_id, set)| {
2136                **replica_id != self.text.replica_id() && !set.selections.is_empty()
2137            })
2138            .map(move |(replica_id, set)| {
2139                let start_ix = match set.selections.binary_search_by(|probe| {
2140                    probe.end.cmp(&range.start, self).then(Ordering::Greater)
2141                }) {
2142                    Ok(ix) | Err(ix) => ix,
2143                };
2144                let end_ix = match set.selections.binary_search_by(|probe| {
2145                    probe.start.cmp(&range.end, self).then(Ordering::Less)
2146                }) {
2147                    Ok(ix) | Err(ix) => ix,
2148                };
2149
2150                (
2151                    *replica_id,
2152                    set.line_mode,
2153                    set.selections[start_ix..end_ix].iter(),
2154                )
2155            })
2156    }
2157
2158    pub fn diagnostics_in_range<'a, T, O>(
2159        &'a self,
2160        search_range: Range<T>,
2161        reversed: bool,
2162    ) -> impl 'a + Iterator<Item = DiagnosticEntry<O>>
2163    where
2164        T: 'a + Clone + ToOffset,
2165        O: 'a + FromAnchor,
2166    {
2167        self.diagnostics.range(search_range, self, true, reversed)
2168    }
2169
2170    pub fn diagnostic_groups(&self) -> Vec<DiagnosticGroup<Anchor>> {
2171        let mut groups = Vec::new();
2172        self.diagnostics.groups(&mut groups, self);
2173        groups
2174    }
2175
2176    pub fn diagnostic_group<'a, O>(
2177        &'a self,
2178        group_id: usize,
2179    ) -> impl 'a + Iterator<Item = DiagnosticEntry<O>>
2180    where
2181        O: 'a + FromAnchor,
2182    {
2183        self.diagnostics.group(group_id, self)
2184    }
2185
2186    pub fn diagnostics_update_count(&self) -> usize {
2187        self.diagnostics_update_count
2188    }
2189
2190    pub fn parse_count(&self) -> usize {
2191        self.parse_count
2192    }
2193
2194    pub fn selections_update_count(&self) -> usize {
2195        self.selections_update_count
2196    }
2197
2198    pub fn file(&self) -> Option<&dyn File> {
2199        self.file.as_deref()
2200    }
2201
2202    pub fn file_update_count(&self) -> usize {
2203        self.file_update_count
2204    }
2205}
2206
2207pub fn indent_size_for_line(text: &text::BufferSnapshot, row: u32) -> IndentSize {
2208    indent_size_for_text(text.chars_at(Point::new(row, 0)))
2209}
2210
2211pub fn indent_size_for_text(text: impl Iterator<Item = char>) -> IndentSize {
2212    let mut result = IndentSize::spaces(0);
2213    for c in text {
2214        let kind = match c {
2215            ' ' => IndentKind::Space,
2216            '\t' => IndentKind::Tab,
2217            _ => break,
2218        };
2219        if result.len == 0 {
2220            result.kind = kind;
2221        }
2222        result.len += 1;
2223    }
2224    result
2225}
2226
2227impl Clone for BufferSnapshot {
2228    fn clone(&self) -> Self {
2229        Self {
2230            text: self.text.clone(),
2231            tree: self.tree.clone(),
2232            file: self.file.clone(),
2233            remote_selections: self.remote_selections.clone(),
2234            diagnostics: self.diagnostics.clone(),
2235            selections_update_count: self.selections_update_count,
2236            diagnostics_update_count: self.diagnostics_update_count,
2237            file_update_count: self.file_update_count,
2238            language: self.language.clone(),
2239            parse_count: self.parse_count,
2240        }
2241    }
2242}
2243
2244impl Deref for BufferSnapshot {
2245    type Target = text::BufferSnapshot;
2246
2247    fn deref(&self) -> &Self::Target {
2248        &self.text
2249    }
2250}
2251
2252impl<'a> tree_sitter::TextProvider<'a> for TextProvider<'a> {
2253    type I = ByteChunks<'a>;
2254
2255    fn text(&mut self, node: tree_sitter::Node) -> Self::I {
2256        ByteChunks(self.0.chunks_in_range(node.byte_range()))
2257    }
2258}
2259
2260pub(crate) struct ByteChunks<'a>(rope::Chunks<'a>);
2261
2262impl<'a> Iterator for ByteChunks<'a> {
2263    type Item = &'a [u8];
2264
2265    fn next(&mut self) -> Option<Self::Item> {
2266        self.0.next().map(str::as_bytes)
2267    }
2268}
2269
2270unsafe impl<'a> Send for BufferChunks<'a> {}
2271
2272impl<'a> BufferChunks<'a> {
2273    pub(crate) fn new(
2274        text: &'a Rope,
2275        range: Range<usize>,
2276        tree: Option<&'a Tree>,
2277        grammar: Option<&'a Arc<Grammar>>,
2278        diagnostic_endpoints: Vec<DiagnosticEndpoint>,
2279    ) -> Self {
2280        let mut highlights = None;
2281        if let Some((grammar, tree)) = grammar.zip(tree) {
2282            if let Some(highlights_query) = grammar.highlights_query.as_ref() {
2283                let mut query_cursor = QueryCursorHandle::new();
2284
2285                // TODO - add a Tree-sitter API to remove the need for this.
2286                let cursor = unsafe {
2287                    std::mem::transmute::<_, &'static mut QueryCursor>(query_cursor.deref_mut())
2288                };
2289                let captures = cursor.set_byte_range(range.clone()).captures(
2290                    highlights_query,
2291                    tree.root_node(),
2292                    TextProvider(text),
2293                );
2294                highlights = Some(BufferChunkHighlights {
2295                    captures,
2296                    next_capture: None,
2297                    stack: Default::default(),
2298                    highlight_map: grammar.highlight_map(),
2299                    _query_cursor: query_cursor,
2300                })
2301            }
2302        }
2303
2304        let diagnostic_endpoints = diagnostic_endpoints.into_iter().peekable();
2305        let chunks = text.chunks_in_range(range.clone());
2306
2307        BufferChunks {
2308            range,
2309            chunks,
2310            diagnostic_endpoints,
2311            error_depth: 0,
2312            warning_depth: 0,
2313            information_depth: 0,
2314            hint_depth: 0,
2315            unnecessary_depth: 0,
2316            highlights,
2317        }
2318    }
2319
2320    pub fn seek(&mut self, offset: usize) {
2321        self.range.start = offset;
2322        self.chunks.seek(self.range.start);
2323        if let Some(highlights) = self.highlights.as_mut() {
2324            highlights
2325                .stack
2326                .retain(|(end_offset, _)| *end_offset > offset);
2327            if let Some((mat, capture_ix)) = &highlights.next_capture {
2328                let capture = mat.captures[*capture_ix as usize];
2329                if offset >= capture.node.start_byte() {
2330                    let next_capture_end = capture.node.end_byte();
2331                    if offset < next_capture_end {
2332                        highlights.stack.push((
2333                            next_capture_end,
2334                            highlights.highlight_map.get(capture.index),
2335                        ));
2336                    }
2337                    highlights.next_capture.take();
2338                }
2339            }
2340            highlights.captures.set_byte_range(self.range.clone());
2341        }
2342    }
2343
2344    pub fn offset(&self) -> usize {
2345        self.range.start
2346    }
2347
2348    fn update_diagnostic_depths(&mut self, endpoint: DiagnosticEndpoint) {
2349        let depth = match endpoint.severity {
2350            DiagnosticSeverity::ERROR => &mut self.error_depth,
2351            DiagnosticSeverity::WARNING => &mut self.warning_depth,
2352            DiagnosticSeverity::INFORMATION => &mut self.information_depth,
2353            DiagnosticSeverity::HINT => &mut self.hint_depth,
2354            _ => return,
2355        };
2356        if endpoint.is_start {
2357            *depth += 1;
2358        } else {
2359            *depth -= 1;
2360        }
2361
2362        if endpoint.is_unnecessary {
2363            if endpoint.is_start {
2364                self.unnecessary_depth += 1;
2365            } else {
2366                self.unnecessary_depth -= 1;
2367            }
2368        }
2369    }
2370
2371    fn current_diagnostic_severity(&self) -> Option<DiagnosticSeverity> {
2372        if self.error_depth > 0 {
2373            Some(DiagnosticSeverity::ERROR)
2374        } else if self.warning_depth > 0 {
2375            Some(DiagnosticSeverity::WARNING)
2376        } else if self.information_depth > 0 {
2377            Some(DiagnosticSeverity::INFORMATION)
2378        } else if self.hint_depth > 0 {
2379            Some(DiagnosticSeverity::HINT)
2380        } else {
2381            None
2382        }
2383    }
2384
2385    fn current_code_is_unnecessary(&self) -> bool {
2386        self.unnecessary_depth > 0
2387    }
2388}
2389
2390impl<'a> Iterator for BufferChunks<'a> {
2391    type Item = Chunk<'a>;
2392
2393    fn next(&mut self) -> Option<Self::Item> {
2394        let mut next_capture_start = usize::MAX;
2395        let mut next_diagnostic_endpoint = usize::MAX;
2396
2397        if let Some(highlights) = self.highlights.as_mut() {
2398            while let Some((parent_capture_end, _)) = highlights.stack.last() {
2399                if *parent_capture_end <= self.range.start {
2400                    highlights.stack.pop();
2401                } else {
2402                    break;
2403                }
2404            }
2405
2406            if highlights.next_capture.is_none() {
2407                highlights.next_capture = highlights.captures.next();
2408            }
2409
2410            while let Some((mat, capture_ix)) = highlights.next_capture.as_ref() {
2411                let capture = mat.captures[*capture_ix as usize];
2412                if self.range.start < capture.node.start_byte() {
2413                    next_capture_start = capture.node.start_byte();
2414                    break;
2415                } else {
2416                    let highlight_id = highlights.highlight_map.get(capture.index);
2417                    highlights
2418                        .stack
2419                        .push((capture.node.end_byte(), highlight_id));
2420                    highlights.next_capture = highlights.captures.next();
2421                }
2422            }
2423        }
2424
2425        while let Some(endpoint) = self.diagnostic_endpoints.peek().copied() {
2426            if endpoint.offset <= self.range.start {
2427                self.update_diagnostic_depths(endpoint);
2428                self.diagnostic_endpoints.next();
2429            } else {
2430                next_diagnostic_endpoint = endpoint.offset;
2431                break;
2432            }
2433        }
2434
2435        if let Some(chunk) = self.chunks.peek() {
2436            let chunk_start = self.range.start;
2437            let mut chunk_end = (self.chunks.offset() + chunk.len())
2438                .min(next_capture_start)
2439                .min(next_diagnostic_endpoint);
2440            let mut highlight_id = None;
2441            if let Some(highlights) = self.highlights.as_ref() {
2442                if let Some((parent_capture_end, parent_highlight_id)) = highlights.stack.last() {
2443                    chunk_end = chunk_end.min(*parent_capture_end);
2444                    highlight_id = Some(*parent_highlight_id);
2445                }
2446            }
2447
2448            let slice =
2449                &chunk[chunk_start - self.chunks.offset()..chunk_end - self.chunks.offset()];
2450            self.range.start = chunk_end;
2451            if self.range.start == self.chunks.offset() + chunk.len() {
2452                self.chunks.next().unwrap();
2453            }
2454
2455            Some(Chunk {
2456                text: slice,
2457                syntax_highlight_id: highlight_id,
2458                highlight_style: None,
2459                diagnostic_severity: self.current_diagnostic_severity(),
2460                is_unnecessary: self.current_code_is_unnecessary(),
2461            })
2462        } else {
2463            None
2464        }
2465    }
2466}
2467
2468impl QueryCursorHandle {
2469    pub(crate) fn new() -> Self {
2470        let mut cursor = QUERY_CURSORS.lock().pop().unwrap_or_else(QueryCursor::new);
2471        cursor.set_match_limit(64);
2472        QueryCursorHandle(Some(cursor))
2473    }
2474}
2475
2476impl Deref for QueryCursorHandle {
2477    type Target = QueryCursor;
2478
2479    fn deref(&self) -> &Self::Target {
2480        self.0.as_ref().unwrap()
2481    }
2482}
2483
2484impl DerefMut for QueryCursorHandle {
2485    fn deref_mut(&mut self) -> &mut Self::Target {
2486        self.0.as_mut().unwrap()
2487    }
2488}
2489
2490impl Drop for QueryCursorHandle {
2491    fn drop(&mut self) {
2492        let mut cursor = self.0.take().unwrap();
2493        cursor.set_byte_range(0..usize::MAX);
2494        cursor.set_point_range(Point::zero().to_ts_point()..Point::MAX.to_ts_point());
2495        QUERY_CURSORS.lock().push(cursor)
2496    }
2497}
2498
2499trait ToTreeSitterPoint {
2500    fn to_ts_point(self) -> tree_sitter::Point;
2501    fn from_ts_point(point: tree_sitter::Point) -> Self;
2502}
2503
2504impl ToTreeSitterPoint for Point {
2505    fn to_ts_point(self) -> tree_sitter::Point {
2506        tree_sitter::Point::new(self.row as usize, self.column as usize)
2507    }
2508
2509    fn from_ts_point(point: tree_sitter::Point) -> Self {
2510        Point::new(point.row as u32, point.column as u32)
2511    }
2512}
2513
2514impl operation_queue::Operation for Operation {
2515    fn lamport_timestamp(&self) -> clock::Lamport {
2516        match self {
2517            Operation::Buffer(_) => {
2518                unreachable!("buffer operations should never be deferred at this layer")
2519            }
2520            Operation::UpdateDiagnostics {
2521                lamport_timestamp, ..
2522            }
2523            | Operation::UpdateSelections {
2524                lamport_timestamp, ..
2525            }
2526            | Operation::UpdateCompletionTriggers {
2527                lamport_timestamp, ..
2528            } => *lamport_timestamp,
2529        }
2530    }
2531}
2532
2533impl Default for Diagnostic {
2534    fn default() -> Self {
2535        Self {
2536            code: None,
2537            severity: DiagnosticSeverity::ERROR,
2538            message: Default::default(),
2539            group_id: 0,
2540            is_primary: false,
2541            is_valid: true,
2542            is_disk_based: false,
2543            is_unnecessary: false,
2544        }
2545    }
2546}
2547
2548impl IndentSize {
2549    pub fn spaces(len: u32) -> Self {
2550        Self {
2551            len,
2552            kind: IndentKind::Space,
2553        }
2554    }
2555
2556    pub fn tab() -> Self {
2557        Self {
2558            len: 1,
2559            kind: IndentKind::Tab,
2560        }
2561    }
2562
2563    pub fn chars(&self) -> impl Iterator<Item = char> {
2564        iter::repeat(self.char()).take(self.len as usize)
2565    }
2566
2567    pub fn char(&self) -> char {
2568        match self.kind {
2569            IndentKind::Space => ' ',
2570            IndentKind::Tab => '\t',
2571        }
2572    }
2573
2574    pub fn with_delta(mut self, direction: Ordering, size: IndentSize) -> Self {
2575        match direction {
2576            Ordering::Less => {
2577                if self.kind == size.kind && self.len >= size.len {
2578                    self.len -= size.len;
2579                }
2580            }
2581            Ordering::Equal => {}
2582            Ordering::Greater => {
2583                if self.len == 0 {
2584                    self = size;
2585                } else if self.kind == size.kind {
2586                    self.len += size.len;
2587                }
2588            }
2589        }
2590        self
2591    }
2592}
2593
2594impl Completion {
2595    pub fn sort_key(&self) -> (usize, &str) {
2596        let kind_key = match self.lsp_completion.kind {
2597            Some(lsp::CompletionItemKind::VARIABLE) => 0,
2598            _ => 1,
2599        };
2600        (kind_key, &self.label.text[self.label.filter_range.clone()])
2601    }
2602
2603    pub fn is_snippet(&self) -> bool {
2604        self.lsp_completion.insert_text_format == Some(lsp::InsertTextFormat::SNIPPET)
2605    }
2606}
2607
2608pub fn contiguous_ranges(
2609    values: impl Iterator<Item = u32>,
2610    max_len: usize,
2611) -> impl Iterator<Item = Range<u32>> {
2612    let mut values = values;
2613    let mut current_range: Option<Range<u32>> = None;
2614    std::iter::from_fn(move || loop {
2615        if let Some(value) = values.next() {
2616            if let Some(range) = &mut current_range {
2617                if value == range.end && range.len() < max_len {
2618                    range.end += 1;
2619                    continue;
2620                }
2621            }
2622
2623            let prev_range = current_range.clone();
2624            current_range = Some(value..(value + 1));
2625            if prev_range.is_some() {
2626                return prev_range;
2627            }
2628        } else {
2629            return current_range.take();
2630        }
2631    })
2632}
2633
2634pub fn char_kind(c: char) -> CharKind {
2635    if c.is_whitespace() {
2636        CharKind::Whitespace
2637    } else if c.is_alphanumeric() || c == '_' {
2638        CharKind::Word
2639    } else {
2640        CharKind::Punctuation
2641    }
2642}