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