buffer.rs

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