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