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