lsp_store.rs

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