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