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