lsp_store.rs

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