lsp_store.rs

    1//! LSP store provides unified access to the language server protocol.
    2//! The consumers of LSP store can interact with language servers without knowing exactly which language server they're interacting with.
    3//!
    4//! # Local/Remote LSP Stores
    5//! This module is split up into three distinct parts:
    6//! - [`LocalLspStore`], which is ran on the host machine (either project host or SSH host), that manages the lifecycle of language servers.
    7//! - [`RemoteLspStore`], which is ran on the remote machine (project guests) which is mostly about passing through the requests via RPC.
    8//!   The remote stores don't really care about which language server they're running against - they don't usually get to decide which language server is going to responsible for handling their request.
    9//! - [`LspStore`], which unifies the two under one consistent interface for interacting with language servers.
   10//!
   11//! Most of the interesting work happens at the local layer, as bulk of the complexity is with managing the lifecycle of language servers. The actual implementation of the LSP protocol is handled by [`lsp`] crate.
   12pub mod clangd_ext;
   13pub mod json_language_server_ext;
   14pub mod lsp_ext_command;
   15pub mod rust_analyzer_ext;
   16
   17use crate::{
   18    CodeAction, ColorPresentation, Completion, CompletionResponse, CompletionSource,
   19    CoreCompletion, DocumentColor, Hover, InlayHint, LocationLink, LspAction, LspPullDiagnostics,
   20    ManifestProvidersStore, ProjectItem, ProjectPath, ProjectTransaction, PulledDiagnostics,
   21    ResolveState, Symbol,
   22    buffer_store::{BufferStore, BufferStoreEvent},
   23    environment::ProjectEnvironment,
   24    lsp_command::{self, *},
   25    lsp_store,
   26    manifest_tree::{
   27        LanguageServerTree, LanguageServerTreeNode, LaunchDisposition, ManifestQueryDelegate,
   28        ManifestTree,
   29    },
   30    prettier_store::{self, PrettierStore, PrettierStoreEvent},
   31    project_settings::{LspSettings, ProjectSettings},
   32    relativize_path, resolve_path,
   33    toolchain_store::{LocalToolchainStore, ToolchainStoreEvent},
   34    worktree_store::{WorktreeStore, WorktreeStoreEvent},
   35    yarn::YarnPathStore,
   36};
   37use anyhow::{Context as _, Result, anyhow};
   38use async_trait::async_trait;
   39use client::{TypedEnvelope, proto};
   40use clock::Global;
   41use collections::{BTreeMap, BTreeSet, HashMap, HashSet, btree_map};
   42use futures::{
   43    AsyncWriteExt, Future, FutureExt, StreamExt,
   44    future::{Either, Shared, join_all, pending, select},
   45    select, select_biased,
   46    stream::FuturesUnordered,
   47};
   48use globset::{Glob, GlobBuilder, GlobMatcher, GlobSet, GlobSetBuilder};
   49use gpui::{
   50    App, AppContext, AsyncApp, Context, Entity, EventEmitter, PromptLevel, SharedString, Task,
   51    WeakEntity,
   52};
   53use http_client::HttpClient;
   54use itertools::Itertools as _;
   55use language::{
   56    Bias, BinaryStatus, Buffer, BufferSnapshot, CachedLspAdapter, CodeLabel, Diagnostic,
   57    DiagnosticEntry, DiagnosticSet, DiagnosticSourceKind, Diff, File as _, Language, LanguageName,
   58    LanguageRegistry, LocalFile, LspAdapter, LspAdapterDelegate, ManifestDelegate, ManifestName,
   59    Patch, PointUtf16, TextBufferSnapshot, ToOffset, ToPointUtf16, Toolchain, Transaction,
   60    Unclipped,
   61    language_settings::{
   62        FormatOnSave, Formatter, LanguageSettings, SelectedFormatter, language_settings,
   63    },
   64    point_to_lsp,
   65    proto::{
   66        deserialize_anchor, deserialize_lsp_edit, deserialize_version, serialize_anchor,
   67        serialize_lsp_edit, serialize_version,
   68    },
   69    range_from_lsp, range_to_lsp,
   70};
   71use lsp::{
   72    AdapterServerCapabilities, CodeActionKind, CompletionContext, DiagnosticSeverity,
   73    DiagnosticTag, DidChangeWatchedFilesRegistrationOptions, Edit, FileOperationFilter,
   74    FileOperationPatternKind, FileOperationRegistrationOptions, FileRename, FileSystemWatcher,
   75    LSP_REQUEST_TIMEOUT, LanguageServer, LanguageServerBinary, LanguageServerBinaryOptions,
   76    LanguageServerId, LanguageServerName, LanguageServerSelector, LspRequestFuture,
   77    MessageActionItem, MessageType, OneOf, RenameFilesParams, SymbolKind,
   78    TextDocumentSyncSaveOptions, TextEdit, WillRenameFiles, WorkDoneProgressCancelParams,
   79    WorkspaceFolder, notification::DidRenameFiles,
   80};
   81use node_runtime::read_package_installed_version;
   82use parking_lot::Mutex;
   83use postage::{mpsc, sink::Sink, stream::Stream, watch};
   84use rand::prelude::*;
   85
   86use rpc::{
   87    AnyProtoClient,
   88    proto::{FromProto, LspRequestId, LspRequestMessage as _, ToProto},
   89};
   90use serde::Serialize;
   91use settings::{Settings, SettingsLocation, SettingsStore};
   92use sha2::{Digest, Sha256};
   93use smol::channel::Sender;
   94use snippet::Snippet;
   95use std::{
   96    any::{Any, TypeId},
   97    borrow::Cow,
   98    cell::RefCell,
   99    cmp::{Ordering, Reverse},
  100    convert::TryInto,
  101    ffi::OsStr,
  102    future::ready,
  103    iter, mem,
  104    ops::{ControlFlow, Range},
  105    path::{self, Path, PathBuf},
  106    pin::pin,
  107    rc::Rc,
  108    sync::Arc,
  109    time::{Duration, Instant},
  110};
  111use sum_tree::Dimensions;
  112use text::{Anchor, BufferId, LineEnding, OffsetRangeExt};
  113use url::Url;
  114use util::{
  115    ConnectionResult, ResultExt as _, debug_panic, defer, maybe, merge_json_value_into,
  116    paths::{PathExt, SanitizedPath},
  117    post_inc,
  118};
  119
  120pub use fs::*;
  121pub use language::Location;
  122#[cfg(any(test, feature = "test-support"))]
  123pub use prettier::FORMAT_SUFFIX as TEST_PRETTIER_FORMAT_SUFFIX;
  124pub use worktree::{
  125    Entry, EntryKind, FS_WATCH_LATENCY, File, LocalWorktree, PathChange, ProjectEntryId,
  126    UpdatedEntriesSet, UpdatedGitRepositoriesSet, Worktree, WorktreeId, WorktreeSettings,
  127};
  128
  129const SERVER_LAUNCHING_BEFORE_SHUTDOWN_TIMEOUT: Duration = Duration::from_secs(5);
  130pub const SERVER_PROGRESS_THROTTLE_TIMEOUT: Duration = Duration::from_millis(100);
  131
  132#[derive(Debug, Clone, Copy, PartialEq, Eq)]
  133pub enum FormatTrigger {
  134    Save,
  135    Manual,
  136}
  137
  138pub enum LspFormatTarget {
  139    Buffers,
  140    Ranges(BTreeMap<BufferId, Vec<Range<Anchor>>>),
  141}
  142
  143pub type OpenLspBufferHandle = Entity<Entity<Buffer>>;
  144
  145impl FormatTrigger {
  146    fn from_proto(value: i32) -> FormatTrigger {
  147        match value {
  148            0 => FormatTrigger::Save,
  149            1 => FormatTrigger::Manual,
  150            _ => FormatTrigger::Save,
  151        }
  152    }
  153}
  154
  155#[derive(Clone)]
  156struct UnifiedLanguageServer {
  157    id: LanguageServerId,
  158    project_roots: HashSet<Arc<Path>>,
  159}
  160
  161#[derive(Clone, Hash, PartialEq, Eq)]
  162struct LanguageServerSeed {
  163    worktree_id: WorktreeId,
  164    name: LanguageServerName,
  165    toolchain: Option<Toolchain>,
  166    settings: Arc<LspSettings>,
  167}
  168
  169#[derive(Debug)]
  170pub struct DocumentDiagnosticsUpdate<'a, D> {
  171    pub diagnostics: D,
  172    pub result_id: Option<String>,
  173    pub server_id: LanguageServerId,
  174    pub disk_based_sources: Cow<'a, [String]>,
  175}
  176
  177pub struct DocumentDiagnostics {
  178    diagnostics: Vec<DiagnosticEntry<Unclipped<PointUtf16>>>,
  179    document_abs_path: PathBuf,
  180    version: Option<i32>,
  181}
  182
  183pub struct LocalLspStore {
  184    weak: WeakEntity<LspStore>,
  185    worktree_store: Entity<WorktreeStore>,
  186    toolchain_store: Entity<LocalToolchainStore>,
  187    http_client: Arc<dyn HttpClient>,
  188    environment: Entity<ProjectEnvironment>,
  189    fs: Arc<dyn Fs>,
  190    languages: Arc<LanguageRegistry>,
  191    language_server_ids: HashMap<LanguageServerSeed, UnifiedLanguageServer>,
  192    yarn: Entity<YarnPathStore>,
  193    pub language_servers: HashMap<LanguageServerId, LanguageServerState>,
  194    buffers_being_formatted: HashSet<BufferId>,
  195    last_workspace_edits_by_language_server: HashMap<LanguageServerId, ProjectTransaction>,
  196    language_server_watched_paths: HashMap<LanguageServerId, LanguageServerWatchedPaths>,
  197    watched_manifest_filenames: HashSet<ManifestName>,
  198    language_server_paths_watched_for_rename:
  199        HashMap<LanguageServerId, RenamePathsWatchedForServer>,
  200    language_server_watcher_registrations:
  201        HashMap<LanguageServerId, HashMap<String, Vec<FileSystemWatcher>>>,
  202    supplementary_language_servers:
  203        HashMap<LanguageServerId, (LanguageServerName, Arc<LanguageServer>)>,
  204    prettier_store: Entity<PrettierStore>,
  205    next_diagnostic_group_id: usize,
  206    diagnostics: HashMap<
  207        WorktreeId,
  208        HashMap<
  209            Arc<Path>,
  210            Vec<(
  211                LanguageServerId,
  212                Vec<DiagnosticEntry<Unclipped<PointUtf16>>>,
  213            )>,
  214        >,
  215    >,
  216    buffer_snapshots: HashMap<BufferId, HashMap<LanguageServerId, Vec<LspBufferSnapshot>>>, // buffer_id -> server_id -> vec of snapshots
  217    _subscription: gpui::Subscription,
  218    lsp_tree: LanguageServerTree,
  219    registered_buffers: HashMap<BufferId, usize>,
  220    buffers_opened_in_servers: HashMap<BufferId, HashSet<LanguageServerId>>,
  221    buffer_pull_diagnostics_result_ids: HashMap<LanguageServerId, HashMap<PathBuf, Option<String>>>,
  222}
  223
  224impl LocalLspStore {
  225    /// Returns the running language server for the given ID. Note if the language server is starting, it will not be returned.
  226    pub fn running_language_server_for_id(
  227        &self,
  228        id: LanguageServerId,
  229    ) -> Option<&Arc<LanguageServer>> {
  230        let language_server_state = self.language_servers.get(&id)?;
  231
  232        match language_server_state {
  233            LanguageServerState::Running { server, .. } => Some(server),
  234            LanguageServerState::Starting { .. } => None,
  235        }
  236    }
  237
  238    fn get_or_insert_language_server(
  239        &mut self,
  240        worktree_handle: &Entity<Worktree>,
  241        delegate: Arc<LocalLspAdapterDelegate>,
  242        disposition: &Arc<LaunchDisposition>,
  243        language_name: &LanguageName,
  244        cx: &mut App,
  245    ) -> LanguageServerId {
  246        let key = LanguageServerSeed {
  247            worktree_id: worktree_handle.read(cx).id(),
  248            name: disposition.server_name.clone(),
  249            settings: disposition.settings.clone(),
  250            toolchain: disposition.toolchain.clone(),
  251        };
  252        if let Some(state) = self.language_server_ids.get_mut(&key) {
  253            state.project_roots.insert(disposition.path.path.clone());
  254            state.id
  255        } else {
  256            let adapter = self
  257                .languages
  258                .lsp_adapters(language_name)
  259                .into_iter()
  260                .find(|adapter| adapter.name() == disposition.server_name)
  261                .expect("To find LSP adapter");
  262            let new_language_server_id = self.start_language_server(
  263                worktree_handle,
  264                delegate,
  265                adapter,
  266                disposition.settings.clone(),
  267                key.clone(),
  268                cx,
  269            );
  270            if let Some(state) = self.language_server_ids.get_mut(&key) {
  271                state.project_roots.insert(disposition.path.path.clone());
  272            } else {
  273                debug_assert!(
  274                    false,
  275                    "Expected `start_language_server` to ensure that `key` exists in a map"
  276                );
  277            }
  278            new_language_server_id
  279        }
  280    }
  281
  282    fn start_language_server(
  283        &mut self,
  284        worktree_handle: &Entity<Worktree>,
  285        delegate: Arc<LocalLspAdapterDelegate>,
  286        adapter: Arc<CachedLspAdapter>,
  287        settings: Arc<LspSettings>,
  288        key: LanguageServerSeed,
  289        cx: &mut App,
  290    ) -> LanguageServerId {
  291        let worktree = worktree_handle.read(cx);
  292
  293        let root_path = worktree.abs_path();
  294        let toolchain = key.toolchain.clone();
  295        let override_options = settings.initialization_options.clone();
  296
  297        let stderr_capture = Arc::new(Mutex::new(Some(String::new())));
  298
  299        let server_id = self.languages.next_language_server_id();
  300        log::trace!(
  301            "attempting to start language server {:?}, path: {root_path:?}, id: {server_id}",
  302            adapter.name.0
  303        );
  304
  305        let binary = self.get_language_server_binary(
  306            adapter.clone(),
  307            settings,
  308            toolchain.clone(),
  309            delegate.clone(),
  310            true,
  311            cx,
  312        );
  313        let pending_workspace_folders: Arc<Mutex<BTreeSet<Url>>> = Default::default();
  314
  315        let pending_server = cx.spawn({
  316            let adapter = adapter.clone();
  317            let server_name = adapter.name.clone();
  318            let stderr_capture = stderr_capture.clone();
  319            #[cfg(any(test, feature = "test-support"))]
  320            let lsp_store = self.weak.clone();
  321            let pending_workspace_folders = pending_workspace_folders.clone();
  322            async move |cx| {
  323                let binary = binary.await?;
  324                #[cfg(any(test, feature = "test-support"))]
  325                if let Some(server) = lsp_store
  326                    .update(&mut cx.clone(), |this, cx| {
  327                        this.languages.create_fake_language_server(
  328                            server_id,
  329                            &server_name,
  330                            binary.clone(),
  331                            &mut cx.to_async(),
  332                        )
  333                    })
  334                    .ok()
  335                    .flatten()
  336                {
  337                    return Ok(server);
  338                }
  339
  340                let code_action_kinds = adapter.code_action_kinds();
  341                lsp::LanguageServer::new(
  342                    stderr_capture,
  343                    server_id,
  344                    server_name,
  345                    binary,
  346                    &root_path,
  347                    code_action_kinds,
  348                    Some(pending_workspace_folders),
  349                    cx,
  350                )
  351            }
  352        });
  353
  354        let startup = {
  355            let server_name = adapter.name.0.clone();
  356            let delegate = delegate as Arc<dyn LspAdapterDelegate>;
  357            let key = key.clone();
  358            let adapter = adapter.clone();
  359            let lsp_store = self.weak.clone();
  360            let pending_workspace_folders = pending_workspace_folders.clone();
  361            let fs = self.fs.clone();
  362            let pull_diagnostics = ProjectSettings::get_global(cx)
  363                .diagnostics
  364                .lsp_pull_diagnostics
  365                .enabled;
  366            cx.spawn(async move |cx| {
  367                let result = async {
  368                    let language_server = pending_server.await?;
  369
  370                    let workspace_config = Self::workspace_configuration_for_adapter(
  371                        adapter.adapter.clone(),
  372                        fs.as_ref(),
  373                        &delegate,
  374                        toolchain,
  375                        cx,
  376                    )
  377                    .await?;
  378
  379                    let mut initialization_options = Self::initialization_options_for_adapter(
  380                        adapter.adapter.clone(),
  381                        fs.as_ref(),
  382                        &delegate,
  383                    )
  384                    .await?;
  385
  386                    match (&mut initialization_options, override_options) {
  387                        (Some(initialization_options), Some(override_options)) => {
  388                            merge_json_value_into(override_options, initialization_options);
  389                        }
  390                        (None, override_options) => initialization_options = override_options,
  391                        _ => {}
  392                    }
  393
  394                    let initialization_params = cx.update(|cx| {
  395                        let mut params =
  396                            language_server.default_initialize_params(pull_diagnostics, cx);
  397                        params.initialization_options = initialization_options;
  398                        adapter.adapter.prepare_initialize_params(params, cx)
  399                    })??;
  400
  401                    Self::setup_lsp_messages(
  402                        lsp_store.clone(),
  403                        fs,
  404                        &language_server,
  405                        delegate.clone(),
  406                        adapter.clone(),
  407                    );
  408
  409                    let did_change_configuration_params =
  410                        Arc::new(lsp::DidChangeConfigurationParams {
  411                            settings: workspace_config,
  412                        });
  413                    let language_server = cx
  414                        .update(|cx| {
  415                            language_server.initialize(
  416                                initialization_params,
  417                                did_change_configuration_params.clone(),
  418                                cx,
  419                            )
  420                        })?
  421                        .await
  422                        .inspect_err(|_| {
  423                            if let Some(lsp_store) = lsp_store.upgrade() {
  424                                lsp_store
  425                                    .update(cx, |lsp_store, cx| {
  426                                        lsp_store.cleanup_lsp_data(server_id);
  427                                        cx.emit(LspStoreEvent::LanguageServerRemoved(server_id))
  428                                    })
  429                                    .ok();
  430                            }
  431                        })?;
  432
  433                    language_server
  434                        .notify::<lsp::notification::DidChangeConfiguration>(
  435                            &did_change_configuration_params,
  436                        )
  437                        .ok();
  438
  439                    anyhow::Ok(language_server)
  440                }
  441                .await;
  442
  443                match result {
  444                    Ok(server) => {
  445                        lsp_store
  446                            .update(cx, |lsp_store, cx| {
  447                                lsp_store.insert_newly_running_language_server(
  448                                    adapter,
  449                                    server.clone(),
  450                                    server_id,
  451                                    key,
  452                                    pending_workspace_folders,
  453                                    cx,
  454                                );
  455                            })
  456                            .ok();
  457                        stderr_capture.lock().take();
  458                        Some(server)
  459                    }
  460
  461                    Err(err) => {
  462                        let log = stderr_capture.lock().take().unwrap_or_default();
  463                        delegate.update_status(
  464                            adapter.name(),
  465                            BinaryStatus::Failed {
  466                                error: if log.is_empty() {
  467                                    format!("{err:#}")
  468                                } else {
  469                                    format!("{err:#}\n-- stderr --\n{log}")
  470                                },
  471                            },
  472                        );
  473                        log::error!("Failed to start language server {server_name:?}: {err:?}");
  474                        if !log.is_empty() {
  475                            log::error!("server stderr: {log}");
  476                        }
  477                        None
  478                    }
  479                }
  480            })
  481        };
  482        let state = LanguageServerState::Starting {
  483            startup,
  484            pending_workspace_folders,
  485        };
  486
  487        self.languages
  488            .update_lsp_binary_status(adapter.name(), BinaryStatus::Starting);
  489
  490        self.language_servers.insert(server_id, state);
  491        self.language_server_ids
  492            .entry(key)
  493            .or_insert(UnifiedLanguageServer {
  494                id: server_id,
  495                project_roots: Default::default(),
  496            });
  497        server_id
  498    }
  499
  500    fn get_language_server_binary(
  501        &self,
  502        adapter: Arc<CachedLspAdapter>,
  503        settings: Arc<LspSettings>,
  504        toolchain: Option<Toolchain>,
  505        delegate: Arc<dyn LspAdapterDelegate>,
  506        allow_binary_download: bool,
  507        cx: &mut App,
  508    ) -> Task<Result<LanguageServerBinary>> {
  509        if let Some(settings) = settings.binary.as_ref()
  510            && settings.path.is_some()
  511        {
  512            let settings = settings.clone();
  513
  514            return cx.background_spawn(async move {
  515                let mut env = delegate.shell_env().await;
  516                env.extend(settings.env.unwrap_or_default());
  517
  518                Ok(LanguageServerBinary {
  519                    path: PathBuf::from(&settings.path.unwrap()),
  520                    env: Some(env),
  521                    arguments: settings
  522                        .arguments
  523                        .unwrap_or_default()
  524                        .iter()
  525                        .map(Into::into)
  526                        .collect(),
  527                })
  528            });
  529        }
  530        let lsp_binary_options = LanguageServerBinaryOptions {
  531            allow_path_lookup: !settings
  532                .binary
  533                .as_ref()
  534                .and_then(|b| b.ignore_system_version)
  535                .unwrap_or_default(),
  536            allow_binary_download,
  537        };
  538
  539        cx.spawn(async move |cx| {
  540            let binary_result = adapter
  541                .clone()
  542                .get_language_server_command(delegate.clone(), toolchain, lsp_binary_options, cx)
  543                .await;
  544
  545            delegate.update_status(adapter.name.clone(), BinaryStatus::None);
  546
  547            let mut binary = binary_result?;
  548            let mut shell_env = delegate.shell_env().await;
  549
  550            shell_env.extend(binary.env.unwrap_or_default());
  551
  552            if let Some(settings) = settings.binary.as_ref() {
  553                if let Some(arguments) = &settings.arguments {
  554                    binary.arguments = arguments.iter().map(Into::into).collect();
  555                }
  556                if let Some(env) = &settings.env {
  557                    shell_env.extend(env.iter().map(|(k, v)| (k.clone(), v.clone())));
  558                }
  559            }
  560
  561            binary.env = Some(shell_env);
  562            Ok(binary)
  563        })
  564    }
  565
  566    fn setup_lsp_messages(
  567        this: WeakEntity<LspStore>,
  568        fs: Arc<dyn Fs>,
  569        language_server: &LanguageServer,
  570        delegate: Arc<dyn LspAdapterDelegate>,
  571        adapter: Arc<CachedLspAdapter>,
  572    ) {
  573        let name = language_server.name();
  574        let server_id = language_server.server_id();
  575        language_server
  576            .on_notification::<lsp::notification::PublishDiagnostics, _>({
  577                let adapter = adapter.clone();
  578                let this = this.clone();
  579                move |mut params, cx| {
  580                    let adapter = adapter.clone();
  581                    if let Some(this) = this.upgrade() {
  582                        this.update(cx, |this, cx| {
  583                            {
  584                                let buffer = params
  585                                    .uri
  586                                    .to_file_path()
  587                                    .map(|file_path| this.get_buffer(&file_path, cx))
  588                                    .ok()
  589                                    .flatten();
  590                                adapter.process_diagnostics(&mut params, server_id, buffer);
  591                            }
  592
  593                            this.merge_lsp_diagnostics(
  594                                DiagnosticSourceKind::Pushed,
  595                                vec![DocumentDiagnosticsUpdate {
  596                                    server_id,
  597                                    diagnostics: params,
  598                                    result_id: None,
  599                                    disk_based_sources: Cow::Borrowed(
  600                                        &adapter.disk_based_diagnostic_sources,
  601                                    ),
  602                                }],
  603                                |_, diagnostic, cx| match diagnostic.source_kind {
  604                                    DiagnosticSourceKind::Other | DiagnosticSourceKind::Pushed => {
  605                                        adapter.retain_old_diagnostic(diagnostic, cx)
  606                                    }
  607                                    DiagnosticSourceKind::Pulled => true,
  608                                },
  609                                cx,
  610                            )
  611                            .log_err();
  612                        })
  613                        .ok();
  614                    }
  615                }
  616            })
  617            .detach();
  618        language_server
  619            .on_request::<lsp::request::WorkspaceConfiguration, _, _>({
  620                let adapter = adapter.adapter.clone();
  621                let delegate = delegate.clone();
  622                let this = this.clone();
  623                let fs = fs.clone();
  624                move |params, cx| {
  625                    let adapter = adapter.clone();
  626                    let delegate = delegate.clone();
  627                    let this = this.clone();
  628                    let fs = fs.clone();
  629                    let mut cx = cx.clone();
  630                    async move {
  631                        let toolchain_for_id = this
  632                            .update(&mut cx, |this, _| {
  633                                this.as_local()?.language_server_ids.iter().find_map(
  634                                    |(seed, value)| {
  635                                        (value.id == server_id).then(|| seed.toolchain.clone())
  636                                    },
  637                                )
  638                            })?
  639                            .context("Expected the LSP store to be in a local mode")?;
  640                        let workspace_config = Self::workspace_configuration_for_adapter(
  641                            adapter.clone(),
  642                            fs.as_ref(),
  643                            &delegate,
  644                            toolchain_for_id,
  645                            &mut cx,
  646                        )
  647                        .await?;
  648
  649                        Ok(params
  650                            .items
  651                            .into_iter()
  652                            .map(|item| {
  653                                if let Some(section) = &item.section {
  654                                    workspace_config
  655                                        .get(section)
  656                                        .cloned()
  657                                        .unwrap_or(serde_json::Value::Null)
  658                                } else {
  659                                    workspace_config.clone()
  660                                }
  661                            })
  662                            .collect())
  663                    }
  664                }
  665            })
  666            .detach();
  667
  668        language_server
  669            .on_request::<lsp::request::WorkspaceFoldersRequest, _, _>({
  670                let this = this.clone();
  671                move |_, cx| {
  672                    let this = this.clone();
  673                    let cx = cx.clone();
  674                    async move {
  675                        let Some(server) =
  676                            this.read_with(&cx, |this, _| this.language_server_for_id(server_id))?
  677                        else {
  678                            return Ok(None);
  679                        };
  680                        let root = server.workspace_folders();
  681                        Ok(Some(
  682                            root.into_iter()
  683                                .map(|uri| WorkspaceFolder {
  684                                    uri,
  685                                    name: Default::default(),
  686                                })
  687                                .collect(),
  688                        ))
  689                    }
  690                }
  691            })
  692            .detach();
  693        // Even though we don't have handling for these requests, respond to them to
  694        // avoid stalling any language server like `gopls` which waits for a response
  695        // to these requests when initializing.
  696        language_server
  697            .on_request::<lsp::request::WorkDoneProgressCreate, _, _>({
  698                let this = this.clone();
  699                move |params, cx| {
  700                    let this = this.clone();
  701                    let mut cx = cx.clone();
  702                    async move {
  703                        this.update(&mut cx, |this, _| {
  704                            if let Some(status) = this.language_server_statuses.get_mut(&server_id)
  705                                && let lsp::NumberOrString::String(token) = params.token
  706                            {
  707                                status.progress_tokens.insert(token);
  708                            }
  709                        })?;
  710
  711                        Ok(())
  712                    }
  713                }
  714            })
  715            .detach();
  716
  717        language_server
  718            .on_request::<lsp::request::RegisterCapability, _, _>({
  719                let lsp_store = this.clone();
  720                move |params, cx| {
  721                    let lsp_store = lsp_store.clone();
  722                    let mut cx = cx.clone();
  723                    async move {
  724                        lsp_store
  725                            .update(&mut cx, |lsp_store, cx| {
  726                                if lsp_store.as_local().is_some() {
  727                                    match lsp_store
  728                                        .register_server_capabilities(server_id, params, cx)
  729                                    {
  730                                        Ok(()) => {}
  731                                        Err(e) => {
  732                                            log::error!(
  733                                                "Failed to register server capabilities: {e:#}"
  734                                            );
  735                                        }
  736                                    };
  737                                }
  738                            })
  739                            .ok();
  740                        Ok(())
  741                    }
  742                }
  743            })
  744            .detach();
  745
  746        language_server
  747            .on_request::<lsp::request::UnregisterCapability, _, _>({
  748                let lsp_store = this.clone();
  749                move |params, cx| {
  750                    let lsp_store = lsp_store.clone();
  751                    let mut cx = cx.clone();
  752                    async move {
  753                        lsp_store
  754                            .update(&mut cx, |lsp_store, cx| {
  755                                if lsp_store.as_local().is_some() {
  756                                    match lsp_store
  757                                        .unregister_server_capabilities(server_id, params, cx)
  758                                    {
  759                                        Ok(()) => {}
  760                                        Err(e) => {
  761                                            log::error!(
  762                                                "Failed to unregister server capabilities: {e:#}"
  763                                            );
  764                                        }
  765                                    }
  766                                }
  767                            })
  768                            .ok();
  769                        Ok(())
  770                    }
  771                }
  772            })
  773            .detach();
  774
  775        language_server
  776            .on_request::<lsp::request::ApplyWorkspaceEdit, _, _>({
  777                let this = this.clone();
  778                move |params, cx| {
  779                    let mut cx = cx.clone();
  780                    let this = this.clone();
  781                    async move {
  782                        LocalLspStore::on_lsp_workspace_edit(
  783                            this.clone(),
  784                            params,
  785                            server_id,
  786                            &mut cx,
  787                        )
  788                        .await
  789                    }
  790                }
  791            })
  792            .detach();
  793
  794        language_server
  795            .on_request::<lsp::request::InlayHintRefreshRequest, _, _>({
  796                let this = this.clone();
  797                move |(), cx| {
  798                    let this = this.clone();
  799                    let mut cx = cx.clone();
  800                    async move {
  801                        this.update(&mut cx, |this, cx| {
  802                            cx.emit(LspStoreEvent::RefreshInlayHints);
  803                            this.downstream_client.as_ref().map(|(client, project_id)| {
  804                                client.send(proto::RefreshInlayHints {
  805                                    project_id: *project_id,
  806                                })
  807                            })
  808                        })?
  809                        .transpose()?;
  810                        Ok(())
  811                    }
  812                }
  813            })
  814            .detach();
  815
  816        language_server
  817            .on_request::<lsp::request::CodeLensRefresh, _, _>({
  818                let this = this.clone();
  819                move |(), cx| {
  820                    let this = this.clone();
  821                    let mut cx = cx.clone();
  822                    async move {
  823                        this.update(&mut cx, |this, cx| {
  824                            cx.emit(LspStoreEvent::RefreshCodeLens);
  825                            this.downstream_client.as_ref().map(|(client, project_id)| {
  826                                client.send(proto::RefreshCodeLens {
  827                                    project_id: *project_id,
  828                                })
  829                            })
  830                        })?
  831                        .transpose()?;
  832                        Ok(())
  833                    }
  834                }
  835            })
  836            .detach();
  837
  838        language_server
  839            .on_request::<lsp::request::WorkspaceDiagnosticRefresh, _, _>({
  840                let this = this.clone();
  841                move |(), cx| {
  842                    let this = this.clone();
  843                    let mut cx = cx.clone();
  844                    async move {
  845                        this.update(&mut cx, |lsp_store, _| {
  846                            lsp_store.pull_workspace_diagnostics(server_id);
  847                            lsp_store
  848                                .downstream_client
  849                                .as_ref()
  850                                .map(|(client, project_id)| {
  851                                    client.send(proto::PullWorkspaceDiagnostics {
  852                                        project_id: *project_id,
  853                                        server_id: server_id.to_proto(),
  854                                    })
  855                                })
  856                        })?
  857                        .transpose()?;
  858                        Ok(())
  859                    }
  860                }
  861            })
  862            .detach();
  863
  864        language_server
  865            .on_request::<lsp::request::ShowMessageRequest, _, _>({
  866                let this = this.clone();
  867                let name = name.to_string();
  868                move |params, cx| {
  869                    let this = this.clone();
  870                    let name = name.to_string();
  871                    let mut cx = cx.clone();
  872                    async move {
  873                        let actions = params.actions.unwrap_or_default();
  874                        let (tx, rx) = smol::channel::bounded(1);
  875                        let request = LanguageServerPromptRequest {
  876                            level: match params.typ {
  877                                lsp::MessageType::ERROR => PromptLevel::Critical,
  878                                lsp::MessageType::WARNING => PromptLevel::Warning,
  879                                _ => PromptLevel::Info,
  880                            },
  881                            message: params.message,
  882                            actions,
  883                            response_channel: tx,
  884                            lsp_name: name.clone(),
  885                        };
  886
  887                        let did_update = this
  888                            .update(&mut cx, |_, cx| {
  889                                cx.emit(LspStoreEvent::LanguageServerPrompt(request));
  890                            })
  891                            .is_ok();
  892                        if did_update {
  893                            let response = rx.recv().await.ok();
  894                            Ok(response)
  895                        } else {
  896                            Ok(None)
  897                        }
  898                    }
  899                }
  900            })
  901            .detach();
  902        language_server
  903            .on_notification::<lsp::notification::ShowMessage, _>({
  904                let this = this.clone();
  905                let name = name.to_string();
  906                move |params, cx| {
  907                    let this = this.clone();
  908                    let name = name.to_string();
  909                    let mut cx = cx.clone();
  910
  911                    let (tx, _) = smol::channel::bounded(1);
  912                    let request = LanguageServerPromptRequest {
  913                        level: match params.typ {
  914                            lsp::MessageType::ERROR => PromptLevel::Critical,
  915                            lsp::MessageType::WARNING => PromptLevel::Warning,
  916                            _ => PromptLevel::Info,
  917                        },
  918                        message: params.message,
  919                        actions: vec![],
  920                        response_channel: tx,
  921                        lsp_name: name,
  922                    };
  923
  924                    let _ = this.update(&mut cx, |_, cx| {
  925                        cx.emit(LspStoreEvent::LanguageServerPrompt(request));
  926                    });
  927                }
  928            })
  929            .detach();
  930
  931        let disk_based_diagnostics_progress_token =
  932            adapter.disk_based_diagnostics_progress_token.clone();
  933
  934        language_server
  935            .on_notification::<lsp::notification::Progress, _>({
  936                let this = this.clone();
  937                move |params, cx| {
  938                    if let Some(this) = this.upgrade() {
  939                        this.update(cx, |this, cx| {
  940                            this.on_lsp_progress(
  941                                params,
  942                                server_id,
  943                                disk_based_diagnostics_progress_token.clone(),
  944                                cx,
  945                            );
  946                        })
  947                        .ok();
  948                    }
  949                }
  950            })
  951            .detach();
  952
  953        language_server
  954            .on_notification::<lsp::notification::LogMessage, _>({
  955                let this = this.clone();
  956                move |params, cx| {
  957                    if let Some(this) = this.upgrade() {
  958                        this.update(cx, |_, cx| {
  959                            cx.emit(LspStoreEvent::LanguageServerLog(
  960                                server_id,
  961                                LanguageServerLogType::Log(params.typ),
  962                                params.message,
  963                            ));
  964                        })
  965                        .ok();
  966                    }
  967                }
  968            })
  969            .detach();
  970
  971        language_server
  972            .on_notification::<lsp::notification::LogTrace, _>({
  973                let this = this.clone();
  974                move |params, cx| {
  975                    let mut cx = cx.clone();
  976                    if let Some(this) = this.upgrade() {
  977                        this.update(&mut cx, |_, cx| {
  978                            cx.emit(LspStoreEvent::LanguageServerLog(
  979                                server_id,
  980                                LanguageServerLogType::Trace(params.verbose),
  981                                params.message,
  982                            ));
  983                        })
  984                        .ok();
  985                    }
  986                }
  987            })
  988            .detach();
  989
  990        json_language_server_ext::register_requests(this.clone(), language_server);
  991        rust_analyzer_ext::register_notifications(this.clone(), language_server);
  992        clangd_ext::register_notifications(this, language_server, adapter);
  993    }
  994
  995    fn shutdown_language_servers_on_quit(
  996        &mut self,
  997        _: &mut Context<LspStore>,
  998    ) -> impl Future<Output = ()> + use<> {
  999        let shutdown_futures = self
 1000            .language_servers
 1001            .drain()
 1002            .map(|(_, server_state)| Self::shutdown_server(server_state))
 1003            .collect::<Vec<_>>();
 1004
 1005        async move {
 1006            join_all(shutdown_futures).await;
 1007        }
 1008    }
 1009
 1010    async fn shutdown_server(server_state: LanguageServerState) -> anyhow::Result<()> {
 1011        match server_state {
 1012            LanguageServerState::Running { server, .. } => {
 1013                if let Some(shutdown) = server.shutdown() {
 1014                    shutdown.await;
 1015                }
 1016            }
 1017            LanguageServerState::Starting { startup, .. } => {
 1018                if let Some(server) = startup.await
 1019                    && let Some(shutdown) = server.shutdown()
 1020                {
 1021                    shutdown.await;
 1022                }
 1023            }
 1024        }
 1025        Ok(())
 1026    }
 1027
 1028    fn language_servers_for_worktree(
 1029        &self,
 1030        worktree_id: WorktreeId,
 1031    ) -> impl Iterator<Item = &Arc<LanguageServer>> {
 1032        self.language_server_ids
 1033            .iter()
 1034            .filter_map(move |(seed, state)| {
 1035                if seed.worktree_id != worktree_id {
 1036                    return None;
 1037                }
 1038
 1039                if let Some(LanguageServerState::Running { server, .. }) =
 1040                    self.language_servers.get(&state.id)
 1041                {
 1042                    Some(server)
 1043                } else {
 1044                    None
 1045                }
 1046            })
 1047    }
 1048
 1049    fn language_server_ids_for_project_path(
 1050        &self,
 1051        project_path: ProjectPath,
 1052        language: &Language,
 1053        cx: &mut App,
 1054    ) -> Vec<LanguageServerId> {
 1055        let Some(worktree) = self
 1056            .worktree_store
 1057            .read(cx)
 1058            .worktree_for_id(project_path.worktree_id, cx)
 1059        else {
 1060            return Vec::new();
 1061        };
 1062        let delegate: Arc<dyn ManifestDelegate> =
 1063            Arc::new(ManifestQueryDelegate::new(worktree.read(cx).snapshot()));
 1064
 1065        self.lsp_tree
 1066            .get(
 1067                project_path,
 1068                language.name(),
 1069                language.manifest(),
 1070                &delegate,
 1071                cx,
 1072            )
 1073            .collect::<Vec<_>>()
 1074    }
 1075
 1076    fn language_server_ids_for_buffer(
 1077        &self,
 1078        buffer: &Buffer,
 1079        cx: &mut App,
 1080    ) -> Vec<LanguageServerId> {
 1081        if let Some((file, language)) = File::from_dyn(buffer.file()).zip(buffer.language()) {
 1082            let worktree_id = file.worktree_id(cx);
 1083
 1084            let path: Arc<Path> = file
 1085                .path()
 1086                .parent()
 1087                .map(Arc::from)
 1088                .unwrap_or_else(|| file.path().clone());
 1089            let worktree_path = ProjectPath { worktree_id, path };
 1090            self.language_server_ids_for_project_path(worktree_path, language, cx)
 1091        } else {
 1092            Vec::new()
 1093        }
 1094    }
 1095
 1096    fn language_servers_for_buffer<'a>(
 1097        &'a self,
 1098        buffer: &'a Buffer,
 1099        cx: &'a mut App,
 1100    ) -> impl Iterator<Item = (&'a Arc<CachedLspAdapter>, &'a Arc<LanguageServer>)> {
 1101        self.language_server_ids_for_buffer(buffer, cx)
 1102            .into_iter()
 1103            .filter_map(|server_id| match self.language_servers.get(&server_id)? {
 1104                LanguageServerState::Running {
 1105                    adapter, server, ..
 1106                } => Some((adapter, server)),
 1107                _ => None,
 1108            })
 1109    }
 1110
 1111    async fn execute_code_action_kind_locally(
 1112        lsp_store: WeakEntity<LspStore>,
 1113        mut buffers: Vec<Entity<Buffer>>,
 1114        kind: CodeActionKind,
 1115        push_to_history: bool,
 1116        cx: &mut AsyncApp,
 1117    ) -> anyhow::Result<ProjectTransaction> {
 1118        // Do not allow multiple concurrent code actions requests for the
 1119        // same buffer.
 1120        lsp_store.update(cx, |this, cx| {
 1121            let this = this.as_local_mut().unwrap();
 1122            buffers.retain(|buffer| {
 1123                this.buffers_being_formatted
 1124                    .insert(buffer.read(cx).remote_id())
 1125            });
 1126        })?;
 1127        let _cleanup = defer({
 1128            let this = lsp_store.clone();
 1129            let mut cx = cx.clone();
 1130            let buffers = &buffers;
 1131            move || {
 1132                this.update(&mut cx, |this, cx| {
 1133                    let this = this.as_local_mut().unwrap();
 1134                    for buffer in buffers {
 1135                        this.buffers_being_formatted
 1136                            .remove(&buffer.read(cx).remote_id());
 1137                    }
 1138                })
 1139                .ok();
 1140            }
 1141        });
 1142        let mut project_transaction = ProjectTransaction::default();
 1143
 1144        for buffer in &buffers {
 1145            let adapters_and_servers = lsp_store.update(cx, |lsp_store, cx| {
 1146                buffer.update(cx, |buffer, cx| {
 1147                    lsp_store
 1148                        .as_local()
 1149                        .unwrap()
 1150                        .language_servers_for_buffer(buffer, cx)
 1151                        .map(|(adapter, lsp)| (adapter.clone(), lsp.clone()))
 1152                        .collect::<Vec<_>>()
 1153                })
 1154            })?;
 1155            for (_, language_server) in adapters_and_servers.iter() {
 1156                let actions = Self::get_server_code_actions_from_action_kinds(
 1157                    &lsp_store,
 1158                    language_server.server_id(),
 1159                    vec![kind.clone()],
 1160                    buffer,
 1161                    cx,
 1162                )
 1163                .await?;
 1164                Self::execute_code_actions_on_server(
 1165                    &lsp_store,
 1166                    language_server,
 1167                    actions,
 1168                    push_to_history,
 1169                    &mut project_transaction,
 1170                    cx,
 1171                )
 1172                .await?;
 1173            }
 1174        }
 1175        Ok(project_transaction)
 1176    }
 1177
 1178    async fn format_locally(
 1179        lsp_store: WeakEntity<LspStore>,
 1180        mut buffers: Vec<FormattableBuffer>,
 1181        push_to_history: bool,
 1182        trigger: FormatTrigger,
 1183        logger: zlog::Logger,
 1184        cx: &mut AsyncApp,
 1185    ) -> anyhow::Result<ProjectTransaction> {
 1186        // Do not allow multiple concurrent formatting requests for the
 1187        // same buffer.
 1188        lsp_store.update(cx, |this, cx| {
 1189            let this = this.as_local_mut().unwrap();
 1190            buffers.retain(|buffer| {
 1191                this.buffers_being_formatted
 1192                    .insert(buffer.handle.read(cx).remote_id())
 1193            });
 1194        })?;
 1195
 1196        let _cleanup = defer({
 1197            let this = lsp_store.clone();
 1198            let mut cx = cx.clone();
 1199            let buffers = &buffers;
 1200            move || {
 1201                this.update(&mut cx, |this, cx| {
 1202                    let this = this.as_local_mut().unwrap();
 1203                    for buffer in buffers {
 1204                        this.buffers_being_formatted
 1205                            .remove(&buffer.handle.read(cx).remote_id());
 1206                    }
 1207                })
 1208                .ok();
 1209            }
 1210        });
 1211
 1212        let mut project_transaction = ProjectTransaction::default();
 1213
 1214        for buffer in &buffers {
 1215            zlog::debug!(
 1216                logger =>
 1217                "formatting buffer '{:?}'",
 1218                buffer.abs_path.as_ref().unwrap_or(&PathBuf::from("unknown")).display()
 1219            );
 1220            // Create an empty transaction to hold all of the formatting edits.
 1221            let formatting_transaction_id = buffer.handle.update(cx, |buffer, cx| {
 1222                // ensure no transactions created while formatting are
 1223                // grouped with the previous transaction in the history
 1224                // based on the transaction group interval
 1225                buffer.finalize_last_transaction();
 1226                buffer
 1227                    .start_transaction()
 1228                    .context("transaction already open")?;
 1229                buffer.end_transaction(cx);
 1230                let transaction_id = buffer.push_empty_transaction(cx.background_executor().now());
 1231                buffer.finalize_last_transaction();
 1232                anyhow::Ok(transaction_id)
 1233            })??;
 1234
 1235            let result = Self::format_buffer_locally(
 1236                lsp_store.clone(),
 1237                buffer,
 1238                formatting_transaction_id,
 1239                trigger,
 1240                logger,
 1241                cx,
 1242            )
 1243            .await;
 1244
 1245            buffer.handle.update(cx, |buffer, cx| {
 1246                let Some(formatting_transaction) =
 1247                    buffer.get_transaction(formatting_transaction_id).cloned()
 1248                else {
 1249                    zlog::warn!(logger => "no formatting transaction");
 1250                    return;
 1251                };
 1252                if formatting_transaction.edit_ids.is_empty() {
 1253                    zlog::debug!(logger => "no changes made while formatting");
 1254                    buffer.forget_transaction(formatting_transaction_id);
 1255                    return;
 1256                }
 1257                if !push_to_history {
 1258                    zlog::trace!(logger => "forgetting format transaction");
 1259                    buffer.forget_transaction(formatting_transaction.id);
 1260                }
 1261                project_transaction
 1262                    .0
 1263                    .insert(cx.entity(), formatting_transaction);
 1264            })?;
 1265
 1266            result?;
 1267        }
 1268
 1269        Ok(project_transaction)
 1270    }
 1271
 1272    async fn format_buffer_locally(
 1273        lsp_store: WeakEntity<LspStore>,
 1274        buffer: &FormattableBuffer,
 1275        formatting_transaction_id: clock::Lamport,
 1276        trigger: FormatTrigger,
 1277        logger: zlog::Logger,
 1278        cx: &mut AsyncApp,
 1279    ) -> Result<()> {
 1280        let (adapters_and_servers, settings) = lsp_store.update(cx, |lsp_store, cx| {
 1281            buffer.handle.update(cx, |buffer, cx| {
 1282                let adapters_and_servers = lsp_store
 1283                    .as_local()
 1284                    .unwrap()
 1285                    .language_servers_for_buffer(buffer, cx)
 1286                    .map(|(adapter, lsp)| (adapter.clone(), lsp.clone()))
 1287                    .collect::<Vec<_>>();
 1288                let settings =
 1289                    language_settings(buffer.language().map(|l| l.name()), buffer.file(), cx)
 1290                        .into_owned();
 1291                (adapters_and_servers, settings)
 1292            })
 1293        })?;
 1294
 1295        /// Apply edits to the buffer that will become part of the formatting transaction.
 1296        /// Fails if the buffer has been edited since the start of that transaction.
 1297        fn extend_formatting_transaction(
 1298            buffer: &FormattableBuffer,
 1299            formatting_transaction_id: text::TransactionId,
 1300            cx: &mut AsyncApp,
 1301            operation: impl FnOnce(&mut Buffer, &mut Context<Buffer>),
 1302        ) -> anyhow::Result<()> {
 1303            buffer.handle.update(cx, |buffer, cx| {
 1304                let last_transaction_id = buffer.peek_undo_stack().map(|t| t.transaction_id());
 1305                if last_transaction_id != Some(formatting_transaction_id) {
 1306                    anyhow::bail!("Buffer edited while formatting. Aborting")
 1307                }
 1308                buffer.start_transaction();
 1309                operation(buffer, cx);
 1310                if let Some(transaction_id) = buffer.end_transaction(cx) {
 1311                    buffer.merge_transactions(transaction_id, formatting_transaction_id);
 1312                }
 1313                Ok(())
 1314            })?
 1315        }
 1316
 1317        // handle whitespace formatting
 1318        if settings.remove_trailing_whitespace_on_save {
 1319            zlog::trace!(logger => "removing trailing whitespace");
 1320            let diff = buffer
 1321                .handle
 1322                .read_with(cx, |buffer, cx| buffer.remove_trailing_whitespace(cx))?
 1323                .await;
 1324            extend_formatting_transaction(buffer, formatting_transaction_id, cx, |buffer, cx| {
 1325                buffer.apply_diff(diff, cx);
 1326            })?;
 1327        }
 1328
 1329        if settings.ensure_final_newline_on_save {
 1330            zlog::trace!(logger => "ensuring final newline");
 1331            extend_formatting_transaction(buffer, formatting_transaction_id, cx, |buffer, cx| {
 1332                buffer.ensure_final_newline(cx);
 1333            })?;
 1334        }
 1335
 1336        // Formatter for `code_actions_on_format` that runs before
 1337        // the rest of the formatters
 1338        let mut code_actions_on_format_formatter = None;
 1339        let should_run_code_actions_on_format = !matches!(
 1340            (trigger, &settings.format_on_save),
 1341            (FormatTrigger::Save, &FormatOnSave::Off)
 1342        );
 1343        if should_run_code_actions_on_format {
 1344            let have_code_actions_to_run_on_format = settings
 1345                .code_actions_on_format
 1346                .values()
 1347                .any(|enabled| *enabled);
 1348            if have_code_actions_to_run_on_format {
 1349                zlog::trace!(logger => "going to run code actions on format");
 1350                code_actions_on_format_formatter = Some(Formatter::CodeActions(
 1351                    settings.code_actions_on_format.clone(),
 1352                ));
 1353            }
 1354        }
 1355
 1356        let formatters = match (trigger, &settings.format_on_save) {
 1357            (FormatTrigger::Save, FormatOnSave::Off) => &[],
 1358            (FormatTrigger::Save, FormatOnSave::List(formatters)) => formatters.as_ref(),
 1359            (FormatTrigger::Manual, _) | (FormatTrigger::Save, FormatOnSave::On) => {
 1360                match &settings.formatter {
 1361                    SelectedFormatter::Auto => {
 1362                        if settings.prettier.allowed {
 1363                            zlog::trace!(logger => "Formatter set to auto: defaulting to prettier");
 1364                            std::slice::from_ref(&Formatter::Prettier)
 1365                        } else {
 1366                            zlog::trace!(logger => "Formatter set to auto: defaulting to primary language server");
 1367                            std::slice::from_ref(&Formatter::LanguageServer { name: None })
 1368                        }
 1369                    }
 1370                    SelectedFormatter::List(formatter_list) => formatter_list.as_ref(),
 1371                }
 1372            }
 1373        };
 1374
 1375        let formatters = code_actions_on_format_formatter.iter().chain(formatters);
 1376
 1377        for formatter in formatters {
 1378            match formatter {
 1379                Formatter::Prettier => {
 1380                    let logger = zlog::scoped!(logger => "prettier");
 1381                    zlog::trace!(logger => "formatting");
 1382                    let _timer = zlog::time!(logger => "Formatting buffer via prettier");
 1383
 1384                    let prettier = lsp_store.read_with(cx, |lsp_store, _cx| {
 1385                        lsp_store.prettier_store().unwrap().downgrade()
 1386                    })?;
 1387                    let diff = prettier_store::format_with_prettier(&prettier, &buffer.handle, cx)
 1388                        .await
 1389                        .transpose()?;
 1390                    let Some(diff) = diff else {
 1391                        zlog::trace!(logger => "No changes");
 1392                        continue;
 1393                    };
 1394
 1395                    extend_formatting_transaction(
 1396                        buffer,
 1397                        formatting_transaction_id,
 1398                        cx,
 1399                        |buffer, cx| {
 1400                            buffer.apply_diff(diff, cx);
 1401                        },
 1402                    )?;
 1403                }
 1404                Formatter::External { command, arguments } => {
 1405                    let logger = zlog::scoped!(logger => "command");
 1406                    zlog::trace!(logger => "formatting");
 1407                    let _timer = zlog::time!(logger => "Formatting buffer via external command");
 1408
 1409                    let diff = Self::format_via_external_command(
 1410                        buffer,
 1411                        command.as_ref(),
 1412                        arguments.as_deref(),
 1413                        cx,
 1414                    )
 1415                    .await
 1416                    .with_context(|| {
 1417                        format!("Failed to format buffer via external command: {}", command)
 1418                    })?;
 1419                    let Some(diff) = diff else {
 1420                        zlog::trace!(logger => "No changes");
 1421                        continue;
 1422                    };
 1423
 1424                    extend_formatting_transaction(
 1425                        buffer,
 1426                        formatting_transaction_id,
 1427                        cx,
 1428                        |buffer, cx| {
 1429                            buffer.apply_diff(diff, cx);
 1430                        },
 1431                    )?;
 1432                }
 1433                Formatter::LanguageServer { name } => {
 1434                    let logger = zlog::scoped!(logger => "language-server");
 1435                    zlog::trace!(logger => "formatting");
 1436                    let _timer = zlog::time!(logger => "Formatting buffer using language server");
 1437
 1438                    let Some(buffer_path_abs) = buffer.abs_path.as_ref() else {
 1439                        zlog::warn!(logger => "Cannot format buffer that is not backed by a file on disk using language servers. Skipping");
 1440                        continue;
 1441                    };
 1442
 1443                    let language_server = if let Some(name) = name.as_deref() {
 1444                        adapters_and_servers.iter().find_map(|(adapter, server)| {
 1445                            if adapter.name.0.as_ref() == name {
 1446                                Some(server.clone())
 1447                            } else {
 1448                                None
 1449                            }
 1450                        })
 1451                    } else {
 1452                        adapters_and_servers.first().map(|e| e.1.clone())
 1453                    };
 1454
 1455                    let Some(language_server) = language_server else {
 1456                        log::debug!(
 1457                            "No language server found to format buffer '{:?}'. Skipping",
 1458                            buffer_path_abs.as_path().to_string_lossy()
 1459                        );
 1460                        continue;
 1461                    };
 1462
 1463                    zlog::trace!(
 1464                        logger =>
 1465                        "Formatting buffer '{:?}' using language server '{:?}'",
 1466                        buffer_path_abs.as_path().to_string_lossy(),
 1467                        language_server.name()
 1468                    );
 1469
 1470                    let edits = if let Some(ranges) = buffer.ranges.as_ref() {
 1471                        zlog::trace!(logger => "formatting ranges");
 1472                        Self::format_ranges_via_lsp(
 1473                            &lsp_store,
 1474                            &buffer.handle,
 1475                            ranges,
 1476                            buffer_path_abs,
 1477                            &language_server,
 1478                            &settings,
 1479                            cx,
 1480                        )
 1481                        .await
 1482                        .context("Failed to format ranges via language server")?
 1483                    } else {
 1484                        zlog::trace!(logger => "formatting full");
 1485                        Self::format_via_lsp(
 1486                            &lsp_store,
 1487                            &buffer.handle,
 1488                            buffer_path_abs,
 1489                            &language_server,
 1490                            &settings,
 1491                            cx,
 1492                        )
 1493                        .await
 1494                        .context("failed to format via language server")?
 1495                    };
 1496
 1497                    if edits.is_empty() {
 1498                        zlog::trace!(logger => "No changes");
 1499                        continue;
 1500                    }
 1501                    extend_formatting_transaction(
 1502                        buffer,
 1503                        formatting_transaction_id,
 1504                        cx,
 1505                        |buffer, cx| {
 1506                            buffer.edit(edits, None, cx);
 1507                        },
 1508                    )?;
 1509                }
 1510                Formatter::CodeActions(code_actions) => {
 1511                    let logger = zlog::scoped!(logger => "code-actions");
 1512                    zlog::trace!(logger => "formatting");
 1513                    let _timer = zlog::time!(logger => "Formatting buffer using code actions");
 1514
 1515                    let Some(buffer_path_abs) = buffer.abs_path.as_ref() else {
 1516                        zlog::warn!(logger => "Cannot format buffer that is not backed by a file on disk using code actions. Skipping");
 1517                        continue;
 1518                    };
 1519                    let code_action_kinds = code_actions
 1520                        .iter()
 1521                        .filter_map(|(action_kind, enabled)| {
 1522                            enabled.then_some(action_kind.clone().into())
 1523                        })
 1524                        .collect::<Vec<_>>();
 1525                    if code_action_kinds.is_empty() {
 1526                        zlog::trace!(logger => "No code action kinds enabled, skipping");
 1527                        continue;
 1528                    }
 1529                    zlog::trace!(logger => "Attempting to resolve code actions {:?}", &code_action_kinds);
 1530
 1531                    let mut actions_and_servers = Vec::new();
 1532
 1533                    for (index, (_, language_server)) in adapters_and_servers.iter().enumerate() {
 1534                        let actions_result = Self::get_server_code_actions_from_action_kinds(
 1535                            &lsp_store,
 1536                            language_server.server_id(),
 1537                            code_action_kinds.clone(),
 1538                            &buffer.handle,
 1539                            cx,
 1540                        )
 1541                        .await
 1542                        .with_context(
 1543                            || format!("Failed to resolve code actions with kinds {:?} for language server {}",
 1544                                code_action_kinds.iter().map(|kind| kind.as_str()).join(", "),
 1545                                language_server.name())
 1546                        );
 1547                        let Ok(actions) = actions_result else {
 1548                            // note: it may be better to set result to the error and break formatters here
 1549                            // but for now we try to execute the actions that we can resolve and skip the rest
 1550                            zlog::error!(
 1551                                logger =>
 1552                                "Failed to resolve code actions with kinds {:?} with language server {}",
 1553                                code_action_kinds.iter().map(|kind| kind.as_str()).join(", "),
 1554                                language_server.name()
 1555                            );
 1556                            continue;
 1557                        };
 1558                        for action in actions {
 1559                            actions_and_servers.push((action, index));
 1560                        }
 1561                    }
 1562
 1563                    if actions_and_servers.is_empty() {
 1564                        zlog::warn!(logger => "No code actions were resolved, continuing");
 1565                        continue;
 1566                    }
 1567
 1568                    'actions: for (mut action, server_index) in actions_and_servers {
 1569                        let server = &adapters_and_servers[server_index].1;
 1570
 1571                        let describe_code_action = |action: &CodeAction| {
 1572                            format!(
 1573                                "code action '{}' with title \"{}\" on server {}",
 1574                                action
 1575                                    .lsp_action
 1576                                    .action_kind()
 1577                                    .unwrap_or("unknown".into())
 1578                                    .as_str(),
 1579                                action.lsp_action.title(),
 1580                                server.name(),
 1581                            )
 1582                        };
 1583
 1584                        zlog::trace!(logger => "Executing {}", describe_code_action(&action));
 1585
 1586                        if let Err(err) = Self::try_resolve_code_action(server, &mut action).await {
 1587                            zlog::error!(
 1588                                logger =>
 1589                                "Failed to resolve {}. Error: {}",
 1590                                describe_code_action(&action),
 1591                                err
 1592                            );
 1593                            continue;
 1594                        }
 1595
 1596                        if let Some(edit) = action.lsp_action.edit().cloned() {
 1597                            // NOTE: code below duplicated from `Self::deserialize_workspace_edit`
 1598                            // but filters out and logs warnings for code actions that cause unreasonably
 1599                            // difficult handling on our part, such as:
 1600                            // - applying edits that call commands
 1601                            //   which can result in arbitrary workspace edits being sent from the server that
 1602                            //   have no way of being tied back to the command that initiated them (i.e. we
 1603                            //   can't know which edits are part of the format request, or if the server is done sending
 1604                            //   actions in response to the command)
 1605                            // - actions that create/delete/modify/rename files other than the one we are formatting
 1606                            //   as we then would need to handle such changes correctly in the local history as well
 1607                            //   as the remote history through the ProjectTransaction
 1608                            // - actions with snippet edits, as these simply don't make sense in the context of a format request
 1609                            // Supporting these actions is not impossible, but not supported as of yet.
 1610                            if edit.changes.is_none() && edit.document_changes.is_none() {
 1611                                zlog::trace!(
 1612                                    logger =>
 1613                                    "No changes for code action. Skipping {}",
 1614                                    describe_code_action(&action),
 1615                                );
 1616                                continue;
 1617                            }
 1618
 1619                            let mut operations = Vec::new();
 1620                            if let Some(document_changes) = edit.document_changes {
 1621                                match document_changes {
 1622                                    lsp::DocumentChanges::Edits(edits) => operations.extend(
 1623                                        edits.into_iter().map(lsp::DocumentChangeOperation::Edit),
 1624                                    ),
 1625                                    lsp::DocumentChanges::Operations(ops) => operations = ops,
 1626                                }
 1627                            } else if let Some(changes) = edit.changes {
 1628                                operations.extend(changes.into_iter().map(|(uri, edits)| {
 1629                                    lsp::DocumentChangeOperation::Edit(lsp::TextDocumentEdit {
 1630                                        text_document:
 1631                                            lsp::OptionalVersionedTextDocumentIdentifier {
 1632                                                uri,
 1633                                                version: None,
 1634                                            },
 1635                                        edits: edits.into_iter().map(Edit::Plain).collect(),
 1636                                    })
 1637                                }));
 1638                            }
 1639
 1640                            let mut edits = Vec::with_capacity(operations.len());
 1641
 1642                            if operations.is_empty() {
 1643                                zlog::trace!(
 1644                                    logger =>
 1645                                    "No changes for code action. Skipping {}",
 1646                                    describe_code_action(&action),
 1647                                );
 1648                                continue;
 1649                            }
 1650                            for operation in operations {
 1651                                let op = match operation {
 1652                                    lsp::DocumentChangeOperation::Edit(op) => op,
 1653                                    lsp::DocumentChangeOperation::Op(_) => {
 1654                                        zlog::warn!(
 1655                                            logger =>
 1656                                            "Code actions which create, delete, or rename files are not supported on format. Skipping {}",
 1657                                            describe_code_action(&action),
 1658                                        );
 1659                                        continue 'actions;
 1660                                    }
 1661                                };
 1662                                let Ok(file_path) = op.text_document.uri.to_file_path() else {
 1663                                    zlog::warn!(
 1664                                        logger =>
 1665                                        "Failed to convert URI '{:?}' to file path. Skipping {}",
 1666                                        &op.text_document.uri,
 1667                                        describe_code_action(&action),
 1668                                    );
 1669                                    continue 'actions;
 1670                                };
 1671                                if &file_path != buffer_path_abs {
 1672                                    zlog::warn!(
 1673                                        logger =>
 1674                                        "File path '{:?}' does not match buffer path '{:?}'. Skipping {}",
 1675                                        file_path,
 1676                                        buffer_path_abs,
 1677                                        describe_code_action(&action),
 1678                                    );
 1679                                    continue 'actions;
 1680                                }
 1681
 1682                                let mut lsp_edits = Vec::new();
 1683                                for edit in op.edits {
 1684                                    match edit {
 1685                                        Edit::Plain(edit) => {
 1686                                            if !lsp_edits.contains(&edit) {
 1687                                                lsp_edits.push(edit);
 1688                                            }
 1689                                        }
 1690                                        Edit::Annotated(edit) => {
 1691                                            if !lsp_edits.contains(&edit.text_edit) {
 1692                                                lsp_edits.push(edit.text_edit);
 1693                                            }
 1694                                        }
 1695                                        Edit::Snippet(_) => {
 1696                                            zlog::warn!(
 1697                                                logger =>
 1698                                                "Code actions which produce snippet edits are not supported during formatting. Skipping {}",
 1699                                                describe_code_action(&action),
 1700                                            );
 1701                                            continue 'actions;
 1702                                        }
 1703                                    }
 1704                                }
 1705                                let edits_result = lsp_store
 1706                                    .update(cx, |lsp_store, cx| {
 1707                                        lsp_store.as_local_mut().unwrap().edits_from_lsp(
 1708                                            &buffer.handle,
 1709                                            lsp_edits,
 1710                                            server.server_id(),
 1711                                            op.text_document.version,
 1712                                            cx,
 1713                                        )
 1714                                    })?
 1715                                    .await;
 1716                                let Ok(resolved_edits) = edits_result else {
 1717                                    zlog::warn!(
 1718                                        logger =>
 1719                                        "Failed to resolve edits from LSP for buffer {:?} while handling {}",
 1720                                        buffer_path_abs.as_path(),
 1721                                        describe_code_action(&action),
 1722                                    );
 1723                                    continue 'actions;
 1724                                };
 1725                                edits.extend(resolved_edits);
 1726                            }
 1727
 1728                            if edits.is_empty() {
 1729                                zlog::warn!(logger => "No edits resolved from LSP");
 1730                                continue;
 1731                            }
 1732
 1733                            extend_formatting_transaction(
 1734                                buffer,
 1735                                formatting_transaction_id,
 1736                                cx,
 1737                                |buffer, cx| {
 1738                                    buffer.edit(edits, None, cx);
 1739                                },
 1740                            )?;
 1741                        }
 1742
 1743                        if let Some(command) = action.lsp_action.command() {
 1744                            zlog::warn!(
 1745                                logger =>
 1746                                "Executing code action command '{}'. This may cause formatting to abort unnecessarily as well as splitting formatting into two entries in the undo history",
 1747                                &command.command,
 1748                            );
 1749
 1750                            // bail early if command is invalid
 1751                            let server_capabilities = server.capabilities();
 1752                            let available_commands = server_capabilities
 1753                                .execute_command_provider
 1754                                .as_ref()
 1755                                .map(|options| options.commands.as_slice())
 1756                                .unwrap_or_default();
 1757                            if !available_commands.contains(&command.command) {
 1758                                zlog::warn!(
 1759                                    logger =>
 1760                                    "Cannot execute a command {} not listed in the language server capabilities of server {}",
 1761                                    command.command,
 1762                                    server.name(),
 1763                                );
 1764                                continue;
 1765                            }
 1766
 1767                            // noop so we just ensure buffer hasn't been edited since resolving code actions
 1768                            extend_formatting_transaction(
 1769                                buffer,
 1770                                formatting_transaction_id,
 1771                                cx,
 1772                                |_, _| {},
 1773                            )?;
 1774                            zlog::info!(logger => "Executing command {}", &command.command);
 1775
 1776                            lsp_store.update(cx, |this, _| {
 1777                                this.as_local_mut()
 1778                                    .unwrap()
 1779                                    .last_workspace_edits_by_language_server
 1780                                    .remove(&server.server_id());
 1781                            })?;
 1782
 1783                            let execute_command_result = server
 1784                                .request::<lsp::request::ExecuteCommand>(
 1785                                    lsp::ExecuteCommandParams {
 1786                                        command: command.command.clone(),
 1787                                        arguments: command.arguments.clone().unwrap_or_default(),
 1788                                        ..Default::default()
 1789                                    },
 1790                                )
 1791                                .await
 1792                                .into_response();
 1793
 1794                            if execute_command_result.is_err() {
 1795                                zlog::error!(
 1796                                    logger =>
 1797                                    "Failed to execute command '{}' as part of {}",
 1798                                    &command.command,
 1799                                    describe_code_action(&action),
 1800                                );
 1801                                continue 'actions;
 1802                            }
 1803
 1804                            let mut project_transaction_command =
 1805                                lsp_store.update(cx, |this, _| {
 1806                                    this.as_local_mut()
 1807                                        .unwrap()
 1808                                        .last_workspace_edits_by_language_server
 1809                                        .remove(&server.server_id())
 1810                                        .unwrap_or_default()
 1811                                })?;
 1812
 1813                            if let Some(transaction) =
 1814                                project_transaction_command.0.remove(&buffer.handle)
 1815                            {
 1816                                zlog::trace!(
 1817                                    logger =>
 1818                                    "Successfully captured {} edits that resulted from command {}",
 1819                                    transaction.edit_ids.len(),
 1820                                    &command.command,
 1821                                );
 1822                                let transaction_id_project_transaction = transaction.id;
 1823                                buffer.handle.update(cx, |buffer, _| {
 1824                                    // it may have been removed from history if push_to_history was
 1825                                    // false in deserialize_workspace_edit. If so push it so we
 1826                                    // can merge it with the format transaction
 1827                                    // and pop the combined transaction off the history stack
 1828                                    // later if push_to_history is false
 1829                                    if buffer.get_transaction(transaction.id).is_none() {
 1830                                        buffer.push_transaction(transaction, Instant::now());
 1831                                    }
 1832                                    buffer.merge_transactions(
 1833                                        transaction_id_project_transaction,
 1834                                        formatting_transaction_id,
 1835                                    );
 1836                                })?;
 1837                            }
 1838
 1839                            if !project_transaction_command.0.is_empty() {
 1840                                let extra_buffers = project_transaction_command
 1841                                    .0
 1842                                    .keys()
 1843                                    .filter_map(|buffer_handle| {
 1844                                        buffer_handle
 1845                                            .read_with(cx, |b, cx| b.project_path(cx))
 1846                                            .ok()
 1847                                            .flatten()
 1848                                    })
 1849                                    .map(|p| p.path.to_sanitized_string())
 1850                                    .join(", ");
 1851                                zlog::warn!(
 1852                                    logger =>
 1853                                    "Unexpected edits to buffers other than the buffer actively being formatted due to command {}. Impacted buffers: [{}].",
 1854                                    &command.command,
 1855                                    extra_buffers,
 1856                                );
 1857                                // NOTE: if this case is hit, the proper thing to do is to for each buffer, merge the extra transaction
 1858                                // into the existing transaction in project_transaction if there is one, and if there isn't one in project_transaction,
 1859                                // add it so it's included, and merge it into the format transaction when its created later
 1860                            }
 1861                        }
 1862                    }
 1863                }
 1864            }
 1865        }
 1866
 1867        Ok(())
 1868    }
 1869
 1870    pub async fn format_ranges_via_lsp(
 1871        this: &WeakEntity<LspStore>,
 1872        buffer_handle: &Entity<Buffer>,
 1873        ranges: &[Range<Anchor>],
 1874        abs_path: &Path,
 1875        language_server: &Arc<LanguageServer>,
 1876        settings: &LanguageSettings,
 1877        cx: &mut AsyncApp,
 1878    ) -> Result<Vec<(Range<Anchor>, Arc<str>)>> {
 1879        let capabilities = &language_server.capabilities();
 1880        let range_formatting_provider = capabilities.document_range_formatting_provider.as_ref();
 1881        if range_formatting_provider == Some(&OneOf::Left(false)) {
 1882            anyhow::bail!(
 1883                "{} language server does not support range formatting",
 1884                language_server.name()
 1885            );
 1886        }
 1887
 1888        let uri = file_path_to_lsp_url(abs_path)?;
 1889        let text_document = lsp::TextDocumentIdentifier::new(uri);
 1890
 1891        let lsp_edits = {
 1892            let mut lsp_ranges = Vec::new();
 1893            this.update(cx, |_this, cx| {
 1894                // TODO(#22930): In the case of formatting multibuffer selections, this buffer may
 1895                // not have been sent to the language server. This seems like a fairly systemic
 1896                // issue, though, the resolution probably is not specific to formatting.
 1897                //
 1898                // TODO: Instead of using current snapshot, should use the latest snapshot sent to
 1899                // LSP.
 1900                let snapshot = buffer_handle.read(cx).snapshot();
 1901                for range in ranges {
 1902                    lsp_ranges.push(range_to_lsp(range.to_point_utf16(&snapshot))?);
 1903                }
 1904                anyhow::Ok(())
 1905            })??;
 1906
 1907            let mut edits = None;
 1908            for range in lsp_ranges {
 1909                if let Some(mut edit) = language_server
 1910                    .request::<lsp::request::RangeFormatting>(lsp::DocumentRangeFormattingParams {
 1911                        text_document: text_document.clone(),
 1912                        range,
 1913                        options: lsp_command::lsp_formatting_options(settings),
 1914                        work_done_progress_params: Default::default(),
 1915                    })
 1916                    .await
 1917                    .into_response()?
 1918                {
 1919                    edits.get_or_insert_with(Vec::new).append(&mut edit);
 1920                }
 1921            }
 1922            edits
 1923        };
 1924
 1925        if let Some(lsp_edits) = lsp_edits {
 1926            this.update(cx, |this, cx| {
 1927                this.as_local_mut().unwrap().edits_from_lsp(
 1928                    buffer_handle,
 1929                    lsp_edits,
 1930                    language_server.server_id(),
 1931                    None,
 1932                    cx,
 1933                )
 1934            })?
 1935            .await
 1936        } else {
 1937            Ok(Vec::with_capacity(0))
 1938        }
 1939    }
 1940
 1941    async fn format_via_lsp(
 1942        this: &WeakEntity<LspStore>,
 1943        buffer: &Entity<Buffer>,
 1944        abs_path: &Path,
 1945        language_server: &Arc<LanguageServer>,
 1946        settings: &LanguageSettings,
 1947        cx: &mut AsyncApp,
 1948    ) -> Result<Vec<(Range<Anchor>, Arc<str>)>> {
 1949        let logger = zlog::scoped!("lsp_format");
 1950        zlog::info!(logger => "Formatting via LSP");
 1951
 1952        let uri = file_path_to_lsp_url(abs_path)?;
 1953        let text_document = lsp::TextDocumentIdentifier::new(uri);
 1954        let capabilities = &language_server.capabilities();
 1955
 1956        let formatting_provider = capabilities.document_formatting_provider.as_ref();
 1957        let range_formatting_provider = capabilities.document_range_formatting_provider.as_ref();
 1958
 1959        let lsp_edits = if matches!(formatting_provider, Some(p) if *p != OneOf::Left(false)) {
 1960            let _timer = zlog::time!(logger => "format-full");
 1961            language_server
 1962                .request::<lsp::request::Formatting>(lsp::DocumentFormattingParams {
 1963                    text_document,
 1964                    options: lsp_command::lsp_formatting_options(settings),
 1965                    work_done_progress_params: Default::default(),
 1966                })
 1967                .await
 1968                .into_response()?
 1969        } else if matches!(range_formatting_provider, Some(p) if *p != OneOf::Left(false)) {
 1970            let _timer = zlog::time!(logger => "format-range");
 1971            let buffer_start = lsp::Position::new(0, 0);
 1972            let buffer_end = buffer.read_with(cx, |b, _| point_to_lsp(b.max_point_utf16()))?;
 1973            language_server
 1974                .request::<lsp::request::RangeFormatting>(lsp::DocumentRangeFormattingParams {
 1975                    text_document: text_document.clone(),
 1976                    range: lsp::Range::new(buffer_start, buffer_end),
 1977                    options: lsp_command::lsp_formatting_options(settings),
 1978                    work_done_progress_params: Default::default(),
 1979                })
 1980                .await
 1981                .into_response()?
 1982        } else {
 1983            None
 1984        };
 1985
 1986        if let Some(lsp_edits) = lsp_edits {
 1987            this.update(cx, |this, cx| {
 1988                this.as_local_mut().unwrap().edits_from_lsp(
 1989                    buffer,
 1990                    lsp_edits,
 1991                    language_server.server_id(),
 1992                    None,
 1993                    cx,
 1994                )
 1995            })?
 1996            .await
 1997        } else {
 1998            Ok(Vec::with_capacity(0))
 1999        }
 2000    }
 2001
 2002    async fn format_via_external_command(
 2003        buffer: &FormattableBuffer,
 2004        command: &str,
 2005        arguments: Option<&[String]>,
 2006        cx: &mut AsyncApp,
 2007    ) -> Result<Option<Diff>> {
 2008        let working_dir_path = buffer.handle.update(cx, |buffer, cx| {
 2009            let file = File::from_dyn(buffer.file())?;
 2010            let worktree = file.worktree.read(cx);
 2011            let mut worktree_path = worktree.abs_path().to_path_buf();
 2012            if worktree.root_entry()?.is_file() {
 2013                worktree_path.pop();
 2014            }
 2015            Some(worktree_path)
 2016        })?;
 2017
 2018        let mut child = util::command::new_smol_command(command);
 2019
 2020        if let Some(buffer_env) = buffer.env.as_ref() {
 2021            child.envs(buffer_env);
 2022        }
 2023
 2024        if let Some(working_dir_path) = working_dir_path {
 2025            child.current_dir(working_dir_path);
 2026        }
 2027
 2028        if let Some(arguments) = arguments {
 2029            child.args(arguments.iter().map(|arg| {
 2030                if let Some(buffer_abs_path) = buffer.abs_path.as_ref() {
 2031                    arg.replace("{buffer_path}", &buffer_abs_path.to_string_lossy())
 2032                } else {
 2033                    arg.replace("{buffer_path}", "Untitled")
 2034                }
 2035            }));
 2036        }
 2037
 2038        let mut child = child
 2039            .stdin(smol::process::Stdio::piped())
 2040            .stdout(smol::process::Stdio::piped())
 2041            .stderr(smol::process::Stdio::piped())
 2042            .spawn()?;
 2043
 2044        let stdin = child.stdin.as_mut().context("failed to acquire stdin")?;
 2045        let text = buffer
 2046            .handle
 2047            .read_with(cx, |buffer, _| buffer.as_rope().clone())?;
 2048        for chunk in text.chunks() {
 2049            stdin.write_all(chunk.as_bytes()).await?;
 2050        }
 2051        stdin.flush().await?;
 2052
 2053        let output = child.output().await?;
 2054        anyhow::ensure!(
 2055            output.status.success(),
 2056            "command failed with exit code {:?}:\nstdout: {}\nstderr: {}",
 2057            output.status.code(),
 2058            String::from_utf8_lossy(&output.stdout),
 2059            String::from_utf8_lossy(&output.stderr),
 2060        );
 2061
 2062        let stdout = String::from_utf8(output.stdout)?;
 2063        Ok(Some(
 2064            buffer
 2065                .handle
 2066                .update(cx, |buffer, cx| buffer.diff(stdout, cx))?
 2067                .await,
 2068        ))
 2069    }
 2070
 2071    async fn try_resolve_code_action(
 2072        lang_server: &LanguageServer,
 2073        action: &mut CodeAction,
 2074    ) -> anyhow::Result<()> {
 2075        match &mut action.lsp_action {
 2076            LspAction::Action(lsp_action) => {
 2077                if !action.resolved
 2078                    && GetCodeActions::can_resolve_actions(&lang_server.capabilities())
 2079                    && lsp_action.data.is_some()
 2080                    && (lsp_action.command.is_none() || lsp_action.edit.is_none())
 2081                {
 2082                    *lsp_action = Box::new(
 2083                        lang_server
 2084                            .request::<lsp::request::CodeActionResolveRequest>(*lsp_action.clone())
 2085                            .await
 2086                            .into_response()?,
 2087                    );
 2088                }
 2089            }
 2090            LspAction::CodeLens(lens) => {
 2091                if !action.resolved && GetCodeLens::can_resolve_lens(&lang_server.capabilities()) {
 2092                    *lens = lang_server
 2093                        .request::<lsp::request::CodeLensResolve>(lens.clone())
 2094                        .await
 2095                        .into_response()?;
 2096                }
 2097            }
 2098            LspAction::Command(_) => {}
 2099        }
 2100
 2101        action.resolved = true;
 2102        anyhow::Ok(())
 2103    }
 2104
 2105    fn initialize_buffer(&mut self, buffer_handle: &Entity<Buffer>, cx: &mut Context<LspStore>) {
 2106        let buffer = buffer_handle.read(cx);
 2107
 2108        let file = buffer.file().cloned();
 2109
 2110        let Some(file) = File::from_dyn(file.as_ref()) else {
 2111            return;
 2112        };
 2113        if !file.is_local() {
 2114            return;
 2115        }
 2116        let path = ProjectPath::from_file(file, cx);
 2117        let worktree_id = file.worktree_id(cx);
 2118        let language = buffer.language().cloned();
 2119
 2120        if let Some(diagnostics) = self.diagnostics.get(&worktree_id) {
 2121            for (server_id, diagnostics) in
 2122                diagnostics.get(file.path()).cloned().unwrap_or_default()
 2123            {
 2124                self.update_buffer_diagnostics(
 2125                    buffer_handle,
 2126                    server_id,
 2127                    None,
 2128                    None,
 2129                    diagnostics,
 2130                    Vec::new(),
 2131                    cx,
 2132                )
 2133                .log_err();
 2134            }
 2135        }
 2136        let Some(language) = language else {
 2137            return;
 2138        };
 2139        let Some(snapshot) = self
 2140            .worktree_store
 2141            .read(cx)
 2142            .worktree_for_id(worktree_id, cx)
 2143            .map(|worktree| worktree.read(cx).snapshot())
 2144        else {
 2145            return;
 2146        };
 2147        let delegate: Arc<dyn ManifestDelegate> = Arc::new(ManifestQueryDelegate::new(snapshot));
 2148
 2149        for server_id in
 2150            self.lsp_tree
 2151                .get(path, language.name(), language.manifest(), &delegate, cx)
 2152        {
 2153            let server = self
 2154                .language_servers
 2155                .get(&server_id)
 2156                .and_then(|server_state| {
 2157                    if let LanguageServerState::Running { server, .. } = server_state {
 2158                        Some(server.clone())
 2159                    } else {
 2160                        None
 2161                    }
 2162                });
 2163            let server = match server {
 2164                Some(server) => server,
 2165                None => continue,
 2166            };
 2167
 2168            buffer_handle.update(cx, |buffer, cx| {
 2169                buffer.set_completion_triggers(
 2170                    server.server_id(),
 2171                    server
 2172                        .capabilities()
 2173                        .completion_provider
 2174                        .as_ref()
 2175                        .and_then(|provider| {
 2176                            provider
 2177                                .trigger_characters
 2178                                .as_ref()
 2179                                .map(|characters| characters.iter().cloned().collect())
 2180                        })
 2181                        .unwrap_or_default(),
 2182                    cx,
 2183                );
 2184            });
 2185        }
 2186    }
 2187
 2188    pub(crate) fn reset_buffer(&mut self, buffer: &Entity<Buffer>, old_file: &File, cx: &mut App) {
 2189        buffer.update(cx, |buffer, cx| {
 2190            let Some(language) = buffer.language() else {
 2191                return;
 2192            };
 2193            let path = ProjectPath {
 2194                worktree_id: old_file.worktree_id(cx),
 2195                path: old_file.path.clone(),
 2196            };
 2197            for server_id in self.language_server_ids_for_project_path(path, language, cx) {
 2198                buffer.update_diagnostics(server_id, DiagnosticSet::new([], buffer), cx);
 2199                buffer.set_completion_triggers(server_id, Default::default(), cx);
 2200            }
 2201        });
 2202    }
 2203
 2204    fn update_buffer_diagnostics(
 2205        &mut self,
 2206        buffer: &Entity<Buffer>,
 2207        server_id: LanguageServerId,
 2208        result_id: Option<String>,
 2209        version: Option<i32>,
 2210        new_diagnostics: Vec<DiagnosticEntry<Unclipped<PointUtf16>>>,
 2211        reused_diagnostics: Vec<DiagnosticEntry<Unclipped<PointUtf16>>>,
 2212        cx: &mut Context<LspStore>,
 2213    ) -> Result<()> {
 2214        fn compare_diagnostics(a: &Diagnostic, b: &Diagnostic) -> Ordering {
 2215            Ordering::Equal
 2216                .then_with(|| b.is_primary.cmp(&a.is_primary))
 2217                .then_with(|| a.is_disk_based.cmp(&b.is_disk_based))
 2218                .then_with(|| a.severity.cmp(&b.severity))
 2219                .then_with(|| a.message.cmp(&b.message))
 2220        }
 2221
 2222        let mut diagnostics = Vec::with_capacity(new_diagnostics.len() + reused_diagnostics.len());
 2223        diagnostics.extend(new_diagnostics.into_iter().map(|d| (true, d)));
 2224        diagnostics.extend(reused_diagnostics.into_iter().map(|d| (false, d)));
 2225
 2226        diagnostics.sort_unstable_by(|(_, a), (_, b)| {
 2227            Ordering::Equal
 2228                .then_with(|| a.range.start.cmp(&b.range.start))
 2229                .then_with(|| b.range.end.cmp(&a.range.end))
 2230                .then_with(|| compare_diagnostics(&a.diagnostic, &b.diagnostic))
 2231        });
 2232
 2233        let snapshot = self.buffer_snapshot_for_lsp_version(buffer, server_id, version, cx)?;
 2234
 2235        let edits_since_save = std::cell::LazyCell::new(|| {
 2236            let saved_version = buffer.read(cx).saved_version();
 2237            Patch::new(snapshot.edits_since::<PointUtf16>(saved_version).collect())
 2238        });
 2239
 2240        let mut sanitized_diagnostics = Vec::with_capacity(diagnostics.len());
 2241
 2242        for (new_diagnostic, entry) in diagnostics {
 2243            let start;
 2244            let end;
 2245            if new_diagnostic && entry.diagnostic.is_disk_based {
 2246                // Some diagnostics are based on files on disk instead of buffers'
 2247                // current contents. Adjust these diagnostics' ranges to reflect
 2248                // any unsaved edits.
 2249                // Do not alter the reused ones though, as their coordinates were stored as anchors
 2250                // and were properly adjusted on reuse.
 2251                start = Unclipped((*edits_since_save).old_to_new(entry.range.start.0));
 2252                end = Unclipped((*edits_since_save).old_to_new(entry.range.end.0));
 2253            } else {
 2254                start = entry.range.start;
 2255                end = entry.range.end;
 2256            }
 2257
 2258            let mut range = snapshot.clip_point_utf16(start, Bias::Left)
 2259                ..snapshot.clip_point_utf16(end, Bias::Right);
 2260
 2261            // Expand empty ranges by one codepoint
 2262            if range.start == range.end {
 2263                // This will be go to the next boundary when being clipped
 2264                range.end.column += 1;
 2265                range.end = snapshot.clip_point_utf16(Unclipped(range.end), Bias::Right);
 2266                if range.start == range.end && range.end.column > 0 {
 2267                    range.start.column -= 1;
 2268                    range.start = snapshot.clip_point_utf16(Unclipped(range.start), Bias::Left);
 2269                }
 2270            }
 2271
 2272            sanitized_diagnostics.push(DiagnosticEntry {
 2273                range,
 2274                diagnostic: entry.diagnostic,
 2275            });
 2276        }
 2277        drop(edits_since_save);
 2278
 2279        let set = DiagnosticSet::new(sanitized_diagnostics, &snapshot);
 2280        buffer.update(cx, |buffer, cx| {
 2281            if let Some(abs_path) = File::from_dyn(buffer.file()).map(|f| f.abs_path(cx)) {
 2282                self.buffer_pull_diagnostics_result_ids
 2283                    .entry(server_id)
 2284                    .or_default()
 2285                    .insert(abs_path, result_id);
 2286            }
 2287
 2288            buffer.update_diagnostics(server_id, set, cx)
 2289        });
 2290
 2291        Ok(())
 2292    }
 2293
 2294    fn register_language_server_for_invisible_worktree(
 2295        &mut self,
 2296        worktree: &Entity<Worktree>,
 2297        language_server_id: LanguageServerId,
 2298        cx: &mut App,
 2299    ) {
 2300        let worktree = worktree.read(cx);
 2301        let worktree_id = worktree.id();
 2302        debug_assert!(!worktree.is_visible());
 2303        let Some(mut origin_seed) = self
 2304            .language_server_ids
 2305            .iter()
 2306            .find_map(|(seed, state)| (state.id == language_server_id).then(|| seed.clone()))
 2307        else {
 2308            return;
 2309        };
 2310        origin_seed.worktree_id = worktree_id;
 2311        self.language_server_ids
 2312            .entry(origin_seed)
 2313            .or_insert_with(|| UnifiedLanguageServer {
 2314                id: language_server_id,
 2315                project_roots: Default::default(),
 2316            });
 2317    }
 2318
 2319    fn register_buffer_with_language_servers(
 2320        &mut self,
 2321        buffer_handle: &Entity<Buffer>,
 2322        only_register_servers: HashSet<LanguageServerSelector>,
 2323        cx: &mut Context<LspStore>,
 2324    ) {
 2325        let buffer = buffer_handle.read(cx);
 2326        let buffer_id = buffer.remote_id();
 2327
 2328        let Some(file) = File::from_dyn(buffer.file()) else {
 2329            return;
 2330        };
 2331        if !file.is_local() {
 2332            return;
 2333        }
 2334
 2335        let abs_path = file.abs_path(cx);
 2336        let Some(uri) = file_path_to_lsp_url(&abs_path).log_err() else {
 2337            return;
 2338        };
 2339        let initial_snapshot = buffer.text_snapshot();
 2340        let worktree_id = file.worktree_id(cx);
 2341
 2342        let Some(language) = buffer.language().cloned() else {
 2343            return;
 2344        };
 2345        let path: Arc<Path> = file
 2346            .path()
 2347            .parent()
 2348            .map(Arc::from)
 2349            .unwrap_or_else(|| file.path().clone());
 2350        let Some(worktree) = self
 2351            .worktree_store
 2352            .read(cx)
 2353            .worktree_for_id(worktree_id, cx)
 2354        else {
 2355            return;
 2356        };
 2357        let language_name = language.name();
 2358        let (reused, delegate, servers) = self
 2359            .reuse_existing_language_server(&self.lsp_tree, &worktree, &language_name, cx)
 2360            .map(|(delegate, apply)| (true, delegate, apply(&mut self.lsp_tree)))
 2361            .unwrap_or_else(|| {
 2362                let lsp_delegate = LocalLspAdapterDelegate::from_local_lsp(self, &worktree, cx);
 2363                let delegate: Arc<dyn ManifestDelegate> =
 2364                    Arc::new(ManifestQueryDelegate::new(worktree.read(cx).snapshot()));
 2365
 2366                let servers = self
 2367                    .lsp_tree
 2368                    .walk(
 2369                        ProjectPath { worktree_id, path },
 2370                        language.name(),
 2371                        language.manifest(),
 2372                        &delegate,
 2373                        cx,
 2374                    )
 2375                    .collect::<Vec<_>>();
 2376                (false, lsp_delegate, servers)
 2377            });
 2378        let servers_and_adapters = servers
 2379            .into_iter()
 2380            .filter_map(|server_node| {
 2381                if reused && server_node.server_id().is_none() {
 2382                    return None;
 2383                }
 2384                if !only_register_servers.is_empty() {
 2385                    if let Some(server_id) = server_node.server_id()
 2386                        && !only_register_servers.contains(&LanguageServerSelector::Id(server_id))
 2387                    {
 2388                        return None;
 2389                    }
 2390                    if let Some(name) = server_node.name()
 2391                        && !only_register_servers.contains(&LanguageServerSelector::Name(name))
 2392                    {
 2393                        return None;
 2394                    }
 2395                }
 2396
 2397                let server_id = server_node.server_id_or_init(|disposition| {
 2398                    let path = &disposition.path;
 2399
 2400                    {
 2401                        let uri =
 2402                            Url::from_file_path(worktree.read(cx).abs_path().join(&path.path));
 2403
 2404                        let server_id = self.get_or_insert_language_server(
 2405                            &worktree,
 2406                            delegate.clone(),
 2407                            disposition,
 2408                            &language_name,
 2409                            cx,
 2410                        );
 2411
 2412                        if let Some(state) = self.language_servers.get(&server_id)
 2413                            && let Ok(uri) = uri
 2414                        {
 2415                            state.add_workspace_folder(uri);
 2416                        };
 2417                        server_id
 2418                    }
 2419                })?;
 2420                let server_state = self.language_servers.get(&server_id)?;
 2421                if let LanguageServerState::Running {
 2422                    server, adapter, ..
 2423                } = server_state
 2424                {
 2425                    Some((server.clone(), adapter.clone()))
 2426                } else {
 2427                    None
 2428                }
 2429            })
 2430            .collect::<Vec<_>>();
 2431        for (server, adapter) in servers_and_adapters {
 2432            buffer_handle.update(cx, |buffer, cx| {
 2433                buffer.set_completion_triggers(
 2434                    server.server_id(),
 2435                    server
 2436                        .capabilities()
 2437                        .completion_provider
 2438                        .as_ref()
 2439                        .and_then(|provider| {
 2440                            provider
 2441                                .trigger_characters
 2442                                .as_ref()
 2443                                .map(|characters| characters.iter().cloned().collect())
 2444                        })
 2445                        .unwrap_or_default(),
 2446                    cx,
 2447                );
 2448            });
 2449
 2450            let snapshot = LspBufferSnapshot {
 2451                version: 0,
 2452                snapshot: initial_snapshot.clone(),
 2453            };
 2454
 2455            let mut registered = false;
 2456            self.buffer_snapshots
 2457                .entry(buffer_id)
 2458                .or_default()
 2459                .entry(server.server_id())
 2460                .or_insert_with(|| {
 2461                    registered = true;
 2462                    server.register_buffer(
 2463                        uri.clone(),
 2464                        adapter.language_id(&language.name()),
 2465                        0,
 2466                        initial_snapshot.text(),
 2467                    );
 2468
 2469                    vec![snapshot]
 2470                });
 2471
 2472            self.buffers_opened_in_servers
 2473                .entry(buffer_id)
 2474                .or_default()
 2475                .insert(server.server_id());
 2476            if registered {
 2477                cx.emit(LspStoreEvent::LanguageServerUpdate {
 2478                    language_server_id: server.server_id(),
 2479                    name: None,
 2480                    message: proto::update_language_server::Variant::RegisteredForBuffer(
 2481                        proto::RegisteredForBuffer {
 2482                            buffer_abs_path: abs_path.to_string_lossy().to_string(),
 2483                            buffer_id: buffer_id.to_proto(),
 2484                        },
 2485                    ),
 2486                });
 2487            }
 2488        }
 2489    }
 2490
 2491    fn reuse_existing_language_server<'lang_name>(
 2492        &self,
 2493        server_tree: &LanguageServerTree,
 2494        worktree: &Entity<Worktree>,
 2495        language_name: &'lang_name LanguageName,
 2496        cx: &mut App,
 2497    ) -> Option<(
 2498        Arc<LocalLspAdapterDelegate>,
 2499        impl FnOnce(&mut LanguageServerTree) -> Vec<LanguageServerTreeNode> + use<'lang_name>,
 2500    )> {
 2501        if worktree.read(cx).is_visible() {
 2502            return None;
 2503        }
 2504
 2505        let worktree_store = self.worktree_store.read(cx);
 2506        let servers = server_tree
 2507            .instances
 2508            .iter()
 2509            .filter(|(worktree_id, _)| {
 2510                worktree_store
 2511                    .worktree_for_id(**worktree_id, cx)
 2512                    .is_some_and(|worktree| worktree.read(cx).is_visible())
 2513            })
 2514            .flat_map(|(worktree_id, servers)| {
 2515                servers
 2516                    .roots
 2517                    .iter()
 2518                    .flat_map(|(_, language_servers)| language_servers)
 2519                    .map(move |(_, (server_node, server_languages))| {
 2520                        (worktree_id, server_node, server_languages)
 2521                    })
 2522                    .filter(|(_, _, server_languages)| server_languages.contains(language_name))
 2523                    .map(|(worktree_id, server_node, _)| {
 2524                        (
 2525                            *worktree_id,
 2526                            LanguageServerTreeNode::from(Arc::downgrade(server_node)),
 2527                        )
 2528                    })
 2529            })
 2530            .fold(HashMap::default(), |mut acc, (worktree_id, server_node)| {
 2531                acc.entry(worktree_id)
 2532                    .or_insert_with(Vec::new)
 2533                    .push(server_node);
 2534                acc
 2535            })
 2536            .into_values()
 2537            .max_by_key(|servers| servers.len())?;
 2538
 2539        let worktree_id = worktree.read(cx).id();
 2540        let apply = move |tree: &mut LanguageServerTree| {
 2541            for server_node in &servers {
 2542                tree.register_reused(worktree_id, language_name.clone(), server_node.clone());
 2543            }
 2544            servers
 2545        };
 2546
 2547        let delegate = LocalLspAdapterDelegate::from_local_lsp(self, worktree, cx);
 2548        Some((delegate, apply))
 2549    }
 2550
 2551    pub(crate) fn unregister_old_buffer_from_language_servers(
 2552        &mut self,
 2553        buffer: &Entity<Buffer>,
 2554        old_file: &File,
 2555        cx: &mut App,
 2556    ) {
 2557        let old_path = match old_file.as_local() {
 2558            Some(local) => local.abs_path(cx),
 2559            None => return,
 2560        };
 2561
 2562        let Ok(file_url) = lsp::Url::from_file_path(old_path.as_path()) else {
 2563            debug_panic!(
 2564                "`{}` is not parseable as an URI",
 2565                old_path.to_string_lossy()
 2566            );
 2567            return;
 2568        };
 2569        self.unregister_buffer_from_language_servers(buffer, &file_url, cx);
 2570    }
 2571
 2572    pub(crate) fn unregister_buffer_from_language_servers(
 2573        &mut self,
 2574        buffer: &Entity<Buffer>,
 2575        file_url: &lsp::Url,
 2576        cx: &mut App,
 2577    ) {
 2578        buffer.update(cx, |buffer, cx| {
 2579            let _ = self.buffer_snapshots.remove(&buffer.remote_id());
 2580
 2581            for (_, language_server) in self.language_servers_for_buffer(buffer, cx) {
 2582                language_server.unregister_buffer(file_url.clone());
 2583            }
 2584        });
 2585    }
 2586
 2587    fn buffer_snapshot_for_lsp_version(
 2588        &mut self,
 2589        buffer: &Entity<Buffer>,
 2590        server_id: LanguageServerId,
 2591        version: Option<i32>,
 2592        cx: &App,
 2593    ) -> Result<TextBufferSnapshot> {
 2594        const OLD_VERSIONS_TO_RETAIN: i32 = 10;
 2595
 2596        if let Some(version) = version {
 2597            let buffer_id = buffer.read(cx).remote_id();
 2598            let snapshots = if let Some(snapshots) = self
 2599                .buffer_snapshots
 2600                .get_mut(&buffer_id)
 2601                .and_then(|m| m.get_mut(&server_id))
 2602            {
 2603                snapshots
 2604            } else if version == 0 {
 2605                // Some language servers report version 0 even if the buffer hasn't been opened yet.
 2606                // We detect this case and treat it as if the version was `None`.
 2607                return Ok(buffer.read(cx).text_snapshot());
 2608            } else {
 2609                anyhow::bail!("no snapshots found for buffer {buffer_id} and server {server_id}");
 2610            };
 2611
 2612            let found_snapshot = snapshots
 2613                    .binary_search_by_key(&version, |e| e.version)
 2614                    .map(|ix| snapshots[ix].snapshot.clone())
 2615                    .map_err(|_| {
 2616                        anyhow!("snapshot not found for buffer {buffer_id} server {server_id} at version {version}")
 2617                    })?;
 2618
 2619            snapshots.retain(|snapshot| snapshot.version + OLD_VERSIONS_TO_RETAIN >= version);
 2620            Ok(found_snapshot)
 2621        } else {
 2622            Ok((buffer.read(cx)).text_snapshot())
 2623        }
 2624    }
 2625
 2626    async fn get_server_code_actions_from_action_kinds(
 2627        lsp_store: &WeakEntity<LspStore>,
 2628        language_server_id: LanguageServerId,
 2629        code_action_kinds: Vec<lsp::CodeActionKind>,
 2630        buffer: &Entity<Buffer>,
 2631        cx: &mut AsyncApp,
 2632    ) -> Result<Vec<CodeAction>> {
 2633        let actions = lsp_store
 2634            .update(cx, move |this, cx| {
 2635                let request = GetCodeActions {
 2636                    range: text::Anchor::MIN..text::Anchor::MAX,
 2637                    kinds: Some(code_action_kinds),
 2638                };
 2639                let server = LanguageServerToQuery::Other(language_server_id);
 2640                this.request_lsp(buffer.clone(), server, request, cx)
 2641            })?
 2642            .await?;
 2643        Ok(actions)
 2644    }
 2645
 2646    pub async fn execute_code_actions_on_server(
 2647        lsp_store: &WeakEntity<LspStore>,
 2648        language_server: &Arc<LanguageServer>,
 2649
 2650        actions: Vec<CodeAction>,
 2651        push_to_history: bool,
 2652        project_transaction: &mut ProjectTransaction,
 2653        cx: &mut AsyncApp,
 2654    ) -> anyhow::Result<()> {
 2655        for mut action in actions {
 2656            Self::try_resolve_code_action(language_server, &mut action)
 2657                .await
 2658                .context("resolving a formatting code action")?;
 2659
 2660            if let Some(edit) = action.lsp_action.edit() {
 2661                if edit.changes.is_none() && edit.document_changes.is_none() {
 2662                    continue;
 2663                }
 2664
 2665                let new = Self::deserialize_workspace_edit(
 2666                    lsp_store.upgrade().context("project dropped")?,
 2667                    edit.clone(),
 2668                    push_to_history,
 2669                    language_server.clone(),
 2670                    cx,
 2671                )
 2672                .await?;
 2673                project_transaction.0.extend(new.0);
 2674            }
 2675
 2676            if let Some(command) = action.lsp_action.command() {
 2677                let server_capabilities = language_server.capabilities();
 2678                let available_commands = server_capabilities
 2679                    .execute_command_provider
 2680                    .as_ref()
 2681                    .map(|options| options.commands.as_slice())
 2682                    .unwrap_or_default();
 2683                if available_commands.contains(&command.command) {
 2684                    lsp_store.update(cx, |lsp_store, _| {
 2685                        if let LspStoreMode::Local(mode) = &mut lsp_store.mode {
 2686                            mode.last_workspace_edits_by_language_server
 2687                                .remove(&language_server.server_id());
 2688                        }
 2689                    })?;
 2690
 2691                    language_server
 2692                        .request::<lsp::request::ExecuteCommand>(lsp::ExecuteCommandParams {
 2693                            command: command.command.clone(),
 2694                            arguments: command.arguments.clone().unwrap_or_default(),
 2695                            ..Default::default()
 2696                        })
 2697                        .await
 2698                        .into_response()
 2699                        .context("execute command")?;
 2700
 2701                    lsp_store.update(cx, |this, _| {
 2702                        if let LspStoreMode::Local(mode) = &mut this.mode {
 2703                            project_transaction.0.extend(
 2704                                mode.last_workspace_edits_by_language_server
 2705                                    .remove(&language_server.server_id())
 2706                                    .unwrap_or_default()
 2707                                    .0,
 2708                            )
 2709                        }
 2710                    })?;
 2711                } else {
 2712                    log::warn!(
 2713                        "Cannot execute a command {} not listed in the language server capabilities",
 2714                        command.command
 2715                    )
 2716                }
 2717            }
 2718        }
 2719        Ok(())
 2720    }
 2721
 2722    pub async fn deserialize_text_edits(
 2723        this: Entity<LspStore>,
 2724        buffer_to_edit: Entity<Buffer>,
 2725        edits: Vec<lsp::TextEdit>,
 2726        push_to_history: bool,
 2727        _: Arc<CachedLspAdapter>,
 2728        language_server: Arc<LanguageServer>,
 2729        cx: &mut AsyncApp,
 2730    ) -> Result<Option<Transaction>> {
 2731        let edits = this
 2732            .update(cx, |this, cx| {
 2733                this.as_local_mut().unwrap().edits_from_lsp(
 2734                    &buffer_to_edit,
 2735                    edits,
 2736                    language_server.server_id(),
 2737                    None,
 2738                    cx,
 2739                )
 2740            })?
 2741            .await?;
 2742
 2743        let transaction = buffer_to_edit.update(cx, |buffer, cx| {
 2744            buffer.finalize_last_transaction();
 2745            buffer.start_transaction();
 2746            for (range, text) in edits {
 2747                buffer.edit([(range, text)], None, cx);
 2748            }
 2749
 2750            if buffer.end_transaction(cx).is_some() {
 2751                let transaction = buffer.finalize_last_transaction().unwrap().clone();
 2752                if !push_to_history {
 2753                    buffer.forget_transaction(transaction.id);
 2754                }
 2755                Some(transaction)
 2756            } else {
 2757                None
 2758            }
 2759        })?;
 2760
 2761        Ok(transaction)
 2762    }
 2763
 2764    #[allow(clippy::type_complexity)]
 2765    pub(crate) fn edits_from_lsp(
 2766        &mut self,
 2767        buffer: &Entity<Buffer>,
 2768        lsp_edits: impl 'static + Send + IntoIterator<Item = lsp::TextEdit>,
 2769        server_id: LanguageServerId,
 2770        version: Option<i32>,
 2771        cx: &mut Context<LspStore>,
 2772    ) -> Task<Result<Vec<(Range<Anchor>, Arc<str>)>>> {
 2773        let snapshot = self.buffer_snapshot_for_lsp_version(buffer, server_id, version, cx);
 2774        cx.background_spawn(async move {
 2775            let snapshot = snapshot?;
 2776            let mut lsp_edits = lsp_edits
 2777                .into_iter()
 2778                .map(|edit| (range_from_lsp(edit.range), edit.new_text))
 2779                .collect::<Vec<_>>();
 2780
 2781            lsp_edits.sort_by_key(|(range, _)| (range.start, range.end));
 2782
 2783            let mut lsp_edits = lsp_edits.into_iter().peekable();
 2784            let mut edits = Vec::new();
 2785            while let Some((range, mut new_text)) = lsp_edits.next() {
 2786                // Clip invalid ranges provided by the language server.
 2787                let mut range = snapshot.clip_point_utf16(range.start, Bias::Left)
 2788                    ..snapshot.clip_point_utf16(range.end, Bias::Left);
 2789
 2790                // Combine any LSP edits that are adjacent.
 2791                //
 2792                // Also, combine LSP edits that are separated from each other by only
 2793                // a newline. This is important because for some code actions,
 2794                // Rust-analyzer rewrites the entire buffer via a series of edits that
 2795                // are separated by unchanged newline characters.
 2796                //
 2797                // In order for the diffing logic below to work properly, any edits that
 2798                // cancel each other out must be combined into one.
 2799                while let Some((next_range, next_text)) = lsp_edits.peek() {
 2800                    if next_range.start.0 > range.end {
 2801                        if next_range.start.0.row > range.end.row + 1
 2802                            || next_range.start.0.column > 0
 2803                            || snapshot.clip_point_utf16(
 2804                                Unclipped(PointUtf16::new(range.end.row, u32::MAX)),
 2805                                Bias::Left,
 2806                            ) > range.end
 2807                        {
 2808                            break;
 2809                        }
 2810                        new_text.push('\n');
 2811                    }
 2812                    range.end = snapshot.clip_point_utf16(next_range.end, Bias::Left);
 2813                    new_text.push_str(next_text);
 2814                    lsp_edits.next();
 2815                }
 2816
 2817                // For multiline edits, perform a diff of the old and new text so that
 2818                // we can identify the changes more precisely, preserving the locations
 2819                // of any anchors positioned in the unchanged regions.
 2820                if range.end.row > range.start.row {
 2821                    let offset = range.start.to_offset(&snapshot);
 2822                    let old_text = snapshot.text_for_range(range).collect::<String>();
 2823                    let range_edits = language::text_diff(old_text.as_str(), &new_text);
 2824                    edits.extend(range_edits.into_iter().map(|(range, replacement)| {
 2825                        (
 2826                            snapshot.anchor_after(offset + range.start)
 2827                                ..snapshot.anchor_before(offset + range.end),
 2828                            replacement,
 2829                        )
 2830                    }));
 2831                } else if range.end == range.start {
 2832                    let anchor = snapshot.anchor_after(range.start);
 2833                    edits.push((anchor..anchor, new_text.into()));
 2834                } else {
 2835                    let edit_start = snapshot.anchor_after(range.start);
 2836                    let edit_end = snapshot.anchor_before(range.end);
 2837                    edits.push((edit_start..edit_end, new_text.into()));
 2838                }
 2839            }
 2840
 2841            Ok(edits)
 2842        })
 2843    }
 2844
 2845    pub(crate) async fn deserialize_workspace_edit(
 2846        this: Entity<LspStore>,
 2847        edit: lsp::WorkspaceEdit,
 2848        push_to_history: bool,
 2849        language_server: Arc<LanguageServer>,
 2850        cx: &mut AsyncApp,
 2851    ) -> Result<ProjectTransaction> {
 2852        let fs = this.read_with(cx, |this, _| this.as_local().unwrap().fs.clone())?;
 2853
 2854        let mut operations = Vec::new();
 2855        if let Some(document_changes) = edit.document_changes {
 2856            match document_changes {
 2857                lsp::DocumentChanges::Edits(edits) => {
 2858                    operations.extend(edits.into_iter().map(lsp::DocumentChangeOperation::Edit))
 2859                }
 2860                lsp::DocumentChanges::Operations(ops) => operations = ops,
 2861            }
 2862        } else if let Some(changes) = edit.changes {
 2863            operations.extend(changes.into_iter().map(|(uri, edits)| {
 2864                lsp::DocumentChangeOperation::Edit(lsp::TextDocumentEdit {
 2865                    text_document: lsp::OptionalVersionedTextDocumentIdentifier {
 2866                        uri,
 2867                        version: None,
 2868                    },
 2869                    edits: edits.into_iter().map(Edit::Plain).collect(),
 2870                })
 2871            }));
 2872        }
 2873
 2874        let mut project_transaction = ProjectTransaction::default();
 2875        for operation in operations {
 2876            match operation {
 2877                lsp::DocumentChangeOperation::Op(lsp::ResourceOp::Create(op)) => {
 2878                    let abs_path = op
 2879                        .uri
 2880                        .to_file_path()
 2881                        .map_err(|()| anyhow!("can't convert URI to path"))?;
 2882
 2883                    if let Some(parent_path) = abs_path.parent() {
 2884                        fs.create_dir(parent_path).await?;
 2885                    }
 2886                    if abs_path.ends_with("/") {
 2887                        fs.create_dir(&abs_path).await?;
 2888                    } else {
 2889                        fs.create_file(
 2890                            &abs_path,
 2891                            op.options
 2892                                .map(|options| fs::CreateOptions {
 2893                                    overwrite: options.overwrite.unwrap_or(false),
 2894                                    ignore_if_exists: options.ignore_if_exists.unwrap_or(false),
 2895                                })
 2896                                .unwrap_or_default(),
 2897                        )
 2898                        .await?;
 2899                    }
 2900                }
 2901
 2902                lsp::DocumentChangeOperation::Op(lsp::ResourceOp::Rename(op)) => {
 2903                    let source_abs_path = op
 2904                        .old_uri
 2905                        .to_file_path()
 2906                        .map_err(|()| anyhow!("can't convert URI to path"))?;
 2907                    let target_abs_path = op
 2908                        .new_uri
 2909                        .to_file_path()
 2910                        .map_err(|()| anyhow!("can't convert URI to path"))?;
 2911                    fs.rename(
 2912                        &source_abs_path,
 2913                        &target_abs_path,
 2914                        op.options
 2915                            .map(|options| fs::RenameOptions {
 2916                                overwrite: options.overwrite.unwrap_or(false),
 2917                                ignore_if_exists: options.ignore_if_exists.unwrap_or(false),
 2918                            })
 2919                            .unwrap_or_default(),
 2920                    )
 2921                    .await?;
 2922                }
 2923
 2924                lsp::DocumentChangeOperation::Op(lsp::ResourceOp::Delete(op)) => {
 2925                    let abs_path = op
 2926                        .uri
 2927                        .to_file_path()
 2928                        .map_err(|()| anyhow!("can't convert URI to path"))?;
 2929                    let options = op
 2930                        .options
 2931                        .map(|options| fs::RemoveOptions {
 2932                            recursive: options.recursive.unwrap_or(false),
 2933                            ignore_if_not_exists: options.ignore_if_not_exists.unwrap_or(false),
 2934                        })
 2935                        .unwrap_or_default();
 2936                    if abs_path.ends_with("/") {
 2937                        fs.remove_dir(&abs_path, options).await?;
 2938                    } else {
 2939                        fs.remove_file(&abs_path, options).await?;
 2940                    }
 2941                }
 2942
 2943                lsp::DocumentChangeOperation::Edit(op) => {
 2944                    let buffer_to_edit = this
 2945                        .update(cx, |this, cx| {
 2946                            this.open_local_buffer_via_lsp(
 2947                                op.text_document.uri.clone(),
 2948                                language_server.server_id(),
 2949                                cx,
 2950                            )
 2951                        })?
 2952                        .await?;
 2953
 2954                    let edits = this
 2955                        .update(cx, |this, cx| {
 2956                            let path = buffer_to_edit.read(cx).project_path(cx);
 2957                            let active_entry = this.active_entry;
 2958                            let is_active_entry = path.is_some_and(|project_path| {
 2959                                this.worktree_store
 2960                                    .read(cx)
 2961                                    .entry_for_path(&project_path, cx)
 2962                                    .is_some_and(|entry| Some(entry.id) == active_entry)
 2963                            });
 2964                            let local = this.as_local_mut().unwrap();
 2965
 2966                            let (mut edits, mut snippet_edits) = (vec![], vec![]);
 2967                            for edit in op.edits {
 2968                                match edit {
 2969                                    Edit::Plain(edit) => {
 2970                                        if !edits.contains(&edit) {
 2971                                            edits.push(edit)
 2972                                        }
 2973                                    }
 2974                                    Edit::Annotated(edit) => {
 2975                                        if !edits.contains(&edit.text_edit) {
 2976                                            edits.push(edit.text_edit)
 2977                                        }
 2978                                    }
 2979                                    Edit::Snippet(edit) => {
 2980                                        let Ok(snippet) = Snippet::parse(&edit.snippet.value)
 2981                                        else {
 2982                                            continue;
 2983                                        };
 2984
 2985                                        if is_active_entry {
 2986                                            snippet_edits.push((edit.range, snippet));
 2987                                        } else {
 2988                                            // Since this buffer is not focused, apply a normal edit.
 2989                                            let new_edit = TextEdit {
 2990                                                range: edit.range,
 2991                                                new_text: snippet.text,
 2992                                            };
 2993                                            if !edits.contains(&new_edit) {
 2994                                                edits.push(new_edit);
 2995                                            }
 2996                                        }
 2997                                    }
 2998                                }
 2999                            }
 3000                            if !snippet_edits.is_empty() {
 3001                                let buffer_id = buffer_to_edit.read(cx).remote_id();
 3002                                let version = if let Some(buffer_version) = op.text_document.version
 3003                                {
 3004                                    local
 3005                                        .buffer_snapshot_for_lsp_version(
 3006                                            &buffer_to_edit,
 3007                                            language_server.server_id(),
 3008                                            Some(buffer_version),
 3009                                            cx,
 3010                                        )
 3011                                        .ok()
 3012                                        .map(|snapshot| snapshot.version)
 3013                                } else {
 3014                                    Some(buffer_to_edit.read(cx).saved_version().clone())
 3015                                };
 3016
 3017                                let most_recent_edit = version.and_then(|version| {
 3018                                    version.iter().max_by_key(|timestamp| timestamp.value)
 3019                                });
 3020                                // Check if the edit that triggered that edit has been made by this participant.
 3021
 3022                                if let Some(most_recent_edit) = most_recent_edit {
 3023                                    cx.emit(LspStoreEvent::SnippetEdit {
 3024                                        buffer_id,
 3025                                        edits: snippet_edits,
 3026                                        most_recent_edit,
 3027                                    });
 3028                                }
 3029                            }
 3030
 3031                            local.edits_from_lsp(
 3032                                &buffer_to_edit,
 3033                                edits,
 3034                                language_server.server_id(),
 3035                                op.text_document.version,
 3036                                cx,
 3037                            )
 3038                        })?
 3039                        .await?;
 3040
 3041                    let transaction = buffer_to_edit.update(cx, |buffer, cx| {
 3042                        buffer.finalize_last_transaction();
 3043                        buffer.start_transaction();
 3044                        for (range, text) in edits {
 3045                            buffer.edit([(range, text)], None, cx);
 3046                        }
 3047
 3048                        buffer.end_transaction(cx).and_then(|transaction_id| {
 3049                            if push_to_history {
 3050                                buffer.finalize_last_transaction();
 3051                                buffer.get_transaction(transaction_id).cloned()
 3052                            } else {
 3053                                buffer.forget_transaction(transaction_id)
 3054                            }
 3055                        })
 3056                    })?;
 3057                    if let Some(transaction) = transaction {
 3058                        project_transaction.0.insert(buffer_to_edit, transaction);
 3059                    }
 3060                }
 3061            }
 3062        }
 3063
 3064        Ok(project_transaction)
 3065    }
 3066
 3067    async fn on_lsp_workspace_edit(
 3068        this: WeakEntity<LspStore>,
 3069        params: lsp::ApplyWorkspaceEditParams,
 3070        server_id: LanguageServerId,
 3071        cx: &mut AsyncApp,
 3072    ) -> Result<lsp::ApplyWorkspaceEditResponse> {
 3073        let this = this.upgrade().context("project project closed")?;
 3074        let language_server = this
 3075            .read_with(cx, |this, _| this.language_server_for_id(server_id))?
 3076            .context("language server not found")?;
 3077        let transaction = Self::deserialize_workspace_edit(
 3078            this.clone(),
 3079            params.edit,
 3080            true,
 3081            language_server.clone(),
 3082            cx,
 3083        )
 3084        .await
 3085        .log_err();
 3086        this.update(cx, |this, _| {
 3087            if let Some(transaction) = transaction {
 3088                this.as_local_mut()
 3089                    .unwrap()
 3090                    .last_workspace_edits_by_language_server
 3091                    .insert(server_id, transaction);
 3092            }
 3093        })?;
 3094        Ok(lsp::ApplyWorkspaceEditResponse {
 3095            applied: true,
 3096            failed_change: None,
 3097            failure_reason: None,
 3098        })
 3099    }
 3100
 3101    fn remove_worktree(
 3102        &mut self,
 3103        id_to_remove: WorktreeId,
 3104        cx: &mut Context<LspStore>,
 3105    ) -> Vec<LanguageServerId> {
 3106        self.diagnostics.remove(&id_to_remove);
 3107        self.prettier_store.update(cx, |prettier_store, cx| {
 3108            prettier_store.remove_worktree(id_to_remove, cx);
 3109        });
 3110
 3111        let mut servers_to_remove = BTreeSet::default();
 3112        let mut servers_to_preserve = HashSet::default();
 3113        for (seed, state) in &self.language_server_ids {
 3114            if seed.worktree_id == id_to_remove {
 3115                servers_to_remove.insert(state.id);
 3116            } else {
 3117                servers_to_preserve.insert(state.id);
 3118            }
 3119        }
 3120        servers_to_remove.retain(|server_id| !servers_to_preserve.contains(server_id));
 3121        self.language_server_ids
 3122            .retain(|_, state| !servers_to_remove.contains(&state.id));
 3123        for server_id_to_remove in &servers_to_remove {
 3124            self.language_server_watched_paths
 3125                .remove(server_id_to_remove);
 3126            self.language_server_paths_watched_for_rename
 3127                .remove(server_id_to_remove);
 3128            self.last_workspace_edits_by_language_server
 3129                .remove(server_id_to_remove);
 3130            self.language_servers.remove(server_id_to_remove);
 3131            self.buffer_pull_diagnostics_result_ids
 3132                .remove(server_id_to_remove);
 3133            for buffer_servers in self.buffers_opened_in_servers.values_mut() {
 3134                buffer_servers.remove(server_id_to_remove);
 3135            }
 3136            cx.emit(LspStoreEvent::LanguageServerRemoved(*server_id_to_remove));
 3137        }
 3138        servers_to_remove.into_iter().collect()
 3139    }
 3140
 3141    fn rebuild_watched_paths_inner<'a>(
 3142        &'a self,
 3143        language_server_id: LanguageServerId,
 3144        watchers: impl Iterator<Item = &'a FileSystemWatcher>,
 3145        cx: &mut Context<LspStore>,
 3146    ) -> LanguageServerWatchedPathsBuilder {
 3147        let worktrees = self
 3148            .worktree_store
 3149            .read(cx)
 3150            .worktrees()
 3151            .filter_map(|worktree| {
 3152                self.language_servers_for_worktree(worktree.read(cx).id())
 3153                    .find(|server| server.server_id() == language_server_id)
 3154                    .map(|_| worktree)
 3155            })
 3156            .collect::<Vec<_>>();
 3157
 3158        let mut worktree_globs = HashMap::default();
 3159        let mut abs_globs = HashMap::default();
 3160        log::trace!(
 3161            "Processing new watcher paths for language server with id {}",
 3162            language_server_id
 3163        );
 3164
 3165        for watcher in watchers {
 3166            if let Some((worktree, literal_prefix, pattern)) =
 3167                self.worktree_and_path_for_file_watcher(&worktrees, watcher, cx)
 3168            {
 3169                worktree.update(cx, |worktree, _| {
 3170                    if let Some((tree, glob)) =
 3171                        worktree.as_local_mut().zip(Glob::new(&pattern).log_err())
 3172                    {
 3173                        tree.add_path_prefix_to_scan(literal_prefix.into());
 3174                        worktree_globs
 3175                            .entry(tree.id())
 3176                            .or_insert_with(GlobSetBuilder::new)
 3177                            .add(glob);
 3178                    }
 3179                });
 3180            } else {
 3181                let (path, pattern) = match &watcher.glob_pattern {
 3182                    lsp::GlobPattern::String(s) => {
 3183                        let watcher_path = SanitizedPath::from(s);
 3184                        let path = glob_literal_prefix(watcher_path.as_path());
 3185                        let pattern = watcher_path
 3186                            .as_path()
 3187                            .strip_prefix(&path)
 3188                            .map(|p| p.to_string_lossy().to_string())
 3189                            .unwrap_or_else(|e| {
 3190                                debug_panic!(
 3191                                    "Failed to strip prefix for string pattern: {}, with prefix: {}, with error: {}",
 3192                                    s,
 3193                                    path.display(),
 3194                                    e
 3195                                );
 3196                                watcher_path.as_path().to_string_lossy().to_string()
 3197                            });
 3198                        (path, pattern)
 3199                    }
 3200                    lsp::GlobPattern::Relative(rp) => {
 3201                        let Ok(mut base_uri) = match &rp.base_uri {
 3202                            lsp::OneOf::Left(workspace_folder) => &workspace_folder.uri,
 3203                            lsp::OneOf::Right(base_uri) => base_uri,
 3204                        }
 3205                        .to_file_path() else {
 3206                            continue;
 3207                        };
 3208
 3209                        let path = glob_literal_prefix(Path::new(&rp.pattern));
 3210                        let pattern = Path::new(&rp.pattern)
 3211                            .strip_prefix(&path)
 3212                            .map(|p| p.to_string_lossy().to_string())
 3213                            .unwrap_or_else(|e| {
 3214                                debug_panic!(
 3215                                    "Failed to strip prefix for relative pattern: {}, with prefix: {}, with error: {}",
 3216                                    rp.pattern,
 3217                                    path.display(),
 3218                                    e
 3219                                );
 3220                                rp.pattern.clone()
 3221                            });
 3222                        base_uri.push(path);
 3223                        (base_uri, pattern)
 3224                    }
 3225                };
 3226
 3227                if let Some(glob) = Glob::new(&pattern).log_err() {
 3228                    if !path
 3229                        .components()
 3230                        .any(|c| matches!(c, path::Component::Normal(_)))
 3231                    {
 3232                        // For an unrooted glob like `**/Cargo.toml`, watch it within each worktree,
 3233                        // rather than adding a new watcher for `/`.
 3234                        for worktree in &worktrees {
 3235                            worktree_globs
 3236                                .entry(worktree.read(cx).id())
 3237                                .or_insert_with(GlobSetBuilder::new)
 3238                                .add(glob.clone());
 3239                        }
 3240                    } else {
 3241                        abs_globs
 3242                            .entry(path.into())
 3243                            .or_insert_with(GlobSetBuilder::new)
 3244                            .add(glob);
 3245                    }
 3246                }
 3247            }
 3248        }
 3249
 3250        let mut watch_builder = LanguageServerWatchedPathsBuilder::default();
 3251        for (worktree_id, builder) in worktree_globs {
 3252            if let Ok(globset) = builder.build() {
 3253                watch_builder.watch_worktree(worktree_id, globset);
 3254            }
 3255        }
 3256        for (abs_path, builder) in abs_globs {
 3257            if let Ok(globset) = builder.build() {
 3258                watch_builder.watch_abs_path(abs_path, globset);
 3259            }
 3260        }
 3261        watch_builder
 3262    }
 3263
 3264    fn worktree_and_path_for_file_watcher(
 3265        &self,
 3266        worktrees: &[Entity<Worktree>],
 3267        watcher: &FileSystemWatcher,
 3268        cx: &App,
 3269    ) -> Option<(Entity<Worktree>, PathBuf, String)> {
 3270        worktrees.iter().find_map(|worktree| {
 3271            let tree = worktree.read(cx);
 3272            let worktree_root_path = tree.abs_path();
 3273            match &watcher.glob_pattern {
 3274                lsp::GlobPattern::String(s) => {
 3275                    let watcher_path = SanitizedPath::from(s);
 3276                    let relative = watcher_path
 3277                        .as_path()
 3278                        .strip_prefix(&worktree_root_path)
 3279                        .ok()?;
 3280                    let literal_prefix = glob_literal_prefix(relative);
 3281                    Some((
 3282                        worktree.clone(),
 3283                        literal_prefix,
 3284                        relative.to_string_lossy().to_string(),
 3285                    ))
 3286                }
 3287                lsp::GlobPattern::Relative(rp) => {
 3288                    let base_uri = match &rp.base_uri {
 3289                        lsp::OneOf::Left(workspace_folder) => &workspace_folder.uri,
 3290                        lsp::OneOf::Right(base_uri) => base_uri,
 3291                    }
 3292                    .to_file_path()
 3293                    .ok()?;
 3294                    let relative = base_uri.strip_prefix(&worktree_root_path).ok()?;
 3295                    let mut literal_prefix = relative.to_owned();
 3296                    literal_prefix.push(glob_literal_prefix(Path::new(&rp.pattern)));
 3297                    Some((worktree.clone(), literal_prefix, rp.pattern.clone()))
 3298                }
 3299            }
 3300        })
 3301    }
 3302
 3303    fn rebuild_watched_paths(
 3304        &mut self,
 3305        language_server_id: LanguageServerId,
 3306        cx: &mut Context<LspStore>,
 3307    ) {
 3308        let Some(watchers) = self
 3309            .language_server_watcher_registrations
 3310            .get(&language_server_id)
 3311        else {
 3312            return;
 3313        };
 3314
 3315        let watch_builder =
 3316            self.rebuild_watched_paths_inner(language_server_id, watchers.values().flatten(), cx);
 3317        let watcher = watch_builder.build(self.fs.clone(), language_server_id, cx);
 3318        self.language_server_watched_paths
 3319            .insert(language_server_id, watcher);
 3320
 3321        cx.notify();
 3322    }
 3323
 3324    fn on_lsp_did_change_watched_files(
 3325        &mut self,
 3326        language_server_id: LanguageServerId,
 3327        registration_id: &str,
 3328        params: DidChangeWatchedFilesRegistrationOptions,
 3329        cx: &mut Context<LspStore>,
 3330    ) {
 3331        let registrations = self
 3332            .language_server_watcher_registrations
 3333            .entry(language_server_id)
 3334            .or_default();
 3335
 3336        registrations.insert(registration_id.to_string(), params.watchers);
 3337
 3338        self.rebuild_watched_paths(language_server_id, cx);
 3339    }
 3340
 3341    fn on_lsp_unregister_did_change_watched_files(
 3342        &mut self,
 3343        language_server_id: LanguageServerId,
 3344        registration_id: &str,
 3345        cx: &mut Context<LspStore>,
 3346    ) {
 3347        let registrations = self
 3348            .language_server_watcher_registrations
 3349            .entry(language_server_id)
 3350            .or_default();
 3351
 3352        if registrations.remove(registration_id).is_some() {
 3353            log::info!(
 3354                "language server {}: unregistered workspace/DidChangeWatchedFiles capability with id {}",
 3355                language_server_id,
 3356                registration_id
 3357            );
 3358        } else {
 3359            log::warn!(
 3360                "language server {}: failed to unregister workspace/DidChangeWatchedFiles capability with id {}. not registered.",
 3361                language_server_id,
 3362                registration_id
 3363            );
 3364        }
 3365
 3366        self.rebuild_watched_paths(language_server_id, cx);
 3367    }
 3368
 3369    async fn initialization_options_for_adapter(
 3370        adapter: Arc<dyn LspAdapter>,
 3371        fs: &dyn Fs,
 3372        delegate: &Arc<dyn LspAdapterDelegate>,
 3373    ) -> Result<Option<serde_json::Value>> {
 3374        let Some(mut initialization_config) =
 3375            adapter.clone().initialization_options(fs, delegate).await?
 3376        else {
 3377            return Ok(None);
 3378        };
 3379
 3380        for other_adapter in delegate.registered_lsp_adapters() {
 3381            if other_adapter.name() == adapter.name() {
 3382                continue;
 3383            }
 3384            if let Ok(Some(target_config)) = other_adapter
 3385                .clone()
 3386                .additional_initialization_options(adapter.name(), fs, delegate)
 3387                .await
 3388            {
 3389                merge_json_value_into(target_config.clone(), &mut initialization_config);
 3390            }
 3391        }
 3392
 3393        Ok(Some(initialization_config))
 3394    }
 3395
 3396    fn toolchain_store(&self) -> &Entity<LocalToolchainStore> {
 3397        &self.toolchain_store
 3398    }
 3399
 3400    async fn workspace_configuration_for_adapter(
 3401        adapter: Arc<dyn LspAdapter>,
 3402        fs: &dyn Fs,
 3403        delegate: &Arc<dyn LspAdapterDelegate>,
 3404        toolchain: Option<Toolchain>,
 3405        cx: &mut AsyncApp,
 3406    ) -> Result<serde_json::Value> {
 3407        let mut workspace_config = adapter
 3408            .clone()
 3409            .workspace_configuration(fs, delegate, toolchain, cx)
 3410            .await?;
 3411
 3412        for other_adapter in delegate.registered_lsp_adapters() {
 3413            if other_adapter.name() == adapter.name() {
 3414                continue;
 3415            }
 3416            if let Ok(Some(target_config)) = other_adapter
 3417                .clone()
 3418                .additional_workspace_configuration(adapter.name(), fs, delegate, cx)
 3419                .await
 3420            {
 3421                merge_json_value_into(target_config.clone(), &mut workspace_config);
 3422            }
 3423        }
 3424
 3425        Ok(workspace_config)
 3426    }
 3427
 3428    fn language_server_for_id(&self, id: LanguageServerId) -> Option<Arc<LanguageServer>> {
 3429        if let Some(LanguageServerState::Running { server, .. }) = self.language_servers.get(&id) {
 3430            Some(server.clone())
 3431        } else if let Some((_, server)) = self.supplementary_language_servers.get(&id) {
 3432            Some(Arc::clone(server))
 3433        } else {
 3434            None
 3435        }
 3436    }
 3437}
 3438
 3439fn notify_server_capabilities_updated(server: &LanguageServer, cx: &mut Context<LspStore>) {
 3440    if let Some(capabilities) = serde_json::to_string(&server.capabilities()).ok() {
 3441        cx.emit(LspStoreEvent::LanguageServerUpdate {
 3442            language_server_id: server.server_id(),
 3443            name: Some(server.name()),
 3444            message: proto::update_language_server::Variant::MetadataUpdated(
 3445                proto::ServerMetadataUpdated {
 3446                    capabilities: Some(capabilities),
 3447                },
 3448            ),
 3449        });
 3450    }
 3451}
 3452
 3453#[derive(Debug)]
 3454pub struct FormattableBuffer {
 3455    handle: Entity<Buffer>,
 3456    abs_path: Option<PathBuf>,
 3457    env: Option<HashMap<String, String>>,
 3458    ranges: Option<Vec<Range<Anchor>>>,
 3459}
 3460
 3461pub struct RemoteLspStore {
 3462    upstream_client: Option<AnyProtoClient>,
 3463    upstream_project_id: u64,
 3464}
 3465
 3466pub(crate) enum LspStoreMode {
 3467    Local(LocalLspStore),   // ssh host and collab host
 3468    Remote(RemoteLspStore), // collab guest
 3469}
 3470
 3471impl LspStoreMode {
 3472    fn is_local(&self) -> bool {
 3473        matches!(self, LspStoreMode::Local(_))
 3474    }
 3475}
 3476
 3477pub struct LspStore {
 3478    mode: LspStoreMode,
 3479    last_formatting_failure: Option<String>,
 3480    downstream_client: Option<(AnyProtoClient, u64)>,
 3481    nonce: u128,
 3482    buffer_store: Entity<BufferStore>,
 3483    worktree_store: Entity<WorktreeStore>,
 3484    pub languages: Arc<LanguageRegistry>,
 3485    language_server_statuses: BTreeMap<LanguageServerId, LanguageServerStatus>,
 3486    active_entry: Option<ProjectEntryId>,
 3487    _maintain_workspace_config: (Task<Result<()>>, watch::Sender<()>),
 3488    _maintain_buffer_languages: Task<()>,
 3489    diagnostic_summaries:
 3490        HashMap<WorktreeId, HashMap<Arc<Path>, HashMap<LanguageServerId, DiagnosticSummary>>>,
 3491    pub(super) lsp_server_capabilities: HashMap<LanguageServerId, lsp::ServerCapabilities>,
 3492    lsp_document_colors: HashMap<BufferId, DocumentColorData>,
 3493    lsp_code_lens: HashMap<BufferId, CodeLensData>,
 3494    running_lsp_requests: HashMap<TypeId, (Global, HashMap<LspRequestId, Task<()>>)>,
 3495}
 3496
 3497#[derive(Debug, Default, Clone)]
 3498pub struct DocumentColors {
 3499    pub colors: HashSet<DocumentColor>,
 3500    pub cache_version: Option<usize>,
 3501}
 3502
 3503type DocumentColorTask = Shared<Task<std::result::Result<DocumentColors, Arc<anyhow::Error>>>>;
 3504type CodeLensTask = Shared<Task<std::result::Result<Option<Vec<CodeAction>>, Arc<anyhow::Error>>>>;
 3505
 3506#[derive(Debug, Default)]
 3507struct DocumentColorData {
 3508    colors_for_version: Global,
 3509    colors: HashMap<LanguageServerId, HashSet<DocumentColor>>,
 3510    cache_version: usize,
 3511    colors_update: Option<(Global, DocumentColorTask)>,
 3512}
 3513
 3514#[derive(Debug, Default)]
 3515struct CodeLensData {
 3516    lens_for_version: Global,
 3517    lens: HashMap<LanguageServerId, Vec<CodeAction>>,
 3518    update: Option<(Global, CodeLensTask)>,
 3519}
 3520
 3521#[derive(Debug, PartialEq, Eq, Clone, Copy)]
 3522pub enum LspFetchStrategy {
 3523    IgnoreCache,
 3524    UseCache { known_cache_version: Option<usize> },
 3525}
 3526
 3527#[derive(Debug)]
 3528pub enum LspStoreEvent {
 3529    LanguageServerAdded(LanguageServerId, LanguageServerName, Option<WorktreeId>),
 3530    LanguageServerRemoved(LanguageServerId),
 3531    LanguageServerUpdate {
 3532        language_server_id: LanguageServerId,
 3533        name: Option<LanguageServerName>,
 3534        message: proto::update_language_server::Variant,
 3535    },
 3536    LanguageServerLog(LanguageServerId, LanguageServerLogType, String),
 3537    LanguageServerPrompt(LanguageServerPromptRequest),
 3538    LanguageDetected {
 3539        buffer: Entity<Buffer>,
 3540        new_language: Option<Arc<Language>>,
 3541    },
 3542    Notification(String),
 3543    RefreshInlayHints,
 3544    RefreshCodeLens,
 3545    DiagnosticsUpdated {
 3546        server_id: LanguageServerId,
 3547        paths: Vec<ProjectPath>,
 3548    },
 3549    DiskBasedDiagnosticsStarted {
 3550        language_server_id: LanguageServerId,
 3551    },
 3552    DiskBasedDiagnosticsFinished {
 3553        language_server_id: LanguageServerId,
 3554    },
 3555    SnippetEdit {
 3556        buffer_id: BufferId,
 3557        edits: Vec<(lsp::Range, Snippet)>,
 3558        most_recent_edit: clock::Lamport,
 3559    },
 3560}
 3561
 3562#[derive(Clone, Debug, Serialize)]
 3563pub struct LanguageServerStatus {
 3564    pub name: LanguageServerName,
 3565    pub pending_work: BTreeMap<String, LanguageServerProgress>,
 3566    pub has_pending_diagnostic_updates: bool,
 3567    progress_tokens: HashSet<String>,
 3568}
 3569
 3570#[derive(Clone, Debug)]
 3571struct CoreSymbol {
 3572    pub language_server_name: LanguageServerName,
 3573    pub source_worktree_id: WorktreeId,
 3574    pub source_language_server_id: LanguageServerId,
 3575    pub path: ProjectPath,
 3576    pub name: String,
 3577    pub kind: lsp::SymbolKind,
 3578    pub range: Range<Unclipped<PointUtf16>>,
 3579    pub signature: [u8; 32],
 3580}
 3581
 3582impl LspStore {
 3583    pub fn init(client: &AnyProtoClient) {
 3584        client.add_entity_request_handler(Self::handle_lsp_query);
 3585        client.add_entity_message_handler(Self::handle_lsp_query_response);
 3586        client.add_entity_request_handler(Self::handle_multi_lsp_query);
 3587        client.add_entity_request_handler(Self::handle_restart_language_servers);
 3588        client.add_entity_request_handler(Self::handle_stop_language_servers);
 3589        client.add_entity_request_handler(Self::handle_cancel_language_server_work);
 3590        client.add_entity_message_handler(Self::handle_start_language_server);
 3591        client.add_entity_message_handler(Self::handle_update_language_server);
 3592        client.add_entity_message_handler(Self::handle_language_server_log);
 3593        client.add_entity_message_handler(Self::handle_update_diagnostic_summary);
 3594        client.add_entity_request_handler(Self::handle_format_buffers);
 3595        client.add_entity_request_handler(Self::handle_apply_code_action_kind);
 3596        client.add_entity_request_handler(Self::handle_resolve_completion_documentation);
 3597        client.add_entity_request_handler(Self::handle_apply_code_action);
 3598        client.add_entity_request_handler(Self::handle_inlay_hints);
 3599        client.add_entity_request_handler(Self::handle_get_project_symbols);
 3600        client.add_entity_request_handler(Self::handle_resolve_inlay_hint);
 3601        client.add_entity_request_handler(Self::handle_get_color_presentation);
 3602        client.add_entity_request_handler(Self::handle_open_buffer_for_symbol);
 3603        client.add_entity_request_handler(Self::handle_refresh_inlay_hints);
 3604        client.add_entity_request_handler(Self::handle_refresh_code_lens);
 3605        client.add_entity_request_handler(Self::handle_on_type_formatting);
 3606        client.add_entity_request_handler(Self::handle_apply_additional_edits_for_completion);
 3607        client.add_entity_request_handler(Self::handle_register_buffer_with_language_servers);
 3608        client.add_entity_request_handler(Self::handle_rename_project_entry);
 3609        client.add_entity_request_handler(Self::handle_pull_workspace_diagnostics);
 3610        client.add_entity_request_handler(Self::handle_lsp_command::<GetCodeActions>);
 3611        client.add_entity_request_handler(Self::handle_lsp_command::<GetCompletions>);
 3612        client.add_entity_request_handler(Self::handle_lsp_command::<GetHover>);
 3613        client.add_entity_request_handler(Self::handle_lsp_command::<GetDocumentHighlights>);
 3614        client.add_entity_request_handler(Self::handle_lsp_command::<GetDocumentSymbols>);
 3615        client.add_entity_request_handler(Self::handle_lsp_command::<PrepareRename>);
 3616        client.add_entity_request_handler(Self::handle_lsp_command::<PerformRename>);
 3617        client.add_entity_request_handler(Self::handle_lsp_command::<LinkedEditingRange>);
 3618
 3619        client.add_entity_request_handler(Self::handle_lsp_ext_cancel_flycheck);
 3620        client.add_entity_request_handler(Self::handle_lsp_ext_run_flycheck);
 3621        client.add_entity_request_handler(Self::handle_lsp_ext_clear_flycheck);
 3622        client.add_entity_request_handler(Self::handle_lsp_command::<lsp_ext_command::ExpandMacro>);
 3623        client.add_entity_request_handler(Self::handle_lsp_command::<lsp_ext_command::OpenDocs>);
 3624        client.add_entity_request_handler(
 3625            Self::handle_lsp_command::<lsp_ext_command::GoToParentModule>,
 3626        );
 3627        client.add_entity_request_handler(
 3628            Self::handle_lsp_command::<lsp_ext_command::GetLspRunnables>,
 3629        );
 3630        client.add_entity_request_handler(
 3631            Self::handle_lsp_command::<lsp_ext_command::SwitchSourceHeader>,
 3632        );
 3633        client.add_entity_request_handler(Self::handle_lsp_command::<GetDocumentDiagnostics>);
 3634    }
 3635
 3636    pub fn as_remote(&self) -> Option<&RemoteLspStore> {
 3637        match &self.mode {
 3638            LspStoreMode::Remote(remote_lsp_store) => Some(remote_lsp_store),
 3639            _ => None,
 3640        }
 3641    }
 3642
 3643    pub fn as_local(&self) -> Option<&LocalLspStore> {
 3644        match &self.mode {
 3645            LspStoreMode::Local(local_lsp_store) => Some(local_lsp_store),
 3646            _ => None,
 3647        }
 3648    }
 3649
 3650    pub fn as_local_mut(&mut self) -> Option<&mut LocalLspStore> {
 3651        match &mut self.mode {
 3652            LspStoreMode::Local(local_lsp_store) => Some(local_lsp_store),
 3653            _ => None,
 3654        }
 3655    }
 3656
 3657    pub fn upstream_client(&self) -> Option<(AnyProtoClient, u64)> {
 3658        match &self.mode {
 3659            LspStoreMode::Remote(RemoteLspStore {
 3660                upstream_client: Some(upstream_client),
 3661                upstream_project_id,
 3662                ..
 3663            }) => Some((upstream_client.clone(), *upstream_project_id)),
 3664
 3665            LspStoreMode::Remote(RemoteLspStore {
 3666                upstream_client: None,
 3667                ..
 3668            }) => None,
 3669            LspStoreMode::Local(_) => None,
 3670        }
 3671    }
 3672
 3673    pub fn new_local(
 3674        buffer_store: Entity<BufferStore>,
 3675        worktree_store: Entity<WorktreeStore>,
 3676        prettier_store: Entity<PrettierStore>,
 3677        toolchain_store: Entity<LocalToolchainStore>,
 3678        environment: Entity<ProjectEnvironment>,
 3679        manifest_tree: Entity<ManifestTree>,
 3680        languages: Arc<LanguageRegistry>,
 3681        http_client: Arc<dyn HttpClient>,
 3682        fs: Arc<dyn Fs>,
 3683        cx: &mut Context<Self>,
 3684    ) -> Self {
 3685        let yarn = YarnPathStore::new(fs.clone(), cx);
 3686        cx.subscribe(&buffer_store, Self::on_buffer_store_event)
 3687            .detach();
 3688        cx.subscribe(&worktree_store, Self::on_worktree_store_event)
 3689            .detach();
 3690        cx.subscribe(&prettier_store, Self::on_prettier_store_event)
 3691            .detach();
 3692        cx.subscribe(&toolchain_store, Self::on_toolchain_store_event)
 3693            .detach();
 3694        if let Some(extension_events) = extension::ExtensionEvents::try_global(cx).as_ref() {
 3695            cx.subscribe(
 3696                extension_events,
 3697                Self::reload_zed_json_schemas_on_extensions_changed,
 3698            )
 3699            .detach();
 3700        } else {
 3701            log::debug!("No extension events global found. Skipping JSON schema auto-reload setup");
 3702        }
 3703        cx.observe_global::<SettingsStore>(Self::on_settings_changed)
 3704            .detach();
 3705        subscribe_to_binary_statuses(&languages, cx).detach();
 3706
 3707        let _maintain_workspace_config = {
 3708            let (sender, receiver) = watch::channel();
 3709            (
 3710                Self::maintain_workspace_config(fs.clone(), receiver, cx),
 3711                sender,
 3712            )
 3713        };
 3714
 3715        Self {
 3716            mode: LspStoreMode::Local(LocalLspStore {
 3717                weak: cx.weak_entity(),
 3718                worktree_store: worktree_store.clone(),
 3719
 3720                supplementary_language_servers: Default::default(),
 3721                languages: languages.clone(),
 3722                language_server_ids: Default::default(),
 3723                language_servers: Default::default(),
 3724                last_workspace_edits_by_language_server: Default::default(),
 3725                language_server_watched_paths: Default::default(),
 3726                language_server_paths_watched_for_rename: Default::default(),
 3727                language_server_watcher_registrations: Default::default(),
 3728                buffers_being_formatted: Default::default(),
 3729                buffer_snapshots: Default::default(),
 3730                prettier_store,
 3731                environment,
 3732                http_client,
 3733                fs,
 3734                yarn,
 3735                next_diagnostic_group_id: Default::default(),
 3736                diagnostics: Default::default(),
 3737                _subscription: cx.on_app_quit(|this, cx| {
 3738                    this.as_local_mut()
 3739                        .unwrap()
 3740                        .shutdown_language_servers_on_quit(cx)
 3741                }),
 3742                lsp_tree: LanguageServerTree::new(
 3743                    manifest_tree,
 3744                    languages.clone(),
 3745                    toolchain_store.clone(),
 3746                ),
 3747                toolchain_store,
 3748                registered_buffers: HashMap::default(),
 3749                buffers_opened_in_servers: HashMap::default(),
 3750                buffer_pull_diagnostics_result_ids: HashMap::default(),
 3751                watched_manifest_filenames: ManifestProvidersStore::global(cx)
 3752                    .manifest_file_names(),
 3753            }),
 3754            last_formatting_failure: None,
 3755            downstream_client: None,
 3756            buffer_store,
 3757            worktree_store,
 3758            languages: languages.clone(),
 3759            language_server_statuses: Default::default(),
 3760            nonce: StdRng::from_entropy().r#gen(),
 3761            diagnostic_summaries: HashMap::default(),
 3762            lsp_server_capabilities: HashMap::default(),
 3763            lsp_document_colors: HashMap::default(),
 3764            lsp_code_lens: HashMap::default(),
 3765            running_lsp_requests: HashMap::default(),
 3766            active_entry: None,
 3767            _maintain_workspace_config,
 3768            _maintain_buffer_languages: Self::maintain_buffer_languages(languages, cx),
 3769        }
 3770    }
 3771
 3772    fn send_lsp_proto_request<R: LspCommand>(
 3773        &self,
 3774        buffer: Entity<Buffer>,
 3775        client: AnyProtoClient,
 3776        upstream_project_id: u64,
 3777        request: R,
 3778        cx: &mut Context<LspStore>,
 3779    ) -> Task<anyhow::Result<<R as LspCommand>::Response>> {
 3780        if !self.is_capable_for_proto_request(&buffer, &request, cx) {
 3781            return Task::ready(Ok(R::Response::default()));
 3782        }
 3783        let message = request.to_proto(upstream_project_id, buffer.read(cx));
 3784        cx.spawn(async move |this, cx| {
 3785            let response = client.request(message).await?;
 3786            let this = this.upgrade().context("project dropped")?;
 3787            request
 3788                .response_from_proto(response, this, buffer, cx.clone())
 3789                .await
 3790        })
 3791    }
 3792
 3793    pub(super) fn new_remote(
 3794        buffer_store: Entity<BufferStore>,
 3795        worktree_store: Entity<WorktreeStore>,
 3796        languages: Arc<LanguageRegistry>,
 3797        upstream_client: AnyProtoClient,
 3798        project_id: u64,
 3799        fs: Arc<dyn Fs>,
 3800        cx: &mut Context<Self>,
 3801    ) -> Self {
 3802        cx.subscribe(&buffer_store, Self::on_buffer_store_event)
 3803            .detach();
 3804        cx.subscribe(&worktree_store, Self::on_worktree_store_event)
 3805            .detach();
 3806        subscribe_to_binary_statuses(&languages, cx).detach();
 3807        let _maintain_workspace_config = {
 3808            let (sender, receiver) = watch::channel();
 3809            (Self::maintain_workspace_config(fs, receiver, cx), sender)
 3810        };
 3811        Self {
 3812            mode: LspStoreMode::Remote(RemoteLspStore {
 3813                upstream_client: Some(upstream_client),
 3814                upstream_project_id: project_id,
 3815            }),
 3816            downstream_client: None,
 3817            last_formatting_failure: None,
 3818            buffer_store,
 3819            worktree_store,
 3820            languages: languages.clone(),
 3821            language_server_statuses: Default::default(),
 3822            nonce: StdRng::from_entropy().r#gen(),
 3823            diagnostic_summaries: HashMap::default(),
 3824            lsp_server_capabilities: HashMap::default(),
 3825            lsp_document_colors: HashMap::default(),
 3826            lsp_code_lens: HashMap::default(),
 3827            running_lsp_requests: HashMap::default(),
 3828            active_entry: None,
 3829
 3830            _maintain_workspace_config,
 3831            _maintain_buffer_languages: Self::maintain_buffer_languages(languages.clone(), cx),
 3832        }
 3833    }
 3834
 3835    fn on_buffer_store_event(
 3836        &mut self,
 3837        _: Entity<BufferStore>,
 3838        event: &BufferStoreEvent,
 3839        cx: &mut Context<Self>,
 3840    ) {
 3841        match event {
 3842            BufferStoreEvent::BufferAdded(buffer) => {
 3843                self.on_buffer_added(buffer, cx).log_err();
 3844            }
 3845            BufferStoreEvent::BufferChangedFilePath { buffer, old_file } => {
 3846                let buffer_id = buffer.read(cx).remote_id();
 3847                if let Some(local) = self.as_local_mut()
 3848                    && let Some(old_file) = File::from_dyn(old_file.as_ref())
 3849                {
 3850                    local.reset_buffer(buffer, old_file, cx);
 3851
 3852                    if local.registered_buffers.contains_key(&buffer_id) {
 3853                        local.unregister_old_buffer_from_language_servers(buffer, old_file, cx);
 3854                    }
 3855                }
 3856
 3857                self.detect_language_for_buffer(buffer, cx);
 3858                if let Some(local) = self.as_local_mut() {
 3859                    local.initialize_buffer(buffer, cx);
 3860                    if local.registered_buffers.contains_key(&buffer_id) {
 3861                        local.register_buffer_with_language_servers(buffer, HashSet::default(), cx);
 3862                    }
 3863                }
 3864            }
 3865            _ => {}
 3866        }
 3867    }
 3868
 3869    fn on_worktree_store_event(
 3870        &mut self,
 3871        _: Entity<WorktreeStore>,
 3872        event: &WorktreeStoreEvent,
 3873        cx: &mut Context<Self>,
 3874    ) {
 3875        match event {
 3876            WorktreeStoreEvent::WorktreeAdded(worktree) => {
 3877                if !worktree.read(cx).is_local() {
 3878                    return;
 3879                }
 3880                cx.subscribe(worktree, |this, worktree, event, cx| match event {
 3881                    worktree::Event::UpdatedEntries(changes) => {
 3882                        this.update_local_worktree_language_servers(&worktree, changes, cx);
 3883                    }
 3884                    worktree::Event::UpdatedGitRepositories(_)
 3885                    | worktree::Event::DeletedEntry(_) => {}
 3886                })
 3887                .detach()
 3888            }
 3889            WorktreeStoreEvent::WorktreeRemoved(_, id) => self.remove_worktree(*id, cx),
 3890            WorktreeStoreEvent::WorktreeUpdateSent(worktree) => {
 3891                worktree.update(cx, |worktree, _cx| self.send_diagnostic_summaries(worktree));
 3892            }
 3893            WorktreeStoreEvent::WorktreeReleased(..)
 3894            | WorktreeStoreEvent::WorktreeOrderChanged
 3895            | WorktreeStoreEvent::WorktreeUpdatedEntries(..)
 3896            | WorktreeStoreEvent::WorktreeUpdatedGitRepositories(..)
 3897            | WorktreeStoreEvent::WorktreeDeletedEntry(..) => {}
 3898        }
 3899    }
 3900
 3901    fn on_prettier_store_event(
 3902        &mut self,
 3903        _: Entity<PrettierStore>,
 3904        event: &PrettierStoreEvent,
 3905        cx: &mut Context<Self>,
 3906    ) {
 3907        match event {
 3908            PrettierStoreEvent::LanguageServerRemoved(prettier_server_id) => {
 3909                self.unregister_supplementary_language_server(*prettier_server_id, cx);
 3910            }
 3911            PrettierStoreEvent::LanguageServerAdded {
 3912                new_server_id,
 3913                name,
 3914                prettier_server,
 3915            } => {
 3916                self.register_supplementary_language_server(
 3917                    *new_server_id,
 3918                    name.clone(),
 3919                    prettier_server.clone(),
 3920                    cx,
 3921                );
 3922            }
 3923        }
 3924    }
 3925
 3926    fn on_toolchain_store_event(
 3927        &mut self,
 3928        _: Entity<LocalToolchainStore>,
 3929        event: &ToolchainStoreEvent,
 3930        _: &mut Context<Self>,
 3931    ) {
 3932        match event {
 3933            ToolchainStoreEvent::ToolchainActivated => self.request_workspace_config_refresh(),
 3934        }
 3935    }
 3936
 3937    fn request_workspace_config_refresh(&mut self) {
 3938        *self._maintain_workspace_config.1.borrow_mut() = ();
 3939    }
 3940
 3941    pub fn prettier_store(&self) -> Option<Entity<PrettierStore>> {
 3942        self.as_local().map(|local| local.prettier_store.clone())
 3943    }
 3944
 3945    fn on_buffer_event(
 3946        &mut self,
 3947        buffer: Entity<Buffer>,
 3948        event: &language::BufferEvent,
 3949        cx: &mut Context<Self>,
 3950    ) {
 3951        match event {
 3952            language::BufferEvent::Edited => {
 3953                self.on_buffer_edited(buffer, cx);
 3954            }
 3955
 3956            language::BufferEvent::Saved => {
 3957                self.on_buffer_saved(buffer, cx);
 3958            }
 3959
 3960            _ => {}
 3961        }
 3962    }
 3963
 3964    fn on_buffer_added(&mut self, buffer: &Entity<Buffer>, cx: &mut Context<Self>) -> Result<()> {
 3965        buffer
 3966            .read(cx)
 3967            .set_language_registry(self.languages.clone());
 3968
 3969        cx.subscribe(buffer, |this, buffer, event, cx| {
 3970            this.on_buffer_event(buffer, event, cx);
 3971        })
 3972        .detach();
 3973
 3974        self.detect_language_for_buffer(buffer, cx);
 3975        if let Some(local) = self.as_local_mut() {
 3976            local.initialize_buffer(buffer, cx);
 3977        }
 3978
 3979        Ok(())
 3980    }
 3981
 3982    pub fn reload_zed_json_schemas_on_extensions_changed(
 3983        &mut self,
 3984        _: Entity<extension::ExtensionEvents>,
 3985        evt: &extension::Event,
 3986        cx: &mut Context<Self>,
 3987    ) {
 3988        match evt {
 3989            extension::Event::ExtensionInstalled(_)
 3990            | extension::Event::ExtensionUninstalled(_)
 3991            | extension::Event::ConfigureExtensionRequested(_) => return,
 3992            extension::Event::ExtensionsInstalledChanged => {}
 3993        }
 3994        if self.as_local().is_none() {
 3995            return;
 3996        }
 3997        cx.spawn(async move |this, cx| {
 3998            let weak_ref = this.clone();
 3999
 4000            let servers = this
 4001                .update(cx, |this, cx| {
 4002                    let local = this.as_local()?;
 4003
 4004                    let mut servers = Vec::new();
 4005                    for (seed, state) in &local.language_server_ids {
 4006
 4007                            let Some(states) = local.language_servers.get(&state.id) else {
 4008                                continue;
 4009                            };
 4010                            let (json_adapter, json_server) = match states {
 4011                                LanguageServerState::Running {
 4012                                    adapter, server, ..
 4013                                } if adapter.adapter.is_primary_zed_json_schema_adapter() => {
 4014                                    (adapter.adapter.clone(), server.clone())
 4015                                }
 4016                                _ => continue,
 4017                            };
 4018
 4019                            let Some(worktree) = this
 4020                                .worktree_store
 4021                                .read(cx)
 4022                                .worktree_for_id(seed.worktree_id, cx)
 4023                            else {
 4024                                continue;
 4025                            };
 4026                            let json_delegate: Arc<dyn LspAdapterDelegate> =
 4027                                LocalLspAdapterDelegate::new(
 4028                                    local.languages.clone(),
 4029                                    &local.environment,
 4030                                    weak_ref.clone(),
 4031                                    &worktree,
 4032                                    local.http_client.clone(),
 4033                                    local.fs.clone(),
 4034                                    cx,
 4035                                );
 4036
 4037                            servers.push((json_adapter, json_server, json_delegate));
 4038
 4039                    }
 4040                    Some(servers)
 4041                })
 4042                .ok()
 4043                .flatten();
 4044
 4045            let Some(servers) = servers else {
 4046                return;
 4047            };
 4048
 4049            let Ok(Some((fs, _))) = this.read_with(cx, |this, _| {
 4050                let local = this.as_local()?;
 4051                let toolchain_store = local.toolchain_store().clone();
 4052                Some((local.fs.clone(), toolchain_store))
 4053            }) else {
 4054                return;
 4055            };
 4056            for (adapter, server, delegate) in servers {
 4057                adapter.clear_zed_json_schema_cache().await;
 4058
 4059                let Some(json_workspace_config) = LocalLspStore::workspace_configuration_for_adapter(
 4060                        adapter,
 4061                        fs.as_ref(),
 4062                        &delegate,
 4063                        None,
 4064                        cx,
 4065                    )
 4066                    .await
 4067                    .context("generate new workspace configuration for JSON language server while trying to refresh JSON Schemas")
 4068                    .ok()
 4069                else {
 4070                    continue;
 4071                };
 4072                server
 4073                    .notify::<lsp::notification::DidChangeConfiguration>(
 4074                        &lsp::DidChangeConfigurationParams {
 4075                            settings: json_workspace_config,
 4076                        },
 4077                    )
 4078                    .ok();
 4079            }
 4080        })
 4081        .detach();
 4082    }
 4083
 4084    pub(crate) fn register_buffer_with_language_servers(
 4085        &mut self,
 4086        buffer: &Entity<Buffer>,
 4087        only_register_servers: HashSet<LanguageServerSelector>,
 4088        ignore_refcounts: bool,
 4089        cx: &mut Context<Self>,
 4090    ) -> OpenLspBufferHandle {
 4091        let buffer_id = buffer.read(cx).remote_id();
 4092        let handle = cx.new(|_| buffer.clone());
 4093        if let Some(local) = self.as_local_mut() {
 4094            let refcount = local.registered_buffers.entry(buffer_id).or_insert(0);
 4095            if !ignore_refcounts {
 4096                *refcount += 1;
 4097            }
 4098
 4099            // We run early exits on non-existing buffers AFTER we mark the buffer as registered in order to handle buffer saving.
 4100            // When a new unnamed buffer is created and saved, we will start loading it's language. Once the language is loaded, we go over all "language-less" buffers and try to fit that new language
 4101            // with them. However, we do that only for the buffers that we think are open in at least one editor; thus, we need to keep tab of unnamed buffers as well, even though they're not actually registered with any language
 4102            // servers in practice (we don't support non-file URI schemes in our LSP impl).
 4103            let Some(file) = File::from_dyn(buffer.read(cx).file()) else {
 4104                return handle;
 4105            };
 4106            if !file.is_local() {
 4107                return handle;
 4108            }
 4109
 4110            if ignore_refcounts || *refcount == 1 {
 4111                local.register_buffer_with_language_servers(buffer, only_register_servers, cx);
 4112            }
 4113            if !ignore_refcounts {
 4114                cx.observe_release(&handle, move |lsp_store, buffer, cx| {
 4115                    let refcount = {
 4116                        let local = lsp_store.as_local_mut().unwrap();
 4117                        let Some(refcount) = local.registered_buffers.get_mut(&buffer_id) else {
 4118                            debug_panic!("bad refcounting");
 4119                            return;
 4120                        };
 4121
 4122                        *refcount -= 1;
 4123                        *refcount
 4124                    };
 4125                    if refcount == 0 {
 4126                        lsp_store.lsp_document_colors.remove(&buffer_id);
 4127                        lsp_store.lsp_code_lens.remove(&buffer_id);
 4128                        let local = lsp_store.as_local_mut().unwrap();
 4129                        local.registered_buffers.remove(&buffer_id);
 4130                        local.buffers_opened_in_servers.remove(&buffer_id);
 4131                        if let Some(file) = File::from_dyn(buffer.read(cx).file()).cloned() {
 4132                            local.unregister_old_buffer_from_language_servers(buffer, &file, cx);
 4133                        }
 4134                    }
 4135                })
 4136                .detach();
 4137            }
 4138        } else if let Some((upstream_client, upstream_project_id)) = self.upstream_client() {
 4139            let buffer_id = buffer.read(cx).remote_id().to_proto();
 4140            cx.background_spawn(async move {
 4141                upstream_client
 4142                    .request(proto::RegisterBufferWithLanguageServers {
 4143                        project_id: upstream_project_id,
 4144                        buffer_id,
 4145                        only_servers: only_register_servers
 4146                            .into_iter()
 4147                            .map(|selector| {
 4148                                let selector = match selector {
 4149                                    LanguageServerSelector::Id(language_server_id) => {
 4150                                        proto::language_server_selector::Selector::ServerId(
 4151                                            language_server_id.to_proto(),
 4152                                        )
 4153                                    }
 4154                                    LanguageServerSelector::Name(language_server_name) => {
 4155                                        proto::language_server_selector::Selector::Name(
 4156                                            language_server_name.to_string(),
 4157                                        )
 4158                                    }
 4159                                };
 4160                                proto::LanguageServerSelector {
 4161                                    selector: Some(selector),
 4162                                }
 4163                            })
 4164                            .collect(),
 4165                    })
 4166                    .await
 4167            })
 4168            .detach();
 4169        } else {
 4170            panic!("oops!");
 4171        }
 4172        handle
 4173    }
 4174
 4175    fn maintain_buffer_languages(
 4176        languages: Arc<LanguageRegistry>,
 4177        cx: &mut Context<Self>,
 4178    ) -> Task<()> {
 4179        let mut subscription = languages.subscribe();
 4180        let mut prev_reload_count = languages.reload_count();
 4181        cx.spawn(async move |this, cx| {
 4182            while let Some(()) = subscription.next().await {
 4183                if let Some(this) = this.upgrade() {
 4184                    // If the language registry has been reloaded, then remove and
 4185                    // re-assign the languages on all open buffers.
 4186                    let reload_count = languages.reload_count();
 4187                    if reload_count > prev_reload_count {
 4188                        prev_reload_count = reload_count;
 4189                        this.update(cx, |this, cx| {
 4190                            this.buffer_store.clone().update(cx, |buffer_store, cx| {
 4191                                for buffer in buffer_store.buffers() {
 4192                                    if let Some(f) = File::from_dyn(buffer.read(cx).file()).cloned()
 4193                                    {
 4194                                        buffer
 4195                                            .update(cx, |buffer, cx| buffer.set_language(None, cx));
 4196                                        if let Some(local) = this.as_local_mut() {
 4197                                            local.reset_buffer(&buffer, &f, cx);
 4198
 4199                                            if local
 4200                                                .registered_buffers
 4201                                                .contains_key(&buffer.read(cx).remote_id())
 4202                                                && let Some(file_url) =
 4203                                                    file_path_to_lsp_url(&f.abs_path(cx)).log_err()
 4204                                            {
 4205                                                local.unregister_buffer_from_language_servers(
 4206                                                    &buffer, &file_url, cx,
 4207                                                );
 4208                                            }
 4209                                        }
 4210                                    }
 4211                                }
 4212                            });
 4213                        })
 4214                        .ok();
 4215                    }
 4216
 4217                    this.update(cx, |this, cx| {
 4218                        let mut plain_text_buffers = Vec::new();
 4219                        let mut buffers_with_unknown_injections = Vec::new();
 4220                        for handle in this.buffer_store.read(cx).buffers() {
 4221                            let buffer = handle.read(cx);
 4222                            if buffer.language().is_none()
 4223                                || buffer.language() == Some(&*language::PLAIN_TEXT)
 4224                            {
 4225                                plain_text_buffers.push(handle);
 4226                            } else if buffer.contains_unknown_injections() {
 4227                                buffers_with_unknown_injections.push(handle);
 4228                            }
 4229                        }
 4230
 4231                        // Deprioritize the invisible worktrees so main worktrees' language servers can be started first,
 4232                        // and reused later in the invisible worktrees.
 4233                        plain_text_buffers.sort_by_key(|buffer| {
 4234                            Reverse(
 4235                                File::from_dyn(buffer.read(cx).file())
 4236                                    .map(|file| file.worktree.read(cx).is_visible()),
 4237                            )
 4238                        });
 4239
 4240                        for buffer in plain_text_buffers {
 4241                            this.detect_language_for_buffer(&buffer, cx);
 4242                            if let Some(local) = this.as_local_mut() {
 4243                                local.initialize_buffer(&buffer, cx);
 4244                                if local
 4245                                    .registered_buffers
 4246                                    .contains_key(&buffer.read(cx).remote_id())
 4247                                {
 4248                                    local.register_buffer_with_language_servers(
 4249                                        &buffer,
 4250                                        HashSet::default(),
 4251                                        cx,
 4252                                    );
 4253                                }
 4254                            }
 4255                        }
 4256
 4257                        for buffer in buffers_with_unknown_injections {
 4258                            buffer.update(cx, |buffer, cx| buffer.reparse(cx));
 4259                        }
 4260                    })
 4261                    .ok();
 4262                }
 4263            }
 4264        })
 4265    }
 4266
 4267    fn detect_language_for_buffer(
 4268        &mut self,
 4269        buffer_handle: &Entity<Buffer>,
 4270        cx: &mut Context<Self>,
 4271    ) -> Option<language::AvailableLanguage> {
 4272        // If the buffer has a language, set it and start the language server if we haven't already.
 4273        let buffer = buffer_handle.read(cx);
 4274        let file = buffer.file()?;
 4275
 4276        let content = buffer.as_rope();
 4277        let available_language = self.languages.language_for_file(file, Some(content), cx);
 4278        if let Some(available_language) = &available_language {
 4279            if let Some(Ok(Ok(new_language))) = self
 4280                .languages
 4281                .load_language(available_language)
 4282                .now_or_never()
 4283            {
 4284                self.set_language_for_buffer(buffer_handle, new_language, cx);
 4285            }
 4286        } else {
 4287            cx.emit(LspStoreEvent::LanguageDetected {
 4288                buffer: buffer_handle.clone(),
 4289                new_language: None,
 4290            });
 4291        }
 4292
 4293        available_language
 4294    }
 4295
 4296    pub(crate) fn set_language_for_buffer(
 4297        &mut self,
 4298        buffer_entity: &Entity<Buffer>,
 4299        new_language: Arc<Language>,
 4300        cx: &mut Context<Self>,
 4301    ) {
 4302        let buffer = buffer_entity.read(cx);
 4303        let buffer_file = buffer.file().cloned();
 4304        let buffer_id = buffer.remote_id();
 4305        if let Some(local_store) = self.as_local_mut()
 4306            && local_store.registered_buffers.contains_key(&buffer_id)
 4307            && let Some(abs_path) =
 4308                File::from_dyn(buffer_file.as_ref()).map(|file| file.abs_path(cx))
 4309            && let Some(file_url) = file_path_to_lsp_url(&abs_path).log_err()
 4310        {
 4311            local_store.unregister_buffer_from_language_servers(buffer_entity, &file_url, cx);
 4312        }
 4313        buffer_entity.update(cx, |buffer, cx| {
 4314            if buffer
 4315                .language()
 4316                .is_none_or(|old_language| !Arc::ptr_eq(old_language, &new_language))
 4317            {
 4318                buffer.set_language(Some(new_language.clone()), cx);
 4319            }
 4320        });
 4321
 4322        let settings =
 4323            language_settings(Some(new_language.name()), buffer_file.as_ref(), cx).into_owned();
 4324        let buffer_file = File::from_dyn(buffer_file.as_ref());
 4325
 4326        let worktree_id = if let Some(file) = buffer_file {
 4327            let worktree = file.worktree.clone();
 4328
 4329            if let Some(local) = self.as_local_mut()
 4330                && local.registered_buffers.contains_key(&buffer_id)
 4331            {
 4332                local.register_buffer_with_language_servers(buffer_entity, HashSet::default(), cx);
 4333            }
 4334            Some(worktree.read(cx).id())
 4335        } else {
 4336            None
 4337        };
 4338
 4339        if settings.prettier.allowed
 4340            && let Some(prettier_plugins) = prettier_store::prettier_plugins_for_language(&settings)
 4341        {
 4342            let prettier_store = self.as_local().map(|s| s.prettier_store.clone());
 4343            if let Some(prettier_store) = prettier_store {
 4344                prettier_store.update(cx, |prettier_store, cx| {
 4345                    prettier_store.install_default_prettier(
 4346                        worktree_id,
 4347                        prettier_plugins.iter().map(|s| Arc::from(s.as_str())),
 4348                        cx,
 4349                    )
 4350                })
 4351            }
 4352        }
 4353
 4354        cx.emit(LspStoreEvent::LanguageDetected {
 4355            buffer: buffer_entity.clone(),
 4356            new_language: Some(new_language),
 4357        })
 4358    }
 4359
 4360    pub fn buffer_store(&self) -> Entity<BufferStore> {
 4361        self.buffer_store.clone()
 4362    }
 4363
 4364    pub fn set_active_entry(&mut self, active_entry: Option<ProjectEntryId>) {
 4365        self.active_entry = active_entry;
 4366    }
 4367
 4368    pub(crate) fn send_diagnostic_summaries(&self, worktree: &mut Worktree) {
 4369        if let Some((client, downstream_project_id)) = self.downstream_client.clone()
 4370            && let Some(diangostic_summaries) = self.diagnostic_summaries.get(&worktree.id())
 4371        {
 4372            let mut summaries = diangostic_summaries.iter().flat_map(|(path, summaries)| {
 4373                summaries
 4374                    .iter()
 4375                    .map(|(server_id, summary)| summary.to_proto(*server_id, path))
 4376            });
 4377            if let Some(summary) = summaries.next() {
 4378                client
 4379                    .send(proto::UpdateDiagnosticSummary {
 4380                        project_id: downstream_project_id,
 4381                        worktree_id: worktree.id().to_proto(),
 4382                        summary: Some(summary),
 4383                        more_summaries: summaries.collect(),
 4384                    })
 4385                    .log_err();
 4386            }
 4387        }
 4388    }
 4389
 4390    fn is_capable_for_proto_request<R>(
 4391        &self,
 4392        buffer: &Entity<Buffer>,
 4393        request: &R,
 4394        cx: &Context<Self>,
 4395    ) -> bool
 4396    where
 4397        R: LspCommand,
 4398    {
 4399        self.check_if_capable_for_proto_request(
 4400            buffer,
 4401            |capabilities| {
 4402                request.check_capabilities(AdapterServerCapabilities {
 4403                    server_capabilities: capabilities.clone(),
 4404                    code_action_kinds: None,
 4405                })
 4406            },
 4407            cx,
 4408        )
 4409    }
 4410
 4411    fn check_if_capable_for_proto_request<F>(
 4412        &self,
 4413        buffer: &Entity<Buffer>,
 4414        check: F,
 4415        cx: &Context<Self>,
 4416    ) -> bool
 4417    where
 4418        F: Fn(&lsp::ServerCapabilities) -> bool,
 4419    {
 4420        let Some(language) = buffer.read(cx).language().cloned() else {
 4421            return false;
 4422        };
 4423        let relevant_language_servers = self
 4424            .languages
 4425            .lsp_adapters(&language.name())
 4426            .into_iter()
 4427            .map(|lsp_adapter| lsp_adapter.name())
 4428            .collect::<HashSet<_>>();
 4429        self.language_server_statuses
 4430            .iter()
 4431            .filter_map(|(server_id, server_status)| {
 4432                relevant_language_servers
 4433                    .contains(&server_status.name)
 4434                    .then_some(server_id)
 4435            })
 4436            .filter_map(|server_id| self.lsp_server_capabilities.get(server_id))
 4437            .any(check)
 4438    }
 4439
 4440    pub fn request_lsp<R>(
 4441        &mut self,
 4442        buffer: Entity<Buffer>,
 4443        server: LanguageServerToQuery,
 4444        request: R,
 4445        cx: &mut Context<Self>,
 4446    ) -> Task<Result<R::Response>>
 4447    where
 4448        R: LspCommand,
 4449        <R::LspRequest as lsp::request::Request>::Result: Send,
 4450        <R::LspRequest as lsp::request::Request>::Params: Send,
 4451    {
 4452        if let Some((upstream_client, upstream_project_id)) = self.upstream_client() {
 4453            return self.send_lsp_proto_request(
 4454                buffer,
 4455                upstream_client,
 4456                upstream_project_id,
 4457                request,
 4458                cx,
 4459            );
 4460        }
 4461
 4462        let Some(language_server) = buffer.update(cx, |buffer, cx| match server {
 4463            LanguageServerToQuery::FirstCapable => self.as_local().and_then(|local| {
 4464                local
 4465                    .language_servers_for_buffer(buffer, cx)
 4466                    .find(|(_, server)| {
 4467                        request.check_capabilities(server.adapter_server_capabilities())
 4468                    })
 4469                    .map(|(_, server)| server.clone())
 4470            }),
 4471            LanguageServerToQuery::Other(id) => self
 4472                .language_server_for_local_buffer(buffer, id, cx)
 4473                .and_then(|(_, server)| {
 4474                    request
 4475                        .check_capabilities(server.adapter_server_capabilities())
 4476                        .then(|| Arc::clone(server))
 4477                }),
 4478        }) else {
 4479            return Task::ready(Ok(Default::default()));
 4480        };
 4481
 4482        let file = File::from_dyn(buffer.read(cx).file()).and_then(File::as_local);
 4483
 4484        let Some(file) = file else {
 4485            return Task::ready(Ok(Default::default()));
 4486        };
 4487
 4488        let lsp_params = match request.to_lsp_params_or_response(
 4489            &file.abs_path(cx),
 4490            buffer.read(cx),
 4491            &language_server,
 4492            cx,
 4493        ) {
 4494            Ok(LspParamsOrResponse::Params(lsp_params)) => lsp_params,
 4495            Ok(LspParamsOrResponse::Response(response)) => return Task::ready(Ok(response)),
 4496
 4497            Err(err) => {
 4498                let message = format!(
 4499                    "{} via {} failed: {}",
 4500                    request.display_name(),
 4501                    language_server.name(),
 4502                    err
 4503                );
 4504                log::warn!("{message}");
 4505                return Task::ready(Err(anyhow!(message)));
 4506            }
 4507        };
 4508
 4509        let status = request.status();
 4510        if !request.check_capabilities(language_server.adapter_server_capabilities()) {
 4511            return Task::ready(Ok(Default::default()));
 4512        }
 4513        cx.spawn(async move |this, cx| {
 4514            let lsp_request = language_server.request::<R::LspRequest>(lsp_params);
 4515
 4516            let id = lsp_request.id();
 4517            let _cleanup = if status.is_some() {
 4518                cx.update(|cx| {
 4519                    this.update(cx, |this, cx| {
 4520                        this.on_lsp_work_start(
 4521                            language_server.server_id(),
 4522                            id.to_string(),
 4523                            LanguageServerProgress {
 4524                                is_disk_based_diagnostics_progress: false,
 4525                                is_cancellable: false,
 4526                                title: None,
 4527                                message: status.clone(),
 4528                                percentage: None,
 4529                                last_update_at: cx.background_executor().now(),
 4530                            },
 4531                            cx,
 4532                        );
 4533                    })
 4534                })
 4535                .log_err();
 4536
 4537                Some(defer(|| {
 4538                    cx.update(|cx| {
 4539                        this.update(cx, |this, cx| {
 4540                            this.on_lsp_work_end(language_server.server_id(), id.to_string(), cx);
 4541                        })
 4542                    })
 4543                    .log_err();
 4544                }))
 4545            } else {
 4546                None
 4547            };
 4548
 4549            let result = lsp_request.await.into_response();
 4550
 4551            let response = result.map_err(|err| {
 4552                let message = format!(
 4553                    "{} via {} failed: {}",
 4554                    request.display_name(),
 4555                    language_server.name(),
 4556                    err
 4557                );
 4558                log::warn!("{message}");
 4559                anyhow::anyhow!(message)
 4560            })?;
 4561
 4562            request
 4563                .response_from_lsp(
 4564                    response,
 4565                    this.upgrade().context("no app context")?,
 4566                    buffer,
 4567                    language_server.server_id(),
 4568                    cx.clone(),
 4569                )
 4570                .await
 4571        })
 4572    }
 4573
 4574    fn on_settings_changed(&mut self, cx: &mut Context<Self>) {
 4575        let mut language_formatters_to_check = Vec::new();
 4576        for buffer in self.buffer_store.read(cx).buffers() {
 4577            let buffer = buffer.read(cx);
 4578            let buffer_file = File::from_dyn(buffer.file());
 4579            let buffer_language = buffer.language();
 4580            let settings = language_settings(buffer_language.map(|l| l.name()), buffer.file(), cx);
 4581            if buffer_language.is_some() {
 4582                language_formatters_to_check.push((
 4583                    buffer_file.map(|f| f.worktree_id(cx)),
 4584                    settings.into_owned(),
 4585                ));
 4586            }
 4587        }
 4588
 4589        self.request_workspace_config_refresh();
 4590
 4591        if let Some(prettier_store) = self.as_local().map(|s| s.prettier_store.clone()) {
 4592            prettier_store.update(cx, |prettier_store, cx| {
 4593                prettier_store.on_settings_changed(language_formatters_to_check, cx)
 4594            })
 4595        }
 4596
 4597        cx.notify();
 4598    }
 4599
 4600    fn refresh_server_tree(&mut self, cx: &mut Context<Self>) {
 4601        let buffer_store = self.buffer_store.clone();
 4602        let Some(local) = self.as_local_mut() else {
 4603            return;
 4604        };
 4605        let mut adapters = BTreeMap::default();
 4606        let get_adapter = {
 4607            let languages = local.languages.clone();
 4608            let environment = local.environment.clone();
 4609            let weak = local.weak.clone();
 4610            let worktree_store = local.worktree_store.clone();
 4611            let http_client = local.http_client.clone();
 4612            let fs = local.fs.clone();
 4613            move |worktree_id, cx: &mut App| {
 4614                let worktree = worktree_store.read(cx).worktree_for_id(worktree_id, cx)?;
 4615                Some(LocalLspAdapterDelegate::new(
 4616                    languages.clone(),
 4617                    &environment,
 4618                    weak.clone(),
 4619                    &worktree,
 4620                    http_client.clone(),
 4621                    fs.clone(),
 4622                    cx,
 4623                ))
 4624            }
 4625        };
 4626
 4627        let mut messages_to_report = Vec::new();
 4628        let (new_tree, to_stop) = {
 4629            let mut rebase = local.lsp_tree.rebase();
 4630            let buffers = buffer_store
 4631                .read(cx)
 4632                .buffers()
 4633                .filter_map(|buffer| {
 4634                    let raw_buffer = buffer.read(cx);
 4635                    if !local
 4636                        .registered_buffers
 4637                        .contains_key(&raw_buffer.remote_id())
 4638                    {
 4639                        return None;
 4640                    }
 4641                    let file = File::from_dyn(raw_buffer.file()).cloned()?;
 4642                    let language = raw_buffer.language().cloned()?;
 4643                    Some((file, language, raw_buffer.remote_id()))
 4644                })
 4645                .sorted_by_key(|(file, _, _)| Reverse(file.worktree.read(cx).is_visible()));
 4646            for (file, language, buffer_id) in buffers {
 4647                let worktree_id = file.worktree_id(cx);
 4648                let Some(worktree) = local
 4649                    .worktree_store
 4650                    .read(cx)
 4651                    .worktree_for_id(worktree_id, cx)
 4652                else {
 4653                    continue;
 4654                };
 4655
 4656                if let Some((_, apply)) = local.reuse_existing_language_server(
 4657                    rebase.server_tree(),
 4658                    &worktree,
 4659                    &language.name(),
 4660                    cx,
 4661                ) {
 4662                    (apply)(rebase.server_tree());
 4663                } else if let Some(lsp_delegate) = adapters
 4664                    .entry(worktree_id)
 4665                    .or_insert_with(|| get_adapter(worktree_id, cx))
 4666                    .clone()
 4667                {
 4668                    let delegate =
 4669                        Arc::new(ManifestQueryDelegate::new(worktree.read(cx).snapshot()));
 4670                    let path = file
 4671                        .path()
 4672                        .parent()
 4673                        .map(Arc::from)
 4674                        .unwrap_or_else(|| file.path().clone());
 4675                    let worktree_path = ProjectPath { worktree_id, path };
 4676                    let abs_path = file.abs_path(cx);
 4677                    let worktree_root = worktree.read(cx).abs_path();
 4678                    let nodes = rebase
 4679                        .walk(
 4680                            worktree_path,
 4681                            language.name(),
 4682                            language.manifest(),
 4683                            delegate.clone(),
 4684                            cx,
 4685                        )
 4686                        .collect::<Vec<_>>();
 4687                    for node in nodes {
 4688                        let server_id = node.server_id_or_init(|disposition| {
 4689                            let path = &disposition.path;
 4690                            let uri = Url::from_file_path(worktree_root.join(&path.path));
 4691                            let key = LanguageServerSeed {
 4692                                worktree_id,
 4693                                name: disposition.server_name.clone(),
 4694                                settings: disposition.settings.clone(),
 4695                                toolchain: local.toolchain_store.read(cx).active_toolchain(
 4696                                    path.worktree_id,
 4697                                    &path.path,
 4698                                    language.name(),
 4699                                ),
 4700                            };
 4701                            local.language_server_ids.remove(&key);
 4702
 4703                            let server_id = local.get_or_insert_language_server(
 4704                                &worktree,
 4705                                lsp_delegate.clone(),
 4706                                disposition,
 4707                                &language.name(),
 4708                                cx,
 4709                            );
 4710                            if let Some(state) = local.language_servers.get(&server_id)
 4711                                && let Ok(uri) = uri
 4712                            {
 4713                                state.add_workspace_folder(uri);
 4714                            };
 4715                            server_id
 4716                        });
 4717
 4718                        if let Some(language_server_id) = server_id {
 4719                            messages_to_report.push(LspStoreEvent::LanguageServerUpdate {
 4720                                language_server_id,
 4721                                name: node.name(),
 4722                                message:
 4723                                    proto::update_language_server::Variant::RegisteredForBuffer(
 4724                                        proto::RegisteredForBuffer {
 4725                                            buffer_abs_path: abs_path.to_string_lossy().to_string(),
 4726                                            buffer_id: buffer_id.to_proto(),
 4727                                        },
 4728                                    ),
 4729                            });
 4730                        }
 4731                    }
 4732                } else {
 4733                    continue;
 4734                }
 4735            }
 4736            rebase.finish()
 4737        };
 4738        for message in messages_to_report {
 4739            cx.emit(message);
 4740        }
 4741        local.lsp_tree = new_tree;
 4742        for (id, _) in to_stop {
 4743            self.stop_local_language_server(id, cx).detach();
 4744        }
 4745    }
 4746
 4747    pub fn apply_code_action(
 4748        &self,
 4749        buffer_handle: Entity<Buffer>,
 4750        mut action: CodeAction,
 4751        push_to_history: bool,
 4752        cx: &mut Context<Self>,
 4753    ) -> Task<Result<ProjectTransaction>> {
 4754        if let Some((upstream_client, project_id)) = self.upstream_client() {
 4755            let request = proto::ApplyCodeAction {
 4756                project_id,
 4757                buffer_id: buffer_handle.read(cx).remote_id().into(),
 4758                action: Some(Self::serialize_code_action(&action)),
 4759            };
 4760            let buffer_store = self.buffer_store();
 4761            cx.spawn(async move |_, cx| {
 4762                let response = upstream_client
 4763                    .request(request)
 4764                    .await?
 4765                    .transaction
 4766                    .context("missing transaction")?;
 4767
 4768                buffer_store
 4769                    .update(cx, |buffer_store, cx| {
 4770                        buffer_store.deserialize_project_transaction(response, push_to_history, cx)
 4771                    })?
 4772                    .await
 4773            })
 4774        } else if self.mode.is_local() {
 4775            let Some((_, lang_server)) = buffer_handle.update(cx, |buffer, cx| {
 4776                self.language_server_for_local_buffer(buffer, action.server_id, cx)
 4777                    .map(|(adapter, server)| (adapter.clone(), server.clone()))
 4778            }) else {
 4779                return Task::ready(Ok(ProjectTransaction::default()));
 4780            };
 4781            cx.spawn(async move |this,  cx| {
 4782                LocalLspStore::try_resolve_code_action(&lang_server, &mut action)
 4783                    .await
 4784                    .context("resolving a code action")?;
 4785                if let Some(edit) = action.lsp_action.edit()
 4786                    && (edit.changes.is_some() || edit.document_changes.is_some()) {
 4787                        return LocalLspStore::deserialize_workspace_edit(
 4788                            this.upgrade().context("no app present")?,
 4789                            edit.clone(),
 4790                            push_to_history,
 4791
 4792                            lang_server.clone(),
 4793                            cx,
 4794                        )
 4795                        .await;
 4796                    }
 4797
 4798                if let Some(command) = action.lsp_action.command() {
 4799                    let server_capabilities = lang_server.capabilities();
 4800                    let available_commands = server_capabilities
 4801                        .execute_command_provider
 4802                        .as_ref()
 4803                        .map(|options| options.commands.as_slice())
 4804                        .unwrap_or_default();
 4805                    if available_commands.contains(&command.command) {
 4806                        this.update(cx, |this, _| {
 4807                            this.as_local_mut()
 4808                                .unwrap()
 4809                                .last_workspace_edits_by_language_server
 4810                                .remove(&lang_server.server_id());
 4811                        })?;
 4812
 4813                        let _result = lang_server
 4814                            .request::<lsp::request::ExecuteCommand>(lsp::ExecuteCommandParams {
 4815                                command: command.command.clone(),
 4816                                arguments: command.arguments.clone().unwrap_or_default(),
 4817                                ..lsp::ExecuteCommandParams::default()
 4818                            })
 4819                            .await.into_response()
 4820                            .context("execute command")?;
 4821
 4822                        return this.update(cx, |this, _| {
 4823                            this.as_local_mut()
 4824                                .unwrap()
 4825                                .last_workspace_edits_by_language_server
 4826                                .remove(&lang_server.server_id())
 4827                                .unwrap_or_default()
 4828                        });
 4829                    } else {
 4830                        log::warn!("Cannot execute a command {} not listed in the language server capabilities", command.command);
 4831                    }
 4832                }
 4833
 4834                Ok(ProjectTransaction::default())
 4835            })
 4836        } else {
 4837            Task::ready(Err(anyhow!("no upstream client and not local")))
 4838        }
 4839    }
 4840
 4841    pub fn apply_code_action_kind(
 4842        &mut self,
 4843        buffers: HashSet<Entity<Buffer>>,
 4844        kind: CodeActionKind,
 4845        push_to_history: bool,
 4846        cx: &mut Context<Self>,
 4847    ) -> Task<anyhow::Result<ProjectTransaction>> {
 4848        if self.as_local().is_some() {
 4849            cx.spawn(async move |lsp_store, cx| {
 4850                let buffers = buffers.into_iter().collect::<Vec<_>>();
 4851                let result = LocalLspStore::execute_code_action_kind_locally(
 4852                    lsp_store.clone(),
 4853                    buffers,
 4854                    kind,
 4855                    push_to_history,
 4856                    cx,
 4857                )
 4858                .await;
 4859                lsp_store.update(cx, |lsp_store, _| {
 4860                    lsp_store.update_last_formatting_failure(&result);
 4861                })?;
 4862                result
 4863            })
 4864        } else if let Some((client, project_id)) = self.upstream_client() {
 4865            let buffer_store = self.buffer_store();
 4866            cx.spawn(async move |lsp_store, cx| {
 4867                let result = client
 4868                    .request(proto::ApplyCodeActionKind {
 4869                        project_id,
 4870                        kind: kind.as_str().to_owned(),
 4871                        buffer_ids: buffers
 4872                            .iter()
 4873                            .map(|buffer| {
 4874                                buffer.read_with(cx, |buffer, _| buffer.remote_id().into())
 4875                            })
 4876                            .collect::<Result<_>>()?,
 4877                    })
 4878                    .await
 4879                    .and_then(|result| result.transaction.context("missing transaction"));
 4880                lsp_store.update(cx, |lsp_store, _| {
 4881                    lsp_store.update_last_formatting_failure(&result);
 4882                })?;
 4883
 4884                let transaction_response = result?;
 4885                buffer_store
 4886                    .update(cx, |buffer_store, cx| {
 4887                        buffer_store.deserialize_project_transaction(
 4888                            transaction_response,
 4889                            push_to_history,
 4890                            cx,
 4891                        )
 4892                    })?
 4893                    .await
 4894            })
 4895        } else {
 4896            Task::ready(Ok(ProjectTransaction::default()))
 4897        }
 4898    }
 4899
 4900    pub fn resolve_inlay_hint(
 4901        &self,
 4902        mut hint: InlayHint,
 4903        buffer: Entity<Buffer>,
 4904        server_id: LanguageServerId,
 4905        cx: &mut Context<Self>,
 4906    ) -> Task<anyhow::Result<InlayHint>> {
 4907        if let Some((upstream_client, project_id)) = self.upstream_client() {
 4908            if !self.check_if_capable_for_proto_request(&buffer, InlayHints::can_resolve_inlays, cx)
 4909            {
 4910                hint.resolve_state = ResolveState::Resolved;
 4911                return Task::ready(Ok(hint));
 4912            }
 4913            let request = proto::ResolveInlayHint {
 4914                project_id,
 4915                buffer_id: buffer.read(cx).remote_id().into(),
 4916                language_server_id: server_id.0 as u64,
 4917                hint: Some(InlayHints::project_to_proto_hint(hint.clone())),
 4918            };
 4919            cx.background_spawn(async move {
 4920                let response = upstream_client
 4921                    .request(request)
 4922                    .await
 4923                    .context("inlay hints proto request")?;
 4924                match response.hint {
 4925                    Some(resolved_hint) => InlayHints::proto_to_project_hint(resolved_hint)
 4926                        .context("inlay hints proto resolve response conversion"),
 4927                    None => Ok(hint),
 4928                }
 4929            })
 4930        } else {
 4931            let Some(lang_server) = buffer.update(cx, |buffer, cx| {
 4932                self.language_server_for_local_buffer(buffer, server_id, cx)
 4933                    .map(|(_, server)| server.clone())
 4934            }) else {
 4935                return Task::ready(Ok(hint));
 4936            };
 4937            if !InlayHints::can_resolve_inlays(&lang_server.capabilities()) {
 4938                return Task::ready(Ok(hint));
 4939            }
 4940            let buffer_snapshot = buffer.read(cx).snapshot();
 4941            cx.spawn(async move |_, cx| {
 4942                let resolve_task = lang_server.request::<lsp::request::InlayHintResolveRequest>(
 4943                    InlayHints::project_to_lsp_hint(hint, &buffer_snapshot),
 4944                );
 4945                let resolved_hint = resolve_task
 4946                    .await
 4947                    .into_response()
 4948                    .context("inlay hint resolve LSP request")?;
 4949                let resolved_hint = InlayHints::lsp_to_project_hint(
 4950                    resolved_hint,
 4951                    &buffer,
 4952                    server_id,
 4953                    ResolveState::Resolved,
 4954                    false,
 4955                    cx,
 4956                )
 4957                .await?;
 4958                Ok(resolved_hint)
 4959            })
 4960        }
 4961    }
 4962
 4963    pub fn resolve_color_presentation(
 4964        &mut self,
 4965        mut color: DocumentColor,
 4966        buffer: Entity<Buffer>,
 4967        server_id: LanguageServerId,
 4968        cx: &mut Context<Self>,
 4969    ) -> Task<Result<DocumentColor>> {
 4970        if color.resolved {
 4971            return Task::ready(Ok(color));
 4972        }
 4973
 4974        if let Some((upstream_client, project_id)) = self.upstream_client() {
 4975            let start = color.lsp_range.start;
 4976            let end = color.lsp_range.end;
 4977            let request = proto::GetColorPresentation {
 4978                project_id,
 4979                server_id: server_id.to_proto(),
 4980                buffer_id: buffer.read(cx).remote_id().into(),
 4981                color: Some(proto::ColorInformation {
 4982                    red: color.color.red,
 4983                    green: color.color.green,
 4984                    blue: color.color.blue,
 4985                    alpha: color.color.alpha,
 4986                    lsp_range_start: Some(proto::PointUtf16 {
 4987                        row: start.line,
 4988                        column: start.character,
 4989                    }),
 4990                    lsp_range_end: Some(proto::PointUtf16 {
 4991                        row: end.line,
 4992                        column: end.character,
 4993                    }),
 4994                }),
 4995            };
 4996            cx.background_spawn(async move {
 4997                let response = upstream_client
 4998                    .request(request)
 4999                    .await
 5000                    .context("color presentation proto request")?;
 5001                color.resolved = true;
 5002                color.color_presentations = response
 5003                    .presentations
 5004                    .into_iter()
 5005                    .map(|presentation| ColorPresentation {
 5006                        label: SharedString::from(presentation.label),
 5007                        text_edit: presentation.text_edit.and_then(deserialize_lsp_edit),
 5008                        additional_text_edits: presentation
 5009                            .additional_text_edits
 5010                            .into_iter()
 5011                            .filter_map(deserialize_lsp_edit)
 5012                            .collect(),
 5013                    })
 5014                    .collect();
 5015                Ok(color)
 5016            })
 5017        } else {
 5018            let path = match buffer
 5019                .update(cx, |buffer, cx| {
 5020                    Some(File::from_dyn(buffer.file())?.abs_path(cx))
 5021                })
 5022                .context("buffer with the missing path")
 5023            {
 5024                Ok(path) => path,
 5025                Err(e) => return Task::ready(Err(e)),
 5026            };
 5027            let Some(lang_server) = buffer.update(cx, |buffer, cx| {
 5028                self.language_server_for_local_buffer(buffer, server_id, cx)
 5029                    .map(|(_, server)| server.clone())
 5030            }) else {
 5031                return Task::ready(Ok(color));
 5032            };
 5033            cx.background_spawn(async move {
 5034                let resolve_task = lang_server.request::<lsp::request::ColorPresentationRequest>(
 5035                    lsp::ColorPresentationParams {
 5036                        text_document: make_text_document_identifier(&path)?,
 5037                        color: color.color,
 5038                        range: color.lsp_range,
 5039                        work_done_progress_params: Default::default(),
 5040                        partial_result_params: Default::default(),
 5041                    },
 5042                );
 5043                color.color_presentations = resolve_task
 5044                    .await
 5045                    .into_response()
 5046                    .context("color presentation resolve LSP request")?
 5047                    .into_iter()
 5048                    .map(|presentation| ColorPresentation {
 5049                        label: SharedString::from(presentation.label),
 5050                        text_edit: presentation.text_edit,
 5051                        additional_text_edits: presentation
 5052                            .additional_text_edits
 5053                            .unwrap_or_default(),
 5054                    })
 5055                    .collect();
 5056                color.resolved = true;
 5057                Ok(color)
 5058            })
 5059        }
 5060    }
 5061
 5062    pub(crate) fn linked_edits(
 5063        &mut self,
 5064        buffer: &Entity<Buffer>,
 5065        position: Anchor,
 5066        cx: &mut Context<Self>,
 5067    ) -> Task<Result<Vec<Range<Anchor>>>> {
 5068        let snapshot = buffer.read(cx).snapshot();
 5069        let scope = snapshot.language_scope_at(position);
 5070        let Some(server_id) = self
 5071            .as_local()
 5072            .and_then(|local| {
 5073                buffer.update(cx, |buffer, cx| {
 5074                    local
 5075                        .language_servers_for_buffer(buffer, cx)
 5076                        .filter(|(_, server)| {
 5077                            LinkedEditingRange::check_server_capabilities(server.capabilities())
 5078                        })
 5079                        .filter(|(adapter, _)| {
 5080                            scope
 5081                                .as_ref()
 5082                                .map(|scope| scope.language_allowed(&adapter.name))
 5083                                .unwrap_or(true)
 5084                        })
 5085                        .map(|(_, server)| LanguageServerToQuery::Other(server.server_id()))
 5086                        .next()
 5087                })
 5088            })
 5089            .or_else(|| {
 5090                self.upstream_client()
 5091                    .is_some()
 5092                    .then_some(LanguageServerToQuery::FirstCapable)
 5093            })
 5094            .filter(|_| {
 5095                maybe!({
 5096                    let language = buffer.read(cx).language_at(position)?;
 5097                    Some(
 5098                        language_settings(Some(language.name()), buffer.read(cx).file(), cx)
 5099                            .linked_edits,
 5100                    )
 5101                }) == Some(true)
 5102            })
 5103        else {
 5104            return Task::ready(Ok(Vec::new()));
 5105        };
 5106
 5107        self.request_lsp(
 5108            buffer.clone(),
 5109            server_id,
 5110            LinkedEditingRange { position },
 5111            cx,
 5112        )
 5113    }
 5114
 5115    fn apply_on_type_formatting(
 5116        &mut self,
 5117        buffer: Entity<Buffer>,
 5118        position: Anchor,
 5119        trigger: String,
 5120        cx: &mut Context<Self>,
 5121    ) -> Task<Result<Option<Transaction>>> {
 5122        if let Some((client, project_id)) = self.upstream_client() {
 5123            if !self.check_if_capable_for_proto_request(
 5124                &buffer,
 5125                |capabilities| {
 5126                    OnTypeFormatting::supports_on_type_formatting(&trigger, capabilities)
 5127                },
 5128                cx,
 5129            ) {
 5130                return Task::ready(Ok(None));
 5131            }
 5132            let request = proto::OnTypeFormatting {
 5133                project_id,
 5134                buffer_id: buffer.read(cx).remote_id().into(),
 5135                position: Some(serialize_anchor(&position)),
 5136                trigger,
 5137                version: serialize_version(&buffer.read(cx).version()),
 5138            };
 5139            cx.background_spawn(async move {
 5140                client
 5141                    .request(request)
 5142                    .await?
 5143                    .transaction
 5144                    .map(language::proto::deserialize_transaction)
 5145                    .transpose()
 5146            })
 5147        } else if let Some(local) = self.as_local_mut() {
 5148            let buffer_id = buffer.read(cx).remote_id();
 5149            local.buffers_being_formatted.insert(buffer_id);
 5150            cx.spawn(async move |this, cx| {
 5151                let _cleanup = defer({
 5152                    let this = this.clone();
 5153                    let mut cx = cx.clone();
 5154                    move || {
 5155                        this.update(&mut cx, |this, _| {
 5156                            if let Some(local) = this.as_local_mut() {
 5157                                local.buffers_being_formatted.remove(&buffer_id);
 5158                            }
 5159                        })
 5160                        .ok();
 5161                    }
 5162                });
 5163
 5164                buffer
 5165                    .update(cx, |buffer, _| {
 5166                        buffer.wait_for_edits(Some(position.timestamp))
 5167                    })?
 5168                    .await?;
 5169                this.update(cx, |this, cx| {
 5170                    let position = position.to_point_utf16(buffer.read(cx));
 5171                    this.on_type_format(buffer, position, trigger, false, cx)
 5172                })?
 5173                .await
 5174            })
 5175        } else {
 5176            Task::ready(Err(anyhow!("No upstream client or local language server")))
 5177        }
 5178    }
 5179
 5180    pub fn on_type_format<T: ToPointUtf16>(
 5181        &mut self,
 5182        buffer: Entity<Buffer>,
 5183        position: T,
 5184        trigger: String,
 5185        push_to_history: bool,
 5186        cx: &mut Context<Self>,
 5187    ) -> Task<Result<Option<Transaction>>> {
 5188        let position = position.to_point_utf16(buffer.read(cx));
 5189        self.on_type_format_impl(buffer, position, trigger, push_to_history, cx)
 5190    }
 5191
 5192    fn on_type_format_impl(
 5193        &mut self,
 5194        buffer: Entity<Buffer>,
 5195        position: PointUtf16,
 5196        trigger: String,
 5197        push_to_history: bool,
 5198        cx: &mut Context<Self>,
 5199    ) -> Task<Result<Option<Transaction>>> {
 5200        let options = buffer.update(cx, |buffer, cx| {
 5201            lsp_command::lsp_formatting_options(
 5202                language_settings(
 5203                    buffer.language_at(position).map(|l| l.name()),
 5204                    buffer.file(),
 5205                    cx,
 5206                )
 5207                .as_ref(),
 5208            )
 5209        });
 5210
 5211        cx.spawn(async move |this, cx| {
 5212            if let Some(waiter) =
 5213                buffer.update(cx, |buffer, _| buffer.wait_for_autoindent_applied())?
 5214            {
 5215                waiter.await?;
 5216            }
 5217            cx.update(|cx| {
 5218                this.update(cx, |this, cx| {
 5219                    this.request_lsp(
 5220                        buffer.clone(),
 5221                        LanguageServerToQuery::FirstCapable,
 5222                        OnTypeFormatting {
 5223                            position,
 5224                            trigger,
 5225                            options,
 5226                            push_to_history,
 5227                        },
 5228                        cx,
 5229                    )
 5230                })
 5231            })??
 5232            .await
 5233        })
 5234    }
 5235
 5236    pub fn definitions(
 5237        &mut self,
 5238        buffer: &Entity<Buffer>,
 5239        position: PointUtf16,
 5240        cx: &mut Context<Self>,
 5241    ) -> Task<Result<Option<Vec<LocationLink>>>> {
 5242        if let Some((upstream_client, project_id)) = self.upstream_client() {
 5243            let request = GetDefinitions { position };
 5244            if !self.is_capable_for_proto_request(buffer, &request, cx) {
 5245                return Task::ready(Ok(None));
 5246            }
 5247            let request_task = upstream_client.request_lsp(
 5248                project_id,
 5249                LSP_REQUEST_TIMEOUT,
 5250                cx.background_executor().clone(),
 5251                request.to_proto(project_id, buffer.read(cx)),
 5252            );
 5253            let buffer = buffer.clone();
 5254            cx.spawn(async move |weak_project, cx| {
 5255                let Some(project) = weak_project.upgrade() else {
 5256                    return Ok(None);
 5257                };
 5258                let Some(responses) = request_task.await? else {
 5259                    return Ok(None);
 5260                };
 5261                let actions = join_all(responses.payload.into_iter().map(|response| {
 5262                    GetDefinitions { position }.response_from_proto(
 5263                        response.response,
 5264                        project.clone(),
 5265                        buffer.clone(),
 5266                        cx.clone(),
 5267                    )
 5268                }))
 5269                .await;
 5270
 5271                Ok(Some(
 5272                    actions
 5273                        .into_iter()
 5274                        .collect::<Result<Vec<Vec<_>>>>()?
 5275                        .into_iter()
 5276                        .flatten()
 5277                        .dedup()
 5278                        .collect(),
 5279                ))
 5280            })
 5281        } else {
 5282            let definitions_task = self.request_multiple_lsp_locally(
 5283                buffer,
 5284                Some(position),
 5285                GetDefinitions { position },
 5286                cx,
 5287            );
 5288            cx.background_spawn(async move {
 5289                Ok(Some(
 5290                    definitions_task
 5291                        .await
 5292                        .into_iter()
 5293                        .flat_map(|(_, definitions)| definitions)
 5294                        .dedup()
 5295                        .collect(),
 5296                ))
 5297            })
 5298        }
 5299    }
 5300
 5301    pub fn declarations(
 5302        &mut self,
 5303        buffer: &Entity<Buffer>,
 5304        position: PointUtf16,
 5305        cx: &mut Context<Self>,
 5306    ) -> Task<Result<Option<Vec<LocationLink>>>> {
 5307        if let Some((upstream_client, project_id)) = self.upstream_client() {
 5308            let request = GetDeclarations { position };
 5309            if !self.is_capable_for_proto_request(buffer, &request, cx) {
 5310                return Task::ready(Ok(None));
 5311            }
 5312            let request_task = upstream_client.request_lsp(
 5313                project_id,
 5314                LSP_REQUEST_TIMEOUT,
 5315                cx.background_executor().clone(),
 5316                request.to_proto(project_id, buffer.read(cx)),
 5317            );
 5318            let buffer = buffer.clone();
 5319            cx.spawn(async move |weak_project, cx| {
 5320                let Some(project) = weak_project.upgrade() else {
 5321                    return Ok(None);
 5322                };
 5323                let Some(responses) = request_task.await? else {
 5324                    return Ok(None);
 5325                };
 5326                let actions = join_all(responses.payload.into_iter().map(|response| {
 5327                    GetDeclarations { position }.response_from_proto(
 5328                        response.response,
 5329                        project.clone(),
 5330                        buffer.clone(),
 5331                        cx.clone(),
 5332                    )
 5333                }))
 5334                .await;
 5335
 5336                Ok(Some(
 5337                    actions
 5338                        .into_iter()
 5339                        .collect::<Result<Vec<Vec<_>>>>()?
 5340                        .into_iter()
 5341                        .flatten()
 5342                        .dedup()
 5343                        .collect(),
 5344                ))
 5345            })
 5346        } else {
 5347            let declarations_task = self.request_multiple_lsp_locally(
 5348                buffer,
 5349                Some(position),
 5350                GetDeclarations { position },
 5351                cx,
 5352            );
 5353            cx.background_spawn(async move {
 5354                Ok(Some(
 5355                    declarations_task
 5356                        .await
 5357                        .into_iter()
 5358                        .flat_map(|(_, declarations)| declarations)
 5359                        .dedup()
 5360                        .collect(),
 5361                ))
 5362            })
 5363        }
 5364    }
 5365
 5366    pub fn type_definitions(
 5367        &mut self,
 5368        buffer: &Entity<Buffer>,
 5369        position: PointUtf16,
 5370        cx: &mut Context<Self>,
 5371    ) -> Task<Result<Option<Vec<LocationLink>>>> {
 5372        if let Some((upstream_client, project_id)) = self.upstream_client() {
 5373            let request = GetTypeDefinitions { position };
 5374            if !self.is_capable_for_proto_request(buffer, &request, cx) {
 5375                return Task::ready(Ok(None));
 5376            }
 5377            let request_task = upstream_client.request_lsp(
 5378                project_id,
 5379                LSP_REQUEST_TIMEOUT,
 5380                cx.background_executor().clone(),
 5381                request.to_proto(project_id, buffer.read(cx)),
 5382            );
 5383            let buffer = buffer.clone();
 5384            cx.spawn(async move |weak_project, cx| {
 5385                let Some(project) = weak_project.upgrade() else {
 5386                    return Ok(None);
 5387                };
 5388                let Some(responses) = request_task.await? else {
 5389                    return Ok(None);
 5390                };
 5391                let actions = join_all(responses.payload.into_iter().map(|response| {
 5392                    GetTypeDefinitions { position }.response_from_proto(
 5393                        response.response,
 5394                        project.clone(),
 5395                        buffer.clone(),
 5396                        cx.clone(),
 5397                    )
 5398                }))
 5399                .await;
 5400
 5401                Ok(Some(
 5402                    actions
 5403                        .into_iter()
 5404                        .collect::<Result<Vec<Vec<_>>>>()?
 5405                        .into_iter()
 5406                        .flatten()
 5407                        .dedup()
 5408                        .collect(),
 5409                ))
 5410            })
 5411        } else {
 5412            let type_definitions_task = self.request_multiple_lsp_locally(
 5413                buffer,
 5414                Some(position),
 5415                GetTypeDefinitions { position },
 5416                cx,
 5417            );
 5418            cx.background_spawn(async move {
 5419                Ok(Some(
 5420                    type_definitions_task
 5421                        .await
 5422                        .into_iter()
 5423                        .flat_map(|(_, type_definitions)| type_definitions)
 5424                        .dedup()
 5425                        .collect(),
 5426                ))
 5427            })
 5428        }
 5429    }
 5430
 5431    pub fn implementations(
 5432        &mut self,
 5433        buffer: &Entity<Buffer>,
 5434        position: PointUtf16,
 5435        cx: &mut Context<Self>,
 5436    ) -> Task<Result<Option<Vec<LocationLink>>>> {
 5437        if let Some((upstream_client, project_id)) = self.upstream_client() {
 5438            let request = GetImplementations { position };
 5439            if !self.is_capable_for_proto_request(buffer, &request, cx) {
 5440                return Task::ready(Ok(None));
 5441            }
 5442            let request_task = upstream_client.request_lsp(
 5443                project_id,
 5444                LSP_REQUEST_TIMEOUT,
 5445                cx.background_executor().clone(),
 5446                request.to_proto(project_id, buffer.read(cx)),
 5447            );
 5448            let buffer = buffer.clone();
 5449            cx.spawn(async move |weak_project, cx| {
 5450                let Some(project) = weak_project.upgrade() else {
 5451                    return Ok(None);
 5452                };
 5453                let Some(responses) = request_task.await? else {
 5454                    return Ok(None);
 5455                };
 5456                let actions = join_all(responses.payload.into_iter().map(|response| {
 5457                    GetImplementations { position }.response_from_proto(
 5458                        response.response,
 5459                        project.clone(),
 5460                        buffer.clone(),
 5461                        cx.clone(),
 5462                    )
 5463                }))
 5464                .await;
 5465
 5466                Ok(Some(
 5467                    actions
 5468                        .into_iter()
 5469                        .collect::<Result<Vec<Vec<_>>>>()?
 5470                        .into_iter()
 5471                        .flatten()
 5472                        .dedup()
 5473                        .collect(),
 5474                ))
 5475            })
 5476        } else {
 5477            let implementations_task = self.request_multiple_lsp_locally(
 5478                buffer,
 5479                Some(position),
 5480                GetImplementations { position },
 5481                cx,
 5482            );
 5483            cx.background_spawn(async move {
 5484                Ok(Some(
 5485                    implementations_task
 5486                        .await
 5487                        .into_iter()
 5488                        .flat_map(|(_, implementations)| implementations)
 5489                        .dedup()
 5490                        .collect(),
 5491                ))
 5492            })
 5493        }
 5494    }
 5495
 5496    pub fn references(
 5497        &mut self,
 5498        buffer: &Entity<Buffer>,
 5499        position: PointUtf16,
 5500        cx: &mut Context<Self>,
 5501    ) -> Task<Result<Option<Vec<Location>>>> {
 5502        if let Some((upstream_client, project_id)) = self.upstream_client() {
 5503            let request = GetReferences { position };
 5504            if !self.is_capable_for_proto_request(buffer, &request, cx) {
 5505                return Task::ready(Ok(None));
 5506            }
 5507
 5508            let request_task = upstream_client.request_lsp(
 5509                project_id,
 5510                LSP_REQUEST_TIMEOUT,
 5511                cx.background_executor().clone(),
 5512                request.to_proto(project_id, buffer.read(cx)),
 5513            );
 5514            let buffer = buffer.clone();
 5515            cx.spawn(async move |weak_project, cx| {
 5516                let Some(project) = weak_project.upgrade() else {
 5517                    return Ok(None);
 5518                };
 5519                let Some(responses) = request_task.await? else {
 5520                    return Ok(None);
 5521                };
 5522
 5523                let locations = join_all(responses.payload.into_iter().map(|lsp_response| {
 5524                    GetReferences { position }.response_from_proto(
 5525                        lsp_response.response,
 5526                        project.clone(),
 5527                        buffer.clone(),
 5528                        cx.clone(),
 5529                    )
 5530                }))
 5531                .await
 5532                .into_iter()
 5533                .collect::<Result<Vec<Vec<_>>>>()?
 5534                .into_iter()
 5535                .flatten()
 5536                .dedup()
 5537                .collect();
 5538                Ok(Some(locations))
 5539            })
 5540        } else {
 5541            let references_task = self.request_multiple_lsp_locally(
 5542                buffer,
 5543                Some(position),
 5544                GetReferences { position },
 5545                cx,
 5546            );
 5547            cx.background_spawn(async move {
 5548                Ok(Some(
 5549                    references_task
 5550                        .await
 5551                        .into_iter()
 5552                        .flat_map(|(_, references)| references)
 5553                        .dedup()
 5554                        .collect(),
 5555                ))
 5556            })
 5557        }
 5558    }
 5559
 5560    pub fn code_actions(
 5561        &mut self,
 5562        buffer: &Entity<Buffer>,
 5563        range: Range<Anchor>,
 5564        kinds: Option<Vec<CodeActionKind>>,
 5565        cx: &mut Context<Self>,
 5566    ) -> Task<Result<Option<Vec<CodeAction>>>> {
 5567        if let Some((upstream_client, project_id)) = self.upstream_client() {
 5568            let request = GetCodeActions {
 5569                range: range.clone(),
 5570                kinds: kinds.clone(),
 5571            };
 5572            if !self.is_capable_for_proto_request(buffer, &request, cx) {
 5573                return Task::ready(Ok(None));
 5574            }
 5575            let request_task = upstream_client.request_lsp(
 5576                project_id,
 5577                LSP_REQUEST_TIMEOUT,
 5578                cx.background_executor().clone(),
 5579                request.to_proto(project_id, buffer.read(cx)),
 5580            );
 5581            let buffer = buffer.clone();
 5582            cx.spawn(async move |weak_project, cx| {
 5583                let Some(project) = weak_project.upgrade() else {
 5584                    return Ok(None);
 5585                };
 5586                let Some(responses) = request_task.await? else {
 5587                    return Ok(None);
 5588                };
 5589                let actions = join_all(responses.payload.into_iter().map(|response| {
 5590                    GetCodeActions {
 5591                        range: range.clone(),
 5592                        kinds: kinds.clone(),
 5593                    }
 5594                    .response_from_proto(
 5595                        response.response,
 5596                        project.clone(),
 5597                        buffer.clone(),
 5598                        cx.clone(),
 5599                    )
 5600                }))
 5601                .await;
 5602
 5603                Ok(Some(
 5604                    actions
 5605                        .into_iter()
 5606                        .collect::<Result<Vec<Vec<_>>>>()?
 5607                        .into_iter()
 5608                        .flatten()
 5609                        .collect(),
 5610                ))
 5611            })
 5612        } else {
 5613            let all_actions_task = self.request_multiple_lsp_locally(
 5614                buffer,
 5615                Some(range.start),
 5616                GetCodeActions { range, kinds },
 5617                cx,
 5618            );
 5619            cx.background_spawn(async move {
 5620                Ok(Some(
 5621                    all_actions_task
 5622                        .await
 5623                        .into_iter()
 5624                        .flat_map(|(_, actions)| actions)
 5625                        .collect(),
 5626                ))
 5627            })
 5628        }
 5629    }
 5630
 5631    pub fn code_lens_actions(
 5632        &mut self,
 5633        buffer: &Entity<Buffer>,
 5634        cx: &mut Context<Self>,
 5635    ) -> CodeLensTask {
 5636        let version_queried_for = buffer.read(cx).version();
 5637        let buffer_id = buffer.read(cx).remote_id();
 5638
 5639        if let Some(cached_data) = self.lsp_code_lens.get(&buffer_id)
 5640            && !version_queried_for.changed_since(&cached_data.lens_for_version)
 5641        {
 5642            let has_different_servers = self.as_local().is_some_and(|local| {
 5643                local
 5644                    .buffers_opened_in_servers
 5645                    .get(&buffer_id)
 5646                    .cloned()
 5647                    .unwrap_or_default()
 5648                    != cached_data.lens.keys().copied().collect()
 5649            });
 5650            if !has_different_servers {
 5651                return Task::ready(Ok(Some(
 5652                    cached_data.lens.values().flatten().cloned().collect(),
 5653                )))
 5654                .shared();
 5655            }
 5656        }
 5657
 5658        let lsp_data = self.lsp_code_lens.entry(buffer_id).or_default();
 5659        if let Some((updating_for, running_update)) = &lsp_data.update
 5660            && !version_queried_for.changed_since(updating_for)
 5661        {
 5662            return running_update.clone();
 5663        }
 5664        let buffer = buffer.clone();
 5665        let query_version_queried_for = version_queried_for.clone();
 5666        let new_task = cx
 5667            .spawn(async move |lsp_store, cx| {
 5668                cx.background_executor()
 5669                    .timer(Duration::from_millis(30))
 5670                    .await;
 5671                let fetched_lens = lsp_store
 5672                    .update(cx, |lsp_store, cx| lsp_store.fetch_code_lens(&buffer, cx))
 5673                    .map_err(Arc::new)?
 5674                    .await
 5675                    .context("fetching code lens")
 5676                    .map_err(Arc::new);
 5677                let fetched_lens = match fetched_lens {
 5678                    Ok(fetched_lens) => fetched_lens,
 5679                    Err(e) => {
 5680                        lsp_store
 5681                            .update(cx, |lsp_store, _| {
 5682                                lsp_store.lsp_code_lens.entry(buffer_id).or_default().update = None;
 5683                            })
 5684                            .ok();
 5685                        return Err(e);
 5686                    }
 5687                };
 5688
 5689                lsp_store
 5690                    .update(cx, |lsp_store, _| {
 5691                        let lsp_data = lsp_store.lsp_code_lens.entry(buffer_id).or_default();
 5692                        if let Some(fetched_lens) = fetched_lens {
 5693                            if lsp_data.lens_for_version == query_version_queried_for {
 5694                                lsp_data.lens.extend(fetched_lens);
 5695                            } else if !lsp_data
 5696                                .lens_for_version
 5697                                .changed_since(&query_version_queried_for)
 5698                            {
 5699                                lsp_data.lens_for_version = query_version_queried_for;
 5700                                lsp_data.lens = fetched_lens;
 5701                            }
 5702                        }
 5703                        lsp_data.update = None;
 5704                        Some(lsp_data.lens.values().flatten().cloned().collect())
 5705                    })
 5706                    .map_err(Arc::new)
 5707            })
 5708            .shared();
 5709        lsp_data.update = Some((version_queried_for, new_task.clone()));
 5710        new_task
 5711    }
 5712
 5713    fn fetch_code_lens(
 5714        &mut self,
 5715        buffer: &Entity<Buffer>,
 5716        cx: &mut Context<Self>,
 5717    ) -> Task<Result<Option<HashMap<LanguageServerId, Vec<CodeAction>>>>> {
 5718        if let Some((upstream_client, project_id)) = self.upstream_client() {
 5719            let request = GetCodeLens;
 5720            if !self.is_capable_for_proto_request(buffer, &request, cx) {
 5721                return Task::ready(Ok(None));
 5722            }
 5723            let request_task = upstream_client.request_lsp(
 5724                project_id,
 5725                LSP_REQUEST_TIMEOUT,
 5726                cx.background_executor().clone(),
 5727                request.to_proto(project_id, buffer.read(cx)),
 5728            );
 5729            let buffer = buffer.clone();
 5730            cx.spawn(async move |weak_lsp_store, cx| {
 5731                let Some(lsp_store) = weak_lsp_store.upgrade() else {
 5732                    return Ok(None);
 5733                };
 5734                let Some(responses) = request_task.await? else {
 5735                    return Ok(None);
 5736                };
 5737
 5738                let code_lens_actions = join_all(responses.payload.into_iter().map(|response| {
 5739                    let lsp_store = lsp_store.clone();
 5740                    let buffer = buffer.clone();
 5741                    let cx = cx.clone();
 5742                    async move {
 5743                        (
 5744                            LanguageServerId::from_proto(response.server_id),
 5745                            GetCodeLens
 5746                                .response_from_proto(response.response, lsp_store, buffer, cx)
 5747                                .await,
 5748                        )
 5749                    }
 5750                }))
 5751                .await;
 5752
 5753                let mut has_errors = false;
 5754                let code_lens_actions = code_lens_actions
 5755                    .into_iter()
 5756                    .filter_map(|(server_id, code_lens)| match code_lens {
 5757                        Ok(code_lens) => Some((server_id, code_lens)),
 5758                        Err(e) => {
 5759                            has_errors = true;
 5760                            log::error!("{e:#}");
 5761                            None
 5762                        }
 5763                    })
 5764                    .collect::<HashMap<_, _>>();
 5765                anyhow::ensure!(
 5766                    !has_errors || !code_lens_actions.is_empty(),
 5767                    "Failed to fetch code lens"
 5768                );
 5769                Ok(Some(code_lens_actions))
 5770            })
 5771        } else {
 5772            let code_lens_actions_task =
 5773                self.request_multiple_lsp_locally(buffer, None::<usize>, GetCodeLens, cx);
 5774            cx.background_spawn(async move {
 5775                Ok(Some(code_lens_actions_task.await.into_iter().collect()))
 5776            })
 5777        }
 5778    }
 5779
 5780    #[inline(never)]
 5781    pub fn completions(
 5782        &self,
 5783        buffer: &Entity<Buffer>,
 5784        position: PointUtf16,
 5785        context: CompletionContext,
 5786        cx: &mut Context<Self>,
 5787    ) -> Task<Result<Vec<CompletionResponse>>> {
 5788        let language_registry = self.languages.clone();
 5789
 5790        if let Some((upstream_client, project_id)) = self.upstream_client() {
 5791            let request = GetCompletions { position, context };
 5792            if !self.is_capable_for_proto_request(buffer, &request, cx) {
 5793                return Task::ready(Ok(Vec::new()));
 5794            }
 5795            let task = self.send_lsp_proto_request(
 5796                buffer.clone(),
 5797                upstream_client,
 5798                project_id,
 5799                request,
 5800                cx,
 5801            );
 5802            let language = buffer.read(cx).language().cloned();
 5803
 5804            // In the future, we should provide project guests with the names of LSP adapters,
 5805            // so that they can use the correct LSP adapter when computing labels. For now,
 5806            // guests just use the first LSP adapter associated with the buffer's language.
 5807            let lsp_adapter = language.as_ref().and_then(|language| {
 5808                language_registry
 5809                    .lsp_adapters(&language.name())
 5810                    .first()
 5811                    .cloned()
 5812            });
 5813
 5814            cx.foreground_executor().spawn(async move {
 5815                let completion_response = task.await?;
 5816                let completions = populate_labels_for_completions(
 5817                    completion_response.completions,
 5818                    language,
 5819                    lsp_adapter,
 5820                )
 5821                .await;
 5822                Ok(vec![CompletionResponse {
 5823                    completions,
 5824                    is_incomplete: completion_response.is_incomplete,
 5825                }])
 5826            })
 5827        } else if let Some(local) = self.as_local() {
 5828            let snapshot = buffer.read(cx).snapshot();
 5829            let offset = position.to_offset(&snapshot);
 5830            let scope = snapshot.language_scope_at(offset);
 5831            let language = snapshot.language().cloned();
 5832            let completion_settings = language_settings(
 5833                language.as_ref().map(|language| language.name()),
 5834                buffer.read(cx).file(),
 5835                cx,
 5836            )
 5837            .completions;
 5838            if !completion_settings.lsp {
 5839                return Task::ready(Ok(Vec::new()));
 5840            }
 5841
 5842            let server_ids: Vec<_> = buffer.update(cx, |buffer, cx| {
 5843                local
 5844                    .language_servers_for_buffer(buffer, cx)
 5845                    .filter(|(_, server)| server.capabilities().completion_provider.is_some())
 5846                    .filter(|(adapter, _)| {
 5847                        scope
 5848                            .as_ref()
 5849                            .map(|scope| scope.language_allowed(&adapter.name))
 5850                            .unwrap_or(true)
 5851                    })
 5852                    .map(|(_, server)| server.server_id())
 5853                    .collect()
 5854            });
 5855
 5856            let buffer = buffer.clone();
 5857            let lsp_timeout = completion_settings.lsp_fetch_timeout_ms;
 5858            let lsp_timeout = if lsp_timeout > 0 {
 5859                Some(Duration::from_millis(lsp_timeout))
 5860            } else {
 5861                None
 5862            };
 5863            cx.spawn(async move |this,  cx| {
 5864                let mut tasks = Vec::with_capacity(server_ids.len());
 5865                this.update(cx, |lsp_store, cx| {
 5866                    for server_id in server_ids {
 5867                        let lsp_adapter = lsp_store.language_server_adapter_for_id(server_id);
 5868                        let lsp_timeout = lsp_timeout
 5869                            .map(|lsp_timeout| cx.background_executor().timer(lsp_timeout));
 5870                        let mut timeout = cx.background_spawn(async move {
 5871                            match lsp_timeout {
 5872                                Some(lsp_timeout) => {
 5873                                    lsp_timeout.await;
 5874                                    true
 5875                                },
 5876                                None => false,
 5877                            }
 5878                        }).fuse();
 5879                        let mut lsp_request = lsp_store.request_lsp(
 5880                            buffer.clone(),
 5881                            LanguageServerToQuery::Other(server_id),
 5882                            GetCompletions {
 5883                                position,
 5884                                context: context.clone(),
 5885                            },
 5886                            cx,
 5887                        ).fuse();
 5888                        let new_task = cx.background_spawn(async move {
 5889                            select_biased! {
 5890                                response = lsp_request => anyhow::Ok(Some(response?)),
 5891                                timeout_happened = timeout => {
 5892                                    if timeout_happened {
 5893                                        log::warn!("Fetching completions from server {server_id} timed out, timeout ms: {}", completion_settings.lsp_fetch_timeout_ms);
 5894                                        Ok(None)
 5895                                    } else {
 5896                                        let completions = lsp_request.await?;
 5897                                        Ok(Some(completions))
 5898                                    }
 5899                                },
 5900                            }
 5901                        });
 5902                        tasks.push((lsp_adapter, new_task));
 5903                    }
 5904                })?;
 5905
 5906                let futures = tasks.into_iter().map(async |(lsp_adapter, task)| {
 5907                    let completion_response = task.await.ok()??;
 5908                    let completions = populate_labels_for_completions(
 5909                            completion_response.completions,
 5910                            language.clone(),
 5911                            lsp_adapter,
 5912                        )
 5913                        .await;
 5914                    Some(CompletionResponse {
 5915                        completions,
 5916                        is_incomplete: completion_response.is_incomplete,
 5917                    })
 5918                });
 5919
 5920                let responses: Vec<Option<CompletionResponse>> = join_all(futures).await;
 5921
 5922                Ok(responses.into_iter().flatten().collect())
 5923            })
 5924        } else {
 5925            Task::ready(Err(anyhow!("No upstream client or local language server")))
 5926        }
 5927    }
 5928
 5929    pub fn resolve_completions(
 5930        &self,
 5931        buffer: Entity<Buffer>,
 5932        completion_indices: Vec<usize>,
 5933        completions: Rc<RefCell<Box<[Completion]>>>,
 5934        cx: &mut Context<Self>,
 5935    ) -> Task<Result<bool>> {
 5936        let client = self.upstream_client();
 5937        let buffer_id = buffer.read(cx).remote_id();
 5938        let buffer_snapshot = buffer.read(cx).snapshot();
 5939
 5940        if !self.check_if_capable_for_proto_request(
 5941            &buffer,
 5942            GetCompletions::can_resolve_completions,
 5943            cx,
 5944        ) {
 5945            return Task::ready(Ok(false));
 5946        }
 5947        cx.spawn(async move |lsp_store, cx| {
 5948            let mut did_resolve = false;
 5949            if let Some((client, project_id)) = client {
 5950                for completion_index in completion_indices {
 5951                    let server_id = {
 5952                        let completion = &completions.borrow()[completion_index];
 5953                        completion.source.server_id()
 5954                    };
 5955                    if let Some(server_id) = server_id {
 5956                        if Self::resolve_completion_remote(
 5957                            project_id,
 5958                            server_id,
 5959                            buffer_id,
 5960                            completions.clone(),
 5961                            completion_index,
 5962                            client.clone(),
 5963                        )
 5964                        .await
 5965                        .log_err()
 5966                        .is_some()
 5967                        {
 5968                            did_resolve = true;
 5969                        }
 5970                    } else {
 5971                        resolve_word_completion(
 5972                            &buffer_snapshot,
 5973                            &mut completions.borrow_mut()[completion_index],
 5974                        );
 5975                    }
 5976                }
 5977            } else {
 5978                for completion_index in completion_indices {
 5979                    let server_id = {
 5980                        let completion = &completions.borrow()[completion_index];
 5981                        completion.source.server_id()
 5982                    };
 5983                    if let Some(server_id) = server_id {
 5984                        let server_and_adapter = lsp_store
 5985                            .read_with(cx, |lsp_store, _| {
 5986                                let server = lsp_store.language_server_for_id(server_id)?;
 5987                                let adapter =
 5988                                    lsp_store.language_server_adapter_for_id(server.server_id())?;
 5989                                Some((server, adapter))
 5990                            })
 5991                            .ok()
 5992                            .flatten();
 5993                        let Some((server, adapter)) = server_and_adapter else {
 5994                            continue;
 5995                        };
 5996
 5997                        let resolved = Self::resolve_completion_local(
 5998                            server,
 5999                            completions.clone(),
 6000                            completion_index,
 6001                        )
 6002                        .await
 6003                        .log_err()
 6004                        .is_some();
 6005                        if resolved {
 6006                            Self::regenerate_completion_labels(
 6007                                adapter,
 6008                                &buffer_snapshot,
 6009                                completions.clone(),
 6010                                completion_index,
 6011                            )
 6012                            .await
 6013                            .log_err();
 6014                            did_resolve = true;
 6015                        }
 6016                    } else {
 6017                        resolve_word_completion(
 6018                            &buffer_snapshot,
 6019                            &mut completions.borrow_mut()[completion_index],
 6020                        );
 6021                    }
 6022                }
 6023            }
 6024
 6025            Ok(did_resolve)
 6026        })
 6027    }
 6028
 6029    async fn resolve_completion_local(
 6030        server: Arc<lsp::LanguageServer>,
 6031        completions: Rc<RefCell<Box<[Completion]>>>,
 6032        completion_index: usize,
 6033    ) -> Result<()> {
 6034        let server_id = server.server_id();
 6035        if !GetCompletions::can_resolve_completions(&server.capabilities()) {
 6036            return Ok(());
 6037        }
 6038
 6039        let request = {
 6040            let completion = &completions.borrow()[completion_index];
 6041            match &completion.source {
 6042                CompletionSource::Lsp {
 6043                    lsp_completion,
 6044                    resolved,
 6045                    server_id: completion_server_id,
 6046                    ..
 6047                } => {
 6048                    if *resolved {
 6049                        return Ok(());
 6050                    }
 6051                    anyhow::ensure!(
 6052                        server_id == *completion_server_id,
 6053                        "server_id mismatch, querying completion resolve for {server_id} but completion server id is {completion_server_id}"
 6054                    );
 6055                    server.request::<lsp::request::ResolveCompletionItem>(*lsp_completion.clone())
 6056                }
 6057                CompletionSource::BufferWord { .. }
 6058                | CompletionSource::Dap { .. }
 6059                | CompletionSource::Custom => {
 6060                    return Ok(());
 6061                }
 6062            }
 6063        };
 6064        let resolved_completion = request
 6065            .await
 6066            .into_response()
 6067            .context("resolve completion")?;
 6068
 6069        // We must not use any data such as sortText, filterText, insertText and textEdit to edit `Completion` since they are not suppose change during resolve.
 6070        // Refer: https://microsoft.github.io/language-server-protocol/specifications/lsp/3.17/specification/#textDocument_completion
 6071
 6072        let mut completions = completions.borrow_mut();
 6073        let completion = &mut completions[completion_index];
 6074        if let CompletionSource::Lsp {
 6075            lsp_completion,
 6076            resolved,
 6077            server_id: completion_server_id,
 6078            ..
 6079        } = &mut completion.source
 6080        {
 6081            if *resolved {
 6082                return Ok(());
 6083            }
 6084            anyhow::ensure!(
 6085                server_id == *completion_server_id,
 6086                "server_id mismatch, applying completion resolve for {server_id} but completion server id is {completion_server_id}"
 6087            );
 6088            *lsp_completion = Box::new(resolved_completion);
 6089            *resolved = true;
 6090        }
 6091        Ok(())
 6092    }
 6093
 6094    async fn regenerate_completion_labels(
 6095        adapter: Arc<CachedLspAdapter>,
 6096        snapshot: &BufferSnapshot,
 6097        completions: Rc<RefCell<Box<[Completion]>>>,
 6098        completion_index: usize,
 6099    ) -> Result<()> {
 6100        let completion_item = completions.borrow()[completion_index]
 6101            .source
 6102            .lsp_completion(true)
 6103            .map(Cow::into_owned);
 6104        if let Some(lsp_documentation) = completion_item
 6105            .as_ref()
 6106            .and_then(|completion_item| completion_item.documentation.clone())
 6107        {
 6108            let mut completions = completions.borrow_mut();
 6109            let completion = &mut completions[completion_index];
 6110            completion.documentation = Some(lsp_documentation.into());
 6111        } else {
 6112            let mut completions = completions.borrow_mut();
 6113            let completion = &mut completions[completion_index];
 6114            completion.documentation = Some(CompletionDocumentation::Undocumented);
 6115        }
 6116
 6117        let mut new_label = match completion_item {
 6118            Some(completion_item) => {
 6119                // NB: Zed does not have `details` inside the completion resolve capabilities, but certain language servers violate the spec and do not return `details` immediately, e.g. https://github.com/yioneko/vtsls/issues/213
 6120                // So we have to update the label here anyway...
 6121                let language = snapshot.language();
 6122                match language {
 6123                    Some(language) => {
 6124                        adapter
 6125                            .labels_for_completions(
 6126                                std::slice::from_ref(&completion_item),
 6127                                language,
 6128                            )
 6129                            .await?
 6130                    }
 6131                    None => Vec::new(),
 6132                }
 6133                .pop()
 6134                .flatten()
 6135                .unwrap_or_else(|| {
 6136                    CodeLabel::fallback_for_completion(
 6137                        &completion_item,
 6138                        language.map(|language| language.as_ref()),
 6139                    )
 6140                })
 6141            }
 6142            None => CodeLabel::plain(
 6143                completions.borrow()[completion_index].new_text.clone(),
 6144                None,
 6145            ),
 6146        };
 6147        ensure_uniform_list_compatible_label(&mut new_label);
 6148
 6149        let mut completions = completions.borrow_mut();
 6150        let completion = &mut completions[completion_index];
 6151        if completion.label.filter_text() == new_label.filter_text() {
 6152            completion.label = new_label;
 6153        } else {
 6154            log::error!(
 6155                "Resolved completion changed display label from {} to {}. \
 6156                 Refusing to apply this because it changes the fuzzy match text from {} to {}",
 6157                completion.label.text(),
 6158                new_label.text(),
 6159                completion.label.filter_text(),
 6160                new_label.filter_text()
 6161            );
 6162        }
 6163
 6164        Ok(())
 6165    }
 6166
 6167    async fn resolve_completion_remote(
 6168        project_id: u64,
 6169        server_id: LanguageServerId,
 6170        buffer_id: BufferId,
 6171        completions: Rc<RefCell<Box<[Completion]>>>,
 6172        completion_index: usize,
 6173        client: AnyProtoClient,
 6174    ) -> Result<()> {
 6175        let lsp_completion = {
 6176            let completion = &completions.borrow()[completion_index];
 6177            match &completion.source {
 6178                CompletionSource::Lsp {
 6179                    lsp_completion,
 6180                    resolved,
 6181                    server_id: completion_server_id,
 6182                    ..
 6183                } => {
 6184                    anyhow::ensure!(
 6185                        server_id == *completion_server_id,
 6186                        "remote server_id mismatch, querying completion resolve for {server_id} but completion server id is {completion_server_id}"
 6187                    );
 6188                    if *resolved {
 6189                        return Ok(());
 6190                    }
 6191                    serde_json::to_string(lsp_completion).unwrap().into_bytes()
 6192                }
 6193                CompletionSource::Custom
 6194                | CompletionSource::Dap { .. }
 6195                | CompletionSource::BufferWord { .. } => {
 6196                    return Ok(());
 6197                }
 6198            }
 6199        };
 6200        let request = proto::ResolveCompletionDocumentation {
 6201            project_id,
 6202            language_server_id: server_id.0 as u64,
 6203            lsp_completion,
 6204            buffer_id: buffer_id.into(),
 6205        };
 6206
 6207        let response = client
 6208            .request(request)
 6209            .await
 6210            .context("completion documentation resolve proto request")?;
 6211        let resolved_lsp_completion = serde_json::from_slice(&response.lsp_completion)?;
 6212
 6213        let documentation = if response.documentation.is_empty() {
 6214            CompletionDocumentation::Undocumented
 6215        } else if response.documentation_is_markdown {
 6216            CompletionDocumentation::MultiLineMarkdown(response.documentation.into())
 6217        } else if response.documentation.lines().count() <= 1 {
 6218            CompletionDocumentation::SingleLine(response.documentation.into())
 6219        } else {
 6220            CompletionDocumentation::MultiLinePlainText(response.documentation.into())
 6221        };
 6222
 6223        let mut completions = completions.borrow_mut();
 6224        let completion = &mut completions[completion_index];
 6225        completion.documentation = Some(documentation);
 6226        if let CompletionSource::Lsp {
 6227            insert_range,
 6228            lsp_completion,
 6229            resolved,
 6230            server_id: completion_server_id,
 6231            lsp_defaults: _,
 6232        } = &mut completion.source
 6233        {
 6234            let completion_insert_range = response
 6235                .old_insert_start
 6236                .and_then(deserialize_anchor)
 6237                .zip(response.old_insert_end.and_then(deserialize_anchor));
 6238            *insert_range = completion_insert_range.map(|(start, end)| start..end);
 6239
 6240            if *resolved {
 6241                return Ok(());
 6242            }
 6243            anyhow::ensure!(
 6244                server_id == *completion_server_id,
 6245                "remote server_id mismatch, applying completion resolve for {server_id} but completion server id is {completion_server_id}"
 6246            );
 6247            *lsp_completion = Box::new(resolved_lsp_completion);
 6248            *resolved = true;
 6249        }
 6250
 6251        let replace_range = response
 6252            .old_replace_start
 6253            .and_then(deserialize_anchor)
 6254            .zip(response.old_replace_end.and_then(deserialize_anchor));
 6255        if let Some((old_replace_start, old_replace_end)) = replace_range
 6256            && !response.new_text.is_empty()
 6257        {
 6258            completion.new_text = response.new_text;
 6259            completion.replace_range = old_replace_start..old_replace_end;
 6260        }
 6261
 6262        Ok(())
 6263    }
 6264
 6265    pub fn apply_additional_edits_for_completion(
 6266        &self,
 6267        buffer_handle: Entity<Buffer>,
 6268        completions: Rc<RefCell<Box<[Completion]>>>,
 6269        completion_index: usize,
 6270        push_to_history: bool,
 6271        cx: &mut Context<Self>,
 6272    ) -> Task<Result<Option<Transaction>>> {
 6273        if let Some((client, project_id)) = self.upstream_client() {
 6274            let buffer = buffer_handle.read(cx);
 6275            let buffer_id = buffer.remote_id();
 6276            cx.spawn(async move |_, cx| {
 6277                let request = {
 6278                    let completion = completions.borrow()[completion_index].clone();
 6279                    proto::ApplyCompletionAdditionalEdits {
 6280                        project_id,
 6281                        buffer_id: buffer_id.into(),
 6282                        completion: Some(Self::serialize_completion(&CoreCompletion {
 6283                            replace_range: completion.replace_range,
 6284                            new_text: completion.new_text,
 6285                            source: completion.source,
 6286                        })),
 6287                    }
 6288                };
 6289
 6290                if let Some(transaction) = client.request(request).await?.transaction {
 6291                    let transaction = language::proto::deserialize_transaction(transaction)?;
 6292                    buffer_handle
 6293                        .update(cx, |buffer, _| {
 6294                            buffer.wait_for_edits(transaction.edit_ids.iter().copied())
 6295                        })?
 6296                        .await?;
 6297                    if push_to_history {
 6298                        buffer_handle.update(cx, |buffer, _| {
 6299                            buffer.push_transaction(transaction.clone(), Instant::now());
 6300                            buffer.finalize_last_transaction();
 6301                        })?;
 6302                    }
 6303                    Ok(Some(transaction))
 6304                } else {
 6305                    Ok(None)
 6306                }
 6307            })
 6308        } else {
 6309            let Some(server) = buffer_handle.update(cx, |buffer, cx| {
 6310                let completion = &completions.borrow()[completion_index];
 6311                let server_id = completion.source.server_id()?;
 6312                Some(
 6313                    self.language_server_for_local_buffer(buffer, server_id, cx)?
 6314                        .1
 6315                        .clone(),
 6316                )
 6317            }) else {
 6318                return Task::ready(Ok(None));
 6319            };
 6320
 6321            cx.spawn(async move |this, cx| {
 6322                Self::resolve_completion_local(
 6323                    server.clone(),
 6324                    completions.clone(),
 6325                    completion_index,
 6326                )
 6327                .await
 6328                .context("resolving completion")?;
 6329                let completion = completions.borrow()[completion_index].clone();
 6330                let additional_text_edits = completion
 6331                    .source
 6332                    .lsp_completion(true)
 6333                    .as_ref()
 6334                    .and_then(|lsp_completion| lsp_completion.additional_text_edits.clone());
 6335                if let Some(edits) = additional_text_edits {
 6336                    let edits = this
 6337                        .update(cx, |this, cx| {
 6338                            this.as_local_mut().unwrap().edits_from_lsp(
 6339                                &buffer_handle,
 6340                                edits,
 6341                                server.server_id(),
 6342                                None,
 6343                                cx,
 6344                            )
 6345                        })?
 6346                        .await?;
 6347
 6348                    buffer_handle.update(cx, |buffer, cx| {
 6349                        buffer.finalize_last_transaction();
 6350                        buffer.start_transaction();
 6351
 6352                        for (range, text) in edits {
 6353                            let primary = &completion.replace_range;
 6354                            let start_within = primary.start.cmp(&range.start, buffer).is_le()
 6355                                && primary.end.cmp(&range.start, buffer).is_ge();
 6356                            let end_within = range.start.cmp(&primary.end, buffer).is_le()
 6357                                && range.end.cmp(&primary.end, buffer).is_ge();
 6358
 6359                            //Skip additional edits which overlap with the primary completion edit
 6360                            //https://github.com/zed-industries/zed/pull/1871
 6361                            if !start_within && !end_within {
 6362                                buffer.edit([(range, text)], None, cx);
 6363                            }
 6364                        }
 6365
 6366                        let transaction = if buffer.end_transaction(cx).is_some() {
 6367                            let transaction = buffer.finalize_last_transaction().unwrap().clone();
 6368                            if !push_to_history {
 6369                                buffer.forget_transaction(transaction.id);
 6370                            }
 6371                            Some(transaction)
 6372                        } else {
 6373                            None
 6374                        };
 6375                        Ok(transaction)
 6376                    })?
 6377                } else {
 6378                    Ok(None)
 6379                }
 6380            })
 6381        }
 6382    }
 6383
 6384    pub fn pull_diagnostics(
 6385        &mut self,
 6386        buffer: Entity<Buffer>,
 6387        cx: &mut Context<Self>,
 6388    ) -> Task<Result<Option<Vec<LspPullDiagnostics>>>> {
 6389        let buffer_id = buffer.read(cx).remote_id();
 6390
 6391        if let Some((client, upstream_project_id)) = self.upstream_client() {
 6392            let request = GetDocumentDiagnostics {
 6393                previous_result_id: None,
 6394            };
 6395            if !self.is_capable_for_proto_request(&buffer, &request, cx) {
 6396                return Task::ready(Ok(None));
 6397            }
 6398            let request_task = client.request_lsp(
 6399                upstream_project_id,
 6400                LSP_REQUEST_TIMEOUT,
 6401                cx.background_executor().clone(),
 6402                request.to_proto(upstream_project_id, buffer.read(cx)),
 6403            );
 6404            cx.background_spawn(async move {
 6405                // Proto requests cause the diagnostics to be pulled from language server(s) on the local side
 6406                // and then, buffer state updated with the diagnostics received, which will be later propagated to the client.
 6407                // Do not attempt to further process the dummy responses here.
 6408                let _response = request_task.await?;
 6409                Ok(None)
 6410            })
 6411        } else {
 6412            let server_ids = buffer.update(cx, |buffer, cx| {
 6413                self.language_servers_for_local_buffer(buffer, cx)
 6414                    .map(|(_, server)| server.server_id())
 6415                    .collect::<Vec<_>>()
 6416            });
 6417            let pull_diagnostics = server_ids
 6418                .into_iter()
 6419                .map(|server_id| {
 6420                    let result_id = self.result_id(server_id, buffer_id, cx);
 6421                    self.request_lsp(
 6422                        buffer.clone(),
 6423                        LanguageServerToQuery::Other(server_id),
 6424                        GetDocumentDiagnostics {
 6425                            previous_result_id: result_id,
 6426                        },
 6427                        cx,
 6428                    )
 6429                })
 6430                .collect::<Vec<_>>();
 6431
 6432            cx.background_spawn(async move {
 6433                let mut responses = Vec::new();
 6434                for diagnostics in join_all(pull_diagnostics).await {
 6435                    responses.extend(diagnostics?);
 6436                }
 6437                Ok(Some(responses))
 6438            })
 6439        }
 6440    }
 6441
 6442    pub fn inlay_hints(
 6443        &mut self,
 6444        buffer: Entity<Buffer>,
 6445        range: Range<Anchor>,
 6446        cx: &mut Context<Self>,
 6447    ) -> Task<anyhow::Result<Vec<InlayHint>>> {
 6448        let range_start = range.start;
 6449        let range_end = range.end;
 6450        let buffer_id = buffer.read(cx).remote_id().into();
 6451        let request = InlayHints { range };
 6452
 6453        if let Some((client, project_id)) = self.upstream_client() {
 6454            if !self.is_capable_for_proto_request(&buffer, &request, cx) {
 6455                return Task::ready(Ok(Vec::new()));
 6456            }
 6457            let proto_request = proto::InlayHints {
 6458                project_id,
 6459                buffer_id,
 6460                start: Some(serialize_anchor(&range_start)),
 6461                end: Some(serialize_anchor(&range_end)),
 6462                version: serialize_version(&buffer.read(cx).version()),
 6463            };
 6464            cx.spawn(async move |project, cx| {
 6465                let response = client
 6466                    .request(proto_request)
 6467                    .await
 6468                    .context("inlay hints proto request")?;
 6469                LspCommand::response_from_proto(
 6470                    request,
 6471                    response,
 6472                    project.upgrade().context("No project")?,
 6473                    buffer.clone(),
 6474                    cx.clone(),
 6475                )
 6476                .await
 6477                .context("inlay hints proto response conversion")
 6478            })
 6479        } else {
 6480            let lsp_request_task = self.request_lsp(
 6481                buffer.clone(),
 6482                LanguageServerToQuery::FirstCapable,
 6483                request,
 6484                cx,
 6485            );
 6486            cx.spawn(async move |_, cx| {
 6487                buffer
 6488                    .update(cx, |buffer, _| {
 6489                        buffer.wait_for_edits(vec![range_start.timestamp, range_end.timestamp])
 6490                    })?
 6491                    .await
 6492                    .context("waiting for inlay hint request range edits")?;
 6493                lsp_request_task.await.context("inlay hints LSP request")
 6494            })
 6495        }
 6496    }
 6497
 6498    pub fn pull_diagnostics_for_buffer(
 6499        &mut self,
 6500        buffer: Entity<Buffer>,
 6501        cx: &mut Context<Self>,
 6502    ) -> Task<anyhow::Result<()>> {
 6503        let diagnostics = self.pull_diagnostics(buffer, cx);
 6504        cx.spawn(async move |lsp_store, cx| {
 6505            let Some(diagnostics) = diagnostics.await.context("pulling diagnostics")? else {
 6506                return Ok(());
 6507            };
 6508            lsp_store.update(cx, |lsp_store, cx| {
 6509                if lsp_store.as_local().is_none() {
 6510                    return;
 6511                }
 6512
 6513                let mut unchanged_buffers = HashSet::default();
 6514                let mut changed_buffers = HashSet::default();
 6515                let server_diagnostics_updates = diagnostics
 6516                    .into_iter()
 6517                    .filter_map(|diagnostics_set| match diagnostics_set {
 6518                        LspPullDiagnostics::Response {
 6519                            server_id,
 6520                            uri,
 6521                            diagnostics,
 6522                        } => Some((server_id, uri, diagnostics)),
 6523                        LspPullDiagnostics::Default => None,
 6524                    })
 6525                    .fold(
 6526                        HashMap::default(),
 6527                        |mut acc, (server_id, uri, diagnostics)| {
 6528                            let (result_id, diagnostics) = match diagnostics {
 6529                                PulledDiagnostics::Unchanged { result_id } => {
 6530                                    unchanged_buffers.insert(uri.clone());
 6531                                    (Some(result_id), Vec::new())
 6532                                }
 6533                                PulledDiagnostics::Changed {
 6534                                    result_id,
 6535                                    diagnostics,
 6536                                } => {
 6537                                    changed_buffers.insert(uri.clone());
 6538                                    (result_id, diagnostics)
 6539                                }
 6540                            };
 6541                            let disk_based_sources = Cow::Owned(
 6542                                lsp_store
 6543                                    .language_server_adapter_for_id(server_id)
 6544                                    .as_ref()
 6545                                    .map(|adapter| adapter.disk_based_diagnostic_sources.as_slice())
 6546                                    .unwrap_or(&[])
 6547                                    .to_vec(),
 6548                            );
 6549                            acc.entry(server_id).or_insert_with(Vec::new).push(
 6550                                DocumentDiagnosticsUpdate {
 6551                                    server_id,
 6552                                    diagnostics: lsp::PublishDiagnosticsParams {
 6553                                        uri,
 6554                                        diagnostics,
 6555                                        version: None,
 6556                                    },
 6557                                    result_id,
 6558                                    disk_based_sources,
 6559                                },
 6560                            );
 6561                            acc
 6562                        },
 6563                    );
 6564
 6565                for diagnostic_updates in server_diagnostics_updates.into_values() {
 6566                    lsp_store
 6567                        .merge_lsp_diagnostics(
 6568                            DiagnosticSourceKind::Pulled,
 6569                            diagnostic_updates,
 6570                            |buffer, old_diagnostic, cx| {
 6571                                File::from_dyn(buffer.file())
 6572                                    .and_then(|file| {
 6573                                        let abs_path = file.as_local()?.abs_path(cx);
 6574                                        lsp::Url::from_file_path(abs_path).ok()
 6575                                    })
 6576                                    .is_none_or(|buffer_uri| {
 6577                                        unchanged_buffers.contains(&buffer_uri)
 6578                                            || match old_diagnostic.source_kind {
 6579                                                DiagnosticSourceKind::Pulled => {
 6580                                                    !changed_buffers.contains(&buffer_uri)
 6581                                                }
 6582                                                DiagnosticSourceKind::Other
 6583                                                | DiagnosticSourceKind::Pushed => true,
 6584                                            }
 6585                                    })
 6586                            },
 6587                            cx,
 6588                        )
 6589                        .log_err();
 6590                }
 6591            })
 6592        })
 6593    }
 6594
 6595    pub fn document_colors(
 6596        &mut self,
 6597        fetch_strategy: LspFetchStrategy,
 6598        buffer: Entity<Buffer>,
 6599        cx: &mut Context<Self>,
 6600    ) -> Option<DocumentColorTask> {
 6601        let version_queried_for = buffer.read(cx).version();
 6602        let buffer_id = buffer.read(cx).remote_id();
 6603
 6604        match fetch_strategy {
 6605            LspFetchStrategy::IgnoreCache => {}
 6606            LspFetchStrategy::UseCache {
 6607                known_cache_version,
 6608            } => {
 6609                if let Some(cached_data) = self.lsp_document_colors.get(&buffer_id)
 6610                    && !version_queried_for.changed_since(&cached_data.colors_for_version)
 6611                {
 6612                    let has_different_servers = self.as_local().is_some_and(|local| {
 6613                        local
 6614                            .buffers_opened_in_servers
 6615                            .get(&buffer_id)
 6616                            .cloned()
 6617                            .unwrap_or_default()
 6618                            != cached_data.colors.keys().copied().collect()
 6619                    });
 6620                    if !has_different_servers {
 6621                        if Some(cached_data.cache_version) == known_cache_version {
 6622                            return None;
 6623                        } else {
 6624                            return Some(
 6625                                Task::ready(Ok(DocumentColors {
 6626                                    colors: cached_data
 6627                                        .colors
 6628                                        .values()
 6629                                        .flatten()
 6630                                        .cloned()
 6631                                        .collect(),
 6632                                    cache_version: Some(cached_data.cache_version),
 6633                                }))
 6634                                .shared(),
 6635                            );
 6636                        }
 6637                    }
 6638                }
 6639            }
 6640        }
 6641
 6642        let lsp_data = self.lsp_document_colors.entry(buffer_id).or_default();
 6643        if let Some((updating_for, running_update)) = &lsp_data.colors_update
 6644            && !version_queried_for.changed_since(updating_for)
 6645        {
 6646            return Some(running_update.clone());
 6647        }
 6648        let query_version_queried_for = version_queried_for.clone();
 6649        let new_task = cx
 6650            .spawn(async move |lsp_store, cx| {
 6651                cx.background_executor()
 6652                    .timer(Duration::from_millis(30))
 6653                    .await;
 6654                let fetched_colors = lsp_store
 6655                    .update(cx, |lsp_store, cx| {
 6656                        lsp_store.fetch_document_colors_for_buffer(&buffer, cx)
 6657                    })?
 6658                    .await
 6659                    .context("fetching document colors")
 6660                    .map_err(Arc::new);
 6661                let fetched_colors = match fetched_colors {
 6662                    Ok(fetched_colors) => {
 6663                        if fetch_strategy != LspFetchStrategy::IgnoreCache
 6664                            && Some(true)
 6665                                == buffer
 6666                                    .update(cx, |buffer, _| {
 6667                                        buffer.version() != query_version_queried_for
 6668                                    })
 6669                                    .ok()
 6670                        {
 6671                            return Ok(DocumentColors::default());
 6672                        }
 6673                        fetched_colors
 6674                    }
 6675                    Err(e) => {
 6676                        lsp_store
 6677                            .update(cx, |lsp_store, _| {
 6678                                lsp_store
 6679                                    .lsp_document_colors
 6680                                    .entry(buffer_id)
 6681                                    .or_default()
 6682                                    .colors_update = None;
 6683                            })
 6684                            .ok();
 6685                        return Err(e);
 6686                    }
 6687                };
 6688
 6689                lsp_store
 6690                    .update(cx, |lsp_store, _| {
 6691                        let lsp_data = lsp_store.lsp_document_colors.entry(buffer_id).or_default();
 6692
 6693                        if let Some(fetched_colors) = fetched_colors {
 6694                            if lsp_data.colors_for_version == query_version_queried_for {
 6695                                lsp_data.colors.extend(fetched_colors);
 6696                                lsp_data.cache_version += 1;
 6697                            } else if !lsp_data
 6698                                .colors_for_version
 6699                                .changed_since(&query_version_queried_for)
 6700                            {
 6701                                lsp_data.colors_for_version = query_version_queried_for;
 6702                                lsp_data.colors = fetched_colors;
 6703                                lsp_data.cache_version += 1;
 6704                            }
 6705                        }
 6706                        lsp_data.colors_update = None;
 6707                        let colors = lsp_data
 6708                            .colors
 6709                            .values()
 6710                            .flatten()
 6711                            .cloned()
 6712                            .collect::<HashSet<_>>();
 6713                        DocumentColors {
 6714                            colors,
 6715                            cache_version: Some(lsp_data.cache_version),
 6716                        }
 6717                    })
 6718                    .map_err(Arc::new)
 6719            })
 6720            .shared();
 6721        lsp_data.colors_update = Some((version_queried_for, new_task.clone()));
 6722        Some(new_task)
 6723    }
 6724
 6725    fn fetch_document_colors_for_buffer(
 6726        &mut self,
 6727        buffer: &Entity<Buffer>,
 6728        cx: &mut Context<Self>,
 6729    ) -> Task<anyhow::Result<Option<HashMap<LanguageServerId, HashSet<DocumentColor>>>>> {
 6730        if let Some((client, project_id)) = self.upstream_client() {
 6731            let request = GetDocumentColor {};
 6732            if !self.is_capable_for_proto_request(buffer, &request, cx) {
 6733                return Task::ready(Ok(None));
 6734            }
 6735
 6736            let request_task = client.request_lsp(
 6737                project_id,
 6738                LSP_REQUEST_TIMEOUT,
 6739                cx.background_executor().clone(),
 6740                request.to_proto(project_id, buffer.read(cx)),
 6741            );
 6742            let buffer = buffer.clone();
 6743            cx.spawn(async move |lsp_store, cx| {
 6744                let Some(project) = lsp_store.upgrade() else {
 6745                    return Ok(None);
 6746                };
 6747                let colors = join_all(
 6748                    request_task
 6749                        .await
 6750                        .log_err()
 6751                        .flatten()
 6752                        .map(|response| response.payload)
 6753                        .unwrap_or_default()
 6754                        .into_iter()
 6755                        .map(|color_response| {
 6756                            let response = request.response_from_proto(
 6757                                color_response.response,
 6758                                project.clone(),
 6759                                buffer.clone(),
 6760                                cx.clone(),
 6761                            );
 6762                            async move {
 6763                                (
 6764                                    LanguageServerId::from_proto(color_response.server_id),
 6765                                    response.await.log_err().unwrap_or_default(),
 6766                                )
 6767                            }
 6768                        }),
 6769                )
 6770                .await
 6771                .into_iter()
 6772                .fold(HashMap::default(), |mut acc, (server_id, colors)| {
 6773                    acc.entry(server_id)
 6774                        .or_insert_with(HashSet::default)
 6775                        .extend(colors);
 6776                    acc
 6777                });
 6778                Ok(Some(colors))
 6779            })
 6780        } else {
 6781            let document_colors_task =
 6782                self.request_multiple_lsp_locally(buffer, None::<usize>, GetDocumentColor, cx);
 6783            cx.background_spawn(async move {
 6784                Ok(Some(
 6785                    document_colors_task
 6786                        .await
 6787                        .into_iter()
 6788                        .fold(HashMap::default(), |mut acc, (server_id, colors)| {
 6789                            acc.entry(server_id)
 6790                                .or_insert_with(HashSet::default)
 6791                                .extend(colors);
 6792                            acc
 6793                        })
 6794                        .into_iter()
 6795                        .collect(),
 6796                ))
 6797            })
 6798        }
 6799    }
 6800
 6801    pub fn signature_help<T: ToPointUtf16>(
 6802        &mut self,
 6803        buffer: &Entity<Buffer>,
 6804        position: T,
 6805        cx: &mut Context<Self>,
 6806    ) -> Task<Option<Vec<SignatureHelp>>> {
 6807        let position = position.to_point_utf16(buffer.read(cx));
 6808
 6809        if let Some((client, upstream_project_id)) = self.upstream_client() {
 6810            let request = GetSignatureHelp { position };
 6811            if !self.is_capable_for_proto_request(buffer, &request, cx) {
 6812                return Task::ready(None);
 6813            }
 6814            let request_task = client.request_lsp(
 6815                upstream_project_id,
 6816                LSP_REQUEST_TIMEOUT,
 6817                cx.background_executor().clone(),
 6818                request.to_proto(upstream_project_id, buffer.read(cx)),
 6819            );
 6820            let buffer = buffer.clone();
 6821            cx.spawn(async move |weak_project, cx| {
 6822                let project = weak_project.upgrade()?;
 6823                let signatures = join_all(
 6824                    request_task
 6825                        .await
 6826                        .log_err()
 6827                        .flatten()
 6828                        .map(|response| response.payload)
 6829                        .unwrap_or_default()
 6830                        .into_iter()
 6831                        .map(|response| {
 6832                            let response = GetSignatureHelp { position }.response_from_proto(
 6833                                response.response,
 6834                                project.clone(),
 6835                                buffer.clone(),
 6836                                cx.clone(),
 6837                            );
 6838                            async move { response.await.log_err().flatten() }
 6839                        }),
 6840                )
 6841                .await
 6842                .into_iter()
 6843                .flatten()
 6844                .collect();
 6845                Some(signatures)
 6846            })
 6847        } else {
 6848            let all_actions_task = self.request_multiple_lsp_locally(
 6849                buffer,
 6850                Some(position),
 6851                GetSignatureHelp { position },
 6852                cx,
 6853            );
 6854            cx.background_spawn(async move {
 6855                Some(
 6856                    all_actions_task
 6857                        .await
 6858                        .into_iter()
 6859                        .flat_map(|(_, actions)| actions)
 6860                        .collect::<Vec<_>>(),
 6861                )
 6862            })
 6863        }
 6864    }
 6865
 6866    pub fn hover(
 6867        &mut self,
 6868        buffer: &Entity<Buffer>,
 6869        position: PointUtf16,
 6870        cx: &mut Context<Self>,
 6871    ) -> Task<Option<Vec<Hover>>> {
 6872        if let Some((client, upstream_project_id)) = self.upstream_client() {
 6873            let request = GetHover { position };
 6874            if !self.is_capable_for_proto_request(buffer, &request, cx) {
 6875                return Task::ready(None);
 6876            }
 6877            let request_task = client.request_lsp(
 6878                upstream_project_id,
 6879                LSP_REQUEST_TIMEOUT,
 6880                cx.background_executor().clone(),
 6881                request.to_proto(upstream_project_id, buffer.read(cx)),
 6882            );
 6883            let buffer = buffer.clone();
 6884            cx.spawn(async move |weak_project, cx| {
 6885                let project = weak_project.upgrade()?;
 6886                let hovers = join_all(
 6887                    request_task
 6888                        .await
 6889                        .log_err()
 6890                        .flatten()
 6891                        .map(|response| response.payload)
 6892                        .unwrap_or_default()
 6893                        .into_iter()
 6894                        .map(|response| {
 6895                            let response = GetHover { position }.response_from_proto(
 6896                                response.response,
 6897                                project.clone(),
 6898                                buffer.clone(),
 6899                                cx.clone(),
 6900                            );
 6901                            async move {
 6902                                response
 6903                                    .await
 6904                                    .log_err()
 6905                                    .flatten()
 6906                                    .and_then(remove_empty_hover_blocks)
 6907                            }
 6908                        }),
 6909                )
 6910                .await
 6911                .into_iter()
 6912                .flatten()
 6913                .collect();
 6914                Some(hovers)
 6915            })
 6916        } else {
 6917            let all_actions_task = self.request_multiple_lsp_locally(
 6918                buffer,
 6919                Some(position),
 6920                GetHover { position },
 6921                cx,
 6922            );
 6923            cx.background_spawn(async move {
 6924                Some(
 6925                    all_actions_task
 6926                        .await
 6927                        .into_iter()
 6928                        .filter_map(|(_, hover)| remove_empty_hover_blocks(hover?))
 6929                        .collect::<Vec<Hover>>(),
 6930                )
 6931            })
 6932        }
 6933    }
 6934
 6935    pub fn symbols(&self, query: &str, cx: &mut Context<Self>) -> Task<Result<Vec<Symbol>>> {
 6936        let language_registry = self.languages.clone();
 6937
 6938        if let Some((upstream_client, project_id)) = self.upstream_client().as_ref() {
 6939            let request = upstream_client.request(proto::GetProjectSymbols {
 6940                project_id: *project_id,
 6941                query: query.to_string(),
 6942            });
 6943            cx.foreground_executor().spawn(async move {
 6944                let response = request.await?;
 6945                let mut symbols = Vec::new();
 6946                let core_symbols = response
 6947                    .symbols
 6948                    .into_iter()
 6949                    .filter_map(|symbol| Self::deserialize_symbol(symbol).log_err())
 6950                    .collect::<Vec<_>>();
 6951                populate_labels_for_symbols(core_symbols, &language_registry, None, &mut symbols)
 6952                    .await;
 6953                Ok(symbols)
 6954            })
 6955        } else if let Some(local) = self.as_local() {
 6956            struct WorkspaceSymbolsResult {
 6957                server_id: LanguageServerId,
 6958                lsp_adapter: Arc<CachedLspAdapter>,
 6959                worktree: WeakEntity<Worktree>,
 6960                worktree_abs_path: Arc<Path>,
 6961                lsp_symbols: Vec<(String, SymbolKind, lsp::Location)>,
 6962            }
 6963
 6964            let mut requests = Vec::new();
 6965            let mut requested_servers = BTreeSet::new();
 6966            for (seed, state) in local.language_server_ids.iter() {
 6967                let Some(worktree_handle) = self
 6968                    .worktree_store
 6969                    .read(cx)
 6970                    .worktree_for_id(seed.worktree_id, cx)
 6971                else {
 6972                    continue;
 6973                };
 6974                let worktree = worktree_handle.read(cx);
 6975                if !worktree.is_visible() {
 6976                    continue;
 6977                }
 6978
 6979                if !requested_servers.insert(state.id) {
 6980                    continue;
 6981                }
 6982
 6983                let (lsp_adapter, server) = match local.language_servers.get(&state.id) {
 6984                    Some(LanguageServerState::Running {
 6985                        adapter, server, ..
 6986                    }) => (adapter.clone(), server),
 6987
 6988                    _ => continue,
 6989                };
 6990                let supports_workspace_symbol_request =
 6991                    match server.capabilities().workspace_symbol_provider {
 6992                        Some(OneOf::Left(supported)) => supported,
 6993                        Some(OneOf::Right(_)) => true,
 6994                        None => false,
 6995                    };
 6996                if !supports_workspace_symbol_request {
 6997                    continue;
 6998                }
 6999                let worktree_abs_path = worktree.abs_path().clone();
 7000                let worktree_handle = worktree_handle.clone();
 7001                let server_id = server.server_id();
 7002                requests.push(
 7003                        server
 7004                            .request::<lsp::request::WorkspaceSymbolRequest>(
 7005                                lsp::WorkspaceSymbolParams {
 7006                                    query: query.to_string(),
 7007                                    ..Default::default()
 7008                                },
 7009                            )
 7010                            .map(move |response| {
 7011                                let lsp_symbols = response.into_response()
 7012                                    .context("workspace symbols request")
 7013                                    .log_err()
 7014                                    .flatten()
 7015                                    .map(|symbol_response| match symbol_response {
 7016                                        lsp::WorkspaceSymbolResponse::Flat(flat_responses) => {
 7017                                            flat_responses.into_iter().map(|lsp_symbol| {
 7018                                            (lsp_symbol.name, lsp_symbol.kind, lsp_symbol.location)
 7019                                            }).collect::<Vec<_>>()
 7020                                        }
 7021                                        lsp::WorkspaceSymbolResponse::Nested(nested_responses) => {
 7022                                            nested_responses.into_iter().filter_map(|lsp_symbol| {
 7023                                                let location = match lsp_symbol.location {
 7024                                                    OneOf::Left(location) => location,
 7025                                                    OneOf::Right(_) => {
 7026                                                        log::error!("Unexpected: client capabilities forbid symbol resolutions in workspace.symbol.resolveSupport");
 7027                                                        return None
 7028                                                    }
 7029                                                };
 7030                                                Some((lsp_symbol.name, lsp_symbol.kind, location))
 7031                                            }).collect::<Vec<_>>()
 7032                                        }
 7033                                    }).unwrap_or_default();
 7034
 7035                                WorkspaceSymbolsResult {
 7036                                    server_id,
 7037                                    lsp_adapter,
 7038                                    worktree: worktree_handle.downgrade(),
 7039                                    worktree_abs_path,
 7040                                    lsp_symbols,
 7041                                }
 7042                            }),
 7043                    );
 7044            }
 7045
 7046            cx.spawn(async move |this, cx| {
 7047                let responses = futures::future::join_all(requests).await;
 7048                let this = match this.upgrade() {
 7049                    Some(this) => this,
 7050                    None => return Ok(Vec::new()),
 7051                };
 7052
 7053                let mut symbols = Vec::new();
 7054                for result in responses {
 7055                    let core_symbols = this.update(cx, |this, cx| {
 7056                        result
 7057                            .lsp_symbols
 7058                            .into_iter()
 7059                            .filter_map(|(symbol_name, symbol_kind, symbol_location)| {
 7060                                let abs_path = symbol_location.uri.to_file_path().ok()?;
 7061                                let source_worktree = result.worktree.upgrade()?;
 7062                                let source_worktree_id = source_worktree.read(cx).id();
 7063
 7064                                let path;
 7065                                let worktree;
 7066                                if let Some((tree, rel_path)) =
 7067                                    this.worktree_store.read(cx).find_worktree(&abs_path, cx)
 7068                                {
 7069                                    worktree = tree;
 7070                                    path = rel_path;
 7071                                } else {
 7072                                    worktree = source_worktree;
 7073                                    path = relativize_path(&result.worktree_abs_path, &abs_path);
 7074                                }
 7075
 7076                                let worktree_id = worktree.read(cx).id();
 7077                                let project_path = ProjectPath {
 7078                                    worktree_id,
 7079                                    path: path.into(),
 7080                                };
 7081                                let signature = this.symbol_signature(&project_path);
 7082                                Some(CoreSymbol {
 7083                                    source_language_server_id: result.server_id,
 7084                                    language_server_name: result.lsp_adapter.name.clone(),
 7085                                    source_worktree_id,
 7086                                    path: project_path,
 7087                                    kind: symbol_kind,
 7088                                    name: symbol_name,
 7089                                    range: range_from_lsp(symbol_location.range),
 7090                                    signature,
 7091                                })
 7092                            })
 7093                            .collect()
 7094                    })?;
 7095
 7096                    populate_labels_for_symbols(
 7097                        core_symbols,
 7098                        &language_registry,
 7099                        Some(result.lsp_adapter),
 7100                        &mut symbols,
 7101                    )
 7102                    .await;
 7103                }
 7104
 7105                Ok(symbols)
 7106            })
 7107        } else {
 7108            Task::ready(Err(anyhow!("No upstream client or local language server")))
 7109        }
 7110    }
 7111
 7112    pub fn diagnostic_summary(&self, include_ignored: bool, cx: &App) -> DiagnosticSummary {
 7113        let mut summary = DiagnosticSummary::default();
 7114        for (_, _, path_summary) in self.diagnostic_summaries(include_ignored, cx) {
 7115            summary.error_count += path_summary.error_count;
 7116            summary.warning_count += path_summary.warning_count;
 7117        }
 7118        summary
 7119    }
 7120
 7121    pub fn diagnostic_summaries<'a>(
 7122        &'a self,
 7123        include_ignored: bool,
 7124        cx: &'a App,
 7125    ) -> impl Iterator<Item = (ProjectPath, LanguageServerId, DiagnosticSummary)> + 'a {
 7126        self.worktree_store
 7127            .read(cx)
 7128            .visible_worktrees(cx)
 7129            .filter_map(|worktree| {
 7130                let worktree = worktree.read(cx);
 7131                Some((worktree, self.diagnostic_summaries.get(&worktree.id())?))
 7132            })
 7133            .flat_map(move |(worktree, summaries)| {
 7134                let worktree_id = worktree.id();
 7135                summaries
 7136                    .iter()
 7137                    .filter(move |(path, _)| {
 7138                        include_ignored
 7139                            || worktree
 7140                                .entry_for_path(path.as_ref())
 7141                                .is_some_and(|entry| !entry.is_ignored)
 7142                    })
 7143                    .flat_map(move |(path, summaries)| {
 7144                        summaries.iter().map(move |(server_id, summary)| {
 7145                            (
 7146                                ProjectPath {
 7147                                    worktree_id,
 7148                                    path: path.clone(),
 7149                                },
 7150                                *server_id,
 7151                                *summary,
 7152                            )
 7153                        })
 7154                    })
 7155            })
 7156    }
 7157
 7158    pub fn on_buffer_edited(
 7159        &mut self,
 7160        buffer: Entity<Buffer>,
 7161        cx: &mut Context<Self>,
 7162    ) -> Option<()> {
 7163        let language_servers: Vec<_> = buffer.update(cx, |buffer, cx| {
 7164            Some(
 7165                self.as_local()?
 7166                    .language_servers_for_buffer(buffer, cx)
 7167                    .map(|i| i.1.clone())
 7168                    .collect(),
 7169            )
 7170        })?;
 7171
 7172        let buffer = buffer.read(cx);
 7173        let file = File::from_dyn(buffer.file())?;
 7174        let abs_path = file.as_local()?.abs_path(cx);
 7175        let uri = lsp::Url::from_file_path(abs_path).unwrap();
 7176        let next_snapshot = buffer.text_snapshot();
 7177        for language_server in language_servers {
 7178            let language_server = language_server.clone();
 7179
 7180            let buffer_snapshots = self
 7181                .as_local_mut()
 7182                .unwrap()
 7183                .buffer_snapshots
 7184                .get_mut(&buffer.remote_id())
 7185                .and_then(|m| m.get_mut(&language_server.server_id()))?;
 7186            let previous_snapshot = buffer_snapshots.last()?;
 7187
 7188            let build_incremental_change = || {
 7189                buffer
 7190                    .edits_since::<Dimensions<PointUtf16, usize>>(
 7191                        previous_snapshot.snapshot.version(),
 7192                    )
 7193                    .map(|edit| {
 7194                        let edit_start = edit.new.start.0;
 7195                        let edit_end = edit_start + (edit.old.end.0 - edit.old.start.0);
 7196                        let new_text = next_snapshot
 7197                            .text_for_range(edit.new.start.1..edit.new.end.1)
 7198                            .collect();
 7199                        lsp::TextDocumentContentChangeEvent {
 7200                            range: Some(lsp::Range::new(
 7201                                point_to_lsp(edit_start),
 7202                                point_to_lsp(edit_end),
 7203                            )),
 7204                            range_length: None,
 7205                            text: new_text,
 7206                        }
 7207                    })
 7208                    .collect()
 7209            };
 7210
 7211            let document_sync_kind = {
 7212                let dyn_caps = language_server.dynamic_capabilities();
 7213                let dynamic = dyn_caps
 7214                    .text_document_sync_did_change
 7215                    .as_ref()
 7216                    .and_then(|m| {
 7217                        if m.is_empty() {
 7218                            None
 7219                        } else {
 7220                            let mut best: Option<lsp::TextDocumentSyncKind> = None;
 7221                            for kind in m.values() {
 7222                                best = Some(match (best, kind) {
 7223                                    (None, k) => *k,
 7224                                    (
 7225                                        Some(lsp::TextDocumentSyncKind::FULL),
 7226                                        lsp::TextDocumentSyncKind::INCREMENTAL,
 7227                                    ) => lsp::TextDocumentSyncKind::INCREMENTAL,
 7228                                    (Some(curr), _) => curr,
 7229                                });
 7230                            }
 7231                            best
 7232                        }
 7233                    });
 7234                dynamic.or_else(|| {
 7235                    language_server
 7236                        .capabilities()
 7237                        .text_document_sync
 7238                        .as_ref()
 7239                        .and_then(|sync| match sync {
 7240                            lsp::TextDocumentSyncCapability::Kind(kind) => Some(*kind),
 7241                            lsp::TextDocumentSyncCapability::Options(options) => options.change,
 7242                        })
 7243                })
 7244            };
 7245
 7246            let content_changes: Vec<_> = match document_sync_kind {
 7247                Some(lsp::TextDocumentSyncKind::FULL) => {
 7248                    vec![lsp::TextDocumentContentChangeEvent {
 7249                        range: None,
 7250                        range_length: None,
 7251                        text: next_snapshot.text(),
 7252                    }]
 7253                }
 7254                Some(lsp::TextDocumentSyncKind::INCREMENTAL) => build_incremental_change(),
 7255                _ => {
 7256                    #[cfg(any(test, feature = "test-support"))]
 7257                    {
 7258                        build_incremental_change()
 7259                    }
 7260
 7261                    #[cfg(not(any(test, feature = "test-support")))]
 7262                    {
 7263                        continue;
 7264                    }
 7265                }
 7266            };
 7267
 7268            let next_version = previous_snapshot.version + 1;
 7269            buffer_snapshots.push(LspBufferSnapshot {
 7270                version: next_version,
 7271                snapshot: next_snapshot.clone(),
 7272            });
 7273
 7274            language_server
 7275                .notify::<lsp::notification::DidChangeTextDocument>(
 7276                    &lsp::DidChangeTextDocumentParams {
 7277                        text_document: lsp::VersionedTextDocumentIdentifier::new(
 7278                            uri.clone(),
 7279                            next_version,
 7280                        ),
 7281                        content_changes,
 7282                    },
 7283                )
 7284                .ok();
 7285            self.pull_workspace_diagnostics(language_server.server_id());
 7286        }
 7287
 7288        None
 7289    }
 7290
 7291    pub fn on_buffer_saved(
 7292        &mut self,
 7293        buffer: Entity<Buffer>,
 7294        cx: &mut Context<Self>,
 7295    ) -> Option<()> {
 7296        let file = File::from_dyn(buffer.read(cx).file())?;
 7297        let worktree_id = file.worktree_id(cx);
 7298        let abs_path = file.as_local()?.abs_path(cx);
 7299        let text_document = lsp::TextDocumentIdentifier {
 7300            uri: file_path_to_lsp_url(&abs_path).log_err()?,
 7301        };
 7302        let local = self.as_local()?;
 7303
 7304        for server in local.language_servers_for_worktree(worktree_id) {
 7305            if let Some(include_text) = include_text(server.as_ref()) {
 7306                let text = if include_text {
 7307                    Some(buffer.read(cx).text())
 7308                } else {
 7309                    None
 7310                };
 7311                server
 7312                    .notify::<lsp::notification::DidSaveTextDocument>(
 7313                        &lsp::DidSaveTextDocumentParams {
 7314                            text_document: text_document.clone(),
 7315                            text,
 7316                        },
 7317                    )
 7318                    .ok();
 7319            }
 7320        }
 7321
 7322        let language_servers = buffer.update(cx, |buffer, cx| {
 7323            local.language_server_ids_for_buffer(buffer, cx)
 7324        });
 7325        for language_server_id in language_servers {
 7326            self.simulate_disk_based_diagnostics_events_if_needed(language_server_id, cx);
 7327        }
 7328
 7329        None
 7330    }
 7331
 7332    async fn refresh_workspace_configurations(
 7333        lsp_store: &WeakEntity<Self>,
 7334        fs: Arc<dyn Fs>,
 7335        cx: &mut AsyncApp,
 7336    ) {
 7337        maybe!(async move {
 7338            let mut refreshed_servers = HashSet::default();
 7339            let servers = lsp_store
 7340                .update(cx, |lsp_store, cx| {
 7341                    let local = lsp_store.as_local()?;
 7342
 7343                    let servers = local
 7344                        .language_server_ids
 7345                        .iter()
 7346                        .filter_map(|(seed, state)| {
 7347                            let worktree = lsp_store
 7348                                .worktree_store
 7349                                .read(cx)
 7350                                .worktree_for_id(seed.worktree_id, cx);
 7351                            let delegate: Arc<dyn LspAdapterDelegate> =
 7352                                worktree.map(|worktree| {
 7353                                    LocalLspAdapterDelegate::new(
 7354                                        local.languages.clone(),
 7355                                        &local.environment,
 7356                                        cx.weak_entity(),
 7357                                        &worktree,
 7358                                        local.http_client.clone(),
 7359                                        local.fs.clone(),
 7360                                        cx,
 7361                                    )
 7362                                })?;
 7363                            let server_id = state.id;
 7364
 7365                            let states = local.language_servers.get(&server_id)?;
 7366
 7367                            match states {
 7368                                LanguageServerState::Starting { .. } => None,
 7369                                LanguageServerState::Running {
 7370                                    adapter, server, ..
 7371                                } => {
 7372                                    let fs = fs.clone();
 7373
 7374                                    let adapter = adapter.clone();
 7375                                    let server = server.clone();
 7376                                    refreshed_servers.insert(server.name());
 7377                                    let toolchain = seed.toolchain.clone();
 7378                                    Some(cx.spawn(async move |_, cx| {
 7379                                        let settings =
 7380                                            LocalLspStore::workspace_configuration_for_adapter(
 7381                                                adapter.adapter.clone(),
 7382                                                fs.as_ref(),
 7383                                                &delegate,
 7384                                                toolchain,
 7385                                                cx,
 7386                                            )
 7387                                            .await
 7388                                            .ok()?;
 7389                                        server
 7390                                            .notify::<lsp::notification::DidChangeConfiguration>(
 7391                                                &lsp::DidChangeConfigurationParams { settings },
 7392                                            )
 7393                                            .ok()?;
 7394                                        Some(())
 7395                                    }))
 7396                                }
 7397                            }
 7398                        })
 7399                        .collect::<Vec<_>>();
 7400
 7401                    Some(servers)
 7402                })
 7403                .ok()
 7404                .flatten()?;
 7405
 7406            log::debug!("Refreshing workspace configurations for servers {refreshed_servers:?}");
 7407            // TODO this asynchronous job runs concurrently with extension (de)registration and may take enough time for a certain extension
 7408            // to stop and unregister its language server wrapper.
 7409            // This is racy : an extension might have already removed all `local.language_servers` state, but here we `.clone()` and hold onto it anyway.
 7410            // This now causes errors in the logs, we should find a way to remove such servers from the processing everywhere.
 7411            let _: Vec<Option<()>> = join_all(servers).await;
 7412
 7413            Some(())
 7414        })
 7415        .await;
 7416    }
 7417
 7418    fn maintain_workspace_config(
 7419        fs: Arc<dyn Fs>,
 7420        external_refresh_requests: watch::Receiver<()>,
 7421        cx: &mut Context<Self>,
 7422    ) -> Task<Result<()>> {
 7423        let (mut settings_changed_tx, mut settings_changed_rx) = watch::channel();
 7424        let _ = postage::stream::Stream::try_recv(&mut settings_changed_rx);
 7425
 7426        let settings_observation = cx.observe_global::<SettingsStore>(move |_, _| {
 7427            *settings_changed_tx.borrow_mut() = ();
 7428        });
 7429
 7430        let mut joint_future =
 7431            futures::stream::select(settings_changed_rx, external_refresh_requests);
 7432        // Multiple things can happen when a workspace environment (selected toolchain + settings) change:
 7433        // - We might shut down a language server if it's no longer enabled for a given language (and there are no buffers using it otherwise).
 7434        // - We might also shut it down when the workspace configuration of all of the users of a given language server converges onto that of the other.
 7435        // - In the same vein, we might also decide to start a new language server if the workspace configuration *diverges* from the other.
 7436        // - In the easiest case (where we're not wrangling the lifetime of a language server anyhow), if none of the roots of a single language server diverge in their configuration,
 7437        // but it is still different to what we had before, we're gonna send out a workspace configuration update.
 7438        cx.spawn(async move |this, cx| {
 7439            while let Some(()) = joint_future.next().await {
 7440                this.update(cx, |this, cx| {
 7441                    this.refresh_server_tree(cx);
 7442                })
 7443                .ok();
 7444
 7445                Self::refresh_workspace_configurations(&this, fs.clone(), cx).await;
 7446            }
 7447
 7448            drop(settings_observation);
 7449            anyhow::Ok(())
 7450        })
 7451    }
 7452
 7453    pub fn language_servers_for_local_buffer<'a>(
 7454        &'a self,
 7455        buffer: &Buffer,
 7456        cx: &mut App,
 7457    ) -> impl Iterator<Item = (&'a Arc<CachedLspAdapter>, &'a Arc<LanguageServer>)> {
 7458        let local = self.as_local();
 7459        let language_server_ids = local
 7460            .map(|local| local.language_server_ids_for_buffer(buffer, cx))
 7461            .unwrap_or_default();
 7462
 7463        language_server_ids
 7464            .into_iter()
 7465            .filter_map(
 7466                move |server_id| match local?.language_servers.get(&server_id)? {
 7467                    LanguageServerState::Running {
 7468                        adapter, server, ..
 7469                    } => Some((adapter, server)),
 7470                    _ => None,
 7471                },
 7472            )
 7473    }
 7474
 7475    pub fn language_server_for_local_buffer<'a>(
 7476        &'a self,
 7477        buffer: &'a Buffer,
 7478        server_id: LanguageServerId,
 7479        cx: &'a mut App,
 7480    ) -> Option<(&'a Arc<CachedLspAdapter>, &'a Arc<LanguageServer>)> {
 7481        self.as_local()?
 7482            .language_servers_for_buffer(buffer, cx)
 7483            .find(|(_, s)| s.server_id() == server_id)
 7484    }
 7485
 7486    fn remove_worktree(&mut self, id_to_remove: WorktreeId, cx: &mut Context<Self>) {
 7487        self.diagnostic_summaries.remove(&id_to_remove);
 7488        if let Some(local) = self.as_local_mut() {
 7489            let to_remove = local.remove_worktree(id_to_remove, cx);
 7490            for server in to_remove {
 7491                self.language_server_statuses.remove(&server);
 7492            }
 7493        }
 7494    }
 7495
 7496    pub fn shared(
 7497        &mut self,
 7498        project_id: u64,
 7499        downstream_client: AnyProtoClient,
 7500        _: &mut Context<Self>,
 7501    ) {
 7502        self.downstream_client = Some((downstream_client.clone(), project_id));
 7503
 7504        for (server_id, status) in &self.language_server_statuses {
 7505            if let Some(server) = self.language_server_for_id(*server_id) {
 7506                downstream_client
 7507                    .send(proto::StartLanguageServer {
 7508                        project_id,
 7509                        server: Some(proto::LanguageServer {
 7510                            id: server_id.to_proto(),
 7511                            name: status.name.to_string(),
 7512                            worktree_id: None,
 7513                        }),
 7514                        capabilities: serde_json::to_string(&server.capabilities())
 7515                            .expect("serializing server LSP capabilities"),
 7516                    })
 7517                    .log_err();
 7518            }
 7519        }
 7520    }
 7521
 7522    pub fn disconnected_from_host(&mut self) {
 7523        self.downstream_client.take();
 7524    }
 7525
 7526    pub fn disconnected_from_ssh_remote(&mut self) {
 7527        if let LspStoreMode::Remote(RemoteLspStore {
 7528            upstream_client, ..
 7529        }) = &mut self.mode
 7530        {
 7531            upstream_client.take();
 7532        }
 7533    }
 7534
 7535    pub(crate) fn set_language_server_statuses_from_proto(
 7536        &mut self,
 7537        language_servers: Vec<proto::LanguageServer>,
 7538        server_capabilities: Vec<String>,
 7539    ) {
 7540        self.language_server_statuses = language_servers
 7541            .into_iter()
 7542            .zip(server_capabilities)
 7543            .map(|(server, server_capabilities)| {
 7544                let server_id = LanguageServerId(server.id as usize);
 7545                if let Ok(server_capabilities) = serde_json::from_str(&server_capabilities) {
 7546                    self.lsp_server_capabilities
 7547                        .insert(server_id, server_capabilities);
 7548                }
 7549                (
 7550                    server_id,
 7551                    LanguageServerStatus {
 7552                        name: LanguageServerName::from_proto(server.name),
 7553                        pending_work: Default::default(),
 7554                        has_pending_diagnostic_updates: false,
 7555                        progress_tokens: Default::default(),
 7556                    },
 7557                )
 7558            })
 7559            .collect();
 7560    }
 7561
 7562    #[cfg(test)]
 7563    pub fn update_diagnostic_entries(
 7564        &mut self,
 7565        server_id: LanguageServerId,
 7566        abs_path: PathBuf,
 7567        result_id: Option<String>,
 7568        version: Option<i32>,
 7569        diagnostics: Vec<DiagnosticEntry<Unclipped<PointUtf16>>>,
 7570        cx: &mut Context<Self>,
 7571    ) -> anyhow::Result<()> {
 7572        self.merge_diagnostic_entries(
 7573            vec![DocumentDiagnosticsUpdate {
 7574                diagnostics: DocumentDiagnostics {
 7575                    diagnostics,
 7576                    document_abs_path: abs_path,
 7577                    version,
 7578                },
 7579                result_id,
 7580                server_id,
 7581                disk_based_sources: Cow::Borrowed(&[]),
 7582            }],
 7583            |_, _, _| false,
 7584            cx,
 7585        )?;
 7586        Ok(())
 7587    }
 7588
 7589    pub fn merge_diagnostic_entries<'a>(
 7590        &mut self,
 7591        diagnostic_updates: Vec<DocumentDiagnosticsUpdate<'a, DocumentDiagnostics>>,
 7592        merge: impl Fn(&Buffer, &Diagnostic, &App) -> bool + Clone,
 7593        cx: &mut Context<Self>,
 7594    ) -> anyhow::Result<()> {
 7595        let mut diagnostics_summary = None::<proto::UpdateDiagnosticSummary>;
 7596        let mut updated_diagnostics_paths = HashMap::default();
 7597        for mut update in diagnostic_updates {
 7598            let abs_path = &update.diagnostics.document_abs_path;
 7599            let server_id = update.server_id;
 7600            let Some((worktree, relative_path)) =
 7601                self.worktree_store.read(cx).find_worktree(abs_path, cx)
 7602            else {
 7603                log::warn!("skipping diagnostics update, no worktree found for path {abs_path:?}");
 7604                return Ok(());
 7605            };
 7606
 7607            let worktree_id = worktree.read(cx).id();
 7608            let project_path = ProjectPath {
 7609                worktree_id,
 7610                path: relative_path.into(),
 7611            };
 7612
 7613            if let Some(buffer_handle) = self.buffer_store.read(cx).get_by_path(&project_path) {
 7614                let snapshot = buffer_handle.read(cx).snapshot();
 7615                let buffer = buffer_handle.read(cx);
 7616                let reused_diagnostics = buffer
 7617                    .get_diagnostics(server_id)
 7618                    .into_iter()
 7619                    .flat_map(|diag| {
 7620                        diag.iter()
 7621                            .filter(|v| merge(buffer, &v.diagnostic, cx))
 7622                            .map(|v| {
 7623                                let start = Unclipped(v.range.start.to_point_utf16(&snapshot));
 7624                                let end = Unclipped(v.range.end.to_point_utf16(&snapshot));
 7625                                DiagnosticEntry {
 7626                                    range: start..end,
 7627                                    diagnostic: v.diagnostic.clone(),
 7628                                }
 7629                            })
 7630                    })
 7631                    .collect::<Vec<_>>();
 7632
 7633                self.as_local_mut()
 7634                    .context("cannot merge diagnostics on a remote LspStore")?
 7635                    .update_buffer_diagnostics(
 7636                        &buffer_handle,
 7637                        server_id,
 7638                        update.result_id,
 7639                        update.diagnostics.version,
 7640                        update.diagnostics.diagnostics.clone(),
 7641                        reused_diagnostics.clone(),
 7642                        cx,
 7643                    )?;
 7644
 7645                update.diagnostics.diagnostics.extend(reused_diagnostics);
 7646            }
 7647
 7648            let updated = worktree.update(cx, |worktree, cx| {
 7649                self.update_worktree_diagnostics(
 7650                    worktree.id(),
 7651                    server_id,
 7652                    project_path.path.clone(),
 7653                    update.diagnostics.diagnostics,
 7654                    cx,
 7655                )
 7656            })?;
 7657            match updated {
 7658                ControlFlow::Continue(new_summary) => {
 7659                    if let Some((project_id, new_summary)) = new_summary {
 7660                        match &mut diagnostics_summary {
 7661                            Some(diagnostics_summary) => {
 7662                                diagnostics_summary
 7663                                    .more_summaries
 7664                                    .push(proto::DiagnosticSummary {
 7665                                        path: project_path.path.as_ref().to_proto(),
 7666                                        language_server_id: server_id.0 as u64,
 7667                                        error_count: new_summary.error_count,
 7668                                        warning_count: new_summary.warning_count,
 7669                                    })
 7670                            }
 7671                            None => {
 7672                                diagnostics_summary = Some(proto::UpdateDiagnosticSummary {
 7673                                    project_id,
 7674                                    worktree_id: worktree_id.to_proto(),
 7675                                    summary: Some(proto::DiagnosticSummary {
 7676                                        path: project_path.path.as_ref().to_proto(),
 7677                                        language_server_id: server_id.0 as u64,
 7678                                        error_count: new_summary.error_count,
 7679                                        warning_count: new_summary.warning_count,
 7680                                    }),
 7681                                    more_summaries: Vec::new(),
 7682                                })
 7683                            }
 7684                        }
 7685                    }
 7686                    updated_diagnostics_paths
 7687                        .entry(server_id)
 7688                        .or_insert_with(Vec::new)
 7689                        .push(project_path);
 7690                }
 7691                ControlFlow::Break(()) => {}
 7692            }
 7693        }
 7694
 7695        if let Some((diagnostics_summary, (downstream_client, _))) =
 7696            diagnostics_summary.zip(self.downstream_client.as_ref())
 7697        {
 7698            downstream_client.send(diagnostics_summary).log_err();
 7699        }
 7700        for (server_id, paths) in updated_diagnostics_paths {
 7701            cx.emit(LspStoreEvent::DiagnosticsUpdated { server_id, paths });
 7702        }
 7703        Ok(())
 7704    }
 7705
 7706    fn update_worktree_diagnostics(
 7707        &mut self,
 7708        worktree_id: WorktreeId,
 7709        server_id: LanguageServerId,
 7710        path_in_worktree: Arc<Path>,
 7711        diagnostics: Vec<DiagnosticEntry<Unclipped<PointUtf16>>>,
 7712        _: &mut Context<Worktree>,
 7713    ) -> Result<ControlFlow<(), Option<(u64, proto::DiagnosticSummary)>>> {
 7714        let local = match &mut self.mode {
 7715            LspStoreMode::Local(local_lsp_store) => local_lsp_store,
 7716            _ => anyhow::bail!("update_worktree_diagnostics called on remote"),
 7717        };
 7718
 7719        let summaries_for_tree = self.diagnostic_summaries.entry(worktree_id).or_default();
 7720        let diagnostics_for_tree = local.diagnostics.entry(worktree_id).or_default();
 7721        let summaries_by_server_id = summaries_for_tree
 7722            .entry(path_in_worktree.clone())
 7723            .or_default();
 7724
 7725        let old_summary = summaries_by_server_id
 7726            .remove(&server_id)
 7727            .unwrap_or_default();
 7728
 7729        let new_summary = DiagnosticSummary::new(&diagnostics);
 7730        if new_summary.is_empty() {
 7731            if let Some(diagnostics_by_server_id) = diagnostics_for_tree.get_mut(&path_in_worktree)
 7732            {
 7733                if let Ok(ix) = diagnostics_by_server_id.binary_search_by_key(&server_id, |e| e.0) {
 7734                    diagnostics_by_server_id.remove(ix);
 7735                }
 7736                if diagnostics_by_server_id.is_empty() {
 7737                    diagnostics_for_tree.remove(&path_in_worktree);
 7738                }
 7739            }
 7740        } else {
 7741            summaries_by_server_id.insert(server_id, new_summary);
 7742            let diagnostics_by_server_id = diagnostics_for_tree
 7743                .entry(path_in_worktree.clone())
 7744                .or_default();
 7745            match diagnostics_by_server_id.binary_search_by_key(&server_id, |e| e.0) {
 7746                Ok(ix) => {
 7747                    diagnostics_by_server_id[ix] = (server_id, diagnostics);
 7748                }
 7749                Err(ix) => {
 7750                    diagnostics_by_server_id.insert(ix, (server_id, diagnostics));
 7751                }
 7752            }
 7753        }
 7754
 7755        if !old_summary.is_empty() || !new_summary.is_empty() {
 7756            if let Some((_, project_id)) = &self.downstream_client {
 7757                Ok(ControlFlow::Continue(Some((
 7758                    *project_id,
 7759                    proto::DiagnosticSummary {
 7760                        path: path_in_worktree.to_proto(),
 7761                        language_server_id: server_id.0 as u64,
 7762                        error_count: new_summary.error_count as u32,
 7763                        warning_count: new_summary.warning_count as u32,
 7764                    },
 7765                ))))
 7766            } else {
 7767                Ok(ControlFlow::Continue(None))
 7768            }
 7769        } else {
 7770            Ok(ControlFlow::Break(()))
 7771        }
 7772    }
 7773
 7774    pub fn open_buffer_for_symbol(
 7775        &mut self,
 7776        symbol: &Symbol,
 7777        cx: &mut Context<Self>,
 7778    ) -> Task<Result<Entity<Buffer>>> {
 7779        if let Some((client, project_id)) = self.upstream_client() {
 7780            let request = client.request(proto::OpenBufferForSymbol {
 7781                project_id,
 7782                symbol: Some(Self::serialize_symbol(symbol)),
 7783            });
 7784            cx.spawn(async move |this, cx| {
 7785                let response = request.await?;
 7786                let buffer_id = BufferId::new(response.buffer_id)?;
 7787                this.update(cx, |this, cx| this.wait_for_remote_buffer(buffer_id, cx))?
 7788                    .await
 7789            })
 7790        } else if let Some(local) = self.as_local() {
 7791            let is_valid = local.language_server_ids.iter().any(|(seed, state)| {
 7792                seed.worktree_id == symbol.source_worktree_id
 7793                    && state.id == symbol.source_language_server_id
 7794                    && symbol.language_server_name == seed.name
 7795            });
 7796            if !is_valid {
 7797                return Task::ready(Err(anyhow!(
 7798                    "language server for worktree and language not found"
 7799                )));
 7800            };
 7801
 7802            let worktree_abs_path = if let Some(worktree_abs_path) = self
 7803                .worktree_store
 7804                .read(cx)
 7805                .worktree_for_id(symbol.path.worktree_id, cx)
 7806                .map(|worktree| worktree.read(cx).abs_path())
 7807            {
 7808                worktree_abs_path
 7809            } else {
 7810                return Task::ready(Err(anyhow!("worktree not found for symbol")));
 7811            };
 7812
 7813            let symbol_abs_path = resolve_path(&worktree_abs_path, &symbol.path.path);
 7814            let symbol_uri = if let Ok(uri) = lsp::Url::from_file_path(symbol_abs_path) {
 7815                uri
 7816            } else {
 7817                return Task::ready(Err(anyhow!("invalid symbol path")));
 7818            };
 7819
 7820            self.open_local_buffer_via_lsp(symbol_uri, symbol.source_language_server_id, cx)
 7821        } else {
 7822            Task::ready(Err(anyhow!("no upstream client or local store")))
 7823        }
 7824    }
 7825
 7826    pub(crate) fn open_local_buffer_via_lsp(
 7827        &mut self,
 7828        mut abs_path: lsp::Url,
 7829        language_server_id: LanguageServerId,
 7830        cx: &mut Context<Self>,
 7831    ) -> Task<Result<Entity<Buffer>>> {
 7832        cx.spawn(async move |lsp_store, cx| {
 7833            // Escape percent-encoded string.
 7834            let current_scheme = abs_path.scheme().to_owned();
 7835            let _ = abs_path.set_scheme("file");
 7836
 7837            let abs_path = abs_path
 7838                .to_file_path()
 7839                .map_err(|()| anyhow!("can't convert URI to path"))?;
 7840            let p = abs_path.clone();
 7841            let yarn_worktree = lsp_store
 7842                .update(cx, move |lsp_store, cx| match lsp_store.as_local() {
 7843                    Some(local_lsp_store) => local_lsp_store.yarn.update(cx, |_, cx| {
 7844                        cx.spawn(async move |this, cx| {
 7845                            let t = this
 7846                                .update(cx, |this, cx| this.process_path(&p, &current_scheme, cx))
 7847                                .ok()?;
 7848                            t.await
 7849                        })
 7850                    }),
 7851                    None => Task::ready(None),
 7852                })?
 7853                .await;
 7854            let (worktree_root_target, known_relative_path) =
 7855                if let Some((zip_root, relative_path)) = yarn_worktree {
 7856                    (zip_root, Some(relative_path))
 7857                } else {
 7858                    (Arc::<Path>::from(abs_path.as_path()), None)
 7859                };
 7860            let (worktree, relative_path) = if let Some(result) =
 7861                lsp_store.update(cx, |lsp_store, cx| {
 7862                    lsp_store.worktree_store.update(cx, |worktree_store, cx| {
 7863                        worktree_store.find_worktree(&worktree_root_target, cx)
 7864                    })
 7865                })? {
 7866                let relative_path =
 7867                    known_relative_path.unwrap_or_else(|| Arc::<Path>::from(result.1));
 7868                (result.0, relative_path)
 7869            } else {
 7870                let worktree = lsp_store
 7871                    .update(cx, |lsp_store, cx| {
 7872                        lsp_store.worktree_store.update(cx, |worktree_store, cx| {
 7873                            worktree_store.create_worktree(&worktree_root_target, false, cx)
 7874                        })
 7875                    })?
 7876                    .await?;
 7877                if worktree.read_with(cx, |worktree, _| worktree.is_local())? {
 7878                    lsp_store
 7879                        .update(cx, |lsp_store, cx| {
 7880                            if let Some(local) = lsp_store.as_local_mut() {
 7881                                local.register_language_server_for_invisible_worktree(
 7882                                    &worktree,
 7883                                    language_server_id,
 7884                                    cx,
 7885                                )
 7886                            }
 7887                        })
 7888                        .ok();
 7889                }
 7890                let worktree_root = worktree.read_with(cx, |worktree, _| worktree.abs_path())?;
 7891                let relative_path = if let Some(known_path) = known_relative_path {
 7892                    known_path
 7893                } else {
 7894                    abs_path.strip_prefix(worktree_root)?.into()
 7895                };
 7896                (worktree, relative_path)
 7897            };
 7898            let project_path = ProjectPath {
 7899                worktree_id: worktree.read_with(cx, |worktree, _| worktree.id())?,
 7900                path: relative_path,
 7901            };
 7902            lsp_store
 7903                .update(cx, |lsp_store, cx| {
 7904                    lsp_store.buffer_store().update(cx, |buffer_store, cx| {
 7905                        buffer_store.open_buffer(project_path, cx)
 7906                    })
 7907                })?
 7908                .await
 7909        })
 7910    }
 7911
 7912    fn request_multiple_lsp_locally<P, R>(
 7913        &mut self,
 7914        buffer: &Entity<Buffer>,
 7915        position: Option<P>,
 7916        request: R,
 7917        cx: &mut Context<Self>,
 7918    ) -> Task<Vec<(LanguageServerId, R::Response)>>
 7919    where
 7920        P: ToOffset,
 7921        R: LspCommand + Clone,
 7922        <R::LspRequest as lsp::request::Request>::Result: Send,
 7923        <R::LspRequest as lsp::request::Request>::Params: Send,
 7924    {
 7925        let Some(local) = self.as_local() else {
 7926            return Task::ready(Vec::new());
 7927        };
 7928
 7929        let snapshot = buffer.read(cx).snapshot();
 7930        let scope = position.and_then(|position| snapshot.language_scope_at(position));
 7931
 7932        let server_ids = buffer.update(cx, |buffer, cx| {
 7933            local
 7934                .language_servers_for_buffer(buffer, cx)
 7935                .filter(|(adapter, _)| {
 7936                    scope
 7937                        .as_ref()
 7938                        .map(|scope| scope.language_allowed(&adapter.name))
 7939                        .unwrap_or(true)
 7940                })
 7941                .map(|(_, server)| server.server_id())
 7942                .filter(|server_id| {
 7943                    self.as_local().is_none_or(|local| {
 7944                        local
 7945                            .buffers_opened_in_servers
 7946                            .get(&snapshot.remote_id())
 7947                            .is_some_and(|servers| servers.contains(server_id))
 7948                    })
 7949                })
 7950                .collect::<Vec<_>>()
 7951        });
 7952
 7953        let mut response_results = server_ids
 7954            .into_iter()
 7955            .map(|server_id| {
 7956                let task = self.request_lsp(
 7957                    buffer.clone(),
 7958                    LanguageServerToQuery::Other(server_id),
 7959                    request.clone(),
 7960                    cx,
 7961                );
 7962                async move { (server_id, task.await) }
 7963            })
 7964            .collect::<FuturesUnordered<_>>();
 7965
 7966        cx.background_spawn(async move {
 7967            let mut responses = Vec::with_capacity(response_results.len());
 7968            while let Some((server_id, response_result)) = response_results.next().await {
 7969                if let Some(response) = response_result.log_err() {
 7970                    responses.push((server_id, response));
 7971                }
 7972            }
 7973            responses
 7974        })
 7975    }
 7976
 7977    async fn handle_lsp_command<T: LspCommand>(
 7978        this: Entity<Self>,
 7979        envelope: TypedEnvelope<T::ProtoRequest>,
 7980        mut cx: AsyncApp,
 7981    ) -> Result<<T::ProtoRequest as proto::RequestMessage>::Response>
 7982    where
 7983        <T::LspRequest as lsp::request::Request>::Params: Send,
 7984        <T::LspRequest as lsp::request::Request>::Result: Send,
 7985    {
 7986        let sender_id = envelope.original_sender_id().unwrap_or_default();
 7987        let buffer_id = T::buffer_id_from_proto(&envelope.payload)?;
 7988        let buffer_handle = this.update(&mut cx, |this, cx| {
 7989            this.buffer_store.read(cx).get_existing(buffer_id)
 7990        })??;
 7991        let request = T::from_proto(
 7992            envelope.payload,
 7993            this.clone(),
 7994            buffer_handle.clone(),
 7995            cx.clone(),
 7996        )
 7997        .await?;
 7998        let response = this
 7999            .update(&mut cx, |this, cx| {
 8000                this.request_lsp(
 8001                    buffer_handle.clone(),
 8002                    LanguageServerToQuery::FirstCapable,
 8003                    request,
 8004                    cx,
 8005                )
 8006            })?
 8007            .await?;
 8008        this.update(&mut cx, |this, cx| {
 8009            Ok(T::response_to_proto(
 8010                response,
 8011                this,
 8012                sender_id,
 8013                &buffer_handle.read(cx).version(),
 8014                cx,
 8015            ))
 8016        })?
 8017    }
 8018
 8019    async fn handle_lsp_query(
 8020        lsp_store: Entity<Self>,
 8021        envelope: TypedEnvelope<proto::LspQuery>,
 8022        mut cx: AsyncApp,
 8023    ) -> Result<proto::Ack> {
 8024        use proto::lsp_query::Request;
 8025        let sender_id = envelope.original_sender_id().unwrap_or_default();
 8026        let lsp_query = envelope.payload;
 8027        let lsp_request_id = LspRequestId(lsp_query.lsp_request_id);
 8028        match lsp_query.request.context("invalid LSP query request")? {
 8029            Request::GetReferences(get_references) => {
 8030                let position = get_references.position.clone().and_then(deserialize_anchor);
 8031                Self::query_lsp_locally::<GetReferences>(
 8032                    lsp_store,
 8033                    sender_id,
 8034                    lsp_request_id,
 8035                    get_references,
 8036                    position,
 8037                    cx.clone(),
 8038                )
 8039                .await?;
 8040            }
 8041            Request::GetDocumentColor(get_document_color) => {
 8042                Self::query_lsp_locally::<GetDocumentColor>(
 8043                    lsp_store,
 8044                    sender_id,
 8045                    lsp_request_id,
 8046                    get_document_color,
 8047                    None,
 8048                    cx.clone(),
 8049                )
 8050                .await?;
 8051            }
 8052            Request::GetHover(get_hover) => {
 8053                let position = get_hover.position.clone().and_then(deserialize_anchor);
 8054                Self::query_lsp_locally::<GetHover>(
 8055                    lsp_store,
 8056                    sender_id,
 8057                    lsp_request_id,
 8058                    get_hover,
 8059                    position,
 8060                    cx.clone(),
 8061                )
 8062                .await?;
 8063            }
 8064            Request::GetCodeActions(get_code_actions) => {
 8065                Self::query_lsp_locally::<GetCodeActions>(
 8066                    lsp_store,
 8067                    sender_id,
 8068                    lsp_request_id,
 8069                    get_code_actions,
 8070                    None,
 8071                    cx.clone(),
 8072                )
 8073                .await?;
 8074            }
 8075            Request::GetSignatureHelp(get_signature_help) => {
 8076                let position = get_signature_help
 8077                    .position
 8078                    .clone()
 8079                    .and_then(deserialize_anchor);
 8080                Self::query_lsp_locally::<GetSignatureHelp>(
 8081                    lsp_store,
 8082                    sender_id,
 8083                    lsp_request_id,
 8084                    get_signature_help,
 8085                    position,
 8086                    cx.clone(),
 8087                )
 8088                .await?;
 8089            }
 8090            Request::GetCodeLens(get_code_lens) => {
 8091                Self::query_lsp_locally::<GetCodeLens>(
 8092                    lsp_store,
 8093                    sender_id,
 8094                    lsp_request_id,
 8095                    get_code_lens,
 8096                    None,
 8097                    cx.clone(),
 8098                )
 8099                .await?;
 8100            }
 8101            Request::GetDefinition(get_definition) => {
 8102                let position = get_definition.position.clone().and_then(deserialize_anchor);
 8103                Self::query_lsp_locally::<GetDefinitions>(
 8104                    lsp_store,
 8105                    sender_id,
 8106                    lsp_request_id,
 8107                    get_definition,
 8108                    position,
 8109                    cx.clone(),
 8110                )
 8111                .await?;
 8112            }
 8113            Request::GetDeclaration(get_declaration) => {
 8114                let position = get_declaration
 8115                    .position
 8116                    .clone()
 8117                    .and_then(deserialize_anchor);
 8118                Self::query_lsp_locally::<GetDeclarations>(
 8119                    lsp_store,
 8120                    sender_id,
 8121                    lsp_request_id,
 8122                    get_declaration,
 8123                    position,
 8124                    cx.clone(),
 8125                )
 8126                .await?;
 8127            }
 8128            Request::GetTypeDefinition(get_type_definition) => {
 8129                let position = get_type_definition
 8130                    .position
 8131                    .clone()
 8132                    .and_then(deserialize_anchor);
 8133                Self::query_lsp_locally::<GetTypeDefinitions>(
 8134                    lsp_store,
 8135                    sender_id,
 8136                    lsp_request_id,
 8137                    get_type_definition,
 8138                    position,
 8139                    cx.clone(),
 8140                )
 8141                .await?;
 8142            }
 8143            Request::GetImplementation(get_implementation) => {
 8144                let position = get_implementation
 8145                    .position
 8146                    .clone()
 8147                    .and_then(deserialize_anchor);
 8148                Self::query_lsp_locally::<GetImplementations>(
 8149                    lsp_store,
 8150                    sender_id,
 8151                    lsp_request_id,
 8152                    get_implementation,
 8153                    position,
 8154                    cx.clone(),
 8155                )
 8156                .await?;
 8157            }
 8158            // Diagnostics pull synchronizes internally via the buffer state, and cannot be handled generically as the other requests.
 8159            Request::GetDocumentDiagnostics(get_document_diagnostics) => {
 8160                let buffer_id = BufferId::new(get_document_diagnostics.buffer_id())?;
 8161                let version = deserialize_version(get_document_diagnostics.buffer_version());
 8162                let buffer = lsp_store.update(&mut cx, |this, cx| {
 8163                    this.buffer_store.read(cx).get_existing(buffer_id)
 8164                })??;
 8165                buffer
 8166                    .update(&mut cx, |buffer, _| {
 8167                        buffer.wait_for_version(version.clone())
 8168                    })?
 8169                    .await?;
 8170                lsp_store.update(&mut cx, |lsp_store, cx| {
 8171                    let existing_queries = lsp_store
 8172                        .running_lsp_requests
 8173                        .entry(TypeId::of::<GetDocumentDiagnostics>())
 8174                        .or_default();
 8175                    if <GetDocumentDiagnostics as LspCommand>::ProtoRequest::stop_previous_requests(
 8176                    ) || buffer.read(cx).version.changed_since(&existing_queries.0)
 8177                    {
 8178                        existing_queries.1.clear();
 8179                    }
 8180                    existing_queries.1.insert(
 8181                        lsp_request_id,
 8182                        cx.spawn(async move |lsp_store, cx| {
 8183                            let diagnostics_pull = lsp_store
 8184                                .update(cx, |lsp_store, cx| {
 8185                                    lsp_store.pull_diagnostics_for_buffer(buffer, cx)
 8186                                })
 8187                                .ok();
 8188                            if let Some(diagnostics_pull) = diagnostics_pull {
 8189                                match diagnostics_pull.await {
 8190                                    Ok(()) => {}
 8191                                    Err(e) => log::error!("Failed to pull diagnostics: {e:#}"),
 8192                                };
 8193                            }
 8194                        }),
 8195                    );
 8196                })?;
 8197            }
 8198        }
 8199        Ok(proto::Ack {})
 8200    }
 8201
 8202    async fn handle_lsp_query_response(
 8203        lsp_store: Entity<Self>,
 8204        envelope: TypedEnvelope<proto::LspQueryResponse>,
 8205        cx: AsyncApp,
 8206    ) -> Result<()> {
 8207        lsp_store.read_with(&cx, |lsp_store, _| {
 8208            if let Some((upstream_client, _)) = lsp_store.upstream_client() {
 8209                upstream_client.handle_lsp_response(envelope.clone());
 8210            }
 8211        })?;
 8212        Ok(())
 8213    }
 8214
 8215    // todo(lsp) remove after Zed Stable hits v0.204.x
 8216    async fn handle_multi_lsp_query(
 8217        lsp_store: Entity<Self>,
 8218        envelope: TypedEnvelope<proto::MultiLspQuery>,
 8219        mut cx: AsyncApp,
 8220    ) -> Result<proto::MultiLspQueryResponse> {
 8221        let response_from_ssh = lsp_store.read_with(&cx, |this, _| {
 8222            let (upstream_client, project_id) = this.upstream_client()?;
 8223            let mut payload = envelope.payload.clone();
 8224            payload.project_id = project_id;
 8225
 8226            Some(upstream_client.request(payload))
 8227        })?;
 8228        if let Some(response_from_ssh) = response_from_ssh {
 8229            return response_from_ssh.await;
 8230        }
 8231
 8232        let sender_id = envelope.original_sender_id().unwrap_or_default();
 8233        let buffer_id = BufferId::new(envelope.payload.buffer_id)?;
 8234        let version = deserialize_version(&envelope.payload.version);
 8235        let buffer = lsp_store.update(&mut cx, |this, cx| {
 8236            this.buffer_store.read(cx).get_existing(buffer_id)
 8237        })??;
 8238        buffer
 8239            .update(&mut cx, |buffer, _| {
 8240                buffer.wait_for_version(version.clone())
 8241            })?
 8242            .await?;
 8243        let buffer_version = buffer.read_with(&cx, |buffer, _| buffer.version())?;
 8244        match envelope
 8245            .payload
 8246            .strategy
 8247            .context("invalid request without the strategy")?
 8248        {
 8249            proto::multi_lsp_query::Strategy::All(_) => {
 8250                // currently, there's only one multiple language servers query strategy,
 8251                // so just ensure it's specified correctly
 8252            }
 8253        }
 8254        match envelope.payload.request {
 8255            Some(proto::multi_lsp_query::Request::GetHover(message)) => {
 8256                buffer
 8257                    .update(&mut cx, |buffer, _| {
 8258                        buffer.wait_for_version(deserialize_version(&message.version))
 8259                    })?
 8260                    .await?;
 8261                let get_hover =
 8262                    GetHover::from_proto(message, lsp_store.clone(), buffer.clone(), cx.clone())
 8263                        .await?;
 8264                let all_hovers = lsp_store
 8265                    .update(&mut cx, |this, cx| {
 8266                        this.request_multiple_lsp_locally(
 8267                            &buffer,
 8268                            Some(get_hover.position),
 8269                            get_hover,
 8270                            cx,
 8271                        )
 8272                    })?
 8273                    .await
 8274                    .into_iter()
 8275                    .filter_map(|(server_id, hover)| {
 8276                        Some((server_id, remove_empty_hover_blocks(hover?)?))
 8277                    });
 8278                lsp_store.update(&mut cx, |project, cx| proto::MultiLspQueryResponse {
 8279                    responses: all_hovers
 8280                        .map(|(server_id, hover)| proto::LspResponse {
 8281                            server_id: server_id.to_proto(),
 8282                            response: Some(proto::lsp_response::Response::GetHoverResponse(
 8283                                GetHover::response_to_proto(
 8284                                    Some(hover),
 8285                                    project,
 8286                                    sender_id,
 8287                                    &buffer_version,
 8288                                    cx,
 8289                                ),
 8290                            )),
 8291                        })
 8292                        .collect(),
 8293                })
 8294            }
 8295            Some(proto::multi_lsp_query::Request::GetCodeActions(message)) => {
 8296                buffer
 8297                    .update(&mut cx, |buffer, _| {
 8298                        buffer.wait_for_version(deserialize_version(&message.version))
 8299                    })?
 8300                    .await?;
 8301                let get_code_actions = GetCodeActions::from_proto(
 8302                    message,
 8303                    lsp_store.clone(),
 8304                    buffer.clone(),
 8305                    cx.clone(),
 8306                )
 8307                .await?;
 8308
 8309                let all_actions = lsp_store
 8310                    .update(&mut cx, |project, cx| {
 8311                        project.request_multiple_lsp_locally(
 8312                            &buffer,
 8313                            Some(get_code_actions.range.start),
 8314                            get_code_actions,
 8315                            cx,
 8316                        )
 8317                    })?
 8318                    .await
 8319                    .into_iter();
 8320
 8321                lsp_store.update(&mut cx, |project, cx| proto::MultiLspQueryResponse {
 8322                    responses: all_actions
 8323                        .map(|(server_id, code_actions)| proto::LspResponse {
 8324                            server_id: server_id.to_proto(),
 8325                            response: Some(proto::lsp_response::Response::GetCodeActionsResponse(
 8326                                GetCodeActions::response_to_proto(
 8327                                    code_actions,
 8328                                    project,
 8329                                    sender_id,
 8330                                    &buffer_version,
 8331                                    cx,
 8332                                ),
 8333                            )),
 8334                        })
 8335                        .collect(),
 8336                })
 8337            }
 8338            Some(proto::multi_lsp_query::Request::GetSignatureHelp(message)) => {
 8339                buffer
 8340                    .update(&mut cx, |buffer, _| {
 8341                        buffer.wait_for_version(deserialize_version(&message.version))
 8342                    })?
 8343                    .await?;
 8344                let get_signature_help = GetSignatureHelp::from_proto(
 8345                    message,
 8346                    lsp_store.clone(),
 8347                    buffer.clone(),
 8348                    cx.clone(),
 8349                )
 8350                .await?;
 8351
 8352                let all_signatures = lsp_store
 8353                    .update(&mut cx, |project, cx| {
 8354                        project.request_multiple_lsp_locally(
 8355                            &buffer,
 8356                            Some(get_signature_help.position),
 8357                            get_signature_help,
 8358                            cx,
 8359                        )
 8360                    })?
 8361                    .await
 8362                    .into_iter();
 8363
 8364                lsp_store.update(&mut cx, |project, cx| proto::MultiLspQueryResponse {
 8365                    responses: all_signatures
 8366                        .map(|(server_id, signature_help)| proto::LspResponse {
 8367                            server_id: server_id.to_proto(),
 8368                            response: Some(
 8369                                proto::lsp_response::Response::GetSignatureHelpResponse(
 8370                                    GetSignatureHelp::response_to_proto(
 8371                                        signature_help,
 8372                                        project,
 8373                                        sender_id,
 8374                                        &buffer_version,
 8375                                        cx,
 8376                                    ),
 8377                                ),
 8378                            ),
 8379                        })
 8380                        .collect(),
 8381                })
 8382            }
 8383            Some(proto::multi_lsp_query::Request::GetCodeLens(message)) => {
 8384                buffer
 8385                    .update(&mut cx, |buffer, _| {
 8386                        buffer.wait_for_version(deserialize_version(&message.version))
 8387                    })?
 8388                    .await?;
 8389                let get_code_lens =
 8390                    GetCodeLens::from_proto(message, lsp_store.clone(), buffer.clone(), cx.clone())
 8391                        .await?;
 8392
 8393                let code_lens_actions = lsp_store
 8394                    .update(&mut cx, |project, cx| {
 8395                        project.request_multiple_lsp_locally(
 8396                            &buffer,
 8397                            None::<usize>,
 8398                            get_code_lens,
 8399                            cx,
 8400                        )
 8401                    })?
 8402                    .await
 8403                    .into_iter();
 8404
 8405                lsp_store.update(&mut cx, |project, cx| proto::MultiLspQueryResponse {
 8406                    responses: code_lens_actions
 8407                        .map(|(server_id, actions)| proto::LspResponse {
 8408                            server_id: server_id.to_proto(),
 8409                            response: Some(proto::lsp_response::Response::GetCodeLensResponse(
 8410                                GetCodeLens::response_to_proto(
 8411                                    actions,
 8412                                    project,
 8413                                    sender_id,
 8414                                    &buffer_version,
 8415                                    cx,
 8416                                ),
 8417                            )),
 8418                        })
 8419                        .collect(),
 8420                })
 8421            }
 8422            Some(proto::multi_lsp_query::Request::GetDocumentDiagnostics(message)) => {
 8423                buffer
 8424                    .update(&mut cx, |buffer, _| {
 8425                        buffer.wait_for_version(deserialize_version(&message.version))
 8426                    })?
 8427                    .await?;
 8428                lsp_store
 8429                    .update(&mut cx, |lsp_store, cx| {
 8430                        lsp_store.pull_diagnostics_for_buffer(buffer, cx)
 8431                    })?
 8432                    .await?;
 8433                // `pull_diagnostics_for_buffer` will merge in the new diagnostics and send them to the client.
 8434                // The client cannot merge anything into its non-local LspStore, so we do not need to return anything.
 8435                Ok(proto::MultiLspQueryResponse {
 8436                    responses: Vec::new(),
 8437                })
 8438            }
 8439            Some(proto::multi_lsp_query::Request::GetDocumentColor(message)) => {
 8440                buffer
 8441                    .update(&mut cx, |buffer, _| {
 8442                        buffer.wait_for_version(deserialize_version(&message.version))
 8443                    })?
 8444                    .await?;
 8445                let get_document_color = GetDocumentColor::from_proto(
 8446                    message,
 8447                    lsp_store.clone(),
 8448                    buffer.clone(),
 8449                    cx.clone(),
 8450                )
 8451                .await?;
 8452
 8453                let all_colors = lsp_store
 8454                    .update(&mut cx, |project, cx| {
 8455                        project.request_multiple_lsp_locally(
 8456                            &buffer,
 8457                            None::<usize>,
 8458                            get_document_color,
 8459                            cx,
 8460                        )
 8461                    })?
 8462                    .await
 8463                    .into_iter();
 8464
 8465                lsp_store.update(&mut cx, |project, cx| proto::MultiLspQueryResponse {
 8466                    responses: all_colors
 8467                        .map(|(server_id, colors)| proto::LspResponse {
 8468                            server_id: server_id.to_proto(),
 8469                            response: Some(
 8470                                proto::lsp_response::Response::GetDocumentColorResponse(
 8471                                    GetDocumentColor::response_to_proto(
 8472                                        colors,
 8473                                        project,
 8474                                        sender_id,
 8475                                        &buffer_version,
 8476                                        cx,
 8477                                    ),
 8478                                ),
 8479                            ),
 8480                        })
 8481                        .collect(),
 8482                })
 8483            }
 8484            Some(proto::multi_lsp_query::Request::GetDefinition(message)) => {
 8485                let get_definitions = GetDefinitions::from_proto(
 8486                    message,
 8487                    lsp_store.clone(),
 8488                    buffer.clone(),
 8489                    cx.clone(),
 8490                )
 8491                .await?;
 8492
 8493                let definitions = lsp_store
 8494                    .update(&mut cx, |project, cx| {
 8495                        project.request_multiple_lsp_locally(
 8496                            &buffer,
 8497                            Some(get_definitions.position),
 8498                            get_definitions,
 8499                            cx,
 8500                        )
 8501                    })?
 8502                    .await
 8503                    .into_iter();
 8504
 8505                lsp_store.update(&mut cx, |project, cx| proto::MultiLspQueryResponse {
 8506                    responses: definitions
 8507                        .map(|(server_id, definitions)| proto::LspResponse {
 8508                            server_id: server_id.to_proto(),
 8509                            response: Some(proto::lsp_response::Response::GetDefinitionResponse(
 8510                                GetDefinitions::response_to_proto(
 8511                                    definitions,
 8512                                    project,
 8513                                    sender_id,
 8514                                    &buffer_version,
 8515                                    cx,
 8516                                ),
 8517                            )),
 8518                        })
 8519                        .collect(),
 8520                })
 8521            }
 8522            Some(proto::multi_lsp_query::Request::GetDeclaration(message)) => {
 8523                let get_declarations = GetDeclarations::from_proto(
 8524                    message,
 8525                    lsp_store.clone(),
 8526                    buffer.clone(),
 8527                    cx.clone(),
 8528                )
 8529                .await?;
 8530
 8531                let declarations = lsp_store
 8532                    .update(&mut cx, |project, cx| {
 8533                        project.request_multiple_lsp_locally(
 8534                            &buffer,
 8535                            Some(get_declarations.position),
 8536                            get_declarations,
 8537                            cx,
 8538                        )
 8539                    })?
 8540                    .await
 8541                    .into_iter();
 8542
 8543                lsp_store.update(&mut cx, |project, cx| proto::MultiLspQueryResponse {
 8544                    responses: declarations
 8545                        .map(|(server_id, declarations)| proto::LspResponse {
 8546                            server_id: server_id.to_proto(),
 8547                            response: Some(proto::lsp_response::Response::GetDeclarationResponse(
 8548                                GetDeclarations::response_to_proto(
 8549                                    declarations,
 8550                                    project,
 8551                                    sender_id,
 8552                                    &buffer_version,
 8553                                    cx,
 8554                                ),
 8555                            )),
 8556                        })
 8557                        .collect(),
 8558                })
 8559            }
 8560            Some(proto::multi_lsp_query::Request::GetTypeDefinition(message)) => {
 8561                let get_type_definitions = GetTypeDefinitions::from_proto(
 8562                    message,
 8563                    lsp_store.clone(),
 8564                    buffer.clone(),
 8565                    cx.clone(),
 8566                )
 8567                .await?;
 8568
 8569                let type_definitions = lsp_store
 8570                    .update(&mut cx, |project, cx| {
 8571                        project.request_multiple_lsp_locally(
 8572                            &buffer,
 8573                            Some(get_type_definitions.position),
 8574                            get_type_definitions,
 8575                            cx,
 8576                        )
 8577                    })?
 8578                    .await
 8579                    .into_iter();
 8580
 8581                lsp_store.update(&mut cx, |project, cx| proto::MultiLspQueryResponse {
 8582                    responses: type_definitions
 8583                        .map(|(server_id, type_definitions)| proto::LspResponse {
 8584                            server_id: server_id.to_proto(),
 8585                            response: Some(
 8586                                proto::lsp_response::Response::GetTypeDefinitionResponse(
 8587                                    GetTypeDefinitions::response_to_proto(
 8588                                        type_definitions,
 8589                                        project,
 8590                                        sender_id,
 8591                                        &buffer_version,
 8592                                        cx,
 8593                                    ),
 8594                                ),
 8595                            ),
 8596                        })
 8597                        .collect(),
 8598                })
 8599            }
 8600            Some(proto::multi_lsp_query::Request::GetImplementation(message)) => {
 8601                let get_implementations = GetImplementations::from_proto(
 8602                    message,
 8603                    lsp_store.clone(),
 8604                    buffer.clone(),
 8605                    cx.clone(),
 8606                )
 8607                .await?;
 8608
 8609                let implementations = lsp_store
 8610                    .update(&mut cx, |project, cx| {
 8611                        project.request_multiple_lsp_locally(
 8612                            &buffer,
 8613                            Some(get_implementations.position),
 8614                            get_implementations,
 8615                            cx,
 8616                        )
 8617                    })?
 8618                    .await
 8619                    .into_iter();
 8620
 8621                lsp_store.update(&mut cx, |project, cx| proto::MultiLspQueryResponse {
 8622                    responses: implementations
 8623                        .map(|(server_id, implementations)| proto::LspResponse {
 8624                            server_id: server_id.to_proto(),
 8625                            response: Some(
 8626                                proto::lsp_response::Response::GetImplementationResponse(
 8627                                    GetImplementations::response_to_proto(
 8628                                        implementations,
 8629                                        project,
 8630                                        sender_id,
 8631                                        &buffer_version,
 8632                                        cx,
 8633                                    ),
 8634                                ),
 8635                            ),
 8636                        })
 8637                        .collect(),
 8638                })
 8639            }
 8640            Some(proto::multi_lsp_query::Request::GetReferences(message)) => {
 8641                let get_references = GetReferences::from_proto(
 8642                    message,
 8643                    lsp_store.clone(),
 8644                    buffer.clone(),
 8645                    cx.clone(),
 8646                )
 8647                .await?;
 8648
 8649                let references = lsp_store
 8650                    .update(&mut cx, |project, cx| {
 8651                        project.request_multiple_lsp_locally(
 8652                            &buffer,
 8653                            Some(get_references.position),
 8654                            get_references,
 8655                            cx,
 8656                        )
 8657                    })?
 8658                    .await
 8659                    .into_iter();
 8660
 8661                lsp_store.update(&mut cx, |project, cx| proto::MultiLspQueryResponse {
 8662                    responses: references
 8663                        .map(|(server_id, references)| proto::LspResponse {
 8664                            server_id: server_id.to_proto(),
 8665                            response: Some(proto::lsp_response::Response::GetReferencesResponse(
 8666                                GetReferences::response_to_proto(
 8667                                    references,
 8668                                    project,
 8669                                    sender_id,
 8670                                    &buffer_version,
 8671                                    cx,
 8672                                ),
 8673                            )),
 8674                        })
 8675                        .collect(),
 8676                })
 8677            }
 8678            None => anyhow::bail!("empty multi lsp query request"),
 8679        }
 8680    }
 8681
 8682    async fn handle_apply_code_action(
 8683        this: Entity<Self>,
 8684        envelope: TypedEnvelope<proto::ApplyCodeAction>,
 8685        mut cx: AsyncApp,
 8686    ) -> Result<proto::ApplyCodeActionResponse> {
 8687        let sender_id = envelope.original_sender_id().unwrap_or_default();
 8688        let action =
 8689            Self::deserialize_code_action(envelope.payload.action.context("invalid action")?)?;
 8690        let apply_code_action = this.update(&mut cx, |this, cx| {
 8691            let buffer_id = BufferId::new(envelope.payload.buffer_id)?;
 8692            let buffer = this.buffer_store.read(cx).get_existing(buffer_id)?;
 8693            anyhow::Ok(this.apply_code_action(buffer, action, false, cx))
 8694        })??;
 8695
 8696        let project_transaction = apply_code_action.await?;
 8697        let project_transaction = this.update(&mut cx, |this, cx| {
 8698            this.buffer_store.update(cx, |buffer_store, cx| {
 8699                buffer_store.serialize_project_transaction_for_peer(
 8700                    project_transaction,
 8701                    sender_id,
 8702                    cx,
 8703                )
 8704            })
 8705        })?;
 8706        Ok(proto::ApplyCodeActionResponse {
 8707            transaction: Some(project_transaction),
 8708        })
 8709    }
 8710
 8711    async fn handle_register_buffer_with_language_servers(
 8712        this: Entity<Self>,
 8713        envelope: TypedEnvelope<proto::RegisterBufferWithLanguageServers>,
 8714        mut cx: AsyncApp,
 8715    ) -> Result<proto::Ack> {
 8716        let buffer_id = BufferId::new(envelope.payload.buffer_id)?;
 8717        let peer_id = envelope.original_sender_id.unwrap_or(envelope.sender_id);
 8718        this.update(&mut cx, |this, cx| {
 8719            if let Some((upstream_client, upstream_project_id)) = this.upstream_client() {
 8720                return upstream_client.send(proto::RegisterBufferWithLanguageServers {
 8721                    project_id: upstream_project_id,
 8722                    buffer_id: buffer_id.to_proto(),
 8723                    only_servers: envelope.payload.only_servers,
 8724                });
 8725            }
 8726
 8727            let Some(buffer) = this.buffer_store().read(cx).get(buffer_id) else {
 8728                anyhow::bail!("buffer is not open");
 8729            };
 8730
 8731            let handle = this.register_buffer_with_language_servers(
 8732                &buffer,
 8733                envelope
 8734                    .payload
 8735                    .only_servers
 8736                    .into_iter()
 8737                    .filter_map(|selector| {
 8738                        Some(match selector.selector? {
 8739                            proto::language_server_selector::Selector::ServerId(server_id) => {
 8740                                LanguageServerSelector::Id(LanguageServerId::from_proto(server_id))
 8741                            }
 8742                            proto::language_server_selector::Selector::Name(name) => {
 8743                                LanguageServerSelector::Name(LanguageServerName(
 8744                                    SharedString::from(name),
 8745                                ))
 8746                            }
 8747                        })
 8748                    })
 8749                    .collect(),
 8750                false,
 8751                cx,
 8752            );
 8753            this.buffer_store().update(cx, |buffer_store, _| {
 8754                buffer_store.register_shared_lsp_handle(peer_id, buffer_id, handle);
 8755            });
 8756
 8757            Ok(())
 8758        })??;
 8759        Ok(proto::Ack {})
 8760    }
 8761
 8762    async fn handle_rename_project_entry(
 8763        this: Entity<Self>,
 8764        envelope: TypedEnvelope<proto::RenameProjectEntry>,
 8765        mut cx: AsyncApp,
 8766    ) -> Result<proto::ProjectEntryResponse> {
 8767        let entry_id = ProjectEntryId::from_proto(envelope.payload.entry_id);
 8768        let (worktree_id, worktree, old_path, is_dir) = this
 8769            .update(&mut cx, |this, cx| {
 8770                this.worktree_store
 8771                    .read(cx)
 8772                    .worktree_and_entry_for_id(entry_id, cx)
 8773                    .map(|(worktree, entry)| {
 8774                        (
 8775                            worktree.read(cx).id(),
 8776                            worktree,
 8777                            entry.path.clone(),
 8778                            entry.is_dir(),
 8779                        )
 8780                    })
 8781            })?
 8782            .context("worktree not found")?;
 8783        let (old_abs_path, new_abs_path) = {
 8784            let root_path = worktree.read_with(&cx, |this, _| this.abs_path())?;
 8785            let new_path = PathBuf::from_proto(envelope.payload.new_path.clone());
 8786            (root_path.join(&old_path), root_path.join(&new_path))
 8787        };
 8788
 8789        let _transaction = Self::will_rename_entry(
 8790            this.downgrade(),
 8791            worktree_id,
 8792            &old_abs_path,
 8793            &new_abs_path,
 8794            is_dir,
 8795            cx.clone(),
 8796        )
 8797        .await;
 8798        let response = Worktree::handle_rename_entry(worktree, envelope.payload, cx.clone()).await;
 8799        this.read_with(&cx, |this, _| {
 8800            this.did_rename_entry(worktree_id, &old_abs_path, &new_abs_path, is_dir);
 8801        })
 8802        .ok();
 8803        response
 8804    }
 8805
 8806    async fn handle_update_diagnostic_summary(
 8807        this: Entity<Self>,
 8808        envelope: TypedEnvelope<proto::UpdateDiagnosticSummary>,
 8809        mut cx: AsyncApp,
 8810    ) -> Result<()> {
 8811        this.update(&mut cx, |lsp_store, cx| {
 8812            let worktree_id = WorktreeId::from_proto(envelope.payload.worktree_id);
 8813            let mut updated_diagnostics_paths = HashMap::default();
 8814            let mut diagnostics_summary = None::<proto::UpdateDiagnosticSummary>;
 8815            for message_summary in envelope
 8816                .payload
 8817                .summary
 8818                .into_iter()
 8819                .chain(envelope.payload.more_summaries)
 8820            {
 8821                let project_path = ProjectPath {
 8822                    worktree_id,
 8823                    path: Arc::<Path>::from_proto(message_summary.path),
 8824                };
 8825                let path = project_path.path.clone();
 8826                let server_id = LanguageServerId(message_summary.language_server_id as usize);
 8827                let summary = DiagnosticSummary {
 8828                    error_count: message_summary.error_count as usize,
 8829                    warning_count: message_summary.warning_count as usize,
 8830                };
 8831
 8832                if summary.is_empty() {
 8833                    if let Some(worktree_summaries) =
 8834                        lsp_store.diagnostic_summaries.get_mut(&worktree_id)
 8835                        && let Some(summaries) = worktree_summaries.get_mut(&path)
 8836                    {
 8837                        summaries.remove(&server_id);
 8838                        if summaries.is_empty() {
 8839                            worktree_summaries.remove(&path);
 8840                        }
 8841                    }
 8842                } else {
 8843                    lsp_store
 8844                        .diagnostic_summaries
 8845                        .entry(worktree_id)
 8846                        .or_default()
 8847                        .entry(path)
 8848                        .or_default()
 8849                        .insert(server_id, summary);
 8850                }
 8851
 8852                if let Some((_, project_id)) = &lsp_store.downstream_client {
 8853                    match &mut diagnostics_summary {
 8854                        Some(diagnostics_summary) => {
 8855                            diagnostics_summary
 8856                                .more_summaries
 8857                                .push(proto::DiagnosticSummary {
 8858                                    path: project_path.path.as_ref().to_proto(),
 8859                                    language_server_id: server_id.0 as u64,
 8860                                    error_count: summary.error_count as u32,
 8861                                    warning_count: summary.warning_count as u32,
 8862                                })
 8863                        }
 8864                        None => {
 8865                            diagnostics_summary = Some(proto::UpdateDiagnosticSummary {
 8866                                project_id: *project_id,
 8867                                worktree_id: worktree_id.to_proto(),
 8868                                summary: Some(proto::DiagnosticSummary {
 8869                                    path: project_path.path.as_ref().to_proto(),
 8870                                    language_server_id: server_id.0 as u64,
 8871                                    error_count: summary.error_count as u32,
 8872                                    warning_count: summary.warning_count as u32,
 8873                                }),
 8874                                more_summaries: Vec::new(),
 8875                            })
 8876                        }
 8877                    }
 8878                }
 8879                updated_diagnostics_paths
 8880                    .entry(server_id)
 8881                    .or_insert_with(Vec::new)
 8882                    .push(project_path);
 8883            }
 8884
 8885            if let Some((diagnostics_summary, (downstream_client, _))) =
 8886                diagnostics_summary.zip(lsp_store.downstream_client.as_ref())
 8887            {
 8888                downstream_client.send(diagnostics_summary).log_err();
 8889            }
 8890            for (server_id, paths) in updated_diagnostics_paths {
 8891                cx.emit(LspStoreEvent::DiagnosticsUpdated { server_id, paths });
 8892            }
 8893            Ok(())
 8894        })?
 8895    }
 8896
 8897    async fn handle_start_language_server(
 8898        lsp_store: Entity<Self>,
 8899        envelope: TypedEnvelope<proto::StartLanguageServer>,
 8900        mut cx: AsyncApp,
 8901    ) -> Result<()> {
 8902        let server = envelope.payload.server.context("invalid server")?;
 8903        let server_capabilities =
 8904            serde_json::from_str::<lsp::ServerCapabilities>(&envelope.payload.capabilities)
 8905                .with_context(|| {
 8906                    format!(
 8907                        "incorrect server capabilities {}",
 8908                        envelope.payload.capabilities
 8909                    )
 8910                })?;
 8911        lsp_store.update(&mut cx, |lsp_store, cx| {
 8912            let server_id = LanguageServerId(server.id as usize);
 8913            let server_name = LanguageServerName::from_proto(server.name.clone());
 8914            lsp_store
 8915                .lsp_server_capabilities
 8916                .insert(server_id, server_capabilities);
 8917            lsp_store.language_server_statuses.insert(
 8918                server_id,
 8919                LanguageServerStatus {
 8920                    name: server_name.clone(),
 8921                    pending_work: Default::default(),
 8922                    has_pending_diagnostic_updates: false,
 8923                    progress_tokens: Default::default(),
 8924                },
 8925            );
 8926            cx.emit(LspStoreEvent::LanguageServerAdded(
 8927                server_id,
 8928                server_name,
 8929                server.worktree_id.map(WorktreeId::from_proto),
 8930            ));
 8931            cx.notify();
 8932        })?;
 8933        Ok(())
 8934    }
 8935
 8936    async fn handle_update_language_server(
 8937        lsp_store: Entity<Self>,
 8938        envelope: TypedEnvelope<proto::UpdateLanguageServer>,
 8939        mut cx: AsyncApp,
 8940    ) -> Result<()> {
 8941        lsp_store.update(&mut cx, |lsp_store, cx| {
 8942            let language_server_id = LanguageServerId(envelope.payload.language_server_id as usize);
 8943
 8944            match envelope.payload.variant.context("invalid variant")? {
 8945                proto::update_language_server::Variant::WorkStart(payload) => {
 8946                    lsp_store.on_lsp_work_start(
 8947                        language_server_id,
 8948                        payload.token,
 8949                        LanguageServerProgress {
 8950                            title: payload.title,
 8951                            is_disk_based_diagnostics_progress: false,
 8952                            is_cancellable: payload.is_cancellable.unwrap_or(false),
 8953                            message: payload.message,
 8954                            percentage: payload.percentage.map(|p| p as usize),
 8955                            last_update_at: cx.background_executor().now(),
 8956                        },
 8957                        cx,
 8958                    );
 8959                }
 8960                proto::update_language_server::Variant::WorkProgress(payload) => {
 8961                    lsp_store.on_lsp_work_progress(
 8962                        language_server_id,
 8963                        payload.token,
 8964                        LanguageServerProgress {
 8965                            title: None,
 8966                            is_disk_based_diagnostics_progress: false,
 8967                            is_cancellable: payload.is_cancellable.unwrap_or(false),
 8968                            message: payload.message,
 8969                            percentage: payload.percentage.map(|p| p as usize),
 8970                            last_update_at: cx.background_executor().now(),
 8971                        },
 8972                        cx,
 8973                    );
 8974                }
 8975
 8976                proto::update_language_server::Variant::WorkEnd(payload) => {
 8977                    lsp_store.on_lsp_work_end(language_server_id, payload.token, cx);
 8978                }
 8979
 8980                proto::update_language_server::Variant::DiskBasedDiagnosticsUpdating(_) => {
 8981                    lsp_store.disk_based_diagnostics_started(language_server_id, cx);
 8982                }
 8983
 8984                proto::update_language_server::Variant::DiskBasedDiagnosticsUpdated(_) => {
 8985                    lsp_store.disk_based_diagnostics_finished(language_server_id, cx)
 8986                }
 8987
 8988                non_lsp @ proto::update_language_server::Variant::StatusUpdate(_)
 8989                | non_lsp @ proto::update_language_server::Variant::RegisteredForBuffer(_)
 8990                | non_lsp @ proto::update_language_server::Variant::MetadataUpdated(_) => {
 8991                    cx.emit(LspStoreEvent::LanguageServerUpdate {
 8992                        language_server_id,
 8993                        name: envelope
 8994                            .payload
 8995                            .server_name
 8996                            .map(SharedString::new)
 8997                            .map(LanguageServerName),
 8998                        message: non_lsp,
 8999                    });
 9000                }
 9001            }
 9002
 9003            Ok(())
 9004        })?
 9005    }
 9006
 9007    async fn handle_language_server_log(
 9008        this: Entity<Self>,
 9009        envelope: TypedEnvelope<proto::LanguageServerLog>,
 9010        mut cx: AsyncApp,
 9011    ) -> Result<()> {
 9012        let language_server_id = LanguageServerId(envelope.payload.language_server_id as usize);
 9013        let log_type = envelope
 9014            .payload
 9015            .log_type
 9016            .map(LanguageServerLogType::from_proto)
 9017            .context("invalid language server log type")?;
 9018
 9019        let message = envelope.payload.message;
 9020
 9021        this.update(&mut cx, |_, cx| {
 9022            cx.emit(LspStoreEvent::LanguageServerLog(
 9023                language_server_id,
 9024                log_type,
 9025                message,
 9026            ));
 9027        })
 9028    }
 9029
 9030    async fn handle_lsp_ext_cancel_flycheck(
 9031        lsp_store: Entity<Self>,
 9032        envelope: TypedEnvelope<proto::LspExtCancelFlycheck>,
 9033        cx: AsyncApp,
 9034    ) -> Result<proto::Ack> {
 9035        let server_id = LanguageServerId(envelope.payload.language_server_id as usize);
 9036        lsp_store.read_with(&cx, |lsp_store, _| {
 9037            if let Some(server) = lsp_store.language_server_for_id(server_id) {
 9038                server
 9039                    .notify::<lsp_store::lsp_ext_command::LspExtCancelFlycheck>(&())
 9040                    .context("handling lsp ext cancel flycheck")
 9041            } else {
 9042                anyhow::Ok(())
 9043            }
 9044        })??;
 9045
 9046        Ok(proto::Ack {})
 9047    }
 9048
 9049    async fn handle_lsp_ext_run_flycheck(
 9050        lsp_store: Entity<Self>,
 9051        envelope: TypedEnvelope<proto::LspExtRunFlycheck>,
 9052        mut cx: AsyncApp,
 9053    ) -> Result<proto::Ack> {
 9054        let server_id = LanguageServerId(envelope.payload.language_server_id as usize);
 9055        lsp_store.update(&mut cx, |lsp_store, cx| {
 9056            if let Some(server) = lsp_store.language_server_for_id(server_id) {
 9057                let text_document = if envelope.payload.current_file_only {
 9058                    let buffer_id = envelope
 9059                        .payload
 9060                        .buffer_id
 9061                        .map(|id| BufferId::new(id))
 9062                        .transpose()?;
 9063                    buffer_id
 9064                        .and_then(|buffer_id| {
 9065                            lsp_store
 9066                                .buffer_store()
 9067                                .read(cx)
 9068                                .get(buffer_id)
 9069                                .and_then(|buffer| {
 9070                                    Some(buffer.read(cx).file()?.as_local()?.abs_path(cx))
 9071                                })
 9072                                .map(|path| make_text_document_identifier(&path))
 9073                        })
 9074                        .transpose()?
 9075                } else {
 9076                    None
 9077                };
 9078                server
 9079                    .notify::<lsp_store::lsp_ext_command::LspExtRunFlycheck>(
 9080                        &lsp_store::lsp_ext_command::RunFlycheckParams { text_document },
 9081                    )
 9082                    .context("handling lsp ext run flycheck")
 9083            } else {
 9084                anyhow::Ok(())
 9085            }
 9086        })??;
 9087
 9088        Ok(proto::Ack {})
 9089    }
 9090
 9091    async fn handle_lsp_ext_clear_flycheck(
 9092        lsp_store: Entity<Self>,
 9093        envelope: TypedEnvelope<proto::LspExtClearFlycheck>,
 9094        cx: AsyncApp,
 9095    ) -> Result<proto::Ack> {
 9096        let server_id = LanguageServerId(envelope.payload.language_server_id as usize);
 9097        lsp_store.read_with(&cx, |lsp_store, _| {
 9098            if let Some(server) = lsp_store.language_server_for_id(server_id) {
 9099                server
 9100                    .notify::<lsp_store::lsp_ext_command::LspExtClearFlycheck>(&())
 9101                    .context("handling lsp ext clear flycheck")
 9102            } else {
 9103                anyhow::Ok(())
 9104            }
 9105        })??;
 9106
 9107        Ok(proto::Ack {})
 9108    }
 9109
 9110    pub fn disk_based_diagnostics_started(
 9111        &mut self,
 9112        language_server_id: LanguageServerId,
 9113        cx: &mut Context<Self>,
 9114    ) {
 9115        if let Some(language_server_status) =
 9116            self.language_server_statuses.get_mut(&language_server_id)
 9117        {
 9118            language_server_status.has_pending_diagnostic_updates = true;
 9119        }
 9120
 9121        cx.emit(LspStoreEvent::DiskBasedDiagnosticsStarted { language_server_id });
 9122        cx.emit(LspStoreEvent::LanguageServerUpdate {
 9123            language_server_id,
 9124            name: self
 9125                .language_server_adapter_for_id(language_server_id)
 9126                .map(|adapter| adapter.name()),
 9127            message: proto::update_language_server::Variant::DiskBasedDiagnosticsUpdating(
 9128                Default::default(),
 9129            ),
 9130        })
 9131    }
 9132
 9133    pub fn disk_based_diagnostics_finished(
 9134        &mut self,
 9135        language_server_id: LanguageServerId,
 9136        cx: &mut Context<Self>,
 9137    ) {
 9138        if let Some(language_server_status) =
 9139            self.language_server_statuses.get_mut(&language_server_id)
 9140        {
 9141            language_server_status.has_pending_diagnostic_updates = false;
 9142        }
 9143
 9144        cx.emit(LspStoreEvent::DiskBasedDiagnosticsFinished { language_server_id });
 9145        cx.emit(LspStoreEvent::LanguageServerUpdate {
 9146            language_server_id,
 9147            name: self
 9148                .language_server_adapter_for_id(language_server_id)
 9149                .map(|adapter| adapter.name()),
 9150            message: proto::update_language_server::Variant::DiskBasedDiagnosticsUpdated(
 9151                Default::default(),
 9152            ),
 9153        })
 9154    }
 9155
 9156    // After saving a buffer using a language server that doesn't provide a disk-based progress token,
 9157    // kick off a timer that will reset every time the buffer is saved. If the timer eventually fires,
 9158    // simulate disk-based diagnostics being finished so that other pieces of UI (e.g., project
 9159    // diagnostics view, diagnostic status bar) can update. We don't emit an event right away because
 9160    // the language server might take some time to publish diagnostics.
 9161    fn simulate_disk_based_diagnostics_events_if_needed(
 9162        &mut self,
 9163        language_server_id: LanguageServerId,
 9164        cx: &mut Context<Self>,
 9165    ) {
 9166        const DISK_BASED_DIAGNOSTICS_DEBOUNCE: Duration = Duration::from_secs(1);
 9167
 9168        let Some(LanguageServerState::Running {
 9169            simulate_disk_based_diagnostics_completion,
 9170            adapter,
 9171            ..
 9172        }) = self
 9173            .as_local_mut()
 9174            .and_then(|local_store| local_store.language_servers.get_mut(&language_server_id))
 9175        else {
 9176            return;
 9177        };
 9178
 9179        if adapter.disk_based_diagnostics_progress_token.is_some() {
 9180            return;
 9181        }
 9182
 9183        let prev_task =
 9184            simulate_disk_based_diagnostics_completion.replace(cx.spawn(async move |this, cx| {
 9185                cx.background_executor()
 9186                    .timer(DISK_BASED_DIAGNOSTICS_DEBOUNCE)
 9187                    .await;
 9188
 9189                this.update(cx, |this, cx| {
 9190                    this.disk_based_diagnostics_finished(language_server_id, cx);
 9191
 9192                    if let Some(LanguageServerState::Running {
 9193                        simulate_disk_based_diagnostics_completion,
 9194                        ..
 9195                    }) = this.as_local_mut().and_then(|local_store| {
 9196                        local_store.language_servers.get_mut(&language_server_id)
 9197                    }) {
 9198                        *simulate_disk_based_diagnostics_completion = None;
 9199                    }
 9200                })
 9201                .ok();
 9202            }));
 9203
 9204        if prev_task.is_none() {
 9205            self.disk_based_diagnostics_started(language_server_id, cx);
 9206        }
 9207    }
 9208
 9209    pub fn language_server_statuses(
 9210        &self,
 9211    ) -> impl DoubleEndedIterator<Item = (LanguageServerId, &LanguageServerStatus)> {
 9212        self.language_server_statuses
 9213            .iter()
 9214            .map(|(key, value)| (*key, value))
 9215    }
 9216
 9217    pub(super) fn did_rename_entry(
 9218        &self,
 9219        worktree_id: WorktreeId,
 9220        old_path: &Path,
 9221        new_path: &Path,
 9222        is_dir: bool,
 9223    ) {
 9224        maybe!({
 9225            let local_store = self.as_local()?;
 9226
 9227            let old_uri = lsp::Url::from_file_path(old_path).ok().map(String::from)?;
 9228            let new_uri = lsp::Url::from_file_path(new_path).ok().map(String::from)?;
 9229
 9230            for language_server in local_store.language_servers_for_worktree(worktree_id) {
 9231                let Some(filter) = local_store
 9232                    .language_server_paths_watched_for_rename
 9233                    .get(&language_server.server_id())
 9234                else {
 9235                    continue;
 9236                };
 9237
 9238                if filter.should_send_did_rename(&old_uri, is_dir) {
 9239                    language_server
 9240                        .notify::<DidRenameFiles>(&RenameFilesParams {
 9241                            files: vec![FileRename {
 9242                                old_uri: old_uri.clone(),
 9243                                new_uri: new_uri.clone(),
 9244                            }],
 9245                        })
 9246                        .ok();
 9247                }
 9248            }
 9249            Some(())
 9250        });
 9251    }
 9252
 9253    pub(super) fn will_rename_entry(
 9254        this: WeakEntity<Self>,
 9255        worktree_id: WorktreeId,
 9256        old_path: &Path,
 9257        new_path: &Path,
 9258        is_dir: bool,
 9259        cx: AsyncApp,
 9260    ) -> Task<ProjectTransaction> {
 9261        let old_uri = lsp::Url::from_file_path(old_path).ok().map(String::from);
 9262        let new_uri = lsp::Url::from_file_path(new_path).ok().map(String::from);
 9263        cx.spawn(async move |cx| {
 9264            let mut tasks = vec![];
 9265            this.update(cx, |this, cx| {
 9266                let local_store = this.as_local()?;
 9267                let old_uri = old_uri?;
 9268                let new_uri = new_uri?;
 9269                for language_server in local_store.language_servers_for_worktree(worktree_id) {
 9270                    let Some(filter) = local_store
 9271                        .language_server_paths_watched_for_rename
 9272                        .get(&language_server.server_id())
 9273                    else {
 9274                        continue;
 9275                    };
 9276
 9277                    if filter.should_send_will_rename(&old_uri, is_dir) {
 9278                        let apply_edit = cx.spawn({
 9279                            let old_uri = old_uri.clone();
 9280                            let new_uri = new_uri.clone();
 9281                            let language_server = language_server.clone();
 9282                            async move |this, cx| {
 9283                                let edit = language_server
 9284                                    .request::<WillRenameFiles>(RenameFilesParams {
 9285                                        files: vec![FileRename { old_uri, new_uri }],
 9286                                    })
 9287                                    .await
 9288                                    .into_response()
 9289                                    .context("will rename files")
 9290                                    .log_err()
 9291                                    .flatten()?;
 9292
 9293                                let transaction = LocalLspStore::deserialize_workspace_edit(
 9294                                    this.upgrade()?,
 9295                                    edit,
 9296                                    false,
 9297                                    language_server.clone(),
 9298                                    cx,
 9299                                )
 9300                                .await
 9301                                .ok()?;
 9302                                Some(transaction)
 9303                            }
 9304                        });
 9305                        tasks.push(apply_edit);
 9306                    }
 9307                }
 9308                Some(())
 9309            })
 9310            .ok()
 9311            .flatten();
 9312            let mut merged_transaction = ProjectTransaction::default();
 9313            for task in tasks {
 9314                // Await on tasks sequentially so that the order of application of edits is deterministic
 9315                // (at least with regards to the order of registration of language servers)
 9316                if let Some(transaction) = task.await {
 9317                    for (buffer, buffer_transaction) in transaction.0 {
 9318                        merged_transaction.0.insert(buffer, buffer_transaction);
 9319                    }
 9320                }
 9321            }
 9322            merged_transaction
 9323        })
 9324    }
 9325
 9326    fn lsp_notify_abs_paths_changed(
 9327        &mut self,
 9328        server_id: LanguageServerId,
 9329        changes: Vec<PathEvent>,
 9330    ) {
 9331        maybe!({
 9332            let server = self.language_server_for_id(server_id)?;
 9333            let changes = changes
 9334                .into_iter()
 9335                .filter_map(|event| {
 9336                    let typ = match event.kind? {
 9337                        PathEventKind::Created => lsp::FileChangeType::CREATED,
 9338                        PathEventKind::Removed => lsp::FileChangeType::DELETED,
 9339                        PathEventKind::Changed => lsp::FileChangeType::CHANGED,
 9340                    };
 9341                    Some(lsp::FileEvent {
 9342                        uri: file_path_to_lsp_url(&event.path).log_err()?,
 9343                        typ,
 9344                    })
 9345                })
 9346                .collect::<Vec<_>>();
 9347            if !changes.is_empty() {
 9348                server
 9349                    .notify::<lsp::notification::DidChangeWatchedFiles>(
 9350                        &lsp::DidChangeWatchedFilesParams { changes },
 9351                    )
 9352                    .ok();
 9353            }
 9354            Some(())
 9355        });
 9356    }
 9357
 9358    pub fn language_server_for_id(&self, id: LanguageServerId) -> Option<Arc<LanguageServer>> {
 9359        self.as_local()?.language_server_for_id(id)
 9360    }
 9361
 9362    fn on_lsp_progress(
 9363        &mut self,
 9364        progress: lsp::ProgressParams,
 9365        language_server_id: LanguageServerId,
 9366        disk_based_diagnostics_progress_token: Option<String>,
 9367        cx: &mut Context<Self>,
 9368    ) {
 9369        let token = match progress.token {
 9370            lsp::NumberOrString::String(token) => token,
 9371            lsp::NumberOrString::Number(token) => {
 9372                log::info!("skipping numeric progress token {}", token);
 9373                return;
 9374            }
 9375        };
 9376
 9377        match progress.value {
 9378            lsp::ProgressParamsValue::WorkDone(progress) => {
 9379                self.handle_work_done_progress(
 9380                    progress,
 9381                    language_server_id,
 9382                    disk_based_diagnostics_progress_token,
 9383                    token,
 9384                    cx,
 9385                );
 9386            }
 9387            lsp::ProgressParamsValue::WorkspaceDiagnostic(report) => {
 9388                if let Some(LanguageServerState::Running {
 9389                    workspace_refresh_task: Some(workspace_refresh_task),
 9390                    ..
 9391                }) = self
 9392                    .as_local_mut()
 9393                    .and_then(|local| local.language_servers.get_mut(&language_server_id))
 9394                {
 9395                    workspace_refresh_task.progress_tx.try_send(()).ok();
 9396                    self.apply_workspace_diagnostic_report(language_server_id, report, cx)
 9397                }
 9398            }
 9399        }
 9400    }
 9401
 9402    fn handle_work_done_progress(
 9403        &mut self,
 9404        progress: lsp::WorkDoneProgress,
 9405        language_server_id: LanguageServerId,
 9406        disk_based_diagnostics_progress_token: Option<String>,
 9407        token: String,
 9408        cx: &mut Context<Self>,
 9409    ) {
 9410        let language_server_status =
 9411            if let Some(status) = self.language_server_statuses.get_mut(&language_server_id) {
 9412                status
 9413            } else {
 9414                return;
 9415            };
 9416
 9417        if !language_server_status.progress_tokens.contains(&token) {
 9418            return;
 9419        }
 9420
 9421        let is_disk_based_diagnostics_progress = disk_based_diagnostics_progress_token
 9422            .as_ref()
 9423            .is_some_and(|disk_based_token| token.starts_with(disk_based_token));
 9424
 9425        match progress {
 9426            lsp::WorkDoneProgress::Begin(report) => {
 9427                if is_disk_based_diagnostics_progress {
 9428                    self.disk_based_diagnostics_started(language_server_id, cx);
 9429                }
 9430                self.on_lsp_work_start(
 9431                    language_server_id,
 9432                    token.clone(),
 9433                    LanguageServerProgress {
 9434                        title: Some(report.title),
 9435                        is_disk_based_diagnostics_progress,
 9436                        is_cancellable: report.cancellable.unwrap_or(false),
 9437                        message: report.message.clone(),
 9438                        percentage: report.percentage.map(|p| p as usize),
 9439                        last_update_at: cx.background_executor().now(),
 9440                    },
 9441                    cx,
 9442                );
 9443            }
 9444            lsp::WorkDoneProgress::Report(report) => self.on_lsp_work_progress(
 9445                language_server_id,
 9446                token,
 9447                LanguageServerProgress {
 9448                    title: None,
 9449                    is_disk_based_diagnostics_progress,
 9450                    is_cancellable: report.cancellable.unwrap_or(false),
 9451                    message: report.message,
 9452                    percentage: report.percentage.map(|p| p as usize),
 9453                    last_update_at: cx.background_executor().now(),
 9454                },
 9455                cx,
 9456            ),
 9457            lsp::WorkDoneProgress::End(_) => {
 9458                language_server_status.progress_tokens.remove(&token);
 9459                self.on_lsp_work_end(language_server_id, token.clone(), cx);
 9460                if is_disk_based_diagnostics_progress {
 9461                    self.disk_based_diagnostics_finished(language_server_id, cx);
 9462                }
 9463            }
 9464        }
 9465    }
 9466
 9467    fn on_lsp_work_start(
 9468        &mut self,
 9469        language_server_id: LanguageServerId,
 9470        token: String,
 9471        progress: LanguageServerProgress,
 9472        cx: &mut Context<Self>,
 9473    ) {
 9474        if let Some(status) = self.language_server_statuses.get_mut(&language_server_id) {
 9475            status.pending_work.insert(token.clone(), progress.clone());
 9476            cx.notify();
 9477        }
 9478        cx.emit(LspStoreEvent::LanguageServerUpdate {
 9479            language_server_id,
 9480            name: self
 9481                .language_server_adapter_for_id(language_server_id)
 9482                .map(|adapter| adapter.name()),
 9483            message: proto::update_language_server::Variant::WorkStart(proto::LspWorkStart {
 9484                token,
 9485                title: progress.title,
 9486                message: progress.message,
 9487                percentage: progress.percentage.map(|p| p as u32),
 9488                is_cancellable: Some(progress.is_cancellable),
 9489            }),
 9490        })
 9491    }
 9492
 9493    fn on_lsp_work_progress(
 9494        &mut self,
 9495        language_server_id: LanguageServerId,
 9496        token: String,
 9497        progress: LanguageServerProgress,
 9498        cx: &mut Context<Self>,
 9499    ) {
 9500        let mut did_update = false;
 9501        if let Some(status) = self.language_server_statuses.get_mut(&language_server_id) {
 9502            match status.pending_work.entry(token.clone()) {
 9503                btree_map::Entry::Vacant(entry) => {
 9504                    entry.insert(progress.clone());
 9505                    did_update = true;
 9506                }
 9507                btree_map::Entry::Occupied(mut entry) => {
 9508                    let entry = entry.get_mut();
 9509                    if (progress.last_update_at - entry.last_update_at)
 9510                        >= SERVER_PROGRESS_THROTTLE_TIMEOUT
 9511                    {
 9512                        entry.last_update_at = progress.last_update_at;
 9513                        if progress.message.is_some() {
 9514                            entry.message = progress.message.clone();
 9515                        }
 9516                        if progress.percentage.is_some() {
 9517                            entry.percentage = progress.percentage;
 9518                        }
 9519                        if progress.is_cancellable != entry.is_cancellable {
 9520                            entry.is_cancellable = progress.is_cancellable;
 9521                        }
 9522                        did_update = true;
 9523                    }
 9524                }
 9525            }
 9526        }
 9527
 9528        if did_update {
 9529            cx.emit(LspStoreEvent::LanguageServerUpdate {
 9530                language_server_id,
 9531                name: self
 9532                    .language_server_adapter_for_id(language_server_id)
 9533                    .map(|adapter| adapter.name()),
 9534                message: proto::update_language_server::Variant::WorkProgress(
 9535                    proto::LspWorkProgress {
 9536                        token,
 9537                        message: progress.message,
 9538                        percentage: progress.percentage.map(|p| p as u32),
 9539                        is_cancellable: Some(progress.is_cancellable),
 9540                    },
 9541                ),
 9542            })
 9543        }
 9544    }
 9545
 9546    fn on_lsp_work_end(
 9547        &mut self,
 9548        language_server_id: LanguageServerId,
 9549        token: String,
 9550        cx: &mut Context<Self>,
 9551    ) {
 9552        if let Some(status) = self.language_server_statuses.get_mut(&language_server_id) {
 9553            if let Some(work) = status.pending_work.remove(&token)
 9554                && !work.is_disk_based_diagnostics_progress
 9555            {
 9556                cx.emit(LspStoreEvent::RefreshInlayHints);
 9557            }
 9558            cx.notify();
 9559        }
 9560
 9561        cx.emit(LspStoreEvent::LanguageServerUpdate {
 9562            language_server_id,
 9563            name: self
 9564                .language_server_adapter_for_id(language_server_id)
 9565                .map(|adapter| adapter.name()),
 9566            message: proto::update_language_server::Variant::WorkEnd(proto::LspWorkEnd { token }),
 9567        })
 9568    }
 9569
 9570    pub async fn handle_resolve_completion_documentation(
 9571        this: Entity<Self>,
 9572        envelope: TypedEnvelope<proto::ResolveCompletionDocumentation>,
 9573        mut cx: AsyncApp,
 9574    ) -> Result<proto::ResolveCompletionDocumentationResponse> {
 9575        let lsp_completion = serde_json::from_slice(&envelope.payload.lsp_completion)?;
 9576
 9577        let completion = this
 9578            .read_with(&cx, |this, cx| {
 9579                let id = LanguageServerId(envelope.payload.language_server_id as usize);
 9580                let server = this
 9581                    .language_server_for_id(id)
 9582                    .with_context(|| format!("No language server {id}"))?;
 9583
 9584                anyhow::Ok(cx.background_spawn(async move {
 9585                    let can_resolve = server
 9586                        .capabilities()
 9587                        .completion_provider
 9588                        .as_ref()
 9589                        .and_then(|options| options.resolve_provider)
 9590                        .unwrap_or(false);
 9591                    if can_resolve {
 9592                        server
 9593                            .request::<lsp::request::ResolveCompletionItem>(lsp_completion)
 9594                            .await
 9595                            .into_response()
 9596                            .context("resolve completion item")
 9597                    } else {
 9598                        anyhow::Ok(lsp_completion)
 9599                    }
 9600                }))
 9601            })??
 9602            .await?;
 9603
 9604        let mut documentation_is_markdown = false;
 9605        let lsp_completion = serde_json::to_string(&completion)?.into_bytes();
 9606        let documentation = match completion.documentation {
 9607            Some(lsp::Documentation::String(text)) => text,
 9608
 9609            Some(lsp::Documentation::MarkupContent(lsp::MarkupContent { kind, value })) => {
 9610                documentation_is_markdown = kind == lsp::MarkupKind::Markdown;
 9611                value
 9612            }
 9613
 9614            _ => String::new(),
 9615        };
 9616
 9617        // If we have a new buffer_id, that means we're talking to a new client
 9618        // and want to check for new text_edits in the completion too.
 9619        let mut old_replace_start = None;
 9620        let mut old_replace_end = None;
 9621        let mut old_insert_start = None;
 9622        let mut old_insert_end = None;
 9623        let mut new_text = String::default();
 9624        if let Ok(buffer_id) = BufferId::new(envelope.payload.buffer_id) {
 9625            let buffer_snapshot = this.update(&mut cx, |this, cx| {
 9626                let buffer = this.buffer_store.read(cx).get_existing(buffer_id)?;
 9627                anyhow::Ok(buffer.read(cx).snapshot())
 9628            })??;
 9629
 9630            if let Some(text_edit) = completion.text_edit.as_ref() {
 9631                let edit = parse_completion_text_edit(text_edit, &buffer_snapshot);
 9632
 9633                if let Some(mut edit) = edit {
 9634                    LineEnding::normalize(&mut edit.new_text);
 9635
 9636                    new_text = edit.new_text;
 9637                    old_replace_start = Some(serialize_anchor(&edit.replace_range.start));
 9638                    old_replace_end = Some(serialize_anchor(&edit.replace_range.end));
 9639                    if let Some(insert_range) = edit.insert_range {
 9640                        old_insert_start = Some(serialize_anchor(&insert_range.start));
 9641                        old_insert_end = Some(serialize_anchor(&insert_range.end));
 9642                    }
 9643                }
 9644            }
 9645        }
 9646
 9647        Ok(proto::ResolveCompletionDocumentationResponse {
 9648            documentation,
 9649            documentation_is_markdown,
 9650            old_replace_start,
 9651            old_replace_end,
 9652            new_text,
 9653            lsp_completion,
 9654            old_insert_start,
 9655            old_insert_end,
 9656        })
 9657    }
 9658
 9659    async fn handle_on_type_formatting(
 9660        this: Entity<Self>,
 9661        envelope: TypedEnvelope<proto::OnTypeFormatting>,
 9662        mut cx: AsyncApp,
 9663    ) -> Result<proto::OnTypeFormattingResponse> {
 9664        let on_type_formatting = this.update(&mut cx, |this, cx| {
 9665            let buffer_id = BufferId::new(envelope.payload.buffer_id)?;
 9666            let buffer = this.buffer_store.read(cx).get_existing(buffer_id)?;
 9667            let position = envelope
 9668                .payload
 9669                .position
 9670                .and_then(deserialize_anchor)
 9671                .context("invalid position")?;
 9672            anyhow::Ok(this.apply_on_type_formatting(
 9673                buffer,
 9674                position,
 9675                envelope.payload.trigger.clone(),
 9676                cx,
 9677            ))
 9678        })??;
 9679
 9680        let transaction = on_type_formatting
 9681            .await?
 9682            .as_ref()
 9683            .map(language::proto::serialize_transaction);
 9684        Ok(proto::OnTypeFormattingResponse { transaction })
 9685    }
 9686
 9687    async fn handle_refresh_inlay_hints(
 9688        this: Entity<Self>,
 9689        _: TypedEnvelope<proto::RefreshInlayHints>,
 9690        mut cx: AsyncApp,
 9691    ) -> Result<proto::Ack> {
 9692        this.update(&mut cx, |_, cx| {
 9693            cx.emit(LspStoreEvent::RefreshInlayHints);
 9694        })?;
 9695        Ok(proto::Ack {})
 9696    }
 9697
 9698    async fn handle_pull_workspace_diagnostics(
 9699        lsp_store: Entity<Self>,
 9700        envelope: TypedEnvelope<proto::PullWorkspaceDiagnostics>,
 9701        mut cx: AsyncApp,
 9702    ) -> Result<proto::Ack> {
 9703        let server_id = LanguageServerId::from_proto(envelope.payload.server_id);
 9704        lsp_store.update(&mut cx, |lsp_store, _| {
 9705            lsp_store.pull_workspace_diagnostics(server_id);
 9706        })?;
 9707        Ok(proto::Ack {})
 9708    }
 9709
 9710    async fn handle_inlay_hints(
 9711        this: Entity<Self>,
 9712        envelope: TypedEnvelope<proto::InlayHints>,
 9713        mut cx: AsyncApp,
 9714    ) -> Result<proto::InlayHintsResponse> {
 9715        let sender_id = envelope.original_sender_id().unwrap_or_default();
 9716        let buffer_id = BufferId::new(envelope.payload.buffer_id)?;
 9717        let buffer = this.update(&mut cx, |this, cx| {
 9718            this.buffer_store.read(cx).get_existing(buffer_id)
 9719        })??;
 9720        buffer
 9721            .update(&mut cx, |buffer, _| {
 9722                buffer.wait_for_version(deserialize_version(&envelope.payload.version))
 9723            })?
 9724            .await
 9725            .with_context(|| format!("waiting for version for buffer {}", buffer.entity_id()))?;
 9726
 9727        let start = envelope
 9728            .payload
 9729            .start
 9730            .and_then(deserialize_anchor)
 9731            .context("missing range start")?;
 9732        let end = envelope
 9733            .payload
 9734            .end
 9735            .and_then(deserialize_anchor)
 9736            .context("missing range end")?;
 9737        let buffer_hints = this
 9738            .update(&mut cx, |lsp_store, cx| {
 9739                lsp_store.inlay_hints(buffer.clone(), start..end, cx)
 9740            })?
 9741            .await
 9742            .context("inlay hints fetch")?;
 9743
 9744        this.update(&mut cx, |project, cx| {
 9745            InlayHints::response_to_proto(
 9746                buffer_hints,
 9747                project,
 9748                sender_id,
 9749                &buffer.read(cx).version(),
 9750                cx,
 9751            )
 9752        })
 9753    }
 9754
 9755    async fn handle_get_color_presentation(
 9756        lsp_store: Entity<Self>,
 9757        envelope: TypedEnvelope<proto::GetColorPresentation>,
 9758        mut cx: AsyncApp,
 9759    ) -> Result<proto::GetColorPresentationResponse> {
 9760        let buffer_id = BufferId::new(envelope.payload.buffer_id)?;
 9761        let buffer = lsp_store.update(&mut cx, |lsp_store, cx| {
 9762            lsp_store.buffer_store.read(cx).get_existing(buffer_id)
 9763        })??;
 9764
 9765        let color = envelope
 9766            .payload
 9767            .color
 9768            .context("invalid color resolve request")?;
 9769        let start = color
 9770            .lsp_range_start
 9771            .context("invalid color resolve request")?;
 9772        let end = color
 9773            .lsp_range_end
 9774            .context("invalid color resolve request")?;
 9775
 9776        let color = DocumentColor {
 9777            lsp_range: lsp::Range {
 9778                start: point_to_lsp(PointUtf16::new(start.row, start.column)),
 9779                end: point_to_lsp(PointUtf16::new(end.row, end.column)),
 9780            },
 9781            color: lsp::Color {
 9782                red: color.red,
 9783                green: color.green,
 9784                blue: color.blue,
 9785                alpha: color.alpha,
 9786            },
 9787            resolved: false,
 9788            color_presentations: Vec::new(),
 9789        };
 9790        let resolved_color = lsp_store
 9791            .update(&mut cx, |lsp_store, cx| {
 9792                lsp_store.resolve_color_presentation(
 9793                    color,
 9794                    buffer.clone(),
 9795                    LanguageServerId(envelope.payload.server_id as usize),
 9796                    cx,
 9797                )
 9798            })?
 9799            .await
 9800            .context("resolving color presentation")?;
 9801
 9802        Ok(proto::GetColorPresentationResponse {
 9803            presentations: resolved_color
 9804                .color_presentations
 9805                .into_iter()
 9806                .map(|presentation| proto::ColorPresentation {
 9807                    label: presentation.label.to_string(),
 9808                    text_edit: presentation.text_edit.map(serialize_lsp_edit),
 9809                    additional_text_edits: presentation
 9810                        .additional_text_edits
 9811                        .into_iter()
 9812                        .map(serialize_lsp_edit)
 9813                        .collect(),
 9814                })
 9815                .collect(),
 9816        })
 9817    }
 9818
 9819    async fn handle_resolve_inlay_hint(
 9820        this: Entity<Self>,
 9821        envelope: TypedEnvelope<proto::ResolveInlayHint>,
 9822        mut cx: AsyncApp,
 9823    ) -> Result<proto::ResolveInlayHintResponse> {
 9824        let proto_hint = envelope
 9825            .payload
 9826            .hint
 9827            .expect("incorrect protobuf resolve inlay hint message: missing the inlay hint");
 9828        let hint = InlayHints::proto_to_project_hint(proto_hint)
 9829            .context("resolved proto inlay hint conversion")?;
 9830        let buffer = this.update(&mut cx, |this, cx| {
 9831            let buffer_id = BufferId::new(envelope.payload.buffer_id)?;
 9832            this.buffer_store.read(cx).get_existing(buffer_id)
 9833        })??;
 9834        let response_hint = this
 9835            .update(&mut cx, |this, cx| {
 9836                this.resolve_inlay_hint(
 9837                    hint,
 9838                    buffer,
 9839                    LanguageServerId(envelope.payload.language_server_id as usize),
 9840                    cx,
 9841                )
 9842            })?
 9843            .await
 9844            .context("inlay hints fetch")?;
 9845        Ok(proto::ResolveInlayHintResponse {
 9846            hint: Some(InlayHints::project_to_proto_hint(response_hint)),
 9847        })
 9848    }
 9849
 9850    async fn handle_refresh_code_lens(
 9851        this: Entity<Self>,
 9852        _: TypedEnvelope<proto::RefreshCodeLens>,
 9853        mut cx: AsyncApp,
 9854    ) -> Result<proto::Ack> {
 9855        this.update(&mut cx, |_, cx| {
 9856            cx.emit(LspStoreEvent::RefreshCodeLens);
 9857        })?;
 9858        Ok(proto::Ack {})
 9859    }
 9860
 9861    async fn handle_open_buffer_for_symbol(
 9862        this: Entity<Self>,
 9863        envelope: TypedEnvelope<proto::OpenBufferForSymbol>,
 9864        mut cx: AsyncApp,
 9865    ) -> Result<proto::OpenBufferForSymbolResponse> {
 9866        let peer_id = envelope.original_sender_id().unwrap_or_default();
 9867        let symbol = envelope.payload.symbol.context("invalid symbol")?;
 9868        let symbol = Self::deserialize_symbol(symbol)?;
 9869        let symbol = this.read_with(&cx, |this, _| {
 9870            let signature = this.symbol_signature(&symbol.path);
 9871            anyhow::ensure!(signature == symbol.signature, "invalid symbol signature");
 9872            Ok(symbol)
 9873        })??;
 9874        let buffer = this
 9875            .update(&mut cx, |this, cx| {
 9876                this.open_buffer_for_symbol(
 9877                    &Symbol {
 9878                        language_server_name: symbol.language_server_name,
 9879                        source_worktree_id: symbol.source_worktree_id,
 9880                        source_language_server_id: symbol.source_language_server_id,
 9881                        path: symbol.path,
 9882                        name: symbol.name,
 9883                        kind: symbol.kind,
 9884                        range: symbol.range,
 9885                        signature: symbol.signature,
 9886                        label: CodeLabel {
 9887                            text: Default::default(),
 9888                            runs: Default::default(),
 9889                            filter_range: Default::default(),
 9890                        },
 9891                    },
 9892                    cx,
 9893                )
 9894            })?
 9895            .await?;
 9896
 9897        this.update(&mut cx, |this, cx| {
 9898            let is_private = buffer
 9899                .read(cx)
 9900                .file()
 9901                .map(|f| f.is_private())
 9902                .unwrap_or_default();
 9903            if is_private {
 9904                Err(anyhow!(rpc::ErrorCode::UnsharedItem))
 9905            } else {
 9906                this.buffer_store
 9907                    .update(cx, |buffer_store, cx| {
 9908                        buffer_store.create_buffer_for_peer(&buffer, peer_id, cx)
 9909                    })
 9910                    .detach_and_log_err(cx);
 9911                let buffer_id = buffer.read(cx).remote_id().to_proto();
 9912                Ok(proto::OpenBufferForSymbolResponse { buffer_id })
 9913            }
 9914        })?
 9915    }
 9916
 9917    fn symbol_signature(&self, project_path: &ProjectPath) -> [u8; 32] {
 9918        let mut hasher = Sha256::new();
 9919        hasher.update(project_path.worktree_id.to_proto().to_be_bytes());
 9920        hasher.update(project_path.path.to_string_lossy().as_bytes());
 9921        hasher.update(self.nonce.to_be_bytes());
 9922        hasher.finalize().as_slice().try_into().unwrap()
 9923    }
 9924
 9925    pub async fn handle_get_project_symbols(
 9926        this: Entity<Self>,
 9927        envelope: TypedEnvelope<proto::GetProjectSymbols>,
 9928        mut cx: AsyncApp,
 9929    ) -> Result<proto::GetProjectSymbolsResponse> {
 9930        let symbols = this
 9931            .update(&mut cx, |this, cx| {
 9932                this.symbols(&envelope.payload.query, cx)
 9933            })?
 9934            .await?;
 9935
 9936        Ok(proto::GetProjectSymbolsResponse {
 9937            symbols: symbols.iter().map(Self::serialize_symbol).collect(),
 9938        })
 9939    }
 9940
 9941    pub async fn handle_restart_language_servers(
 9942        this: Entity<Self>,
 9943        envelope: TypedEnvelope<proto::RestartLanguageServers>,
 9944        mut cx: AsyncApp,
 9945    ) -> Result<proto::Ack> {
 9946        this.update(&mut cx, |lsp_store, cx| {
 9947            let buffers =
 9948                lsp_store.buffer_ids_to_buffers(envelope.payload.buffer_ids.into_iter(), cx);
 9949            lsp_store.restart_language_servers_for_buffers(
 9950                buffers,
 9951                envelope
 9952                    .payload
 9953                    .only_servers
 9954                    .into_iter()
 9955                    .filter_map(|selector| {
 9956                        Some(match selector.selector? {
 9957                            proto::language_server_selector::Selector::ServerId(server_id) => {
 9958                                LanguageServerSelector::Id(LanguageServerId::from_proto(server_id))
 9959                            }
 9960                            proto::language_server_selector::Selector::Name(name) => {
 9961                                LanguageServerSelector::Name(LanguageServerName(
 9962                                    SharedString::from(name),
 9963                                ))
 9964                            }
 9965                        })
 9966                    })
 9967                    .collect(),
 9968                cx,
 9969            );
 9970        })?;
 9971
 9972        Ok(proto::Ack {})
 9973    }
 9974
 9975    pub async fn handle_stop_language_servers(
 9976        lsp_store: Entity<Self>,
 9977        envelope: TypedEnvelope<proto::StopLanguageServers>,
 9978        mut cx: AsyncApp,
 9979    ) -> Result<proto::Ack> {
 9980        lsp_store.update(&mut cx, |lsp_store, cx| {
 9981            if envelope.payload.all
 9982                && envelope.payload.also_servers.is_empty()
 9983                && envelope.payload.buffer_ids.is_empty()
 9984            {
 9985                lsp_store.stop_all_language_servers(cx);
 9986            } else {
 9987                let buffers =
 9988                    lsp_store.buffer_ids_to_buffers(envelope.payload.buffer_ids.into_iter(), cx);
 9989                lsp_store
 9990                    .stop_language_servers_for_buffers(
 9991                        buffers,
 9992                        envelope
 9993                            .payload
 9994                            .also_servers
 9995                            .into_iter()
 9996                            .filter_map(|selector| {
 9997                                Some(match selector.selector? {
 9998                                    proto::language_server_selector::Selector::ServerId(
 9999                                        server_id,
10000                                    ) => LanguageServerSelector::Id(LanguageServerId::from_proto(
10001                                        server_id,
10002                                    )),
10003                                    proto::language_server_selector::Selector::Name(name) => {
10004                                        LanguageServerSelector::Name(LanguageServerName(
10005                                            SharedString::from(name),
10006                                        ))
10007                                    }
10008                                })
10009                            })
10010                            .collect(),
10011                        cx,
10012                    )
10013                    .detach_and_log_err(cx);
10014            }
10015        })?;
10016
10017        Ok(proto::Ack {})
10018    }
10019
10020    pub async fn handle_cancel_language_server_work(
10021        this: Entity<Self>,
10022        envelope: TypedEnvelope<proto::CancelLanguageServerWork>,
10023        mut cx: AsyncApp,
10024    ) -> Result<proto::Ack> {
10025        this.update(&mut cx, |this, cx| {
10026            if let Some(work) = envelope.payload.work {
10027                match work {
10028                    proto::cancel_language_server_work::Work::Buffers(buffers) => {
10029                        let buffers =
10030                            this.buffer_ids_to_buffers(buffers.buffer_ids.into_iter(), cx);
10031                        this.cancel_language_server_work_for_buffers(buffers, cx);
10032                    }
10033                    proto::cancel_language_server_work::Work::LanguageServerWork(work) => {
10034                        let server_id = LanguageServerId::from_proto(work.language_server_id);
10035                        this.cancel_language_server_work(server_id, work.token, cx);
10036                    }
10037                }
10038            }
10039        })?;
10040
10041        Ok(proto::Ack {})
10042    }
10043
10044    fn buffer_ids_to_buffers(
10045        &mut self,
10046        buffer_ids: impl Iterator<Item = u64>,
10047        cx: &mut Context<Self>,
10048    ) -> Vec<Entity<Buffer>> {
10049        buffer_ids
10050            .into_iter()
10051            .flat_map(|buffer_id| {
10052                self.buffer_store
10053                    .read(cx)
10054                    .get(BufferId::new(buffer_id).log_err()?)
10055            })
10056            .collect::<Vec<_>>()
10057    }
10058
10059    async fn handle_apply_additional_edits_for_completion(
10060        this: Entity<Self>,
10061        envelope: TypedEnvelope<proto::ApplyCompletionAdditionalEdits>,
10062        mut cx: AsyncApp,
10063    ) -> Result<proto::ApplyCompletionAdditionalEditsResponse> {
10064        let (buffer, completion) = this.update(&mut cx, |this, cx| {
10065            let buffer_id = BufferId::new(envelope.payload.buffer_id)?;
10066            let buffer = this.buffer_store.read(cx).get_existing(buffer_id)?;
10067            let completion = Self::deserialize_completion(
10068                envelope.payload.completion.context("invalid completion")?,
10069            )?;
10070            anyhow::Ok((buffer, completion))
10071        })??;
10072
10073        let apply_additional_edits = this.update(&mut cx, |this, cx| {
10074            this.apply_additional_edits_for_completion(
10075                buffer,
10076                Rc::new(RefCell::new(Box::new([Completion {
10077                    replace_range: completion.replace_range,
10078                    new_text: completion.new_text,
10079                    source: completion.source,
10080                    documentation: None,
10081                    label: CodeLabel {
10082                        text: Default::default(),
10083                        runs: Default::default(),
10084                        filter_range: Default::default(),
10085                    },
10086                    insert_text_mode: None,
10087                    icon_path: None,
10088                    confirm: None,
10089                }]))),
10090                0,
10091                false,
10092                cx,
10093            )
10094        })?;
10095
10096        Ok(proto::ApplyCompletionAdditionalEditsResponse {
10097            transaction: apply_additional_edits
10098                .await?
10099                .as_ref()
10100                .map(language::proto::serialize_transaction),
10101        })
10102    }
10103
10104    pub fn last_formatting_failure(&self) -> Option<&str> {
10105        self.last_formatting_failure.as_deref()
10106    }
10107
10108    pub fn reset_last_formatting_failure(&mut self) {
10109        self.last_formatting_failure = None;
10110    }
10111
10112    pub fn environment_for_buffer(
10113        &self,
10114        buffer: &Entity<Buffer>,
10115        cx: &mut Context<Self>,
10116    ) -> Shared<Task<Option<HashMap<String, String>>>> {
10117        if let Some(environment) = &self.as_local().map(|local| local.environment.clone()) {
10118            environment.update(cx, |env, cx| {
10119                env.get_buffer_environment(buffer, &self.worktree_store, cx)
10120            })
10121        } else {
10122            Task::ready(None).shared()
10123        }
10124    }
10125
10126    pub fn format(
10127        &mut self,
10128        buffers: HashSet<Entity<Buffer>>,
10129        target: LspFormatTarget,
10130        push_to_history: bool,
10131        trigger: FormatTrigger,
10132        cx: &mut Context<Self>,
10133    ) -> Task<anyhow::Result<ProjectTransaction>> {
10134        let logger = zlog::scoped!("format");
10135        if self.as_local().is_some() {
10136            zlog::trace!(logger => "Formatting locally");
10137            let logger = zlog::scoped!(logger => "local");
10138            let buffers = buffers
10139                .into_iter()
10140                .map(|buffer_handle| {
10141                    let buffer = buffer_handle.read(cx);
10142                    let buffer_abs_path = File::from_dyn(buffer.file())
10143                        .and_then(|file| file.as_local().map(|f| f.abs_path(cx)));
10144
10145                    (buffer_handle, buffer_abs_path, buffer.remote_id())
10146                })
10147                .collect::<Vec<_>>();
10148
10149            cx.spawn(async move |lsp_store, cx| {
10150                let mut formattable_buffers = Vec::with_capacity(buffers.len());
10151
10152                for (handle, abs_path, id) in buffers {
10153                    let env = lsp_store
10154                        .update(cx, |lsp_store, cx| {
10155                            lsp_store.environment_for_buffer(&handle, cx)
10156                        })?
10157                        .await;
10158
10159                    let ranges = match &target {
10160                        LspFormatTarget::Buffers => None,
10161                        LspFormatTarget::Ranges(ranges) => {
10162                            Some(ranges.get(&id).context("No format ranges provided for buffer")?.clone())
10163                        }
10164                    };
10165
10166                    formattable_buffers.push(FormattableBuffer {
10167                        handle,
10168                        abs_path,
10169                        env,
10170                        ranges,
10171                    });
10172                }
10173                zlog::trace!(logger => "Formatting {:?} buffers", formattable_buffers.len());
10174
10175                let format_timer = zlog::time!(logger => "Formatting buffers");
10176                let result = LocalLspStore::format_locally(
10177                    lsp_store.clone(),
10178                    formattable_buffers,
10179                    push_to_history,
10180                    trigger,
10181                    logger,
10182                    cx,
10183                )
10184                .await;
10185                format_timer.end();
10186
10187                zlog::trace!(logger => "Formatting completed with result {:?}", result.as_ref().map(|_| "<project-transaction>"));
10188
10189                lsp_store.update(cx, |lsp_store, _| {
10190                    lsp_store.update_last_formatting_failure(&result);
10191                })?;
10192
10193                result
10194            })
10195        } else if let Some((client, project_id)) = self.upstream_client() {
10196            zlog::trace!(logger => "Formatting remotely");
10197            let logger = zlog::scoped!(logger => "remote");
10198            // Don't support formatting ranges via remote
10199            match target {
10200                LspFormatTarget::Buffers => {}
10201                LspFormatTarget::Ranges(_) => {
10202                    zlog::trace!(logger => "Ignoring unsupported remote range formatting request");
10203                    return Task::ready(Ok(ProjectTransaction::default()));
10204                }
10205            }
10206
10207            let buffer_store = self.buffer_store();
10208            cx.spawn(async move |lsp_store, cx| {
10209                zlog::trace!(logger => "Sending remote format request");
10210                let request_timer = zlog::time!(logger => "remote format request");
10211                let result = client
10212                    .request(proto::FormatBuffers {
10213                        project_id,
10214                        trigger: trigger as i32,
10215                        buffer_ids: buffers
10216                            .iter()
10217                            .map(|buffer| buffer.read_with(cx, |buffer, _| buffer.remote_id().into()))
10218                            .collect::<Result<_>>()?,
10219                    })
10220                    .await
10221                    .and_then(|result| result.transaction.context("missing transaction"));
10222                request_timer.end();
10223
10224                zlog::trace!(logger => "Remote format request resolved to {:?}", result.as_ref().map(|_| "<project_transaction>"));
10225
10226                lsp_store.update(cx, |lsp_store, _| {
10227                    lsp_store.update_last_formatting_failure(&result);
10228                })?;
10229
10230                let transaction_response = result?;
10231                let _timer = zlog::time!(logger => "deserializing project transaction");
10232                buffer_store
10233                    .update(cx, |buffer_store, cx| {
10234                        buffer_store.deserialize_project_transaction(
10235                            transaction_response,
10236                            push_to_history,
10237                            cx,
10238                        )
10239                    })?
10240                    .await
10241            })
10242        } else {
10243            zlog::trace!(logger => "Not formatting");
10244            Task::ready(Ok(ProjectTransaction::default()))
10245        }
10246    }
10247
10248    async fn handle_format_buffers(
10249        this: Entity<Self>,
10250        envelope: TypedEnvelope<proto::FormatBuffers>,
10251        mut cx: AsyncApp,
10252    ) -> Result<proto::FormatBuffersResponse> {
10253        let sender_id = envelope.original_sender_id().unwrap_or_default();
10254        let format = this.update(&mut cx, |this, cx| {
10255            let mut buffers = HashSet::default();
10256            for buffer_id in &envelope.payload.buffer_ids {
10257                let buffer_id = BufferId::new(*buffer_id)?;
10258                buffers.insert(this.buffer_store.read(cx).get_existing(buffer_id)?);
10259            }
10260            let trigger = FormatTrigger::from_proto(envelope.payload.trigger);
10261            anyhow::Ok(this.format(buffers, LspFormatTarget::Buffers, false, trigger, cx))
10262        })??;
10263
10264        let project_transaction = format.await?;
10265        let project_transaction = this.update(&mut cx, |this, cx| {
10266            this.buffer_store.update(cx, |buffer_store, cx| {
10267                buffer_store.serialize_project_transaction_for_peer(
10268                    project_transaction,
10269                    sender_id,
10270                    cx,
10271                )
10272            })
10273        })?;
10274        Ok(proto::FormatBuffersResponse {
10275            transaction: Some(project_transaction),
10276        })
10277    }
10278
10279    async fn handle_apply_code_action_kind(
10280        this: Entity<Self>,
10281        envelope: TypedEnvelope<proto::ApplyCodeActionKind>,
10282        mut cx: AsyncApp,
10283    ) -> Result<proto::ApplyCodeActionKindResponse> {
10284        let sender_id = envelope.original_sender_id().unwrap_or_default();
10285        let format = this.update(&mut cx, |this, cx| {
10286            let mut buffers = HashSet::default();
10287            for buffer_id in &envelope.payload.buffer_ids {
10288                let buffer_id = BufferId::new(*buffer_id)?;
10289                buffers.insert(this.buffer_store.read(cx).get_existing(buffer_id)?);
10290            }
10291            let kind = match envelope.payload.kind.as_str() {
10292                "" => CodeActionKind::EMPTY,
10293                "quickfix" => CodeActionKind::QUICKFIX,
10294                "refactor" => CodeActionKind::REFACTOR,
10295                "refactor.extract" => CodeActionKind::REFACTOR_EXTRACT,
10296                "refactor.inline" => CodeActionKind::REFACTOR_INLINE,
10297                "refactor.rewrite" => CodeActionKind::REFACTOR_REWRITE,
10298                "source" => CodeActionKind::SOURCE,
10299                "source.organizeImports" => CodeActionKind::SOURCE_ORGANIZE_IMPORTS,
10300                "source.fixAll" => CodeActionKind::SOURCE_FIX_ALL,
10301                _ => anyhow::bail!(
10302                    "Invalid code action kind {}",
10303                    envelope.payload.kind.as_str()
10304                ),
10305            };
10306            anyhow::Ok(this.apply_code_action_kind(buffers, kind, false, cx))
10307        })??;
10308
10309        let project_transaction = format.await?;
10310        let project_transaction = this.update(&mut cx, |this, cx| {
10311            this.buffer_store.update(cx, |buffer_store, cx| {
10312                buffer_store.serialize_project_transaction_for_peer(
10313                    project_transaction,
10314                    sender_id,
10315                    cx,
10316                )
10317            })
10318        })?;
10319        Ok(proto::ApplyCodeActionKindResponse {
10320            transaction: Some(project_transaction),
10321        })
10322    }
10323
10324    async fn shutdown_language_server(
10325        server_state: Option<LanguageServerState>,
10326        name: LanguageServerName,
10327        cx: &mut AsyncApp,
10328    ) {
10329        let server = match server_state {
10330            Some(LanguageServerState::Starting { startup, .. }) => {
10331                let mut timer = cx
10332                    .background_executor()
10333                    .timer(SERVER_LAUNCHING_BEFORE_SHUTDOWN_TIMEOUT)
10334                    .fuse();
10335
10336                select! {
10337                    server = startup.fuse() => server,
10338                    () = timer => {
10339                        log::info!("timeout waiting for language server {name} to finish launching before stopping");
10340                        None
10341                    },
10342                }
10343            }
10344
10345            Some(LanguageServerState::Running { server, .. }) => Some(server),
10346
10347            None => None,
10348        };
10349
10350        if let Some(server) = server
10351            && let Some(shutdown) = server.shutdown()
10352        {
10353            shutdown.await;
10354        }
10355    }
10356
10357    // Returns a list of all of the worktrees which no longer have a language server and the root path
10358    // for the stopped server
10359    fn stop_local_language_server(
10360        &mut self,
10361        server_id: LanguageServerId,
10362        cx: &mut Context<Self>,
10363    ) -> Task<()> {
10364        let local = match &mut self.mode {
10365            LspStoreMode::Local(local) => local,
10366            _ => {
10367                return Task::ready(());
10368            }
10369        };
10370
10371        // Remove this server ID from all entries in the given worktree.
10372        local
10373            .language_server_ids
10374            .retain(|_, state| state.id != server_id);
10375        self.buffer_store.update(cx, |buffer_store, cx| {
10376            for buffer in buffer_store.buffers() {
10377                buffer.update(cx, |buffer, cx| {
10378                    buffer.update_diagnostics(server_id, DiagnosticSet::new([], buffer), cx);
10379                    buffer.set_completion_triggers(server_id, Default::default(), cx);
10380                });
10381            }
10382        });
10383
10384        for (worktree_id, summaries) in self.diagnostic_summaries.iter_mut() {
10385            summaries.retain(|path, summaries_by_server_id| {
10386                if summaries_by_server_id.remove(&server_id).is_some() {
10387                    if let Some((client, project_id)) = self.downstream_client.clone() {
10388                        client
10389                            .send(proto::UpdateDiagnosticSummary {
10390                                project_id,
10391                                worktree_id: worktree_id.to_proto(),
10392                                summary: Some(proto::DiagnosticSummary {
10393                                    path: path.as_ref().to_proto(),
10394                                    language_server_id: server_id.0 as u64,
10395                                    error_count: 0,
10396                                    warning_count: 0,
10397                                }),
10398                                more_summaries: Vec::new(),
10399                            })
10400                            .log_err();
10401                    }
10402                    !summaries_by_server_id.is_empty()
10403                } else {
10404                    true
10405                }
10406            });
10407        }
10408
10409        let local = self.as_local_mut().unwrap();
10410        for diagnostics in local.diagnostics.values_mut() {
10411            diagnostics.retain(|_, diagnostics_by_server_id| {
10412                if let Ok(ix) = diagnostics_by_server_id.binary_search_by_key(&server_id, |e| e.0) {
10413                    diagnostics_by_server_id.remove(ix);
10414                    !diagnostics_by_server_id.is_empty()
10415                } else {
10416                    true
10417                }
10418            });
10419        }
10420        local.language_server_watched_paths.remove(&server_id);
10421
10422        let server_state = local.language_servers.remove(&server_id);
10423        self.cleanup_lsp_data(server_id);
10424        let name = self
10425            .language_server_statuses
10426            .remove(&server_id)
10427            .map(|status| status.name)
10428            .or_else(|| {
10429                if let Some(LanguageServerState::Running { adapter, .. }) = server_state.as_ref() {
10430                    Some(adapter.name())
10431                } else {
10432                    None
10433                }
10434            });
10435
10436        if let Some(name) = name {
10437            log::info!("stopping language server {name}");
10438            self.languages
10439                .update_lsp_binary_status(name.clone(), BinaryStatus::Stopping);
10440            cx.notify();
10441
10442            return cx.spawn(async move |lsp_store, cx| {
10443                Self::shutdown_language_server(server_state, name.clone(), cx).await;
10444                lsp_store
10445                    .update(cx, |lsp_store, cx| {
10446                        lsp_store
10447                            .languages
10448                            .update_lsp_binary_status(name, BinaryStatus::Stopped);
10449                        cx.emit(LspStoreEvent::LanguageServerRemoved(server_id));
10450                        cx.notify();
10451                    })
10452                    .ok();
10453            });
10454        }
10455
10456        if server_state.is_some() {
10457            cx.emit(LspStoreEvent::LanguageServerRemoved(server_id));
10458        }
10459        Task::ready(())
10460    }
10461
10462    pub fn stop_all_language_servers(&mut self, cx: &mut Context<Self>) {
10463        if let Some((client, project_id)) = self.upstream_client() {
10464            let request = client.request(proto::StopLanguageServers {
10465                project_id,
10466                buffer_ids: Vec::new(),
10467                also_servers: Vec::new(),
10468                all: true,
10469            });
10470            cx.background_spawn(request).detach_and_log_err(cx);
10471        } else {
10472            let Some(local) = self.as_local_mut() else {
10473                return;
10474            };
10475            let language_servers_to_stop = local
10476                .language_server_ids
10477                .values()
10478                .map(|state| state.id)
10479                .collect();
10480            local.lsp_tree.remove_nodes(&language_servers_to_stop);
10481            let tasks = language_servers_to_stop
10482                .into_iter()
10483                .map(|server| self.stop_local_language_server(server, cx))
10484                .collect::<Vec<_>>();
10485            cx.background_spawn(async move {
10486                futures::future::join_all(tasks).await;
10487            })
10488            .detach();
10489        }
10490    }
10491
10492    pub fn restart_language_servers_for_buffers(
10493        &mut self,
10494        buffers: Vec<Entity<Buffer>>,
10495        only_restart_servers: HashSet<LanguageServerSelector>,
10496        cx: &mut Context<Self>,
10497    ) {
10498        if let Some((client, project_id)) = self.upstream_client() {
10499            let request = client.request(proto::RestartLanguageServers {
10500                project_id,
10501                buffer_ids: buffers
10502                    .into_iter()
10503                    .map(|b| b.read(cx).remote_id().to_proto())
10504                    .collect(),
10505                only_servers: only_restart_servers
10506                    .into_iter()
10507                    .map(|selector| {
10508                        let selector = match selector {
10509                            LanguageServerSelector::Id(language_server_id) => {
10510                                proto::language_server_selector::Selector::ServerId(
10511                                    language_server_id.to_proto(),
10512                                )
10513                            }
10514                            LanguageServerSelector::Name(language_server_name) => {
10515                                proto::language_server_selector::Selector::Name(
10516                                    language_server_name.to_string(),
10517                                )
10518                            }
10519                        };
10520                        proto::LanguageServerSelector {
10521                            selector: Some(selector),
10522                        }
10523                    })
10524                    .collect(),
10525                all: false,
10526            });
10527            cx.background_spawn(request).detach_and_log_err(cx);
10528        } else {
10529            let stop_task = if only_restart_servers.is_empty() {
10530                self.stop_local_language_servers_for_buffers(&buffers, HashSet::default(), cx)
10531            } else {
10532                self.stop_local_language_servers_for_buffers(&[], only_restart_servers.clone(), cx)
10533            };
10534            cx.spawn(async move |lsp_store, cx| {
10535                stop_task.await;
10536                lsp_store
10537                    .update(cx, |lsp_store, cx| {
10538                        for buffer in buffers {
10539                            lsp_store.register_buffer_with_language_servers(
10540                                &buffer,
10541                                only_restart_servers.clone(),
10542                                true,
10543                                cx,
10544                            );
10545                        }
10546                    })
10547                    .ok()
10548            })
10549            .detach();
10550        }
10551    }
10552
10553    pub fn stop_language_servers_for_buffers(
10554        &mut self,
10555        buffers: Vec<Entity<Buffer>>,
10556        also_stop_servers: HashSet<LanguageServerSelector>,
10557        cx: &mut Context<Self>,
10558    ) -> Task<Result<()>> {
10559        if let Some((client, project_id)) = self.upstream_client() {
10560            let request = client.request(proto::StopLanguageServers {
10561                project_id,
10562                buffer_ids: buffers
10563                    .into_iter()
10564                    .map(|b| b.read(cx).remote_id().to_proto())
10565                    .collect(),
10566                also_servers: also_stop_servers
10567                    .into_iter()
10568                    .map(|selector| {
10569                        let selector = match selector {
10570                            LanguageServerSelector::Id(language_server_id) => {
10571                                proto::language_server_selector::Selector::ServerId(
10572                                    language_server_id.to_proto(),
10573                                )
10574                            }
10575                            LanguageServerSelector::Name(language_server_name) => {
10576                                proto::language_server_selector::Selector::Name(
10577                                    language_server_name.to_string(),
10578                                )
10579                            }
10580                        };
10581                        proto::LanguageServerSelector {
10582                            selector: Some(selector),
10583                        }
10584                    })
10585                    .collect(),
10586                all: false,
10587            });
10588            cx.background_spawn(async move {
10589                let _ = request.await?;
10590                Ok(())
10591            })
10592        } else {
10593            let task =
10594                self.stop_local_language_servers_for_buffers(&buffers, also_stop_servers, cx);
10595            cx.background_spawn(async move {
10596                task.await;
10597                Ok(())
10598            })
10599        }
10600    }
10601
10602    fn stop_local_language_servers_for_buffers(
10603        &mut self,
10604        buffers: &[Entity<Buffer>],
10605        also_stop_servers: HashSet<LanguageServerSelector>,
10606        cx: &mut Context<Self>,
10607    ) -> Task<()> {
10608        let Some(local) = self.as_local_mut() else {
10609            return Task::ready(());
10610        };
10611        let mut language_server_names_to_stop = BTreeSet::default();
10612        let mut language_servers_to_stop = also_stop_servers
10613            .into_iter()
10614            .flat_map(|selector| match selector {
10615                LanguageServerSelector::Id(id) => Some(id),
10616                LanguageServerSelector::Name(name) => {
10617                    language_server_names_to_stop.insert(name);
10618                    None
10619                }
10620            })
10621            .collect::<BTreeSet<_>>();
10622
10623        let mut covered_worktrees = HashSet::default();
10624        for buffer in buffers {
10625            buffer.update(cx, |buffer, cx| {
10626                language_servers_to_stop.extend(local.language_server_ids_for_buffer(buffer, cx));
10627                if let Some(worktree_id) = buffer.file().map(|f| f.worktree_id(cx))
10628                    && covered_worktrees.insert(worktree_id)
10629                {
10630                    language_server_names_to_stop.retain(|name| {
10631                        let old_ids_count = language_servers_to_stop.len();
10632                        let all_language_servers_with_this_name = local
10633                            .language_server_ids
10634                            .iter()
10635                            .filter_map(|(seed, state)| seed.name.eq(name).then(|| state.id));
10636                        language_servers_to_stop.extend(all_language_servers_with_this_name);
10637                        old_ids_count == language_servers_to_stop.len()
10638                    });
10639                }
10640            });
10641        }
10642        for name in language_server_names_to_stop {
10643            language_servers_to_stop.extend(
10644                local
10645                    .language_server_ids
10646                    .iter()
10647                    .filter_map(|(seed, v)| seed.name.eq(&name).then(|| v.id)),
10648            );
10649        }
10650
10651        local.lsp_tree.remove_nodes(&language_servers_to_stop);
10652        let tasks = language_servers_to_stop
10653            .into_iter()
10654            .map(|server| self.stop_local_language_server(server, cx))
10655            .collect::<Vec<_>>();
10656
10657        cx.background_spawn(futures::future::join_all(tasks).map(|_| ()))
10658    }
10659
10660    fn get_buffer<'a>(&self, abs_path: &Path, cx: &'a App) -> Option<&'a Buffer> {
10661        let (worktree, relative_path) =
10662            self.worktree_store.read(cx).find_worktree(&abs_path, cx)?;
10663
10664        let project_path = ProjectPath {
10665            worktree_id: worktree.read(cx).id(),
10666            path: relative_path.into(),
10667        };
10668
10669        Some(
10670            self.buffer_store()
10671                .read(cx)
10672                .get_by_path(&project_path)?
10673                .read(cx),
10674        )
10675    }
10676
10677    #[cfg(any(test, feature = "test-support"))]
10678    pub fn update_diagnostics(
10679        &mut self,
10680        server_id: LanguageServerId,
10681        diagnostics: lsp::PublishDiagnosticsParams,
10682        result_id: Option<String>,
10683        source_kind: DiagnosticSourceKind,
10684        disk_based_sources: &[String],
10685        cx: &mut Context<Self>,
10686    ) -> Result<()> {
10687        self.merge_lsp_diagnostics(
10688            source_kind,
10689            vec![DocumentDiagnosticsUpdate {
10690                diagnostics,
10691                result_id,
10692                server_id,
10693                disk_based_sources: Cow::Borrowed(disk_based_sources),
10694            }],
10695            |_, _, _| false,
10696            cx,
10697        )
10698    }
10699
10700    pub fn merge_lsp_diagnostics(
10701        &mut self,
10702        source_kind: DiagnosticSourceKind,
10703        lsp_diagnostics: Vec<DocumentDiagnosticsUpdate<lsp::PublishDiagnosticsParams>>,
10704        merge: impl Fn(&Buffer, &Diagnostic, &App) -> bool + Clone,
10705        cx: &mut Context<Self>,
10706    ) -> Result<()> {
10707        anyhow::ensure!(self.mode.is_local(), "called update_diagnostics on remote");
10708        let updates = lsp_diagnostics
10709            .into_iter()
10710            .filter_map(|update| {
10711                let abs_path = update.diagnostics.uri.to_file_path().ok()?;
10712                Some(DocumentDiagnosticsUpdate {
10713                    diagnostics: self.lsp_to_document_diagnostics(
10714                        abs_path,
10715                        source_kind,
10716                        update.server_id,
10717                        update.diagnostics,
10718                        &update.disk_based_sources,
10719                    ),
10720                    result_id: update.result_id,
10721                    server_id: update.server_id,
10722                    disk_based_sources: update.disk_based_sources,
10723                })
10724            })
10725            .collect();
10726        self.merge_diagnostic_entries(updates, merge, cx)?;
10727        Ok(())
10728    }
10729
10730    fn lsp_to_document_diagnostics(
10731        &mut self,
10732        document_abs_path: PathBuf,
10733        source_kind: DiagnosticSourceKind,
10734        server_id: LanguageServerId,
10735        mut lsp_diagnostics: lsp::PublishDiagnosticsParams,
10736        disk_based_sources: &[String],
10737    ) -> DocumentDiagnostics {
10738        let mut diagnostics = Vec::default();
10739        let mut primary_diagnostic_group_ids = HashMap::default();
10740        let mut sources_by_group_id = HashMap::default();
10741        let mut supporting_diagnostics = HashMap::default();
10742
10743        let adapter = self.language_server_adapter_for_id(server_id);
10744
10745        // Ensure that primary diagnostics are always the most severe
10746        lsp_diagnostics
10747            .diagnostics
10748            .sort_by_key(|item| item.severity);
10749
10750        for diagnostic in &lsp_diagnostics.diagnostics {
10751            let source = diagnostic.source.as_ref();
10752            let range = range_from_lsp(diagnostic.range);
10753            let is_supporting = diagnostic
10754                .related_information
10755                .as_ref()
10756                .is_some_and(|infos| {
10757                    infos.iter().any(|info| {
10758                        primary_diagnostic_group_ids.contains_key(&(
10759                            source,
10760                            diagnostic.code.clone(),
10761                            range_from_lsp(info.location.range),
10762                        ))
10763                    })
10764                });
10765
10766            let is_unnecessary = diagnostic
10767                .tags
10768                .as_ref()
10769                .is_some_and(|tags| tags.contains(&DiagnosticTag::UNNECESSARY));
10770
10771            let underline = self
10772                .language_server_adapter_for_id(server_id)
10773                .is_none_or(|adapter| adapter.underline_diagnostic(diagnostic));
10774
10775            if is_supporting {
10776                supporting_diagnostics.insert(
10777                    (source, diagnostic.code.clone(), range),
10778                    (diagnostic.severity, is_unnecessary),
10779                );
10780            } else {
10781                let group_id = post_inc(&mut self.as_local_mut().unwrap().next_diagnostic_group_id);
10782                let is_disk_based =
10783                    source.is_some_and(|source| disk_based_sources.contains(source));
10784
10785                sources_by_group_id.insert(group_id, source);
10786                primary_diagnostic_group_ids
10787                    .insert((source, diagnostic.code.clone(), range.clone()), group_id);
10788
10789                diagnostics.push(DiagnosticEntry {
10790                    range,
10791                    diagnostic: Diagnostic {
10792                        source: diagnostic.source.clone(),
10793                        source_kind,
10794                        code: diagnostic.code.clone(),
10795                        code_description: diagnostic
10796                            .code_description
10797                            .as_ref()
10798                            .and_then(|d| d.href.clone()),
10799                        severity: diagnostic.severity.unwrap_or(DiagnosticSeverity::ERROR),
10800                        markdown: adapter.as_ref().and_then(|adapter| {
10801                            adapter.diagnostic_message_to_markdown(&diagnostic.message)
10802                        }),
10803                        message: diagnostic.message.trim().to_string(),
10804                        group_id,
10805                        is_primary: true,
10806                        is_disk_based,
10807                        is_unnecessary,
10808                        underline,
10809                        data: diagnostic.data.clone(),
10810                    },
10811                });
10812                if let Some(infos) = &diagnostic.related_information {
10813                    for info in infos {
10814                        if info.location.uri == lsp_diagnostics.uri && !info.message.is_empty() {
10815                            let range = range_from_lsp(info.location.range);
10816                            diagnostics.push(DiagnosticEntry {
10817                                range,
10818                                diagnostic: Diagnostic {
10819                                    source: diagnostic.source.clone(),
10820                                    source_kind,
10821                                    code: diagnostic.code.clone(),
10822                                    code_description: diagnostic
10823                                        .code_description
10824                                        .as_ref()
10825                                        .and_then(|d| d.href.clone()),
10826                                    severity: DiagnosticSeverity::INFORMATION,
10827                                    markdown: adapter.as_ref().and_then(|adapter| {
10828                                        adapter.diagnostic_message_to_markdown(&info.message)
10829                                    }),
10830                                    message: info.message.trim().to_string(),
10831                                    group_id,
10832                                    is_primary: false,
10833                                    is_disk_based,
10834                                    is_unnecessary: false,
10835                                    underline,
10836                                    data: diagnostic.data.clone(),
10837                                },
10838                            });
10839                        }
10840                    }
10841                }
10842            }
10843        }
10844
10845        for entry in &mut diagnostics {
10846            let diagnostic = &mut entry.diagnostic;
10847            if !diagnostic.is_primary {
10848                let source = *sources_by_group_id.get(&diagnostic.group_id).unwrap();
10849                if let Some(&(severity, is_unnecessary)) = supporting_diagnostics.get(&(
10850                    source,
10851                    diagnostic.code.clone(),
10852                    entry.range.clone(),
10853                )) {
10854                    if let Some(severity) = severity {
10855                        diagnostic.severity = severity;
10856                    }
10857                    diagnostic.is_unnecessary = is_unnecessary;
10858                }
10859            }
10860        }
10861
10862        DocumentDiagnostics {
10863            diagnostics,
10864            document_abs_path,
10865            version: lsp_diagnostics.version,
10866        }
10867    }
10868
10869    fn insert_newly_running_language_server(
10870        &mut self,
10871        adapter: Arc<CachedLspAdapter>,
10872        language_server: Arc<LanguageServer>,
10873        server_id: LanguageServerId,
10874        key: LanguageServerSeed,
10875        workspace_folders: Arc<Mutex<BTreeSet<Url>>>,
10876        cx: &mut Context<Self>,
10877    ) {
10878        let Some(local) = self.as_local_mut() else {
10879            return;
10880        };
10881        // If the language server for this key doesn't match the server id, don't store the
10882        // server. Which will cause it to be dropped, killing the process
10883        if local
10884            .language_server_ids
10885            .get(&key)
10886            .map(|state| state.id != server_id)
10887            .unwrap_or(false)
10888        {
10889            return;
10890        }
10891
10892        // Update language_servers collection with Running variant of LanguageServerState
10893        // indicating that the server is up and running and ready
10894        let workspace_folders = workspace_folders.lock().clone();
10895        language_server.set_workspace_folders(workspace_folders);
10896
10897        local.language_servers.insert(
10898            server_id,
10899            LanguageServerState::Running {
10900                workspace_refresh_task: lsp_workspace_diagnostics_refresh(
10901                    language_server.clone(),
10902                    cx,
10903                ),
10904                adapter: adapter.clone(),
10905                server: language_server.clone(),
10906                simulate_disk_based_diagnostics_completion: None,
10907            },
10908        );
10909        local
10910            .languages
10911            .update_lsp_binary_status(adapter.name(), BinaryStatus::None);
10912        if let Some(file_ops_caps) = language_server
10913            .capabilities()
10914            .workspace
10915            .as_ref()
10916            .and_then(|ws| ws.file_operations.as_ref())
10917        {
10918            let did_rename_caps = file_ops_caps.did_rename.as_ref();
10919            let will_rename_caps = file_ops_caps.will_rename.as_ref();
10920            if did_rename_caps.or(will_rename_caps).is_some() {
10921                let watcher = RenamePathsWatchedForServer::default()
10922                    .with_did_rename_patterns(did_rename_caps)
10923                    .with_will_rename_patterns(will_rename_caps);
10924                local
10925                    .language_server_paths_watched_for_rename
10926                    .insert(server_id, watcher);
10927            }
10928        }
10929
10930        self.language_server_statuses.insert(
10931            server_id,
10932            LanguageServerStatus {
10933                name: language_server.name(),
10934                pending_work: Default::default(),
10935                has_pending_diagnostic_updates: false,
10936                progress_tokens: Default::default(),
10937            },
10938        );
10939
10940        cx.emit(LspStoreEvent::LanguageServerAdded(
10941            server_id,
10942            language_server.name(),
10943            Some(key.worktree_id),
10944        ));
10945        cx.emit(LspStoreEvent::RefreshInlayHints);
10946
10947        let server_capabilities = language_server.capabilities();
10948        if let Some((downstream_client, project_id)) = self.downstream_client.as_ref() {
10949            downstream_client
10950                .send(proto::StartLanguageServer {
10951                    project_id: *project_id,
10952                    server: Some(proto::LanguageServer {
10953                        id: server_id.to_proto(),
10954                        name: language_server.name().to_string(),
10955                        worktree_id: Some(key.worktree_id.to_proto()),
10956                    }),
10957                    capabilities: serde_json::to_string(&server_capabilities)
10958                        .expect("serializing server LSP capabilities"),
10959                })
10960                .log_err();
10961        }
10962        self.lsp_server_capabilities
10963            .insert(server_id, server_capabilities);
10964
10965        // Tell the language server about every open buffer in the worktree that matches the language.
10966        // Also check for buffers in worktrees that reused this server
10967        let mut worktrees_using_server = vec![key.worktree_id];
10968        if let Some(local) = self.as_local() {
10969            // Find all worktrees that have this server in their language server tree
10970            for (worktree_id, servers) in &local.lsp_tree.instances {
10971                if *worktree_id != key.worktree_id {
10972                    for server_map in servers.roots.values() {
10973                        if server_map.contains_key(&key.name) {
10974                            worktrees_using_server.push(*worktree_id);
10975                        }
10976                    }
10977                }
10978            }
10979        }
10980
10981        let mut buffer_paths_registered = Vec::new();
10982        self.buffer_store.clone().update(cx, |buffer_store, cx| {
10983            for buffer_handle in buffer_store.buffers() {
10984                let buffer = buffer_handle.read(cx);
10985                let file = match File::from_dyn(buffer.file()) {
10986                    Some(file) => file,
10987                    None => continue,
10988                };
10989                let language = match buffer.language() {
10990                    Some(language) => language,
10991                    None => continue,
10992                };
10993
10994                if !worktrees_using_server.contains(&file.worktree.read(cx).id())
10995                    || !self
10996                        .languages
10997                        .lsp_adapters(&language.name())
10998                        .iter()
10999                        .any(|a| a.name == key.name)
11000                {
11001                    continue;
11002                }
11003                // didOpen
11004                let file = match file.as_local() {
11005                    Some(file) => file,
11006                    None => continue,
11007                };
11008
11009                let local = self.as_local_mut().unwrap();
11010
11011                let buffer_id = buffer.remote_id();
11012                if local.registered_buffers.contains_key(&buffer_id) {
11013                    let versions = local
11014                        .buffer_snapshots
11015                        .entry(buffer_id)
11016                        .or_default()
11017                        .entry(server_id)
11018                        .and_modify(|_| {
11019                            assert!(
11020                            false,
11021                            "There should not be an existing snapshot for a newly inserted buffer"
11022                        )
11023                        })
11024                        .or_insert_with(|| {
11025                            vec![LspBufferSnapshot {
11026                                version: 0,
11027                                snapshot: buffer.text_snapshot(),
11028                            }]
11029                        });
11030
11031                    let snapshot = versions.last().unwrap();
11032                    let version = snapshot.version;
11033                    let initial_snapshot = &snapshot.snapshot;
11034                    let uri = lsp::Url::from_file_path(file.abs_path(cx)).unwrap();
11035                    language_server.register_buffer(
11036                        uri,
11037                        adapter.language_id(&language.name()),
11038                        version,
11039                        initial_snapshot.text(),
11040                    );
11041                    buffer_paths_registered.push((buffer_id, file.abs_path(cx)));
11042                    local
11043                        .buffers_opened_in_servers
11044                        .entry(buffer_id)
11045                        .or_default()
11046                        .insert(server_id);
11047                }
11048                buffer_handle.update(cx, |buffer, cx| {
11049                    buffer.set_completion_triggers(
11050                        server_id,
11051                        language_server
11052                            .capabilities()
11053                            .completion_provider
11054                            .as_ref()
11055                            .and_then(|provider| {
11056                                provider
11057                                    .trigger_characters
11058                                    .as_ref()
11059                                    .map(|characters| characters.iter().cloned().collect())
11060                            })
11061                            .unwrap_or_default(),
11062                        cx,
11063                    )
11064                });
11065            }
11066        });
11067
11068        for (buffer_id, abs_path) in buffer_paths_registered {
11069            cx.emit(LspStoreEvent::LanguageServerUpdate {
11070                language_server_id: server_id,
11071                name: Some(adapter.name()),
11072                message: proto::update_language_server::Variant::RegisteredForBuffer(
11073                    proto::RegisteredForBuffer {
11074                        buffer_abs_path: abs_path.to_string_lossy().to_string(),
11075                        buffer_id: buffer_id.to_proto(),
11076                    },
11077                ),
11078            });
11079        }
11080
11081        cx.notify();
11082    }
11083
11084    pub fn language_servers_running_disk_based_diagnostics(
11085        &self,
11086    ) -> impl Iterator<Item = LanguageServerId> + '_ {
11087        self.language_server_statuses
11088            .iter()
11089            .filter_map(|(id, status)| {
11090                if status.has_pending_diagnostic_updates {
11091                    Some(*id)
11092                } else {
11093                    None
11094                }
11095            })
11096    }
11097
11098    pub(crate) fn cancel_language_server_work_for_buffers(
11099        &mut self,
11100        buffers: impl IntoIterator<Item = Entity<Buffer>>,
11101        cx: &mut Context<Self>,
11102    ) {
11103        if let Some((client, project_id)) = self.upstream_client() {
11104            let request = client.request(proto::CancelLanguageServerWork {
11105                project_id,
11106                work: Some(proto::cancel_language_server_work::Work::Buffers(
11107                    proto::cancel_language_server_work::Buffers {
11108                        buffer_ids: buffers
11109                            .into_iter()
11110                            .map(|b| b.read(cx).remote_id().to_proto())
11111                            .collect(),
11112                    },
11113                )),
11114            });
11115            cx.background_spawn(request).detach_and_log_err(cx);
11116        } else if let Some(local) = self.as_local() {
11117            let servers = buffers
11118                .into_iter()
11119                .flat_map(|buffer| {
11120                    buffer.update(cx, |buffer, cx| {
11121                        local.language_server_ids_for_buffer(buffer, cx).into_iter()
11122                    })
11123                })
11124                .collect::<HashSet<_>>();
11125            for server_id in servers {
11126                self.cancel_language_server_work(server_id, None, cx);
11127            }
11128        }
11129    }
11130
11131    pub(crate) fn cancel_language_server_work(
11132        &mut self,
11133        server_id: LanguageServerId,
11134        token_to_cancel: Option<String>,
11135        cx: &mut Context<Self>,
11136    ) {
11137        if let Some(local) = self.as_local() {
11138            let status = self.language_server_statuses.get(&server_id);
11139            let server = local.language_servers.get(&server_id);
11140            if let Some((LanguageServerState::Running { server, .. }, status)) = server.zip(status)
11141            {
11142                for (token, progress) in &status.pending_work {
11143                    if let Some(token_to_cancel) = token_to_cancel.as_ref()
11144                        && token != token_to_cancel
11145                    {
11146                        continue;
11147                    }
11148                    if progress.is_cancellable {
11149                        server
11150                            .notify::<lsp::notification::WorkDoneProgressCancel>(
11151                                &WorkDoneProgressCancelParams {
11152                                    token: lsp::NumberOrString::String(token.clone()),
11153                                },
11154                            )
11155                            .ok();
11156                    }
11157                }
11158            }
11159        } else if let Some((client, project_id)) = self.upstream_client() {
11160            let request = client.request(proto::CancelLanguageServerWork {
11161                project_id,
11162                work: Some(
11163                    proto::cancel_language_server_work::Work::LanguageServerWork(
11164                        proto::cancel_language_server_work::LanguageServerWork {
11165                            language_server_id: server_id.to_proto(),
11166                            token: token_to_cancel,
11167                        },
11168                    ),
11169                ),
11170            });
11171            cx.background_spawn(request).detach_and_log_err(cx);
11172        }
11173    }
11174
11175    fn register_supplementary_language_server(
11176        &mut self,
11177        id: LanguageServerId,
11178        name: LanguageServerName,
11179        server: Arc<LanguageServer>,
11180        cx: &mut Context<Self>,
11181    ) {
11182        if let Some(local) = self.as_local_mut() {
11183            local
11184                .supplementary_language_servers
11185                .insert(id, (name.clone(), server));
11186            cx.emit(LspStoreEvent::LanguageServerAdded(id, name, None));
11187        }
11188    }
11189
11190    fn unregister_supplementary_language_server(
11191        &mut self,
11192        id: LanguageServerId,
11193        cx: &mut Context<Self>,
11194    ) {
11195        if let Some(local) = self.as_local_mut() {
11196            local.supplementary_language_servers.remove(&id);
11197            cx.emit(LspStoreEvent::LanguageServerRemoved(id));
11198        }
11199    }
11200
11201    pub(crate) fn supplementary_language_servers(
11202        &self,
11203    ) -> impl '_ + Iterator<Item = (LanguageServerId, LanguageServerName)> {
11204        self.as_local().into_iter().flat_map(|local| {
11205            local
11206                .supplementary_language_servers
11207                .iter()
11208                .map(|(id, (name, _))| (*id, name.clone()))
11209        })
11210    }
11211
11212    pub fn language_server_adapter_for_id(
11213        &self,
11214        id: LanguageServerId,
11215    ) -> Option<Arc<CachedLspAdapter>> {
11216        self.as_local()
11217            .and_then(|local| local.language_servers.get(&id))
11218            .and_then(|language_server_state| match language_server_state {
11219                LanguageServerState::Running { adapter, .. } => Some(adapter.clone()),
11220                _ => None,
11221            })
11222    }
11223
11224    pub(super) fn update_local_worktree_language_servers(
11225        &mut self,
11226        worktree_handle: &Entity<Worktree>,
11227        changes: &[(Arc<Path>, ProjectEntryId, PathChange)],
11228        cx: &mut Context<Self>,
11229    ) {
11230        if changes.is_empty() {
11231            return;
11232        }
11233
11234        let Some(local) = self.as_local() else { return };
11235
11236        local.prettier_store.update(cx, |prettier_store, cx| {
11237            prettier_store.update_prettier_settings(worktree_handle, changes, cx)
11238        });
11239
11240        let worktree_id = worktree_handle.read(cx).id();
11241        let mut language_server_ids = local
11242            .language_server_ids
11243            .iter()
11244            .filter_map(|(seed, v)| seed.worktree_id.eq(&worktree_id).then(|| v.id))
11245            .collect::<Vec<_>>();
11246        language_server_ids.sort();
11247        language_server_ids.dedup();
11248
11249        let abs_path = worktree_handle.read(cx).abs_path();
11250        for server_id in &language_server_ids {
11251            if let Some(LanguageServerState::Running { server, .. }) =
11252                local.language_servers.get(server_id)
11253                && let Some(watched_paths) = local
11254                    .language_server_watched_paths
11255                    .get(server_id)
11256                    .and_then(|paths| paths.worktree_paths.get(&worktree_id))
11257            {
11258                let params = lsp::DidChangeWatchedFilesParams {
11259                    changes: changes
11260                        .iter()
11261                        .filter_map(|(path, _, change)| {
11262                            if !watched_paths.is_match(path) {
11263                                return None;
11264                            }
11265                            let typ = match change {
11266                                PathChange::Loaded => return None,
11267                                PathChange::Added => lsp::FileChangeType::CREATED,
11268                                PathChange::Removed => lsp::FileChangeType::DELETED,
11269                                PathChange::Updated => lsp::FileChangeType::CHANGED,
11270                                PathChange::AddedOrUpdated => lsp::FileChangeType::CHANGED,
11271                            };
11272                            Some(lsp::FileEvent {
11273                                uri: lsp::Url::from_file_path(abs_path.join(path)).unwrap(),
11274                                typ,
11275                            })
11276                        })
11277                        .collect(),
11278                };
11279                if !params.changes.is_empty() {
11280                    server
11281                        .notify::<lsp::notification::DidChangeWatchedFiles>(&params)
11282                        .ok();
11283                }
11284            }
11285        }
11286        for (path, _, _) in changes {
11287            if let Some(file_name) = path.file_name().and_then(|file_name| file_name.to_str())
11288                && local.watched_manifest_filenames.contains(file_name)
11289            {
11290                self.request_workspace_config_refresh();
11291                break;
11292            }
11293        }
11294    }
11295
11296    pub fn wait_for_remote_buffer(
11297        &mut self,
11298        id: BufferId,
11299        cx: &mut Context<Self>,
11300    ) -> Task<Result<Entity<Buffer>>> {
11301        self.buffer_store.update(cx, |buffer_store, cx| {
11302            buffer_store.wait_for_remote_buffer(id, cx)
11303        })
11304    }
11305
11306    fn serialize_symbol(symbol: &Symbol) -> proto::Symbol {
11307        proto::Symbol {
11308            language_server_name: symbol.language_server_name.0.to_string(),
11309            source_worktree_id: symbol.source_worktree_id.to_proto(),
11310            language_server_id: symbol.source_language_server_id.to_proto(),
11311            worktree_id: symbol.path.worktree_id.to_proto(),
11312            path: symbol.path.path.as_ref().to_proto(),
11313            name: symbol.name.clone(),
11314            kind: unsafe { mem::transmute::<lsp::SymbolKind, i32>(symbol.kind) },
11315            start: Some(proto::PointUtf16 {
11316                row: symbol.range.start.0.row,
11317                column: symbol.range.start.0.column,
11318            }),
11319            end: Some(proto::PointUtf16 {
11320                row: symbol.range.end.0.row,
11321                column: symbol.range.end.0.column,
11322            }),
11323            signature: symbol.signature.to_vec(),
11324        }
11325    }
11326
11327    fn deserialize_symbol(serialized_symbol: proto::Symbol) -> Result<CoreSymbol> {
11328        let source_worktree_id = WorktreeId::from_proto(serialized_symbol.source_worktree_id);
11329        let worktree_id = WorktreeId::from_proto(serialized_symbol.worktree_id);
11330        let kind = unsafe { mem::transmute::<i32, lsp::SymbolKind>(serialized_symbol.kind) };
11331        let path = ProjectPath {
11332            worktree_id,
11333            path: Arc::<Path>::from_proto(serialized_symbol.path),
11334        };
11335
11336        let start = serialized_symbol.start.context("invalid start")?;
11337        let end = serialized_symbol.end.context("invalid end")?;
11338        Ok(CoreSymbol {
11339            language_server_name: LanguageServerName(serialized_symbol.language_server_name.into()),
11340            source_worktree_id,
11341            source_language_server_id: LanguageServerId::from_proto(
11342                serialized_symbol.language_server_id,
11343            ),
11344            path,
11345            name: serialized_symbol.name,
11346            range: Unclipped(PointUtf16::new(start.row, start.column))
11347                ..Unclipped(PointUtf16::new(end.row, end.column)),
11348            kind,
11349            signature: serialized_symbol
11350                .signature
11351                .try_into()
11352                .map_err(|_| anyhow!("invalid signature"))?,
11353        })
11354    }
11355
11356    pub(crate) fn serialize_completion(completion: &CoreCompletion) -> proto::Completion {
11357        let mut serialized_completion = proto::Completion {
11358            old_replace_start: Some(serialize_anchor(&completion.replace_range.start)),
11359            old_replace_end: Some(serialize_anchor(&completion.replace_range.end)),
11360            new_text: completion.new_text.clone(),
11361            ..proto::Completion::default()
11362        };
11363        match &completion.source {
11364            CompletionSource::Lsp {
11365                insert_range,
11366                server_id,
11367                lsp_completion,
11368                lsp_defaults,
11369                resolved,
11370            } => {
11371                let (old_insert_start, old_insert_end) = insert_range
11372                    .as_ref()
11373                    .map(|range| (serialize_anchor(&range.start), serialize_anchor(&range.end)))
11374                    .unzip();
11375
11376                serialized_completion.old_insert_start = old_insert_start;
11377                serialized_completion.old_insert_end = old_insert_end;
11378                serialized_completion.source = proto::completion::Source::Lsp as i32;
11379                serialized_completion.server_id = server_id.0 as u64;
11380                serialized_completion.lsp_completion = serde_json::to_vec(lsp_completion).unwrap();
11381                serialized_completion.lsp_defaults = lsp_defaults
11382                    .as_deref()
11383                    .map(|lsp_defaults| serde_json::to_vec(lsp_defaults).unwrap());
11384                serialized_completion.resolved = *resolved;
11385            }
11386            CompletionSource::BufferWord {
11387                word_range,
11388                resolved,
11389            } => {
11390                serialized_completion.source = proto::completion::Source::BufferWord as i32;
11391                serialized_completion.buffer_word_start = Some(serialize_anchor(&word_range.start));
11392                serialized_completion.buffer_word_end = Some(serialize_anchor(&word_range.end));
11393                serialized_completion.resolved = *resolved;
11394            }
11395            CompletionSource::Custom => {
11396                serialized_completion.source = proto::completion::Source::Custom as i32;
11397                serialized_completion.resolved = true;
11398            }
11399            CompletionSource::Dap { sort_text } => {
11400                serialized_completion.source = proto::completion::Source::Dap as i32;
11401                serialized_completion.sort_text = Some(sort_text.clone());
11402            }
11403        }
11404
11405        serialized_completion
11406    }
11407
11408    pub(crate) fn deserialize_completion(completion: proto::Completion) -> Result<CoreCompletion> {
11409        let old_replace_start = completion
11410            .old_replace_start
11411            .and_then(deserialize_anchor)
11412            .context("invalid old start")?;
11413        let old_replace_end = completion
11414            .old_replace_end
11415            .and_then(deserialize_anchor)
11416            .context("invalid old end")?;
11417        let insert_range = {
11418            match completion.old_insert_start.zip(completion.old_insert_end) {
11419                Some((start, end)) => {
11420                    let start = deserialize_anchor(start).context("invalid insert old start")?;
11421                    let end = deserialize_anchor(end).context("invalid insert old end")?;
11422                    Some(start..end)
11423                }
11424                None => None,
11425            }
11426        };
11427        Ok(CoreCompletion {
11428            replace_range: old_replace_start..old_replace_end,
11429            new_text: completion.new_text,
11430            source: match proto::completion::Source::from_i32(completion.source) {
11431                Some(proto::completion::Source::Custom) => CompletionSource::Custom,
11432                Some(proto::completion::Source::Lsp) => CompletionSource::Lsp {
11433                    insert_range,
11434                    server_id: LanguageServerId::from_proto(completion.server_id),
11435                    lsp_completion: serde_json::from_slice(&completion.lsp_completion)?,
11436                    lsp_defaults: completion
11437                        .lsp_defaults
11438                        .as_deref()
11439                        .map(serde_json::from_slice)
11440                        .transpose()?,
11441                    resolved: completion.resolved,
11442                },
11443                Some(proto::completion::Source::BufferWord) => {
11444                    let word_range = completion
11445                        .buffer_word_start
11446                        .and_then(deserialize_anchor)
11447                        .context("invalid buffer word start")?
11448                        ..completion
11449                            .buffer_word_end
11450                            .and_then(deserialize_anchor)
11451                            .context("invalid buffer word end")?;
11452                    CompletionSource::BufferWord {
11453                        word_range,
11454                        resolved: completion.resolved,
11455                    }
11456                }
11457                Some(proto::completion::Source::Dap) => CompletionSource::Dap {
11458                    sort_text: completion
11459                        .sort_text
11460                        .context("expected sort text to exist")?,
11461                },
11462                _ => anyhow::bail!("Unexpected completion source {}", completion.source),
11463            },
11464        })
11465    }
11466
11467    pub(crate) fn serialize_code_action(action: &CodeAction) -> proto::CodeAction {
11468        let (kind, lsp_action) = match &action.lsp_action {
11469            LspAction::Action(code_action) => (
11470                proto::code_action::Kind::Action as i32,
11471                serde_json::to_vec(code_action).unwrap(),
11472            ),
11473            LspAction::Command(command) => (
11474                proto::code_action::Kind::Command as i32,
11475                serde_json::to_vec(command).unwrap(),
11476            ),
11477            LspAction::CodeLens(code_lens) => (
11478                proto::code_action::Kind::CodeLens as i32,
11479                serde_json::to_vec(code_lens).unwrap(),
11480            ),
11481        };
11482
11483        proto::CodeAction {
11484            server_id: action.server_id.0 as u64,
11485            start: Some(serialize_anchor(&action.range.start)),
11486            end: Some(serialize_anchor(&action.range.end)),
11487            lsp_action,
11488            kind,
11489            resolved: action.resolved,
11490        }
11491    }
11492
11493    pub(crate) fn deserialize_code_action(action: proto::CodeAction) -> Result<CodeAction> {
11494        let start = action
11495            .start
11496            .and_then(deserialize_anchor)
11497            .context("invalid start")?;
11498        let end = action
11499            .end
11500            .and_then(deserialize_anchor)
11501            .context("invalid end")?;
11502        let lsp_action = match proto::code_action::Kind::from_i32(action.kind) {
11503            Some(proto::code_action::Kind::Action) => {
11504                LspAction::Action(serde_json::from_slice(&action.lsp_action)?)
11505            }
11506            Some(proto::code_action::Kind::Command) => {
11507                LspAction::Command(serde_json::from_slice(&action.lsp_action)?)
11508            }
11509            Some(proto::code_action::Kind::CodeLens) => {
11510                LspAction::CodeLens(serde_json::from_slice(&action.lsp_action)?)
11511            }
11512            None => anyhow::bail!("Unknown action kind {}", action.kind),
11513        };
11514        Ok(CodeAction {
11515            server_id: LanguageServerId(action.server_id as usize),
11516            range: start..end,
11517            resolved: action.resolved,
11518            lsp_action,
11519        })
11520    }
11521
11522    fn update_last_formatting_failure<T>(&mut self, formatting_result: &anyhow::Result<T>) {
11523        match &formatting_result {
11524            Ok(_) => self.last_formatting_failure = None,
11525            Err(error) => {
11526                let error_string = format!("{error:#}");
11527                log::error!("Formatting failed: {error_string}");
11528                self.last_formatting_failure
11529                    .replace(error_string.lines().join(" "));
11530            }
11531        }
11532    }
11533
11534    fn cleanup_lsp_data(&mut self, for_server: LanguageServerId) {
11535        self.lsp_server_capabilities.remove(&for_server);
11536        for buffer_colors in self.lsp_document_colors.values_mut() {
11537            buffer_colors.colors.remove(&for_server);
11538            buffer_colors.cache_version += 1;
11539        }
11540        for buffer_lens in self.lsp_code_lens.values_mut() {
11541            buffer_lens.lens.remove(&for_server);
11542        }
11543        if let Some(local) = self.as_local_mut() {
11544            local.buffer_pull_diagnostics_result_ids.remove(&for_server);
11545            for buffer_servers in local.buffers_opened_in_servers.values_mut() {
11546                buffer_servers.remove(&for_server);
11547            }
11548        }
11549    }
11550
11551    pub fn result_id(
11552        &self,
11553        server_id: LanguageServerId,
11554        buffer_id: BufferId,
11555        cx: &App,
11556    ) -> Option<String> {
11557        let abs_path = self
11558            .buffer_store
11559            .read(cx)
11560            .get(buffer_id)
11561            .and_then(|b| File::from_dyn(b.read(cx).file()))
11562            .map(|f| f.abs_path(cx))?;
11563        self.as_local()?
11564            .buffer_pull_diagnostics_result_ids
11565            .get(&server_id)?
11566            .get(&abs_path)?
11567            .clone()
11568    }
11569
11570    pub fn all_result_ids(&self, server_id: LanguageServerId) -> HashMap<PathBuf, String> {
11571        let Some(local) = self.as_local() else {
11572            return HashMap::default();
11573        };
11574        local
11575            .buffer_pull_diagnostics_result_ids
11576            .get(&server_id)
11577            .into_iter()
11578            .flatten()
11579            .filter_map(|(abs_path, result_id)| Some((abs_path.clone(), result_id.clone()?)))
11580            .collect()
11581    }
11582
11583    pub fn pull_workspace_diagnostics(&mut self, server_id: LanguageServerId) {
11584        if let Some(LanguageServerState::Running {
11585            workspace_refresh_task: Some(workspace_refresh_task),
11586            ..
11587        }) = self
11588            .as_local_mut()
11589            .and_then(|local| local.language_servers.get_mut(&server_id))
11590        {
11591            workspace_refresh_task.refresh_tx.try_send(()).ok();
11592        }
11593    }
11594
11595    pub fn pull_workspace_diagnostics_for_buffer(&mut self, buffer_id: BufferId, cx: &mut App) {
11596        let Some(buffer) = self.buffer_store().read(cx).get_existing(buffer_id).ok() else {
11597            return;
11598        };
11599        let Some(local) = self.as_local_mut() else {
11600            return;
11601        };
11602
11603        for server_id in buffer.update(cx, |buffer, cx| {
11604            local.language_server_ids_for_buffer(buffer, cx)
11605        }) {
11606            if let Some(LanguageServerState::Running {
11607                workspace_refresh_task: Some(workspace_refresh_task),
11608                ..
11609            }) = local.language_servers.get_mut(&server_id)
11610            {
11611                workspace_refresh_task.refresh_tx.try_send(()).ok();
11612            }
11613        }
11614    }
11615
11616    fn apply_workspace_diagnostic_report(
11617        &mut self,
11618        server_id: LanguageServerId,
11619        report: lsp::WorkspaceDiagnosticReportResult,
11620        cx: &mut Context<Self>,
11621    ) {
11622        let workspace_diagnostics =
11623            GetDocumentDiagnostics::deserialize_workspace_diagnostics_report(report, server_id);
11624        let mut unchanged_buffers = HashSet::default();
11625        let mut changed_buffers = HashSet::default();
11626        let workspace_diagnostics_updates = workspace_diagnostics
11627            .into_iter()
11628            .filter_map(
11629                |workspace_diagnostics| match workspace_diagnostics.diagnostics {
11630                    LspPullDiagnostics::Response {
11631                        server_id,
11632                        uri,
11633                        diagnostics,
11634                    } => Some((server_id, uri, diagnostics, workspace_diagnostics.version)),
11635                    LspPullDiagnostics::Default => None,
11636                },
11637            )
11638            .fold(
11639                HashMap::default(),
11640                |mut acc, (server_id, uri, diagnostics, version)| {
11641                    let (result_id, diagnostics) = match diagnostics {
11642                        PulledDiagnostics::Unchanged { result_id } => {
11643                            unchanged_buffers.insert(uri.clone());
11644                            (Some(result_id), Vec::new())
11645                        }
11646                        PulledDiagnostics::Changed {
11647                            result_id,
11648                            diagnostics,
11649                        } => {
11650                            changed_buffers.insert(uri.clone());
11651                            (result_id, diagnostics)
11652                        }
11653                    };
11654                    let disk_based_sources = Cow::Owned(
11655                        self.language_server_adapter_for_id(server_id)
11656                            .as_ref()
11657                            .map(|adapter| adapter.disk_based_diagnostic_sources.as_slice())
11658                            .unwrap_or(&[])
11659                            .to_vec(),
11660                    );
11661                    acc.entry(server_id)
11662                        .or_insert_with(Vec::new)
11663                        .push(DocumentDiagnosticsUpdate {
11664                            server_id,
11665                            diagnostics: lsp::PublishDiagnosticsParams {
11666                                uri,
11667                                diagnostics,
11668                                version,
11669                            },
11670                            result_id,
11671                            disk_based_sources,
11672                        });
11673                    acc
11674                },
11675            );
11676
11677        for diagnostic_updates in workspace_diagnostics_updates.into_values() {
11678            self.merge_lsp_diagnostics(
11679                DiagnosticSourceKind::Pulled,
11680                diagnostic_updates,
11681                |buffer, old_diagnostic, cx| {
11682                    File::from_dyn(buffer.file())
11683                        .and_then(|file| {
11684                            let abs_path = file.as_local()?.abs_path(cx);
11685                            lsp::Url::from_file_path(abs_path).ok()
11686                        })
11687                        .is_none_or(|buffer_uri| {
11688                            unchanged_buffers.contains(&buffer_uri)
11689                                || match old_diagnostic.source_kind {
11690                                    DiagnosticSourceKind::Pulled => {
11691                                        !changed_buffers.contains(&buffer_uri)
11692                                    }
11693                                    DiagnosticSourceKind::Other | DiagnosticSourceKind::Pushed => {
11694                                        true
11695                                    }
11696                                }
11697                        })
11698                },
11699                cx,
11700            )
11701            .log_err();
11702        }
11703    }
11704
11705    fn register_server_capabilities(
11706        &mut self,
11707        server_id: LanguageServerId,
11708        params: lsp::RegistrationParams,
11709        cx: &mut Context<Self>,
11710    ) -> anyhow::Result<()> {
11711        let server = self
11712            .language_server_for_id(server_id)
11713            .with_context(|| format!("no server {server_id} found"))?;
11714        for reg in params.registrations {
11715            match reg.method.as_str() {
11716                "workspace/didChangeWatchedFiles" => {
11717                    if let Some(options) = reg.register_options {
11718                        let notify = if let Some(local_lsp_store) = self.as_local_mut() {
11719                            let caps = serde_json::from_value(options)?;
11720                            local_lsp_store
11721                                .on_lsp_did_change_watched_files(server_id, &reg.id, caps, cx);
11722                            true
11723                        } else {
11724                            false
11725                        };
11726                        if notify {
11727                            notify_server_capabilities_updated(&server, cx);
11728                        }
11729                    }
11730                }
11731                "workspace/didChangeConfiguration" => {
11732                    // Ignore payload since we notify clients of setting changes unconditionally, relying on them pulling the latest settings.
11733                }
11734                "workspace/symbol" => {
11735                    let options = parse_register_capabilities(reg)?;
11736                    server.update_capabilities(|capabilities| {
11737                        capabilities.workspace_symbol_provider = Some(options);
11738                    });
11739                    notify_server_capabilities_updated(&server, cx);
11740                }
11741                "workspace/fileOperations" => {
11742                    if let Some(options) = reg.register_options {
11743                        let caps = serde_json::from_value(options)?;
11744                        server.update_capabilities(|capabilities| {
11745                            capabilities
11746                                .workspace
11747                                .get_or_insert_default()
11748                                .file_operations = Some(caps);
11749                        });
11750                        notify_server_capabilities_updated(&server, cx);
11751                    }
11752                }
11753                "workspace/executeCommand" => {
11754                    if let Some(options) = reg.register_options {
11755                        let options = serde_json::from_value(options)?;
11756                        server.update_capabilities(|capabilities| {
11757                            capabilities.execute_command_provider = Some(options);
11758                        });
11759                        notify_server_capabilities_updated(&server, cx);
11760                    }
11761                }
11762                "textDocument/rangeFormatting" => {
11763                    let options = parse_register_capabilities(reg)?;
11764                    server.update_capabilities(|capabilities| {
11765                        capabilities.document_range_formatting_provider = Some(options);
11766                    });
11767                    notify_server_capabilities_updated(&server, cx);
11768                }
11769                "textDocument/onTypeFormatting" => {
11770                    if let Some(options) = reg
11771                        .register_options
11772                        .map(serde_json::from_value)
11773                        .transpose()?
11774                    {
11775                        server.update_capabilities(|capabilities| {
11776                            capabilities.document_on_type_formatting_provider = Some(options);
11777                        });
11778                        notify_server_capabilities_updated(&server, cx);
11779                    }
11780                }
11781                "textDocument/formatting" => {
11782                    let options = parse_register_capabilities(reg)?;
11783                    server.update_capabilities(|capabilities| {
11784                        capabilities.document_formatting_provider = Some(options);
11785                    });
11786                    notify_server_capabilities_updated(&server, cx);
11787                }
11788                "textDocument/rename" => {
11789                    let options = parse_register_capabilities(reg)?;
11790                    server.update_capabilities(|capabilities| {
11791                        capabilities.rename_provider = Some(options);
11792                    });
11793                    notify_server_capabilities_updated(&server, cx);
11794                }
11795                "textDocument/inlayHint" => {
11796                    let options = parse_register_capabilities(reg)?;
11797                    server.update_capabilities(|capabilities| {
11798                        capabilities.inlay_hint_provider = Some(options);
11799                    });
11800                    notify_server_capabilities_updated(&server, cx);
11801                }
11802                "textDocument/documentSymbol" => {
11803                    let options = parse_register_capabilities(reg)?;
11804                    server.update_capabilities(|capabilities| {
11805                        capabilities.document_symbol_provider = Some(options);
11806                    });
11807                    notify_server_capabilities_updated(&server, cx);
11808                }
11809                "textDocument/codeAction" => {
11810                    if let Some(options) = reg
11811                        .register_options
11812                        .map(serde_json::from_value)
11813                        .transpose()?
11814                    {
11815                        server.update_capabilities(|capabilities| {
11816                            capabilities.code_action_provider =
11817                                Some(lsp::CodeActionProviderCapability::Options(options));
11818                        });
11819                        notify_server_capabilities_updated(&server, cx);
11820                    }
11821                }
11822                "textDocument/definition" => {
11823                    let options = parse_register_capabilities(reg)?;
11824                    server.update_capabilities(|capabilities| {
11825                        capabilities.definition_provider = Some(options);
11826                    });
11827                    notify_server_capabilities_updated(&server, cx);
11828                }
11829                "textDocument/completion" => {
11830                    if let Some(caps) = reg
11831                        .register_options
11832                        .map(serde_json::from_value)
11833                        .transpose()?
11834                    {
11835                        server.update_capabilities(|capabilities| {
11836                            capabilities.completion_provider = Some(caps);
11837                        });
11838                        notify_server_capabilities_updated(&server, cx);
11839                    }
11840                }
11841                "textDocument/hover" => {
11842                    if let Some(caps) = reg
11843                        .register_options
11844                        .map(serde_json::from_value)
11845                        .transpose()?
11846                    {
11847                        server.update_capabilities(|capabilities| {
11848                            capabilities.hover_provider = Some(caps);
11849                        });
11850                        notify_server_capabilities_updated(&server, cx);
11851                    }
11852                }
11853                "textDocument/signatureHelp" => {
11854                    if let Some(caps) = reg
11855                        .register_options
11856                        .map(serde_json::from_value)
11857                        .transpose()?
11858                    {
11859                        server.update_capabilities(|capabilities| {
11860                            capabilities.signature_help_provider = Some(caps);
11861                        });
11862                        notify_server_capabilities_updated(&server, cx);
11863                    }
11864                }
11865                "textDocument/didChange" => {
11866                    if let Some(sync_kind) = reg
11867                        .register_options
11868                        .and_then(|opts| opts.get("syncKind").cloned())
11869                        .map(serde_json::from_value::<lsp::TextDocumentSyncKind>)
11870                        .transpose()?
11871                    {
11872                        server.update_dynamic_capabilities(|dyn_caps| {
11873                            let map = dyn_caps
11874                                .text_document_sync_did_change
11875                                .get_or_insert_with(HashMap::default);
11876                            map.insert(reg.id.clone(), sync_kind);
11877                        });
11878                        notify_server_capabilities_updated(&server, cx);
11879                    }
11880                }
11881                "textDocument/didSave" => {
11882                    if let Some(include_text) = reg
11883                        .register_options
11884                        .map(|opts| {
11885                            let transpose = opts
11886                                .get("includeText")
11887                                .cloned()
11888                                .map(serde_json::from_value::<Option<bool>>)
11889                                .transpose();
11890                            match transpose {
11891                                Ok(value) => Ok(value.flatten()),
11892                                Err(e) => Err(e),
11893                            }
11894                        })
11895                        .transpose()?
11896                    {
11897                        server.update_dynamic_capabilities(|dyn_caps| {
11898                            let map = dyn_caps
11899                                .text_document_sync_did_save
11900                                .get_or_insert_with(HashMap::default);
11901                            map.insert(reg.id.clone(), lsp::SaveOptions { include_text });
11902                        });
11903                        notify_server_capabilities_updated(&server, cx);
11904                    }
11905                }
11906                "textDocument/codeLens" => {
11907                    if let Some(caps) = reg
11908                        .register_options
11909                        .map(serde_json::from_value)
11910                        .transpose()?
11911                    {
11912                        server.update_capabilities(|capabilities| {
11913                            capabilities.code_lens_provider = Some(caps);
11914                        });
11915                        notify_server_capabilities_updated(&server, cx);
11916                    }
11917                }
11918                "textDocument/diagnostic" => {
11919                    if let Some(caps) = reg
11920                        .register_options
11921                        .map(serde_json::from_value)
11922                        .transpose()?
11923                    {
11924                        server.update_capabilities(|capabilities| {
11925                            capabilities.diagnostic_provider = Some(caps);
11926                        });
11927                        notify_server_capabilities_updated(&server, cx);
11928                    }
11929                }
11930                "textDocument/documentColor" => {
11931                    if let Some(caps) = reg
11932                        .register_options
11933                        .map(serde_json::from_value)
11934                        .transpose()?
11935                    {
11936                        server.update_capabilities(|capabilities| {
11937                            capabilities.color_provider = Some(caps);
11938                        });
11939                        notify_server_capabilities_updated(&server, cx);
11940                    }
11941                }
11942                _ => log::warn!("unhandled capability registration: {reg:?}"),
11943            }
11944        }
11945
11946        Ok(())
11947    }
11948
11949    fn unregister_server_capabilities(
11950        &mut self,
11951        server_id: LanguageServerId,
11952        params: lsp::UnregistrationParams,
11953        cx: &mut Context<Self>,
11954    ) -> anyhow::Result<()> {
11955        let server = self
11956            .language_server_for_id(server_id)
11957            .with_context(|| format!("no server {server_id} found"))?;
11958        for unreg in params.unregisterations.iter() {
11959            match unreg.method.as_str() {
11960                "workspace/didChangeWatchedFiles" => {
11961                    let notify = if let Some(local_lsp_store) = self.as_local_mut() {
11962                        local_lsp_store
11963                            .on_lsp_unregister_did_change_watched_files(server_id, &unreg.id, cx);
11964                        true
11965                    } else {
11966                        false
11967                    };
11968                    if notify {
11969                        notify_server_capabilities_updated(&server, cx);
11970                    }
11971                }
11972                "workspace/didChangeConfiguration" => {
11973                    // Ignore payload since we notify clients of setting changes unconditionally, relying on them pulling the latest settings.
11974                }
11975                "workspace/symbol" => {
11976                    server.update_capabilities(|capabilities| {
11977                        capabilities.workspace_symbol_provider = None
11978                    });
11979                    notify_server_capabilities_updated(&server, cx);
11980                }
11981                "workspace/fileOperations" => {
11982                    server.update_capabilities(|capabilities| {
11983                        capabilities
11984                            .workspace
11985                            .get_or_insert_with(|| lsp::WorkspaceServerCapabilities {
11986                                workspace_folders: None,
11987                                file_operations: None,
11988                            })
11989                            .file_operations = None;
11990                    });
11991                    notify_server_capabilities_updated(&server, cx);
11992                }
11993                "workspace/executeCommand" => {
11994                    server.update_capabilities(|capabilities| {
11995                        capabilities.execute_command_provider = None;
11996                    });
11997                    notify_server_capabilities_updated(&server, cx);
11998                }
11999                "textDocument/rangeFormatting" => {
12000                    server.update_capabilities(|capabilities| {
12001                        capabilities.document_range_formatting_provider = None
12002                    });
12003                    notify_server_capabilities_updated(&server, cx);
12004                }
12005                "textDocument/onTypeFormatting" => {
12006                    server.update_capabilities(|capabilities| {
12007                        capabilities.document_on_type_formatting_provider = None;
12008                    });
12009                    notify_server_capabilities_updated(&server, cx);
12010                }
12011                "textDocument/formatting" => {
12012                    server.update_capabilities(|capabilities| {
12013                        capabilities.document_formatting_provider = None;
12014                    });
12015                    notify_server_capabilities_updated(&server, cx);
12016                }
12017                "textDocument/rename" => {
12018                    server.update_capabilities(|capabilities| capabilities.rename_provider = None);
12019                    notify_server_capabilities_updated(&server, cx);
12020                }
12021                "textDocument/codeAction" => {
12022                    server.update_capabilities(|capabilities| {
12023                        capabilities.code_action_provider = None;
12024                    });
12025                    notify_server_capabilities_updated(&server, cx);
12026                }
12027                "textDocument/definition" => {
12028                    server.update_capabilities(|capabilities| {
12029                        capabilities.definition_provider = None;
12030                    });
12031                    notify_server_capabilities_updated(&server, cx);
12032                }
12033                "textDocument/completion" => {
12034                    server.update_capabilities(|capabilities| {
12035                        capabilities.completion_provider = None;
12036                    });
12037                    notify_server_capabilities_updated(&server, cx);
12038                }
12039                "textDocument/hover" => {
12040                    server.update_capabilities(|capabilities| {
12041                        capabilities.hover_provider = None;
12042                    });
12043                    notify_server_capabilities_updated(&server, cx);
12044                }
12045                "textDocument/signatureHelp" => {
12046                    server.update_capabilities(|capabilities| {
12047                        capabilities.signature_help_provider = None;
12048                    });
12049                    notify_server_capabilities_updated(&server, cx);
12050                }
12051                "textDocument/didChange" => {
12052                    server.update_dynamic_capabilities(|dyn_caps| {
12053                        if let Some(map) = dyn_caps.text_document_sync_did_change.as_mut() {
12054                            map.remove(&unreg.id);
12055                        }
12056                    });
12057                    notify_server_capabilities_updated(&server, cx);
12058                }
12059                "textDocument/didSave" => {
12060                    server.update_dynamic_capabilities(|dyn_caps| {
12061                        if let Some(map) = dyn_caps.text_document_sync_did_save.as_mut() {
12062                            map.remove(&unreg.id);
12063                        }
12064                    });
12065                    notify_server_capabilities_updated(&server, cx);
12066                }
12067                "textDocument/codeLens" => {
12068                    server.update_capabilities(|capabilities| {
12069                        capabilities.code_lens_provider = None;
12070                    });
12071                    notify_server_capabilities_updated(&server, cx);
12072                }
12073                "textDocument/diagnostic" => {
12074                    server.update_capabilities(|capabilities| {
12075                        capabilities.diagnostic_provider = None;
12076                    });
12077                    notify_server_capabilities_updated(&server, cx);
12078                }
12079                "textDocument/documentColor" => {
12080                    server.update_capabilities(|capabilities| {
12081                        capabilities.color_provider = None;
12082                    });
12083                    notify_server_capabilities_updated(&server, cx);
12084                }
12085                _ => log::warn!("unhandled capability unregistration: {unreg:?}"),
12086            }
12087        }
12088
12089        Ok(())
12090    }
12091
12092    async fn query_lsp_locally<T>(
12093        lsp_store: Entity<Self>,
12094        sender_id: proto::PeerId,
12095        lsp_request_id: LspRequestId,
12096        proto_request: T::ProtoRequest,
12097        position: Option<Anchor>,
12098        mut cx: AsyncApp,
12099    ) -> Result<()>
12100    where
12101        T: LspCommand + Clone,
12102        T::ProtoRequest: proto::LspRequestMessage,
12103        <T::ProtoRequest as proto::RequestMessage>::Response:
12104            Into<<T::ProtoRequest as proto::LspRequestMessage>::Response>,
12105    {
12106        let buffer_id = BufferId::new(proto_request.buffer_id())?;
12107        let version = deserialize_version(proto_request.buffer_version());
12108        let buffer = lsp_store.update(&mut cx, |this, cx| {
12109            this.buffer_store.read(cx).get_existing(buffer_id)
12110        })??;
12111        buffer
12112            .update(&mut cx, |buffer, _| {
12113                buffer.wait_for_version(version.clone())
12114            })?
12115            .await?;
12116        let buffer_version = buffer.read_with(&cx, |buffer, _| buffer.version())?;
12117        let request =
12118            T::from_proto(proto_request, lsp_store.clone(), buffer.clone(), cx.clone()).await?;
12119        lsp_store.update(&mut cx, |lsp_store, cx| {
12120            let request_task =
12121                lsp_store.request_multiple_lsp_locally(&buffer, position, request, cx);
12122            let existing_queries = lsp_store
12123                .running_lsp_requests
12124                .entry(TypeId::of::<T>())
12125                .or_default();
12126            if T::ProtoRequest::stop_previous_requests()
12127                || buffer_version.changed_since(&existing_queries.0)
12128            {
12129                existing_queries.1.clear();
12130            }
12131            existing_queries.1.insert(
12132                lsp_request_id,
12133                cx.spawn(async move |lsp_store, cx| {
12134                    let response = request_task.await;
12135                    lsp_store
12136                        .update(cx, |lsp_store, cx| {
12137                            if let Some((client, project_id)) = lsp_store.downstream_client.clone()
12138                            {
12139                                let response = response
12140                                    .into_iter()
12141                                    .map(|(server_id, response)| {
12142                                        (
12143                                            server_id.to_proto(),
12144                                            T::response_to_proto(
12145                                                response,
12146                                                lsp_store,
12147                                                sender_id,
12148                                                &buffer_version,
12149                                                cx,
12150                                            )
12151                                            .into(),
12152                                        )
12153                                    })
12154                                    .collect::<HashMap<_, _>>();
12155                                match client.send_lsp_response::<T::ProtoRequest>(
12156                                    project_id,
12157                                    lsp_request_id,
12158                                    response,
12159                                ) {
12160                                    Ok(()) => {}
12161                                    Err(e) => {
12162                                        log::error!("Failed to send LSP response: {e:#}",)
12163                                    }
12164                                }
12165                            }
12166                        })
12167                        .ok();
12168                }),
12169            );
12170        })?;
12171        Ok(())
12172    }
12173
12174    fn take_text_document_sync_options(
12175        capabilities: &mut lsp::ServerCapabilities,
12176    ) -> lsp::TextDocumentSyncOptions {
12177        match capabilities.text_document_sync.take() {
12178            Some(lsp::TextDocumentSyncCapability::Options(sync_options)) => sync_options,
12179            Some(lsp::TextDocumentSyncCapability::Kind(sync_kind)) => {
12180                let mut sync_options = lsp::TextDocumentSyncOptions::default();
12181                sync_options.change = Some(sync_kind);
12182                sync_options
12183            }
12184            None => lsp::TextDocumentSyncOptions::default(),
12185        }
12186    }
12187
12188    #[cfg(any(test, feature = "test-support"))]
12189    pub fn forget_code_lens_task(&mut self, buffer_id: BufferId) -> Option<CodeLensTask> {
12190        let data = self.lsp_code_lens.get_mut(&buffer_id)?;
12191        Some(data.update.take()?.1)
12192    }
12193}
12194
12195// Registration with registerOptions as null, should fallback to true.
12196// https://github.com/microsoft/vscode-languageserver-node/blob/d90a87f9557a0df9142cfb33e251cfa6fe27d970/client/src/common/client.ts#L2133
12197fn parse_register_capabilities<T: serde::de::DeserializeOwned>(
12198    reg: lsp::Registration,
12199) -> Result<OneOf<bool, T>> {
12200    Ok(match reg.register_options {
12201        Some(options) => OneOf::Right(serde_json::from_value::<T>(options)?),
12202        None => OneOf::Left(true),
12203    })
12204}
12205
12206fn subscribe_to_binary_statuses(
12207    languages: &Arc<LanguageRegistry>,
12208    cx: &mut Context<'_, LspStore>,
12209) -> Task<()> {
12210    let mut server_statuses = languages.language_server_binary_statuses();
12211    cx.spawn(async move |lsp_store, cx| {
12212        while let Some((server_name, binary_status)) = server_statuses.next().await {
12213            if lsp_store
12214                .update(cx, |_, cx| {
12215                    let mut message = None;
12216                    let binary_status = match binary_status {
12217                        BinaryStatus::None => proto::ServerBinaryStatus::None,
12218                        BinaryStatus::CheckingForUpdate => {
12219                            proto::ServerBinaryStatus::CheckingForUpdate
12220                        }
12221                        BinaryStatus::Downloading => proto::ServerBinaryStatus::Downloading,
12222                        BinaryStatus::Starting => proto::ServerBinaryStatus::Starting,
12223                        BinaryStatus::Stopping => proto::ServerBinaryStatus::Stopping,
12224                        BinaryStatus::Stopped => proto::ServerBinaryStatus::Stopped,
12225                        BinaryStatus::Failed { error } => {
12226                            message = Some(error);
12227                            proto::ServerBinaryStatus::Failed
12228                        }
12229                    };
12230                    cx.emit(LspStoreEvent::LanguageServerUpdate {
12231                        // Binary updates are about the binary that might not have any language server id at that point.
12232                        // Reuse `LanguageServerUpdate` for them and provide a fake id that won't be used on the receiver side.
12233                        language_server_id: LanguageServerId(0),
12234                        name: Some(server_name),
12235                        message: proto::update_language_server::Variant::StatusUpdate(
12236                            proto::StatusUpdate {
12237                                message,
12238                                status: Some(proto::status_update::Status::Binary(
12239                                    binary_status as i32,
12240                                )),
12241                            },
12242                        ),
12243                    });
12244                })
12245                .is_err()
12246            {
12247                break;
12248            }
12249        }
12250    })
12251}
12252
12253fn lsp_workspace_diagnostics_refresh(
12254    server: Arc<LanguageServer>,
12255    cx: &mut Context<'_, LspStore>,
12256) -> Option<WorkspaceRefreshTask> {
12257    let identifier = match server.capabilities().diagnostic_provider? {
12258        lsp::DiagnosticServerCapabilities::Options(diagnostic_options) => {
12259            if !diagnostic_options.workspace_diagnostics {
12260                return None;
12261            }
12262            diagnostic_options.identifier
12263        }
12264        lsp::DiagnosticServerCapabilities::RegistrationOptions(registration_options) => {
12265            let diagnostic_options = registration_options.diagnostic_options;
12266            if !diagnostic_options.workspace_diagnostics {
12267                return None;
12268            }
12269            diagnostic_options.identifier
12270        }
12271    };
12272
12273    let (progress_tx, mut progress_rx) = mpsc::channel(1);
12274    let (mut refresh_tx, mut refresh_rx) = mpsc::channel(1);
12275    refresh_tx.try_send(()).ok();
12276
12277    let workspace_query_language_server = cx.spawn(async move |lsp_store, cx| {
12278        let mut attempts = 0;
12279        let max_attempts = 50;
12280        let mut requests = 0;
12281
12282        loop {
12283            let Some(()) = refresh_rx.recv().await else {
12284                return;
12285            };
12286
12287            'request: loop {
12288                requests += 1;
12289                if attempts > max_attempts {
12290                    log::error!(
12291                        "Failed to pull workspace diagnostics {max_attempts} times, aborting"
12292                    );
12293                    return;
12294                }
12295                let backoff_millis = (50 * (1 << attempts)).clamp(30, 1000);
12296                cx.background_executor()
12297                    .timer(Duration::from_millis(backoff_millis))
12298                    .await;
12299                attempts += 1;
12300
12301                let Ok(previous_result_ids) = lsp_store.update(cx, |lsp_store, _| {
12302                    lsp_store
12303                        .all_result_ids(server.server_id())
12304                        .into_iter()
12305                        .filter_map(|(abs_path, result_id)| {
12306                            let uri = file_path_to_lsp_url(&abs_path).ok()?;
12307                            Some(lsp::PreviousResultId {
12308                                uri,
12309                                value: result_id,
12310                            })
12311                        })
12312                        .collect()
12313                }) else {
12314                    return;
12315                };
12316
12317                let token = format!("workspace/diagnostic-{}-{}", server.server_id(), requests);
12318
12319                progress_rx.try_recv().ok();
12320                let timer =
12321                    LanguageServer::default_request_timer(cx.background_executor().clone()).fuse();
12322                let progress = pin!(progress_rx.recv().fuse());
12323                let response_result = server
12324                    .request_with_timer::<lsp::WorkspaceDiagnosticRequest, _>(
12325                        lsp::WorkspaceDiagnosticParams {
12326                            previous_result_ids,
12327                            identifier: identifier.clone(),
12328                            work_done_progress_params: Default::default(),
12329                            partial_result_params: lsp::PartialResultParams {
12330                                partial_result_token: Some(lsp::ProgressToken::String(token)),
12331                            },
12332                        },
12333                        select(timer, progress).then(|either| match either {
12334                            Either::Left((message, ..)) => ready(message).left_future(),
12335                            Either::Right(..) => pending::<String>().right_future(),
12336                        }),
12337                    )
12338                    .await;
12339
12340                // https://microsoft.github.io/language-server-protocol/specifications/lsp/3.17/specification/#diagnostic_refresh
12341                // >  If a server closes a workspace diagnostic pull request the client should re-trigger the request.
12342                match response_result {
12343                    ConnectionResult::Timeout => {
12344                        log::error!("Timeout during workspace diagnostics pull");
12345                        continue 'request;
12346                    }
12347                    ConnectionResult::ConnectionReset => {
12348                        log::error!("Server closed a workspace diagnostics pull request");
12349                        continue 'request;
12350                    }
12351                    ConnectionResult::Result(Err(e)) => {
12352                        log::error!("Error during workspace diagnostics pull: {e:#}");
12353                        break 'request;
12354                    }
12355                    ConnectionResult::Result(Ok(pulled_diagnostics)) => {
12356                        attempts = 0;
12357                        if lsp_store
12358                            .update(cx, |lsp_store, cx| {
12359                                lsp_store.apply_workspace_diagnostic_report(
12360                                    server.server_id(),
12361                                    pulled_diagnostics,
12362                                    cx,
12363                                )
12364                            })
12365                            .is_err()
12366                        {
12367                            return;
12368                        }
12369                        break 'request;
12370                    }
12371                }
12372            }
12373        }
12374    });
12375
12376    Some(WorkspaceRefreshTask {
12377        refresh_tx,
12378        progress_tx,
12379        task: workspace_query_language_server,
12380    })
12381}
12382
12383fn resolve_word_completion(snapshot: &BufferSnapshot, completion: &mut Completion) {
12384    let CompletionSource::BufferWord {
12385        word_range,
12386        resolved,
12387    } = &mut completion.source
12388    else {
12389        return;
12390    };
12391    if *resolved {
12392        return;
12393    }
12394
12395    if completion.new_text
12396        != snapshot
12397            .text_for_range(word_range.clone())
12398            .collect::<String>()
12399    {
12400        return;
12401    }
12402
12403    let mut offset = 0;
12404    for chunk in snapshot.chunks(word_range.clone(), true) {
12405        let end_offset = offset + chunk.text.len();
12406        if let Some(highlight_id) = chunk.syntax_highlight_id {
12407            completion
12408                .label
12409                .runs
12410                .push((offset..end_offset, highlight_id));
12411        }
12412        offset = end_offset;
12413    }
12414    *resolved = true;
12415}
12416
12417impl EventEmitter<LspStoreEvent> for LspStore {}
12418
12419fn remove_empty_hover_blocks(mut hover: Hover) -> Option<Hover> {
12420    hover
12421        .contents
12422        .retain(|hover_block| !hover_block.text.trim().is_empty());
12423    if hover.contents.is_empty() {
12424        None
12425    } else {
12426        Some(hover)
12427    }
12428}
12429
12430async fn populate_labels_for_completions(
12431    new_completions: Vec<CoreCompletion>,
12432    language: Option<Arc<Language>>,
12433    lsp_adapter: Option<Arc<CachedLspAdapter>>,
12434) -> Vec<Completion> {
12435    let lsp_completions = new_completions
12436        .iter()
12437        .filter_map(|new_completion| {
12438            new_completion
12439                .source
12440                .lsp_completion(true)
12441                .map(|lsp_completion| lsp_completion.into_owned())
12442        })
12443        .collect::<Vec<_>>();
12444
12445    let mut labels = if let Some((language, lsp_adapter)) = language.as_ref().zip(lsp_adapter) {
12446        lsp_adapter
12447            .labels_for_completions(&lsp_completions, language)
12448            .await
12449            .log_err()
12450            .unwrap_or_default()
12451    } else {
12452        Vec::new()
12453    }
12454    .into_iter()
12455    .fuse();
12456
12457    let mut completions = Vec::new();
12458    for completion in new_completions {
12459        match completion.source.lsp_completion(true) {
12460            Some(lsp_completion) => {
12461                let documentation = lsp_completion.documentation.clone().map(|docs| docs.into());
12462
12463                let mut label = labels.next().flatten().unwrap_or_else(|| {
12464                    CodeLabel::fallback_for_completion(&lsp_completion, language.as_deref())
12465                });
12466                ensure_uniform_list_compatible_label(&mut label);
12467                completions.push(Completion {
12468                    label,
12469                    documentation,
12470                    replace_range: completion.replace_range,
12471                    new_text: completion.new_text,
12472                    insert_text_mode: lsp_completion.insert_text_mode,
12473                    source: completion.source,
12474                    icon_path: None,
12475                    confirm: None,
12476                });
12477            }
12478            None => {
12479                let mut label = CodeLabel::plain(completion.new_text.clone(), None);
12480                ensure_uniform_list_compatible_label(&mut label);
12481                completions.push(Completion {
12482                    label,
12483                    documentation: None,
12484                    replace_range: completion.replace_range,
12485                    new_text: completion.new_text,
12486                    source: completion.source,
12487                    insert_text_mode: None,
12488                    icon_path: None,
12489                    confirm: None,
12490                });
12491            }
12492        }
12493    }
12494    completions
12495}
12496
12497#[derive(Debug)]
12498pub enum LanguageServerToQuery {
12499    /// Query language servers in order of users preference, up until one capable of handling the request is found.
12500    FirstCapable,
12501    /// Query a specific language server.
12502    Other(LanguageServerId),
12503}
12504
12505#[derive(Default)]
12506struct RenamePathsWatchedForServer {
12507    did_rename: Vec<RenameActionPredicate>,
12508    will_rename: Vec<RenameActionPredicate>,
12509}
12510
12511impl RenamePathsWatchedForServer {
12512    fn with_did_rename_patterns(
12513        mut self,
12514        did_rename: Option<&FileOperationRegistrationOptions>,
12515    ) -> Self {
12516        if let Some(did_rename) = did_rename {
12517            self.did_rename = did_rename
12518                .filters
12519                .iter()
12520                .filter_map(|filter| filter.try_into().log_err())
12521                .collect();
12522        }
12523        self
12524    }
12525    fn with_will_rename_patterns(
12526        mut self,
12527        will_rename: Option<&FileOperationRegistrationOptions>,
12528    ) -> Self {
12529        if let Some(will_rename) = will_rename {
12530            self.will_rename = will_rename
12531                .filters
12532                .iter()
12533                .filter_map(|filter| filter.try_into().log_err())
12534                .collect();
12535        }
12536        self
12537    }
12538
12539    fn should_send_did_rename(&self, path: &str, is_dir: bool) -> bool {
12540        self.did_rename.iter().any(|pred| pred.eval(path, is_dir))
12541    }
12542    fn should_send_will_rename(&self, path: &str, is_dir: bool) -> bool {
12543        self.will_rename.iter().any(|pred| pred.eval(path, is_dir))
12544    }
12545}
12546
12547impl TryFrom<&FileOperationFilter> for RenameActionPredicate {
12548    type Error = globset::Error;
12549    fn try_from(ops: &FileOperationFilter) -> Result<Self, globset::Error> {
12550        Ok(Self {
12551            kind: ops.pattern.matches.clone(),
12552            glob: GlobBuilder::new(&ops.pattern.glob)
12553                .case_insensitive(
12554                    ops.pattern
12555                        .options
12556                        .as_ref()
12557                        .is_some_and(|ops| ops.ignore_case.unwrap_or(false)),
12558                )
12559                .build()?
12560                .compile_matcher(),
12561        })
12562    }
12563}
12564struct RenameActionPredicate {
12565    glob: GlobMatcher,
12566    kind: Option<FileOperationPatternKind>,
12567}
12568
12569impl RenameActionPredicate {
12570    // Returns true if language server should be notified
12571    fn eval(&self, path: &str, is_dir: bool) -> bool {
12572        self.kind.as_ref().is_none_or(|kind| {
12573            let expected_kind = if is_dir {
12574                FileOperationPatternKind::Folder
12575            } else {
12576                FileOperationPatternKind::File
12577            };
12578            kind == &expected_kind
12579        }) && self.glob.is_match(path)
12580    }
12581}
12582
12583#[derive(Default)]
12584struct LanguageServerWatchedPaths {
12585    worktree_paths: HashMap<WorktreeId, GlobSet>,
12586    abs_paths: HashMap<Arc<Path>, (GlobSet, Task<()>)>,
12587}
12588
12589#[derive(Default)]
12590struct LanguageServerWatchedPathsBuilder {
12591    worktree_paths: HashMap<WorktreeId, GlobSet>,
12592    abs_paths: HashMap<Arc<Path>, GlobSet>,
12593}
12594
12595impl LanguageServerWatchedPathsBuilder {
12596    fn watch_worktree(&mut self, worktree_id: WorktreeId, glob_set: GlobSet) {
12597        self.worktree_paths.insert(worktree_id, glob_set);
12598    }
12599    fn watch_abs_path(&mut self, path: Arc<Path>, glob_set: GlobSet) {
12600        self.abs_paths.insert(path, glob_set);
12601    }
12602    fn build(
12603        self,
12604        fs: Arc<dyn Fs>,
12605        language_server_id: LanguageServerId,
12606        cx: &mut Context<LspStore>,
12607    ) -> LanguageServerWatchedPaths {
12608        let project = cx.weak_entity();
12609
12610        const LSP_ABS_PATH_OBSERVE: Duration = Duration::from_millis(100);
12611        let abs_paths = self
12612            .abs_paths
12613            .into_iter()
12614            .map(|(abs_path, globset)| {
12615                let task = cx.spawn({
12616                    let abs_path = abs_path.clone();
12617                    let fs = fs.clone();
12618
12619                    let lsp_store = project.clone();
12620                    async move |_, cx| {
12621                        maybe!(async move {
12622                            let mut push_updates = fs.watch(&abs_path, LSP_ABS_PATH_OBSERVE).await;
12623                            while let Some(update) = push_updates.0.next().await {
12624                                let action = lsp_store
12625                                    .update(cx, |this, _| {
12626                                        let Some(local) = this.as_local() else {
12627                                            return ControlFlow::Break(());
12628                                        };
12629                                        let Some(watcher) = local
12630                                            .language_server_watched_paths
12631                                            .get(&language_server_id)
12632                                        else {
12633                                            return ControlFlow::Break(());
12634                                        };
12635                                        let (globs, _) = watcher.abs_paths.get(&abs_path).expect(
12636                                            "Watched abs path is not registered with a watcher",
12637                                        );
12638                                        let matching_entries = update
12639                                            .into_iter()
12640                                            .filter(|event| globs.is_match(&event.path))
12641                                            .collect::<Vec<_>>();
12642                                        this.lsp_notify_abs_paths_changed(
12643                                            language_server_id,
12644                                            matching_entries,
12645                                        );
12646                                        ControlFlow::Continue(())
12647                                    })
12648                                    .ok()?;
12649
12650                                if action.is_break() {
12651                                    break;
12652                                }
12653                            }
12654                            Some(())
12655                        })
12656                        .await;
12657                    }
12658                });
12659                (abs_path, (globset, task))
12660            })
12661            .collect();
12662        LanguageServerWatchedPaths {
12663            worktree_paths: self.worktree_paths,
12664            abs_paths,
12665        }
12666    }
12667}
12668
12669struct LspBufferSnapshot {
12670    version: i32,
12671    snapshot: TextBufferSnapshot,
12672}
12673
12674/// A prompt requested by LSP server.
12675#[derive(Clone, Debug)]
12676pub struct LanguageServerPromptRequest {
12677    pub level: PromptLevel,
12678    pub message: String,
12679    pub actions: Vec<MessageActionItem>,
12680    pub lsp_name: String,
12681    pub(crate) response_channel: Sender<MessageActionItem>,
12682}
12683
12684impl LanguageServerPromptRequest {
12685    pub async fn respond(self, index: usize) -> Option<()> {
12686        if let Some(response) = self.actions.into_iter().nth(index) {
12687            self.response_channel.send(response).await.ok()
12688        } else {
12689            None
12690        }
12691    }
12692}
12693impl PartialEq for LanguageServerPromptRequest {
12694    fn eq(&self, other: &Self) -> bool {
12695        self.message == other.message && self.actions == other.actions
12696    }
12697}
12698
12699#[derive(Clone, Debug, PartialEq)]
12700pub enum LanguageServerLogType {
12701    Log(MessageType),
12702    Trace(Option<String>),
12703}
12704
12705impl LanguageServerLogType {
12706    pub fn to_proto(&self) -> proto::language_server_log::LogType {
12707        match self {
12708            Self::Log(log_type) => {
12709                let message_type = match *log_type {
12710                    MessageType::ERROR => 1,
12711                    MessageType::WARNING => 2,
12712                    MessageType::INFO => 3,
12713                    MessageType::LOG => 4,
12714                    other => {
12715                        log::warn!("Unknown lsp log message type: {:?}", other);
12716                        4
12717                    }
12718                };
12719                proto::language_server_log::LogType::LogMessageType(message_type)
12720            }
12721            Self::Trace(message) => {
12722                proto::language_server_log::LogType::LogTrace(proto::LspLogTrace {
12723                    message: message.clone(),
12724                })
12725            }
12726        }
12727    }
12728
12729    pub fn from_proto(log_type: proto::language_server_log::LogType) -> Self {
12730        match log_type {
12731            proto::language_server_log::LogType::LogMessageType(message_type) => {
12732                Self::Log(match message_type {
12733                    1 => MessageType::ERROR,
12734                    2 => MessageType::WARNING,
12735                    3 => MessageType::INFO,
12736                    4 => MessageType::LOG,
12737                    _ => MessageType::LOG,
12738                })
12739            }
12740            proto::language_server_log::LogType::LogTrace(trace) => Self::Trace(trace.message),
12741        }
12742    }
12743}
12744
12745pub struct WorkspaceRefreshTask {
12746    refresh_tx: mpsc::Sender<()>,
12747    progress_tx: mpsc::Sender<()>,
12748    #[allow(dead_code)]
12749    task: Task<()>,
12750}
12751
12752pub enum LanguageServerState {
12753    Starting {
12754        startup: Task<Option<Arc<LanguageServer>>>,
12755        /// List of language servers that will be added to the workspace once it's initialization completes.
12756        pending_workspace_folders: Arc<Mutex<BTreeSet<Url>>>,
12757    },
12758
12759    Running {
12760        adapter: Arc<CachedLspAdapter>,
12761        server: Arc<LanguageServer>,
12762        simulate_disk_based_diagnostics_completion: Option<Task<()>>,
12763        workspace_refresh_task: Option<WorkspaceRefreshTask>,
12764    },
12765}
12766
12767impl LanguageServerState {
12768    fn add_workspace_folder(&self, uri: Url) {
12769        match self {
12770            LanguageServerState::Starting {
12771                pending_workspace_folders,
12772                ..
12773            } => {
12774                pending_workspace_folders.lock().insert(uri);
12775            }
12776            LanguageServerState::Running { server, .. } => {
12777                server.add_workspace_folder(uri);
12778            }
12779        }
12780    }
12781    fn _remove_workspace_folder(&self, uri: Url) {
12782        match self {
12783            LanguageServerState::Starting {
12784                pending_workspace_folders,
12785                ..
12786            } => {
12787                pending_workspace_folders.lock().remove(&uri);
12788            }
12789            LanguageServerState::Running { server, .. } => server.remove_workspace_folder(uri),
12790        }
12791    }
12792}
12793
12794impl std::fmt::Debug for LanguageServerState {
12795    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
12796        match self {
12797            LanguageServerState::Starting { .. } => {
12798                f.debug_struct("LanguageServerState::Starting").finish()
12799            }
12800            LanguageServerState::Running { .. } => {
12801                f.debug_struct("LanguageServerState::Running").finish()
12802            }
12803        }
12804    }
12805}
12806
12807#[derive(Clone, Debug, Serialize)]
12808pub struct LanguageServerProgress {
12809    pub is_disk_based_diagnostics_progress: bool,
12810    pub is_cancellable: bool,
12811    pub title: Option<String>,
12812    pub message: Option<String>,
12813    pub percentage: Option<usize>,
12814    #[serde(skip_serializing)]
12815    pub last_update_at: Instant,
12816}
12817
12818#[derive(Copy, Clone, Debug, Default, PartialEq, Serialize)]
12819pub struct DiagnosticSummary {
12820    pub error_count: usize,
12821    pub warning_count: usize,
12822}
12823
12824impl DiagnosticSummary {
12825    pub fn new<'a, T: 'a>(diagnostics: impl IntoIterator<Item = &'a DiagnosticEntry<T>>) -> Self {
12826        let mut this = Self {
12827            error_count: 0,
12828            warning_count: 0,
12829        };
12830
12831        for entry in diagnostics {
12832            if entry.diagnostic.is_primary {
12833                match entry.diagnostic.severity {
12834                    DiagnosticSeverity::ERROR => this.error_count += 1,
12835                    DiagnosticSeverity::WARNING => this.warning_count += 1,
12836                    _ => {}
12837                }
12838            }
12839        }
12840
12841        this
12842    }
12843
12844    pub fn is_empty(&self) -> bool {
12845        self.error_count == 0 && self.warning_count == 0
12846    }
12847
12848    pub fn to_proto(
12849        self,
12850        language_server_id: LanguageServerId,
12851        path: &Path,
12852    ) -> proto::DiagnosticSummary {
12853        proto::DiagnosticSummary {
12854            path: path.to_proto(),
12855            language_server_id: language_server_id.0 as u64,
12856            error_count: self.error_count as u32,
12857            warning_count: self.warning_count as u32,
12858        }
12859    }
12860}
12861
12862#[derive(Clone, Debug)]
12863pub enum CompletionDocumentation {
12864    /// There is no documentation for this completion.
12865    Undocumented,
12866    /// A single line of documentation.
12867    SingleLine(SharedString),
12868    /// Multiple lines of plain text documentation.
12869    MultiLinePlainText(SharedString),
12870    /// Markdown documentation.
12871    MultiLineMarkdown(SharedString),
12872    /// Both single line and multiple lines of plain text documentation.
12873    SingleLineAndMultiLinePlainText {
12874        single_line: SharedString,
12875        plain_text: Option<SharedString>,
12876    },
12877}
12878
12879impl From<lsp::Documentation> for CompletionDocumentation {
12880    fn from(docs: lsp::Documentation) -> Self {
12881        match docs {
12882            lsp::Documentation::String(text) => {
12883                if text.lines().count() <= 1 {
12884                    CompletionDocumentation::SingleLine(text.into())
12885                } else {
12886                    CompletionDocumentation::MultiLinePlainText(text.into())
12887                }
12888            }
12889
12890            lsp::Documentation::MarkupContent(lsp::MarkupContent { kind, value }) => match kind {
12891                lsp::MarkupKind::PlainText => {
12892                    if value.lines().count() <= 1 {
12893                        CompletionDocumentation::SingleLine(value.into())
12894                    } else {
12895                        CompletionDocumentation::MultiLinePlainText(value.into())
12896                    }
12897                }
12898
12899                lsp::MarkupKind::Markdown => {
12900                    CompletionDocumentation::MultiLineMarkdown(value.into())
12901                }
12902            },
12903        }
12904    }
12905}
12906
12907fn glob_literal_prefix(glob: &Path) -> PathBuf {
12908    glob.components()
12909        .take_while(|component| match component {
12910            path::Component::Normal(part) => !part.to_string_lossy().contains(['*', '?', '{', '}']),
12911            _ => true,
12912        })
12913        .collect()
12914}
12915
12916pub struct SshLspAdapter {
12917    name: LanguageServerName,
12918    binary: LanguageServerBinary,
12919    initialization_options: Option<String>,
12920    code_action_kinds: Option<Vec<CodeActionKind>>,
12921}
12922
12923impl SshLspAdapter {
12924    pub fn new(
12925        name: LanguageServerName,
12926        binary: LanguageServerBinary,
12927        initialization_options: Option<String>,
12928        code_action_kinds: Option<String>,
12929    ) -> Self {
12930        Self {
12931            name,
12932            binary,
12933            initialization_options,
12934            code_action_kinds: code_action_kinds
12935                .as_ref()
12936                .and_then(|c| serde_json::from_str(c).ok()),
12937        }
12938    }
12939}
12940
12941#[async_trait(?Send)]
12942impl LspAdapter for SshLspAdapter {
12943    fn name(&self) -> LanguageServerName {
12944        self.name.clone()
12945    }
12946
12947    async fn initialization_options(
12948        self: Arc<Self>,
12949        _: &dyn Fs,
12950        _: &Arc<dyn LspAdapterDelegate>,
12951    ) -> Result<Option<serde_json::Value>> {
12952        let Some(options) = &self.initialization_options else {
12953            return Ok(None);
12954        };
12955        let result = serde_json::from_str(options)?;
12956        Ok(result)
12957    }
12958
12959    fn code_action_kinds(&self) -> Option<Vec<CodeActionKind>> {
12960        self.code_action_kinds.clone()
12961    }
12962
12963    async fn check_if_user_installed(
12964        &self,
12965        _: &dyn LspAdapterDelegate,
12966        _: Option<Toolchain>,
12967        _: &AsyncApp,
12968    ) -> Option<LanguageServerBinary> {
12969        Some(self.binary.clone())
12970    }
12971
12972    async fn cached_server_binary(
12973        &self,
12974        _: PathBuf,
12975        _: &dyn LspAdapterDelegate,
12976    ) -> Option<LanguageServerBinary> {
12977        None
12978    }
12979
12980    async fn fetch_latest_server_version(
12981        &self,
12982        _: &dyn LspAdapterDelegate,
12983    ) -> Result<Box<dyn 'static + Send + Any>> {
12984        anyhow::bail!("SshLspAdapter does not support fetch_latest_server_version")
12985    }
12986
12987    async fn fetch_server_binary(
12988        &self,
12989        _: Box<dyn 'static + Send + Any>,
12990        _: PathBuf,
12991        _: &dyn LspAdapterDelegate,
12992    ) -> Result<LanguageServerBinary> {
12993        anyhow::bail!("SshLspAdapter does not support fetch_server_binary")
12994    }
12995}
12996
12997pub fn language_server_settings<'a>(
12998    delegate: &'a dyn LspAdapterDelegate,
12999    language: &LanguageServerName,
13000    cx: &'a App,
13001) -> Option<&'a LspSettings> {
13002    language_server_settings_for(
13003        SettingsLocation {
13004            worktree_id: delegate.worktree_id(),
13005            path: delegate.worktree_root_path(),
13006        },
13007        language,
13008        cx,
13009    )
13010}
13011
13012pub(crate) fn language_server_settings_for<'a>(
13013    location: SettingsLocation<'a>,
13014    language: &LanguageServerName,
13015    cx: &'a App,
13016) -> Option<&'a LspSettings> {
13017    ProjectSettings::get(Some(location), cx).lsp.get(language)
13018}
13019
13020pub struct LocalLspAdapterDelegate {
13021    lsp_store: WeakEntity<LspStore>,
13022    worktree: worktree::Snapshot,
13023    fs: Arc<dyn Fs>,
13024    http_client: Arc<dyn HttpClient>,
13025    language_registry: Arc<LanguageRegistry>,
13026    load_shell_env_task: Shared<Task<Option<HashMap<String, String>>>>,
13027}
13028
13029impl LocalLspAdapterDelegate {
13030    pub fn new(
13031        language_registry: Arc<LanguageRegistry>,
13032        environment: &Entity<ProjectEnvironment>,
13033        lsp_store: WeakEntity<LspStore>,
13034        worktree: &Entity<Worktree>,
13035        http_client: Arc<dyn HttpClient>,
13036        fs: Arc<dyn Fs>,
13037        cx: &mut App,
13038    ) -> Arc<Self> {
13039        let load_shell_env_task = environment.update(cx, |env, cx| {
13040            env.get_worktree_environment(worktree.clone(), cx)
13041        });
13042
13043        Arc::new(Self {
13044            lsp_store,
13045            worktree: worktree.read(cx).snapshot(),
13046            fs,
13047            http_client,
13048            language_registry,
13049            load_shell_env_task,
13050        })
13051    }
13052
13053    fn from_local_lsp(
13054        local: &LocalLspStore,
13055        worktree: &Entity<Worktree>,
13056        cx: &mut App,
13057    ) -> Arc<Self> {
13058        Self::new(
13059            local.languages.clone(),
13060            &local.environment,
13061            local.weak.clone(),
13062            worktree,
13063            local.http_client.clone(),
13064            local.fs.clone(),
13065            cx,
13066        )
13067    }
13068}
13069
13070#[async_trait]
13071impl LspAdapterDelegate for LocalLspAdapterDelegate {
13072    fn show_notification(&self, message: &str, cx: &mut App) {
13073        self.lsp_store
13074            .update(cx, |_, cx| {
13075                cx.emit(LspStoreEvent::Notification(message.to_owned()))
13076            })
13077            .ok();
13078    }
13079
13080    fn http_client(&self) -> Arc<dyn HttpClient> {
13081        self.http_client.clone()
13082    }
13083
13084    fn worktree_id(&self) -> WorktreeId {
13085        self.worktree.id()
13086    }
13087
13088    fn worktree_root_path(&self) -> &Path {
13089        self.worktree.abs_path().as_ref()
13090    }
13091
13092    async fn shell_env(&self) -> HashMap<String, String> {
13093        let task = self.load_shell_env_task.clone();
13094        task.await.unwrap_or_default()
13095    }
13096
13097    async fn npm_package_installed_version(
13098        &self,
13099        package_name: &str,
13100    ) -> Result<Option<(PathBuf, String)>> {
13101        let local_package_directory = self.worktree_root_path();
13102        let node_modules_directory = local_package_directory.join("node_modules");
13103
13104        if let Some(version) =
13105            read_package_installed_version(node_modules_directory.clone(), package_name).await?
13106        {
13107            return Ok(Some((node_modules_directory, version)));
13108        }
13109        let Some(npm) = self.which("npm".as_ref()).await else {
13110            log::warn!(
13111                "Failed to find npm executable for {:?}",
13112                local_package_directory
13113            );
13114            return Ok(None);
13115        };
13116
13117        let env = self.shell_env().await;
13118        let output = util::command::new_smol_command(&npm)
13119            .args(["root", "-g"])
13120            .envs(env)
13121            .current_dir(local_package_directory)
13122            .output()
13123            .await?;
13124        let global_node_modules =
13125            PathBuf::from(String::from_utf8_lossy(&output.stdout).to_string());
13126
13127        if let Some(version) =
13128            read_package_installed_version(global_node_modules.clone(), package_name).await?
13129        {
13130            return Ok(Some((global_node_modules, version)));
13131        }
13132        return Ok(None);
13133    }
13134
13135    #[cfg(not(target_os = "windows"))]
13136    async fn which(&self, command: &OsStr) -> Option<PathBuf> {
13137        let worktree_abs_path = self.worktree.abs_path();
13138        let shell_path = self.shell_env().await.get("PATH").cloned();
13139        which::which_in(command, shell_path.as_ref(), worktree_abs_path).ok()
13140    }
13141
13142    #[cfg(target_os = "windows")]
13143    async fn which(&self, command: &OsStr) -> Option<PathBuf> {
13144        // todo(windows) Getting the shell env variables in a current directory on Windows is more complicated than other platforms
13145        //               there isn't a 'default shell' necessarily. The closest would be the default profile on the windows terminal
13146        //               SEE: https://learn.microsoft.com/en-us/windows/terminal/customize-settings/startup
13147        which::which(command).ok()
13148    }
13149
13150    async fn try_exec(&self, command: LanguageServerBinary) -> Result<()> {
13151        let working_dir = self.worktree_root_path();
13152        let output = util::command::new_smol_command(&command.path)
13153            .args(command.arguments)
13154            .envs(command.env.clone().unwrap_or_default())
13155            .current_dir(working_dir)
13156            .output()
13157            .await?;
13158
13159        anyhow::ensure!(
13160            output.status.success(),
13161            "{}, stdout: {:?}, stderr: {:?}",
13162            output.status,
13163            String::from_utf8_lossy(&output.stdout),
13164            String::from_utf8_lossy(&output.stderr)
13165        );
13166        Ok(())
13167    }
13168
13169    fn update_status(&self, server_name: LanguageServerName, status: language::BinaryStatus) {
13170        self.language_registry
13171            .update_lsp_binary_status(server_name, status);
13172    }
13173
13174    fn registered_lsp_adapters(&self) -> Vec<Arc<dyn LspAdapter>> {
13175        self.language_registry
13176            .all_lsp_adapters()
13177            .into_iter()
13178            .map(|adapter| adapter.adapter.clone() as Arc<dyn LspAdapter>)
13179            .collect()
13180    }
13181
13182    async fn language_server_download_dir(&self, name: &LanguageServerName) -> Option<Arc<Path>> {
13183        let dir = self.language_registry.language_server_download_dir(name)?;
13184
13185        if !dir.exists() {
13186            smol::fs::create_dir_all(&dir)
13187                .await
13188                .context("failed to create container directory")
13189                .log_err()?;
13190        }
13191
13192        Some(dir)
13193    }
13194
13195    async fn read_text_file(&self, path: PathBuf) -> Result<String> {
13196        let entry = self
13197            .worktree
13198            .entry_for_path(&path)
13199            .with_context(|| format!("no worktree entry for path {path:?}"))?;
13200        let abs_path = self
13201            .worktree
13202            .absolutize(&entry.path)
13203            .with_context(|| format!("cannot absolutize path {path:?}"))?;
13204
13205        self.fs.load(&abs_path).await
13206    }
13207}
13208
13209async fn populate_labels_for_symbols(
13210    symbols: Vec<CoreSymbol>,
13211    language_registry: &Arc<LanguageRegistry>,
13212    lsp_adapter: Option<Arc<CachedLspAdapter>>,
13213    output: &mut Vec<Symbol>,
13214) {
13215    #[allow(clippy::mutable_key_type)]
13216    let mut symbols_by_language = HashMap::<Option<Arc<Language>>, Vec<CoreSymbol>>::default();
13217
13218    let mut unknown_paths = BTreeSet::new();
13219    for symbol in symbols {
13220        let language = language_registry
13221            .language_for_file_path(&symbol.path.path)
13222            .await
13223            .ok()
13224            .or_else(|| {
13225                unknown_paths.insert(symbol.path.path.clone());
13226                None
13227            });
13228        symbols_by_language
13229            .entry(language)
13230            .or_default()
13231            .push(symbol);
13232    }
13233
13234    for unknown_path in unknown_paths {
13235        log::info!(
13236            "no language found for symbol path {}",
13237            unknown_path.display()
13238        );
13239    }
13240
13241    let mut label_params = Vec::new();
13242    for (language, mut symbols) in symbols_by_language {
13243        label_params.clear();
13244        label_params.extend(
13245            symbols
13246                .iter_mut()
13247                .map(|symbol| (mem::take(&mut symbol.name), symbol.kind)),
13248        );
13249
13250        let mut labels = Vec::new();
13251        if let Some(language) = language {
13252            let lsp_adapter = lsp_adapter.clone().or_else(|| {
13253                language_registry
13254                    .lsp_adapters(&language.name())
13255                    .first()
13256                    .cloned()
13257            });
13258            if let Some(lsp_adapter) = lsp_adapter {
13259                labels = lsp_adapter
13260                    .labels_for_symbols(&label_params, &language)
13261                    .await
13262                    .log_err()
13263                    .unwrap_or_default();
13264            }
13265        }
13266
13267        for ((symbol, (name, _)), label) in symbols
13268            .into_iter()
13269            .zip(label_params.drain(..))
13270            .zip(labels.into_iter().chain(iter::repeat(None)))
13271        {
13272            output.push(Symbol {
13273                language_server_name: symbol.language_server_name,
13274                source_worktree_id: symbol.source_worktree_id,
13275                source_language_server_id: symbol.source_language_server_id,
13276                path: symbol.path,
13277                label: label.unwrap_or_else(|| CodeLabel::plain(name.clone(), None)),
13278                name,
13279                kind: symbol.kind,
13280                range: symbol.range,
13281                signature: symbol.signature,
13282            });
13283        }
13284    }
13285}
13286
13287fn include_text(server: &lsp::LanguageServer) -> Option<bool> {
13288    let dyn_caps = server.dynamic_capabilities();
13289    if let Some(map) = dyn_caps.text_document_sync_did_save.as_ref() {
13290        if !map.is_empty() {
13291            let any_true = map.values().any(|opts| opts.include_text.unwrap_or(false));
13292            return Some(any_true);
13293        }
13294    }
13295    match server.capabilities().text_document_sync.as_ref()? {
13296        lsp::TextDocumentSyncCapability::Options(opts) => match opts.save.as_ref()? {
13297            // Server wants didSave but didn't specify includeText.
13298            lsp::TextDocumentSyncSaveOptions::Supported(true) => Some(false),
13299            // Server doesn't want didSave at all.
13300            lsp::TextDocumentSyncSaveOptions::Supported(false) => None,
13301            // Server provided SaveOptions.
13302            lsp::TextDocumentSyncSaveOptions::SaveOptions(save_options) => {
13303                Some(save_options.include_text.unwrap_or(false))
13304            }
13305        },
13306        // We do not have any save info. Kind affects didChange only.
13307        lsp::TextDocumentSyncCapability::Kind(_) => None,
13308    }
13309}
13310
13311/// Completion items are displayed in a `UniformList`.
13312/// Usually, those items are single-line strings, but in LSP responses,
13313/// completion items `label`, `detail` and `label_details.description` may contain newlines or long spaces.
13314/// Many language plugins construct these items by joining these parts together, and we may use `CodeLabel::fallback_for_completion` that uses `label` at least.
13315/// All that may lead to a newline being inserted into resulting `CodeLabel.text`, which will force `UniformList` to bloat each entry to occupy more space,
13316/// breaking the completions menu presentation.
13317///
13318/// Sanitize the text to ensure there are no newlines, or, if there are some, remove them and also remove long space sequences if there were newlines.
13319fn ensure_uniform_list_compatible_label(label: &mut CodeLabel) {
13320    let mut new_text = String::with_capacity(label.text.len());
13321    let mut offset_map = vec![0; label.text.len() + 1];
13322    let mut last_char_was_space = false;
13323    let mut new_idx = 0;
13324    let chars = label.text.char_indices().fuse();
13325    let mut newlines_removed = false;
13326
13327    for (idx, c) in chars {
13328        offset_map[idx] = new_idx;
13329
13330        match c {
13331            '\n' if last_char_was_space => {
13332                newlines_removed = true;
13333            }
13334            '\t' | ' ' if last_char_was_space => {}
13335            '\n' if !last_char_was_space => {
13336                new_text.push(' ');
13337                new_idx += 1;
13338                last_char_was_space = true;
13339                newlines_removed = true;
13340            }
13341            ' ' | '\t' => {
13342                new_text.push(' ');
13343                new_idx += 1;
13344                last_char_was_space = true;
13345            }
13346            _ => {
13347                new_text.push(c);
13348                new_idx += c.len_utf8();
13349                last_char_was_space = false;
13350            }
13351        }
13352    }
13353    offset_map[label.text.len()] = new_idx;
13354
13355    // Only modify the label if newlines were removed.
13356    if !newlines_removed {
13357        return;
13358    }
13359
13360    let last_index = new_idx;
13361    let mut run_ranges_errors = Vec::new();
13362    label.runs.retain_mut(|(range, _)| {
13363        match offset_map.get(range.start) {
13364            Some(&start) => range.start = start,
13365            None => {
13366                run_ranges_errors.push(range.clone());
13367                return false;
13368            }
13369        }
13370
13371        match offset_map.get(range.end) {
13372            Some(&end) => range.end = end,
13373            None => {
13374                run_ranges_errors.push(range.clone());
13375                range.end = last_index;
13376            }
13377        }
13378        true
13379    });
13380    if !run_ranges_errors.is_empty() {
13381        log::error!(
13382            "Completion label has errors in its run ranges: {run_ranges_errors:?}, label text: {}",
13383            label.text
13384        );
13385    }
13386
13387    let mut wrong_filter_range = None;
13388    if label.filter_range == (0..label.text.len()) {
13389        label.filter_range = 0..new_text.len();
13390    } else {
13391        let mut original_filter_range = Some(label.filter_range.clone());
13392        match offset_map.get(label.filter_range.start) {
13393            Some(&start) => label.filter_range.start = start,
13394            None => {
13395                wrong_filter_range = original_filter_range.take();
13396                label.filter_range.start = last_index;
13397            }
13398        }
13399
13400        match offset_map.get(label.filter_range.end) {
13401            Some(&end) => label.filter_range.end = end,
13402            None => {
13403                wrong_filter_range = original_filter_range.take();
13404                label.filter_range.end = last_index;
13405            }
13406        }
13407    }
13408    if let Some(wrong_filter_range) = wrong_filter_range {
13409        log::error!(
13410            "Completion label has an invalid filter range: {wrong_filter_range:?}, label text: {}",
13411            label.text
13412        );
13413    }
13414
13415    label.text = new_text;
13416}
13417
13418#[cfg(test)]
13419mod tests {
13420    use language::HighlightId;
13421
13422    use super::*;
13423
13424    #[test]
13425    fn test_glob_literal_prefix() {
13426        assert_eq!(glob_literal_prefix(Path::new("**/*.js")), Path::new(""));
13427        assert_eq!(
13428            glob_literal_prefix(Path::new("node_modules/**/*.js")),
13429            Path::new("node_modules")
13430        );
13431        assert_eq!(
13432            glob_literal_prefix(Path::new("foo/{bar,baz}.js")),
13433            Path::new("foo")
13434        );
13435        assert_eq!(
13436            glob_literal_prefix(Path::new("foo/bar/baz.js")),
13437            Path::new("foo/bar/baz.js")
13438        );
13439
13440        #[cfg(target_os = "windows")]
13441        {
13442            assert_eq!(glob_literal_prefix(Path::new("**\\*.js")), Path::new(""));
13443            assert_eq!(
13444                glob_literal_prefix(Path::new("node_modules\\**/*.js")),
13445                Path::new("node_modules")
13446            );
13447            assert_eq!(
13448                glob_literal_prefix(Path::new("foo/{bar,baz}.js")),
13449                Path::new("foo")
13450            );
13451            assert_eq!(
13452                glob_literal_prefix(Path::new("foo\\bar\\baz.js")),
13453                Path::new("foo/bar/baz.js")
13454            );
13455        }
13456    }
13457
13458    #[test]
13459    fn test_multi_len_chars_normalization() {
13460        let mut label = CodeLabel {
13461            text: "myElˇ (parameter) myElˇ: {\n    foo: string;\n}".to_string(),
13462            runs: vec![(0..6, HighlightId(1))],
13463            filter_range: 0..6,
13464        };
13465        ensure_uniform_list_compatible_label(&mut label);
13466        assert_eq!(
13467            label,
13468            CodeLabel {
13469                text: "myElˇ (parameter) myElˇ: { foo: string; }".to_string(),
13470                runs: vec![(0..6, HighlightId(1))],
13471                filter_range: 0..6,
13472            }
13473        );
13474    }
13475}