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