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