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, Error, 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    /*
4746    ssh client owns the lifecycle of the language servers
4747    ssh host actually runs the binaries
4748
4749    in the future: ssh client will use the local extensions to get the downloads etc.
4750        and send them up over the ssh connection (but today) we'll just the static config
4751
4752        languages::() <-- registers lsp adapters
4753        on the ssh host we won't have adapters for the LSPs
4754    */
4755
4756    fn start_language_server_on_ssh_host(
4757        &mut self,
4758        worktree: &Model<Worktree>,
4759        adapter: Arc<CachedLspAdapter>,
4760        language: LanguageName,
4761        cx: &mut ModelContext<Self>,
4762    ) {
4763        let ssh = self.as_ssh().unwrap();
4764
4765        let delegate = Arc::new(SshLspAdapterDelegate {
4766            lsp_store: cx.handle().downgrade(),
4767            worktree: worktree.read(cx).snapshot(),
4768            upstream_client: ssh.upstream_client.clone(),
4769            language_registry: self.languages.clone(),
4770        }) as Arc<dyn LspAdapterDelegate>;
4771
4772        // TODO: We should use `adapter` here instead of reaching through the `CachedLspAdapter`.
4773        let lsp_adapter = adapter.adapter.clone();
4774
4775        let project_id = self.project_id;
4776        let worktree_id = worktree.read(cx).id().to_proto();
4777        let upstream_client = ssh.upstream_client.clone();
4778        let name = adapter.name().to_string();
4779
4780        let Some(available_language) = self.languages.available_language_for_name(&language) else {
4781            log::error!("failed to find available language {language}");
4782            return;
4783        };
4784
4785        let task = cx.spawn(|_, cx| async move {
4786            let user_binary_task = lsp_adapter.check_if_user_installed(delegate.as_ref(), &cx);
4787            let binary = match user_binary_task.await {
4788                Some(binary) => binary,
4789                None => {
4790                    return Err(anyhow!(
4791                        "Downloading language server for ssh host is not supported yet"
4792                    ))
4793                }
4794            };
4795
4796            let name = adapter.name().to_string();
4797            let code_action_kinds = adapter
4798                .adapter
4799                .code_action_kinds()
4800                .map(|kinds| serde_json::to_string(&kinds))
4801                .transpose()?;
4802            let get_options = adapter.adapter.clone().initialization_options(&delegate);
4803            let initialization_options = get_options
4804                .await?
4805                .map(|options| serde_json::to_string(&options))
4806                .transpose()?;
4807
4808            let language_server_command = proto::LanguageServerCommand {
4809                path: binary.path.to_string_lossy().to_string(),
4810                arguments: binary
4811                    .arguments
4812                    .iter()
4813                    .map(|args| args.to_string_lossy().to_string())
4814                    .collect(),
4815                env: binary.env.unwrap_or_default().into_iter().collect(),
4816            };
4817
4818            upstream_client
4819                .request(proto::CreateLanguageServer {
4820                    project_id,
4821                    worktree_id,
4822                    name,
4823                    binary: Some(language_server_command),
4824                    initialization_options,
4825                    code_action_kinds,
4826                    language: Some(proto::AvailableLanguage {
4827                        name: language.to_proto(),
4828                        matcher: serde_json::to_string(&available_language.matcher())?,
4829                    }),
4830                })
4831                .await
4832        });
4833        cx.spawn(|this, mut cx| async move {
4834            if let Err(e) = task.await {
4835                this.update(&mut cx, |_this, cx| {
4836                    cx.emit(LspStoreEvent::Notification(format!(
4837                        "failed to start {}: {}",
4838                        name, e
4839                    )))
4840                })
4841                .ok();
4842            }
4843        })
4844        .detach();
4845    }
4846
4847    fn start_language_server(
4848        &mut self,
4849        worktree_handle: &Model<Worktree>,
4850        adapter: Arc<CachedLspAdapter>,
4851        language: LanguageName,
4852        cx: &mut ModelContext<Self>,
4853    ) {
4854        if self.mode.is_remote() {
4855            return;
4856        }
4857
4858        let worktree = worktree_handle.read(cx);
4859        let worktree_id = worktree.id();
4860        let worktree_path = worktree.abs_path();
4861        let key = (worktree_id, adapter.name.clone());
4862        if self.language_server_ids.contains_key(&key) {
4863            return;
4864        }
4865
4866        if self.mode.is_ssh() {
4867            self.start_language_server_on_ssh_host(worktree_handle, adapter, language, cx);
4868            return;
4869        }
4870
4871        if adapter.reinstall_attempt_count.load(SeqCst) > MAX_SERVER_REINSTALL_ATTEMPT_COUNT {
4872            return;
4873        }
4874
4875        let local = self.as_local().unwrap();
4876
4877        let stderr_capture = Arc::new(Mutex::new(Some(String::new())));
4878        let lsp_adapter_delegate = LocalLspAdapterDelegate::for_local(self, worktree_handle, cx);
4879        let project_environment = local.environment.update(cx, |environment, cx| {
4880            environment.get_environment(Some(worktree_id), Some(worktree_path.clone()), cx)
4881        });
4882
4883        let pending_server = match self.languages.create_pending_language_server(
4884            stderr_capture.clone(),
4885            language.clone(),
4886            adapter.clone(),
4887            Arc::clone(&worktree_path),
4888            lsp_adapter_delegate.clone(),
4889            project_environment,
4890            cx,
4891        ) {
4892            Some(pending_server) => pending_server,
4893            None => return,
4894        };
4895
4896        let project_settings = ProjectSettings::get(
4897            Some(SettingsLocation {
4898                worktree_id,
4899                path: Path::new(""),
4900            }),
4901            cx,
4902        );
4903
4904        // We need some on the SSH client, and some on SSH host
4905        let lsp = project_settings.lsp.get(&adapter.name.0);
4906        let override_options = lsp.and_then(|s| s.initialization_options.clone());
4907
4908        let server_id = pending_server.server_id;
4909        let container_dir = pending_server.container_dir.clone();
4910        let state = LanguageServerState::Starting({
4911            let adapter = adapter.clone();
4912            let server_name = adapter.name.0.clone();
4913            let language = language.clone();
4914            let key = key.clone();
4915
4916            cx.spawn(move |this, mut cx| async move {
4917                let result = Self::setup_and_insert_language_server(
4918                    this.clone(),
4919                    lsp_adapter_delegate,
4920                    override_options,
4921                    pending_server,
4922                    adapter.clone(),
4923                    language.clone(),
4924                    server_id,
4925                    key,
4926                    &mut cx,
4927                )
4928                .await;
4929
4930                match result {
4931                    Ok(server) => {
4932                        stderr_capture.lock().take();
4933                        server
4934                    }
4935
4936                    Err(err) => {
4937                        log::error!("failed to start language server {server_name:?}: {err}");
4938                        log::error!("server stderr: {:?}", stderr_capture.lock().take());
4939
4940                        let this = this.upgrade()?;
4941                        let container_dir = container_dir?;
4942
4943                        let attempt_count = adapter.reinstall_attempt_count.fetch_add(1, SeqCst);
4944                        if attempt_count >= MAX_SERVER_REINSTALL_ATTEMPT_COUNT {
4945                            let max = MAX_SERVER_REINSTALL_ATTEMPT_COUNT;
4946                            log::error!("Hit {max} reinstallation attempts for {server_name:?}");
4947                            return None;
4948                        }
4949
4950                        log::info!(
4951                            "retrying installation of language server {server_name:?} in {}s",
4952                            SERVER_REINSTALL_DEBOUNCE_TIMEOUT.as_secs()
4953                        );
4954                        cx.background_executor()
4955                            .timer(SERVER_REINSTALL_DEBOUNCE_TIMEOUT)
4956                            .await;
4957
4958                        let installation_test_binary = adapter
4959                            .installation_test_binary(container_dir.to_path_buf())
4960                            .await;
4961
4962                        this.update(&mut cx, |_, cx| {
4963                            Self::check_errored_server(
4964                                language,
4965                                adapter,
4966                                server_id,
4967                                installation_test_binary,
4968                                cx,
4969                            )
4970                        })
4971                        .ok();
4972
4973                        None
4974                    }
4975                }
4976            })
4977        });
4978
4979        self.as_local_mut()
4980            .unwrap()
4981            .language_servers
4982            .insert(server_id, state);
4983        self.language_server_ids.insert(key, server_id);
4984    }
4985
4986    #[allow(clippy::too_many_arguments)]
4987    async fn setup_and_insert_language_server(
4988        this: WeakModel<Self>,
4989        delegate: Arc<dyn LspAdapterDelegate>,
4990        override_initialization_options: Option<serde_json::Value>,
4991        pending_server: PendingLanguageServer,
4992        adapter: Arc<CachedLspAdapter>,
4993        language: LanguageName,
4994        server_id: LanguageServerId,
4995        key: (WorktreeId, LanguageServerName),
4996        cx: &mut AsyncAppContext,
4997    ) -> Result<Option<Arc<LanguageServer>>> {
4998        let language_server = Self::setup_pending_language_server(
4999            this.clone(),
5000            override_initialization_options,
5001            pending_server,
5002            delegate,
5003            adapter.clone(),
5004            server_id,
5005            cx,
5006        )
5007        .await?;
5008
5009        let this = match this.upgrade() {
5010            Some(this) => this,
5011            None => return Err(anyhow!("failed to upgrade project handle")),
5012        };
5013
5014        this.update(cx, |this, cx| {
5015            this.insert_newly_running_language_server(
5016                language,
5017                adapter,
5018                language_server.clone(),
5019                server_id,
5020                key,
5021                cx,
5022            )
5023        })??;
5024
5025        Ok(Some(language_server))
5026    }
5027
5028    fn reinstall_language_server(
5029        &mut self,
5030        language: LanguageName,
5031        adapter: Arc<CachedLspAdapter>,
5032        server_id: LanguageServerId,
5033        cx: &mut ModelContext<Self>,
5034    ) -> Option<Task<()>> {
5035        log::info!("beginning to reinstall server");
5036
5037        if let Some(local) = self.as_local_mut() {
5038            let existing_server = match local.language_servers.remove(&server_id) {
5039                Some(LanguageServerState::Running { server, .. }) => Some(server),
5040                _ => None,
5041            };
5042
5043            self.worktree_store.update(cx, |store, cx| {
5044                for worktree in store.worktrees() {
5045                    let key = (worktree.read(cx).id(), adapter.name.clone());
5046                    self.language_server_ids.remove(&key);
5047                }
5048            });
5049
5050            Some(cx.spawn(move |this, mut cx| async move {
5051                if let Some(task) = existing_server.and_then(|server| server.shutdown()) {
5052                    log::info!("shutting down existing server");
5053                    task.await;
5054                }
5055
5056                // TODO: This is race-safe with regards to preventing new instances from
5057                // starting while deleting, but existing instances in other projects are going
5058                // to be very confused and messed up
5059                let Some(task) = this
5060                    .update(&mut cx, |this, cx| {
5061                        this.languages.delete_server_container(adapter.clone(), cx)
5062                    })
5063                    .log_err()
5064                else {
5065                    return;
5066                };
5067                task.await;
5068
5069                this.update(&mut cx, |this, cx| {
5070                    for worktree in this.worktree_store.read(cx).worktrees().collect::<Vec<_>>() {
5071                        this.start_language_server(
5072                            &worktree,
5073                            adapter.clone(),
5074                            language.clone(),
5075                            cx,
5076                        );
5077                    }
5078                })
5079                .ok();
5080            }))
5081        } else if let Some(_ssh_store) = self.as_ssh() {
5082            // TODO
5083            None
5084        } else {
5085            None
5086        }
5087    }
5088
5089    async fn shutdown_language_server(
5090        server_state: Option<LanguageServerState>,
5091        name: Arc<str>,
5092        cx: AsyncAppContext,
5093    ) {
5094        let server = match server_state {
5095            Some(LanguageServerState::Starting(task)) => {
5096                let mut timer = cx
5097                    .background_executor()
5098                    .timer(SERVER_LAUNCHING_BEFORE_SHUTDOWN_TIMEOUT)
5099                    .fuse();
5100
5101                select! {
5102                    server = task.fuse() => server,
5103                    _ = timer => {
5104                        log::info!(
5105                            "timeout waiting for language server {} to finish launching before stopping",
5106                            name
5107                        );
5108                        None
5109                    },
5110                }
5111            }
5112
5113            Some(LanguageServerState::Running { server, .. }) => Some(server),
5114
5115            None => None,
5116        };
5117
5118        if let Some(server) = server {
5119            if let Some(shutdown) = server.shutdown() {
5120                shutdown.await;
5121            }
5122        }
5123    }
5124
5125    // Returns a list of all of the worktrees which no longer have a language server and the root path
5126    // for the stopped server
5127    pub fn stop_language_server(
5128        &mut self,
5129        worktree_id: WorktreeId,
5130        adapter_name: LanguageServerName,
5131        cx: &mut ModelContext<Self>,
5132    ) -> Task<Vec<WorktreeId>> {
5133        let key = (worktree_id, adapter_name);
5134        if self.mode.is_local() {
5135            if let Some(server_id) = self.language_server_ids.remove(&key) {
5136                let name = key.1 .0;
5137                log::info!("stopping language server {name}");
5138
5139                // Remove other entries for this language server as well
5140                let mut orphaned_worktrees = vec![worktree_id];
5141                let other_keys = self.language_server_ids.keys().cloned().collect::<Vec<_>>();
5142                for other_key in other_keys {
5143                    if self.language_server_ids.get(&other_key) == Some(&server_id) {
5144                        self.language_server_ids.remove(&other_key);
5145                        orphaned_worktrees.push(other_key.0);
5146                    }
5147                }
5148
5149                self.buffer_store.update(cx, |buffer_store, cx| {
5150                    for buffer in buffer_store.buffers() {
5151                        buffer.update(cx, |buffer, cx| {
5152                            buffer.update_diagnostics(
5153                                server_id,
5154                                DiagnosticSet::new([], buffer),
5155                                cx,
5156                            );
5157                        });
5158                    }
5159                });
5160
5161                let project_id = self.project_id;
5162                for (worktree_id, summaries) in self.diagnostic_summaries.iter_mut() {
5163                    summaries.retain(|path, summaries_by_server_id| {
5164                        if summaries_by_server_id.remove(&server_id).is_some() {
5165                            if let Some(downstream_client) = self.downstream_client.clone() {
5166                                downstream_client
5167                                    .send(proto::UpdateDiagnosticSummary {
5168                                        project_id,
5169                                        worktree_id: worktree_id.to_proto(),
5170                                        summary: Some(proto::DiagnosticSummary {
5171                                            path: path.to_string_lossy().to_string(),
5172                                            language_server_id: server_id.0 as u64,
5173                                            error_count: 0,
5174                                            warning_count: 0,
5175                                        }),
5176                                    })
5177                                    .log_err();
5178                            }
5179                            !summaries_by_server_id.is_empty()
5180                        } else {
5181                            true
5182                        }
5183                    });
5184                }
5185
5186                for diagnostics in self.diagnostics.values_mut() {
5187                    diagnostics.retain(|_, diagnostics_by_server_id| {
5188                        if let Ok(ix) =
5189                            diagnostics_by_server_id.binary_search_by_key(&server_id, |e| e.0)
5190                        {
5191                            diagnostics_by_server_id.remove(ix);
5192                            !diagnostics_by_server_id.is_empty()
5193                        } else {
5194                            true
5195                        }
5196                    });
5197                }
5198
5199                self.as_local_mut()
5200                    .unwrap()
5201                    .language_server_watched_paths
5202                    .remove(&server_id);
5203                self.language_server_statuses.remove(&server_id);
5204                cx.notify();
5205
5206                let server_state = self
5207                    .as_local_mut()
5208                    .unwrap()
5209                    .language_servers
5210                    .remove(&server_id);
5211                cx.emit(LspStoreEvent::LanguageServerRemoved(server_id));
5212                cx.spawn(move |_, cx| async move {
5213                    Self::shutdown_language_server(server_state, name, cx).await;
5214                    orphaned_worktrees
5215                })
5216            } else {
5217                Task::ready(Vec::new())
5218            }
5219        } else if self.mode.is_ssh() {
5220            // TODO ssh
5221            Task::ready(Vec::new())
5222        } else {
5223            Task::ready(Vec::new())
5224        }
5225    }
5226
5227    pub fn restart_language_servers_for_buffers(
5228        &mut self,
5229        buffers: impl IntoIterator<Item = Model<Buffer>>,
5230        cx: &mut ModelContext<Self>,
5231    ) {
5232        if let Some(client) = self.upstream_client() {
5233            let request = client.request(proto::RestartLanguageServers {
5234                project_id: self.project_id,
5235                buffer_ids: buffers
5236                    .into_iter()
5237                    .map(|b| b.read(cx).remote_id().to_proto())
5238                    .collect(),
5239            });
5240            cx.background_executor()
5241                .spawn(request)
5242                .detach_and_log_err(cx);
5243        } else {
5244            #[allow(clippy::mutable_key_type)]
5245            let language_server_lookup_info: HashSet<(Model<Worktree>, LanguageName)> = buffers
5246                .into_iter()
5247                .filter_map(|buffer| {
5248                    let buffer = buffer.read(cx);
5249                    let file = buffer.file()?;
5250                    let worktree = File::from_dyn(Some(file))?.worktree.clone();
5251                    let language =
5252                        self.languages
5253                            .language_for_file(file, Some(buffer.as_rope()), cx)?;
5254
5255                    Some((worktree, language.name()))
5256                })
5257                .collect();
5258
5259            for (worktree, language) in language_server_lookup_info {
5260                self.restart_language_servers(worktree, language, cx);
5261            }
5262        }
5263    }
5264
5265    pub fn restart_language_servers(
5266        &mut self,
5267        worktree: Model<Worktree>,
5268        language: LanguageName,
5269        cx: &mut ModelContext<Self>,
5270    ) {
5271        let worktree_id = worktree.read(cx).id();
5272
5273        let stop_tasks = self
5274            .languages
5275            .clone()
5276            .lsp_adapters(&language)
5277            .iter()
5278            .map(|adapter| {
5279                let stop_task = self.stop_language_server(worktree_id, adapter.name.clone(), cx);
5280                (stop_task, adapter.name.clone())
5281            })
5282            .collect::<Vec<_>>();
5283        if stop_tasks.is_empty() {
5284            return;
5285        }
5286
5287        cx.spawn(move |this, mut cx| async move {
5288            // For each stopped language server, record all of the worktrees with which
5289            // it was associated.
5290            let mut affected_worktrees = Vec::new();
5291            for (stop_task, language_server_name) in stop_tasks {
5292                for affected_worktree_id in stop_task.await {
5293                    affected_worktrees.push((affected_worktree_id, language_server_name.clone()));
5294                }
5295            }
5296
5297            this.update(&mut cx, |this, cx| {
5298                // Restart the language server for the given worktree.
5299                this.start_language_servers(&worktree, language.clone(), cx);
5300
5301                // Lookup new server ids and set them for each of the orphaned worktrees
5302                for (affected_worktree_id, language_server_name) in affected_worktrees {
5303                    if let Some(new_server_id) = this
5304                        .language_server_ids
5305                        .get(&(worktree_id, language_server_name.clone()))
5306                        .cloned()
5307                    {
5308                        this.language_server_ids
5309                            .insert((affected_worktree_id, language_server_name), new_server_id);
5310                    }
5311                }
5312            })
5313            .ok();
5314        })
5315        .detach();
5316    }
5317
5318    fn check_errored_server(
5319        language: LanguageName,
5320        adapter: Arc<CachedLspAdapter>,
5321        server_id: LanguageServerId,
5322        installation_test_binary: Option<LanguageServerBinary>,
5323        cx: &mut ModelContext<Self>,
5324    ) {
5325        if !adapter.can_be_reinstalled() {
5326            log::info!(
5327                "Validation check requested for {:?} but it cannot be reinstalled",
5328                adapter.name.0
5329            );
5330            return;
5331        }
5332
5333        cx.spawn(move |this, mut cx| async move {
5334            log::info!("About to spawn test binary");
5335
5336            // A lack of test binary counts as a failure
5337            let process = installation_test_binary.and_then(|binary| {
5338                smol::process::Command::new(&binary.path)
5339                    .current_dir(&binary.path)
5340                    .args(binary.arguments)
5341                    .stdin(Stdio::piped())
5342                    .stdout(Stdio::piped())
5343                    .stderr(Stdio::inherit())
5344                    .kill_on_drop(true)
5345                    .spawn()
5346                    .ok()
5347            });
5348
5349            const PROCESS_TIMEOUT: Duration = Duration::from_secs(5);
5350            let mut timeout = cx.background_executor().timer(PROCESS_TIMEOUT).fuse();
5351
5352            let mut errored = false;
5353            if let Some(mut process) = process {
5354                futures::select! {
5355                    status = process.status().fuse() => match status {
5356                        Ok(status) => errored = !status.success(),
5357                        Err(_) => errored = true,
5358                    },
5359
5360                    _ = timeout => {
5361                        log::info!("test binary time-ed out, this counts as a success");
5362                        _ = process.kill();
5363                    }
5364                }
5365            } else {
5366                log::warn!("test binary failed to launch");
5367                errored = true;
5368            }
5369
5370            if errored {
5371                log::warn!("test binary check failed");
5372                let task = this
5373                    .update(&mut cx, move |this, cx| {
5374                        this.reinstall_language_server(language, adapter, server_id, cx)
5375                    })
5376                    .ok()
5377                    .flatten();
5378
5379                if let Some(task) = task {
5380                    task.await;
5381                }
5382            }
5383        })
5384        .detach();
5385    }
5386
5387    async fn setup_pending_language_server(
5388        this: WeakModel<Self>,
5389        override_options: Option<serde_json::Value>,
5390        pending_server: PendingLanguageServer,
5391        delegate: Arc<dyn LspAdapterDelegate>,
5392        adapter: Arc<CachedLspAdapter>,
5393        server_id: LanguageServerId,
5394        cx: &mut AsyncAppContext,
5395    ) -> Result<Arc<LanguageServer>> {
5396        let workspace_config = adapter
5397            .adapter
5398            .clone()
5399            .workspace_configuration(&delegate, cx)
5400            .await?;
5401        // This has to come from the server
5402        let (language_server, mut initialization_options) = pending_server.task.await?;
5403
5404        let name = language_server.name();
5405        language_server
5406            .on_notification::<lsp::notification::PublishDiagnostics, _>({
5407                let adapter = adapter.clone();
5408                let this = this.clone();
5409                move |mut params, mut cx| {
5410                    let adapter = adapter.clone();
5411                    if let Some(this) = this.upgrade() {
5412                        adapter.process_diagnostics(&mut params);
5413                        // Everything else has to be on the server, Can we make it on the client?
5414                        this.update(&mut cx, |this, cx| {
5415                            this.update_diagnostics(
5416                                server_id,
5417                                params,
5418                                &adapter.disk_based_diagnostic_sources,
5419                                cx,
5420                            )
5421                            .log_err();
5422                        })
5423                        .ok();
5424                    }
5425                }
5426            })
5427            .detach();
5428
5429        language_server
5430            .on_request::<lsp::request::WorkspaceConfiguration, _, _>({
5431                let adapter = adapter.adapter.clone();
5432                let delegate = delegate.clone();
5433                move |params, mut cx| {
5434                    let adapter = adapter.clone();
5435                    let delegate = delegate.clone();
5436                    async move {
5437                        let workspace_config =
5438                            adapter.workspace_configuration(&delegate, &mut cx).await?;
5439                        Ok(params
5440                            .items
5441                            .into_iter()
5442                            .map(|item| {
5443                                if let Some(section) = &item.section {
5444                                    workspace_config
5445                                        .get(section)
5446                                        .cloned()
5447                                        .unwrap_or(serde_json::Value::Null)
5448                                } else {
5449                                    workspace_config.clone()
5450                                }
5451                            })
5452                            .collect())
5453                    }
5454                }
5455            })
5456            .detach();
5457
5458        let id = language_server.server_id();
5459        language_server
5460            .on_request::<lsp::request::WorkspaceFoldersRequest, _, _>({
5461                let this = this.clone();
5462                move |_, mut cx| {
5463                    let this = this.clone();
5464                    async move {
5465                        let Some(server) =
5466                            this.update(&mut cx, |this, _| this.language_server_for_id(id))?
5467                        else {
5468                            return Ok(None);
5469                        };
5470                        let root = server.root_path();
5471                        let Ok(uri) = Url::from_file_path(&root) else {
5472                            return Ok(None);
5473                        };
5474                        Ok(Some(vec![WorkspaceFolder {
5475                            uri,
5476                            name: Default::default(),
5477                        }]))
5478                    }
5479                }
5480            })
5481            .detach();
5482        // Even though we don't have handling for these requests, respond to them to
5483        // avoid stalling any language server like `gopls` which waits for a response
5484        // to these requests when initializing.
5485        language_server
5486            .on_request::<lsp::request::WorkDoneProgressCreate, _, _>({
5487                let this = this.clone();
5488                move |params, mut cx| {
5489                    let this = this.clone();
5490                    async move {
5491                        this.update(&mut cx, |this, _| {
5492                            if let Some(status) = this.language_server_statuses.get_mut(&server_id)
5493                            {
5494                                if let lsp::NumberOrString::String(token) = params.token {
5495                                    status.progress_tokens.insert(token);
5496                                }
5497                            }
5498                        })?;
5499
5500                        Ok(())
5501                    }
5502                }
5503            })
5504            .detach();
5505
5506        language_server
5507            .on_request::<lsp::request::RegisterCapability, _, _>({
5508                let this = this.clone();
5509                move |params, mut cx| {
5510                    let this = this.clone();
5511                    async move {
5512                        for reg in params.registrations {
5513                            match reg.method.as_str() {
5514                                "workspace/didChangeWatchedFiles" => {
5515                                    if let Some(options) = reg.register_options {
5516                                        let options = serde_json::from_value(options)?;
5517                                        this.update(&mut cx, |this, cx| {
5518                                            this.on_lsp_did_change_watched_files(
5519                                                server_id, &reg.id, options, cx,
5520                                            );
5521                                        })?;
5522                                    }
5523                                }
5524                                "textDocument/rangeFormatting" => {
5525                                    this.update(&mut cx, |this, _| {
5526                                        if let Some(server) = this.language_server_for_id(server_id)
5527                                        {
5528                                            let options = reg
5529                                                .register_options
5530                                                .map(|options| {
5531                                                    serde_json::from_value::<
5532                                                        lsp::DocumentRangeFormattingOptions,
5533                                                    >(
5534                                                        options
5535                                                    )
5536                                                })
5537                                                .transpose()?;
5538                                            let provider = match options {
5539                                                None => OneOf::Left(true),
5540                                                Some(options) => OneOf::Right(options),
5541                                            };
5542                                            server.update_capabilities(|capabilities| {
5543                                                capabilities.document_range_formatting_provider =
5544                                                    Some(provider);
5545                                            })
5546                                        }
5547                                        anyhow::Ok(())
5548                                    })??;
5549                                }
5550                                "textDocument/onTypeFormatting" => {
5551                                    this.update(&mut cx, |this, _| {
5552                                        if let Some(server) = this.language_server_for_id(server_id)
5553                                        {
5554                                            let options = reg
5555                                                .register_options
5556                                                .map(|options| {
5557                                                    serde_json::from_value::<
5558                                                        lsp::DocumentOnTypeFormattingOptions,
5559                                                    >(
5560                                                        options
5561                                                    )
5562                                                })
5563                                                .transpose()?;
5564                                            if let Some(options) = options {
5565                                                server.update_capabilities(|capabilities| {
5566                                                    capabilities
5567                                                        .document_on_type_formatting_provider =
5568                                                        Some(options);
5569                                                })
5570                                            }
5571                                        }
5572                                        anyhow::Ok(())
5573                                    })??;
5574                                }
5575                                "textDocument/formatting" => {
5576                                    this.update(&mut cx, |this, _| {
5577                                        if let Some(server) = this.language_server_for_id(server_id)
5578                                        {
5579                                            let options = reg
5580                                                .register_options
5581                                                .map(|options| {
5582                                                    serde_json::from_value::<
5583                                                        lsp::DocumentFormattingOptions,
5584                                                    >(
5585                                                        options
5586                                                    )
5587                                                })
5588                                                .transpose()?;
5589                                            let provider = match options {
5590                                                None => OneOf::Left(true),
5591                                                Some(options) => OneOf::Right(options),
5592                                            };
5593                                            server.update_capabilities(|capabilities| {
5594                                                capabilities.document_formatting_provider =
5595                                                    Some(provider);
5596                                            })
5597                                        }
5598                                        anyhow::Ok(())
5599                                    })??;
5600                                }
5601                                _ => log::warn!("unhandled capability registration: {reg:?}"),
5602                            }
5603                        }
5604                        Ok(())
5605                    }
5606                }
5607            })
5608            .detach();
5609
5610        language_server
5611            .on_request::<lsp::request::UnregisterCapability, _, _>({
5612                let this = this.clone();
5613                move |params, mut cx| {
5614                    let this = this.clone();
5615                    async move {
5616                        for unreg in params.unregisterations.iter() {
5617                            match unreg.method.as_str() {
5618                                "workspace/didChangeWatchedFiles" => {
5619                                    this.update(&mut cx, |this, cx| {
5620                                        this.on_lsp_unregister_did_change_watched_files(
5621                                            server_id, &unreg.id, cx,
5622                                        );
5623                                    })?;
5624                                }
5625                                "textDocument/rangeFormatting" => {
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_range_formatting_provider =
5631                                                    None
5632                                            })
5633                                        }
5634                                    })?;
5635                                }
5636                                "textDocument/onTypeFormatting" => {
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_on_type_formatting_provider =
5642                                                    None;
5643                                            })
5644                                        }
5645                                    })?;
5646                                }
5647                                "textDocument/formatting" => {
5648                                    this.update(&mut cx, |this, _| {
5649                                        if let Some(server) = this.language_server_for_id(server_id)
5650                                        {
5651                                            server.update_capabilities(|capabilities| {
5652                                                capabilities.document_formatting_provider = None;
5653                                            })
5654                                        }
5655                                    })?;
5656                                }
5657                                _ => log::warn!("unhandled capability unregistration: {unreg:?}"),
5658                            }
5659                        }
5660                        Ok(())
5661                    }
5662                }
5663            })
5664            .detach();
5665
5666        language_server
5667            .on_request::<lsp::request::ApplyWorkspaceEdit, _, _>({
5668                let adapter = adapter.clone();
5669                let this = this.clone();
5670                move |params, cx| {
5671                    Self::on_lsp_workspace_edit(
5672                        this.clone(),
5673                        params,
5674                        server_id,
5675                        adapter.clone(),
5676                        cx,
5677                    )
5678                }
5679            })
5680            .detach();
5681
5682        language_server
5683            .on_request::<lsp::request::InlayHintRefreshRequest, _, _>({
5684                let this = this.clone();
5685                move |(), mut cx| {
5686                    let this = this.clone();
5687                    async move {
5688                        this.update(&mut cx, |this, cx| {
5689                            cx.emit(LspStoreEvent::RefreshInlayHints);
5690                            this.downstream_client.as_ref().map(|client| {
5691                                client.send(proto::RefreshInlayHints {
5692                                    project_id: this.project_id,
5693                                })
5694                            })
5695                        })?
5696                        .transpose()?;
5697                        Ok(())
5698                    }
5699                }
5700            })
5701            .detach();
5702
5703        language_server
5704            .on_request::<lsp::request::ShowMessageRequest, _, _>({
5705                let this = this.clone();
5706                let name = name.to_string();
5707                move |params, mut cx| {
5708                    let this = this.clone();
5709                    let name = name.to_string();
5710                    async move {
5711                        let actions = params.actions.unwrap_or_default();
5712                        let (tx, mut rx) = smol::channel::bounded(1);
5713                        let request = LanguageServerPromptRequest {
5714                            level: match params.typ {
5715                                lsp::MessageType::ERROR => PromptLevel::Critical,
5716                                lsp::MessageType::WARNING => PromptLevel::Warning,
5717                                _ => PromptLevel::Info,
5718                            },
5719                            message: params.message,
5720                            actions,
5721                            response_channel: tx,
5722                            lsp_name: name.clone(),
5723                        };
5724
5725                        let did_update = this
5726                            .update(&mut cx, |_, cx| {
5727                                cx.emit(LspStoreEvent::LanguageServerPrompt(request));
5728                            })
5729                            .is_ok();
5730                        if did_update {
5731                            let response = rx.next().await;
5732
5733                            Ok(response)
5734                        } else {
5735                            Ok(None)
5736                        }
5737                    }
5738                }
5739            })
5740            .detach();
5741
5742        let disk_based_diagnostics_progress_token =
5743            adapter.disk_based_diagnostics_progress_token.clone();
5744
5745        language_server
5746            .on_notification::<ServerStatus, _>({
5747                let this = this.clone();
5748                let name = name.to_string();
5749                move |params, mut cx| {
5750                    let this = this.clone();
5751                    let name = name.to_string();
5752                    if let Some(ref message) = params.message {
5753                        let message = message.trim();
5754                        if !message.is_empty() {
5755                            let formatted_message = format!(
5756                                "Language server {name} (id {server_id}) status update: {message}"
5757                            );
5758                            match params.health {
5759                                ServerHealthStatus::Ok => log::info!("{}", formatted_message),
5760                                ServerHealthStatus::Warning => log::warn!("{}", formatted_message),
5761                                ServerHealthStatus::Error => {
5762                                    log::error!("{}", formatted_message);
5763                                    let (tx, _rx) = smol::channel::bounded(1);
5764                                    let request = LanguageServerPromptRequest {
5765                                        level: PromptLevel::Critical,
5766                                        message: params.message.unwrap_or_default(),
5767                                        actions: Vec::new(),
5768                                        response_channel: tx,
5769                                        lsp_name: name.clone(),
5770                                    };
5771                                    let _ = this
5772                                        .update(&mut cx, |_, cx| {
5773                                            cx.emit(LspStoreEvent::LanguageServerPrompt(request));
5774                                        })
5775                                        .ok();
5776                                }
5777                                ServerHealthStatus::Other(status) => {
5778                                    log::info!(
5779                                        "Unknown server health: {status}\n{formatted_message}"
5780                                    )
5781                                }
5782                            }
5783                        }
5784                    }
5785                }
5786            })
5787            .detach();
5788        language_server
5789            .on_notification::<lsp::notification::ShowMessage, _>({
5790                let this = this.clone();
5791                let name = name.to_string();
5792                move |params, mut cx| {
5793                    let this = this.clone();
5794                    let name = name.to_string();
5795
5796                    let (tx, _) = smol::channel::bounded(1);
5797                    let request = LanguageServerPromptRequest {
5798                        level: match params.typ {
5799                            lsp::MessageType::ERROR => PromptLevel::Critical,
5800                            lsp::MessageType::WARNING => PromptLevel::Warning,
5801                            _ => PromptLevel::Info,
5802                        },
5803                        message: params.message,
5804                        actions: vec![],
5805                        response_channel: tx,
5806                        lsp_name: name.clone(),
5807                    };
5808
5809                    let _ = this.update(&mut cx, |_, cx| {
5810                        cx.emit(LspStoreEvent::LanguageServerPrompt(request));
5811                    });
5812                }
5813            })
5814            .detach();
5815        language_server
5816            .on_notification::<lsp::notification::Progress, _>({
5817                let this = this.clone();
5818                move |params, mut cx| {
5819                    if let Some(this) = this.upgrade() {
5820                        this.update(&mut cx, |this, cx| {
5821                            this.on_lsp_progress(
5822                                params,
5823                                server_id,
5824                                disk_based_diagnostics_progress_token.clone(),
5825                                cx,
5826                            );
5827                        })
5828                        .ok();
5829                    }
5830                }
5831            })
5832            .detach();
5833
5834        language_server
5835            .on_notification::<lsp::notification::LogMessage, _>({
5836                let this = this.clone();
5837                move |params, mut cx| {
5838                    if let Some(this) = this.upgrade() {
5839                        this.update(&mut cx, |_, cx| {
5840                            cx.emit(LspStoreEvent::LanguageServerLog(
5841                                server_id,
5842                                LanguageServerLogType::Log(params.typ),
5843                                params.message,
5844                            ));
5845                        })
5846                        .ok();
5847                    }
5848                }
5849            })
5850            .detach();
5851
5852        language_server
5853            .on_notification::<lsp::notification::LogTrace, _>({
5854                let this = this.clone();
5855                move |params, mut cx| {
5856                    if let Some(this) = this.upgrade() {
5857                        this.update(&mut cx, |_, cx| {
5858                            cx.emit(LspStoreEvent::LanguageServerLog(
5859                                server_id,
5860                                LanguageServerLogType::Trace(params.verbose),
5861                                params.message,
5862                            ));
5863                        })
5864                        .ok();
5865                    }
5866                }
5867            })
5868            .detach();
5869
5870        match (&mut initialization_options, override_options) {
5871            (Some(initialization_options), Some(override_options)) => {
5872                merge_json_value_into(override_options, initialization_options);
5873            }
5874            (None, override_options) => initialization_options = override_options,
5875            _ => {}
5876        }
5877
5878        let language_server = cx
5879            .update(|cx| language_server.initialize(initialization_options, cx))?
5880            .await
5881            .inspect_err(|_| {
5882                if let Some(this) = this.upgrade() {
5883                    this.update(cx, |_, cx| {
5884                        cx.emit(LspStoreEvent::LanguageServerRemoved(server_id))
5885                    })
5886                    .ok();
5887                }
5888            })?;
5889
5890        language_server
5891            .notify::<lsp::notification::DidChangeConfiguration>(
5892                lsp::DidChangeConfigurationParams {
5893                    settings: workspace_config,
5894                },
5895            )
5896            .ok();
5897
5898        Ok(language_server)
5899    }
5900
5901    pub fn update_diagnostics(
5902        &mut self,
5903        language_server_id: LanguageServerId,
5904        mut params: lsp::PublishDiagnosticsParams,
5905        disk_based_sources: &[String],
5906        cx: &mut ModelContext<Self>,
5907    ) -> Result<()> {
5908        let abs_path = params
5909            .uri
5910            .to_file_path()
5911            .map_err(|_| anyhow!("URI is not a file"))?;
5912        let mut diagnostics = Vec::default();
5913        let mut primary_diagnostic_group_ids = HashMap::default();
5914        let mut sources_by_group_id = HashMap::default();
5915        let mut supporting_diagnostics = HashMap::default();
5916
5917        // Ensure that primary diagnostics are always the most severe
5918        params.diagnostics.sort_by_key(|item| item.severity);
5919
5920        for diagnostic in &params.diagnostics {
5921            let source = diagnostic.source.as_ref();
5922            let code = diagnostic.code.as_ref().map(|code| match code {
5923                lsp::NumberOrString::Number(code) => code.to_string(),
5924                lsp::NumberOrString::String(code) => code.clone(),
5925            });
5926            let range = range_from_lsp(diagnostic.range);
5927            let is_supporting = diagnostic
5928                .related_information
5929                .as_ref()
5930                .map_or(false, |infos| {
5931                    infos.iter().any(|info| {
5932                        primary_diagnostic_group_ids.contains_key(&(
5933                            source,
5934                            code.clone(),
5935                            range_from_lsp(info.location.range),
5936                        ))
5937                    })
5938                });
5939
5940            let is_unnecessary = diagnostic.tags.as_ref().map_or(false, |tags| {
5941                tags.iter().any(|tag| *tag == DiagnosticTag::UNNECESSARY)
5942            });
5943
5944            if is_supporting {
5945                supporting_diagnostics.insert(
5946                    (source, code.clone(), range),
5947                    (diagnostic.severity, is_unnecessary),
5948                );
5949            } else {
5950                let group_id = post_inc(&mut self.next_diagnostic_group_id);
5951                let is_disk_based =
5952                    source.map_or(false, |source| disk_based_sources.contains(source));
5953
5954                sources_by_group_id.insert(group_id, source);
5955                primary_diagnostic_group_ids
5956                    .insert((source, code.clone(), range.clone()), group_id);
5957
5958                diagnostics.push(DiagnosticEntry {
5959                    range,
5960                    diagnostic: Diagnostic {
5961                        source: diagnostic.source.clone(),
5962                        code: code.clone(),
5963                        severity: diagnostic.severity.unwrap_or(DiagnosticSeverity::ERROR),
5964                        message: diagnostic.message.trim().to_string(),
5965                        group_id,
5966                        is_primary: true,
5967                        is_disk_based,
5968                        is_unnecessary,
5969                        data: diagnostic.data.clone(),
5970                    },
5971                });
5972                if let Some(infos) = &diagnostic.related_information {
5973                    for info in infos {
5974                        if info.location.uri == params.uri && !info.message.is_empty() {
5975                            let range = range_from_lsp(info.location.range);
5976                            diagnostics.push(DiagnosticEntry {
5977                                range,
5978                                diagnostic: Diagnostic {
5979                                    source: diagnostic.source.clone(),
5980                                    code: code.clone(),
5981                                    severity: DiagnosticSeverity::INFORMATION,
5982                                    message: info.message.trim().to_string(),
5983                                    group_id,
5984                                    is_primary: false,
5985                                    is_disk_based,
5986                                    is_unnecessary: false,
5987                                    data: diagnostic.data.clone(),
5988                                },
5989                            });
5990                        }
5991                    }
5992                }
5993            }
5994        }
5995
5996        for entry in &mut diagnostics {
5997            let diagnostic = &mut entry.diagnostic;
5998            if !diagnostic.is_primary {
5999                let source = *sources_by_group_id.get(&diagnostic.group_id).unwrap();
6000                if let Some(&(severity, is_unnecessary)) = supporting_diagnostics.get(&(
6001                    source,
6002                    diagnostic.code.clone(),
6003                    entry.range.clone(),
6004                )) {
6005                    if let Some(severity) = severity {
6006                        diagnostic.severity = severity;
6007                    }
6008                    diagnostic.is_unnecessary = is_unnecessary;
6009                }
6010            }
6011        }
6012
6013        self.update_diagnostic_entries(
6014            language_server_id,
6015            abs_path,
6016            params.version,
6017            diagnostics,
6018            cx,
6019        )?;
6020        Ok(())
6021    }
6022
6023    fn insert_newly_running_language_server(
6024        &mut self,
6025        language: LanguageName,
6026        adapter: Arc<CachedLspAdapter>,
6027        language_server: Arc<LanguageServer>,
6028        server_id: LanguageServerId,
6029        key: (WorktreeId, LanguageServerName),
6030        cx: &mut ModelContext<Self>,
6031    ) -> Result<()> {
6032        // If the language server for this key doesn't match the server id, don't store the
6033        // server. Which will cause it to be dropped, killing the process
6034        if self
6035            .language_server_ids
6036            .get(&key)
6037            .map(|id| id != &server_id)
6038            .unwrap_or(false)
6039        {
6040            return Ok(());
6041        }
6042
6043        // Update language_servers collection with Running variant of LanguageServerState
6044        // indicating that the server is up and running and ready
6045        if let Some(local) = self.as_local_mut() {
6046            local.language_servers.insert(
6047                server_id,
6048                LanguageServerState::Running {
6049                    adapter: adapter.clone(),
6050                    language: language.clone(),
6051                    server: language_server.clone(),
6052                    simulate_disk_based_diagnostics_completion: None,
6053                },
6054            );
6055        }
6056
6057        self.language_server_statuses.insert(
6058            server_id,
6059            LanguageServerStatus {
6060                name: language_server.name().to_string(),
6061                pending_work: Default::default(),
6062                has_pending_diagnostic_updates: false,
6063                progress_tokens: Default::default(),
6064            },
6065        );
6066
6067        cx.emit(LspStoreEvent::LanguageServerAdded(server_id));
6068
6069        if let Some(downstream_client) = self.downstream_client.as_ref() {
6070            downstream_client.send(proto::StartLanguageServer {
6071                project_id: self.project_id,
6072                server: Some(proto::LanguageServer {
6073                    id: server_id.0 as u64,
6074                    name: language_server.name().to_string(),
6075                }),
6076            })?;
6077        }
6078
6079        // Tell the language server about every open buffer in the worktree that matches the language.
6080        self.buffer_store.update(cx, |buffer_store, cx| {
6081            for buffer_handle in buffer_store.buffers() {
6082                let buffer = buffer_handle.read(cx);
6083                let file = match File::from_dyn(buffer.file()) {
6084                    Some(file) => file,
6085                    None => continue,
6086                };
6087                let language = match buffer.language() {
6088                    Some(language) => language,
6089                    None => continue,
6090                };
6091
6092                if file.worktree.read(cx).id() != key.0
6093                    || !self
6094                        .languages
6095                        .lsp_adapters(&language.name())
6096                        .iter()
6097                        .any(|a| a.name == key.1)
6098                {
6099                    continue;
6100                }
6101
6102                let file = match file.as_local() {
6103                    Some(file) => file,
6104                    None => continue,
6105                };
6106
6107                let versions = self
6108                    .buffer_snapshots
6109                    .entry(buffer.remote_id())
6110                    .or_default()
6111                    .entry(server_id)
6112                    .or_insert_with(|| {
6113                        vec![LspBufferSnapshot {
6114                            version: 0,
6115                            snapshot: buffer.text_snapshot(),
6116                        }]
6117                    });
6118
6119                let snapshot = versions.last().unwrap();
6120                let version = snapshot.version;
6121                let initial_snapshot = &snapshot.snapshot;
6122                let uri = lsp::Url::from_file_path(file.abs_path(cx)).unwrap();
6123                language_server.notify::<lsp::notification::DidOpenTextDocument>(
6124                    lsp::DidOpenTextDocumentParams {
6125                        text_document: lsp::TextDocumentItem::new(
6126                            uri,
6127                            adapter.language_id(&language.name()),
6128                            version,
6129                            initial_snapshot.text(),
6130                        ),
6131                    },
6132                )?;
6133
6134                buffer_handle.update(cx, |buffer, cx| {
6135                    buffer.set_completion_triggers(
6136                        language_server
6137                            .capabilities()
6138                            .completion_provider
6139                            .as_ref()
6140                            .and_then(|provider| provider.trigger_characters.clone())
6141                            .unwrap_or_default(),
6142                        cx,
6143                    )
6144                });
6145            }
6146            anyhow::Ok(())
6147        })?;
6148
6149        cx.notify();
6150        Ok(())
6151    }
6152
6153    fn buffer_snapshot_for_lsp_version(
6154        &mut self,
6155        buffer: &Model<Buffer>,
6156        server_id: LanguageServerId,
6157        version: Option<i32>,
6158        cx: &AppContext,
6159    ) -> Result<TextBufferSnapshot> {
6160        const OLD_VERSIONS_TO_RETAIN: i32 = 10;
6161
6162        if let Some(version) = version {
6163            let buffer_id = buffer.read(cx).remote_id();
6164            let snapshots = self
6165                .buffer_snapshots
6166                .get_mut(&buffer_id)
6167                .and_then(|m| m.get_mut(&server_id))
6168                .ok_or_else(|| {
6169                    anyhow!("no snapshots found for buffer {buffer_id} and server {server_id}")
6170                })?;
6171
6172            let found_snapshot = snapshots
6173                .binary_search_by_key(&version, |e| e.version)
6174                .map(|ix| snapshots[ix].snapshot.clone())
6175                .map_err(|_| {
6176                    anyhow!("snapshot not found for buffer {buffer_id} server {server_id} at version {version}")
6177                })?;
6178
6179            snapshots.retain(|snapshot| snapshot.version + OLD_VERSIONS_TO_RETAIN >= version);
6180            Ok(found_snapshot)
6181        } else {
6182            Ok((buffer.read(cx)).text_snapshot())
6183        }
6184    }
6185
6186    pub fn language_servers_running_disk_based_diagnostics(
6187        &self,
6188    ) -> impl Iterator<Item = LanguageServerId> + '_ {
6189        self.language_server_statuses
6190            .iter()
6191            .filter_map(|(id, status)| {
6192                if status.has_pending_diagnostic_updates {
6193                    Some(*id)
6194                } else {
6195                    None
6196                }
6197            })
6198    }
6199
6200    pub(crate) fn language_servers_for_buffer<'a>(
6201        &'a self,
6202        buffer: &'a Buffer,
6203        cx: &'a AppContext,
6204    ) -> impl Iterator<Item = (&'a Arc<CachedLspAdapter>, &'a Arc<LanguageServer>)> {
6205        self.language_server_ids_for_buffer(buffer, cx)
6206            .into_iter()
6207            .filter_map(
6208                |server_id| match self.as_local()?.language_servers.get(&server_id)? {
6209                    LanguageServerState::Running {
6210                        adapter, server, ..
6211                    } => Some((adapter, server)),
6212                    _ => None,
6213                },
6214            )
6215    }
6216
6217    pub(crate) fn cancel_language_server_work_for_buffers(
6218        &mut self,
6219        buffers: impl IntoIterator<Item = Model<Buffer>>,
6220        cx: &mut ModelContext<Self>,
6221    ) {
6222        let servers = buffers
6223            .into_iter()
6224            .flat_map(|buffer| {
6225                self.language_server_ids_for_buffer(buffer.read(cx), cx)
6226                    .into_iter()
6227            })
6228            .collect::<HashSet<_>>();
6229
6230        for server_id in servers {
6231            self.cancel_language_server_work(server_id, None, cx);
6232        }
6233    }
6234
6235    pub fn language_servers(
6236        &self,
6237    ) -> impl '_ + Iterator<Item = (LanguageServerId, LanguageServerName, WorktreeId)> {
6238        self.language_server_ids
6239            .iter()
6240            .map(|((worktree_id, server_name), server_id)| {
6241                (*server_id, server_name.clone(), *worktree_id)
6242            })
6243    }
6244
6245    pub fn register_supplementary_language_server(
6246        &mut self,
6247        id: LanguageServerId,
6248        name: LanguageServerName,
6249        server: Arc<LanguageServer>,
6250        cx: &mut ModelContext<Self>,
6251    ) {
6252        if let Some(local) = self.as_local_mut() {
6253            local
6254                .supplementary_language_servers
6255                .insert(id, (name, server));
6256            cx.emit(LspStoreEvent::LanguageServerAdded(id));
6257        }
6258    }
6259
6260    pub fn unregister_supplementary_language_server(
6261        &mut self,
6262        id: LanguageServerId,
6263        cx: &mut ModelContext<Self>,
6264    ) {
6265        if let Some(local) = self.as_local_mut() {
6266            local.supplementary_language_servers.remove(&id);
6267            cx.emit(LspStoreEvent::LanguageServerRemoved(id));
6268        }
6269    }
6270
6271    pub fn supplementary_language_servers(
6272        &self,
6273    ) -> impl '_ + Iterator<Item = (LanguageServerId, LanguageServerName)> {
6274        self.as_local().into_iter().flat_map(|local| {
6275            local
6276                .supplementary_language_servers
6277                .iter()
6278                .map(|(id, (name, _))| (*id, name.clone()))
6279        })
6280    }
6281
6282    pub fn language_server_adapter_for_id(
6283        &self,
6284        id: LanguageServerId,
6285    ) -> Option<Arc<CachedLspAdapter>> {
6286        self.as_local()
6287            .and_then(|local| local.language_servers.get(&id))
6288            .and_then(|language_server_state| match language_server_state {
6289                LanguageServerState::Running { adapter, .. } => Some(adapter.clone()),
6290                _ => None,
6291            })
6292    }
6293
6294    pub(super) fn update_local_worktree_language_servers(
6295        &mut self,
6296        worktree_handle: &Model<Worktree>,
6297        changes: &[(Arc<Path>, ProjectEntryId, PathChange)],
6298        cx: &mut ModelContext<Self>,
6299    ) {
6300        if changes.is_empty() {
6301            return;
6302        }
6303
6304        let Some(local) = self.as_local() else { return };
6305
6306        local.prettier_store.update(cx, |prettier_store, cx| {
6307            prettier_store.update_prettier_settings(&worktree_handle, changes, cx)
6308        });
6309
6310        let worktree_id = worktree_handle.read(cx).id();
6311        let mut language_server_ids = self
6312            .language_server_ids
6313            .iter()
6314            .filter_map(|((server_worktree_id, _), server_id)| {
6315                (*server_worktree_id == worktree_id).then_some(*server_id)
6316            })
6317            .collect::<Vec<_>>();
6318        language_server_ids.sort();
6319        language_server_ids.dedup();
6320
6321        let abs_path = worktree_handle.read(cx).abs_path();
6322        for server_id in &language_server_ids {
6323            if let Some(LanguageServerState::Running { server, .. }) =
6324                local.language_servers.get(server_id)
6325            {
6326                if let Some(watched_paths) = local
6327                    .language_server_watched_paths
6328                    .get(server_id)
6329                    .and_then(|paths| paths.read(cx).worktree_paths.get(&worktree_id))
6330                {
6331                    let params = lsp::DidChangeWatchedFilesParams {
6332                        changes: changes
6333                            .iter()
6334                            .filter_map(|(path, _, change)| {
6335                                if !watched_paths.is_match(path) {
6336                                    return None;
6337                                }
6338                                let typ = match change {
6339                                    PathChange::Loaded => return None,
6340                                    PathChange::Added => lsp::FileChangeType::CREATED,
6341                                    PathChange::Removed => lsp::FileChangeType::DELETED,
6342                                    PathChange::Updated => lsp::FileChangeType::CHANGED,
6343                                    PathChange::AddedOrUpdated => lsp::FileChangeType::CHANGED,
6344                                };
6345                                Some(lsp::FileEvent {
6346                                    uri: lsp::Url::from_file_path(abs_path.join(path)).unwrap(),
6347                                    typ,
6348                                })
6349                            })
6350                            .collect(),
6351                    };
6352                    if !params.changes.is_empty() {
6353                        server
6354                            .notify::<lsp::notification::DidChangeWatchedFiles>(params)
6355                            .log_err();
6356                    }
6357                }
6358            }
6359        }
6360    }
6361
6362    pub(crate) fn cancel_language_server_work(
6363        &mut self,
6364        server_id: LanguageServerId,
6365        token_to_cancel: Option<String>,
6366        _cx: &mut ModelContext<Self>,
6367    ) {
6368        let Some(local) = self.as_local() else {
6369            return;
6370        };
6371        let status = self.language_server_statuses.get(&server_id);
6372        let server = local.language_servers.get(&server_id);
6373        if let Some((LanguageServerState::Running { server, .. }, status)) = server.zip(status) {
6374            for (token, progress) in &status.pending_work {
6375                if let Some(token_to_cancel) = token_to_cancel.as_ref() {
6376                    if token != token_to_cancel {
6377                        continue;
6378                    }
6379                }
6380                if progress.is_cancellable {
6381                    server
6382                        .notify::<lsp::notification::WorkDoneProgressCancel>(
6383                            WorkDoneProgressCancelParams {
6384                                token: lsp::NumberOrString::String(token.clone()),
6385                            },
6386                        )
6387                        .ok();
6388                }
6389
6390                if progress.is_cancellable {
6391                    server
6392                        .notify::<lsp::notification::WorkDoneProgressCancel>(
6393                            WorkDoneProgressCancelParams {
6394                                token: lsp::NumberOrString::String(token.clone()),
6395                            },
6396                        )
6397                        .ok();
6398                }
6399            }
6400        }
6401    }
6402
6403    pub fn wait_for_remote_buffer(
6404        &mut self,
6405        id: BufferId,
6406        cx: &mut ModelContext<Self>,
6407    ) -> Task<Result<Model<Buffer>>> {
6408        self.buffer_store.update(cx, |buffer_store, cx| {
6409            buffer_store.wait_for_remote_buffer(id, cx)
6410        })
6411    }
6412
6413    pub(crate) fn language_server_ids_for_buffer(
6414        &self,
6415        buffer: &Buffer,
6416        cx: &AppContext,
6417    ) -> Vec<LanguageServerId> {
6418        if let Some((file, language)) = File::from_dyn(buffer.file()).zip(buffer.language()) {
6419            let worktree_id = file.worktree_id(cx);
6420            self.languages
6421                .lsp_adapters(&language.name())
6422                .iter()
6423                .flat_map(|adapter| {
6424                    let key = (worktree_id, adapter.name.clone());
6425                    self.language_server_ids.get(&key).copied()
6426                })
6427                .collect()
6428        } else {
6429            Vec::new()
6430        }
6431    }
6432
6433    pub async fn deserialize_text_edits(
6434        this: Model<Self>,
6435        buffer_to_edit: Model<Buffer>,
6436        edits: Vec<lsp::TextEdit>,
6437        push_to_history: bool,
6438        _: Arc<CachedLspAdapter>,
6439        language_server: Arc<LanguageServer>,
6440        cx: &mut AsyncAppContext,
6441    ) -> Result<Option<Transaction>> {
6442        let edits = this
6443            .update(cx, |this, cx| {
6444                this.edits_from_lsp(
6445                    &buffer_to_edit,
6446                    edits,
6447                    language_server.server_id(),
6448                    None,
6449                    cx,
6450                )
6451            })?
6452            .await?;
6453
6454        let transaction = buffer_to_edit.update(cx, |buffer, cx| {
6455            buffer.finalize_last_transaction();
6456            buffer.start_transaction();
6457            for (range, text) in edits {
6458                buffer.edit([(range, text)], None, cx);
6459            }
6460
6461            if buffer.end_transaction(cx).is_some() {
6462                let transaction = buffer.finalize_last_transaction().unwrap().clone();
6463                if !push_to_history {
6464                    buffer.forget_transaction(transaction.id);
6465                }
6466                Some(transaction)
6467            } else {
6468                None
6469            }
6470        })?;
6471
6472        Ok(transaction)
6473    }
6474
6475    pub async fn deserialize_workspace_edit(
6476        this: Model<Self>,
6477        edit: lsp::WorkspaceEdit,
6478        push_to_history: bool,
6479        lsp_adapter: Arc<CachedLspAdapter>,
6480        language_server: Arc<LanguageServer>,
6481        cx: &mut AsyncAppContext,
6482    ) -> Result<ProjectTransaction> {
6483        let fs = this.read_with(cx, |this, _| this.as_local().unwrap().fs.clone())?;
6484
6485        let mut operations = Vec::new();
6486        if let Some(document_changes) = edit.document_changes {
6487            match document_changes {
6488                lsp::DocumentChanges::Edits(edits) => {
6489                    operations.extend(edits.into_iter().map(lsp::DocumentChangeOperation::Edit))
6490                }
6491                lsp::DocumentChanges::Operations(ops) => operations = ops,
6492            }
6493        } else if let Some(changes) = edit.changes {
6494            operations.extend(changes.into_iter().map(|(uri, edits)| {
6495                lsp::DocumentChangeOperation::Edit(lsp::TextDocumentEdit {
6496                    text_document: lsp::OptionalVersionedTextDocumentIdentifier {
6497                        uri,
6498                        version: None,
6499                    },
6500                    edits: edits.into_iter().map(Edit::Plain).collect(),
6501                })
6502            }));
6503        }
6504
6505        let mut project_transaction = ProjectTransaction::default();
6506        for operation in operations {
6507            match operation {
6508                lsp::DocumentChangeOperation::Op(lsp::ResourceOp::Create(op)) => {
6509                    let abs_path = op
6510                        .uri
6511                        .to_file_path()
6512                        .map_err(|_| anyhow!("can't convert URI to path"))?;
6513
6514                    if let Some(parent_path) = abs_path.parent() {
6515                        fs.create_dir(parent_path).await?;
6516                    }
6517                    if abs_path.ends_with("/") {
6518                        fs.create_dir(&abs_path).await?;
6519                    } else {
6520                        fs.create_file(
6521                            &abs_path,
6522                            op.options
6523                                .map(|options| fs::CreateOptions {
6524                                    overwrite: options.overwrite.unwrap_or(false),
6525                                    ignore_if_exists: options.ignore_if_exists.unwrap_or(false),
6526                                })
6527                                .unwrap_or_default(),
6528                        )
6529                        .await?;
6530                    }
6531                }
6532
6533                lsp::DocumentChangeOperation::Op(lsp::ResourceOp::Rename(op)) => {
6534                    let source_abs_path = op
6535                        .old_uri
6536                        .to_file_path()
6537                        .map_err(|_| anyhow!("can't convert URI to path"))?;
6538                    let target_abs_path = op
6539                        .new_uri
6540                        .to_file_path()
6541                        .map_err(|_| anyhow!("can't convert URI to path"))?;
6542                    fs.rename(
6543                        &source_abs_path,
6544                        &target_abs_path,
6545                        op.options
6546                            .map(|options| fs::RenameOptions {
6547                                overwrite: options.overwrite.unwrap_or(false),
6548                                ignore_if_exists: options.ignore_if_exists.unwrap_or(false),
6549                            })
6550                            .unwrap_or_default(),
6551                    )
6552                    .await?;
6553                }
6554
6555                lsp::DocumentChangeOperation::Op(lsp::ResourceOp::Delete(op)) => {
6556                    let abs_path = op
6557                        .uri
6558                        .to_file_path()
6559                        .map_err(|_| anyhow!("can't convert URI to path"))?;
6560                    let options = op
6561                        .options
6562                        .map(|options| fs::RemoveOptions {
6563                            recursive: options.recursive.unwrap_or(false),
6564                            ignore_if_not_exists: options.ignore_if_not_exists.unwrap_or(false),
6565                        })
6566                        .unwrap_or_default();
6567                    if abs_path.ends_with("/") {
6568                        fs.remove_dir(&abs_path, options).await?;
6569                    } else {
6570                        fs.remove_file(&abs_path, options).await?;
6571                    }
6572                }
6573
6574                lsp::DocumentChangeOperation::Edit(op) => {
6575                    let buffer_to_edit = this
6576                        .update(cx, |this, cx| {
6577                            this.open_local_buffer_via_lsp(
6578                                op.text_document.uri.clone(),
6579                                language_server.server_id(),
6580                                lsp_adapter.name.clone(),
6581                                cx,
6582                            )
6583                        })?
6584                        .await?;
6585
6586                    let edits = this
6587                        .update(cx, |this, cx| {
6588                            let path = buffer_to_edit.read(cx).project_path(cx);
6589                            let active_entry = this.active_entry;
6590                            let is_active_entry = path.clone().map_or(false, |project_path| {
6591                                this.worktree_store
6592                                    .read(cx)
6593                                    .entry_for_path(&project_path, cx)
6594                                    .map_or(false, |entry| Some(entry.id) == active_entry)
6595                            });
6596
6597                            let (mut edits, mut snippet_edits) = (vec![], vec![]);
6598                            for edit in op.edits {
6599                                match edit {
6600                                    Edit::Plain(edit) => edits.push(edit),
6601                                    Edit::Annotated(edit) => edits.push(edit.text_edit),
6602                                    Edit::Snippet(edit) => {
6603                                        let Ok(snippet) = Snippet::parse(&edit.snippet.value)
6604                                        else {
6605                                            continue;
6606                                        };
6607
6608                                        if is_active_entry {
6609                                            snippet_edits.push((edit.range, snippet));
6610                                        } else {
6611                                            // Since this buffer is not focused, apply a normal edit.
6612                                            edits.push(TextEdit {
6613                                                range: edit.range,
6614                                                new_text: snippet.text,
6615                                            });
6616                                        }
6617                                    }
6618                                }
6619                            }
6620                            if !snippet_edits.is_empty() {
6621                                let buffer_id = buffer_to_edit.read(cx).remote_id();
6622                                let version = if let Some(buffer_version) = op.text_document.version
6623                                {
6624                                    this.buffer_snapshot_for_lsp_version(
6625                                        &buffer_to_edit,
6626                                        language_server.server_id(),
6627                                        Some(buffer_version),
6628                                        cx,
6629                                    )
6630                                    .ok()
6631                                    .map(|snapshot| snapshot.version)
6632                                } else {
6633                                    Some(buffer_to_edit.read(cx).saved_version().clone())
6634                                };
6635
6636                                let most_recent_edit = version.and_then(|version| {
6637                                    version.iter().max_by_key(|timestamp| timestamp.value)
6638                                });
6639                                // Check if the edit that triggered that edit has been made by this participant.
6640
6641                                if let Some(most_recent_edit) = most_recent_edit {
6642                                    cx.emit(LspStoreEvent::SnippetEdit {
6643                                        buffer_id,
6644                                        edits: snippet_edits,
6645                                        most_recent_edit,
6646                                    });
6647                                }
6648                            }
6649
6650                            this.edits_from_lsp(
6651                                &buffer_to_edit,
6652                                edits,
6653                                language_server.server_id(),
6654                                op.text_document.version,
6655                                cx,
6656                            )
6657                        })?
6658                        .await?;
6659
6660                    let transaction = buffer_to_edit.update(cx, |buffer, cx| {
6661                        buffer.finalize_last_transaction();
6662                        buffer.start_transaction();
6663                        for (range, text) in edits {
6664                            buffer.edit([(range, text)], None, cx);
6665                        }
6666                        let transaction = if buffer.end_transaction(cx).is_some() {
6667                            let transaction = buffer.finalize_last_transaction().unwrap().clone();
6668                            if !push_to_history {
6669                                buffer.forget_transaction(transaction.id);
6670                            }
6671                            Some(transaction)
6672                        } else {
6673                            None
6674                        };
6675
6676                        transaction
6677                    })?;
6678                    if let Some(transaction) = transaction {
6679                        project_transaction.0.insert(buffer_to_edit, transaction);
6680                    }
6681                }
6682            }
6683        }
6684
6685        Ok(project_transaction)
6686    }
6687
6688    fn serialize_symbol(symbol: &Symbol) -> proto::Symbol {
6689        proto::Symbol {
6690            language_server_name: symbol.language_server_name.0.to_string(),
6691            source_worktree_id: symbol.source_worktree_id.to_proto(),
6692            worktree_id: symbol.path.worktree_id.to_proto(),
6693            path: symbol.path.path.to_string_lossy().to_string(),
6694            name: symbol.name.clone(),
6695            kind: unsafe { mem::transmute::<lsp::SymbolKind, i32>(symbol.kind) },
6696            start: Some(proto::PointUtf16 {
6697                row: symbol.range.start.0.row,
6698                column: symbol.range.start.0.column,
6699            }),
6700            end: Some(proto::PointUtf16 {
6701                row: symbol.range.end.0.row,
6702                column: symbol.range.end.0.column,
6703            }),
6704            signature: symbol.signature.to_vec(),
6705        }
6706    }
6707
6708    fn deserialize_symbol(serialized_symbol: proto::Symbol) -> Result<CoreSymbol> {
6709        let source_worktree_id = WorktreeId::from_proto(serialized_symbol.source_worktree_id);
6710        let worktree_id = WorktreeId::from_proto(serialized_symbol.worktree_id);
6711        let kind = unsafe { mem::transmute::<i32, lsp::SymbolKind>(serialized_symbol.kind) };
6712        let path = ProjectPath {
6713            worktree_id,
6714            path: PathBuf::from(serialized_symbol.path).into(),
6715        };
6716
6717        let start = serialized_symbol
6718            .start
6719            .ok_or_else(|| anyhow!("invalid start"))?;
6720        let end = serialized_symbol
6721            .end
6722            .ok_or_else(|| anyhow!("invalid end"))?;
6723        Ok(CoreSymbol {
6724            language_server_name: LanguageServerName(serialized_symbol.language_server_name.into()),
6725            source_worktree_id,
6726            path,
6727            name: serialized_symbol.name,
6728            range: Unclipped(PointUtf16::new(start.row, start.column))
6729                ..Unclipped(PointUtf16::new(end.row, end.column)),
6730            kind,
6731            signature: serialized_symbol
6732                .signature
6733                .try_into()
6734                .map_err(|_| anyhow!("invalid signature"))?,
6735        })
6736    }
6737
6738    pub(crate) fn serialize_completion(completion: &CoreCompletion) -> proto::Completion {
6739        proto::Completion {
6740            old_start: Some(serialize_anchor(&completion.old_range.start)),
6741            old_end: Some(serialize_anchor(&completion.old_range.end)),
6742            new_text: completion.new_text.clone(),
6743            server_id: completion.server_id.0 as u64,
6744            lsp_completion: serde_json::to_vec(&completion.lsp_completion).unwrap(),
6745        }
6746    }
6747
6748    pub(crate) fn deserialize_completion(completion: proto::Completion) -> Result<CoreCompletion> {
6749        let old_start = completion
6750            .old_start
6751            .and_then(deserialize_anchor)
6752            .ok_or_else(|| anyhow!("invalid old start"))?;
6753        let old_end = completion
6754            .old_end
6755            .and_then(deserialize_anchor)
6756            .ok_or_else(|| anyhow!("invalid old end"))?;
6757        let lsp_completion = serde_json::from_slice(&completion.lsp_completion)?;
6758
6759        Ok(CoreCompletion {
6760            old_range: old_start..old_end,
6761            new_text: completion.new_text,
6762            server_id: LanguageServerId(completion.server_id as usize),
6763            lsp_completion,
6764        })
6765    }
6766
6767    pub(crate) fn serialize_code_action(action: &CodeAction) -> proto::CodeAction {
6768        proto::CodeAction {
6769            server_id: action.server_id.0 as u64,
6770            start: Some(serialize_anchor(&action.range.start)),
6771            end: Some(serialize_anchor(&action.range.end)),
6772            lsp_action: serde_json::to_vec(&action.lsp_action).unwrap(),
6773        }
6774    }
6775
6776    pub(crate) fn deserialize_code_action(action: proto::CodeAction) -> Result<CodeAction> {
6777        let start = action
6778            .start
6779            .and_then(deserialize_anchor)
6780            .ok_or_else(|| anyhow!("invalid start"))?;
6781        let end = action
6782            .end
6783            .and_then(deserialize_anchor)
6784            .ok_or_else(|| anyhow!("invalid end"))?;
6785        let lsp_action = serde_json::from_slice(&action.lsp_action)?;
6786        Ok(CodeAction {
6787            server_id: LanguageServerId(action.server_id as usize),
6788            range: start..end,
6789            lsp_action,
6790        })
6791    }
6792}
6793
6794impl EventEmitter<LspStoreEvent> for LspStore {}
6795
6796fn remove_empty_hover_blocks(mut hover: Hover) -> Option<Hover> {
6797    hover
6798        .contents
6799        .retain(|hover_block| !hover_block.text.trim().is_empty());
6800    if hover.contents.is_empty() {
6801        None
6802    } else {
6803        Some(hover)
6804    }
6805}
6806
6807async fn populate_labels_for_completions(
6808    mut new_completions: Vec<CoreCompletion>,
6809    language_registry: &Arc<LanguageRegistry>,
6810    language: Option<Arc<Language>>,
6811    lsp_adapter: Option<Arc<CachedLspAdapter>>,
6812    completions: &mut Vec<Completion>,
6813) {
6814    let lsp_completions = new_completions
6815        .iter_mut()
6816        .map(|completion| mem::take(&mut completion.lsp_completion))
6817        .collect::<Vec<_>>();
6818
6819    let labels = if let Some((language, lsp_adapter)) = language.as_ref().zip(lsp_adapter) {
6820        lsp_adapter
6821            .labels_for_completions(&lsp_completions, language)
6822            .await
6823            .log_err()
6824            .unwrap_or_default()
6825    } else {
6826        Vec::new()
6827    };
6828
6829    for ((completion, lsp_completion), label) in new_completions
6830        .into_iter()
6831        .zip(lsp_completions)
6832        .zip(labels.into_iter().chain(iter::repeat(None)))
6833    {
6834        let documentation = if let Some(docs) = &lsp_completion.documentation {
6835            Some(prepare_completion_documentation(docs, language_registry, language.clone()).await)
6836        } else {
6837            None
6838        };
6839
6840        completions.push(Completion {
6841            old_range: completion.old_range,
6842            new_text: completion.new_text,
6843            label: label.unwrap_or_else(|| {
6844                CodeLabel::plain(
6845                    lsp_completion.label.clone(),
6846                    lsp_completion.filter_text.as_deref(),
6847                )
6848            }),
6849            server_id: completion.server_id,
6850            documentation,
6851            lsp_completion,
6852            confirm: None,
6853        })
6854    }
6855}
6856
6857#[derive(Debug)]
6858pub enum LanguageServerToQuery {
6859    Primary,
6860    Other(LanguageServerId),
6861}
6862
6863#[derive(Default)]
6864struct LanguageServerWatchedPaths {
6865    worktree_paths: HashMap<WorktreeId, GlobSet>,
6866    abs_paths: HashMap<Arc<Path>, (GlobSet, Task<()>)>,
6867}
6868
6869#[derive(Default)]
6870struct LanguageServerWatchedPathsBuilder {
6871    worktree_paths: HashMap<WorktreeId, GlobSet>,
6872    abs_paths: HashMap<Arc<Path>, GlobSet>,
6873}
6874
6875impl LanguageServerWatchedPathsBuilder {
6876    fn watch_worktree(&mut self, worktree_id: WorktreeId, glob_set: GlobSet) {
6877        self.worktree_paths.insert(worktree_id, glob_set);
6878    }
6879    fn watch_abs_path(&mut self, path: Arc<Path>, glob_set: GlobSet) {
6880        self.abs_paths.insert(path, glob_set);
6881    }
6882    fn build(
6883        self,
6884        fs: Arc<dyn Fs>,
6885        language_server_id: LanguageServerId,
6886        cx: &mut ModelContext<LspStore>,
6887    ) -> Model<LanguageServerWatchedPaths> {
6888        let project = cx.weak_model();
6889
6890        cx.new_model(|cx| {
6891            let this_id = cx.entity_id();
6892            const LSP_ABS_PATH_OBSERVE: Duration = Duration::from_millis(100);
6893            let abs_paths = self
6894                .abs_paths
6895                .into_iter()
6896                .map(|(abs_path, globset)| {
6897                    let task = cx.spawn({
6898                        let abs_path = abs_path.clone();
6899                        let fs = fs.clone();
6900
6901                        let lsp_store = project.clone();
6902                        |_, mut cx| async move {
6903                            maybe!(async move {
6904                                let mut push_updates =
6905                                    fs.watch(&abs_path, LSP_ABS_PATH_OBSERVE).await;
6906                                while let Some(update) = push_updates.0.next().await {
6907                                    let action = lsp_store
6908                                        .update(&mut cx, |this, cx| {
6909                                            let Some(local) = this.as_local() else {
6910                                                return ControlFlow::Break(());
6911                                            };
6912                                            let Some(watcher) = local
6913                                                .language_server_watched_paths
6914                                                .get(&language_server_id)
6915                                            else {
6916                                                return ControlFlow::Break(());
6917                                            };
6918                                            if watcher.entity_id() != this_id {
6919                                                // This watcher is no longer registered on the project, which means that we should
6920                                                // cease operations.
6921                                                return ControlFlow::Break(());
6922                                            }
6923                                            let (globs, _) = watcher
6924                                                .read(cx)
6925                                                .abs_paths
6926                                                .get(&abs_path)
6927                                                .expect(
6928                                                "Watched abs path is not registered with a watcher",
6929                                            );
6930                                            let matching_entries = update
6931                                                .into_iter()
6932                                                .filter(|event| globs.is_match(&event.path))
6933                                                .collect::<Vec<_>>();
6934                                            this.lsp_notify_abs_paths_changed(
6935                                                language_server_id,
6936                                                matching_entries,
6937                                            );
6938                                            ControlFlow::Continue(())
6939                                        })
6940                                        .ok()?;
6941
6942                                    if action.is_break() {
6943                                        break;
6944                                    }
6945                                }
6946                                Some(())
6947                            })
6948                            .await;
6949                        }
6950                    });
6951                    (abs_path, (globset, task))
6952                })
6953                .collect();
6954            LanguageServerWatchedPaths {
6955                worktree_paths: self.worktree_paths,
6956                abs_paths,
6957            }
6958        })
6959    }
6960}
6961
6962struct LspBufferSnapshot {
6963    version: i32,
6964    snapshot: TextBufferSnapshot,
6965}
6966
6967/// A prompt requested by LSP server.
6968#[derive(Clone, Debug)]
6969pub struct LanguageServerPromptRequest {
6970    pub level: PromptLevel,
6971    pub message: String,
6972    pub actions: Vec<MessageActionItem>,
6973    pub lsp_name: String,
6974    pub(crate) response_channel: Sender<MessageActionItem>,
6975}
6976
6977impl LanguageServerPromptRequest {
6978    pub async fn respond(self, index: usize) -> Option<()> {
6979        if let Some(response) = self.actions.into_iter().nth(index) {
6980            self.response_channel.send(response).await.ok()
6981        } else {
6982            None
6983        }
6984    }
6985}
6986impl PartialEq for LanguageServerPromptRequest {
6987    fn eq(&self, other: &Self) -> bool {
6988        self.message == other.message && self.actions == other.actions
6989    }
6990}
6991
6992#[derive(Clone, Debug, PartialEq)]
6993pub enum LanguageServerLogType {
6994    Log(MessageType),
6995    Trace(Option<String>),
6996}
6997
6998pub enum LanguageServerState {
6999    Starting(Task<Option<Arc<LanguageServer>>>),
7000
7001    Running {
7002        language: LanguageName,
7003        adapter: Arc<CachedLspAdapter>,
7004        server: Arc<LanguageServer>,
7005        simulate_disk_based_diagnostics_completion: Option<Task<()>>,
7006    },
7007}
7008
7009impl std::fmt::Debug for LanguageServerState {
7010    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
7011        match self {
7012            LanguageServerState::Starting(_) => {
7013                f.debug_struct("LanguageServerState::Starting").finish()
7014            }
7015            LanguageServerState::Running { language, .. } => f
7016                .debug_struct("LanguageServerState::Running")
7017                .field("language", &language)
7018                .finish(),
7019        }
7020    }
7021}
7022
7023#[derive(Clone, Debug, Serialize)]
7024pub struct LanguageServerProgress {
7025    pub is_disk_based_diagnostics_progress: bool,
7026    pub is_cancellable: bool,
7027    pub title: Option<String>,
7028    pub message: Option<String>,
7029    pub percentage: Option<usize>,
7030    #[serde(skip_serializing)]
7031    pub last_update_at: Instant,
7032}
7033
7034#[derive(Copy, Clone, Debug, Default, PartialEq, Serialize)]
7035pub struct DiagnosticSummary {
7036    pub error_count: usize,
7037    pub warning_count: usize,
7038}
7039
7040impl DiagnosticSummary {
7041    pub fn new<'a, T: 'a>(diagnostics: impl IntoIterator<Item = &'a DiagnosticEntry<T>>) -> Self {
7042        let mut this = Self {
7043            error_count: 0,
7044            warning_count: 0,
7045        };
7046
7047        for entry in diagnostics {
7048            if entry.diagnostic.is_primary {
7049                match entry.diagnostic.severity {
7050                    DiagnosticSeverity::ERROR => this.error_count += 1,
7051                    DiagnosticSeverity::WARNING => this.warning_count += 1,
7052                    _ => {}
7053                }
7054            }
7055        }
7056
7057        this
7058    }
7059
7060    pub fn is_empty(&self) -> bool {
7061        self.error_count == 0 && self.warning_count == 0
7062    }
7063
7064    pub fn to_proto(
7065        &self,
7066        language_server_id: LanguageServerId,
7067        path: &Path,
7068    ) -> proto::DiagnosticSummary {
7069        proto::DiagnosticSummary {
7070            path: path.to_string_lossy().to_string(),
7071            language_server_id: language_server_id.0 as u64,
7072            error_count: self.error_count as u32,
7073            warning_count: self.warning_count as u32,
7074        }
7075    }
7076}
7077
7078fn glob_literal_prefix(glob: &str) -> &str {
7079    let is_absolute = glob.starts_with(path::MAIN_SEPARATOR);
7080
7081    let mut literal_end = is_absolute as usize;
7082    for (i, part) in glob.split(path::MAIN_SEPARATOR).enumerate() {
7083        if part.contains(['*', '?', '{', '}']) {
7084            break;
7085        } else {
7086            if i > 0 {
7087                // Account for separator prior to this part
7088                literal_end += path::MAIN_SEPARATOR.len_utf8();
7089            }
7090            literal_end += part.len();
7091        }
7092    }
7093    let literal_end = literal_end.min(glob.len());
7094    &glob[..literal_end]
7095}
7096
7097pub struct SshLspAdapter {
7098    name: LanguageServerName,
7099    binary: LanguageServerBinary,
7100    initialization_options: Option<String>,
7101    code_action_kinds: Option<Vec<CodeActionKind>>,
7102}
7103
7104impl SshLspAdapter {
7105    pub fn new(
7106        name: LanguageServerName,
7107        binary: LanguageServerBinary,
7108        initialization_options: Option<String>,
7109        code_action_kinds: Option<String>,
7110    ) -> Self {
7111        Self {
7112            name,
7113            binary,
7114            initialization_options,
7115            code_action_kinds: code_action_kinds
7116                .as_ref()
7117                .and_then(|c| serde_json::from_str(c).ok()),
7118        }
7119    }
7120}
7121
7122#[async_trait(?Send)]
7123impl LspAdapter for SshLspAdapter {
7124    fn name(&self) -> LanguageServerName {
7125        self.name.clone()
7126    }
7127
7128    async fn initialization_options(
7129        self: Arc<Self>,
7130        _: &Arc<dyn LspAdapterDelegate>,
7131    ) -> Result<Option<serde_json::Value>> {
7132        let Some(options) = &self.initialization_options else {
7133            return Ok(None);
7134        };
7135        let result = serde_json::from_str(options)?;
7136        Ok(result)
7137    }
7138
7139    fn code_action_kinds(&self) -> Option<Vec<CodeActionKind>> {
7140        self.code_action_kinds.clone()
7141    }
7142
7143    async fn check_if_user_installed(
7144        &self,
7145        _: &dyn LspAdapterDelegate,
7146        _: &AsyncAppContext,
7147    ) -> Option<LanguageServerBinary> {
7148        Some(self.binary.clone())
7149    }
7150
7151    async fn cached_server_binary(
7152        &self,
7153        _: PathBuf,
7154        _: &dyn LspAdapterDelegate,
7155    ) -> Option<LanguageServerBinary> {
7156        None
7157    }
7158
7159    async fn fetch_latest_server_version(
7160        &self,
7161        _: &dyn LspAdapterDelegate,
7162    ) -> Result<Box<dyn 'static + Send + Any>> {
7163        anyhow::bail!("SshLspAdapter does not support fetch_latest_server_version")
7164    }
7165
7166    async fn fetch_server_binary(
7167        &self,
7168        _: Box<dyn 'static + Send + Any>,
7169        _: PathBuf,
7170        _: &dyn LspAdapterDelegate,
7171    ) -> Result<LanguageServerBinary> {
7172        anyhow::bail!("SshLspAdapter does not support fetch_server_binary")
7173    }
7174
7175    async fn installation_test_binary(&self, _: PathBuf) -> Option<LanguageServerBinary> {
7176        None
7177    }
7178}
7179pub fn language_server_settings<'a, 'b: 'a>(
7180    delegate: &'a dyn LspAdapterDelegate,
7181    language: &str,
7182    cx: &'b AppContext,
7183) -> Option<&'a LspSettings> {
7184    ProjectSettings::get(
7185        Some(SettingsLocation {
7186            worktree_id: delegate.worktree_id(),
7187            path: delegate.worktree_root_path(),
7188        }),
7189        cx,
7190    )
7191    .lsp
7192    .get(language)
7193}
7194
7195pub struct LocalLspAdapterDelegate {
7196    lsp_store: WeakModel<LspStore>,
7197    worktree: worktree::Snapshot,
7198    fs: Arc<dyn Fs>,
7199    http_client: Arc<dyn HttpClient>,
7200    language_registry: Arc<LanguageRegistry>,
7201    load_shell_env_task: Shared<Task<Option<HashMap<String, String>>>>,
7202}
7203
7204impl LocalLspAdapterDelegate {
7205    fn for_local(
7206        lsp_store: &LspStore,
7207        worktree: &Model<Worktree>,
7208        cx: &mut ModelContext<LspStore>,
7209    ) -> Arc<Self> {
7210        let local = lsp_store
7211            .as_local()
7212            .expect("LocalLspAdapterDelegate cannot be constructed on a remote");
7213
7214        let http_client = local
7215            .http_client
7216            .clone()
7217            .unwrap_or_else(|| Arc::new(BlockedHttpClient));
7218
7219        Self::new(lsp_store, worktree, http_client, local.fs.clone(), cx)
7220    }
7221
7222    // fn for_ssh(
7223    //     lsp_store: &LspStore,
7224    //     worktree: &Model<Worktree>,
7225    //     upstream_client: AnyProtoClient,
7226    //     cx: &mut ModelContext<LspStore>,
7227    // ) -> Arc<Self> {
7228    //     Self::new(
7229    //         lsp_store,
7230    //         worktree,
7231    //         Arc::new(BlockedHttpClient),
7232    //         None,
7233    //         Some(upstream_client),
7234    //         cx,
7235    //     )
7236    // }
7237
7238    pub fn new(
7239        lsp_store: &LspStore,
7240        worktree: &Model<Worktree>,
7241        http_client: Arc<dyn HttpClient>,
7242        fs: Arc<dyn Fs>,
7243        cx: &mut ModelContext<LspStore>,
7244    ) -> Arc<Self> {
7245        let worktree_id = worktree.read(cx).id();
7246        let worktree_abs_path = worktree.read(cx).abs_path();
7247        let load_shell_env_task = if let Some(environment) =
7248            &lsp_store.as_local().map(|local| local.environment.clone())
7249        {
7250            environment.update(cx, |env, cx| {
7251                env.get_environment(Some(worktree_id), Some(worktree_abs_path), cx)
7252            })
7253        } else {
7254            Task::ready(None).shared()
7255        };
7256
7257        Arc::new(Self {
7258            lsp_store: cx.weak_model(),
7259            worktree: worktree.read(cx).snapshot(),
7260            fs,
7261            http_client,
7262            language_registry: lsp_store.languages.clone(),
7263            load_shell_env_task,
7264        })
7265    }
7266}
7267
7268#[async_trait]
7269impl LspAdapterDelegate for LocalLspAdapterDelegate {
7270    fn show_notification(&self, message: &str, cx: &mut AppContext) {
7271        self.lsp_store
7272            .update(cx, |_, cx| {
7273                cx.emit(LspStoreEvent::Notification(message.to_owned()))
7274            })
7275            .ok();
7276    }
7277
7278    fn http_client(&self) -> Arc<dyn HttpClient> {
7279        self.http_client.clone()
7280    }
7281
7282    fn worktree_id(&self) -> WorktreeId {
7283        self.worktree.id()
7284    }
7285
7286    fn worktree_root_path(&self) -> &Path {
7287        self.worktree.abs_path().as_ref()
7288    }
7289
7290    async fn shell_env(&self) -> HashMap<String, String> {
7291        let task = self.load_shell_env_task.clone();
7292        task.await.unwrap_or_default()
7293    }
7294
7295    #[cfg(not(target_os = "windows"))]
7296    async fn which(&self, command: &OsStr) -> Option<PathBuf> {
7297        let worktree_abs_path = self.worktree.abs_path();
7298        let shell_path = self.shell_env().await.get("PATH").cloned();
7299        which::which_in(command, shell_path.as_ref(), worktree_abs_path).ok()
7300    }
7301
7302    #[cfg(target_os = "windows")]
7303    async fn which(&self, command: &OsStr) -> Option<PathBuf> {
7304        // todo(windows) Getting the shell env variables in a current directory on Windows is more complicated than other platforms
7305        //               there isn't a 'default shell' necessarily. The closest would be the default profile on the windows terminal
7306        //               SEE: https://learn.microsoft.com/en-us/windows/terminal/customize-settings/startup
7307        which::which(command).ok()
7308    }
7309
7310    async fn try_exec(&self, command: LanguageServerBinary) -> Result<()> {
7311        let working_dir = self.worktree_root_path();
7312        let output = smol::process::Command::new(&command.path)
7313            .args(command.arguments)
7314            .envs(command.env.clone().unwrap_or_default())
7315            .current_dir(working_dir)
7316            .output()
7317            .await?;
7318
7319        if output.status.success() {
7320            return Ok(());
7321        }
7322        Err(anyhow!(
7323            "{}, stdout: {:?}, stderr: {:?}",
7324            output.status,
7325            String::from_utf8_lossy(&output.stdout),
7326            String::from_utf8_lossy(&output.stderr)
7327        ))
7328    }
7329
7330    fn update_status(
7331        &self,
7332        server_name: LanguageServerName,
7333        status: language::LanguageServerBinaryStatus,
7334    ) {
7335        self.language_registry
7336            .update_lsp_status(server_name, status);
7337    }
7338
7339    async fn read_text_file(&self, path: PathBuf) -> Result<String> {
7340        if self.worktree.entry_for_path(&path).is_none() {
7341            return Err(anyhow!("no such path {path:?}"));
7342        };
7343        self.fs.load(&path).await
7344    }
7345}
7346
7347struct BlockedHttpClient;
7348
7349impl HttpClient for BlockedHttpClient {
7350    fn send(
7351        &self,
7352        _req: Request<AsyncBody>,
7353    ) -> BoxFuture<'static, Result<Response<AsyncBody>, Error>> {
7354        Box::pin(async {
7355            Err(std::io::Error::new(
7356                std::io::ErrorKind::PermissionDenied,
7357                "ssh host blocked http connection",
7358            )
7359            .into())
7360        })
7361    }
7362
7363    fn proxy(&self) -> Option<&Uri> {
7364        None
7365    }
7366}
7367
7368struct SshLspAdapterDelegate {
7369    lsp_store: WeakModel<LspStore>,
7370    worktree: worktree::Snapshot,
7371    upstream_client: AnyProtoClient,
7372    language_registry: Arc<LanguageRegistry>,
7373}
7374
7375#[async_trait]
7376impl LspAdapterDelegate for SshLspAdapterDelegate {
7377    fn show_notification(&self, message: &str, cx: &mut AppContext) {
7378        self.lsp_store
7379            .update(cx, |_, cx| {
7380                cx.emit(LspStoreEvent::Notification(message.to_owned()))
7381            })
7382            .ok();
7383    }
7384
7385    fn http_client(&self) -> Arc<dyn HttpClient> {
7386        Arc::new(BlockedHttpClient)
7387    }
7388
7389    fn worktree_id(&self) -> WorktreeId {
7390        self.worktree.id()
7391    }
7392
7393    fn worktree_root_path(&self) -> &Path {
7394        self.worktree.abs_path().as_ref()
7395    }
7396
7397    async fn shell_env(&self) -> HashMap<String, String> {
7398        use rpc::proto::SSH_PROJECT_ID;
7399
7400        self.upstream_client
7401            .request(proto::ShellEnv {
7402                project_id: SSH_PROJECT_ID,
7403                worktree_id: self.worktree_id().to_proto(),
7404            })
7405            .await
7406            .map(|response| response.env.into_iter().collect())
7407            .unwrap_or_default()
7408    }
7409
7410    async fn which(&self, command: &OsStr) -> Option<PathBuf> {
7411        use rpc::proto::SSH_PROJECT_ID;
7412
7413        self.upstream_client
7414            .request(proto::WhichCommand {
7415                project_id: SSH_PROJECT_ID,
7416                worktree_id: self.worktree_id().to_proto(),
7417                command: command.to_string_lossy().to_string(),
7418            })
7419            .await
7420            .log_err()
7421            .and_then(|response| response.path)
7422            .map(PathBuf::from)
7423    }
7424
7425    async fn try_exec(&self, command: LanguageServerBinary) -> Result<()> {
7426        self.upstream_client
7427            .request(proto::TryExec {
7428                project_id: rpc::proto::SSH_PROJECT_ID,
7429                worktree_id: self.worktree.id().to_proto(),
7430                binary: Some(proto::LanguageServerCommand {
7431                    path: command.path.to_string_lossy().to_string(),
7432                    arguments: command
7433                        .arguments
7434                        .into_iter()
7435                        .map(|s| s.to_string_lossy().to_string())
7436                        .collect(),
7437                    env: command.env.unwrap_or_default().into_iter().collect(),
7438                }),
7439            })
7440            .await?;
7441        Ok(())
7442    }
7443
7444    fn update_status(
7445        &self,
7446        server_name: LanguageServerName,
7447        status: language::LanguageServerBinaryStatus,
7448    ) {
7449        self.language_registry
7450            .update_lsp_status(server_name, status);
7451    }
7452
7453    async fn read_text_file(&self, path: PathBuf) -> Result<String> {
7454        self.upstream_client
7455            .request(proto::ReadTextFile {
7456                project_id: rpc::proto::SSH_PROJECT_ID,
7457                path: Some(proto::ProjectPath {
7458                    worktree_id: self.worktree.id().to_proto(),
7459                    path: path.to_string_lossy().to_string(),
7460                }),
7461            })
7462            .await
7463            .map(|r| r.text)
7464    }
7465}
7466
7467async fn populate_labels_for_symbols(
7468    symbols: Vec<CoreSymbol>,
7469    language_registry: &Arc<LanguageRegistry>,
7470    default_language: Option<LanguageName>,
7471    lsp_adapter: Option<Arc<CachedLspAdapter>>,
7472    output: &mut Vec<Symbol>,
7473) {
7474    #[allow(clippy::mutable_key_type)]
7475    let mut symbols_by_language = HashMap::<Option<Arc<Language>>, Vec<CoreSymbol>>::default();
7476
7477    let mut unknown_path = None;
7478    for symbol in symbols {
7479        let language = language_registry
7480            .language_for_file_path(&symbol.path.path)
7481            .await
7482            .ok()
7483            .or_else(|| {
7484                unknown_path.get_or_insert(symbol.path.path.clone());
7485                default_language.as_ref().and_then(|name| {
7486                    language_registry
7487                        .language_for_name(&name.0)
7488                        .now_or_never()?
7489                        .ok()
7490                })
7491            });
7492        symbols_by_language
7493            .entry(language)
7494            .or_default()
7495            .push(symbol);
7496    }
7497
7498    if let Some(unknown_path) = unknown_path {
7499        log::info!(
7500            "no language found for symbol path {}",
7501            unknown_path.display()
7502        );
7503    }
7504
7505    let mut label_params = Vec::new();
7506    for (language, mut symbols) in symbols_by_language {
7507        label_params.clear();
7508        label_params.extend(
7509            symbols
7510                .iter_mut()
7511                .map(|symbol| (mem::take(&mut symbol.name), symbol.kind)),
7512        );
7513
7514        let mut labels = Vec::new();
7515        if let Some(language) = language {
7516            let lsp_adapter = lsp_adapter.clone().or_else(|| {
7517                language_registry
7518                    .lsp_adapters(&language.name())
7519                    .first()
7520                    .cloned()
7521            });
7522            if let Some(lsp_adapter) = lsp_adapter {
7523                labels = lsp_adapter
7524                    .labels_for_symbols(&label_params, &language)
7525                    .await
7526                    .log_err()
7527                    .unwrap_or_default();
7528            }
7529        }
7530
7531        for ((symbol, (name, _)), label) in symbols
7532            .into_iter()
7533            .zip(label_params.drain(..))
7534            .zip(labels.into_iter().chain(iter::repeat(None)))
7535        {
7536            output.push(Symbol {
7537                language_server_name: symbol.language_server_name,
7538                source_worktree_id: symbol.source_worktree_id,
7539                path: symbol.path,
7540                label: label.unwrap_or_else(|| CodeLabel::plain(name.clone(), None)),
7541                name,
7542                kind: symbol.kind,
7543                range: symbol.range,
7544                signature: symbol.signature,
7545            });
7546        }
7547    }
7548}
7549
7550fn include_text(server: &lsp::LanguageServer) -> Option<bool> {
7551    match server.capabilities().text_document_sync.as_ref()? {
7552        lsp::TextDocumentSyncCapability::Kind(kind) => match *kind {
7553            lsp::TextDocumentSyncKind::NONE => None,
7554            lsp::TextDocumentSyncKind::FULL => Some(true),
7555            lsp::TextDocumentSyncKind::INCREMENTAL => Some(false),
7556            _ => None,
7557        },
7558        lsp::TextDocumentSyncCapability::Options(options) => match options.save.as_ref()? {
7559            lsp::TextDocumentSyncSaveOptions::Supported(supported) => {
7560                if *supported {
7561                    Some(true)
7562                } else {
7563                    None
7564                }
7565            }
7566            lsp::TextDocumentSyncSaveOptions::SaveOptions(save_options) => {
7567                Some(save_options.include_text.unwrap_or(false))
7568            }
7569        },
7570    }
7571}
7572
7573#[cfg(test)]
7574#[test]
7575fn test_glob_literal_prefix() {
7576    assert_eq!(glob_literal_prefix("**/*.js"), "");
7577    assert_eq!(glob_literal_prefix("node_modules/**/*.js"), "node_modules");
7578    assert_eq!(glob_literal_prefix("foo/{bar,baz}.js"), "foo");
7579    assert_eq!(glob_literal_prefix("foo/bar/baz.js"), "foo/bar/baz.js");
7580}