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