buffer.rs

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