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