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