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