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