lsp_store.rs

   1use crate::{
   2    buffer_store::{BufferStore, BufferStoreEvent},
   3    environment::ProjectEnvironment,
   4    lsp_command::{self, *},
   5    lsp_ext_command,
   6    prettier_store::{self, PrettierStore, PrettierStoreEvent},
   7    project_settings::{LspSettings, ProjectSettings},
   8    relativize_path, resolve_path,
   9    worktree_store::{WorktreeStore, WorktreeStoreEvent},
  10    yarn::YarnPathStore,
  11    CodeAction, Completion, CoreCompletion, Hover, InlayHint, Item as _, ProjectPath,
  12    ProjectTransaction, ResolveState, Symbol,
  13};
  14use anyhow::{anyhow, Context as _, Result};
  15use async_trait::async_trait;
  16use client::{proto, TypedEnvelope};
  17use collections::{btree_map, BTreeMap, HashMap, HashSet};
  18use futures::{
  19    future::{join_all, BoxFuture, Shared},
  20    select,
  21    stream::FuturesUnordered,
  22    Future, FutureExt, StreamExt,
  23};
  24use globset::{Glob, GlobSet, GlobSetBuilder};
  25use gpui::{
  26    AppContext, AsyncAppContext, Context, Entity, EventEmitter, Model, ModelContext, PromptLevel,
  27    Task, WeakModel,
  28};
  29use http_client::{AsyncBody, HttpClient, Request, Response, Uri};
  30use language::{
  31    language_settings::{
  32        all_language_settings, language_settings, AllLanguageSettings, LanguageSettings,
  33    },
  34    markdown, point_to_lsp, prepare_completion_documentation,
  35    proto::{deserialize_anchor, deserialize_version, serialize_anchor, serialize_version},
  36    range_from_lsp, Bias, Buffer, BufferSnapshot, CachedLspAdapter, CodeLabel, Diagnostic,
  37    DiagnosticEntry, DiagnosticSet, Documentation, File as _, Language, LanguageConfig,
  38    LanguageMatcher, LanguageName, LanguageRegistry, LanguageServerName, LocalFile, LspAdapter,
  39    LspAdapterDelegate, Patch, PendingLanguageServer, PointUtf16, TextBufferSnapshot, ToOffset,
  40    ToPointUtf16, Transaction, Unclipped,
  41};
  42use lsp::{
  43    CodeActionKind, CompletionContext, DiagnosticSeverity, DiagnosticTag,
  44    DidChangeWatchedFilesRegistrationOptions, Edit, FileSystemWatcher, InsertTextFormat,
  45    LanguageServer, LanguageServerBinary, LanguageServerId, LspRequestFuture, MessageActionItem,
  46    MessageType, OneOf, ServerHealthStatus, ServerStatus, SymbolKind, TextEdit, Url,
  47    WorkDoneProgressCancelParams, WorkspaceFolder,
  48};
  49use parking_lot::{Mutex, RwLock};
  50use postage::watch;
  51use rand::prelude::*;
  52
  53use rpc::AnyProtoClient;
  54use serde::Serialize;
  55use settings::{Settings, SettingsLocation, SettingsStore};
  56use sha2::{Digest, Sha256};
  57use similar::{ChangeTag, TextDiff};
  58use smol::channel::Sender;
  59use snippet::Snippet;
  60use std::{
  61    any::Any,
  62    cmp::Ordering,
  63    convert::TryInto,
  64    ffi::OsStr,
  65    iter, mem,
  66    ops::{ControlFlow, Range},
  67    path::{self, Path, PathBuf},
  68    process::Stdio,
  69    str,
  70    sync::{atomic::Ordering::SeqCst, Arc},
  71    time::{Duration, Instant},
  72};
  73use text::{Anchor, BufferId, LineEnding};
  74use util::{
  75    debug_panic, defer, maybe, merge_json_value_into, post_inc, ResultExt, TryFutureExt as _,
  76};
  77
  78pub use fs::*;
  79pub use language::Location;
  80#[cfg(any(test, feature = "test-support"))]
  81pub use prettier::FORMAT_SUFFIX as TEST_PRETTIER_FORMAT_SUFFIX;
  82pub use worktree::{
  83    Entry, EntryKind, File, LocalWorktree, PathChange, ProjectEntryId, RepositoryEntry,
  84    UpdatedEntriesSet, UpdatedGitRepositoriesSet, Worktree, WorktreeId, WorktreeSettings,
  85    FS_WATCH_LATENCY,
  86};
  87
  88const MAX_SERVER_REINSTALL_ATTEMPT_COUNT: u64 = 4;
  89const SERVER_REINSTALL_DEBOUNCE_TIMEOUT: Duration = Duration::from_secs(1);
  90const SERVER_LAUNCHING_BEFORE_SHUTDOWN_TIMEOUT: Duration = Duration::from_secs(5);
  91pub const SERVER_PROGRESS_THROTTLE_TIMEOUT: Duration = Duration::from_millis(100);
  92
  93pub struct LocalLspStore {
  94    http_client: Option<Arc<dyn HttpClient>>,
  95    environment: Model<ProjectEnvironment>,
  96    fs: Arc<dyn Fs>,
  97    yarn: Model<YarnPathStore>,
  98    pub language_servers: HashMap<LanguageServerId, LanguageServerState>,
  99    last_workspace_edits_by_language_server: HashMap<LanguageServerId, ProjectTransaction>,
 100    language_server_watched_paths: HashMap<LanguageServerId, Model<LanguageServerWatchedPaths>>,
 101    language_server_watcher_registrations:
 102        HashMap<LanguageServerId, HashMap<String, Vec<FileSystemWatcher>>>,
 103    supplementary_language_servers:
 104        HashMap<LanguageServerId, (LanguageServerName, Arc<LanguageServer>)>,
 105    prettier_store: Model<PrettierStore>,
 106    current_lsp_settings: HashMap<Arc<str>, LspSettings>,
 107    _subscription: gpui::Subscription,
 108}
 109
 110impl LocalLspStore {
 111    fn shutdown_language_servers(
 112        &mut self,
 113        _cx: &mut ModelContext<LspStore>,
 114    ) -> impl Future<Output = ()> {
 115        let shutdown_futures = self
 116            .language_servers
 117            .drain()
 118            .map(|(_, server_state)| async {
 119                use LanguageServerState::*;
 120                match server_state {
 121                    Running { server, .. } => server.shutdown()?.await,
 122                    Starting(task) => task.await?.shutdown()?.await,
 123                }
 124            })
 125            .collect::<Vec<_>>();
 126
 127        async move {
 128            futures::future::join_all(shutdown_futures).await;
 129        }
 130    }
 131}
 132
 133pub struct RemoteLspStore {
 134    upstream_client: AnyProtoClient,
 135}
 136
 137impl RemoteLspStore {}
 138
 139pub struct SshLspStore {
 140    upstream_client: AnyProtoClient,
 141    current_lsp_settings: HashMap<Arc<str>, LspSettings>,
 142}
 143
 144#[allow(clippy::large_enum_variant)]
 145pub enum LspStoreMode {
 146    Local(LocalLspStore),   // ssh host and collab host
 147    Remote(RemoteLspStore), // collab guest
 148    Ssh(SshLspStore),       // ssh client
 149}
 150
 151impl LspStoreMode {
 152    fn is_local(&self) -> bool {
 153        matches!(self, LspStoreMode::Local(_))
 154    }
 155
 156    fn is_ssh(&self) -> bool {
 157        matches!(self, LspStoreMode::Ssh(_))
 158    }
 159
 160    fn is_remote(&self) -> bool {
 161        matches!(self, LspStoreMode::Remote(_))
 162    }
 163}
 164
 165pub struct LspStore {
 166    mode: LspStoreMode,
 167    downstream_client: Option<AnyProtoClient>,
 168    project_id: u64,
 169    nonce: u128,
 170    buffer_store: Model<BufferStore>,
 171    worktree_store: Model<WorktreeStore>,
 172    buffer_snapshots: HashMap<BufferId, HashMap<LanguageServerId, Vec<LspBufferSnapshot>>>, // buffer_id -> server_id -> vec of snapshots
 173    pub languages: Arc<LanguageRegistry>,
 174    language_server_ids: HashMap<(WorktreeId, LanguageServerName), LanguageServerId>,
 175    pub language_server_statuses: BTreeMap<LanguageServerId, LanguageServerStatus>,
 176    active_entry: Option<ProjectEntryId>,
 177    _maintain_workspace_config: Task<Result<()>>,
 178    _maintain_buffer_languages: Task<()>,
 179    next_diagnostic_group_id: usize,
 180    diagnostic_summaries:
 181        HashMap<WorktreeId, HashMap<Arc<Path>, HashMap<LanguageServerId, DiagnosticSummary>>>,
 182    diagnostics: HashMap<
 183        WorktreeId,
 184        HashMap<
 185            Arc<Path>,
 186            Vec<(
 187                LanguageServerId,
 188                Vec<DiagnosticEntry<Unclipped<PointUtf16>>>,
 189            )>,
 190        >,
 191    >,
 192}
 193
 194pub enum LspStoreEvent {
 195    LanguageServerAdded(LanguageServerId),
 196    LanguageServerRemoved(LanguageServerId),
 197    LanguageServerUpdate {
 198        language_server_id: LanguageServerId,
 199        message: proto::update_language_server::Variant,
 200    },
 201    LanguageServerLog(LanguageServerId, LanguageServerLogType, String),
 202    LanguageServerPrompt(LanguageServerPromptRequest),
 203    LanguageDetected {
 204        buffer: Model<Buffer>,
 205        new_language: Option<Arc<Language>>,
 206    },
 207    Notification(String),
 208    RefreshInlayHints,
 209    DiagnosticsUpdated {
 210        language_server_id: LanguageServerId,
 211        path: ProjectPath,
 212    },
 213    DiskBasedDiagnosticsStarted {
 214        language_server_id: LanguageServerId,
 215    },
 216    DiskBasedDiagnosticsFinished {
 217        language_server_id: LanguageServerId,
 218    },
 219    SnippetEdit {
 220        buffer_id: BufferId,
 221        edits: Vec<(lsp::Range, Snippet)>,
 222        most_recent_edit: clock::Lamport,
 223    },
 224    StartFormattingLocalBuffer(BufferId),
 225    FinishFormattingLocalBuffer(BufferId),
 226}
 227
 228#[derive(Clone, Debug, Serialize)]
 229pub struct LanguageServerStatus {
 230    pub name: String,
 231    pub pending_work: BTreeMap<String, LanguageServerProgress>,
 232    pub has_pending_diagnostic_updates: bool,
 233    progress_tokens: HashSet<String>,
 234}
 235
 236#[derive(Clone, Debug)]
 237struct CoreSymbol {
 238    pub language_server_name: LanguageServerName,
 239    pub source_worktree_id: WorktreeId,
 240    pub path: ProjectPath,
 241    pub name: String,
 242    pub kind: lsp::SymbolKind,
 243    pub range: Range<Unclipped<PointUtf16>>,
 244    pub signature: [u8; 32],
 245}
 246
 247impl LspStore {
 248    pub fn init(client: &AnyProtoClient) {
 249        client.add_model_request_handler(Self::handle_multi_lsp_query);
 250        client.add_model_request_handler(Self::handle_restart_language_servers);
 251        client.add_model_message_handler(Self::handle_start_language_server);
 252        client.add_model_message_handler(Self::handle_update_language_server);
 253        client.add_model_message_handler(Self::handle_update_diagnostic_summary);
 254        client.add_model_request_handler(Self::handle_resolve_completion_documentation);
 255        client.add_model_request_handler(Self::handle_apply_code_action);
 256        client.add_model_request_handler(Self::handle_inlay_hints);
 257        client.add_model_request_handler(Self::handle_get_project_symbols);
 258        client.add_model_request_handler(Self::handle_resolve_inlay_hint);
 259        client.add_model_request_handler(Self::handle_open_buffer_for_symbol);
 260        client.add_model_request_handler(Self::handle_refresh_inlay_hints);
 261        client.add_model_request_handler(Self::handle_on_type_formatting);
 262        client.add_model_request_handler(Self::handle_apply_additional_edits_for_completion);
 263        client.add_model_request_handler(Self::handle_lsp_command::<GetCodeActions>);
 264        client.add_model_request_handler(Self::handle_lsp_command::<GetCompletions>);
 265        client.add_model_request_handler(Self::handle_lsp_command::<GetHover>);
 266        client.add_model_request_handler(Self::handle_lsp_command::<GetDefinition>);
 267        client.add_model_request_handler(Self::handle_lsp_command::<GetDeclaration>);
 268        client.add_model_request_handler(Self::handle_lsp_command::<GetTypeDefinition>);
 269        client.add_model_request_handler(Self::handle_lsp_command::<GetDocumentHighlights>);
 270        client.add_model_request_handler(Self::handle_lsp_command::<GetReferences>);
 271        client.add_model_request_handler(Self::handle_lsp_command::<PrepareRename>);
 272        client.add_model_request_handler(Self::handle_lsp_command::<PerformRename>);
 273        client.add_model_request_handler(Self::handle_lsp_command::<lsp_ext_command::ExpandMacro>);
 274        client.add_model_request_handler(Self::handle_lsp_command::<LinkedEditingRange>);
 275    }
 276
 277    pub fn as_remote(&self) -> Option<&RemoteLspStore> {
 278        match &self.mode {
 279            LspStoreMode::Remote(remote_lsp_store) => Some(remote_lsp_store),
 280            _ => None,
 281        }
 282    }
 283
 284    pub fn as_ssh(&self) -> Option<&SshLspStore> {
 285        match &self.mode {
 286            LspStoreMode::Ssh(ssh_lsp_store) => Some(ssh_lsp_store),
 287            _ => None,
 288        }
 289    }
 290
 291    pub fn as_local(&self) -> Option<&LocalLspStore> {
 292        match &self.mode {
 293            LspStoreMode::Local(local_lsp_store) => Some(local_lsp_store),
 294            _ => None,
 295        }
 296    }
 297
 298    pub fn as_local_mut(&mut self) -> Option<&mut LocalLspStore> {
 299        match &mut self.mode {
 300            LspStoreMode::Local(local_lsp_store) => Some(local_lsp_store),
 301            _ => None,
 302        }
 303    }
 304
 305    pub fn upstream_client(&self) -> Option<AnyProtoClient> {
 306        match &self.mode {
 307            LspStoreMode::Ssh(SshLspStore {
 308                upstream_client, ..
 309            })
 310            | LspStoreMode::Remote(RemoteLspStore {
 311                upstream_client, ..
 312            }) => Some(upstream_client.clone()),
 313            LspStoreMode::Local(_) => None,
 314        }
 315    }
 316
 317    pub fn swap_current_lsp_settings(
 318        &mut self,
 319        new_settings: HashMap<Arc<str>, LspSettings>,
 320    ) -> Option<HashMap<Arc<str>, LspSettings>> {
 321        match &mut self.mode {
 322            LspStoreMode::Ssh(SshLspStore {
 323                current_lsp_settings,
 324                ..
 325            })
 326            | LspStoreMode::Local(LocalLspStore {
 327                current_lsp_settings,
 328                ..
 329            }) => {
 330                let ret = mem::take(current_lsp_settings);
 331                *current_lsp_settings = new_settings;
 332                Some(ret)
 333            }
 334            LspStoreMode::Remote(_) => None,
 335        }
 336    }
 337
 338    #[allow(clippy::too_many_arguments)]
 339    pub fn new_local(
 340        buffer_store: Model<BufferStore>,
 341        worktree_store: Model<WorktreeStore>,
 342        prettier_store: Model<PrettierStore>,
 343        environment: Model<ProjectEnvironment>,
 344        languages: Arc<LanguageRegistry>,
 345        http_client: Option<Arc<dyn HttpClient>>,
 346        fs: Arc<dyn Fs>,
 347        cx: &mut ModelContext<Self>,
 348    ) -> Self {
 349        let yarn = YarnPathStore::new(fs.clone(), cx);
 350        cx.subscribe(&buffer_store, Self::on_buffer_store_event)
 351            .detach();
 352        cx.subscribe(&worktree_store, Self::on_worktree_store_event)
 353            .detach();
 354        cx.subscribe(&prettier_store, Self::on_prettier_store_event)
 355            .detach();
 356        cx.observe_global::<SettingsStore>(Self::on_settings_changed)
 357            .detach();
 358
 359        Self {
 360            mode: LspStoreMode::Local(LocalLspStore {
 361                supplementary_language_servers: Default::default(),
 362                language_servers: Default::default(),
 363                last_workspace_edits_by_language_server: Default::default(),
 364                language_server_watched_paths: Default::default(),
 365                language_server_watcher_registrations: Default::default(),
 366                current_lsp_settings: ProjectSettings::get_global(cx).lsp.clone(),
 367                prettier_store,
 368                environment,
 369                http_client,
 370                fs,
 371                yarn,
 372                _subscription: cx.on_app_quit(|this, cx| {
 373                    this.as_local_mut().unwrap().shutdown_language_servers(cx)
 374                }),
 375            }),
 376            downstream_client: None,
 377            project_id: 0,
 378            buffer_store,
 379            worktree_store,
 380            languages: languages.clone(),
 381            language_server_ids: Default::default(),
 382            language_server_statuses: Default::default(),
 383            nonce: StdRng::from_entropy().gen(),
 384            buffer_snapshots: Default::default(),
 385            next_diagnostic_group_id: Default::default(),
 386            diagnostic_summaries: Default::default(),
 387            diagnostics: Default::default(),
 388            active_entry: None,
 389            _maintain_workspace_config: Self::maintain_workspace_config(cx),
 390            _maintain_buffer_languages: Self::maintain_buffer_languages(languages.clone(), cx),
 391        }
 392    }
 393
 394    fn send_lsp_proto_request<R: LspCommand>(
 395        &self,
 396        buffer: Model<Buffer>,
 397        client: AnyProtoClient,
 398        request: R,
 399        cx: &mut ModelContext<'_, LspStore>,
 400    ) -> Task<anyhow::Result<<R as LspCommand>::Response>> {
 401        let message = request.to_proto(self.project_id, buffer.read(cx));
 402        cx.spawn(move |this, cx| async move {
 403            let response = client.request(message).await?;
 404            let this = this.upgrade().context("project dropped")?;
 405            request
 406                .response_from_proto(response, this, buffer, cx)
 407                .await
 408        })
 409    }
 410
 411    pub fn new_ssh(
 412        buffer_store: Model<BufferStore>,
 413        worktree_store: Model<WorktreeStore>,
 414        languages: Arc<LanguageRegistry>,
 415        upstream_client: AnyProtoClient,
 416        project_id: u64,
 417        cx: &mut ModelContext<Self>,
 418    ) -> Self {
 419        cx.subscribe(&buffer_store, Self::on_buffer_store_event)
 420            .detach();
 421        cx.subscribe(&worktree_store, Self::on_worktree_store_event)
 422            .detach();
 423        cx.observe_global::<SettingsStore>(Self::on_settings_changed)
 424            .detach();
 425
 426        Self {
 427            mode: LspStoreMode::Ssh(SshLspStore {
 428                upstream_client,
 429                current_lsp_settings: Default::default(),
 430            }),
 431            downstream_client: None,
 432            project_id,
 433            buffer_store,
 434            worktree_store,
 435            languages: languages.clone(),
 436            language_server_ids: Default::default(),
 437            language_server_statuses: Default::default(),
 438            nonce: StdRng::from_entropy().gen(),
 439            buffer_snapshots: Default::default(),
 440            next_diagnostic_group_id: Default::default(),
 441            diagnostic_summaries: Default::default(),
 442
 443            diagnostics: Default::default(),
 444            active_entry: None,
 445            _maintain_workspace_config: Self::maintain_workspace_config(cx),
 446            _maintain_buffer_languages: Self::maintain_buffer_languages(languages.clone(), cx),
 447        }
 448    }
 449
 450    pub fn new_remote(
 451        buffer_store: Model<BufferStore>,
 452        worktree_store: Model<WorktreeStore>,
 453        languages: Arc<LanguageRegistry>,
 454        upstream_client: AnyProtoClient,
 455        project_id: u64,
 456        cx: &mut ModelContext<Self>,
 457    ) -> Self {
 458        cx.subscribe(&buffer_store, Self::on_buffer_store_event)
 459            .detach();
 460        cx.subscribe(&worktree_store, Self::on_worktree_store_event)
 461            .detach();
 462
 463        Self {
 464            mode: LspStoreMode::Remote(RemoteLspStore { upstream_client }),
 465            downstream_client: None,
 466            project_id,
 467            buffer_store,
 468            worktree_store,
 469            languages: languages.clone(),
 470            language_server_ids: Default::default(),
 471            language_server_statuses: Default::default(),
 472            nonce: StdRng::from_entropy().gen(),
 473            buffer_snapshots: Default::default(),
 474            next_diagnostic_group_id: Default::default(),
 475            diagnostic_summaries: Default::default(),
 476            diagnostics: Default::default(),
 477            active_entry: None,
 478            _maintain_workspace_config: Self::maintain_workspace_config(cx),
 479            _maintain_buffer_languages: Self::maintain_buffer_languages(languages.clone(), cx),
 480        }
 481    }
 482
 483    fn worktree_for_id(
 484        &self,
 485        worktree_id: WorktreeId,
 486        cx: &ModelContext<Self>,
 487    ) -> Result<Model<Worktree>> {
 488        self.worktree_store
 489            .read(cx)
 490            .worktree_for_id(worktree_id, cx)
 491            .ok_or_else(|| anyhow!("worktree not found"))
 492    }
 493
 494    fn on_buffer_store_event(
 495        &mut self,
 496        _: Model<BufferStore>,
 497        event: &BufferStoreEvent,
 498        cx: &mut ModelContext<Self>,
 499    ) {
 500        match event {
 501            BufferStoreEvent::BufferAdded(buffer) => {
 502                self.register_buffer(buffer, cx).log_err();
 503            }
 504            BufferStoreEvent::BufferChangedFilePath { buffer, old_file } => {
 505                if let Some(old_file) = File::from_dyn(old_file.as_ref()) {
 506                    self.unregister_buffer_from_language_servers(buffer, old_file, cx);
 507                }
 508
 509                self.register_buffer_with_language_servers(buffer, cx);
 510            }
 511            BufferStoreEvent::BufferDropped(_) => {}
 512        }
 513    }
 514
 515    fn on_worktree_store_event(
 516        &mut self,
 517        _: Model<WorktreeStore>,
 518        event: &WorktreeStoreEvent,
 519        cx: &mut ModelContext<Self>,
 520    ) {
 521        match event {
 522            WorktreeStoreEvent::WorktreeAdded(worktree) => {
 523                if !worktree.read(cx).is_local() {
 524                    return;
 525                }
 526                cx.subscribe(worktree, |this, worktree, event, cx| match event {
 527                    worktree::Event::UpdatedEntries(changes) => {
 528                        this.update_local_worktree_language_servers(&worktree, changes, cx);
 529                    }
 530                    worktree::Event::UpdatedGitRepositories(_)
 531                    | worktree::Event::DeletedEntry(_) => {}
 532                })
 533                .detach()
 534            }
 535            WorktreeStoreEvent::WorktreeRemoved(_, id) => self.remove_worktree(*id, cx),
 536            WorktreeStoreEvent::WorktreeOrderChanged => {}
 537        }
 538    }
 539
 540    fn on_prettier_store_event(
 541        &mut self,
 542        _: Model<PrettierStore>,
 543        event: &PrettierStoreEvent,
 544        cx: &mut ModelContext<Self>,
 545    ) {
 546        match event {
 547            PrettierStoreEvent::LanguageServerRemoved(prettier_server_id) => {
 548                self.unregister_supplementary_language_server(*prettier_server_id, cx);
 549            }
 550            PrettierStoreEvent::LanguageServerAdded {
 551                new_server_id,
 552                name,
 553                prettier_server,
 554            } => {
 555                self.register_supplementary_language_server(
 556                    *new_server_id,
 557                    name.clone(),
 558                    prettier_server.clone(),
 559                    cx,
 560                );
 561            }
 562        }
 563    }
 564
 565    // todo!
 566    pub fn prettier_store(&self) -> Option<Model<PrettierStore>> {
 567        self.as_local().map(|local| local.prettier_store.clone())
 568    }
 569
 570    fn on_buffer_event(
 571        &mut self,
 572        buffer: Model<Buffer>,
 573        event: &language::BufferEvent,
 574        cx: &mut ModelContext<Self>,
 575    ) {
 576        match event {
 577            language::BufferEvent::Edited { .. } => {
 578                self.on_buffer_edited(buffer, cx);
 579            }
 580
 581            language::BufferEvent::Saved => {
 582                self.on_buffer_saved(buffer, cx);
 583            }
 584
 585            _ => {}
 586        }
 587    }
 588
 589    fn register_buffer(
 590        &mut self,
 591        buffer: &Model<Buffer>,
 592        cx: &mut ModelContext<Self>,
 593    ) -> Result<()> {
 594        buffer.update(cx, |buffer, _| {
 595            buffer.set_language_registry(self.languages.clone())
 596        });
 597
 598        cx.subscribe(buffer, |this, buffer, event, cx| {
 599            this.on_buffer_event(buffer, event, cx);
 600        })
 601        .detach();
 602
 603        self.register_buffer_with_language_servers(buffer, cx);
 604        cx.observe_release(buffer, |this, buffer, cx| {
 605            if let Some(file) = File::from_dyn(buffer.file()) {
 606                if file.is_local() {
 607                    let uri = lsp::Url::from_file_path(file.abs_path(cx)).unwrap();
 608                    for server in this.language_servers_for_buffer(buffer, cx) {
 609                        server
 610                            .1
 611                            .notify::<lsp::notification::DidCloseTextDocument>(
 612                                lsp::DidCloseTextDocumentParams {
 613                                    text_document: lsp::TextDocumentIdentifier::new(uri.clone()),
 614                                },
 615                            )
 616                            .log_err();
 617                    }
 618                }
 619            }
 620        })
 621        .detach();
 622
 623        Ok(())
 624    }
 625
 626    fn maintain_buffer_languages(
 627        languages: Arc<LanguageRegistry>,
 628        cx: &mut ModelContext<Self>,
 629    ) -> Task<()> {
 630        let mut subscription = languages.subscribe();
 631        let mut prev_reload_count = languages.reload_count();
 632        cx.spawn(move |this, mut cx| async move {
 633            while let Some(()) = subscription.next().await {
 634                if let Some(this) = this.upgrade() {
 635                    // If the language registry has been reloaded, then remove and
 636                    // re-assign the languages on all open buffers.
 637                    let reload_count = languages.reload_count();
 638                    if reload_count > prev_reload_count {
 639                        prev_reload_count = reload_count;
 640                        this.update(&mut cx, |this, cx| {
 641                            this.buffer_store.clone().update(cx, |buffer_store, cx| {
 642                                for buffer in buffer_store.buffers() {
 643                                    if let Some(f) = File::from_dyn(buffer.read(cx).file()).cloned()
 644                                    {
 645                                        this.unregister_buffer_from_language_servers(
 646                                            &buffer, &f, cx,
 647                                        );
 648                                        buffer
 649                                            .update(cx, |buffer, cx| buffer.set_language(None, cx));
 650                                    }
 651                                }
 652                            });
 653                        })
 654                        .ok();
 655                    }
 656
 657                    this.update(&mut cx, |this, cx| {
 658                        let mut plain_text_buffers = Vec::new();
 659                        let mut buffers_with_unknown_injections = Vec::new();
 660                        for handle in this.buffer_store.read(cx).buffers() {
 661                            let buffer = handle.read(cx);
 662                            if buffer.language().is_none()
 663                                || buffer.language() == Some(&*language::PLAIN_TEXT)
 664                            {
 665                                plain_text_buffers.push(handle);
 666                            } else if buffer.contains_unknown_injections() {
 667                                buffers_with_unknown_injections.push(handle);
 668                            }
 669                        }
 670                        for buffer in plain_text_buffers {
 671                            this.register_buffer_with_language_servers(&buffer, cx);
 672                        }
 673
 674                        for buffer in buffers_with_unknown_injections {
 675                            buffer.update(cx, |buffer, cx| buffer.reparse(cx));
 676                        }
 677                    })
 678                    .ok();
 679                }
 680            }
 681        })
 682    }
 683
 684    fn detect_language_for_buffer(
 685        &mut self,
 686        buffer_handle: &Model<Buffer>,
 687        cx: &mut ModelContext<Self>,
 688    ) -> Option<language::AvailableLanguage> {
 689        // If the buffer has a language, set it and start the language server if we haven't already.
 690        let buffer = buffer_handle.read(cx);
 691        let file = buffer.file()?;
 692
 693        let content = buffer.as_rope();
 694        let available_language = self.languages.language_for_file(file, Some(content), cx);
 695        if let Some(available_language) = &available_language {
 696            if let Some(Ok(Ok(new_language))) = self
 697                .languages
 698                .load_language(available_language)
 699                .now_or_never()
 700            {
 701                self.set_language_for_buffer(buffer_handle, new_language, cx);
 702            }
 703        } else {
 704            cx.emit(LspStoreEvent::LanguageDetected {
 705                buffer: buffer_handle.clone(),
 706                new_language: None,
 707            });
 708        }
 709
 710        available_language
 711    }
 712
 713    pub fn set_language_for_buffer(
 714        &mut self,
 715        buffer: &Model<Buffer>,
 716        new_language: Arc<Language>,
 717        cx: &mut ModelContext<Self>,
 718    ) {
 719        buffer.update(cx, |buffer, cx| {
 720            if buffer.language().map_or(true, |old_language| {
 721                !Arc::ptr_eq(old_language, &new_language)
 722            }) {
 723                buffer.set_language(Some(new_language.clone()), cx);
 724            }
 725        });
 726
 727        let buffer_file = buffer.read(cx).file().cloned();
 728        let settings = language_settings(Some(&new_language), buffer_file.as_ref(), cx).clone();
 729        let buffer_file = File::from_dyn(buffer_file.as_ref());
 730
 731        let worktree_id = if let Some(file) = buffer_file {
 732            let worktree = file.worktree.clone();
 733            self.start_language_servers(&worktree, new_language.name(), cx);
 734
 735            Some(worktree.read(cx).id())
 736        } else {
 737            None
 738        };
 739
 740        if let Some(prettier_plugins) = prettier_store::prettier_plugins_for_language(&settings) {
 741            let prettier_store = self.as_local().map(|s| s.prettier_store.clone());
 742            if let Some(prettier_store) = prettier_store {
 743                prettier_store.update(cx, |prettier_store, cx| {
 744                    prettier_store.install_default_prettier(
 745                        worktree_id,
 746                        prettier_plugins.iter().map(|s| Arc::from(s.as_str())),
 747                        cx,
 748                    )
 749                })
 750            }
 751        }
 752
 753        cx.emit(LspStoreEvent::LanguageDetected {
 754            buffer: buffer.clone(),
 755            new_language: Some(new_language),
 756        })
 757    }
 758
 759    pub fn buffer_store(&self) -> Model<BufferStore> {
 760        self.buffer_store.clone()
 761    }
 762
 763    pub fn set_active_entry(&mut self, active_entry: Option<ProjectEntryId>) {
 764        self.active_entry = active_entry;
 765    }
 766
 767    pub(crate) fn send_diagnostic_summaries(
 768        &self,
 769        worktree: &mut Worktree,
 770    ) -> Result<(), anyhow::Error> {
 771        if let Some(client) = self.downstream_client.clone() {
 772            if let Some(summaries) = self.diagnostic_summaries.get(&worktree.id()) {
 773                for (path, summaries) in summaries {
 774                    for (&server_id, summary) in summaries {
 775                        client.send(proto::UpdateDiagnosticSummary {
 776                            project_id: self.project_id,
 777                            worktree_id: worktree.id().to_proto(),
 778                            summary: Some(summary.to_proto(server_id, path)),
 779                        })?;
 780                    }
 781                }
 782            }
 783        }
 784        Ok(())
 785    }
 786
 787    pub fn request_lsp<R: LspCommand>(
 788        &self,
 789        buffer_handle: Model<Buffer>,
 790        server: LanguageServerToQuery,
 791        request: R,
 792        cx: &mut ModelContext<Self>,
 793    ) -> Task<Result<R::Response>>
 794    where
 795        <R::LspRequest as lsp::request::Request>::Result: Send,
 796        <R::LspRequest as lsp::request::Request>::Params: Send,
 797    {
 798        let buffer = buffer_handle.read(cx);
 799
 800        if let Some(upstream_client) = self.upstream_client() {
 801            return self.send_lsp_proto_request(buffer_handle, upstream_client, request, cx);
 802        }
 803
 804        let language_server = match server {
 805            LanguageServerToQuery::Primary => {
 806                match self.primary_language_server_for_buffer(buffer, cx) {
 807                    Some((_, server)) => Some(Arc::clone(server)),
 808                    None => return Task::ready(Ok(Default::default())),
 809                }
 810            }
 811            LanguageServerToQuery::Other(id) => self
 812                .language_server_for_buffer(buffer, id, cx)
 813                .map(|(_, server)| Arc::clone(server)),
 814        };
 815        let file = File::from_dyn(buffer.file()).and_then(File::as_local);
 816        if let (Some(file), Some(language_server)) = (file, language_server) {
 817            let lsp_params = request.to_lsp(&file.abs_path(cx), buffer, &language_server, cx);
 818            let status = request.status();
 819            return cx.spawn(move |this, cx| async move {
 820                if !request.check_capabilities(language_server.adapter_server_capabilities()) {
 821                    return Ok(Default::default());
 822                }
 823
 824                let lsp_request = language_server.request::<R::LspRequest>(lsp_params);
 825
 826                let id = lsp_request.id();
 827                let _cleanup = if status.is_some() {
 828                    cx.update(|cx| {
 829                        this.update(cx, |this, cx| {
 830                            this.on_lsp_work_start(
 831                                language_server.server_id(),
 832                                id.to_string(),
 833                                LanguageServerProgress {
 834                                    is_disk_based_diagnostics_progress: false,
 835                                    is_cancellable: false,
 836                                    title: None,
 837                                    message: status.clone(),
 838                                    percentage: None,
 839                                    last_update_at: cx.background_executor().now(),
 840                                },
 841                                cx,
 842                            );
 843                        })
 844                    })
 845                    .log_err();
 846
 847                    Some(defer(|| {
 848                        cx.update(|cx| {
 849                            this.update(cx, |this, cx| {
 850                                this.on_lsp_work_end(
 851                                    language_server.server_id(),
 852                                    id.to_string(),
 853                                    cx,
 854                                );
 855                            })
 856                        })
 857                        .log_err();
 858                    }))
 859                } else {
 860                    None
 861                };
 862
 863                let result = lsp_request.await;
 864
 865                let response = result.map_err(|err| {
 866                    log::warn!(
 867                        "Generic lsp request to {} failed: {}",
 868                        language_server.name(),
 869                        err
 870                    );
 871                    err
 872                })?;
 873
 874                request
 875                    .response_from_lsp(
 876                        response,
 877                        this.upgrade().ok_or_else(|| anyhow!("no app context"))?,
 878                        buffer_handle,
 879                        language_server.server_id(),
 880                        cx.clone(),
 881                    )
 882                    .await
 883            });
 884        }
 885
 886        Task::ready(Ok(Default::default()))
 887    }
 888
 889    fn on_settings_changed(&mut self, cx: &mut ModelContext<Self>) {
 890        let mut language_servers_to_start = Vec::new();
 891        let mut language_formatters_to_check = Vec::new();
 892        for buffer in self.buffer_store.read(cx).buffers() {
 893            let buffer = buffer.read(cx);
 894            let buffer_file = File::from_dyn(buffer.file());
 895            let buffer_language = buffer.language();
 896            let settings = language_settings(buffer_language, buffer.file(), cx);
 897            if let Some(language) = buffer_language {
 898                if settings.enable_language_server {
 899                    if let Some(file) = buffer_file {
 900                        language_servers_to_start.push((file.worktree.clone(), language.name()));
 901                    }
 902                }
 903                language_formatters_to_check
 904                    .push((buffer_file.map(|f| f.worktree_id(cx)), settings.clone()));
 905            }
 906        }
 907
 908        let mut language_servers_to_stop = Vec::new();
 909        let mut language_servers_to_restart = Vec::new();
 910        let languages = self.languages.to_vec();
 911
 912        let new_lsp_settings = ProjectSettings::get_global(cx).lsp.clone();
 913        let Some(current_lsp_settings) = self.swap_current_lsp_settings(new_lsp_settings.clone())
 914        else {
 915            return;
 916        };
 917        for (worktree_id, started_lsp_name) in self.started_language_servers() {
 918            let language = languages.iter().find_map(|l| {
 919                let adapter = self
 920                    .languages
 921                    .lsp_adapters(&l.name())
 922                    .iter()
 923                    .find(|adapter| adapter.name == started_lsp_name)?
 924                    .clone();
 925                Some((l, adapter))
 926            });
 927            if let Some((language, adapter)) = language {
 928                let worktree = self.worktree_for_id(worktree_id, cx).ok();
 929                let file = worktree.as_ref().and_then(|tree| {
 930                    tree.update(cx, |tree, cx| tree.root_file(cx).map(|f| f as _))
 931                });
 932                if !language_settings(Some(language), file.as_ref(), cx).enable_language_server {
 933                    language_servers_to_stop.push((worktree_id, started_lsp_name.clone()));
 934                } else if let Some(worktree) = worktree {
 935                    let server_name = &adapter.name.0;
 936                    match (
 937                        current_lsp_settings.get(server_name),
 938                        new_lsp_settings.get(server_name),
 939                    ) {
 940                        (None, None) => {}
 941                        (Some(_), None) | (None, Some(_)) => {
 942                            language_servers_to_restart.push((worktree, language.name()));
 943                        }
 944                        (Some(current_lsp_settings), Some(new_lsp_settings)) => {
 945                            if current_lsp_settings != new_lsp_settings {
 946                                language_servers_to_restart.push((worktree, language.name()));
 947                            }
 948                        }
 949                    }
 950                }
 951            }
 952        }
 953
 954        for (worktree_id, adapter_name) in language_servers_to_stop {
 955            self.stop_language_server(worktree_id, adapter_name, cx)
 956                .detach();
 957        }
 958
 959        if let Some(prettier_store) = self.as_local().map(|s| s.prettier_store.clone()) {
 960            prettier_store.update(cx, |prettier_store, cx| {
 961                prettier_store.on_settings_changed(language_formatters_to_check, cx)
 962            })
 963        }
 964
 965        // Start all the newly-enabled language servers.
 966        for (worktree, language) in language_servers_to_start {
 967            self.start_language_servers(&worktree, language, cx);
 968        }
 969
 970        // Restart all language servers with changed initialization options.
 971        for (worktree, language) in language_servers_to_restart {
 972            self.restart_language_servers(worktree, language, cx);
 973        }
 974
 975        cx.notify();
 976    }
 977
 978    pub async fn execute_code_actions_on_servers(
 979        this: &WeakModel<LspStore>,
 980        adapters_and_servers: &[(Arc<CachedLspAdapter>, Arc<LanguageServer>)],
 981        code_actions: Vec<lsp::CodeActionKind>,
 982        buffer: &Model<Buffer>,
 983        push_to_history: bool,
 984        project_transaction: &mut ProjectTransaction,
 985        cx: &mut AsyncAppContext,
 986    ) -> Result<(), anyhow::Error> {
 987        for (lsp_adapter, language_server) in adapters_and_servers.iter() {
 988            let code_actions = code_actions.clone();
 989
 990            let actions = this
 991                .update(cx, move |this, cx| {
 992                    let request = GetCodeActions {
 993                        range: text::Anchor::MIN..text::Anchor::MAX,
 994                        kinds: Some(code_actions),
 995                    };
 996                    let server = LanguageServerToQuery::Other(language_server.server_id());
 997                    this.request_lsp(buffer.clone(), server, request, cx)
 998                })?
 999                .await?;
1000
1001            for mut action in actions {
1002                Self::try_resolve_code_action(language_server, &mut action)
1003                    .await
1004                    .context("resolving a formatting code action")?;
1005
1006                if let Some(edit) = action.lsp_action.edit {
1007                    if edit.changes.is_none() && edit.document_changes.is_none() {
1008                        continue;
1009                    }
1010
1011                    let new = Self::deserialize_workspace_edit(
1012                        this.upgrade().ok_or_else(|| anyhow!("project dropped"))?,
1013                        edit,
1014                        push_to_history,
1015                        lsp_adapter.clone(),
1016                        language_server.clone(),
1017                        cx,
1018                    )
1019                    .await?;
1020                    project_transaction.0.extend(new.0);
1021                }
1022
1023                if let Some(command) = action.lsp_action.command {
1024                    this.update(cx, |this, _| {
1025                        if let LspStoreMode::Local(mode) = &mut this.mode {
1026                            mode.last_workspace_edits_by_language_server
1027                                .remove(&language_server.server_id());
1028                        }
1029                    })?;
1030
1031                    language_server
1032                        .request::<lsp::request::ExecuteCommand>(lsp::ExecuteCommandParams {
1033                            command: command.command,
1034                            arguments: command.arguments.unwrap_or_default(),
1035                            ..Default::default()
1036                        })
1037                        .await?;
1038
1039                    this.update(cx, |this, _| {
1040                        if let LspStoreMode::Local(mode) = &mut this.mode {
1041                            project_transaction.0.extend(
1042                                mode.last_workspace_edits_by_language_server
1043                                    .remove(&language_server.server_id())
1044                                    .unwrap_or_default()
1045                                    .0,
1046                            )
1047                        }
1048                    })?;
1049                }
1050            }
1051        }
1052
1053        Ok(())
1054    }
1055
1056    async fn try_resolve_code_action(
1057        lang_server: &LanguageServer,
1058        action: &mut CodeAction,
1059    ) -> anyhow::Result<()> {
1060        if GetCodeActions::can_resolve_actions(&lang_server.capabilities())
1061            && action.lsp_action.data.is_some()
1062            && (action.lsp_action.command.is_none() || action.lsp_action.edit.is_none())
1063        {
1064            action.lsp_action = lang_server
1065                .request::<lsp::request::CodeActionResolveRequest>(action.lsp_action.clone())
1066                .await?;
1067        }
1068
1069        anyhow::Ok(())
1070    }
1071
1072    pub fn apply_code_action(
1073        &self,
1074        buffer_handle: Model<Buffer>,
1075        mut action: CodeAction,
1076        push_to_history: bool,
1077        cx: &mut ModelContext<Self>,
1078    ) -> Task<Result<ProjectTransaction>> {
1079        if let Some(upstream_client) = self.upstream_client() {
1080            let request = proto::ApplyCodeAction {
1081                project_id: self.project_id,
1082                buffer_id: buffer_handle.read(cx).remote_id().into(),
1083                action: Some(Self::serialize_code_action(&action)),
1084            };
1085            cx.spawn(move |this, cx| async move {
1086                let response = upstream_client
1087                    .request(request)
1088                    .await?
1089                    .transaction
1090                    .ok_or_else(|| anyhow!("missing transaction"))?;
1091                BufferStore::deserialize_project_transaction(
1092                    this.read_with(&cx, |this, _| this.buffer_store.downgrade())?,
1093                    response,
1094                    push_to_history,
1095                    cx,
1096                )
1097                .await
1098            })
1099        } else {
1100            let buffer = buffer_handle.read(cx);
1101            let (lsp_adapter, lang_server) = if let Some((adapter, server)) =
1102                self.language_server_for_buffer(buffer, action.server_id, cx)
1103            {
1104                (adapter.clone(), server.clone())
1105            } else {
1106                return Task::ready(Ok(Default::default()));
1107            };
1108            cx.spawn(move |this, mut cx| async move {
1109                Self::try_resolve_code_action(&lang_server, &mut action)
1110                    .await
1111                    .context("resolving a code action")?;
1112                if let Some(edit) = action.lsp_action.edit {
1113                    if edit.changes.is_some() || edit.document_changes.is_some() {
1114                        return Self::deserialize_workspace_edit(
1115                            this.upgrade().ok_or_else(|| anyhow!("no app present"))?,
1116                            edit,
1117                            push_to_history,
1118                            lsp_adapter.clone(),
1119                            lang_server.clone(),
1120                            &mut cx,
1121                        )
1122                        .await;
1123                    }
1124                }
1125
1126                if let Some(command) = action.lsp_action.command {
1127                    this.update(&mut cx, |this, _| {
1128                        this.as_local_mut()
1129                            .unwrap()
1130                            .last_workspace_edits_by_language_server
1131                            .remove(&lang_server.server_id());
1132                    })?;
1133
1134                    let result = lang_server
1135                        .request::<lsp::request::ExecuteCommand>(lsp::ExecuteCommandParams {
1136                            command: command.command,
1137                            arguments: command.arguments.unwrap_or_default(),
1138                            ..Default::default()
1139                        })
1140                        .await;
1141
1142                    result?;
1143
1144                    return this.update(&mut cx, |this, _| {
1145                        this.as_local_mut()
1146                            .unwrap()
1147                            .last_workspace_edits_by_language_server
1148                            .remove(&lang_server.server_id())
1149                            .unwrap_or_default()
1150                    });
1151                }
1152
1153                Ok(ProjectTransaction::default())
1154            })
1155        }
1156    }
1157
1158    pub fn resolve_inlay_hint(
1159        &self,
1160        hint: InlayHint,
1161        buffer_handle: Model<Buffer>,
1162        server_id: LanguageServerId,
1163        cx: &mut ModelContext<Self>,
1164    ) -> Task<anyhow::Result<InlayHint>> {
1165        if let Some(upstream_client) = self.upstream_client() {
1166            let request = proto::ResolveInlayHint {
1167                project_id: self.project_id,
1168                buffer_id: buffer_handle.read(cx).remote_id().into(),
1169                language_server_id: server_id.0 as u64,
1170                hint: Some(InlayHints::project_to_proto_hint(hint.clone())),
1171            };
1172            cx.spawn(move |_, _| async move {
1173                let response = upstream_client
1174                    .request(request)
1175                    .await
1176                    .context("inlay hints proto request")?;
1177                match response.hint {
1178                    Some(resolved_hint) => InlayHints::proto_to_project_hint(resolved_hint)
1179                        .context("inlay hints proto resolve response conversion"),
1180                    None => Ok(hint),
1181                }
1182            })
1183        } else {
1184            let buffer = buffer_handle.read(cx);
1185            let (_, lang_server) = if let Some((adapter, server)) =
1186                self.language_server_for_buffer(buffer, server_id, cx)
1187            {
1188                (adapter.clone(), server.clone())
1189            } else {
1190                return Task::ready(Ok(hint));
1191            };
1192            if !InlayHints::can_resolve_inlays(&lang_server.capabilities()) {
1193                return Task::ready(Ok(hint));
1194            }
1195
1196            let buffer_snapshot = buffer.snapshot();
1197            cx.spawn(move |_, mut cx| async move {
1198                let resolve_task = lang_server.request::<lsp::request::InlayHintResolveRequest>(
1199                    InlayHints::project_to_lsp_hint(hint, &buffer_snapshot),
1200                );
1201                let resolved_hint = resolve_task
1202                    .await
1203                    .context("inlay hint resolve LSP request")?;
1204                let resolved_hint = InlayHints::lsp_to_project_hint(
1205                    resolved_hint,
1206                    &buffer_handle,
1207                    server_id,
1208                    ResolveState::Resolved,
1209                    false,
1210                    &mut cx,
1211                )
1212                .await?;
1213                Ok(resolved_hint)
1214            })
1215        }
1216    }
1217
1218    pub(crate) fn linked_edit(
1219        &self,
1220        buffer: &Model<Buffer>,
1221        position: Anchor,
1222        cx: &mut ModelContext<Self>,
1223    ) -> Task<Result<Vec<Range<Anchor>>>> {
1224        let snapshot = buffer.read(cx).snapshot();
1225        let scope = snapshot.language_scope_at(position);
1226        let Some(server_id) = self
1227            .language_servers_for_buffer(buffer.read(cx), cx)
1228            .filter(|(_, server)| {
1229                server
1230                    .capabilities()
1231                    .linked_editing_range_provider
1232                    .is_some()
1233            })
1234            .filter(|(adapter, _)| {
1235                scope
1236                    .as_ref()
1237                    .map(|scope| scope.language_allowed(&adapter.name))
1238                    .unwrap_or(true)
1239            })
1240            .map(|(_, server)| LanguageServerToQuery::Other(server.server_id()))
1241            .next()
1242            .or_else(|| {
1243                self.upstream_client()
1244                    .is_some()
1245                    .then_some(LanguageServerToQuery::Primary)
1246            })
1247            .filter(|_| {
1248                maybe!({
1249                    let language_name = buffer.read(cx).language_at(position)?.name();
1250                    Some(
1251                        AllLanguageSettings::get_global(cx)
1252                            .language(Some(&language_name))
1253                            .linked_edits,
1254                    )
1255                }) == Some(true)
1256            })
1257        else {
1258            return Task::ready(Ok(vec![]));
1259        };
1260
1261        self.request_lsp(
1262            buffer.clone(),
1263            server_id,
1264            LinkedEditingRange { position },
1265            cx,
1266        )
1267    }
1268
1269    fn apply_on_type_formatting(
1270        &self,
1271        buffer: Model<Buffer>,
1272        position: Anchor,
1273        trigger: String,
1274        cx: &mut ModelContext<Self>,
1275    ) -> Task<Result<Option<Transaction>>> {
1276        if let Some(client) = self.upstream_client() {
1277            let request = proto::OnTypeFormatting {
1278                project_id: self.project_id,
1279                buffer_id: buffer.read(cx).remote_id().into(),
1280                position: Some(serialize_anchor(&position)),
1281                trigger,
1282                version: serialize_version(&buffer.read(cx).version()),
1283            };
1284            cx.spawn(move |_, _| async move {
1285                client
1286                    .request(request)
1287                    .await?
1288                    .transaction
1289                    .map(language::proto::deserialize_transaction)
1290                    .transpose()
1291            })
1292        } else {
1293            cx.spawn(move |this, mut cx| async move {
1294                // Do not allow multiple concurrent formatting requests for the
1295                // same buffer.
1296                this.update(&mut cx, |_, cx| {
1297                    cx.emit(LspStoreEvent::StartFormattingLocalBuffer(
1298                        buffer.read(cx).remote_id(),
1299                    ));
1300                })?;
1301
1302                let _cleanup = defer({
1303                    let this = this.clone();
1304                    let mut cx = cx.clone();
1305                    let closure_buffer = buffer.clone();
1306                    move || {
1307                        this.update(&mut cx, |_, cx| {
1308                            cx.emit(LspStoreEvent::FinishFormattingLocalBuffer(
1309                                closure_buffer.read(cx).remote_id(),
1310                            ))
1311                        })
1312                        .ok();
1313                    }
1314                });
1315
1316                buffer
1317                    .update(&mut cx, |buffer, _| {
1318                        buffer.wait_for_edits(Some(position.timestamp))
1319                    })?
1320                    .await?;
1321                this.update(&mut cx, |this, cx| {
1322                    let position = position.to_point_utf16(buffer.read(cx));
1323                    this.on_type_format(buffer, position, trigger, false, cx)
1324                })?
1325                .await
1326            })
1327        }
1328    }
1329
1330    pub fn on_type_format<T: ToPointUtf16>(
1331        &mut self,
1332        buffer: Model<Buffer>,
1333        position: T,
1334        trigger: String,
1335        push_to_history: bool,
1336        cx: &mut ModelContext<Self>,
1337    ) -> Task<Result<Option<Transaction>>> {
1338        let position = position.to_point_utf16(buffer.read(cx));
1339        self.on_type_format_impl(buffer, position, trigger, push_to_history, cx)
1340    }
1341
1342    fn on_type_format_impl(
1343        &mut self,
1344        buffer: Model<Buffer>,
1345        position: PointUtf16,
1346        trigger: String,
1347        push_to_history: bool,
1348        cx: &mut ModelContext<Self>,
1349    ) -> Task<Result<Option<Transaction>>> {
1350        let options = buffer.update(cx, |buffer, cx| {
1351            lsp_command::lsp_formatting_options(language_settings(
1352                buffer.language_at(position).as_ref(),
1353                buffer.file(),
1354                cx,
1355            ))
1356        });
1357        self.request_lsp(
1358            buffer.clone(),
1359            LanguageServerToQuery::Primary,
1360            OnTypeFormatting {
1361                position,
1362                trigger,
1363                options,
1364                push_to_history,
1365            },
1366            cx,
1367        )
1368    }
1369
1370    pub async fn format_via_lsp(
1371        this: &WeakModel<Self>,
1372        buffer: &Model<Buffer>,
1373        abs_path: &Path,
1374        language_server: &Arc<LanguageServer>,
1375        settings: &LanguageSettings,
1376        cx: &mut AsyncAppContext,
1377    ) -> Result<Vec<(Range<Anchor>, String)>> {
1378        let uri = lsp::Url::from_file_path(abs_path)
1379            .map_err(|_| anyhow!("failed to convert abs path to uri"))?;
1380        let text_document = lsp::TextDocumentIdentifier::new(uri);
1381        let capabilities = &language_server.capabilities();
1382
1383        let formatting_provider = capabilities.document_formatting_provider.as_ref();
1384        let range_formatting_provider = capabilities.document_range_formatting_provider.as_ref();
1385
1386        let lsp_edits = if matches!(formatting_provider, Some(p) if *p != OneOf::Left(false)) {
1387            language_server
1388                .request::<lsp::request::Formatting>(lsp::DocumentFormattingParams {
1389                    text_document,
1390                    options: lsp_command::lsp_formatting_options(settings),
1391                    work_done_progress_params: Default::default(),
1392                })
1393                .await?
1394        } else if matches!(range_formatting_provider, Some(p) if *p != OneOf::Left(false)) {
1395            let buffer_start = lsp::Position::new(0, 0);
1396            let buffer_end = buffer.update(cx, |b, _| point_to_lsp(b.max_point_utf16()))?;
1397
1398            language_server
1399                .request::<lsp::request::RangeFormatting>(lsp::DocumentRangeFormattingParams {
1400                    text_document,
1401                    range: lsp::Range::new(buffer_start, buffer_end),
1402                    options: lsp_command::lsp_formatting_options(settings),
1403                    work_done_progress_params: Default::default(),
1404                })
1405                .await?
1406        } else {
1407            None
1408        };
1409
1410        if let Some(lsp_edits) = lsp_edits {
1411            this.update(cx, |this, cx| {
1412                this.edits_from_lsp(buffer, lsp_edits, language_server.server_id(), None, cx)
1413            })?
1414            .await
1415        } else {
1416            Ok(Vec::new())
1417        }
1418    }
1419
1420    pub fn code_actions(
1421        &mut self,
1422        buffer_handle: &Model<Buffer>,
1423        range: Range<Anchor>,
1424        cx: &mut ModelContext<Self>,
1425    ) -> Task<Vec<CodeAction>> {
1426        if let Some(upstream_client) = self.upstream_client() {
1427            let request_task = upstream_client.request(proto::MultiLspQuery {
1428                buffer_id: buffer_handle.read(cx).remote_id().into(),
1429                version: serialize_version(&buffer_handle.read(cx).version()),
1430                project_id: self.project_id,
1431                strategy: Some(proto::multi_lsp_query::Strategy::All(
1432                    proto::AllLanguageServers {},
1433                )),
1434                request: Some(proto::multi_lsp_query::Request::GetCodeActions(
1435                    GetCodeActions {
1436                        range: range.clone(),
1437                        kinds: None,
1438                    }
1439                    .to_proto(self.project_id, buffer_handle.read(cx)),
1440                )),
1441            });
1442            let buffer = buffer_handle.clone();
1443            cx.spawn(|weak_project, cx| async move {
1444                let Some(project) = weak_project.upgrade() else {
1445                    return Vec::new();
1446                };
1447                join_all(
1448                    request_task
1449                        .await
1450                        .log_err()
1451                        .map(|response| response.responses)
1452                        .unwrap_or_default()
1453                        .into_iter()
1454                        .filter_map(|lsp_response| match lsp_response.response? {
1455                            proto::lsp_response::Response::GetCodeActionsResponse(response) => {
1456                                Some(response)
1457                            }
1458                            unexpected => {
1459                                debug_panic!("Unexpected response: {unexpected:?}");
1460                                None
1461                            }
1462                        })
1463                        .map(|code_actions_response| {
1464                            let response = GetCodeActions {
1465                                range: range.clone(),
1466                                kinds: None,
1467                            }
1468                            .response_from_proto(
1469                                code_actions_response,
1470                                project.clone(),
1471                                buffer.clone(),
1472                                cx.clone(),
1473                            );
1474                            async move { response.await.log_err().unwrap_or_default() }
1475                        }),
1476                )
1477                .await
1478                .into_iter()
1479                .flatten()
1480                .collect()
1481            })
1482        } else {
1483            let all_actions_task = self.request_multiple_lsp_locally(
1484                buffer_handle,
1485                Some(range.start),
1486                GetCodeActions {
1487                    range: range.clone(),
1488                    kinds: None,
1489                },
1490                cx,
1491            );
1492            cx.spawn(|_, _| async move { all_actions_task.await.into_iter().flatten().collect() })
1493        }
1494    }
1495
1496    #[inline(never)]
1497    pub fn completions(
1498        &self,
1499        buffer: &Model<Buffer>,
1500        position: PointUtf16,
1501        context: CompletionContext,
1502        cx: &mut ModelContext<Self>,
1503    ) -> Task<Result<Vec<Completion>>> {
1504        let language_registry = self.languages.clone();
1505
1506        if let Some(upstream_client) = self.upstream_client() {
1507            let task = self.send_lsp_proto_request(
1508                buffer.clone(),
1509                upstream_client,
1510                GetCompletions { position, context },
1511                cx,
1512            );
1513            let language = buffer.read(cx).language().cloned();
1514
1515            // In the future, we should provide project guests with the names of LSP adapters,
1516            // so that they can use the correct LSP adapter when computing labels. For now,
1517            // guests just use the first LSP adapter associated with the buffer's language.
1518            let lsp_adapter = language.as_ref().and_then(|language| {
1519                language_registry
1520                    .lsp_adapters(&language.name())
1521                    .first()
1522                    .cloned()
1523            });
1524
1525            cx.foreground_executor().spawn(async move {
1526                let completions = task.await?;
1527                let mut result = Vec::new();
1528                populate_labels_for_completions(
1529                    completions,
1530                    &language_registry,
1531                    language,
1532                    lsp_adapter,
1533                    &mut result,
1534                )
1535                .await;
1536                Ok(result)
1537            })
1538        } else {
1539            let snapshot = buffer.read(cx).snapshot();
1540            let offset = position.to_offset(&snapshot);
1541            let scope = snapshot.language_scope_at(offset);
1542            let language = snapshot.language().cloned();
1543
1544            let server_ids: Vec<_> = self
1545                .language_servers_for_buffer(buffer.read(cx), cx)
1546                .filter(|(_, server)| server.capabilities().completion_provider.is_some())
1547                .filter(|(adapter, _)| {
1548                    scope
1549                        .as_ref()
1550                        .map(|scope| scope.language_allowed(&adapter.name))
1551                        .unwrap_or(true)
1552                })
1553                .map(|(_, server)| server.server_id())
1554                .collect();
1555
1556            let buffer = buffer.clone();
1557            cx.spawn(move |this, mut cx| async move {
1558                let mut tasks = Vec::with_capacity(server_ids.len());
1559                this.update(&mut cx, |this, cx| {
1560                    for server_id in server_ids {
1561                        let lsp_adapter = this.language_server_adapter_for_id(server_id);
1562                        tasks.push((
1563                            lsp_adapter,
1564                            this.request_lsp(
1565                                buffer.clone(),
1566                                LanguageServerToQuery::Other(server_id),
1567                                GetCompletions {
1568                                    position,
1569                                    context: context.clone(),
1570                                },
1571                                cx,
1572                            ),
1573                        ));
1574                    }
1575                })?;
1576
1577                let mut completions = Vec::new();
1578                for (lsp_adapter, task) in tasks {
1579                    if let Ok(new_completions) = task.await {
1580                        populate_labels_for_completions(
1581                            new_completions,
1582                            &language_registry,
1583                            language.clone(),
1584                            lsp_adapter,
1585                            &mut completions,
1586                        )
1587                        .await;
1588                    }
1589                }
1590
1591                Ok(completions)
1592            })
1593        }
1594    }
1595
1596    pub fn resolve_completions(
1597        &self,
1598        buffer: Model<Buffer>,
1599        completion_indices: Vec<usize>,
1600        completions: Arc<RwLock<Box<[Completion]>>>,
1601        cx: &mut ModelContext<Self>,
1602    ) -> Task<Result<bool>> {
1603        let client = self.upstream_client();
1604        let language_registry = self.languages.clone();
1605        let project_id = self.project_id;
1606
1607        let buffer_id = buffer.read(cx).remote_id();
1608        let buffer_snapshot = buffer.read(cx).snapshot();
1609
1610        cx.spawn(move |this, cx| async move {
1611            let mut did_resolve = false;
1612            if let Some(client) = client {
1613                for completion_index in completion_indices {
1614                    let (server_id, completion) = {
1615                        let completions_guard = completions.read();
1616                        let completion = &completions_guard[completion_index];
1617                        if completion.documentation.is_some() {
1618                            continue;
1619                        }
1620
1621                        did_resolve = true;
1622                        let server_id = completion.server_id;
1623                        let completion = completion.lsp_completion.clone();
1624
1625                        (server_id, completion)
1626                    };
1627
1628                    Self::resolve_completion_remote(
1629                        project_id,
1630                        server_id,
1631                        buffer_id,
1632                        completions.clone(),
1633                        completion_index,
1634                        completion,
1635                        client.clone(),
1636                        language_registry.clone(),
1637                    )
1638                    .await;
1639                }
1640            } else {
1641                for completion_index in completion_indices {
1642                    let (server_id, completion) = {
1643                        let completions_guard = completions.read();
1644                        let completion = &completions_guard[completion_index];
1645                        if completion.documentation.is_some() {
1646                            continue;
1647                        }
1648
1649                        let server_id = completion.server_id;
1650                        let completion = completion.lsp_completion.clone();
1651
1652                        (server_id, completion)
1653                    };
1654
1655                    let server = this
1656                        .read_with(&cx, |this, _| this.language_server_for_id(server_id))
1657                        .ok()
1658                        .flatten();
1659                    let Some(server) = server else {
1660                        continue;
1661                    };
1662
1663                    did_resolve = true;
1664                    Self::resolve_completion_local(
1665                        server,
1666                        &buffer_snapshot,
1667                        completions.clone(),
1668                        completion_index,
1669                        completion,
1670                        language_registry.clone(),
1671                    )
1672                    .await;
1673                }
1674            }
1675
1676            Ok(did_resolve)
1677        })
1678    }
1679
1680    async fn resolve_completion_local(
1681        server: Arc<lsp::LanguageServer>,
1682        snapshot: &BufferSnapshot,
1683        completions: Arc<RwLock<Box<[Completion]>>>,
1684        completion_index: usize,
1685        completion: lsp::CompletionItem,
1686        language_registry: Arc<LanguageRegistry>,
1687    ) {
1688        let can_resolve = server
1689            .capabilities()
1690            .completion_provider
1691            .as_ref()
1692            .and_then(|options| options.resolve_provider)
1693            .unwrap_or(false);
1694        if !can_resolve {
1695            return;
1696        }
1697
1698        let request = server.request::<lsp::request::ResolveCompletionItem>(completion);
1699        let Some(completion_item) = request.await.log_err() else {
1700            return;
1701        };
1702
1703        if let Some(lsp_documentation) = completion_item.documentation.as_ref() {
1704            let documentation = language::prepare_completion_documentation(
1705                lsp_documentation,
1706                &language_registry,
1707                None, // TODO: Try to reasonably work out which language the completion is for
1708            )
1709            .await;
1710
1711            let mut completions = completions.write();
1712            let completion = &mut completions[completion_index];
1713            completion.documentation = Some(documentation);
1714        } else {
1715            let mut completions = completions.write();
1716            let completion = &mut completions[completion_index];
1717            completion.documentation = Some(Documentation::Undocumented);
1718        }
1719
1720        if let Some(text_edit) = completion_item.text_edit.as_ref() {
1721            // Technically we don't have to parse the whole `text_edit`, since the only
1722            // language server we currently use that does update `text_edit` in `completionItem/resolve`
1723            // is `typescript-language-server` and they only update `text_edit.new_text`.
1724            // But we should not rely on that.
1725            let edit = parse_completion_text_edit(text_edit, snapshot);
1726
1727            if let Some((old_range, mut new_text)) = edit {
1728                LineEnding::normalize(&mut new_text);
1729
1730                let mut completions = completions.write();
1731                let completion = &mut completions[completion_index];
1732
1733                completion.new_text = new_text;
1734                completion.old_range = old_range;
1735            }
1736        }
1737        if completion_item.insert_text_format == Some(InsertTextFormat::SNIPPET) {
1738            // vtsls might change the type of completion after resolution.
1739            let mut completions = completions.write();
1740            let completion = &mut completions[completion_index];
1741            if completion_item.insert_text_format != completion.lsp_completion.insert_text_format {
1742                completion.lsp_completion.insert_text_format = completion_item.insert_text_format;
1743            }
1744        }
1745    }
1746
1747    #[allow(clippy::too_many_arguments)]
1748    async fn resolve_completion_remote(
1749        project_id: u64,
1750        server_id: LanguageServerId,
1751        buffer_id: BufferId,
1752        completions: Arc<RwLock<Box<[Completion]>>>,
1753        completion_index: usize,
1754        completion: lsp::CompletionItem,
1755        client: AnyProtoClient,
1756        language_registry: Arc<LanguageRegistry>,
1757    ) {
1758        let request = proto::ResolveCompletionDocumentation {
1759            project_id,
1760            language_server_id: server_id.0 as u64,
1761            lsp_completion: serde_json::to_string(&completion).unwrap().into_bytes(),
1762            buffer_id: buffer_id.into(),
1763        };
1764
1765        let Some(response) = client
1766            .request(request)
1767            .await
1768            .context("completion documentation resolve proto request")
1769            .log_err()
1770        else {
1771            return;
1772        };
1773
1774        let documentation = if response.documentation.is_empty() {
1775            Documentation::Undocumented
1776        } else if response.documentation_is_markdown {
1777            Documentation::MultiLineMarkdown(
1778                markdown::parse_markdown(&response.documentation, &language_registry, None).await,
1779            )
1780        } else if response.documentation.lines().count() <= 1 {
1781            Documentation::SingleLine(response.documentation)
1782        } else {
1783            Documentation::MultiLinePlainText(response.documentation)
1784        };
1785
1786        let mut completions = completions.write();
1787        let completion = &mut completions[completion_index];
1788        completion.documentation = Some(documentation);
1789
1790        let old_range = response
1791            .old_start
1792            .and_then(deserialize_anchor)
1793            .zip(response.old_end.and_then(deserialize_anchor));
1794        if let Some((old_start, old_end)) = old_range {
1795            if !response.new_text.is_empty() {
1796                completion.new_text = response.new_text;
1797                completion.old_range = old_start..old_end;
1798            }
1799        }
1800    }
1801
1802    pub fn apply_additional_edits_for_completion(
1803        &self,
1804        buffer_handle: Model<Buffer>,
1805        completion: Completion,
1806        push_to_history: bool,
1807        cx: &mut ModelContext<Self>,
1808    ) -> Task<Result<Option<Transaction>>> {
1809        let buffer = buffer_handle.read(cx);
1810        let buffer_id = buffer.remote_id();
1811
1812        if let Some(client) = self.upstream_client() {
1813            let project_id = self.project_id;
1814            cx.spawn(move |_, mut cx| async move {
1815                let response = client
1816                    .request(proto::ApplyCompletionAdditionalEdits {
1817                        project_id,
1818                        buffer_id: buffer_id.into(),
1819                        completion: Some(Self::serialize_completion(&CoreCompletion {
1820                            old_range: completion.old_range,
1821                            new_text: completion.new_text,
1822                            server_id: completion.server_id,
1823                            lsp_completion: completion.lsp_completion,
1824                        })),
1825                    })
1826                    .await?;
1827
1828                if let Some(transaction) = response.transaction {
1829                    let transaction = language::proto::deserialize_transaction(transaction)?;
1830                    buffer_handle
1831                        .update(&mut cx, |buffer, _| {
1832                            buffer.wait_for_edits(transaction.edit_ids.iter().copied())
1833                        })?
1834                        .await?;
1835                    if push_to_history {
1836                        buffer_handle.update(&mut cx, |buffer, _| {
1837                            buffer.push_transaction(transaction.clone(), Instant::now());
1838                        })?;
1839                    }
1840                    Ok(Some(transaction))
1841                } else {
1842                    Ok(None)
1843                }
1844            })
1845        } else {
1846            let server_id = completion.server_id;
1847            let lang_server = match self.language_server_for_buffer(buffer, server_id, cx) {
1848                Some((_, server)) => server.clone(),
1849                _ => return Task::ready(Ok(Default::default())),
1850            };
1851
1852            cx.spawn(move |this, mut cx| async move {
1853                let can_resolve = lang_server
1854                    .capabilities()
1855                    .completion_provider
1856                    .as_ref()
1857                    .and_then(|options| options.resolve_provider)
1858                    .unwrap_or(false);
1859                let additional_text_edits = if can_resolve {
1860                    lang_server
1861                        .request::<lsp::request::ResolveCompletionItem>(completion.lsp_completion)
1862                        .await?
1863                        .additional_text_edits
1864                } else {
1865                    completion.lsp_completion.additional_text_edits
1866                };
1867                if let Some(edits) = additional_text_edits {
1868                    let edits = this
1869                        .update(&mut cx, |this, cx| {
1870                            this.edits_from_lsp(
1871                                &buffer_handle,
1872                                edits,
1873                                lang_server.server_id(),
1874                                None,
1875                                cx,
1876                            )
1877                        })?
1878                        .await?;
1879
1880                    buffer_handle.update(&mut cx, |buffer, cx| {
1881                        buffer.finalize_last_transaction();
1882                        buffer.start_transaction();
1883
1884                        for (range, text) in edits {
1885                            let primary = &completion.old_range;
1886                            let start_within = primary.start.cmp(&range.start, buffer).is_le()
1887                                && primary.end.cmp(&range.start, buffer).is_ge();
1888                            let end_within = range.start.cmp(&primary.end, buffer).is_le()
1889                                && range.end.cmp(&primary.end, buffer).is_ge();
1890
1891                            //Skip additional edits which overlap with the primary completion edit
1892                            //https://github.com/zed-industries/zed/pull/1871
1893                            if !start_within && !end_within {
1894                                buffer.edit([(range, text)], None, cx);
1895                            }
1896                        }
1897
1898                        let transaction = if buffer.end_transaction(cx).is_some() {
1899                            let transaction = buffer.finalize_last_transaction().unwrap().clone();
1900                            if !push_to_history {
1901                                buffer.forget_transaction(transaction.id);
1902                            }
1903                            Some(transaction)
1904                        } else {
1905                            None
1906                        };
1907                        Ok(transaction)
1908                    })?
1909                } else {
1910                    Ok(None)
1911                }
1912            })
1913        }
1914    }
1915
1916    pub fn inlay_hints(
1917        &mut self,
1918        buffer_handle: Model<Buffer>,
1919        range: Range<Anchor>,
1920        cx: &mut ModelContext<Self>,
1921    ) -> Task<anyhow::Result<Vec<InlayHint>>> {
1922        let buffer = buffer_handle.read(cx);
1923        let range_start = range.start;
1924        let range_end = range.end;
1925        let buffer_id = buffer.remote_id().into();
1926        let lsp_request = InlayHints { range };
1927
1928        if let Some(client) = self.upstream_client() {
1929            let request = proto::InlayHints {
1930                project_id: self.project_id,
1931                buffer_id,
1932                start: Some(serialize_anchor(&range_start)),
1933                end: Some(serialize_anchor(&range_end)),
1934                version: serialize_version(&buffer_handle.read(cx).version()),
1935            };
1936            cx.spawn(move |project, cx| async move {
1937                let response = client
1938                    .request(request)
1939                    .await
1940                    .context("inlay hints proto request")?;
1941                LspCommand::response_from_proto(
1942                    lsp_request,
1943                    response,
1944                    project.upgrade().ok_or_else(|| anyhow!("No project"))?,
1945                    buffer_handle.clone(),
1946                    cx.clone(),
1947                )
1948                .await
1949                .context("inlay hints proto response conversion")
1950            })
1951        } else {
1952            let lsp_request_task = self.request_lsp(
1953                buffer_handle.clone(),
1954                LanguageServerToQuery::Primary,
1955                lsp_request,
1956                cx,
1957            );
1958            cx.spawn(move |_, mut cx| async move {
1959                buffer_handle
1960                    .update(&mut cx, |buffer, _| {
1961                        buffer.wait_for_edits(vec![range_start.timestamp, range_end.timestamp])
1962                    })?
1963                    .await
1964                    .context("waiting for inlay hint request range edits")?;
1965                lsp_request_task.await.context("inlay hints LSP request")
1966            })
1967        }
1968    }
1969
1970    pub fn signature_help<T: ToPointUtf16>(
1971        &self,
1972        buffer: &Model<Buffer>,
1973        position: T,
1974        cx: &mut ModelContext<Self>,
1975    ) -> Task<Vec<SignatureHelp>> {
1976        let position = position.to_point_utf16(buffer.read(cx));
1977
1978        if let Some(client) = self.upstream_client() {
1979            let request_task = client.request(proto::MultiLspQuery {
1980                buffer_id: buffer.read(cx).remote_id().into(),
1981                version: serialize_version(&buffer.read(cx).version()),
1982                project_id: self.project_id,
1983                strategy: Some(proto::multi_lsp_query::Strategy::All(
1984                    proto::AllLanguageServers {},
1985                )),
1986                request: Some(proto::multi_lsp_query::Request::GetSignatureHelp(
1987                    GetSignatureHelp { position }.to_proto(self.project_id, buffer.read(cx)),
1988                )),
1989            });
1990            let buffer = buffer.clone();
1991            cx.spawn(|weak_project, cx| async move {
1992                let Some(project) = weak_project.upgrade() else {
1993                    return Vec::new();
1994                };
1995                join_all(
1996                    request_task
1997                        .await
1998                        .log_err()
1999                        .map(|response| response.responses)
2000                        .unwrap_or_default()
2001                        .into_iter()
2002                        .filter_map(|lsp_response| match lsp_response.response? {
2003                            proto::lsp_response::Response::GetSignatureHelpResponse(response) => {
2004                                Some(response)
2005                            }
2006                            unexpected => {
2007                                debug_panic!("Unexpected response: {unexpected:?}");
2008                                None
2009                            }
2010                        })
2011                        .map(|signature_response| {
2012                            let response = GetSignatureHelp { position }.response_from_proto(
2013                                signature_response,
2014                                project.clone(),
2015                                buffer.clone(),
2016                                cx.clone(),
2017                            );
2018                            async move { response.await.log_err().flatten() }
2019                        }),
2020                )
2021                .await
2022                .into_iter()
2023                .flatten()
2024                .collect()
2025            })
2026        } else {
2027            let all_actions_task = self.request_multiple_lsp_locally(
2028                buffer,
2029                Some(position),
2030                GetSignatureHelp { position },
2031                cx,
2032            );
2033            cx.spawn(|_, _| async move {
2034                all_actions_task
2035                    .await
2036                    .into_iter()
2037                    .flatten()
2038                    .filter(|help| !help.markdown.is_empty())
2039                    .collect::<Vec<_>>()
2040            })
2041        }
2042    }
2043
2044    pub fn hover(
2045        &self,
2046        buffer: &Model<Buffer>,
2047        position: PointUtf16,
2048        cx: &mut ModelContext<Self>,
2049    ) -> Task<Vec<Hover>> {
2050        if let Some(client) = self.upstream_client() {
2051            let request_task = client.request(proto::MultiLspQuery {
2052                buffer_id: buffer.read(cx).remote_id().into(),
2053                version: serialize_version(&buffer.read(cx).version()),
2054                project_id: self.project_id,
2055                strategy: Some(proto::multi_lsp_query::Strategy::All(
2056                    proto::AllLanguageServers {},
2057                )),
2058                request: Some(proto::multi_lsp_query::Request::GetHover(
2059                    GetHover { position }.to_proto(self.project_id, buffer.read(cx)),
2060                )),
2061            });
2062            let buffer = buffer.clone();
2063            cx.spawn(|weak_project, cx| async move {
2064                let Some(project) = weak_project.upgrade() else {
2065                    return Vec::new();
2066                };
2067                join_all(
2068                    request_task
2069                        .await
2070                        .log_err()
2071                        .map(|response| response.responses)
2072                        .unwrap_or_default()
2073                        .into_iter()
2074                        .filter_map(|lsp_response| match lsp_response.response? {
2075                            proto::lsp_response::Response::GetHoverResponse(response) => {
2076                                Some(response)
2077                            }
2078                            unexpected => {
2079                                debug_panic!("Unexpected response: {unexpected:?}");
2080                                None
2081                            }
2082                        })
2083                        .map(|hover_response| {
2084                            let response = GetHover { position }.response_from_proto(
2085                                hover_response,
2086                                project.clone(),
2087                                buffer.clone(),
2088                                cx.clone(),
2089                            );
2090                            async move {
2091                                response
2092                                    .await
2093                                    .log_err()
2094                                    .flatten()
2095                                    .and_then(remove_empty_hover_blocks)
2096                            }
2097                        }),
2098                )
2099                .await
2100                .into_iter()
2101                .flatten()
2102                .collect()
2103            })
2104        } else {
2105            let all_actions_task = self.request_multiple_lsp_locally(
2106                buffer,
2107                Some(position),
2108                GetHover { position },
2109                cx,
2110            );
2111            cx.spawn(|_, _| async move {
2112                all_actions_task
2113                    .await
2114                    .into_iter()
2115                    .filter_map(|hover| remove_empty_hover_blocks(hover?))
2116                    .collect::<Vec<Hover>>()
2117            })
2118        }
2119    }
2120
2121    pub fn symbols(&self, query: &str, cx: &mut ModelContext<Self>) -> Task<Result<Vec<Symbol>>> {
2122        let language_registry = self.languages.clone();
2123
2124        if let Some(upstream_client) = self.upstream_client().as_ref() {
2125            let request = upstream_client.request(proto::GetProjectSymbols {
2126                project_id: self.project_id,
2127                query: query.to_string(),
2128            });
2129            cx.foreground_executor().spawn(async move {
2130                let response = request.await?;
2131                let mut symbols = Vec::new();
2132                let core_symbols = response
2133                    .symbols
2134                    .into_iter()
2135                    .filter_map(|symbol| Self::deserialize_symbol(symbol).log_err())
2136                    .collect::<Vec<_>>();
2137                populate_labels_for_symbols(
2138                    core_symbols,
2139                    &language_registry,
2140                    None,
2141                    None,
2142                    &mut symbols,
2143                )
2144                .await;
2145                Ok(symbols)
2146            })
2147        } else {
2148            struct WorkspaceSymbolsResult {
2149                lsp_adapter: Arc<CachedLspAdapter>,
2150                language: LanguageName,
2151                worktree: WeakModel<Worktree>,
2152                worktree_abs_path: Arc<Path>,
2153                lsp_symbols: Vec<(String, SymbolKind, lsp::Location)>,
2154            }
2155
2156            let mut requests = Vec::new();
2157            for ((worktree_id, _), server_id) in self.language_server_ids.iter() {
2158                let Some(worktree_handle) = self
2159                    .worktree_store
2160                    .read(cx)
2161                    .worktree_for_id(*worktree_id, cx)
2162                else {
2163                    continue;
2164                };
2165                let worktree = worktree_handle.read(cx);
2166                if !worktree.is_visible() {
2167                    continue;
2168                }
2169                let worktree_abs_path = worktree.abs_path().clone();
2170
2171                let (lsp_adapter, language, server) =
2172                    match self.as_local().unwrap().language_servers.get(server_id) {
2173                        Some(LanguageServerState::Running {
2174                            adapter,
2175                            language,
2176                            server,
2177                            ..
2178                        }) => (adapter.clone(), language.clone(), server),
2179
2180                        _ => continue,
2181                    };
2182
2183                requests.push(
2184                    server
2185                        .request::<lsp::request::WorkspaceSymbolRequest>(
2186                            lsp::WorkspaceSymbolParams {
2187                                query: query.to_string(),
2188                                ..Default::default()
2189                            },
2190                        )
2191                        .log_err()
2192                        .map(move |response| {
2193                            let lsp_symbols = response.flatten().map(|symbol_response| match symbol_response {
2194                                lsp::WorkspaceSymbolResponse::Flat(flat_responses) => {
2195                                    flat_responses.into_iter().map(|lsp_symbol| {
2196                                        (lsp_symbol.name, lsp_symbol.kind, lsp_symbol.location)
2197                                    }).collect::<Vec<_>>()
2198                                }
2199                                lsp::WorkspaceSymbolResponse::Nested(nested_responses) => {
2200                                    nested_responses.into_iter().filter_map(|lsp_symbol| {
2201                                        let location = match lsp_symbol.location {
2202                                            OneOf::Left(location) => location,
2203                                            OneOf::Right(_) => {
2204                                                log::error!("Unexpected: client capabilities forbid symbol resolutions in workspace.symbol.resolveSupport");
2205                                                return None
2206                                            }
2207                                        };
2208                                        Some((lsp_symbol.name, lsp_symbol.kind, location))
2209                                    }).collect::<Vec<_>>()
2210                                }
2211                            }).unwrap_or_default();
2212
2213                            WorkspaceSymbolsResult {
2214                                lsp_adapter,
2215                                language,
2216                                worktree: worktree_handle.downgrade(),
2217                                worktree_abs_path,
2218                                lsp_symbols,
2219                            }
2220                        }),
2221                );
2222            }
2223
2224            cx.spawn(move |this, mut cx| async move {
2225                let responses = futures::future::join_all(requests).await;
2226                let this = match this.upgrade() {
2227                    Some(this) => this,
2228                    None => return Ok(Vec::new()),
2229                };
2230
2231                let mut symbols = Vec::new();
2232                for result in responses {
2233                    let core_symbols = this.update(&mut cx, |this, cx| {
2234                        result
2235                            .lsp_symbols
2236                            .into_iter()
2237                            .filter_map(|(symbol_name, symbol_kind, symbol_location)| {
2238                                let abs_path = symbol_location.uri.to_file_path().ok()?;
2239                                let source_worktree = result.worktree.upgrade()?;
2240                                let source_worktree_id = source_worktree.read(cx).id();
2241
2242                                let path;
2243                                let worktree;
2244                                if let Some((tree, rel_path)) =
2245                                    this.worktree_store.read(cx).find_worktree(&abs_path, cx)
2246                                {
2247                                    worktree = tree;
2248                                    path = rel_path;
2249                                } else {
2250                                    worktree = source_worktree.clone();
2251                                    path = relativize_path(&result.worktree_abs_path, &abs_path);
2252                                }
2253
2254                                let worktree_id = worktree.read(cx).id();
2255                                let project_path = ProjectPath {
2256                                    worktree_id,
2257                                    path: path.into(),
2258                                };
2259                                let signature = this.symbol_signature(&project_path);
2260                                Some(CoreSymbol {
2261                                    language_server_name: result.lsp_adapter.name.clone(),
2262                                    source_worktree_id,
2263                                    path: project_path,
2264                                    kind: symbol_kind,
2265                                    name: symbol_name,
2266                                    range: range_from_lsp(symbol_location.range),
2267                                    signature,
2268                                })
2269                            })
2270                            .collect()
2271                    })?;
2272
2273                    populate_labels_for_symbols(
2274                        core_symbols,
2275                        &language_registry,
2276                        Some(result.language),
2277                        Some(result.lsp_adapter),
2278                        &mut symbols,
2279                    )
2280                    .await;
2281                }
2282
2283                Ok(symbols)
2284            })
2285        }
2286    }
2287
2288    pub fn diagnostic_summaries<'a>(
2289        &'a self,
2290        include_ignored: bool,
2291        cx: &'a AppContext,
2292    ) -> impl Iterator<Item = (ProjectPath, LanguageServerId, DiagnosticSummary)> + 'a {
2293        self.worktree_store
2294            .read(cx)
2295            .visible_worktrees(cx)
2296            .filter_map(|worktree| {
2297                let worktree = worktree.read(cx);
2298                Some((worktree, self.diagnostic_summaries.get(&worktree.id())?))
2299            })
2300            .flat_map(move |(worktree, summaries)| {
2301                let worktree_id = worktree.id();
2302                summaries
2303                    .iter()
2304                    .filter(move |(path, _)| {
2305                        include_ignored
2306                            || worktree
2307                                .entry_for_path(path.as_ref())
2308                                .map_or(false, |entry| !entry.is_ignored)
2309                    })
2310                    .flat_map(move |(path, summaries)| {
2311                        summaries.iter().map(move |(server_id, summary)| {
2312                            (
2313                                ProjectPath {
2314                                    worktree_id,
2315                                    path: path.clone(),
2316                                },
2317                                *server_id,
2318                                *summary,
2319                            )
2320                        })
2321                    })
2322            })
2323    }
2324
2325    pub fn started_language_servers(&self) -> Vec<(WorktreeId, LanguageServerName)> {
2326        self.language_server_ids.keys().cloned().collect()
2327    }
2328
2329    pub fn on_buffer_edited(
2330        &mut self,
2331        buffer: Model<Buffer>,
2332        cx: &mut ModelContext<Self>,
2333    ) -> Option<()> {
2334        let buffer = buffer.read(cx);
2335        let file = File::from_dyn(buffer.file())?;
2336        let abs_path = file.as_local()?.abs_path(cx);
2337        let uri = lsp::Url::from_file_path(abs_path).unwrap();
2338        let next_snapshot = buffer.text_snapshot();
2339
2340        let language_servers: Vec<_> = self
2341            .language_servers_for_buffer(buffer, cx)
2342            .map(|i| i.1.clone())
2343            .collect();
2344
2345        for language_server in language_servers {
2346            let language_server = language_server.clone();
2347
2348            let buffer_snapshots = self
2349                .buffer_snapshots
2350                .get_mut(&buffer.remote_id())
2351                .and_then(|m| m.get_mut(&language_server.server_id()))?;
2352            let previous_snapshot = buffer_snapshots.last()?;
2353
2354            let build_incremental_change = || {
2355                buffer
2356                    .edits_since::<(PointUtf16, usize)>(previous_snapshot.snapshot.version())
2357                    .map(|edit| {
2358                        let edit_start = edit.new.start.0;
2359                        let edit_end = edit_start + (edit.old.end.0 - edit.old.start.0);
2360                        let new_text = next_snapshot
2361                            .text_for_range(edit.new.start.1..edit.new.end.1)
2362                            .collect();
2363                        lsp::TextDocumentContentChangeEvent {
2364                            range: Some(lsp::Range::new(
2365                                point_to_lsp(edit_start),
2366                                point_to_lsp(edit_end),
2367                            )),
2368                            range_length: None,
2369                            text: new_text,
2370                        }
2371                    })
2372                    .collect()
2373            };
2374
2375            let document_sync_kind = language_server
2376                .capabilities()
2377                .text_document_sync
2378                .as_ref()
2379                .and_then(|sync| match sync {
2380                    lsp::TextDocumentSyncCapability::Kind(kind) => Some(*kind),
2381                    lsp::TextDocumentSyncCapability::Options(options) => options.change,
2382                });
2383
2384            let content_changes: Vec<_> = match document_sync_kind {
2385                Some(lsp::TextDocumentSyncKind::FULL) => {
2386                    vec![lsp::TextDocumentContentChangeEvent {
2387                        range: None,
2388                        range_length: None,
2389                        text: next_snapshot.text(),
2390                    }]
2391                }
2392                Some(lsp::TextDocumentSyncKind::INCREMENTAL) => build_incremental_change(),
2393                _ => {
2394                    #[cfg(any(test, feature = "test-support"))]
2395                    {
2396                        build_incremental_change()
2397                    }
2398
2399                    #[cfg(not(any(test, feature = "test-support")))]
2400                    {
2401                        continue;
2402                    }
2403                }
2404            };
2405
2406            let next_version = previous_snapshot.version + 1;
2407            buffer_snapshots.push(LspBufferSnapshot {
2408                version: next_version,
2409                snapshot: next_snapshot.clone(),
2410            });
2411
2412            language_server
2413                .notify::<lsp::notification::DidChangeTextDocument>(
2414                    lsp::DidChangeTextDocumentParams {
2415                        text_document: lsp::VersionedTextDocumentIdentifier::new(
2416                            uri.clone(),
2417                            next_version,
2418                        ),
2419                        content_changes,
2420                    },
2421                )
2422                .log_err();
2423        }
2424
2425        None
2426    }
2427
2428    pub fn on_buffer_saved(
2429        &mut self,
2430        buffer: Model<Buffer>,
2431        cx: &mut ModelContext<Self>,
2432    ) -> Option<()> {
2433        let file = File::from_dyn(buffer.read(cx).file())?;
2434        let worktree_id = file.worktree_id(cx);
2435        let abs_path = file.as_local()?.abs_path(cx);
2436        let text_document = lsp::TextDocumentIdentifier {
2437            uri: lsp::Url::from_file_path(abs_path).log_err()?,
2438        };
2439
2440        for server in self.language_servers_for_worktree(worktree_id) {
2441            if let Some(include_text) = include_text(server.as_ref()) {
2442                let text = if include_text {
2443                    Some(buffer.read(cx).text())
2444                } else {
2445                    None
2446                };
2447                server
2448                    .notify::<lsp::notification::DidSaveTextDocument>(
2449                        lsp::DidSaveTextDocumentParams {
2450                            text_document: text_document.clone(),
2451                            text,
2452                        },
2453                    )
2454                    .log_err();
2455            }
2456        }
2457
2458        for language_server_id in self.language_server_ids_for_buffer(buffer.read(cx), cx) {
2459            self.simulate_disk_based_diagnostics_events_if_needed(language_server_id, cx);
2460        }
2461
2462        None
2463    }
2464
2465    fn maintain_workspace_config(cx: &mut ModelContext<Self>) -> Task<Result<()>> {
2466        let (mut settings_changed_tx, mut settings_changed_rx) = watch::channel();
2467        let _ = postage::stream::Stream::try_recv(&mut settings_changed_rx);
2468
2469        let settings_observation = cx.observe_global::<SettingsStore>(move |_, _| {
2470            *settings_changed_tx.borrow_mut() = ();
2471        });
2472
2473        cx.spawn(move |this, mut cx| async move {
2474            while let Some(()) = settings_changed_rx.next().await {
2475                let servers = this.update(&mut cx, |this, cx| {
2476                    this.language_server_ids
2477                        .iter()
2478                        .filter_map(|((worktree_id, _), server_id)| {
2479                            let worktree = this
2480                                .worktree_store
2481                                .read(cx)
2482                                .worktree_for_id(*worktree_id, cx)?;
2483                            let state = this.as_local()?.language_servers.get(server_id)?;
2484                            let delegate = LocalLspAdapterDelegate::for_local(this, &worktree, cx);
2485                            match state {
2486                                LanguageServerState::Starting(_) => None,
2487                                LanguageServerState::Running {
2488                                    adapter, server, ..
2489                                } => Some((
2490                                    adapter.adapter.clone(),
2491                                    server.clone(),
2492                                    delegate as Arc<dyn LspAdapterDelegate>,
2493                                )),
2494                            }
2495                        })
2496                        .collect::<Vec<_>>()
2497                })?;
2498
2499                for (adapter, server, delegate) in servers {
2500                    let settings = adapter.workspace_configuration(&delegate, &mut cx).await?;
2501
2502                    server
2503                        .notify::<lsp::notification::DidChangeConfiguration>(
2504                            lsp::DidChangeConfigurationParams { settings },
2505                        )
2506                        .ok();
2507                }
2508            }
2509
2510            drop(settings_observation);
2511            anyhow::Ok(())
2512        })
2513    }
2514
2515    pub fn primary_language_server_for_buffer<'a>(
2516        &'a self,
2517        buffer: &'a Buffer,
2518        cx: &'a AppContext,
2519    ) -> Option<(&'a Arc<CachedLspAdapter>, &'a Arc<LanguageServer>)> {
2520        // The list of language servers is ordered based on the `language_servers` setting
2521        // for each language, thus we can consider the first one in the list to be the
2522        // primary one.
2523        self.language_servers_for_buffer(buffer, cx).next()
2524    }
2525
2526    pub fn language_server_for_buffer<'a>(
2527        &'a self,
2528        buffer: &'a Buffer,
2529        server_id: LanguageServerId,
2530        cx: &'a AppContext,
2531    ) -> Option<(&'a Arc<CachedLspAdapter>, &'a Arc<LanguageServer>)> {
2532        self.language_servers_for_buffer(buffer, cx)
2533            .find(|(_, s)| s.server_id() == server_id)
2534    }
2535
2536    fn language_servers_for_worktree(
2537        &self,
2538        worktree_id: WorktreeId,
2539    ) -> impl Iterator<Item = &Arc<LanguageServer>> {
2540        self.language_server_ids
2541            .iter()
2542            .filter_map(move |((language_server_worktree_id, _), id)| {
2543                if *language_server_worktree_id == worktree_id {
2544                    if let Some(LanguageServerState::Running { server, .. }) =
2545                        self.as_local()?.language_servers.get(id)
2546                    {
2547                        return Some(server);
2548                    }
2549                }
2550                None
2551            })
2552    }
2553
2554    fn remove_worktree(&mut self, id_to_remove: WorktreeId, cx: &mut ModelContext<Self>) {
2555        self.diagnostics.remove(&id_to_remove);
2556        self.diagnostic_summaries.remove(&id_to_remove);
2557
2558        let mut servers_to_remove = HashMap::default();
2559        let mut servers_to_preserve = HashSet::default();
2560        for ((worktree_id, server_name), &server_id) in &self.language_server_ids {
2561            if worktree_id == &id_to_remove {
2562                servers_to_remove.insert(server_id, server_name.clone());
2563            } else {
2564                servers_to_preserve.insert(server_id);
2565            }
2566        }
2567        servers_to_remove.retain(|server_id, _| !servers_to_preserve.contains(server_id));
2568        for (server_id_to_remove, server_name) in servers_to_remove {
2569            self.language_server_ids
2570                .remove(&(id_to_remove, server_name));
2571            self.language_server_statuses.remove(&server_id_to_remove);
2572            if let Some(local_lsp_store) = self.as_local_mut() {
2573                local_lsp_store
2574                    .language_server_watched_paths
2575                    .remove(&server_id_to_remove);
2576                local_lsp_store
2577                    .last_workspace_edits_by_language_server
2578                    .remove(&server_id_to_remove);
2579                local_lsp_store
2580                    .language_servers
2581                    .remove(&server_id_to_remove);
2582            }
2583            cx.emit(LspStoreEvent::LanguageServerRemoved(server_id_to_remove));
2584        }
2585
2586        if let Some(local) = self.as_local() {
2587            local.prettier_store.update(cx, |prettier_store, cx| {
2588                prettier_store.remove_worktree(id_to_remove, cx);
2589            })
2590        }
2591    }
2592
2593    pub fn shared(
2594        &mut self,
2595        project_id: u64,
2596        downstream_client: AnyProtoClient,
2597        _: &mut ModelContext<Self>,
2598    ) {
2599        self.project_id = project_id;
2600        self.downstream_client = Some(downstream_client.clone());
2601
2602        for (server_id, status) in &self.language_server_statuses {
2603            downstream_client
2604                .send(proto::StartLanguageServer {
2605                    project_id,
2606                    server: Some(proto::LanguageServer {
2607                        id: server_id.0 as u64,
2608                        name: status.name.clone(),
2609                    }),
2610                })
2611                .log_err();
2612        }
2613    }
2614
2615    pub fn disconnected_from_host(&mut self) {
2616        self.downstream_client.take();
2617    }
2618
2619    pub(crate) fn set_language_server_statuses_from_proto(
2620        &mut self,
2621        language_servers: Vec<proto::LanguageServer>,
2622    ) {
2623        self.language_server_statuses = language_servers
2624            .into_iter()
2625            .map(|server| {
2626                (
2627                    LanguageServerId(server.id as usize),
2628                    LanguageServerStatus {
2629                        name: server.name,
2630                        pending_work: Default::default(),
2631                        has_pending_diagnostic_updates: false,
2632                        progress_tokens: Default::default(),
2633                    },
2634                )
2635            })
2636            .collect();
2637    }
2638
2639    pub(crate) fn register_language_server(
2640        &mut self,
2641        worktree_id: WorktreeId,
2642        language_server_name: LanguageServerName,
2643        language_server_id: LanguageServerId,
2644    ) {
2645        self.language_server_ids
2646            .insert((worktree_id, language_server_name), language_server_id);
2647    }
2648
2649    #[track_caller]
2650    pub(crate) fn register_buffer_with_language_servers(
2651        &mut self,
2652        buffer_handle: &Model<Buffer>,
2653        cx: &mut ModelContext<Self>,
2654    ) {
2655        let available_language = self.detect_language_for_buffer(buffer_handle, cx);
2656
2657        let buffer = buffer_handle.read(cx);
2658        let buffer_id = buffer.remote_id();
2659
2660        if let Some(file) = File::from_dyn(buffer.file()) {
2661            if !file.is_local() {
2662                return;
2663            }
2664
2665            let abs_path = file.abs_path(cx);
2666            let Some(uri) = lsp::Url::from_file_path(&abs_path).log_err() else {
2667                return;
2668            };
2669            let initial_snapshot = buffer.text_snapshot();
2670            let worktree_id = file.worktree_id(cx);
2671
2672            if let Some(diagnostics) = self.diagnostics.get(&worktree_id) {
2673                for (server_id, diagnostics) in
2674                    diagnostics.get(file.path()).cloned().unwrap_or_default()
2675                {
2676                    self.update_buffer_diagnostics(buffer_handle, server_id, None, diagnostics, cx)
2677                        .log_err();
2678                }
2679            }
2680
2681            if let Some(language) = available_language {
2682                for adapter in self.languages.lsp_adapters(&language.name()) {
2683                    let server = self
2684                        .language_server_ids
2685                        .get(&(worktree_id, adapter.name.clone()))
2686                        .and_then(|id| self.as_local()?.language_servers.get(id))
2687                        .and_then(|server_state| {
2688                            if let LanguageServerState::Running { server, .. } = server_state {
2689                                Some(server.clone())
2690                            } else {
2691                                None
2692                            }
2693                        });
2694                    let server = match server {
2695                        Some(server) => server,
2696                        None => continue,
2697                    };
2698
2699                    server
2700                        .notify::<lsp::notification::DidOpenTextDocument>(
2701                            lsp::DidOpenTextDocumentParams {
2702                                text_document: lsp::TextDocumentItem::new(
2703                                    uri.clone(),
2704                                    adapter.language_id(&language.name()),
2705                                    0,
2706                                    initial_snapshot.text(),
2707                                ),
2708                            },
2709                        )
2710                        .log_err();
2711
2712                    buffer_handle.update(cx, |buffer, cx| {
2713                        buffer.set_completion_triggers(
2714                            server
2715                                .capabilities()
2716                                .completion_provider
2717                                .as_ref()
2718                                .and_then(|provider| provider.trigger_characters.clone())
2719                                .unwrap_or_default(),
2720                            cx,
2721                        );
2722                    });
2723
2724                    let snapshot = LspBufferSnapshot {
2725                        version: 0,
2726                        snapshot: initial_snapshot.clone(),
2727                    };
2728                    self.buffer_snapshots
2729                        .entry(buffer_id)
2730                        .or_default()
2731                        .insert(server.server_id(), vec![snapshot]);
2732                }
2733            }
2734        }
2735    }
2736
2737    pub(crate) fn unregister_buffer_from_language_servers(
2738        &mut self,
2739        buffer: &Model<Buffer>,
2740        old_file: &File,
2741        cx: &mut AppContext,
2742    ) {
2743        let old_path = match old_file.as_local() {
2744            Some(local) => local.abs_path(cx),
2745            None => return,
2746        };
2747
2748        buffer.update(cx, |buffer, cx| {
2749            let worktree_id = old_file.worktree_id(cx);
2750
2751            let ids = &self.language_server_ids;
2752
2753            if let Some(language) = buffer.language().cloned() {
2754                for adapter in self.languages.lsp_adapters(&language.name()) {
2755                    if let Some(server_id) = ids.get(&(worktree_id, adapter.name.clone())) {
2756                        buffer.update_diagnostics(*server_id, DiagnosticSet::new([], buffer), cx);
2757                    }
2758                }
2759            }
2760
2761            self.buffer_snapshots.remove(&buffer.remote_id());
2762            let file_url = lsp::Url::from_file_path(old_path).unwrap();
2763            for (_, language_server) in self.language_servers_for_buffer(buffer, cx) {
2764                language_server
2765                    .notify::<lsp::notification::DidCloseTextDocument>(
2766                        lsp::DidCloseTextDocumentParams {
2767                            text_document: lsp::TextDocumentIdentifier::new(file_url.clone()),
2768                        },
2769                    )
2770                    .log_err();
2771            }
2772        });
2773    }
2774
2775    pub fn update_diagnostic_entries(
2776        &mut self,
2777        server_id: LanguageServerId,
2778        abs_path: PathBuf,
2779        version: Option<i32>,
2780        diagnostics: Vec<DiagnosticEntry<Unclipped<PointUtf16>>>,
2781        cx: &mut ModelContext<Self>,
2782    ) -> Result<(), anyhow::Error> {
2783        let (worktree, relative_path) =
2784            self.worktree_store
2785                .read(cx)
2786                .find_worktree(&abs_path, cx)
2787                .ok_or_else(|| anyhow!("no worktree found for diagnostics path {abs_path:?}"))?;
2788
2789        let project_path = ProjectPath {
2790            worktree_id: worktree.read(cx).id(),
2791            path: relative_path.into(),
2792        };
2793
2794        if let Some(buffer) = self.buffer_store.read(cx).get_by_path(&project_path, cx) {
2795            self.update_buffer_diagnostics(&buffer, server_id, version, diagnostics.clone(), cx)?;
2796        }
2797
2798        let updated = worktree.update(cx, |worktree, cx| {
2799            self.update_worktree_diagnostics(
2800                worktree.id(),
2801                server_id,
2802                project_path.path.clone(),
2803                diagnostics,
2804                cx,
2805            )
2806        })?;
2807        if updated {
2808            cx.emit(LspStoreEvent::DiagnosticsUpdated {
2809                language_server_id: server_id,
2810                path: project_path,
2811            })
2812        }
2813        Ok(())
2814    }
2815
2816    pub fn update_worktree_diagnostics(
2817        &mut self,
2818        worktree_id: WorktreeId,
2819        server_id: LanguageServerId,
2820        worktree_path: Arc<Path>,
2821        diagnostics: Vec<DiagnosticEntry<Unclipped<PointUtf16>>>,
2822        _: &mut ModelContext<Worktree>,
2823    ) -> Result<bool> {
2824        let summaries_for_tree = self.diagnostic_summaries.entry(worktree_id).or_default();
2825        let diagnostics_for_tree = self.diagnostics.entry(worktree_id).or_default();
2826        let summaries_by_server_id = summaries_for_tree.entry(worktree_path.clone()).or_default();
2827
2828        let old_summary = summaries_by_server_id
2829            .remove(&server_id)
2830            .unwrap_or_default();
2831
2832        let new_summary = DiagnosticSummary::new(&diagnostics);
2833        if new_summary.is_empty() {
2834            if let Some(diagnostics_by_server_id) = diagnostics_for_tree.get_mut(&worktree_path) {
2835                if let Ok(ix) = diagnostics_by_server_id.binary_search_by_key(&server_id, |e| e.0) {
2836                    diagnostics_by_server_id.remove(ix);
2837                }
2838                if diagnostics_by_server_id.is_empty() {
2839                    diagnostics_for_tree.remove(&worktree_path);
2840                }
2841            }
2842        } else {
2843            summaries_by_server_id.insert(server_id, new_summary);
2844            let diagnostics_by_server_id = diagnostics_for_tree
2845                .entry(worktree_path.clone())
2846                .or_default();
2847            match diagnostics_by_server_id.binary_search_by_key(&server_id, |e| e.0) {
2848                Ok(ix) => {
2849                    diagnostics_by_server_id[ix] = (server_id, diagnostics);
2850                }
2851                Err(ix) => {
2852                    diagnostics_by_server_id.insert(ix, (server_id, diagnostics));
2853                }
2854            }
2855        }
2856
2857        if !old_summary.is_empty() || !new_summary.is_empty() {
2858            if let Some(downstream_client) = &self.downstream_client {
2859                downstream_client
2860                    .send(proto::UpdateDiagnosticSummary {
2861                        project_id: self.project_id,
2862                        worktree_id: worktree_id.to_proto(),
2863                        summary: Some(proto::DiagnosticSummary {
2864                            path: worktree_path.to_string_lossy().to_string(),
2865                            language_server_id: server_id.0 as u64,
2866                            error_count: new_summary.error_count as u32,
2867                            warning_count: new_summary.warning_count as u32,
2868                        }),
2869                    })
2870                    .log_err();
2871            }
2872        }
2873
2874        Ok(!old_summary.is_empty() || !new_summary.is_empty())
2875    }
2876
2877    pub fn open_buffer_for_symbol(
2878        &mut self,
2879        symbol: &Symbol,
2880        cx: &mut ModelContext<Self>,
2881    ) -> Task<Result<Model<Buffer>>> {
2882        if let Some(client) = self.upstream_client() {
2883            let request = client.request(proto::OpenBufferForSymbol {
2884                project_id: self.project_id,
2885                symbol: Some(Self::serialize_symbol(symbol)),
2886            });
2887            cx.spawn(move |this, mut cx| async move {
2888                let response = request.await?;
2889                let buffer_id = BufferId::new(response.buffer_id)?;
2890                this.update(&mut cx, |this, cx| {
2891                    this.wait_for_remote_buffer(buffer_id, cx)
2892                })?
2893                .await
2894            })
2895        } else {
2896            let Some(&language_server_id) = self.language_server_ids.get(&(
2897                symbol.source_worktree_id,
2898                symbol.language_server_name.clone(),
2899            )) else {
2900                return Task::ready(Err(anyhow!(
2901                    "language server for worktree and language not found"
2902                )));
2903            };
2904
2905            let worktree_abs_path = if let Some(worktree_abs_path) = self
2906                .worktree_store
2907                .read(cx)
2908                .worktree_for_id(symbol.path.worktree_id, cx)
2909                .map(|worktree| worktree.read(cx).abs_path())
2910            {
2911                worktree_abs_path
2912            } else {
2913                return Task::ready(Err(anyhow!("worktree not found for symbol")));
2914            };
2915
2916            let symbol_abs_path = resolve_path(&worktree_abs_path, &symbol.path.path);
2917            let symbol_uri = if let Ok(uri) = lsp::Url::from_file_path(symbol_abs_path) {
2918                uri
2919            } else {
2920                return Task::ready(Err(anyhow!("invalid symbol path")));
2921            };
2922
2923            self.open_local_buffer_via_lsp(
2924                symbol_uri,
2925                language_server_id,
2926                symbol.language_server_name.clone(),
2927                cx,
2928            )
2929        }
2930    }
2931
2932    pub fn open_local_buffer_via_lsp(
2933        &mut self,
2934        mut abs_path: lsp::Url,
2935        language_server_id: LanguageServerId,
2936        language_server_name: LanguageServerName,
2937        cx: &mut ModelContext<Self>,
2938    ) -> Task<Result<Model<Buffer>>> {
2939        cx.spawn(move |this, mut cx| async move {
2940            // Escape percent-encoded string.
2941            let current_scheme = abs_path.scheme().to_owned();
2942            let _ = abs_path.set_scheme("file");
2943
2944            let abs_path = abs_path
2945                .to_file_path()
2946                .map_err(|_| anyhow!("can't convert URI to path"))?;
2947            let p = abs_path.clone();
2948            let yarn_worktree = this
2949                .update(&mut cx, move |this, cx| {
2950                    this.as_local().unwrap().yarn.update(cx, |_, cx| {
2951                        cx.spawn(|this, mut cx| async move {
2952                            let t = this
2953                                .update(&mut cx, |this, cx| {
2954                                    this.process_path(&p, &current_scheme, cx)
2955                                })
2956                                .ok()?;
2957                            t.await
2958                        })
2959                    })
2960                })?
2961                .await;
2962            let (worktree_root_target, known_relative_path) =
2963                if let Some((zip_root, relative_path)) = yarn_worktree {
2964                    (zip_root, Some(relative_path))
2965                } else {
2966                    (Arc::<Path>::from(abs_path.as_path()), None)
2967                };
2968            let (worktree, relative_path) = if let Some(result) =
2969                this.update(&mut cx, |this, cx| {
2970                    this.worktree_store.update(cx, |worktree_store, cx| {
2971                        worktree_store.find_worktree(&worktree_root_target, cx)
2972                    })
2973                })? {
2974                let relative_path =
2975                    known_relative_path.unwrap_or_else(|| Arc::<Path>::from(result.1));
2976                (result.0, relative_path)
2977            } else {
2978                let worktree = this
2979                    .update(&mut cx, |this, cx| {
2980                        this.worktree_store.update(cx, |worktree_store, cx| {
2981                            worktree_store.create_worktree(&worktree_root_target, false, cx)
2982                        })
2983                    })?
2984                    .await?;
2985                this.update(&mut cx, |this, cx| {
2986                    this.register_language_server(
2987                        worktree.read(cx).id(),
2988                        language_server_name,
2989                        language_server_id,
2990                    )
2991                })
2992                .ok();
2993                let worktree_root = worktree.update(&mut cx, |this, _| this.abs_path())?;
2994                let relative_path = if let Some(known_path) = known_relative_path {
2995                    known_path
2996                } else {
2997                    abs_path.strip_prefix(worktree_root)?.into()
2998                };
2999                (worktree, relative_path)
3000            };
3001            let project_path = ProjectPath {
3002                worktree_id: worktree.update(&mut cx, |worktree, _| worktree.id())?,
3003                path: relative_path,
3004            };
3005            this.update(&mut cx, |this, cx| {
3006                this.buffer_store().update(cx, |buffer_store, cx| {
3007                    buffer_store.open_buffer(project_path, cx)
3008                })
3009            })?
3010            .await
3011        })
3012    }
3013
3014    pub(crate) fn update_buffer_diagnostics(
3015        &mut self,
3016        buffer: &Model<Buffer>,
3017        server_id: LanguageServerId,
3018        version: Option<i32>,
3019        mut diagnostics: Vec<DiagnosticEntry<Unclipped<PointUtf16>>>,
3020        cx: &mut ModelContext<Self>,
3021    ) -> Result<()> {
3022        fn compare_diagnostics(a: &Diagnostic, b: &Diagnostic) -> Ordering {
3023            Ordering::Equal
3024                .then_with(|| b.is_primary.cmp(&a.is_primary))
3025                .then_with(|| a.is_disk_based.cmp(&b.is_disk_based))
3026                .then_with(|| a.severity.cmp(&b.severity))
3027                .then_with(|| a.message.cmp(&b.message))
3028        }
3029
3030        let snapshot = self.buffer_snapshot_for_lsp_version(buffer, server_id, version, cx)?;
3031
3032        diagnostics.sort_unstable_by(|a, b| {
3033            Ordering::Equal
3034                .then_with(|| a.range.start.cmp(&b.range.start))
3035                .then_with(|| b.range.end.cmp(&a.range.end))
3036                .then_with(|| compare_diagnostics(&a.diagnostic, &b.diagnostic))
3037        });
3038
3039        let mut sanitized_diagnostics = Vec::new();
3040        let edits_since_save = Patch::new(
3041            snapshot
3042                .edits_since::<Unclipped<PointUtf16>>(buffer.read(cx).saved_version())
3043                .collect(),
3044        );
3045        for entry in diagnostics {
3046            let start;
3047            let end;
3048            if entry.diagnostic.is_disk_based {
3049                // Some diagnostics are based on files on disk instead of buffers'
3050                // current contents. Adjust these diagnostics' ranges to reflect
3051                // any unsaved edits.
3052                start = edits_since_save.old_to_new(entry.range.start);
3053                end = edits_since_save.old_to_new(entry.range.end);
3054            } else {
3055                start = entry.range.start;
3056                end = entry.range.end;
3057            }
3058
3059            let mut range = snapshot.clip_point_utf16(start, Bias::Left)
3060                ..snapshot.clip_point_utf16(end, Bias::Right);
3061
3062            // Expand empty ranges by one codepoint
3063            if range.start == range.end {
3064                // This will be go to the next boundary when being clipped
3065                range.end.column += 1;
3066                range.end = snapshot.clip_point_utf16(Unclipped(range.end), Bias::Right);
3067                if range.start == range.end && range.end.column > 0 {
3068                    range.start.column -= 1;
3069                    range.start = snapshot.clip_point_utf16(Unclipped(range.start), Bias::Left);
3070                }
3071            }
3072
3073            sanitized_diagnostics.push(DiagnosticEntry {
3074                range,
3075                diagnostic: entry.diagnostic,
3076            });
3077        }
3078        drop(edits_since_save);
3079
3080        let set = DiagnosticSet::new(sanitized_diagnostics, &snapshot);
3081        buffer.update(cx, |buffer, cx| {
3082            buffer.update_diagnostics(server_id, set, cx)
3083        });
3084        Ok(())
3085    }
3086
3087    fn request_multiple_lsp_locally<P, R>(
3088        &self,
3089        buffer: &Model<Buffer>,
3090        position: Option<P>,
3091        request: R,
3092        cx: &mut ModelContext<'_, Self>,
3093    ) -> Task<Vec<R::Response>>
3094    where
3095        P: ToOffset,
3096        R: LspCommand + Clone,
3097        <R::LspRequest as lsp::request::Request>::Result: Send,
3098        <R::LspRequest as lsp::request::Request>::Params: Send,
3099    {
3100        debug_assert!(self.upstream_client().is_none());
3101
3102        let snapshot = buffer.read(cx).snapshot();
3103        let scope = position.and_then(|position| snapshot.language_scope_at(position));
3104        let server_ids = self
3105            .language_servers_for_buffer(buffer.read(cx), cx)
3106            .filter(|(adapter, _)| {
3107                scope
3108                    .as_ref()
3109                    .map(|scope| scope.language_allowed(&adapter.name))
3110                    .unwrap_or(true)
3111            })
3112            .map(|(_, server)| server.server_id())
3113            .collect::<Vec<_>>();
3114
3115        let mut response_results = server_ids
3116            .into_iter()
3117            .map(|server_id| {
3118                self.request_lsp(
3119                    buffer.clone(),
3120                    LanguageServerToQuery::Other(server_id),
3121                    request.clone(),
3122                    cx,
3123                )
3124            })
3125            .collect::<FuturesUnordered<_>>();
3126
3127        cx.spawn(|_, _| async move {
3128            let mut responses = Vec::with_capacity(response_results.len());
3129            while let Some(response_result) = response_results.next().await {
3130                if let Some(response) = response_result.log_err() {
3131                    responses.push(response);
3132                }
3133            }
3134            responses
3135        })
3136    }
3137
3138    async fn handle_lsp_command<T: LspCommand>(
3139        this: Model<Self>,
3140        envelope: TypedEnvelope<T::ProtoRequest>,
3141        mut cx: AsyncAppContext,
3142    ) -> Result<<T::ProtoRequest as proto::RequestMessage>::Response>
3143    where
3144        <T::LspRequest as lsp::request::Request>::Params: Send,
3145        <T::LspRequest as lsp::request::Request>::Result: Send,
3146    {
3147        let sender_id = envelope.original_sender_id().unwrap_or_default();
3148        let buffer_id = T::buffer_id_from_proto(&envelope.payload)?;
3149        let buffer_handle = this.update(&mut cx, |this, cx| {
3150            this.buffer_store.read(cx).get_existing(buffer_id)
3151        })??;
3152        let request = T::from_proto(
3153            envelope.payload,
3154            this.clone(),
3155            buffer_handle.clone(),
3156            cx.clone(),
3157        )
3158        .await?;
3159        let response = this
3160            .update(&mut cx, |this, cx| {
3161                this.request_lsp(
3162                    buffer_handle.clone(),
3163                    LanguageServerToQuery::Primary,
3164                    request,
3165                    cx,
3166                )
3167            })?
3168            .await?;
3169        this.update(&mut cx, |this, cx| {
3170            Ok(T::response_to_proto(
3171                response,
3172                this,
3173                sender_id,
3174                &buffer_handle.read(cx).version(),
3175                cx,
3176            ))
3177        })?
3178    }
3179
3180    async fn handle_multi_lsp_query(
3181        this: Model<Self>,
3182        envelope: TypedEnvelope<proto::MultiLspQuery>,
3183        mut cx: AsyncAppContext,
3184    ) -> Result<proto::MultiLspQueryResponse> {
3185        let sender_id = envelope.original_sender_id().unwrap_or_default();
3186        let buffer_id = BufferId::new(envelope.payload.buffer_id)?;
3187        let version = deserialize_version(&envelope.payload.version);
3188        let buffer = this.update(&mut cx, |this, cx| {
3189            this.buffer_store.read(cx).get_existing(buffer_id)
3190        })??;
3191        buffer
3192            .update(&mut cx, |buffer, _| {
3193                buffer.wait_for_version(version.clone())
3194            })?
3195            .await?;
3196        let buffer_version = buffer.update(&mut cx, |buffer, _| buffer.version())?;
3197        match envelope
3198            .payload
3199            .strategy
3200            .context("invalid request without the strategy")?
3201        {
3202            proto::multi_lsp_query::Strategy::All(_) => {
3203                // currently, there's only one multiple language servers query strategy,
3204                // so just ensure it's specified correctly
3205            }
3206        }
3207        match envelope.payload.request {
3208            Some(proto::multi_lsp_query::Request::GetHover(get_hover)) => {
3209                let get_hover =
3210                    GetHover::from_proto(get_hover, this.clone(), buffer.clone(), cx.clone())
3211                        .await?;
3212                let all_hovers = this
3213                    .update(&mut cx, |this, cx| {
3214                        this.request_multiple_lsp_locally(
3215                            &buffer,
3216                            Some(get_hover.position),
3217                            get_hover,
3218                            cx,
3219                        )
3220                    })?
3221                    .await
3222                    .into_iter()
3223                    .filter_map(|hover| remove_empty_hover_blocks(hover?));
3224                this.update(&mut cx, |project, cx| proto::MultiLspQueryResponse {
3225                    responses: all_hovers
3226                        .map(|hover| proto::LspResponse {
3227                            response: Some(proto::lsp_response::Response::GetHoverResponse(
3228                                GetHover::response_to_proto(
3229                                    Some(hover),
3230                                    project,
3231                                    sender_id,
3232                                    &buffer_version,
3233                                    cx,
3234                                ),
3235                            )),
3236                        })
3237                        .collect(),
3238                })
3239            }
3240            Some(proto::multi_lsp_query::Request::GetCodeActions(get_code_actions)) => {
3241                let get_code_actions = GetCodeActions::from_proto(
3242                    get_code_actions,
3243                    this.clone(),
3244                    buffer.clone(),
3245                    cx.clone(),
3246                )
3247                .await?;
3248
3249                let all_actions = this
3250                    .update(&mut cx, |project, cx| {
3251                        project.request_multiple_lsp_locally(
3252                            &buffer,
3253                            Some(get_code_actions.range.start),
3254                            get_code_actions,
3255                            cx,
3256                        )
3257                    })?
3258                    .await
3259                    .into_iter();
3260
3261                this.update(&mut cx, |project, cx| proto::MultiLspQueryResponse {
3262                    responses: all_actions
3263                        .map(|code_actions| proto::LspResponse {
3264                            response: Some(proto::lsp_response::Response::GetCodeActionsResponse(
3265                                GetCodeActions::response_to_proto(
3266                                    code_actions,
3267                                    project,
3268                                    sender_id,
3269                                    &buffer_version,
3270                                    cx,
3271                                ),
3272                            )),
3273                        })
3274                        .collect(),
3275                })
3276            }
3277            Some(proto::multi_lsp_query::Request::GetSignatureHelp(get_signature_help)) => {
3278                let get_signature_help = GetSignatureHelp::from_proto(
3279                    get_signature_help,
3280                    this.clone(),
3281                    buffer.clone(),
3282                    cx.clone(),
3283                )
3284                .await?;
3285
3286                let all_signatures = this
3287                    .update(&mut cx, |project, cx| {
3288                        project.request_multiple_lsp_locally(
3289                            &buffer,
3290                            Some(get_signature_help.position),
3291                            get_signature_help,
3292                            cx,
3293                        )
3294                    })?
3295                    .await
3296                    .into_iter();
3297
3298                this.update(&mut cx, |project, cx| proto::MultiLspQueryResponse {
3299                    responses: all_signatures
3300                        .map(|signature_help| proto::LspResponse {
3301                            response: Some(
3302                                proto::lsp_response::Response::GetSignatureHelpResponse(
3303                                    GetSignatureHelp::response_to_proto(
3304                                        signature_help,
3305                                        project,
3306                                        sender_id,
3307                                        &buffer_version,
3308                                        cx,
3309                                    ),
3310                                ),
3311                            ),
3312                        })
3313                        .collect(),
3314                })
3315            }
3316            None => anyhow::bail!("empty multi lsp query request"),
3317        }
3318    }
3319
3320    async fn handle_apply_code_action(
3321        this: Model<Self>,
3322        envelope: TypedEnvelope<proto::ApplyCodeAction>,
3323        mut cx: AsyncAppContext,
3324    ) -> Result<proto::ApplyCodeActionResponse> {
3325        let sender_id = envelope.original_sender_id().unwrap_or_default();
3326        let action = Self::deserialize_code_action(
3327            envelope
3328                .payload
3329                .action
3330                .ok_or_else(|| anyhow!("invalid action"))?,
3331        )?;
3332        let apply_code_action = this.update(&mut cx, |this, cx| {
3333            let buffer_id = BufferId::new(envelope.payload.buffer_id)?;
3334            let buffer = this.buffer_store.read(cx).get_existing(buffer_id)?;
3335            anyhow::Ok(this.apply_code_action(buffer, action, false, cx))
3336        })??;
3337
3338        let project_transaction = apply_code_action.await?;
3339        let project_transaction = this.update(&mut cx, |this, cx| {
3340            this.buffer_store.update(cx, |buffer_store, cx| {
3341                buffer_store.serialize_project_transaction_for_peer(
3342                    project_transaction,
3343                    sender_id,
3344                    cx,
3345                )
3346            })
3347        })?;
3348        Ok(proto::ApplyCodeActionResponse {
3349            transaction: Some(project_transaction),
3350        })
3351    }
3352
3353    async fn handle_update_diagnostic_summary(
3354        this: Model<Self>,
3355        envelope: TypedEnvelope<proto::UpdateDiagnosticSummary>,
3356        mut cx: AsyncAppContext,
3357    ) -> Result<()> {
3358        this.update(&mut cx, |this, cx| {
3359            let worktree_id = WorktreeId::from_proto(envelope.payload.worktree_id);
3360            if let Some(message) = envelope.payload.summary {
3361                let project_path = ProjectPath {
3362                    worktree_id,
3363                    path: Path::new(&message.path).into(),
3364                };
3365                let path = project_path.path.clone();
3366                let server_id = LanguageServerId(message.language_server_id as usize);
3367                let summary = DiagnosticSummary {
3368                    error_count: message.error_count as usize,
3369                    warning_count: message.warning_count as usize,
3370                };
3371
3372                if summary.is_empty() {
3373                    if let Some(worktree_summaries) =
3374                        this.diagnostic_summaries.get_mut(&worktree_id)
3375                    {
3376                        if let Some(summaries) = worktree_summaries.get_mut(&path) {
3377                            summaries.remove(&server_id);
3378                            if summaries.is_empty() {
3379                                worktree_summaries.remove(&path);
3380                            }
3381                        }
3382                    }
3383                } else {
3384                    this.diagnostic_summaries
3385                        .entry(worktree_id)
3386                        .or_default()
3387                        .entry(path)
3388                        .or_default()
3389                        .insert(server_id, summary);
3390                }
3391                cx.emit(LspStoreEvent::DiagnosticsUpdated {
3392                    language_server_id: LanguageServerId(message.language_server_id as usize),
3393                    path: project_path,
3394                });
3395            }
3396            Ok(())
3397        })?
3398    }
3399
3400    async fn handle_start_language_server(
3401        this: Model<Self>,
3402        envelope: TypedEnvelope<proto::StartLanguageServer>,
3403        mut cx: AsyncAppContext,
3404    ) -> Result<()> {
3405        let server = envelope
3406            .payload
3407            .server
3408            .ok_or_else(|| anyhow!("invalid server"))?;
3409        this.update(&mut cx, |this, cx| {
3410            this.language_server_statuses.insert(
3411                LanguageServerId(server.id as usize),
3412                LanguageServerStatus {
3413                    name: server.name,
3414                    pending_work: Default::default(),
3415                    has_pending_diagnostic_updates: false,
3416                    progress_tokens: Default::default(),
3417                },
3418            );
3419            cx.notify();
3420        })?;
3421        Ok(())
3422    }
3423
3424    async fn handle_update_language_server(
3425        this: Model<Self>,
3426        envelope: TypedEnvelope<proto::UpdateLanguageServer>,
3427        mut cx: AsyncAppContext,
3428    ) -> Result<()> {
3429        this.update(&mut cx, |this, cx| {
3430            let language_server_id = LanguageServerId(envelope.payload.language_server_id as usize);
3431
3432            match envelope
3433                .payload
3434                .variant
3435                .ok_or_else(|| anyhow!("invalid variant"))?
3436            {
3437                proto::update_language_server::Variant::WorkStart(payload) => {
3438                    this.on_lsp_work_start(
3439                        language_server_id,
3440                        payload.token,
3441                        LanguageServerProgress {
3442                            title: payload.title,
3443                            is_disk_based_diagnostics_progress: false,
3444                            is_cancellable: false,
3445                            message: payload.message,
3446                            percentage: payload.percentage.map(|p| p as usize),
3447                            last_update_at: cx.background_executor().now(),
3448                        },
3449                        cx,
3450                    );
3451                }
3452
3453                proto::update_language_server::Variant::WorkProgress(payload) => {
3454                    this.on_lsp_work_progress(
3455                        language_server_id,
3456                        payload.token,
3457                        LanguageServerProgress {
3458                            title: None,
3459                            is_disk_based_diagnostics_progress: false,
3460                            is_cancellable: false,
3461                            message: payload.message,
3462                            percentage: payload.percentage.map(|p| p as usize),
3463                            last_update_at: cx.background_executor().now(),
3464                        },
3465                        cx,
3466                    );
3467                }
3468
3469                proto::update_language_server::Variant::WorkEnd(payload) => {
3470                    this.on_lsp_work_end(language_server_id, payload.token, cx);
3471                }
3472
3473                proto::update_language_server::Variant::DiskBasedDiagnosticsUpdating(_) => {
3474                    this.disk_based_diagnostics_started(language_server_id, cx);
3475                }
3476
3477                proto::update_language_server::Variant::DiskBasedDiagnosticsUpdated(_) => {
3478                    this.disk_based_diagnostics_finished(language_server_id, cx)
3479                }
3480            }
3481
3482            Ok(())
3483        })?
3484    }
3485
3486    pub fn disk_based_diagnostics_started(
3487        &mut self,
3488        language_server_id: LanguageServerId,
3489        cx: &mut ModelContext<Self>,
3490    ) {
3491        if let Some(language_server_status) =
3492            self.language_server_statuses.get_mut(&language_server_id)
3493        {
3494            language_server_status.has_pending_diagnostic_updates = true;
3495        }
3496
3497        cx.emit(LspStoreEvent::DiskBasedDiagnosticsStarted { language_server_id });
3498        cx.emit(LspStoreEvent::LanguageServerUpdate {
3499            language_server_id,
3500            message: proto::update_language_server::Variant::DiskBasedDiagnosticsUpdating(
3501                Default::default(),
3502            ),
3503        })
3504    }
3505
3506    pub fn disk_based_diagnostics_finished(
3507        &mut self,
3508        language_server_id: LanguageServerId,
3509        cx: &mut ModelContext<Self>,
3510    ) {
3511        if let Some(language_server_status) =
3512            self.language_server_statuses.get_mut(&language_server_id)
3513        {
3514            language_server_status.has_pending_diagnostic_updates = false;
3515        }
3516
3517        cx.emit(LspStoreEvent::DiskBasedDiagnosticsFinished { language_server_id });
3518        cx.emit(LspStoreEvent::LanguageServerUpdate {
3519            language_server_id,
3520            message: proto::update_language_server::Variant::DiskBasedDiagnosticsUpdated(
3521                Default::default(),
3522            ),
3523        })
3524    }
3525
3526    // After saving a buffer using a language server that doesn't provide a disk-based progress token,
3527    // kick off a timer that will reset every time the buffer is saved. If the timer eventually fires,
3528    // simulate disk-based diagnostics being finished so that other pieces of UI (e.g., project
3529    // diagnostics view, diagnostic status bar) can update. We don't emit an event right away because
3530    // the language server might take some time to publish diagnostics.
3531    fn simulate_disk_based_diagnostics_events_if_needed(
3532        &mut self,
3533        language_server_id: LanguageServerId,
3534        cx: &mut ModelContext<Self>,
3535    ) {
3536        const DISK_BASED_DIAGNOSTICS_DEBOUNCE: Duration = Duration::from_secs(1);
3537
3538        let Some(LanguageServerState::Running {
3539            simulate_disk_based_diagnostics_completion,
3540            adapter,
3541            ..
3542        }) = self
3543            .as_local_mut()
3544            .and_then(|local_store| local_store.language_servers.get_mut(&language_server_id))
3545        else {
3546            return;
3547        };
3548
3549        if adapter.disk_based_diagnostics_progress_token.is_some() {
3550            return;
3551        }
3552
3553        let prev_task = simulate_disk_based_diagnostics_completion.replace(cx.spawn(
3554            move |this, mut cx| async move {
3555                cx.background_executor()
3556                    .timer(DISK_BASED_DIAGNOSTICS_DEBOUNCE)
3557                    .await;
3558
3559                this.update(&mut cx, |this, cx| {
3560                    this.disk_based_diagnostics_finished(language_server_id, cx);
3561
3562                    if let Some(LanguageServerState::Running {
3563                        simulate_disk_based_diagnostics_completion,
3564                        ..
3565                    }) = this.as_local_mut().and_then(|local_store| {
3566                        local_store.language_servers.get_mut(&language_server_id)
3567                    }) {
3568                        *simulate_disk_based_diagnostics_completion = None;
3569                    }
3570                })
3571                .ok();
3572            },
3573        ));
3574
3575        if prev_task.is_none() {
3576            self.disk_based_diagnostics_started(language_server_id, cx);
3577        }
3578    }
3579
3580    pub fn language_server_statuses(
3581        &self,
3582    ) -> impl DoubleEndedIterator<Item = (LanguageServerId, &LanguageServerStatus)> {
3583        self.language_server_statuses
3584            .iter()
3585            .map(|(key, value)| (*key, value))
3586    }
3587
3588    fn lsp_notify_abs_paths_changed(
3589        &mut self,
3590        server_id: LanguageServerId,
3591        changes: Vec<PathEvent>,
3592    ) {
3593        maybe!({
3594            let server = self.language_server_for_id(server_id)?;
3595            let changes = changes
3596                .into_iter()
3597                .filter_map(|event| {
3598                    let typ = match event.kind? {
3599                        PathEventKind::Created => lsp::FileChangeType::CREATED,
3600                        PathEventKind::Removed => lsp::FileChangeType::DELETED,
3601                        PathEventKind::Changed => lsp::FileChangeType::CHANGED,
3602                    };
3603                    Some(lsp::FileEvent {
3604                        uri: lsp::Url::from_file_path(&event.path).ok()?,
3605                        typ,
3606                    })
3607                })
3608                .collect::<Vec<_>>();
3609            if !changes.is_empty() {
3610                server
3611                    .notify::<lsp::notification::DidChangeWatchedFiles>(
3612                        lsp::DidChangeWatchedFilesParams { changes },
3613                    )
3614                    .log_err();
3615            }
3616            Some(())
3617        });
3618    }
3619
3620    fn rebuild_watched_paths(
3621        &mut self,
3622        language_server_id: LanguageServerId,
3623        cx: &mut ModelContext<Self>,
3624    ) {
3625        let worktrees = self
3626            .worktree_store
3627            .read(cx)
3628            .worktrees()
3629            .filter_map(|worktree| {
3630                self.language_servers_for_worktree(worktree.read(cx).id())
3631                    .find(|server| server.server_id() == language_server_id)
3632                    .map(|_| worktree)
3633            })
3634            .collect::<Vec<_>>();
3635
3636        let local_lsp_store = self.as_local_mut().unwrap();
3637
3638        let Some(watchers) = local_lsp_store
3639            .language_server_watcher_registrations
3640            .get(&language_server_id)
3641        else {
3642            return;
3643        };
3644
3645        let mut worktree_globs = HashMap::default();
3646        let mut abs_globs = HashMap::default();
3647        log::trace!(
3648            "Processing new watcher paths for language server with id {}",
3649            language_server_id
3650        );
3651
3652        enum PathToWatch {
3653            Worktree {
3654                literal_prefix: Arc<Path>,
3655                pattern: String,
3656            },
3657            Absolute {
3658                path: Arc<Path>,
3659                pattern: String,
3660            },
3661        }
3662        for watcher in watchers.values().flatten() {
3663            let mut found_host = false;
3664            for worktree in &worktrees {
3665                let glob_is_inside_worktree = worktree.update(cx, |tree, _| {
3666                    if let Some(worktree_root_path) = tree.abs_path().to_str() {
3667                        let path_to_watch = match &watcher.glob_pattern {
3668                            lsp::GlobPattern::String(s) => {
3669                                match s.strip_prefix(worktree_root_path) {
3670                                    Some(relative) => {
3671                                        let pattern = relative
3672                                            .strip_prefix(std::path::MAIN_SEPARATOR)
3673                                            .unwrap_or(relative)
3674                                            .to_owned();
3675                                        let literal_prefix = glob_literal_prefix(&pattern);
3676
3677                                        let literal_prefix = Arc::from(PathBuf::from(
3678                                            literal_prefix
3679                                                .strip_prefix(std::path::MAIN_SEPARATOR)
3680                                                .unwrap_or(literal_prefix),
3681                                        ));
3682                                        PathToWatch::Worktree {
3683                                            literal_prefix,
3684                                            pattern,
3685                                        }
3686                                    }
3687                                    None => {
3688                                        let path = glob_literal_prefix(s);
3689                                        let glob = &s[path.len()..];
3690                                        let pattern = glob
3691                                            .strip_prefix(std::path::MAIN_SEPARATOR)
3692                                            .unwrap_or(glob)
3693                                            .to_owned();
3694                                        let path = if Path::new(path).components().next().is_none()
3695                                        {
3696                                            Arc::from(Path::new(worktree_root_path))
3697                                        } else {
3698                                            PathBuf::from(path).into()
3699                                        };
3700
3701                                        PathToWatch::Absolute { path, pattern }
3702                                    }
3703                                }
3704                            }
3705                            lsp::GlobPattern::Relative(rp) => {
3706                                let Ok(mut base_uri) = match &rp.base_uri {
3707                                    lsp::OneOf::Left(workspace_folder) => &workspace_folder.uri,
3708                                    lsp::OneOf::Right(base_uri) => base_uri,
3709                                }
3710                                .to_file_path() else {
3711                                    return false;
3712                                };
3713
3714                                match base_uri.strip_prefix(worktree_root_path) {
3715                                    Ok(relative) => {
3716                                        let mut literal_prefix = relative.to_owned();
3717                                        literal_prefix.push(glob_literal_prefix(&rp.pattern));
3718
3719                                        PathToWatch::Worktree {
3720                                            literal_prefix: literal_prefix.into(),
3721                                            pattern: rp.pattern.clone(),
3722                                        }
3723                                    }
3724                                    Err(_) => {
3725                                        let path = glob_literal_prefix(&rp.pattern);
3726                                        let glob = &rp.pattern[path.len()..];
3727                                        let pattern = glob
3728                                            .strip_prefix(std::path::MAIN_SEPARATOR)
3729                                            .unwrap_or(glob)
3730                                            .to_owned();
3731                                        base_uri.push(path);
3732
3733                                        let path = if base_uri.components().next().is_none() {
3734                                            Arc::from(Path::new("/"))
3735                                        } else {
3736                                            base_uri.into()
3737                                        };
3738                                        PathToWatch::Absolute { path, pattern }
3739                                    }
3740                                }
3741                            }
3742                        };
3743                        match path_to_watch {
3744                            PathToWatch::Worktree {
3745                                literal_prefix,
3746                                pattern,
3747                            } => {
3748                                if let Some((tree, glob)) =
3749                                    tree.as_local_mut().zip(Glob::new(&pattern).log_err())
3750                                {
3751                                    tree.add_path_prefix_to_scan(literal_prefix);
3752                                    worktree_globs
3753                                        .entry(tree.id())
3754                                        .or_insert_with(GlobSetBuilder::new)
3755                                        .add(glob);
3756                                } else {
3757                                    return false;
3758                                }
3759                            }
3760                            PathToWatch::Absolute { path, pattern } => {
3761                                if let Some(glob) = Glob::new(&pattern).log_err() {
3762                                    abs_globs
3763                                        .entry(path)
3764                                        .or_insert_with(GlobSetBuilder::new)
3765                                        .add(glob);
3766                                }
3767                            }
3768                        }
3769                        return true;
3770                    }
3771                    false
3772                });
3773                if glob_is_inside_worktree {
3774                    log::trace!(
3775                        "Watcher pattern `{}` has been attached to the worktree at `{}`",
3776                        serde_json::to_string(&watcher.glob_pattern).unwrap(),
3777                        worktree.read(cx).abs_path().display()
3778                    );
3779                    found_host = true;
3780                }
3781            }
3782            if !found_host {
3783                log::error!(
3784                    "Watcher pattern `{}` has not been attached to any worktree or absolute path",
3785                    serde_json::to_string(&watcher.glob_pattern).unwrap()
3786                )
3787            }
3788        }
3789
3790        let mut watch_builder = LanguageServerWatchedPathsBuilder::default();
3791        for (worktree_id, builder) in worktree_globs {
3792            if let Ok(globset) = builder.build() {
3793                watch_builder.watch_worktree(worktree_id, globset);
3794            }
3795        }
3796        for (abs_path, builder) in abs_globs {
3797            if let Ok(globset) = builder.build() {
3798                watch_builder.watch_abs_path(abs_path, globset);
3799            }
3800        }
3801        let watcher = watch_builder.build(local_lsp_store.fs.clone(), language_server_id, cx);
3802        local_lsp_store
3803            .language_server_watched_paths
3804            .insert(language_server_id, watcher);
3805
3806        cx.notify();
3807    }
3808
3809    pub fn language_server_for_id(&self, id: LanguageServerId) -> Option<Arc<LanguageServer>> {
3810        if let Some(local_lsp_store) = self.as_local() {
3811            if let Some(LanguageServerState::Running { server, .. }) =
3812                local_lsp_store.language_servers.get(&id)
3813            {
3814                Some(server.clone())
3815            } else if let Some((_, server)) =
3816                local_lsp_store.supplementary_language_servers.get(&id)
3817            {
3818                Some(Arc::clone(server))
3819            } else {
3820                None
3821            }
3822        } else {
3823            None
3824        }
3825    }
3826
3827    async fn on_lsp_workspace_edit(
3828        this: WeakModel<Self>,
3829        params: lsp::ApplyWorkspaceEditParams,
3830        server_id: LanguageServerId,
3831        adapter: Arc<CachedLspAdapter>,
3832        mut cx: AsyncAppContext,
3833    ) -> Result<lsp::ApplyWorkspaceEditResponse> {
3834        let this = this
3835            .upgrade()
3836            .ok_or_else(|| anyhow!("project project closed"))?;
3837        let language_server = this
3838            .update(&mut cx, |this, _| this.language_server_for_id(server_id))?
3839            .ok_or_else(|| anyhow!("language server not found"))?;
3840        let transaction = Self::deserialize_workspace_edit(
3841            this.clone(),
3842            params.edit,
3843            true,
3844            adapter.clone(),
3845            language_server.clone(),
3846            &mut cx,
3847        )
3848        .await
3849        .log_err();
3850        this.update(&mut cx, |this, _| {
3851            if let Some(transaction) = transaction {
3852                this.as_local_mut()
3853                    .unwrap()
3854                    .last_workspace_edits_by_language_server
3855                    .insert(server_id, transaction);
3856            }
3857        })?;
3858        Ok(lsp::ApplyWorkspaceEditResponse {
3859            applied: true,
3860            failed_change: None,
3861            failure_reason: None,
3862        })
3863    }
3864
3865    fn on_lsp_progress(
3866        &mut self,
3867        progress: lsp::ProgressParams,
3868        language_server_id: LanguageServerId,
3869        disk_based_diagnostics_progress_token: Option<String>,
3870        cx: &mut ModelContext<Self>,
3871    ) {
3872        let token = match progress.token {
3873            lsp::NumberOrString::String(token) => token,
3874            lsp::NumberOrString::Number(token) => {
3875                log::info!("skipping numeric progress token {}", token);
3876                return;
3877            }
3878        };
3879
3880        let lsp::ProgressParamsValue::WorkDone(progress) = progress.value;
3881        let language_server_status =
3882            if let Some(status) = self.language_server_statuses.get_mut(&language_server_id) {
3883                status
3884            } else {
3885                return;
3886            };
3887
3888        if !language_server_status.progress_tokens.contains(&token) {
3889            return;
3890        }
3891
3892        let is_disk_based_diagnostics_progress = disk_based_diagnostics_progress_token
3893            .as_ref()
3894            .map_or(false, |disk_based_token| {
3895                token.starts_with(disk_based_token)
3896            });
3897
3898        match progress {
3899            lsp::WorkDoneProgress::Begin(report) => {
3900                if is_disk_based_diagnostics_progress {
3901                    self.disk_based_diagnostics_started(language_server_id, cx);
3902                }
3903                self.on_lsp_work_start(
3904                    language_server_id,
3905                    token.clone(),
3906                    LanguageServerProgress {
3907                        title: Some(report.title),
3908                        is_disk_based_diagnostics_progress,
3909                        is_cancellable: report.cancellable.unwrap_or(false),
3910                        message: report.message.clone(),
3911                        percentage: report.percentage.map(|p| p as usize),
3912                        last_update_at: cx.background_executor().now(),
3913                    },
3914                    cx,
3915                );
3916            }
3917            lsp::WorkDoneProgress::Report(report) => {
3918                if self.on_lsp_work_progress(
3919                    language_server_id,
3920                    token.clone(),
3921                    LanguageServerProgress {
3922                        title: None,
3923                        is_disk_based_diagnostics_progress,
3924                        is_cancellable: report.cancellable.unwrap_or(false),
3925                        message: report.message.clone(),
3926                        percentage: report.percentage.map(|p| p as usize),
3927                        last_update_at: cx.background_executor().now(),
3928                    },
3929                    cx,
3930                ) {
3931                    cx.emit(LspStoreEvent::LanguageServerUpdate {
3932                        language_server_id,
3933                        message: proto::update_language_server::Variant::WorkProgress(
3934                            proto::LspWorkProgress {
3935                                token,
3936                                message: report.message,
3937                                percentage: report.percentage,
3938                            },
3939                        ),
3940                    })
3941                }
3942            }
3943            lsp::WorkDoneProgress::End(_) => {
3944                language_server_status.progress_tokens.remove(&token);
3945                self.on_lsp_work_end(language_server_id, token.clone(), cx);
3946                if is_disk_based_diagnostics_progress {
3947                    self.disk_based_diagnostics_finished(language_server_id, cx);
3948                }
3949            }
3950        }
3951    }
3952
3953    fn on_lsp_work_start(
3954        &mut self,
3955        language_server_id: LanguageServerId,
3956        token: String,
3957        progress: LanguageServerProgress,
3958        cx: &mut ModelContext<Self>,
3959    ) {
3960        if let Some(status) = self.language_server_statuses.get_mut(&language_server_id) {
3961            status.pending_work.insert(token.clone(), progress.clone());
3962            cx.notify();
3963        }
3964        cx.emit(LspStoreEvent::LanguageServerUpdate {
3965            language_server_id,
3966            message: proto::update_language_server::Variant::WorkStart(proto::LspWorkStart {
3967                token,
3968                title: progress.title,
3969                message: progress.message,
3970                percentage: progress.percentage.map(|p| p as u32),
3971            }),
3972        })
3973    }
3974
3975    fn on_lsp_work_progress(
3976        &mut self,
3977        language_server_id: LanguageServerId,
3978        token: String,
3979        progress: LanguageServerProgress,
3980        cx: &mut ModelContext<Self>,
3981    ) -> bool {
3982        if let Some(status) = self.language_server_statuses.get_mut(&language_server_id) {
3983            match status.pending_work.entry(token) {
3984                btree_map::Entry::Vacant(entry) => {
3985                    entry.insert(progress);
3986                    cx.notify();
3987                    return true;
3988                }
3989                btree_map::Entry::Occupied(mut entry) => {
3990                    let entry = entry.get_mut();
3991                    if (progress.last_update_at - entry.last_update_at)
3992                        >= SERVER_PROGRESS_THROTTLE_TIMEOUT
3993                    {
3994                        entry.last_update_at = progress.last_update_at;
3995                        if progress.message.is_some() {
3996                            entry.message = progress.message;
3997                        }
3998                        if progress.percentage.is_some() {
3999                            entry.percentage = progress.percentage;
4000                        }
4001                        cx.notify();
4002                        return true;
4003                    }
4004                }
4005            }
4006        }
4007
4008        false
4009    }
4010
4011    fn on_lsp_work_end(
4012        &mut self,
4013        language_server_id: LanguageServerId,
4014        token: String,
4015        cx: &mut ModelContext<Self>,
4016    ) {
4017        if let Some(status) = self.language_server_statuses.get_mut(&language_server_id) {
4018            if let Some(work) = status.pending_work.remove(&token) {
4019                if !work.is_disk_based_diagnostics_progress {
4020                    cx.emit(LspStoreEvent::RefreshInlayHints);
4021                }
4022            }
4023            cx.notify();
4024        }
4025
4026        cx.emit(LspStoreEvent::LanguageServerUpdate {
4027            language_server_id,
4028            message: proto::update_language_server::Variant::WorkEnd(proto::LspWorkEnd { token }),
4029        })
4030    }
4031
4032    fn on_lsp_did_change_watched_files(
4033        &mut self,
4034        language_server_id: LanguageServerId,
4035        registration_id: &str,
4036        params: DidChangeWatchedFilesRegistrationOptions,
4037        cx: &mut ModelContext<Self>,
4038    ) {
4039        if let Some(local) = self.as_local_mut() {
4040            let registrations = local
4041                .language_server_watcher_registrations
4042                .entry(language_server_id)
4043                .or_default();
4044
4045            registrations.insert(registration_id.to_string(), params.watchers);
4046
4047            self.rebuild_watched_paths(language_server_id, cx);
4048        }
4049    }
4050
4051    fn on_lsp_unregister_did_change_watched_files(
4052        &mut self,
4053        language_server_id: LanguageServerId,
4054        registration_id: &str,
4055        cx: &mut ModelContext<Self>,
4056    ) {
4057        if let Some(local) = self.as_local_mut() {
4058            let registrations = local
4059                .language_server_watcher_registrations
4060                .entry(language_server_id)
4061                .or_default();
4062
4063            if registrations.remove(registration_id).is_some() {
4064                log::info!(
4065                "language server {}: unregistered workspace/DidChangeWatchedFiles capability with id {}",
4066                language_server_id,
4067                registration_id
4068            );
4069            } else {
4070                log::warn!(
4071                "language server {}: failed to unregister workspace/DidChangeWatchedFiles capability with id {}. not registered.",
4072                language_server_id,
4073                registration_id
4074            );
4075            }
4076
4077            self.rebuild_watched_paths(language_server_id, cx);
4078        }
4079    }
4080
4081    #[allow(clippy::type_complexity)]
4082    pub(crate) fn edits_from_lsp(
4083        &mut self,
4084        buffer: &Model<Buffer>,
4085        lsp_edits: impl 'static + Send + IntoIterator<Item = lsp::TextEdit>,
4086        server_id: LanguageServerId,
4087        version: Option<i32>,
4088        cx: &mut ModelContext<Self>,
4089    ) -> Task<Result<Vec<(Range<Anchor>, String)>>> {
4090        let snapshot = self.buffer_snapshot_for_lsp_version(buffer, server_id, version, cx);
4091        cx.background_executor().spawn(async move {
4092            let snapshot = snapshot?;
4093            let mut lsp_edits = lsp_edits
4094                .into_iter()
4095                .map(|edit| (range_from_lsp(edit.range), edit.new_text))
4096                .collect::<Vec<_>>();
4097            lsp_edits.sort_by_key(|(range, _)| range.start);
4098
4099            let mut lsp_edits = lsp_edits.into_iter().peekable();
4100            let mut edits = Vec::new();
4101            while let Some((range, mut new_text)) = lsp_edits.next() {
4102                // Clip invalid ranges provided by the language server.
4103                let mut range = snapshot.clip_point_utf16(range.start, Bias::Left)
4104                    ..snapshot.clip_point_utf16(range.end, Bias::Left);
4105
4106                // Combine any LSP edits that are adjacent.
4107                //
4108                // Also, combine LSP edits that are separated from each other by only
4109                // a newline. This is important because for some code actions,
4110                // Rust-analyzer rewrites the entire buffer via a series of edits that
4111                // are separated by unchanged newline characters.
4112                //
4113                // In order for the diffing logic below to work properly, any edits that
4114                // cancel each other out must be combined into one.
4115                while let Some((next_range, next_text)) = lsp_edits.peek() {
4116                    if next_range.start.0 > range.end {
4117                        if next_range.start.0.row > range.end.row + 1
4118                            || next_range.start.0.column > 0
4119                            || snapshot.clip_point_utf16(
4120                                Unclipped(PointUtf16::new(range.end.row, u32::MAX)),
4121                                Bias::Left,
4122                            ) > range.end
4123                        {
4124                            break;
4125                        }
4126                        new_text.push('\n');
4127                    }
4128                    range.end = snapshot.clip_point_utf16(next_range.end, Bias::Left);
4129                    new_text.push_str(next_text);
4130                    lsp_edits.next();
4131                }
4132
4133                // For multiline edits, perform a diff of the old and new text so that
4134                // we can identify the changes more precisely, preserving the locations
4135                // of any anchors positioned in the unchanged regions.
4136                if range.end.row > range.start.row {
4137                    let mut offset = range.start.to_offset(&snapshot);
4138                    let old_text = snapshot.text_for_range(range).collect::<String>();
4139
4140                    let diff = TextDiff::from_lines(old_text.as_str(), &new_text);
4141                    let mut moved_since_edit = true;
4142                    for change in diff.iter_all_changes() {
4143                        let tag = change.tag();
4144                        let value = change.value();
4145                        match tag {
4146                            ChangeTag::Equal => {
4147                                offset += value.len();
4148                                moved_since_edit = true;
4149                            }
4150                            ChangeTag::Delete => {
4151                                let start = snapshot.anchor_after(offset);
4152                                let end = snapshot.anchor_before(offset + value.len());
4153                                if moved_since_edit {
4154                                    edits.push((start..end, String::new()));
4155                                } else {
4156                                    edits.last_mut().unwrap().0.end = end;
4157                                }
4158                                offset += value.len();
4159                                moved_since_edit = false;
4160                            }
4161                            ChangeTag::Insert => {
4162                                if moved_since_edit {
4163                                    let anchor = snapshot.anchor_after(offset);
4164                                    edits.push((anchor..anchor, value.to_string()));
4165                                } else {
4166                                    edits.last_mut().unwrap().1.push_str(value);
4167                                }
4168                                moved_since_edit = false;
4169                            }
4170                        }
4171                    }
4172                } else if range.end == range.start {
4173                    let anchor = snapshot.anchor_after(range.start);
4174                    edits.push((anchor..anchor, new_text));
4175                } else {
4176                    let edit_start = snapshot.anchor_after(range.start);
4177                    let edit_end = snapshot.anchor_before(range.end);
4178                    edits.push((edit_start..edit_end, new_text));
4179                }
4180            }
4181
4182            Ok(edits)
4183        })
4184    }
4185
4186    pub async fn handle_resolve_completion_documentation(
4187        this: Model<Self>,
4188        envelope: TypedEnvelope<proto::ResolveCompletionDocumentation>,
4189        mut cx: AsyncAppContext,
4190    ) -> Result<proto::ResolveCompletionDocumentationResponse> {
4191        let lsp_completion = serde_json::from_slice(&envelope.payload.lsp_completion)?;
4192
4193        let completion = this
4194            .read_with(&cx, |this, _| {
4195                let id = LanguageServerId(envelope.payload.language_server_id as usize);
4196                let Some(server) = this.language_server_for_id(id) else {
4197                    return Err(anyhow!("No language server {id}"));
4198                };
4199
4200                Ok(server.request::<lsp::request::ResolveCompletionItem>(lsp_completion))
4201            })??
4202            .await?;
4203
4204        let mut documentation_is_markdown = false;
4205        let documentation = match completion.documentation {
4206            Some(lsp::Documentation::String(text)) => text,
4207
4208            Some(lsp::Documentation::MarkupContent(lsp::MarkupContent { kind, value })) => {
4209                documentation_is_markdown = kind == lsp::MarkupKind::Markdown;
4210                value
4211            }
4212
4213            _ => String::new(),
4214        };
4215
4216        // If we have a new buffer_id, that means we're talking to a new client
4217        // and want to check for new text_edits in the completion too.
4218        let mut old_start = None;
4219        let mut old_end = None;
4220        let mut new_text = String::default();
4221        if let Ok(buffer_id) = BufferId::new(envelope.payload.buffer_id) {
4222            let buffer_snapshot = this.update(&mut cx, |this, cx| {
4223                let buffer = this.buffer_store.read(cx).get_existing(buffer_id)?;
4224                anyhow::Ok(buffer.read(cx).snapshot())
4225            })??;
4226
4227            if let Some(text_edit) = completion.text_edit.as_ref() {
4228                let edit = parse_completion_text_edit(text_edit, &buffer_snapshot);
4229
4230                if let Some((old_range, mut text_edit_new_text)) = edit {
4231                    LineEnding::normalize(&mut text_edit_new_text);
4232
4233                    new_text = text_edit_new_text;
4234                    old_start = Some(serialize_anchor(&old_range.start));
4235                    old_end = Some(serialize_anchor(&old_range.end));
4236                }
4237            }
4238        }
4239
4240        Ok(proto::ResolveCompletionDocumentationResponse {
4241            documentation,
4242            documentation_is_markdown,
4243            old_start,
4244            old_end,
4245            new_text,
4246        })
4247    }
4248
4249    async fn handle_on_type_formatting(
4250        this: Model<Self>,
4251        envelope: TypedEnvelope<proto::OnTypeFormatting>,
4252        mut cx: AsyncAppContext,
4253    ) -> Result<proto::OnTypeFormattingResponse> {
4254        let on_type_formatting = this.update(&mut cx, |this, cx| {
4255            let buffer_id = BufferId::new(envelope.payload.buffer_id)?;
4256            let buffer = this.buffer_store.read(cx).get_existing(buffer_id)?;
4257            let position = envelope
4258                .payload
4259                .position
4260                .and_then(deserialize_anchor)
4261                .ok_or_else(|| anyhow!("invalid position"))?;
4262            Ok::<_, anyhow::Error>(this.apply_on_type_formatting(
4263                buffer,
4264                position,
4265                envelope.payload.trigger.clone(),
4266                cx,
4267            ))
4268        })??;
4269
4270        let transaction = on_type_formatting
4271            .await?
4272            .as_ref()
4273            .map(language::proto::serialize_transaction);
4274        Ok(proto::OnTypeFormattingResponse { transaction })
4275    }
4276
4277    async fn handle_refresh_inlay_hints(
4278        this: Model<Self>,
4279        _: TypedEnvelope<proto::RefreshInlayHints>,
4280        mut cx: AsyncAppContext,
4281    ) -> Result<proto::Ack> {
4282        this.update(&mut cx, |_, cx| {
4283            cx.emit(LspStoreEvent::RefreshInlayHints);
4284        })?;
4285        Ok(proto::Ack {})
4286    }
4287
4288    async fn handle_inlay_hints(
4289        this: Model<Self>,
4290        envelope: TypedEnvelope<proto::InlayHints>,
4291        mut cx: AsyncAppContext,
4292    ) -> Result<proto::InlayHintsResponse> {
4293        let sender_id = envelope.original_sender_id().unwrap_or_default();
4294        let buffer_id = BufferId::new(envelope.payload.buffer_id)?;
4295        let buffer = this.update(&mut cx, |this, cx| {
4296            this.buffer_store.read(cx).get_existing(buffer_id)
4297        })??;
4298        buffer
4299            .update(&mut cx, |buffer, _| {
4300                buffer.wait_for_version(deserialize_version(&envelope.payload.version))
4301            })?
4302            .await
4303            .with_context(|| format!("waiting for version for buffer {}", buffer.entity_id()))?;
4304
4305        let start = envelope
4306            .payload
4307            .start
4308            .and_then(deserialize_anchor)
4309            .context("missing range start")?;
4310        let end = envelope
4311            .payload
4312            .end
4313            .and_then(deserialize_anchor)
4314            .context("missing range end")?;
4315        let buffer_hints = this
4316            .update(&mut cx, |lsp_store, cx| {
4317                lsp_store.inlay_hints(buffer.clone(), start..end, cx)
4318            })?
4319            .await
4320            .context("inlay hints fetch")?;
4321
4322        this.update(&mut cx, |project, cx| {
4323            InlayHints::response_to_proto(
4324                buffer_hints,
4325                project,
4326                sender_id,
4327                &buffer.read(cx).version(),
4328                cx,
4329            )
4330        })
4331    }
4332
4333    async fn handle_resolve_inlay_hint(
4334        this: Model<Self>,
4335        envelope: TypedEnvelope<proto::ResolveInlayHint>,
4336        mut cx: AsyncAppContext,
4337    ) -> Result<proto::ResolveInlayHintResponse> {
4338        let proto_hint = envelope
4339            .payload
4340            .hint
4341            .expect("incorrect protobuf resolve inlay hint message: missing the inlay hint");
4342        let hint = InlayHints::proto_to_project_hint(proto_hint)
4343            .context("resolved proto inlay hint conversion")?;
4344        let buffer = this.update(&mut cx, |this, cx| {
4345            let buffer_id = BufferId::new(envelope.payload.buffer_id)?;
4346            this.buffer_store.read(cx).get_existing(buffer_id)
4347        })??;
4348        let response_hint = this
4349            .update(&mut cx, |this, cx| {
4350                this.resolve_inlay_hint(
4351                    hint,
4352                    buffer,
4353                    LanguageServerId(envelope.payload.language_server_id as usize),
4354                    cx,
4355                )
4356            })?
4357            .await
4358            .context("inlay hints fetch")?;
4359        Ok(proto::ResolveInlayHintResponse {
4360            hint: Some(InlayHints::project_to_proto_hint(response_hint)),
4361        })
4362    }
4363
4364    async fn handle_open_buffer_for_symbol(
4365        this: Model<Self>,
4366        envelope: TypedEnvelope<proto::OpenBufferForSymbol>,
4367        mut cx: AsyncAppContext,
4368    ) -> Result<proto::OpenBufferForSymbolResponse> {
4369        let peer_id = envelope.original_sender_id().unwrap_or_default();
4370        let symbol = envelope
4371            .payload
4372            .symbol
4373            .ok_or_else(|| anyhow!("invalid symbol"))?;
4374        let symbol = Self::deserialize_symbol(symbol)?;
4375        let symbol = this.update(&mut cx, |this, _| {
4376            let signature = this.symbol_signature(&symbol.path);
4377            if signature == symbol.signature {
4378                Ok(symbol)
4379            } else {
4380                Err(anyhow!("invalid symbol signature"))
4381            }
4382        })??;
4383        let buffer = this
4384            .update(&mut cx, |this, cx| {
4385                this.open_buffer_for_symbol(
4386                    &Symbol {
4387                        language_server_name: symbol.language_server_name,
4388                        source_worktree_id: symbol.source_worktree_id,
4389                        path: symbol.path,
4390                        name: symbol.name,
4391                        kind: symbol.kind,
4392                        range: symbol.range,
4393                        signature: symbol.signature,
4394                        label: CodeLabel {
4395                            text: Default::default(),
4396                            runs: Default::default(),
4397                            filter_range: Default::default(),
4398                        },
4399                    },
4400                    cx,
4401                )
4402            })?
4403            .await?;
4404
4405        this.update(&mut cx, |this, cx| {
4406            let is_private = buffer
4407                .read(cx)
4408                .file()
4409                .map(|f| f.is_private())
4410                .unwrap_or_default();
4411            if is_private {
4412                Err(anyhow!(rpc::ErrorCode::UnsharedItem))
4413            } else {
4414                this.buffer_store
4415                    .update(cx, |buffer_store, cx| {
4416                        buffer_store.create_buffer_for_peer(&buffer, peer_id, cx)
4417                    })
4418                    .detach_and_log_err(cx);
4419                let buffer_id = buffer.read(cx).remote_id().to_proto();
4420                Ok(proto::OpenBufferForSymbolResponse { buffer_id })
4421            }
4422        })?
4423    }
4424
4425    fn symbol_signature(&self, project_path: &ProjectPath) -> [u8; 32] {
4426        let mut hasher = Sha256::new();
4427        hasher.update(project_path.worktree_id.to_proto().to_be_bytes());
4428        hasher.update(project_path.path.to_string_lossy().as_bytes());
4429        hasher.update(self.nonce.to_be_bytes());
4430        hasher.finalize().as_slice().try_into().unwrap()
4431    }
4432
4433    pub async fn handle_get_project_symbols(
4434        this: Model<Self>,
4435        envelope: TypedEnvelope<proto::GetProjectSymbols>,
4436        mut cx: AsyncAppContext,
4437    ) -> Result<proto::GetProjectSymbolsResponse> {
4438        let symbols = this
4439            .update(&mut cx, |this, cx| {
4440                this.symbols(&envelope.payload.query, cx)
4441            })?
4442            .await?;
4443
4444        Ok(proto::GetProjectSymbolsResponse {
4445            symbols: symbols.iter().map(Self::serialize_symbol).collect(),
4446        })
4447    }
4448
4449    pub async fn handle_restart_language_servers(
4450        this: Model<Self>,
4451        envelope: TypedEnvelope<proto::RestartLanguageServers>,
4452        mut cx: AsyncAppContext,
4453    ) -> Result<proto::Ack> {
4454        this.update(&mut cx, |this, cx| {
4455            let buffers: Vec<_> = envelope
4456                .payload
4457                .buffer_ids
4458                .into_iter()
4459                .flat_map(|buffer_id| {
4460                    this.buffer_store
4461                        .read(cx)
4462                        .get(BufferId::new(buffer_id).log_err()?)
4463                })
4464                .collect();
4465            this.restart_language_servers_for_buffers(buffers, cx)
4466        })?;
4467
4468        Ok(proto::Ack {})
4469    }
4470
4471    pub async fn handle_create_language_server(
4472        this: Model<Self>,
4473        envelope: TypedEnvelope<proto::CreateLanguageServer>,
4474        mut cx: AsyncAppContext,
4475    ) -> Result<proto::Ack> {
4476        let worktree_id = WorktreeId::from_proto(envelope.payload.worktree_id);
4477        let name = LanguageServerName::from_proto(envelope.payload.name);
4478
4479        let binary = envelope
4480            .payload
4481            .binary
4482            .ok_or_else(|| anyhow!("missing binary"))?;
4483        let binary = LanguageServerBinary {
4484            path: PathBuf::from(binary.path),
4485            env: None,
4486            arguments: binary.arguments.into_iter().map(Into::into).collect(),
4487        };
4488        let language = envelope
4489            .payload
4490            .language
4491            .ok_or_else(|| anyhow!("missing language"))?;
4492        let language_name = LanguageName::from_proto(language.name);
4493        let matcher: LanguageMatcher = serde_json::from_str(&language.matcher)?;
4494
4495        this.update(&mut cx, |this, cx| {
4496            this.languages
4497                .register_language(language_name.clone(), None, matcher.clone(), {
4498                    let language_name = language_name.clone();
4499                    move || {
4500                        Ok((
4501                            LanguageConfig {
4502                                name: language_name.clone(),
4503                                matcher: matcher.clone(),
4504                                ..Default::default()
4505                            },
4506                            Default::default(),
4507                            Default::default(),
4508                        ))
4509                    }
4510                });
4511            cx.background_executor()
4512                .spawn(this.languages.language_for_name(language_name.0.as_ref()))
4513                .detach();
4514
4515            let adapter = Arc::new(SshLspAdapter::new(
4516                name,
4517                binary,
4518                envelope.payload.initialization_options,
4519                envelope.payload.code_action_kinds,
4520            ));
4521
4522            this.languages
4523                .register_lsp_adapter(language_name.clone(), adapter.clone());
4524            let Some(worktree) = this
4525                .worktree_store
4526                .read(cx)
4527                .worktree_for_id(worktree_id, cx)
4528            else {
4529                return Err(anyhow!("worktree not found"));
4530            };
4531            this.start_language_server(
4532                &worktree,
4533                CachedLspAdapter::new(adapter),
4534                language_name,
4535                cx,
4536            );
4537            Ok(())
4538        })??;
4539        Ok(proto::Ack {})
4540    }
4541
4542    pub async fn handle_which_command(
4543        this: Model<Self>,
4544        envelope: TypedEnvelope<proto::WhichCommand>,
4545        mut cx: AsyncAppContext,
4546    ) -> Result<proto::WhichCommandResponse> {
4547        let worktree_id = WorktreeId::from_proto(envelope.payload.worktree_id);
4548        let command = PathBuf::from(envelope.payload.command);
4549        let response = this
4550            .update(&mut cx, |this, cx| {
4551                let worktree = this.worktree_for_id(worktree_id, cx)?;
4552                let delegate = LocalLspAdapterDelegate::for_local(this, &worktree, cx);
4553                anyhow::Ok(
4554                    cx.spawn(|_, _| async move { delegate.which(command.as_os_str()).await }),
4555                )
4556            })??
4557            .await;
4558
4559        Ok(proto::WhichCommandResponse {
4560            path: response.map(|path| path.to_string_lossy().to_string()),
4561        })
4562    }
4563
4564    pub async fn handle_shell_env(
4565        this: Model<Self>,
4566        envelope: TypedEnvelope<proto::ShellEnv>,
4567        mut cx: AsyncAppContext,
4568    ) -> Result<proto::ShellEnvResponse> {
4569        let worktree_id = WorktreeId::from_proto(envelope.payload.worktree_id);
4570        let response = this
4571            .update(&mut cx, |this, cx| {
4572                let worktree = this.worktree_for_id(worktree_id, cx)?;
4573                let delegate = LocalLspAdapterDelegate::for_local(this, &worktree, cx);
4574                anyhow::Ok(cx.spawn(|_, _| async move { delegate.shell_env().await }))
4575            })??
4576            .await;
4577
4578        Ok(proto::ShellEnvResponse {
4579            env: response.into_iter().collect(),
4580        })
4581    }
4582    pub async fn handle_try_exec(
4583        this: Model<Self>,
4584        envelope: TypedEnvelope<proto::TryExec>,
4585        mut cx: AsyncAppContext,
4586    ) -> Result<proto::Ack> {
4587        let worktree_id = WorktreeId::from_proto(envelope.payload.worktree_id);
4588        let binary = envelope
4589            .payload
4590            .binary
4591            .ok_or_else(|| anyhow!("missing binary"))?;
4592        let binary = LanguageServerBinary {
4593            path: PathBuf::from(binary.path),
4594            env: None,
4595            arguments: binary.arguments.into_iter().map(Into::into).collect(),
4596        };
4597        this.update(&mut cx, |this, cx| {
4598            let worktree = this.worktree_for_id(worktree_id, cx)?;
4599            let delegate = LocalLspAdapterDelegate::for_local(this, &worktree, cx);
4600            anyhow::Ok(cx.spawn(|_, _| async move { delegate.try_exec(binary).await }))
4601        })??
4602        .await?;
4603
4604        Ok(proto::Ack {})
4605    }
4606
4607    pub async fn handle_read_text_file(
4608        this: Model<Self>,
4609        envelope: TypedEnvelope<proto::ReadTextFile>,
4610        mut cx: AsyncAppContext,
4611    ) -> Result<proto::ReadTextFileResponse> {
4612        let path = envelope
4613            .payload
4614            .path
4615            .ok_or_else(|| anyhow!("missing path"))?;
4616        let worktree_id = WorktreeId::from_proto(path.worktree_id);
4617        let path = PathBuf::from(path.path);
4618        let response = this
4619            .update(&mut cx, |this, cx| {
4620                let worktree = this.worktree_for_id(worktree_id, cx)?;
4621                let delegate = LocalLspAdapterDelegate::for_local(this, &worktree, cx);
4622                anyhow::Ok(cx.spawn(|_, _| async move { delegate.read_text_file(path).await }))
4623            })??
4624            .await?;
4625
4626        Ok(proto::ReadTextFileResponse { text: response })
4627    }
4628
4629    async fn handle_apply_additional_edits_for_completion(
4630        this: Model<Self>,
4631        envelope: TypedEnvelope<proto::ApplyCompletionAdditionalEdits>,
4632        mut cx: AsyncAppContext,
4633    ) -> Result<proto::ApplyCompletionAdditionalEditsResponse> {
4634        let (buffer, completion) = this.update(&mut cx, |this, cx| {
4635            let buffer_id = BufferId::new(envelope.payload.buffer_id)?;
4636            let buffer = this.buffer_store.read(cx).get_existing(buffer_id)?;
4637            let completion = Self::deserialize_completion(
4638                envelope
4639                    .payload
4640                    .completion
4641                    .ok_or_else(|| anyhow!("invalid completion"))?,
4642            )?;
4643            anyhow::Ok((buffer, completion))
4644        })??;
4645
4646        let apply_additional_edits = this.update(&mut cx, |this, cx| {
4647            this.apply_additional_edits_for_completion(
4648                buffer,
4649                Completion {
4650                    old_range: completion.old_range,
4651                    new_text: completion.new_text,
4652                    lsp_completion: completion.lsp_completion,
4653                    server_id: completion.server_id,
4654                    documentation: None,
4655                    label: CodeLabel {
4656                        text: Default::default(),
4657                        runs: Default::default(),
4658                        filter_range: Default::default(),
4659                    },
4660                    confirm: None,
4661                },
4662                false,
4663                cx,
4664            )
4665        })?;
4666
4667        Ok(proto::ApplyCompletionAdditionalEditsResponse {
4668            transaction: apply_additional_edits
4669                .await?
4670                .as_ref()
4671                .map(language::proto::serialize_transaction),
4672        })
4673    }
4674
4675    fn language_settings<'a>(
4676        &'a self,
4677        worktree: &'a Model<Worktree>,
4678        language: &LanguageName,
4679        cx: &'a mut ModelContext<Self>,
4680    ) -> &'a LanguageSettings {
4681        let root_file = worktree.update(cx, |tree, cx| tree.root_file(cx));
4682        all_language_settings(root_file.map(|f| f as _).as_ref(), cx).language(Some(language))
4683    }
4684
4685    pub fn start_language_servers(
4686        &mut self,
4687        worktree: &Model<Worktree>,
4688        language: LanguageName,
4689        cx: &mut ModelContext<Self>,
4690    ) {
4691        let settings = self.language_settings(worktree, &language, cx);
4692        if !settings.enable_language_server || self.mode.is_remote() {
4693            return;
4694        }
4695
4696        let available_lsp_adapters = self.languages.clone().lsp_adapters(&language);
4697        let available_language_servers = available_lsp_adapters
4698            .iter()
4699            .map(|lsp_adapter| lsp_adapter.name.clone())
4700            .collect::<Vec<_>>();
4701
4702        let desired_language_servers =
4703            settings.customized_language_servers(&available_language_servers);
4704
4705        let mut enabled_lsp_adapters: Vec<Arc<CachedLspAdapter>> = Vec::new();
4706        for desired_language_server in desired_language_servers {
4707            if let Some(adapter) = available_lsp_adapters
4708                .iter()
4709                .find(|adapter| adapter.name == desired_language_server)
4710            {
4711                enabled_lsp_adapters.push(adapter.clone());
4712                continue;
4713            }
4714
4715            if let Some(adapter) = self
4716                .languages
4717                .load_available_lsp_adapter(&desired_language_server)
4718            {
4719                self.languages
4720                    .register_lsp_adapter(language.clone(), adapter.adapter.clone());
4721                enabled_lsp_adapters.push(adapter);
4722                continue;
4723            }
4724
4725            log::warn!(
4726                "no language server found matching '{}'",
4727                desired_language_server.0
4728            );
4729        }
4730
4731        for adapter in &enabled_lsp_adapters {
4732            self.start_language_server(worktree, adapter.clone(), language.clone(), cx);
4733        }
4734
4735        // After starting all the language servers, reorder them to reflect the desired order
4736        // based on the settings.
4737        //
4738        // This is done, in part, to ensure that language servers loaded at different points
4739        // (e.g., native vs extension) still end up in the right order at the end, rather than
4740        // it being based on which language server happened to be loaded in first.
4741        self.languages
4742            .reorder_language_servers(&language, enabled_lsp_adapters);
4743    }
4744
4745    fn start_language_server_on_ssh_host(
4746        &mut self,
4747        worktree: &Model<Worktree>,
4748        adapter: Arc<CachedLspAdapter>,
4749        language: LanguageName,
4750        cx: &mut ModelContext<Self>,
4751    ) {
4752        let ssh = self.as_ssh().unwrap();
4753
4754        let delegate = Arc::new(SshLspAdapterDelegate {
4755            lsp_store: cx.handle().downgrade(),
4756            worktree: worktree.read(cx).snapshot(),
4757            upstream_client: ssh.upstream_client.clone(),
4758            language_registry: self.languages.clone(),
4759        }) as Arc<dyn LspAdapterDelegate>;
4760
4761        // TODO: We should use `adapter` here instead of reaching through the `CachedLspAdapter`.
4762        let lsp_adapter = adapter.adapter.clone();
4763
4764        let project_id = self.project_id;
4765        let worktree_id = worktree.read(cx).id().to_proto();
4766        let upstream_client = ssh.upstream_client.clone();
4767        let name = adapter.name().to_string();
4768
4769        let Some(available_language) = self.languages.available_language_for_name(&language) else {
4770            log::error!("failed to find available language {language}");
4771            return;
4772        };
4773
4774        let task = cx.spawn(|_, cx| async move {
4775            let user_binary_task = lsp_adapter.check_if_user_installed(delegate.as_ref(), &cx);
4776            let binary = match user_binary_task.await {
4777                Some(binary) => binary,
4778                None => {
4779                    return Err(anyhow!(
4780                        "Downloading language server for ssh host is not supported yet"
4781                    ))
4782                }
4783            };
4784
4785            let name = adapter.name().to_string();
4786            let code_action_kinds = adapter
4787                .adapter
4788                .code_action_kinds()
4789                .map(|kinds| serde_json::to_string(&kinds))
4790                .transpose()?;
4791            let get_options = adapter.adapter.clone().initialization_options(&delegate);
4792            let initialization_options = get_options
4793                .await?
4794                .map(|options| serde_json::to_string(&options))
4795                .transpose()?;
4796
4797            let language_server_command = proto::LanguageServerCommand {
4798                path: binary.path.to_string_lossy().to_string(),
4799                arguments: binary
4800                    .arguments
4801                    .iter()
4802                    .map(|args| args.to_string_lossy().to_string())
4803                    .collect(),
4804                env: binary.env.unwrap_or_default().into_iter().collect(),
4805            };
4806
4807            upstream_client
4808                .request(proto::CreateLanguageServer {
4809                    project_id,
4810                    worktree_id,
4811                    name,
4812                    binary: Some(language_server_command),
4813                    initialization_options,
4814                    code_action_kinds,
4815                    language: Some(proto::AvailableLanguage {
4816                        name: language.to_proto(),
4817                        matcher: serde_json::to_string(&available_language.matcher())?,
4818                    }),
4819                })
4820                .await
4821        });
4822        cx.spawn(|this, mut cx| async move {
4823            if let Err(e) = task.await {
4824                this.update(&mut cx, |_this, cx| {
4825                    cx.emit(LspStoreEvent::Notification(format!(
4826                        "failed to start {}: {}",
4827                        name, e
4828                    )))
4829                })
4830                .ok();
4831            }
4832        })
4833        .detach();
4834    }
4835
4836    fn start_language_server(
4837        &mut self,
4838        worktree_handle: &Model<Worktree>,
4839        adapter: Arc<CachedLspAdapter>,
4840        language: LanguageName,
4841        cx: &mut ModelContext<Self>,
4842    ) {
4843        if self.mode.is_remote() {
4844            return;
4845        }
4846
4847        let worktree = worktree_handle.read(cx);
4848        let worktree_id = worktree.id();
4849        let worktree_path = worktree.abs_path();
4850        let key = (worktree_id, adapter.name.clone());
4851        if self.language_server_ids.contains_key(&key) {
4852            return;
4853        }
4854
4855        if self.mode.is_ssh() {
4856            self.start_language_server_on_ssh_host(worktree_handle, adapter, language, cx);
4857            return;
4858        }
4859
4860        if adapter.reinstall_attempt_count.load(SeqCst) > MAX_SERVER_REINSTALL_ATTEMPT_COUNT {
4861            return;
4862        }
4863
4864        let local = self.as_local().unwrap();
4865
4866        let stderr_capture = Arc::new(Mutex::new(Some(String::new())));
4867        let lsp_adapter_delegate = LocalLspAdapterDelegate::for_local(self, worktree_handle, cx);
4868        let project_environment = local.environment.update(cx, |environment, cx| {
4869            environment.get_environment(Some(worktree_id), Some(worktree_path.clone()), cx)
4870        });
4871
4872        let pending_server = match self.languages.create_pending_language_server(
4873            stderr_capture.clone(),
4874            language.clone(),
4875            adapter.clone(),
4876            Arc::clone(&worktree_path),
4877            lsp_adapter_delegate.clone(),
4878            project_environment,
4879            cx,
4880        ) {
4881            Some(pending_server) => pending_server,
4882            None => return,
4883        };
4884
4885        let project_settings = ProjectSettings::get(
4886            Some(SettingsLocation {
4887                worktree_id,
4888                path: Path::new(""),
4889            }),
4890            cx,
4891        );
4892
4893        // We need some on the SSH client, and some on SSH host
4894        let lsp = project_settings.lsp.get(&adapter.name.0);
4895        let override_options = lsp.and_then(|s| s.initialization_options.clone());
4896
4897        let server_id = pending_server.server_id;
4898        let container_dir = pending_server.container_dir.clone();
4899        let state = LanguageServerState::Starting({
4900            let adapter = adapter.clone();
4901            let server_name = adapter.name.0.clone();
4902            let language = language.clone();
4903            let key = key.clone();
4904
4905            cx.spawn(move |this, mut cx| async move {
4906                let result = Self::setup_and_insert_language_server(
4907                    this.clone(),
4908                    lsp_adapter_delegate,
4909                    override_options,
4910                    pending_server,
4911                    adapter.clone(),
4912                    language.clone(),
4913                    server_id,
4914                    key,
4915                    &mut cx,
4916                )
4917                .await;
4918
4919                match result {
4920                    Ok(server) => {
4921                        stderr_capture.lock().take();
4922                        server
4923                    }
4924
4925                    Err(err) => {
4926                        log::error!("failed to start language server {server_name:?}: {err}");
4927                        log::error!("server stderr: {:?}", stderr_capture.lock().take());
4928
4929                        let this = this.upgrade()?;
4930                        let container_dir = container_dir?;
4931
4932                        let attempt_count = adapter.reinstall_attempt_count.fetch_add(1, SeqCst);
4933                        if attempt_count >= MAX_SERVER_REINSTALL_ATTEMPT_COUNT {
4934                            let max = MAX_SERVER_REINSTALL_ATTEMPT_COUNT;
4935                            log::error!("Hit {max} reinstallation attempts for {server_name:?}");
4936                            return None;
4937                        }
4938
4939                        log::info!(
4940                            "retrying installation of language server {server_name:?} in {}s",
4941                            SERVER_REINSTALL_DEBOUNCE_TIMEOUT.as_secs()
4942                        );
4943                        cx.background_executor()
4944                            .timer(SERVER_REINSTALL_DEBOUNCE_TIMEOUT)
4945                            .await;
4946
4947                        let installation_test_binary = adapter
4948                            .installation_test_binary(container_dir.to_path_buf())
4949                            .await;
4950
4951                        this.update(&mut cx, |_, cx| {
4952                            Self::check_errored_server(
4953                                language,
4954                                adapter,
4955                                server_id,
4956                                installation_test_binary,
4957                                cx,
4958                            )
4959                        })
4960                        .ok();
4961
4962                        None
4963                    }
4964                }
4965            })
4966        });
4967
4968        self.as_local_mut()
4969            .unwrap()
4970            .language_servers
4971            .insert(server_id, state);
4972        self.language_server_ids.insert(key, server_id);
4973    }
4974
4975    #[allow(clippy::too_many_arguments)]
4976    async fn setup_and_insert_language_server(
4977        this: WeakModel<Self>,
4978        delegate: Arc<dyn LspAdapterDelegate>,
4979        override_initialization_options: Option<serde_json::Value>,
4980        pending_server: PendingLanguageServer,
4981        adapter: Arc<CachedLspAdapter>,
4982        language: LanguageName,
4983        server_id: LanguageServerId,
4984        key: (WorktreeId, LanguageServerName),
4985        cx: &mut AsyncAppContext,
4986    ) -> Result<Option<Arc<LanguageServer>>> {
4987        let language_server = Self::setup_pending_language_server(
4988            this.clone(),
4989            override_initialization_options,
4990            pending_server,
4991            delegate,
4992            adapter.clone(),
4993            server_id,
4994            cx,
4995        )
4996        .await?;
4997
4998        let this = match this.upgrade() {
4999            Some(this) => this,
5000            None => return Err(anyhow!("failed to upgrade project handle")),
5001        };
5002
5003        this.update(cx, |this, cx| {
5004            this.insert_newly_running_language_server(
5005                language,
5006                adapter,
5007                language_server.clone(),
5008                server_id,
5009                key,
5010                cx,
5011            )
5012        })??;
5013
5014        Ok(Some(language_server))
5015    }
5016
5017    fn reinstall_language_server(
5018        &mut self,
5019        language: LanguageName,
5020        adapter: Arc<CachedLspAdapter>,
5021        server_id: LanguageServerId,
5022        cx: &mut ModelContext<Self>,
5023    ) -> Option<Task<()>> {
5024        log::info!("beginning to reinstall server");
5025
5026        if let Some(local) = self.as_local_mut() {
5027            let existing_server = match local.language_servers.remove(&server_id) {
5028                Some(LanguageServerState::Running { server, .. }) => Some(server),
5029                _ => None,
5030            };
5031
5032            self.worktree_store.update(cx, |store, cx| {
5033                for worktree in store.worktrees() {
5034                    let key = (worktree.read(cx).id(), adapter.name.clone());
5035                    self.language_server_ids.remove(&key);
5036                }
5037            });
5038
5039            Some(cx.spawn(move |this, mut cx| async move {
5040                if let Some(task) = existing_server.and_then(|server| server.shutdown()) {
5041                    log::info!("shutting down existing server");
5042                    task.await;
5043                }
5044
5045                // TODO: This is race-safe with regards to preventing new instances from
5046                // starting while deleting, but existing instances in other projects are going
5047                // to be very confused and messed up
5048                let Some(task) = this
5049                    .update(&mut cx, |this, cx| {
5050                        this.languages.delete_server_container(adapter.clone(), cx)
5051                    })
5052                    .log_err()
5053                else {
5054                    return;
5055                };
5056                task.await;
5057
5058                this.update(&mut cx, |this, cx| {
5059                    for worktree in this.worktree_store.read(cx).worktrees().collect::<Vec<_>>() {
5060                        this.start_language_server(
5061                            &worktree,
5062                            adapter.clone(),
5063                            language.clone(),
5064                            cx,
5065                        );
5066                    }
5067                })
5068                .ok();
5069            }))
5070        } else if let Some(_ssh_store) = self.as_ssh() {
5071            // TODO
5072            None
5073        } else {
5074            None
5075        }
5076    }
5077
5078    async fn shutdown_language_server(
5079        server_state: Option<LanguageServerState>,
5080        name: Arc<str>,
5081        cx: AsyncAppContext,
5082    ) {
5083        let server = match server_state {
5084            Some(LanguageServerState::Starting(task)) => {
5085                let mut timer = cx
5086                    .background_executor()
5087                    .timer(SERVER_LAUNCHING_BEFORE_SHUTDOWN_TIMEOUT)
5088                    .fuse();
5089
5090                select! {
5091                    server = task.fuse() => server,
5092                    _ = timer => {
5093                        log::info!(
5094                            "timeout waiting for language server {} to finish launching before stopping",
5095                            name
5096                        );
5097                        None
5098                    },
5099                }
5100            }
5101
5102            Some(LanguageServerState::Running { server, .. }) => Some(server),
5103
5104            None => None,
5105        };
5106
5107        if let Some(server) = server {
5108            if let Some(shutdown) = server.shutdown() {
5109                shutdown.await;
5110            }
5111        }
5112    }
5113
5114    // Returns a list of all of the worktrees which no longer have a language server and the root path
5115    // for the stopped server
5116    pub fn stop_language_server(
5117        &mut self,
5118        worktree_id: WorktreeId,
5119        adapter_name: LanguageServerName,
5120        cx: &mut ModelContext<Self>,
5121    ) -> Task<Vec<WorktreeId>> {
5122        let key = (worktree_id, adapter_name);
5123        if self.mode.is_local() {
5124            if let Some(server_id) = self.language_server_ids.remove(&key) {
5125                let name = key.1 .0;
5126                log::info!("stopping language server {name}");
5127
5128                // Remove other entries for this language server as well
5129                let mut orphaned_worktrees = vec![worktree_id];
5130                let other_keys = self.language_server_ids.keys().cloned().collect::<Vec<_>>();
5131                for other_key in other_keys {
5132                    if self.language_server_ids.get(&other_key) == Some(&server_id) {
5133                        self.language_server_ids.remove(&other_key);
5134                        orphaned_worktrees.push(other_key.0);
5135                    }
5136                }
5137
5138                self.buffer_store.update(cx, |buffer_store, cx| {
5139                    for buffer in buffer_store.buffers() {
5140                        buffer.update(cx, |buffer, cx| {
5141                            buffer.update_diagnostics(
5142                                server_id,
5143                                DiagnosticSet::new([], buffer),
5144                                cx,
5145                            );
5146                        });
5147                    }
5148                });
5149
5150                let project_id = self.project_id;
5151                for (worktree_id, summaries) in self.diagnostic_summaries.iter_mut() {
5152                    summaries.retain(|path, summaries_by_server_id| {
5153                        if summaries_by_server_id.remove(&server_id).is_some() {
5154                            if let Some(downstream_client) = self.downstream_client.clone() {
5155                                downstream_client
5156                                    .send(proto::UpdateDiagnosticSummary {
5157                                        project_id,
5158                                        worktree_id: worktree_id.to_proto(),
5159                                        summary: Some(proto::DiagnosticSummary {
5160                                            path: path.to_string_lossy().to_string(),
5161                                            language_server_id: server_id.0 as u64,
5162                                            error_count: 0,
5163                                            warning_count: 0,
5164                                        }),
5165                                    })
5166                                    .log_err();
5167                            }
5168                            !summaries_by_server_id.is_empty()
5169                        } else {
5170                            true
5171                        }
5172                    });
5173                }
5174
5175                for diagnostics in self.diagnostics.values_mut() {
5176                    diagnostics.retain(|_, diagnostics_by_server_id| {
5177                        if let Ok(ix) =
5178                            diagnostics_by_server_id.binary_search_by_key(&server_id, |e| e.0)
5179                        {
5180                            diagnostics_by_server_id.remove(ix);
5181                            !diagnostics_by_server_id.is_empty()
5182                        } else {
5183                            true
5184                        }
5185                    });
5186                }
5187
5188                self.as_local_mut()
5189                    .unwrap()
5190                    .language_server_watched_paths
5191                    .remove(&server_id);
5192                self.language_server_statuses.remove(&server_id);
5193                cx.notify();
5194
5195                let server_state = self
5196                    .as_local_mut()
5197                    .unwrap()
5198                    .language_servers
5199                    .remove(&server_id);
5200                cx.emit(LspStoreEvent::LanguageServerRemoved(server_id));
5201                cx.spawn(move |_, cx| async move {
5202                    Self::shutdown_language_server(server_state, name, cx).await;
5203                    orphaned_worktrees
5204                })
5205            } else {
5206                Task::ready(Vec::new())
5207            }
5208        } else if self.mode.is_ssh() {
5209            // TODO ssh
5210            Task::ready(Vec::new())
5211        } else {
5212            Task::ready(Vec::new())
5213        }
5214    }
5215
5216    pub fn restart_language_servers_for_buffers(
5217        &mut self,
5218        buffers: impl IntoIterator<Item = Model<Buffer>>,
5219        cx: &mut ModelContext<Self>,
5220    ) {
5221        if let Some(client) = self.upstream_client() {
5222            let request = client.request(proto::RestartLanguageServers {
5223                project_id: self.project_id,
5224                buffer_ids: buffers
5225                    .into_iter()
5226                    .map(|b| b.read(cx).remote_id().to_proto())
5227                    .collect(),
5228            });
5229            cx.background_executor()
5230                .spawn(request)
5231                .detach_and_log_err(cx);
5232        } else {
5233            #[allow(clippy::mutable_key_type)]
5234            let language_server_lookup_info: HashSet<(Model<Worktree>, LanguageName)> = buffers
5235                .into_iter()
5236                .filter_map(|buffer| {
5237                    let buffer = buffer.read(cx);
5238                    let file = buffer.file()?;
5239                    let worktree = File::from_dyn(Some(file))?.worktree.clone();
5240                    let language =
5241                        self.languages
5242                            .language_for_file(file, Some(buffer.as_rope()), cx)?;
5243
5244                    Some((worktree, language.name()))
5245                })
5246                .collect();
5247
5248            for (worktree, language) in language_server_lookup_info {
5249                self.restart_language_servers(worktree, language, cx);
5250            }
5251        }
5252    }
5253
5254    pub fn restart_language_servers(
5255        &mut self,
5256        worktree: Model<Worktree>,
5257        language: LanguageName,
5258        cx: &mut ModelContext<Self>,
5259    ) {
5260        let worktree_id = worktree.read(cx).id();
5261
5262        let stop_tasks = self
5263            .languages
5264            .clone()
5265            .lsp_adapters(&language)
5266            .iter()
5267            .map(|adapter| {
5268                let stop_task = self.stop_language_server(worktree_id, adapter.name.clone(), cx);
5269                (stop_task, adapter.name.clone())
5270            })
5271            .collect::<Vec<_>>();
5272        if stop_tasks.is_empty() {
5273            return;
5274        }
5275
5276        cx.spawn(move |this, mut cx| async move {
5277            // For each stopped language server, record all of the worktrees with which
5278            // it was associated.
5279            let mut affected_worktrees = Vec::new();
5280            for (stop_task, language_server_name) in stop_tasks {
5281                for affected_worktree_id in stop_task.await {
5282                    affected_worktrees.push((affected_worktree_id, language_server_name.clone()));
5283                }
5284            }
5285
5286            this.update(&mut cx, |this, cx| {
5287                // Restart the language server for the given worktree.
5288                this.start_language_servers(&worktree, language.clone(), cx);
5289
5290                // Lookup new server ids and set them for each of the orphaned worktrees
5291                for (affected_worktree_id, language_server_name) in affected_worktrees {
5292                    if let Some(new_server_id) = this
5293                        .language_server_ids
5294                        .get(&(worktree_id, language_server_name.clone()))
5295                        .cloned()
5296                    {
5297                        this.language_server_ids
5298                            .insert((affected_worktree_id, language_server_name), new_server_id);
5299                    }
5300                }
5301            })
5302            .ok();
5303        })
5304        .detach();
5305    }
5306
5307    fn check_errored_server(
5308        language: LanguageName,
5309        adapter: Arc<CachedLspAdapter>,
5310        server_id: LanguageServerId,
5311        installation_test_binary: Option<LanguageServerBinary>,
5312        cx: &mut ModelContext<Self>,
5313    ) {
5314        if !adapter.can_be_reinstalled() {
5315            log::info!(
5316                "Validation check requested for {:?} but it cannot be reinstalled",
5317                adapter.name.0
5318            );
5319            return;
5320        }
5321
5322        cx.spawn(move |this, mut cx| async move {
5323            log::info!("About to spawn test binary");
5324
5325            // A lack of test binary counts as a failure
5326            let process = installation_test_binary.and_then(|binary| {
5327                smol::process::Command::new(&binary.path)
5328                    .current_dir(&binary.path)
5329                    .args(binary.arguments)
5330                    .stdin(Stdio::piped())
5331                    .stdout(Stdio::piped())
5332                    .stderr(Stdio::inherit())
5333                    .kill_on_drop(true)
5334                    .spawn()
5335                    .ok()
5336            });
5337
5338            const PROCESS_TIMEOUT: Duration = Duration::from_secs(5);
5339            let mut timeout = cx.background_executor().timer(PROCESS_TIMEOUT).fuse();
5340
5341            let mut errored = false;
5342            if let Some(mut process) = process {
5343                futures::select! {
5344                    status = process.status().fuse() => match status {
5345                        Ok(status) => errored = !status.success(),
5346                        Err(_) => errored = true,
5347                    },
5348
5349                    _ = timeout => {
5350                        log::info!("test binary time-ed out, this counts as a success");
5351                        _ = process.kill();
5352                    }
5353                }
5354            } else {
5355                log::warn!("test binary failed to launch");
5356                errored = true;
5357            }
5358
5359            if errored {
5360                log::warn!("test binary check failed");
5361                let task = this
5362                    .update(&mut cx, move |this, cx| {
5363                        this.reinstall_language_server(language, adapter, server_id, cx)
5364                    })
5365                    .ok()
5366                    .flatten();
5367
5368                if let Some(task) = task {
5369                    task.await;
5370                }
5371            }
5372        })
5373        .detach();
5374    }
5375
5376    async fn setup_pending_language_server(
5377        this: WeakModel<Self>,
5378        override_options: Option<serde_json::Value>,
5379        pending_server: PendingLanguageServer,
5380        delegate: Arc<dyn LspAdapterDelegate>,
5381        adapter: Arc<CachedLspAdapter>,
5382        server_id: LanguageServerId,
5383        cx: &mut AsyncAppContext,
5384    ) -> Result<Arc<LanguageServer>> {
5385        let workspace_config = adapter
5386            .adapter
5387            .clone()
5388            .workspace_configuration(&delegate, cx)
5389            .await?;
5390        // This has to come from the server
5391        let (language_server, mut initialization_options) = pending_server.task.await?;
5392
5393        let name = language_server.name();
5394        language_server
5395            .on_notification::<lsp::notification::PublishDiagnostics, _>({
5396                let adapter = adapter.clone();
5397                let this = this.clone();
5398                move |mut params, mut cx| {
5399                    let adapter = adapter.clone();
5400                    if let Some(this) = this.upgrade() {
5401                        adapter.process_diagnostics(&mut params);
5402                        // Everything else has to be on the server, Can we make it on the client?
5403                        this.update(&mut cx, |this, cx| {
5404                            this.update_diagnostics(
5405                                server_id,
5406                                params,
5407                                &adapter.disk_based_diagnostic_sources,
5408                                cx,
5409                            )
5410                            .log_err();
5411                        })
5412                        .ok();
5413                    }
5414                }
5415            })
5416            .detach();
5417
5418        language_server
5419            .on_request::<lsp::request::WorkspaceConfiguration, _, _>({
5420                let adapter = adapter.adapter.clone();
5421                let delegate = delegate.clone();
5422                move |params, mut cx| {
5423                    let adapter = adapter.clone();
5424                    let delegate = delegate.clone();
5425                    async move {
5426                        let workspace_config =
5427                            adapter.workspace_configuration(&delegate, &mut cx).await?;
5428                        Ok(params
5429                            .items
5430                            .into_iter()
5431                            .map(|item| {
5432                                if let Some(section) = &item.section {
5433                                    workspace_config
5434                                        .get(section)
5435                                        .cloned()
5436                                        .unwrap_or(serde_json::Value::Null)
5437                                } else {
5438                                    workspace_config.clone()
5439                                }
5440                            })
5441                            .collect())
5442                    }
5443                }
5444            })
5445            .detach();
5446
5447        let id = language_server.server_id();
5448        language_server
5449            .on_request::<lsp::request::WorkspaceFoldersRequest, _, _>({
5450                let this = this.clone();
5451                move |_, mut cx| {
5452                    let this = this.clone();
5453                    async move {
5454                        let Some(server) =
5455                            this.update(&mut cx, |this, _| this.language_server_for_id(id))?
5456                        else {
5457                            return Ok(None);
5458                        };
5459                        let root = server.root_path();
5460                        let Ok(uri) = Url::from_file_path(&root) else {
5461                            return Ok(None);
5462                        };
5463                        Ok(Some(vec![WorkspaceFolder {
5464                            uri,
5465                            name: Default::default(),
5466                        }]))
5467                    }
5468                }
5469            })
5470            .detach();
5471        // Even though we don't have handling for these requests, respond to them to
5472        // avoid stalling any language server like `gopls` which waits for a response
5473        // to these requests when initializing.
5474        language_server
5475            .on_request::<lsp::request::WorkDoneProgressCreate, _, _>({
5476                let this = this.clone();
5477                move |params, mut cx| {
5478                    let this = this.clone();
5479                    async move {
5480                        this.update(&mut cx, |this, _| {
5481                            if let Some(status) = this.language_server_statuses.get_mut(&server_id)
5482                            {
5483                                if let lsp::NumberOrString::String(token) = params.token {
5484                                    status.progress_tokens.insert(token);
5485                                }
5486                            }
5487                        })?;
5488
5489                        Ok(())
5490                    }
5491                }
5492            })
5493            .detach();
5494
5495        language_server
5496            .on_request::<lsp::request::RegisterCapability, _, _>({
5497                let this = this.clone();
5498                move |params, mut cx| {
5499                    let this = this.clone();
5500                    async move {
5501                        for reg in params.registrations {
5502                            match reg.method.as_str() {
5503                                "workspace/didChangeWatchedFiles" => {
5504                                    if let Some(options) = reg.register_options {
5505                                        let options = serde_json::from_value(options)?;
5506                                        this.update(&mut cx, |this, cx| {
5507                                            this.on_lsp_did_change_watched_files(
5508                                                server_id, &reg.id, options, cx,
5509                                            );
5510                                        })?;
5511                                    }
5512                                }
5513                                "textDocument/rangeFormatting" => {
5514                                    this.update(&mut cx, |this, _| {
5515                                        if let Some(server) = this.language_server_for_id(server_id)
5516                                        {
5517                                            let options = reg
5518                                                .register_options
5519                                                .map(|options| {
5520                                                    serde_json::from_value::<
5521                                                        lsp::DocumentRangeFormattingOptions,
5522                                                    >(
5523                                                        options
5524                                                    )
5525                                                })
5526                                                .transpose()?;
5527                                            let provider = match options {
5528                                                None => OneOf::Left(true),
5529                                                Some(options) => OneOf::Right(options),
5530                                            };
5531                                            server.update_capabilities(|capabilities| {
5532                                                capabilities.document_range_formatting_provider =
5533                                                    Some(provider);
5534                                            })
5535                                        }
5536                                        anyhow::Ok(())
5537                                    })??;
5538                                }
5539                                "textDocument/onTypeFormatting" => {
5540                                    this.update(&mut cx, |this, _| {
5541                                        if let Some(server) = this.language_server_for_id(server_id)
5542                                        {
5543                                            let options = reg
5544                                                .register_options
5545                                                .map(|options| {
5546                                                    serde_json::from_value::<
5547                                                        lsp::DocumentOnTypeFormattingOptions,
5548                                                    >(
5549                                                        options
5550                                                    )
5551                                                })
5552                                                .transpose()?;
5553                                            if let Some(options) = options {
5554                                                server.update_capabilities(|capabilities| {
5555                                                    capabilities
5556                                                        .document_on_type_formatting_provider =
5557                                                        Some(options);
5558                                                })
5559                                            }
5560                                        }
5561                                        anyhow::Ok(())
5562                                    })??;
5563                                }
5564                                "textDocument/formatting" => {
5565                                    this.update(&mut cx, |this, _| {
5566                                        if let Some(server) = this.language_server_for_id(server_id)
5567                                        {
5568                                            let options = reg
5569                                                .register_options
5570                                                .map(|options| {
5571                                                    serde_json::from_value::<
5572                                                        lsp::DocumentFormattingOptions,
5573                                                    >(
5574                                                        options
5575                                                    )
5576                                                })
5577                                                .transpose()?;
5578                                            let provider = match options {
5579                                                None => OneOf::Left(true),
5580                                                Some(options) => OneOf::Right(options),
5581                                            };
5582                                            server.update_capabilities(|capabilities| {
5583                                                capabilities.document_formatting_provider =
5584                                                    Some(provider);
5585                                            })
5586                                        }
5587                                        anyhow::Ok(())
5588                                    })??;
5589                                }
5590                                _ => log::warn!("unhandled capability registration: {reg:?}"),
5591                            }
5592                        }
5593                        Ok(())
5594                    }
5595                }
5596            })
5597            .detach();
5598
5599        language_server
5600            .on_request::<lsp::request::UnregisterCapability, _, _>({
5601                let this = this.clone();
5602                move |params, mut cx| {
5603                    let this = this.clone();
5604                    async move {
5605                        for unreg in params.unregisterations.iter() {
5606                            match unreg.method.as_str() {
5607                                "workspace/didChangeWatchedFiles" => {
5608                                    this.update(&mut cx, |this, cx| {
5609                                        this.on_lsp_unregister_did_change_watched_files(
5610                                            server_id, &unreg.id, cx,
5611                                        );
5612                                    })?;
5613                                }
5614                                "textDocument/rangeFormatting" => {
5615                                    this.update(&mut cx, |this, _| {
5616                                        if let Some(server) = this.language_server_for_id(server_id)
5617                                        {
5618                                            server.update_capabilities(|capabilities| {
5619                                                capabilities.document_range_formatting_provider =
5620                                                    None
5621                                            })
5622                                        }
5623                                    })?;
5624                                }
5625                                "textDocument/onTypeFormatting" => {
5626                                    this.update(&mut cx, |this, _| {
5627                                        if let Some(server) = this.language_server_for_id(server_id)
5628                                        {
5629                                            server.update_capabilities(|capabilities| {
5630                                                capabilities.document_on_type_formatting_provider =
5631                                                    None;
5632                                            })
5633                                        }
5634                                    })?;
5635                                }
5636                                "textDocument/formatting" => {
5637                                    this.update(&mut cx, |this, _| {
5638                                        if let Some(server) = this.language_server_for_id(server_id)
5639                                        {
5640                                            server.update_capabilities(|capabilities| {
5641                                                capabilities.document_formatting_provider = None;
5642                                            })
5643                                        }
5644                                    })?;
5645                                }
5646                                _ => log::warn!("unhandled capability unregistration: {unreg:?}"),
5647                            }
5648                        }
5649                        Ok(())
5650                    }
5651                }
5652            })
5653            .detach();
5654
5655        language_server
5656            .on_request::<lsp::request::ApplyWorkspaceEdit, _, _>({
5657                let adapter = adapter.clone();
5658                let this = this.clone();
5659                move |params, cx| {
5660                    Self::on_lsp_workspace_edit(
5661                        this.clone(),
5662                        params,
5663                        server_id,
5664                        adapter.clone(),
5665                        cx,
5666                    )
5667                }
5668            })
5669            .detach();
5670
5671        language_server
5672            .on_request::<lsp::request::InlayHintRefreshRequest, _, _>({
5673                let this = this.clone();
5674                move |(), mut cx| {
5675                    let this = this.clone();
5676                    async move {
5677                        this.update(&mut cx, |this, cx| {
5678                            cx.emit(LspStoreEvent::RefreshInlayHints);
5679                            this.downstream_client.as_ref().map(|client| {
5680                                client.send(proto::RefreshInlayHints {
5681                                    project_id: this.project_id,
5682                                })
5683                            })
5684                        })?
5685                        .transpose()?;
5686                        Ok(())
5687                    }
5688                }
5689            })
5690            .detach();
5691
5692        language_server
5693            .on_request::<lsp::request::ShowMessageRequest, _, _>({
5694                let this = this.clone();
5695                let name = name.to_string();
5696                move |params, mut cx| {
5697                    let this = this.clone();
5698                    let name = name.to_string();
5699                    async move {
5700                        let actions = params.actions.unwrap_or_default();
5701                        let (tx, mut rx) = smol::channel::bounded(1);
5702                        let request = LanguageServerPromptRequest {
5703                            level: match params.typ {
5704                                lsp::MessageType::ERROR => PromptLevel::Critical,
5705                                lsp::MessageType::WARNING => PromptLevel::Warning,
5706                                _ => PromptLevel::Info,
5707                            },
5708                            message: params.message,
5709                            actions,
5710                            response_channel: tx,
5711                            lsp_name: name.clone(),
5712                        };
5713
5714                        let did_update = this
5715                            .update(&mut cx, |_, cx| {
5716                                cx.emit(LspStoreEvent::LanguageServerPrompt(request));
5717                            })
5718                            .is_ok();
5719                        if did_update {
5720                            let response = rx.next().await;
5721
5722                            Ok(response)
5723                        } else {
5724                            Ok(None)
5725                        }
5726                    }
5727                }
5728            })
5729            .detach();
5730
5731        let disk_based_diagnostics_progress_token =
5732            adapter.disk_based_diagnostics_progress_token.clone();
5733
5734        language_server
5735            .on_notification::<ServerStatus, _>({
5736                let this = this.clone();
5737                let name = name.to_string();
5738                move |params, mut cx| {
5739                    let this = this.clone();
5740                    let name = name.to_string();
5741                    if let Some(ref message) = params.message {
5742                        let message = message.trim();
5743                        if !message.is_empty() {
5744                            let formatted_message = format!(
5745                                "Language server {name} (id {server_id}) status update: {message}"
5746                            );
5747                            match params.health {
5748                                ServerHealthStatus::Ok => log::info!("{}", formatted_message),
5749                                ServerHealthStatus::Warning => log::warn!("{}", formatted_message),
5750                                ServerHealthStatus::Error => {
5751                                    log::error!("{}", formatted_message);
5752                                    let (tx, _rx) = smol::channel::bounded(1);
5753                                    let request = LanguageServerPromptRequest {
5754                                        level: PromptLevel::Critical,
5755                                        message: params.message.unwrap_or_default(),
5756                                        actions: Vec::new(),
5757                                        response_channel: tx,
5758                                        lsp_name: name.clone(),
5759                                    };
5760                                    let _ = this
5761                                        .update(&mut cx, |_, cx| {
5762                                            cx.emit(LspStoreEvent::LanguageServerPrompt(request));
5763                                        })
5764                                        .ok();
5765                                }
5766                                ServerHealthStatus::Other(status) => {
5767                                    log::info!(
5768                                        "Unknown server health: {status}\n{formatted_message}"
5769                                    )
5770                                }
5771                            }
5772                        }
5773                    }
5774                }
5775            })
5776            .detach();
5777        language_server
5778            .on_notification::<lsp::notification::ShowMessage, _>({
5779                let this = this.clone();
5780                let name = name.to_string();
5781                move |params, mut cx| {
5782                    let this = this.clone();
5783                    let name = name.to_string();
5784
5785                    let (tx, _) = smol::channel::bounded(1);
5786                    let request = LanguageServerPromptRequest {
5787                        level: match params.typ {
5788                            lsp::MessageType::ERROR => PromptLevel::Critical,
5789                            lsp::MessageType::WARNING => PromptLevel::Warning,
5790                            _ => PromptLevel::Info,
5791                        },
5792                        message: params.message,
5793                        actions: vec![],
5794                        response_channel: tx,
5795                        lsp_name: name.clone(),
5796                    };
5797
5798                    let _ = this.update(&mut cx, |_, cx| {
5799                        cx.emit(LspStoreEvent::LanguageServerPrompt(request));
5800                    });
5801                }
5802            })
5803            .detach();
5804        language_server
5805            .on_notification::<lsp::notification::Progress, _>({
5806                let this = this.clone();
5807                move |params, mut cx| {
5808                    if let Some(this) = this.upgrade() {
5809                        this.update(&mut cx, |this, cx| {
5810                            this.on_lsp_progress(
5811                                params,
5812                                server_id,
5813                                disk_based_diagnostics_progress_token.clone(),
5814                                cx,
5815                            );
5816                        })
5817                        .ok();
5818                    }
5819                }
5820            })
5821            .detach();
5822
5823        language_server
5824            .on_notification::<lsp::notification::LogMessage, _>({
5825                let this = this.clone();
5826                move |params, mut cx| {
5827                    if let Some(this) = this.upgrade() {
5828                        this.update(&mut cx, |_, cx| {
5829                            cx.emit(LspStoreEvent::LanguageServerLog(
5830                                server_id,
5831                                LanguageServerLogType::Log(params.typ),
5832                                params.message,
5833                            ));
5834                        })
5835                        .ok();
5836                    }
5837                }
5838            })
5839            .detach();
5840
5841        language_server
5842            .on_notification::<lsp::notification::LogTrace, _>({
5843                let this = this.clone();
5844                move |params, mut cx| {
5845                    if let Some(this) = this.upgrade() {
5846                        this.update(&mut cx, |_, cx| {
5847                            cx.emit(LspStoreEvent::LanguageServerLog(
5848                                server_id,
5849                                LanguageServerLogType::Trace(params.verbose),
5850                                params.message,
5851                            ));
5852                        })
5853                        .ok();
5854                    }
5855                }
5856            })
5857            .detach();
5858
5859        match (&mut initialization_options, override_options) {
5860            (Some(initialization_options), Some(override_options)) => {
5861                merge_json_value_into(override_options, initialization_options);
5862            }
5863            (None, override_options) => initialization_options = override_options,
5864            _ => {}
5865        }
5866
5867        let language_server = cx
5868            .update(|cx| language_server.initialize(initialization_options, cx))?
5869            .await
5870            .inspect_err(|_| {
5871                if let Some(this) = this.upgrade() {
5872                    this.update(cx, |_, cx| {
5873                        cx.emit(LspStoreEvent::LanguageServerRemoved(server_id))
5874                    })
5875                    .ok();
5876                }
5877            })?;
5878
5879        language_server
5880            .notify::<lsp::notification::DidChangeConfiguration>(
5881                lsp::DidChangeConfigurationParams {
5882                    settings: workspace_config,
5883                },
5884            )
5885            .ok();
5886
5887        Ok(language_server)
5888    }
5889
5890    pub fn update_diagnostics(
5891        &mut self,
5892        language_server_id: LanguageServerId,
5893        mut params: lsp::PublishDiagnosticsParams,
5894        disk_based_sources: &[String],
5895        cx: &mut ModelContext<Self>,
5896    ) -> Result<()> {
5897        let abs_path = params
5898            .uri
5899            .to_file_path()
5900            .map_err(|_| anyhow!("URI is not a file"))?;
5901        let mut diagnostics = Vec::default();
5902        let mut primary_diagnostic_group_ids = HashMap::default();
5903        let mut sources_by_group_id = HashMap::default();
5904        let mut supporting_diagnostics = HashMap::default();
5905
5906        // Ensure that primary diagnostics are always the most severe
5907        params.diagnostics.sort_by_key(|item| item.severity);
5908
5909        for diagnostic in &params.diagnostics {
5910            let source = diagnostic.source.as_ref();
5911            let code = diagnostic.code.as_ref().map(|code| match code {
5912                lsp::NumberOrString::Number(code) => code.to_string(),
5913                lsp::NumberOrString::String(code) => code.clone(),
5914            });
5915            let range = range_from_lsp(diagnostic.range);
5916            let is_supporting = diagnostic
5917                .related_information
5918                .as_ref()
5919                .map_or(false, |infos| {
5920                    infos.iter().any(|info| {
5921                        primary_diagnostic_group_ids.contains_key(&(
5922                            source,
5923                            code.clone(),
5924                            range_from_lsp(info.location.range),
5925                        ))
5926                    })
5927                });
5928
5929            let is_unnecessary = diagnostic.tags.as_ref().map_or(false, |tags| {
5930                tags.iter().any(|tag| *tag == DiagnosticTag::UNNECESSARY)
5931            });
5932
5933            if is_supporting {
5934                supporting_diagnostics.insert(
5935                    (source, code.clone(), range),
5936                    (diagnostic.severity, is_unnecessary),
5937                );
5938            } else {
5939                let group_id = post_inc(&mut self.next_diagnostic_group_id);
5940                let is_disk_based =
5941                    source.map_or(false, |source| disk_based_sources.contains(source));
5942
5943                sources_by_group_id.insert(group_id, source);
5944                primary_diagnostic_group_ids
5945                    .insert((source, code.clone(), range.clone()), group_id);
5946
5947                diagnostics.push(DiagnosticEntry {
5948                    range,
5949                    diagnostic: Diagnostic {
5950                        source: diagnostic.source.clone(),
5951                        code: code.clone(),
5952                        severity: diagnostic.severity.unwrap_or(DiagnosticSeverity::ERROR),
5953                        message: diagnostic.message.trim().to_string(),
5954                        group_id,
5955                        is_primary: true,
5956                        is_disk_based,
5957                        is_unnecessary,
5958                        data: diagnostic.data.clone(),
5959                    },
5960                });
5961                if let Some(infos) = &diagnostic.related_information {
5962                    for info in infos {
5963                        if info.location.uri == params.uri && !info.message.is_empty() {
5964                            let range = range_from_lsp(info.location.range);
5965                            diagnostics.push(DiagnosticEntry {
5966                                range,
5967                                diagnostic: Diagnostic {
5968                                    source: diagnostic.source.clone(),
5969                                    code: code.clone(),
5970                                    severity: DiagnosticSeverity::INFORMATION,
5971                                    message: info.message.trim().to_string(),
5972                                    group_id,
5973                                    is_primary: false,
5974                                    is_disk_based,
5975                                    is_unnecessary: false,
5976                                    data: diagnostic.data.clone(),
5977                                },
5978                            });
5979                        }
5980                    }
5981                }
5982            }
5983        }
5984
5985        for entry in &mut diagnostics {
5986            let diagnostic = &mut entry.diagnostic;
5987            if !diagnostic.is_primary {
5988                let source = *sources_by_group_id.get(&diagnostic.group_id).unwrap();
5989                if let Some(&(severity, is_unnecessary)) = supporting_diagnostics.get(&(
5990                    source,
5991                    diagnostic.code.clone(),
5992                    entry.range.clone(),
5993                )) {
5994                    if let Some(severity) = severity {
5995                        diagnostic.severity = severity;
5996                    }
5997                    diagnostic.is_unnecessary = is_unnecessary;
5998                }
5999            }
6000        }
6001
6002        self.update_diagnostic_entries(
6003            language_server_id,
6004            abs_path,
6005            params.version,
6006            diagnostics,
6007            cx,
6008        )?;
6009        Ok(())
6010    }
6011
6012    fn insert_newly_running_language_server(
6013        &mut self,
6014        language: LanguageName,
6015        adapter: Arc<CachedLspAdapter>,
6016        language_server: Arc<LanguageServer>,
6017        server_id: LanguageServerId,
6018        key: (WorktreeId, LanguageServerName),
6019        cx: &mut ModelContext<Self>,
6020    ) -> Result<()> {
6021        // If the language server for this key doesn't match the server id, don't store the
6022        // server. Which will cause it to be dropped, killing the process
6023        if self
6024            .language_server_ids
6025            .get(&key)
6026            .map(|id| id != &server_id)
6027            .unwrap_or(false)
6028        {
6029            return Ok(());
6030        }
6031
6032        // Update language_servers collection with Running variant of LanguageServerState
6033        // indicating that the server is up and running and ready
6034        if let Some(local) = self.as_local_mut() {
6035            local.language_servers.insert(
6036                server_id,
6037                LanguageServerState::Running {
6038                    adapter: adapter.clone(),
6039                    language: language.clone(),
6040                    server: language_server.clone(),
6041                    simulate_disk_based_diagnostics_completion: None,
6042                },
6043            );
6044        }
6045
6046        self.language_server_statuses.insert(
6047            server_id,
6048            LanguageServerStatus {
6049                name: language_server.name().to_string(),
6050                pending_work: Default::default(),
6051                has_pending_diagnostic_updates: false,
6052                progress_tokens: Default::default(),
6053            },
6054        );
6055
6056        cx.emit(LspStoreEvent::LanguageServerAdded(server_id));
6057
6058        if let Some(downstream_client) = self.downstream_client.as_ref() {
6059            downstream_client.send(proto::StartLanguageServer {
6060                project_id: self.project_id,
6061                server: Some(proto::LanguageServer {
6062                    id: server_id.0 as u64,
6063                    name: language_server.name().to_string(),
6064                }),
6065            })?;
6066        }
6067
6068        // Tell the language server about every open buffer in the worktree that matches the language.
6069        self.buffer_store.update(cx, |buffer_store, cx| {
6070            for buffer_handle in buffer_store.buffers() {
6071                let buffer = buffer_handle.read(cx);
6072                let file = match File::from_dyn(buffer.file()) {
6073                    Some(file) => file,
6074                    None => continue,
6075                };
6076                let language = match buffer.language() {
6077                    Some(language) => language,
6078                    None => continue,
6079                };
6080
6081                if file.worktree.read(cx).id() != key.0
6082                    || !self
6083                        .languages
6084                        .lsp_adapters(&language.name())
6085                        .iter()
6086                        .any(|a| a.name == key.1)
6087                {
6088                    continue;
6089                }
6090
6091                let file = match file.as_local() {
6092                    Some(file) => file,
6093                    None => continue,
6094                };
6095
6096                let versions = self
6097                    .buffer_snapshots
6098                    .entry(buffer.remote_id())
6099                    .or_default()
6100                    .entry(server_id)
6101                    .or_insert_with(|| {
6102                        vec![LspBufferSnapshot {
6103                            version: 0,
6104                            snapshot: buffer.text_snapshot(),
6105                        }]
6106                    });
6107
6108                let snapshot = versions.last().unwrap();
6109                let version = snapshot.version;
6110                let initial_snapshot = &snapshot.snapshot;
6111                let uri = lsp::Url::from_file_path(file.abs_path(cx)).unwrap();
6112                language_server.notify::<lsp::notification::DidOpenTextDocument>(
6113                    lsp::DidOpenTextDocumentParams {
6114                        text_document: lsp::TextDocumentItem::new(
6115                            uri,
6116                            adapter.language_id(&language.name()),
6117                            version,
6118                            initial_snapshot.text(),
6119                        ),
6120                    },
6121                )?;
6122
6123                buffer_handle.update(cx, |buffer, cx| {
6124                    buffer.set_completion_triggers(
6125                        language_server
6126                            .capabilities()
6127                            .completion_provider
6128                            .as_ref()
6129                            .and_then(|provider| provider.trigger_characters.clone())
6130                            .unwrap_or_default(),
6131                        cx,
6132                    )
6133                });
6134            }
6135            anyhow::Ok(())
6136        })?;
6137
6138        cx.notify();
6139        Ok(())
6140    }
6141
6142    fn buffer_snapshot_for_lsp_version(
6143        &mut self,
6144        buffer: &Model<Buffer>,
6145        server_id: LanguageServerId,
6146        version: Option<i32>,
6147        cx: &AppContext,
6148    ) -> Result<TextBufferSnapshot> {
6149        const OLD_VERSIONS_TO_RETAIN: i32 = 10;
6150
6151        if let Some(version) = version {
6152            let buffer_id = buffer.read(cx).remote_id();
6153            let snapshots = self
6154                .buffer_snapshots
6155                .get_mut(&buffer_id)
6156                .and_then(|m| m.get_mut(&server_id))
6157                .ok_or_else(|| {
6158                    anyhow!("no snapshots found for buffer {buffer_id} and server {server_id}")
6159                })?;
6160
6161            let found_snapshot = snapshots
6162                .binary_search_by_key(&version, |e| e.version)
6163                .map(|ix| snapshots[ix].snapshot.clone())
6164                .map_err(|_| {
6165                    anyhow!("snapshot not found for buffer {buffer_id} server {server_id} at version {version}")
6166                })?;
6167
6168            snapshots.retain(|snapshot| snapshot.version + OLD_VERSIONS_TO_RETAIN >= version);
6169            Ok(found_snapshot)
6170        } else {
6171            Ok((buffer.read(cx)).text_snapshot())
6172        }
6173    }
6174
6175    pub fn language_servers_running_disk_based_diagnostics(
6176        &self,
6177    ) -> impl Iterator<Item = LanguageServerId> + '_ {
6178        self.language_server_statuses
6179            .iter()
6180            .filter_map(|(id, status)| {
6181                if status.has_pending_diagnostic_updates {
6182                    Some(*id)
6183                } else {
6184                    None
6185                }
6186            })
6187    }
6188
6189    pub(crate) fn language_servers_for_buffer<'a>(
6190        &'a self,
6191        buffer: &'a Buffer,
6192        cx: &'a AppContext,
6193    ) -> impl Iterator<Item = (&'a Arc<CachedLspAdapter>, &'a Arc<LanguageServer>)> {
6194        self.language_server_ids_for_buffer(buffer, cx)
6195            .into_iter()
6196            .filter_map(
6197                |server_id| match self.as_local()?.language_servers.get(&server_id)? {
6198                    LanguageServerState::Running {
6199                        adapter, server, ..
6200                    } => Some((adapter, server)),
6201                    _ => None,
6202                },
6203            )
6204    }
6205
6206    pub(crate) fn cancel_language_server_work_for_buffers(
6207        &mut self,
6208        buffers: impl IntoIterator<Item = Model<Buffer>>,
6209        cx: &mut ModelContext<Self>,
6210    ) {
6211        let servers = buffers
6212            .into_iter()
6213            .flat_map(|buffer| {
6214                self.language_server_ids_for_buffer(buffer.read(cx), cx)
6215                    .into_iter()
6216            })
6217            .collect::<HashSet<_>>();
6218
6219        for server_id in servers {
6220            self.cancel_language_server_work(server_id, None, cx);
6221        }
6222    }
6223
6224    pub fn language_servers(
6225        &self,
6226    ) -> impl '_ + Iterator<Item = (LanguageServerId, LanguageServerName, WorktreeId)> {
6227        self.language_server_ids
6228            .iter()
6229            .map(|((worktree_id, server_name), server_id)| {
6230                (*server_id, server_name.clone(), *worktree_id)
6231            })
6232    }
6233
6234    pub fn register_supplementary_language_server(
6235        &mut self,
6236        id: LanguageServerId,
6237        name: LanguageServerName,
6238        server: Arc<LanguageServer>,
6239        cx: &mut ModelContext<Self>,
6240    ) {
6241        if let Some(local) = self.as_local_mut() {
6242            local
6243                .supplementary_language_servers
6244                .insert(id, (name, server));
6245            cx.emit(LspStoreEvent::LanguageServerAdded(id));
6246        }
6247    }
6248
6249    pub fn unregister_supplementary_language_server(
6250        &mut self,
6251        id: LanguageServerId,
6252        cx: &mut ModelContext<Self>,
6253    ) {
6254        if let Some(local) = self.as_local_mut() {
6255            local.supplementary_language_servers.remove(&id);
6256            cx.emit(LspStoreEvent::LanguageServerRemoved(id));
6257        }
6258    }
6259
6260    pub fn supplementary_language_servers(
6261        &self,
6262    ) -> impl '_ + Iterator<Item = (LanguageServerId, LanguageServerName)> {
6263        self.as_local().into_iter().flat_map(|local| {
6264            local
6265                .supplementary_language_servers
6266                .iter()
6267                .map(|(id, (name, _))| (*id, name.clone()))
6268        })
6269    }
6270
6271    pub fn language_server_adapter_for_id(
6272        &self,
6273        id: LanguageServerId,
6274    ) -> Option<Arc<CachedLspAdapter>> {
6275        self.as_local()
6276            .and_then(|local| local.language_servers.get(&id))
6277            .and_then(|language_server_state| match language_server_state {
6278                LanguageServerState::Running { adapter, .. } => Some(adapter.clone()),
6279                _ => None,
6280            })
6281    }
6282
6283    pub(super) fn update_local_worktree_language_servers(
6284        &mut self,
6285        worktree_handle: &Model<Worktree>,
6286        changes: &[(Arc<Path>, ProjectEntryId, PathChange)],
6287        cx: &mut ModelContext<Self>,
6288    ) {
6289        if changes.is_empty() {
6290            return;
6291        }
6292
6293        let Some(local) = self.as_local() else { return };
6294
6295        local.prettier_store.update(cx, |prettier_store, cx| {
6296            prettier_store.update_prettier_settings(&worktree_handle, changes, cx)
6297        });
6298
6299        let worktree_id = worktree_handle.read(cx).id();
6300        let mut language_server_ids = self
6301            .language_server_ids
6302            .iter()
6303            .filter_map(|((server_worktree_id, _), server_id)| {
6304                (*server_worktree_id == worktree_id).then_some(*server_id)
6305            })
6306            .collect::<Vec<_>>();
6307        language_server_ids.sort();
6308        language_server_ids.dedup();
6309
6310        let abs_path = worktree_handle.read(cx).abs_path();
6311        for server_id in &language_server_ids {
6312            if let Some(LanguageServerState::Running { server, .. }) =
6313                local.language_servers.get(server_id)
6314            {
6315                if let Some(watched_paths) = local
6316                    .language_server_watched_paths
6317                    .get(server_id)
6318                    .and_then(|paths| paths.read(cx).worktree_paths.get(&worktree_id))
6319                {
6320                    let params = lsp::DidChangeWatchedFilesParams {
6321                        changes: changes
6322                            .iter()
6323                            .filter_map(|(path, _, change)| {
6324                                if !watched_paths.is_match(path) {
6325                                    return None;
6326                                }
6327                                let typ = match change {
6328                                    PathChange::Loaded => return None,
6329                                    PathChange::Added => lsp::FileChangeType::CREATED,
6330                                    PathChange::Removed => lsp::FileChangeType::DELETED,
6331                                    PathChange::Updated => lsp::FileChangeType::CHANGED,
6332                                    PathChange::AddedOrUpdated => lsp::FileChangeType::CHANGED,
6333                                };
6334                                Some(lsp::FileEvent {
6335                                    uri: lsp::Url::from_file_path(abs_path.join(path)).unwrap(),
6336                                    typ,
6337                                })
6338                            })
6339                            .collect(),
6340                    };
6341                    if !params.changes.is_empty() {
6342                        server
6343                            .notify::<lsp::notification::DidChangeWatchedFiles>(params)
6344                            .log_err();
6345                    }
6346                }
6347            }
6348        }
6349    }
6350
6351    pub(crate) fn cancel_language_server_work(
6352        &mut self,
6353        server_id: LanguageServerId,
6354        token_to_cancel: Option<String>,
6355        _cx: &mut ModelContext<Self>,
6356    ) {
6357        let Some(local) = self.as_local() else {
6358            return;
6359        };
6360        let status = self.language_server_statuses.get(&server_id);
6361        let server = local.language_servers.get(&server_id);
6362        if let Some((LanguageServerState::Running { server, .. }, status)) = server.zip(status) {
6363            for (token, progress) in &status.pending_work {
6364                if let Some(token_to_cancel) = token_to_cancel.as_ref() {
6365                    if token != token_to_cancel {
6366                        continue;
6367                    }
6368                }
6369                if progress.is_cancellable {
6370                    server
6371                        .notify::<lsp::notification::WorkDoneProgressCancel>(
6372                            WorkDoneProgressCancelParams {
6373                                token: lsp::NumberOrString::String(token.clone()),
6374                            },
6375                        )
6376                        .ok();
6377                }
6378
6379                if progress.is_cancellable {
6380                    server
6381                        .notify::<lsp::notification::WorkDoneProgressCancel>(
6382                            WorkDoneProgressCancelParams {
6383                                token: lsp::NumberOrString::String(token.clone()),
6384                            },
6385                        )
6386                        .ok();
6387                }
6388            }
6389        }
6390    }
6391
6392    pub fn wait_for_remote_buffer(
6393        &mut self,
6394        id: BufferId,
6395        cx: &mut ModelContext<Self>,
6396    ) -> Task<Result<Model<Buffer>>> {
6397        self.buffer_store.update(cx, |buffer_store, cx| {
6398            buffer_store.wait_for_remote_buffer(id, cx)
6399        })
6400    }
6401
6402    pub(crate) fn language_server_ids_for_buffer(
6403        &self,
6404        buffer: &Buffer,
6405        cx: &AppContext,
6406    ) -> Vec<LanguageServerId> {
6407        if let Some((file, language)) = File::from_dyn(buffer.file()).zip(buffer.language()) {
6408            let worktree_id = file.worktree_id(cx);
6409            self.languages
6410                .lsp_adapters(&language.name())
6411                .iter()
6412                .flat_map(|adapter| {
6413                    let key = (worktree_id, adapter.name.clone());
6414                    self.language_server_ids.get(&key).copied()
6415                })
6416                .collect()
6417        } else {
6418            Vec::new()
6419        }
6420    }
6421
6422    pub async fn deserialize_text_edits(
6423        this: Model<Self>,
6424        buffer_to_edit: Model<Buffer>,
6425        edits: Vec<lsp::TextEdit>,
6426        push_to_history: bool,
6427        _: Arc<CachedLspAdapter>,
6428        language_server: Arc<LanguageServer>,
6429        cx: &mut AsyncAppContext,
6430    ) -> Result<Option<Transaction>> {
6431        let edits = this
6432            .update(cx, |this, cx| {
6433                this.edits_from_lsp(
6434                    &buffer_to_edit,
6435                    edits,
6436                    language_server.server_id(),
6437                    None,
6438                    cx,
6439                )
6440            })?
6441            .await?;
6442
6443        let transaction = buffer_to_edit.update(cx, |buffer, cx| {
6444            buffer.finalize_last_transaction();
6445            buffer.start_transaction();
6446            for (range, text) in edits {
6447                buffer.edit([(range, text)], None, cx);
6448            }
6449
6450            if buffer.end_transaction(cx).is_some() {
6451                let transaction = buffer.finalize_last_transaction().unwrap().clone();
6452                if !push_to_history {
6453                    buffer.forget_transaction(transaction.id);
6454                }
6455                Some(transaction)
6456            } else {
6457                None
6458            }
6459        })?;
6460
6461        Ok(transaction)
6462    }
6463
6464    pub async fn deserialize_workspace_edit(
6465        this: Model<Self>,
6466        edit: lsp::WorkspaceEdit,
6467        push_to_history: bool,
6468        lsp_adapter: Arc<CachedLspAdapter>,
6469        language_server: Arc<LanguageServer>,
6470        cx: &mut AsyncAppContext,
6471    ) -> Result<ProjectTransaction> {
6472        let fs = this.read_with(cx, |this, _| this.as_local().unwrap().fs.clone())?;
6473
6474        let mut operations = Vec::new();
6475        if let Some(document_changes) = edit.document_changes {
6476            match document_changes {
6477                lsp::DocumentChanges::Edits(edits) => {
6478                    operations.extend(edits.into_iter().map(lsp::DocumentChangeOperation::Edit))
6479                }
6480                lsp::DocumentChanges::Operations(ops) => operations = ops,
6481            }
6482        } else if let Some(changes) = edit.changes {
6483            operations.extend(changes.into_iter().map(|(uri, edits)| {
6484                lsp::DocumentChangeOperation::Edit(lsp::TextDocumentEdit {
6485                    text_document: lsp::OptionalVersionedTextDocumentIdentifier {
6486                        uri,
6487                        version: None,
6488                    },
6489                    edits: edits.into_iter().map(Edit::Plain).collect(),
6490                })
6491            }));
6492        }
6493
6494        let mut project_transaction = ProjectTransaction::default();
6495        for operation in operations {
6496            match operation {
6497                lsp::DocumentChangeOperation::Op(lsp::ResourceOp::Create(op)) => {
6498                    let abs_path = op
6499                        .uri
6500                        .to_file_path()
6501                        .map_err(|_| anyhow!("can't convert URI to path"))?;
6502
6503                    if let Some(parent_path) = abs_path.parent() {
6504                        fs.create_dir(parent_path).await?;
6505                    }
6506                    if abs_path.ends_with("/") {
6507                        fs.create_dir(&abs_path).await?;
6508                    } else {
6509                        fs.create_file(
6510                            &abs_path,
6511                            op.options
6512                                .map(|options| fs::CreateOptions {
6513                                    overwrite: options.overwrite.unwrap_or(false),
6514                                    ignore_if_exists: options.ignore_if_exists.unwrap_or(false),
6515                                })
6516                                .unwrap_or_default(),
6517                        )
6518                        .await?;
6519                    }
6520                }
6521
6522                lsp::DocumentChangeOperation::Op(lsp::ResourceOp::Rename(op)) => {
6523                    let source_abs_path = op
6524                        .old_uri
6525                        .to_file_path()
6526                        .map_err(|_| anyhow!("can't convert URI to path"))?;
6527                    let target_abs_path = op
6528                        .new_uri
6529                        .to_file_path()
6530                        .map_err(|_| anyhow!("can't convert URI to path"))?;
6531                    fs.rename(
6532                        &source_abs_path,
6533                        &target_abs_path,
6534                        op.options
6535                            .map(|options| fs::RenameOptions {
6536                                overwrite: options.overwrite.unwrap_or(false),
6537                                ignore_if_exists: options.ignore_if_exists.unwrap_or(false),
6538                            })
6539                            .unwrap_or_default(),
6540                    )
6541                    .await?;
6542                }
6543
6544                lsp::DocumentChangeOperation::Op(lsp::ResourceOp::Delete(op)) => {
6545                    let abs_path = op
6546                        .uri
6547                        .to_file_path()
6548                        .map_err(|_| anyhow!("can't convert URI to path"))?;
6549                    let options = op
6550                        .options
6551                        .map(|options| fs::RemoveOptions {
6552                            recursive: options.recursive.unwrap_or(false),
6553                            ignore_if_not_exists: options.ignore_if_not_exists.unwrap_or(false),
6554                        })
6555                        .unwrap_or_default();
6556                    if abs_path.ends_with("/") {
6557                        fs.remove_dir(&abs_path, options).await?;
6558                    } else {
6559                        fs.remove_file(&abs_path, options).await?;
6560                    }
6561                }
6562
6563                lsp::DocumentChangeOperation::Edit(op) => {
6564                    let buffer_to_edit = this
6565                        .update(cx, |this, cx| {
6566                            this.open_local_buffer_via_lsp(
6567                                op.text_document.uri.clone(),
6568                                language_server.server_id(),
6569                                lsp_adapter.name.clone(),
6570                                cx,
6571                            )
6572                        })?
6573                        .await?;
6574
6575                    let edits = this
6576                        .update(cx, |this, cx| {
6577                            let path = buffer_to_edit.read(cx).project_path(cx);
6578                            let active_entry = this.active_entry;
6579                            let is_active_entry = path.clone().map_or(false, |project_path| {
6580                                this.worktree_store
6581                                    .read(cx)
6582                                    .entry_for_path(&project_path, cx)
6583                                    .map_or(false, |entry| Some(entry.id) == active_entry)
6584                            });
6585
6586                            let (mut edits, mut snippet_edits) = (vec![], vec![]);
6587                            for edit in op.edits {
6588                                match edit {
6589                                    Edit::Plain(edit) => edits.push(edit),
6590                                    Edit::Annotated(edit) => edits.push(edit.text_edit),
6591                                    Edit::Snippet(edit) => {
6592                                        let Ok(snippet) = Snippet::parse(&edit.snippet.value)
6593                                        else {
6594                                            continue;
6595                                        };
6596
6597                                        if is_active_entry {
6598                                            snippet_edits.push((edit.range, snippet));
6599                                        } else {
6600                                            // Since this buffer is not focused, apply a normal edit.
6601                                            edits.push(TextEdit {
6602                                                range: edit.range,
6603                                                new_text: snippet.text,
6604                                            });
6605                                        }
6606                                    }
6607                                }
6608                            }
6609                            if !snippet_edits.is_empty() {
6610                                let buffer_id = buffer_to_edit.read(cx).remote_id();
6611                                let version = if let Some(buffer_version) = op.text_document.version
6612                                {
6613                                    this.buffer_snapshot_for_lsp_version(
6614                                        &buffer_to_edit,
6615                                        language_server.server_id(),
6616                                        Some(buffer_version),
6617                                        cx,
6618                                    )
6619                                    .ok()
6620                                    .map(|snapshot| snapshot.version)
6621                                } else {
6622                                    Some(buffer_to_edit.read(cx).saved_version().clone())
6623                                };
6624
6625                                let most_recent_edit = version.and_then(|version| {
6626                                    version.iter().max_by_key(|timestamp| timestamp.value)
6627                                });
6628                                // Check if the edit that triggered that edit has been made by this participant.
6629
6630                                if let Some(most_recent_edit) = most_recent_edit {
6631                                    cx.emit(LspStoreEvent::SnippetEdit {
6632                                        buffer_id,
6633                                        edits: snippet_edits,
6634                                        most_recent_edit,
6635                                    });
6636                                }
6637                            }
6638
6639                            this.edits_from_lsp(
6640                                &buffer_to_edit,
6641                                edits,
6642                                language_server.server_id(),
6643                                op.text_document.version,
6644                                cx,
6645                            )
6646                        })?
6647                        .await?;
6648
6649                    let transaction = buffer_to_edit.update(cx, |buffer, cx| {
6650                        buffer.finalize_last_transaction();
6651                        buffer.start_transaction();
6652                        for (range, text) in edits {
6653                            buffer.edit([(range, text)], None, cx);
6654                        }
6655                        let transaction = if buffer.end_transaction(cx).is_some() {
6656                            let transaction = buffer.finalize_last_transaction().unwrap().clone();
6657                            if !push_to_history {
6658                                buffer.forget_transaction(transaction.id);
6659                            }
6660                            Some(transaction)
6661                        } else {
6662                            None
6663                        };
6664
6665                        transaction
6666                    })?;
6667                    if let Some(transaction) = transaction {
6668                        project_transaction.0.insert(buffer_to_edit, transaction);
6669                    }
6670                }
6671            }
6672        }
6673
6674        Ok(project_transaction)
6675    }
6676
6677    fn serialize_symbol(symbol: &Symbol) -> proto::Symbol {
6678        proto::Symbol {
6679            language_server_name: symbol.language_server_name.0.to_string(),
6680            source_worktree_id: symbol.source_worktree_id.to_proto(),
6681            worktree_id: symbol.path.worktree_id.to_proto(),
6682            path: symbol.path.path.to_string_lossy().to_string(),
6683            name: symbol.name.clone(),
6684            kind: unsafe { mem::transmute::<lsp::SymbolKind, i32>(symbol.kind) },
6685            start: Some(proto::PointUtf16 {
6686                row: symbol.range.start.0.row,
6687                column: symbol.range.start.0.column,
6688            }),
6689            end: Some(proto::PointUtf16 {
6690                row: symbol.range.end.0.row,
6691                column: symbol.range.end.0.column,
6692            }),
6693            signature: symbol.signature.to_vec(),
6694        }
6695    }
6696
6697    fn deserialize_symbol(serialized_symbol: proto::Symbol) -> Result<CoreSymbol> {
6698        let source_worktree_id = WorktreeId::from_proto(serialized_symbol.source_worktree_id);
6699        let worktree_id = WorktreeId::from_proto(serialized_symbol.worktree_id);
6700        let kind = unsafe { mem::transmute::<i32, lsp::SymbolKind>(serialized_symbol.kind) };
6701        let path = ProjectPath {
6702            worktree_id,
6703            path: PathBuf::from(serialized_symbol.path).into(),
6704        };
6705
6706        let start = serialized_symbol
6707            .start
6708            .ok_or_else(|| anyhow!("invalid start"))?;
6709        let end = serialized_symbol
6710            .end
6711            .ok_or_else(|| anyhow!("invalid end"))?;
6712        Ok(CoreSymbol {
6713            language_server_name: LanguageServerName(serialized_symbol.language_server_name.into()),
6714            source_worktree_id,
6715            path,
6716            name: serialized_symbol.name,
6717            range: Unclipped(PointUtf16::new(start.row, start.column))
6718                ..Unclipped(PointUtf16::new(end.row, end.column)),
6719            kind,
6720            signature: serialized_symbol
6721                .signature
6722                .try_into()
6723                .map_err(|_| anyhow!("invalid signature"))?,
6724        })
6725    }
6726
6727    pub(crate) fn serialize_completion(completion: &CoreCompletion) -> proto::Completion {
6728        proto::Completion {
6729            old_start: Some(serialize_anchor(&completion.old_range.start)),
6730            old_end: Some(serialize_anchor(&completion.old_range.end)),
6731            new_text: completion.new_text.clone(),
6732            server_id: completion.server_id.0 as u64,
6733            lsp_completion: serde_json::to_vec(&completion.lsp_completion).unwrap(),
6734        }
6735    }
6736
6737    pub(crate) fn deserialize_completion(completion: proto::Completion) -> Result<CoreCompletion> {
6738        let old_start = completion
6739            .old_start
6740            .and_then(deserialize_anchor)
6741            .ok_or_else(|| anyhow!("invalid old start"))?;
6742        let old_end = completion
6743            .old_end
6744            .and_then(deserialize_anchor)
6745            .ok_or_else(|| anyhow!("invalid old end"))?;
6746        let lsp_completion = serde_json::from_slice(&completion.lsp_completion)?;
6747
6748        Ok(CoreCompletion {
6749            old_range: old_start..old_end,
6750            new_text: completion.new_text,
6751            server_id: LanguageServerId(completion.server_id as usize),
6752            lsp_completion,
6753        })
6754    }
6755
6756    pub(crate) fn serialize_code_action(action: &CodeAction) -> proto::CodeAction {
6757        proto::CodeAction {
6758            server_id: action.server_id.0 as u64,
6759            start: Some(serialize_anchor(&action.range.start)),
6760            end: Some(serialize_anchor(&action.range.end)),
6761            lsp_action: serde_json::to_vec(&action.lsp_action).unwrap(),
6762        }
6763    }
6764
6765    pub(crate) fn deserialize_code_action(action: proto::CodeAction) -> Result<CodeAction> {
6766        let start = action
6767            .start
6768            .and_then(deserialize_anchor)
6769            .ok_or_else(|| anyhow!("invalid start"))?;
6770        let end = action
6771            .end
6772            .and_then(deserialize_anchor)
6773            .ok_or_else(|| anyhow!("invalid end"))?;
6774        let lsp_action = serde_json::from_slice(&action.lsp_action)?;
6775        Ok(CodeAction {
6776            server_id: LanguageServerId(action.server_id as usize),
6777            range: start..end,
6778            lsp_action,
6779        })
6780    }
6781}
6782
6783impl EventEmitter<LspStoreEvent> for LspStore {}
6784
6785fn remove_empty_hover_blocks(mut hover: Hover) -> Option<Hover> {
6786    hover
6787        .contents
6788        .retain(|hover_block| !hover_block.text.trim().is_empty());
6789    if hover.contents.is_empty() {
6790        None
6791    } else {
6792        Some(hover)
6793    }
6794}
6795
6796async fn populate_labels_for_completions(
6797    mut new_completions: Vec<CoreCompletion>,
6798    language_registry: &Arc<LanguageRegistry>,
6799    language: Option<Arc<Language>>,
6800    lsp_adapter: Option<Arc<CachedLspAdapter>>,
6801    completions: &mut Vec<Completion>,
6802) {
6803    let lsp_completions = new_completions
6804        .iter_mut()
6805        .map(|completion| mem::take(&mut completion.lsp_completion))
6806        .collect::<Vec<_>>();
6807
6808    let labels = if let Some((language, lsp_adapter)) = language.as_ref().zip(lsp_adapter) {
6809        lsp_adapter
6810            .labels_for_completions(&lsp_completions, language)
6811            .await
6812            .log_err()
6813            .unwrap_or_default()
6814    } else {
6815        Vec::new()
6816    };
6817
6818    for ((completion, lsp_completion), label) in new_completions
6819        .into_iter()
6820        .zip(lsp_completions)
6821        .zip(labels.into_iter().chain(iter::repeat(None)))
6822    {
6823        let documentation = if let Some(docs) = &lsp_completion.documentation {
6824            Some(prepare_completion_documentation(docs, language_registry, language.clone()).await)
6825        } else {
6826            None
6827        };
6828
6829        completions.push(Completion {
6830            old_range: completion.old_range,
6831            new_text: completion.new_text,
6832            label: label.unwrap_or_else(|| {
6833                CodeLabel::plain(
6834                    lsp_completion.label.clone(),
6835                    lsp_completion.filter_text.as_deref(),
6836                )
6837            }),
6838            server_id: completion.server_id,
6839            documentation,
6840            lsp_completion,
6841            confirm: None,
6842        })
6843    }
6844}
6845
6846#[derive(Debug)]
6847pub enum LanguageServerToQuery {
6848    Primary,
6849    Other(LanguageServerId),
6850}
6851
6852#[derive(Default)]
6853struct LanguageServerWatchedPaths {
6854    worktree_paths: HashMap<WorktreeId, GlobSet>,
6855    abs_paths: HashMap<Arc<Path>, (GlobSet, Task<()>)>,
6856}
6857
6858#[derive(Default)]
6859struct LanguageServerWatchedPathsBuilder {
6860    worktree_paths: HashMap<WorktreeId, GlobSet>,
6861    abs_paths: HashMap<Arc<Path>, GlobSet>,
6862}
6863
6864impl LanguageServerWatchedPathsBuilder {
6865    fn watch_worktree(&mut self, worktree_id: WorktreeId, glob_set: GlobSet) {
6866        self.worktree_paths.insert(worktree_id, glob_set);
6867    }
6868    fn watch_abs_path(&mut self, path: Arc<Path>, glob_set: GlobSet) {
6869        self.abs_paths.insert(path, glob_set);
6870    }
6871    fn build(
6872        self,
6873        fs: Arc<dyn Fs>,
6874        language_server_id: LanguageServerId,
6875        cx: &mut ModelContext<LspStore>,
6876    ) -> Model<LanguageServerWatchedPaths> {
6877        let project = cx.weak_model();
6878
6879        cx.new_model(|cx| {
6880            let this_id = cx.entity_id();
6881            const LSP_ABS_PATH_OBSERVE: Duration = Duration::from_millis(100);
6882            let abs_paths = self
6883                .abs_paths
6884                .into_iter()
6885                .map(|(abs_path, globset)| {
6886                    let task = cx.spawn({
6887                        let abs_path = abs_path.clone();
6888                        let fs = fs.clone();
6889
6890                        let lsp_store = project.clone();
6891                        |_, mut cx| async move {
6892                            maybe!(async move {
6893                                let mut push_updates =
6894                                    fs.watch(&abs_path, LSP_ABS_PATH_OBSERVE).await;
6895                                while let Some(update) = push_updates.0.next().await {
6896                                    let action = lsp_store
6897                                        .update(&mut cx, |this, cx| {
6898                                            let Some(local) = this.as_local() else {
6899                                                return ControlFlow::Break(());
6900                                            };
6901                                            let Some(watcher) = local
6902                                                .language_server_watched_paths
6903                                                .get(&language_server_id)
6904                                            else {
6905                                                return ControlFlow::Break(());
6906                                            };
6907                                            if watcher.entity_id() != this_id {
6908                                                // This watcher is no longer registered on the project, which means that we should
6909                                                // cease operations.
6910                                                return ControlFlow::Break(());
6911                                            }
6912                                            let (globs, _) = watcher
6913                                                .read(cx)
6914                                                .abs_paths
6915                                                .get(&abs_path)
6916                                                .expect(
6917                                                "Watched abs path is not registered with a watcher",
6918                                            );
6919                                            let matching_entries = update
6920                                                .into_iter()
6921                                                .filter(|event| globs.is_match(&event.path))
6922                                                .collect::<Vec<_>>();
6923                                            this.lsp_notify_abs_paths_changed(
6924                                                language_server_id,
6925                                                matching_entries,
6926                                            );
6927                                            ControlFlow::Continue(())
6928                                        })
6929                                        .ok()?;
6930
6931                                    if action.is_break() {
6932                                        break;
6933                                    }
6934                                }
6935                                Some(())
6936                            })
6937                            .await;
6938                        }
6939                    });
6940                    (abs_path, (globset, task))
6941                })
6942                .collect();
6943            LanguageServerWatchedPaths {
6944                worktree_paths: self.worktree_paths,
6945                abs_paths,
6946            }
6947        })
6948    }
6949}
6950
6951struct LspBufferSnapshot {
6952    version: i32,
6953    snapshot: TextBufferSnapshot,
6954}
6955
6956/// A prompt requested by LSP server.
6957#[derive(Clone, Debug)]
6958pub struct LanguageServerPromptRequest {
6959    pub level: PromptLevel,
6960    pub message: String,
6961    pub actions: Vec<MessageActionItem>,
6962    pub lsp_name: String,
6963    pub(crate) response_channel: Sender<MessageActionItem>,
6964}
6965
6966impl LanguageServerPromptRequest {
6967    pub async fn respond(self, index: usize) -> Option<()> {
6968        if let Some(response) = self.actions.into_iter().nth(index) {
6969            self.response_channel.send(response).await.ok()
6970        } else {
6971            None
6972        }
6973    }
6974}
6975impl PartialEq for LanguageServerPromptRequest {
6976    fn eq(&self, other: &Self) -> bool {
6977        self.message == other.message && self.actions == other.actions
6978    }
6979}
6980
6981#[derive(Clone, Debug, PartialEq)]
6982pub enum LanguageServerLogType {
6983    Log(MessageType),
6984    Trace(Option<String>),
6985}
6986
6987pub enum LanguageServerState {
6988    Starting(Task<Option<Arc<LanguageServer>>>),
6989
6990    Running {
6991        language: LanguageName,
6992        adapter: Arc<CachedLspAdapter>,
6993        server: Arc<LanguageServer>,
6994        simulate_disk_based_diagnostics_completion: Option<Task<()>>,
6995    },
6996}
6997
6998impl std::fmt::Debug for LanguageServerState {
6999    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
7000        match self {
7001            LanguageServerState::Starting(_) => {
7002                f.debug_struct("LanguageServerState::Starting").finish()
7003            }
7004            LanguageServerState::Running { language, .. } => f
7005                .debug_struct("LanguageServerState::Running")
7006                .field("language", &language)
7007                .finish(),
7008        }
7009    }
7010}
7011
7012#[derive(Clone, Debug, Serialize)]
7013pub struct LanguageServerProgress {
7014    pub is_disk_based_diagnostics_progress: bool,
7015    pub is_cancellable: bool,
7016    pub title: Option<String>,
7017    pub message: Option<String>,
7018    pub percentage: Option<usize>,
7019    #[serde(skip_serializing)]
7020    pub last_update_at: Instant,
7021}
7022
7023#[derive(Copy, Clone, Debug, Default, PartialEq, Serialize)]
7024pub struct DiagnosticSummary {
7025    pub error_count: usize,
7026    pub warning_count: usize,
7027}
7028
7029impl DiagnosticSummary {
7030    pub fn new<'a, T: 'a>(diagnostics: impl IntoIterator<Item = &'a DiagnosticEntry<T>>) -> Self {
7031        let mut this = Self {
7032            error_count: 0,
7033            warning_count: 0,
7034        };
7035
7036        for entry in diagnostics {
7037            if entry.diagnostic.is_primary {
7038                match entry.diagnostic.severity {
7039                    DiagnosticSeverity::ERROR => this.error_count += 1,
7040                    DiagnosticSeverity::WARNING => this.warning_count += 1,
7041                    _ => {}
7042                }
7043            }
7044        }
7045
7046        this
7047    }
7048
7049    pub fn is_empty(&self) -> bool {
7050        self.error_count == 0 && self.warning_count == 0
7051    }
7052
7053    pub fn to_proto(
7054        &self,
7055        language_server_id: LanguageServerId,
7056        path: &Path,
7057    ) -> proto::DiagnosticSummary {
7058        proto::DiagnosticSummary {
7059            path: path.to_string_lossy().to_string(),
7060            language_server_id: language_server_id.0 as u64,
7061            error_count: self.error_count as u32,
7062            warning_count: self.warning_count as u32,
7063        }
7064    }
7065}
7066
7067fn glob_literal_prefix(glob: &str) -> &str {
7068    let is_absolute = glob.starts_with(path::MAIN_SEPARATOR);
7069
7070    let mut literal_end = is_absolute as usize;
7071    for (i, part) in glob.split(path::MAIN_SEPARATOR).enumerate() {
7072        if part.contains(['*', '?', '{', '}']) {
7073            break;
7074        } else {
7075            if i > 0 {
7076                // Account for separator prior to this part
7077                literal_end += path::MAIN_SEPARATOR.len_utf8();
7078            }
7079            literal_end += part.len();
7080        }
7081    }
7082    let literal_end = literal_end.min(glob.len());
7083    &glob[..literal_end]
7084}
7085
7086pub struct SshLspAdapter {
7087    name: LanguageServerName,
7088    binary: LanguageServerBinary,
7089    initialization_options: Option<String>,
7090    code_action_kinds: Option<Vec<CodeActionKind>>,
7091}
7092
7093impl SshLspAdapter {
7094    pub fn new(
7095        name: LanguageServerName,
7096        binary: LanguageServerBinary,
7097        initialization_options: Option<String>,
7098        code_action_kinds: Option<String>,
7099    ) -> Self {
7100        Self {
7101            name,
7102            binary,
7103            initialization_options,
7104            code_action_kinds: code_action_kinds
7105                .as_ref()
7106                .and_then(|c| serde_json::from_str(c).ok()),
7107        }
7108    }
7109}
7110
7111#[async_trait(?Send)]
7112impl LspAdapter for SshLspAdapter {
7113    fn name(&self) -> LanguageServerName {
7114        self.name.clone()
7115    }
7116
7117    async fn initialization_options(
7118        self: Arc<Self>,
7119        _: &Arc<dyn LspAdapterDelegate>,
7120    ) -> Result<Option<serde_json::Value>> {
7121        let Some(options) = &self.initialization_options else {
7122            return Ok(None);
7123        };
7124        let result = serde_json::from_str(options)?;
7125        Ok(result)
7126    }
7127
7128    fn code_action_kinds(&self) -> Option<Vec<CodeActionKind>> {
7129        self.code_action_kinds.clone()
7130    }
7131
7132    async fn check_if_user_installed(
7133        &self,
7134        _: &dyn LspAdapterDelegate,
7135        _: &AsyncAppContext,
7136    ) -> Option<LanguageServerBinary> {
7137        Some(self.binary.clone())
7138    }
7139
7140    async fn cached_server_binary(
7141        &self,
7142        _: PathBuf,
7143        _: &dyn LspAdapterDelegate,
7144    ) -> Option<LanguageServerBinary> {
7145        None
7146    }
7147
7148    async fn fetch_latest_server_version(
7149        &self,
7150        _: &dyn LspAdapterDelegate,
7151    ) -> Result<Box<dyn 'static + Send + Any>> {
7152        anyhow::bail!("SshLspAdapter does not support fetch_latest_server_version")
7153    }
7154
7155    async fn fetch_server_binary(
7156        &self,
7157        _: Box<dyn 'static + Send + Any>,
7158        _: PathBuf,
7159        _: &dyn LspAdapterDelegate,
7160    ) -> Result<LanguageServerBinary> {
7161        anyhow::bail!("SshLspAdapter does not support fetch_server_binary")
7162    }
7163
7164    async fn installation_test_binary(&self, _: PathBuf) -> Option<LanguageServerBinary> {
7165        None
7166    }
7167}
7168pub fn language_server_settings<'a, 'b: 'a>(
7169    delegate: &'a dyn LspAdapterDelegate,
7170    language: &str,
7171    cx: &'b AppContext,
7172) -> Option<&'a LspSettings> {
7173    ProjectSettings::get(
7174        Some(SettingsLocation {
7175            worktree_id: delegate.worktree_id(),
7176            path: delegate.worktree_root_path(),
7177        }),
7178        cx,
7179    )
7180    .lsp
7181    .get(language)
7182}
7183
7184pub struct LocalLspAdapterDelegate {
7185    lsp_store: WeakModel<LspStore>,
7186    worktree: worktree::Snapshot,
7187    fs: Arc<dyn Fs>,
7188    http_client: Arc<dyn HttpClient>,
7189    language_registry: Arc<LanguageRegistry>,
7190    load_shell_env_task: Shared<Task<Option<HashMap<String, String>>>>,
7191}
7192
7193impl LocalLspAdapterDelegate {
7194    fn for_local(
7195        lsp_store: &LspStore,
7196        worktree: &Model<Worktree>,
7197        cx: &mut ModelContext<LspStore>,
7198    ) -> Arc<Self> {
7199        let local = lsp_store
7200            .as_local()
7201            .expect("LocalLspAdapterDelegate cannot be constructed on a remote");
7202
7203        let http_client = local
7204            .http_client
7205            .clone()
7206            .unwrap_or_else(|| Arc::new(BlockedHttpClient));
7207
7208        Self::new(lsp_store, worktree, http_client, local.fs.clone(), cx)
7209    }
7210
7211    // fn for_ssh(
7212    //     lsp_store: &LspStore,
7213    //     worktree: &Model<Worktree>,
7214    //     upstream_client: AnyProtoClient,
7215    //     cx: &mut ModelContext<LspStore>,
7216    // ) -> Arc<Self> {
7217    //     Self::new(
7218    //         lsp_store,
7219    //         worktree,
7220    //         Arc::new(BlockedHttpClient),
7221    //         None,
7222    //         Some(upstream_client),
7223    //         cx,
7224    //     )
7225    // }
7226
7227    pub fn new(
7228        lsp_store: &LspStore,
7229        worktree: &Model<Worktree>,
7230        http_client: Arc<dyn HttpClient>,
7231        fs: Arc<dyn Fs>,
7232        cx: &mut ModelContext<LspStore>,
7233    ) -> Arc<Self> {
7234        let worktree_id = worktree.read(cx).id();
7235        let worktree_abs_path = worktree.read(cx).abs_path();
7236        let load_shell_env_task = if let Some(environment) =
7237            &lsp_store.as_local().map(|local| local.environment.clone())
7238        {
7239            environment.update(cx, |env, cx| {
7240                env.get_environment(Some(worktree_id), Some(worktree_abs_path), cx)
7241            })
7242        } else {
7243            Task::ready(None).shared()
7244        };
7245
7246        Arc::new(Self {
7247            lsp_store: cx.weak_model(),
7248            worktree: worktree.read(cx).snapshot(),
7249            fs,
7250            http_client,
7251            language_registry: lsp_store.languages.clone(),
7252            load_shell_env_task,
7253        })
7254    }
7255}
7256
7257#[async_trait]
7258impl LspAdapterDelegate for LocalLspAdapterDelegate {
7259    fn show_notification(&self, message: &str, cx: &mut AppContext) {
7260        self.lsp_store
7261            .update(cx, |_, cx| {
7262                cx.emit(LspStoreEvent::Notification(message.to_owned()))
7263            })
7264            .ok();
7265    }
7266
7267    fn http_client(&self) -> Arc<dyn HttpClient> {
7268        self.http_client.clone()
7269    }
7270
7271    fn worktree_id(&self) -> WorktreeId {
7272        self.worktree.id()
7273    }
7274
7275    fn worktree_root_path(&self) -> &Path {
7276        self.worktree.abs_path().as_ref()
7277    }
7278
7279    async fn shell_env(&self) -> HashMap<String, String> {
7280        let task = self.load_shell_env_task.clone();
7281        task.await.unwrap_or_default()
7282    }
7283
7284    #[cfg(not(target_os = "windows"))]
7285    async fn which(&self, command: &OsStr) -> Option<PathBuf> {
7286        let worktree_abs_path = self.worktree.abs_path();
7287        let shell_path = self.shell_env().await.get("PATH").cloned();
7288        which::which_in(command, shell_path.as_ref(), worktree_abs_path).ok()
7289    }
7290
7291    #[cfg(target_os = "windows")]
7292    async fn which(&self, command: &OsStr) -> Option<PathBuf> {
7293        // todo(windows) Getting the shell env variables in a current directory on Windows is more complicated than other platforms
7294        //               there isn't a 'default shell' necessarily. The closest would be the default profile on the windows terminal
7295        //               SEE: https://learn.microsoft.com/en-us/windows/terminal/customize-settings/startup
7296        which::which(command).ok()
7297    }
7298
7299    async fn try_exec(&self, command: LanguageServerBinary) -> Result<()> {
7300        let working_dir = self.worktree_root_path();
7301        let output = smol::process::Command::new(&command.path)
7302            .args(command.arguments)
7303            .envs(command.env.clone().unwrap_or_default())
7304            .current_dir(working_dir)
7305            .output()
7306            .await?;
7307
7308        if output.status.success() {
7309            return Ok(());
7310        }
7311        Err(anyhow!(
7312            "{}, stdout: {:?}, stderr: {:?}",
7313            output.status,
7314            String::from_utf8_lossy(&output.stdout),
7315            String::from_utf8_lossy(&output.stderr)
7316        ))
7317    }
7318
7319    fn update_status(
7320        &self,
7321        server_name: LanguageServerName,
7322        status: language::LanguageServerBinaryStatus,
7323    ) {
7324        self.language_registry
7325            .update_lsp_status(server_name, status);
7326    }
7327
7328    async fn read_text_file(&self, path: PathBuf) -> Result<String> {
7329        if self.worktree.entry_for_path(&path).is_none() {
7330            return Err(anyhow!("no such path {path:?}"));
7331        };
7332        self.fs.load(&path).await
7333    }
7334}
7335
7336struct BlockedHttpClient;
7337
7338impl HttpClient for BlockedHttpClient {
7339    fn send(
7340        &self,
7341        _req: Request<AsyncBody>,
7342    ) -> BoxFuture<'static, Result<Response<AsyncBody>, anyhow::Error>> {
7343        Box::pin(async {
7344            Err(std::io::Error::new(
7345                std::io::ErrorKind::PermissionDenied,
7346                "ssh host blocked http connection",
7347            )
7348            .into())
7349        })
7350    }
7351
7352    fn proxy(&self) -> Option<&Uri> {
7353        None
7354    }
7355
7356    fn send_with_redirect_policy(
7357        &self,
7358        req: Request<AsyncBody>,
7359        _: bool,
7360    ) -> BoxFuture<'static, Result<Response<AsyncBody>, anyhow::Error>> {
7361        self.send(req)
7362    }
7363}
7364
7365struct SshLspAdapterDelegate {
7366    lsp_store: WeakModel<LspStore>,
7367    worktree: worktree::Snapshot,
7368    upstream_client: AnyProtoClient,
7369    language_registry: Arc<LanguageRegistry>,
7370}
7371
7372#[async_trait]
7373impl LspAdapterDelegate for SshLspAdapterDelegate {
7374    fn show_notification(&self, message: &str, cx: &mut AppContext) {
7375        self.lsp_store
7376            .update(cx, |_, cx| {
7377                cx.emit(LspStoreEvent::Notification(message.to_owned()))
7378            })
7379            .ok();
7380    }
7381
7382    fn http_client(&self) -> Arc<dyn HttpClient> {
7383        Arc::new(BlockedHttpClient)
7384    }
7385
7386    fn worktree_id(&self) -> WorktreeId {
7387        self.worktree.id()
7388    }
7389
7390    fn worktree_root_path(&self) -> &Path {
7391        self.worktree.abs_path().as_ref()
7392    }
7393
7394    async fn shell_env(&self) -> HashMap<String, String> {
7395        use rpc::proto::SSH_PROJECT_ID;
7396
7397        self.upstream_client
7398            .request(proto::ShellEnv {
7399                project_id: SSH_PROJECT_ID,
7400                worktree_id: self.worktree_id().to_proto(),
7401            })
7402            .await
7403            .map(|response| response.env.into_iter().collect())
7404            .unwrap_or_default()
7405    }
7406
7407    async fn which(&self, command: &OsStr) -> Option<PathBuf> {
7408        use rpc::proto::SSH_PROJECT_ID;
7409
7410        self.upstream_client
7411            .request(proto::WhichCommand {
7412                project_id: SSH_PROJECT_ID,
7413                worktree_id: self.worktree_id().to_proto(),
7414                command: command.to_string_lossy().to_string(),
7415            })
7416            .await
7417            .log_err()
7418            .and_then(|response| response.path)
7419            .map(PathBuf::from)
7420    }
7421
7422    async fn try_exec(&self, command: LanguageServerBinary) -> Result<()> {
7423        self.upstream_client
7424            .request(proto::TryExec {
7425                project_id: rpc::proto::SSH_PROJECT_ID,
7426                worktree_id: self.worktree.id().to_proto(),
7427                binary: Some(proto::LanguageServerCommand {
7428                    path: command.path.to_string_lossy().to_string(),
7429                    arguments: command
7430                        .arguments
7431                        .into_iter()
7432                        .map(|s| s.to_string_lossy().to_string())
7433                        .collect(),
7434                    env: command.env.unwrap_or_default().into_iter().collect(),
7435                }),
7436            })
7437            .await?;
7438        Ok(())
7439    }
7440
7441    fn update_status(
7442        &self,
7443        server_name: LanguageServerName,
7444        status: language::LanguageServerBinaryStatus,
7445    ) {
7446        self.language_registry
7447            .update_lsp_status(server_name, status);
7448    }
7449
7450    async fn read_text_file(&self, path: PathBuf) -> Result<String> {
7451        self.upstream_client
7452            .request(proto::ReadTextFile {
7453                project_id: rpc::proto::SSH_PROJECT_ID,
7454                path: Some(proto::ProjectPath {
7455                    worktree_id: self.worktree.id().to_proto(),
7456                    path: path.to_string_lossy().to_string(),
7457                }),
7458            })
7459            .await
7460            .map(|r| r.text)
7461    }
7462}
7463
7464async fn populate_labels_for_symbols(
7465    symbols: Vec<CoreSymbol>,
7466    language_registry: &Arc<LanguageRegistry>,
7467    default_language: Option<LanguageName>,
7468    lsp_adapter: Option<Arc<CachedLspAdapter>>,
7469    output: &mut Vec<Symbol>,
7470) {
7471    #[allow(clippy::mutable_key_type)]
7472    let mut symbols_by_language = HashMap::<Option<Arc<Language>>, Vec<CoreSymbol>>::default();
7473
7474    let mut unknown_path = None;
7475    for symbol in symbols {
7476        let language = language_registry
7477            .language_for_file_path(&symbol.path.path)
7478            .await
7479            .ok()
7480            .or_else(|| {
7481                unknown_path.get_or_insert(symbol.path.path.clone());
7482                default_language.as_ref().and_then(|name| {
7483                    language_registry
7484                        .language_for_name(&name.0)
7485                        .now_or_never()?
7486                        .ok()
7487                })
7488            });
7489        symbols_by_language
7490            .entry(language)
7491            .or_default()
7492            .push(symbol);
7493    }
7494
7495    if let Some(unknown_path) = unknown_path {
7496        log::info!(
7497            "no language found for symbol path {}",
7498            unknown_path.display()
7499        );
7500    }
7501
7502    let mut label_params = Vec::new();
7503    for (language, mut symbols) in symbols_by_language {
7504        label_params.clear();
7505        label_params.extend(
7506            symbols
7507                .iter_mut()
7508                .map(|symbol| (mem::take(&mut symbol.name), symbol.kind)),
7509        );
7510
7511        let mut labels = Vec::new();
7512        if let Some(language) = language {
7513            let lsp_adapter = lsp_adapter.clone().or_else(|| {
7514                language_registry
7515                    .lsp_adapters(&language.name())
7516                    .first()
7517                    .cloned()
7518            });
7519            if let Some(lsp_adapter) = lsp_adapter {
7520                labels = lsp_adapter
7521                    .labels_for_symbols(&label_params, &language)
7522                    .await
7523                    .log_err()
7524                    .unwrap_or_default();
7525            }
7526        }
7527
7528        for ((symbol, (name, _)), label) in symbols
7529            .into_iter()
7530            .zip(label_params.drain(..))
7531            .zip(labels.into_iter().chain(iter::repeat(None)))
7532        {
7533            output.push(Symbol {
7534                language_server_name: symbol.language_server_name,
7535                source_worktree_id: symbol.source_worktree_id,
7536                path: symbol.path,
7537                label: label.unwrap_or_else(|| CodeLabel::plain(name.clone(), None)),
7538                name,
7539                kind: symbol.kind,
7540                range: symbol.range,
7541                signature: symbol.signature,
7542            });
7543        }
7544    }
7545}
7546
7547fn include_text(server: &lsp::LanguageServer) -> Option<bool> {
7548    match server.capabilities().text_document_sync.as_ref()? {
7549        lsp::TextDocumentSyncCapability::Kind(kind) => match *kind {
7550            lsp::TextDocumentSyncKind::NONE => None,
7551            lsp::TextDocumentSyncKind::FULL => Some(true),
7552            lsp::TextDocumentSyncKind::INCREMENTAL => Some(false),
7553            _ => None,
7554        },
7555        lsp::TextDocumentSyncCapability::Options(options) => match options.save.as_ref()? {
7556            lsp::TextDocumentSyncSaveOptions::Supported(supported) => {
7557                if *supported {
7558                    Some(true)
7559                } else {
7560                    None
7561                }
7562            }
7563            lsp::TextDocumentSyncSaveOptions::SaveOptions(save_options) => {
7564                Some(save_options.include_text.unwrap_or(false))
7565            }
7566        },
7567    }
7568}
7569
7570#[cfg(test)]
7571#[test]
7572fn test_glob_literal_prefix() {
7573    assert_eq!(glob_literal_prefix("**/*.js"), "");
7574    assert_eq!(glob_literal_prefix("node_modules/**/*.js"), "node_modules");
7575    assert_eq!(glob_literal_prefix("foo/{bar,baz}.js"), "foo");
7576    assert_eq!(glob_literal_prefix("foo/bar/baz.js"), "foo/bar/baz.js");
7577}