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 log_store;
   15pub mod lsp_ext_command;
   16pub mod rust_analyzer_ext;
   17pub mod vue_language_server_ext;
   18
   19mod inlay_hint_cache;
   20
   21use self::inlay_hint_cache::BufferInlayHints;
   22use crate::{
   23    CodeAction, ColorPresentation, Completion, CompletionDisplayOptions, CompletionResponse,
   24    CompletionSource, CoreCompletion, DocumentColor, Hover, InlayHint, InlayId, LocationLink,
   25    LspAction, LspPullDiagnostics, ManifestProvidersStore, Project, ProjectItem, ProjectPath,
   26    ProjectTransaction, PulledDiagnostics, ResolveState, Symbol,
   27    buffer_store::{BufferStore, BufferStoreEvent},
   28    environment::ProjectEnvironment,
   29    lsp_command::{self, *},
   30    lsp_store::{
   31        self,
   32        log_store::{GlobalLogStore, LanguageServerKind},
   33    },
   34    manifest_tree::{
   35        LanguageServerTree, LanguageServerTreeNode, LaunchDisposition, ManifestQueryDelegate,
   36        ManifestTree,
   37    },
   38    prettier_store::{self, PrettierStore, PrettierStoreEvent},
   39    project_settings::{LspSettings, ProjectSettings},
   40    toolchain_store::{LocalToolchainStore, ToolchainStoreEvent},
   41    trusted_worktrees::{PathTrust, TrustedWorktrees, TrustedWorktreesEvent},
   42    worktree_store::{WorktreeStore, WorktreeStoreEvent},
   43    yarn::YarnPathStore,
   44};
   45use anyhow::{Context as _, Result, anyhow};
   46use async_trait::async_trait;
   47use client::{TypedEnvelope, proto};
   48use clock::Global;
   49use collections::{BTreeMap, BTreeSet, HashMap, HashSet, btree_map};
   50use futures::{
   51    AsyncWriteExt, Future, FutureExt, StreamExt,
   52    future::{Either, Shared, join_all, pending, select},
   53    select, select_biased,
   54    stream::FuturesUnordered,
   55};
   56use globset::{Glob, GlobBuilder, GlobMatcher, GlobSet, GlobSetBuilder};
   57use gpui::{
   58    App, AppContext, AsyncApp, Context, Entity, EventEmitter, PromptLevel, SharedString,
   59    Subscription, Task, WeakEntity,
   60};
   61use http_client::HttpClient;
   62use itertools::Itertools as _;
   63use language::{
   64    Bias, BinaryStatus, Buffer, BufferRow, BufferSnapshot, CachedLspAdapter, CodeLabel, Diagnostic,
   65    DiagnosticEntry, DiagnosticSet, DiagnosticSourceKind, Diff, File as _, Language, LanguageName,
   66    LanguageRegistry, LocalFile, LspAdapter, LspAdapterDelegate, LspInstaller, ManifestDelegate,
   67    ManifestName, Patch, PointUtf16, TextBufferSnapshot, ToOffset, ToPointUtf16, Toolchain,
   68    Transaction, Unclipped,
   69    language_settings::{FormatOnSave, Formatter, LanguageSettings, language_settings},
   70    point_to_lsp,
   71    proto::{
   72        deserialize_anchor, deserialize_lsp_edit, deserialize_version, serialize_anchor,
   73        serialize_lsp_edit, serialize_version,
   74    },
   75    range_from_lsp, range_to_lsp,
   76    row_chunk::RowChunk,
   77};
   78use lsp::{
   79    AdapterServerCapabilities, CodeActionKind, CompletionContext, CompletionOptions,
   80    DiagnosticServerCapabilities, DiagnosticSeverity, DiagnosticTag,
   81    DidChangeWatchedFilesRegistrationOptions, Edit, FileOperationFilter, FileOperationPatternKind,
   82    FileOperationRegistrationOptions, FileRename, FileSystemWatcher, LSP_REQUEST_TIMEOUT,
   83    LanguageServer, LanguageServerBinary, LanguageServerBinaryOptions, LanguageServerId,
   84    LanguageServerName, LanguageServerSelector, LspRequestFuture, MessageActionItem, MessageType,
   85    OneOf, RenameFilesParams, SymbolKind, TextDocumentSyncSaveOptions, TextEdit, Uri,
   86    WillRenameFiles, WorkDoneProgressCancelParams, WorkspaceFolder, notification::DidRenameFiles,
   87};
   88use node_runtime::read_package_installed_version;
   89use parking_lot::Mutex;
   90use postage::{mpsc, sink::Sink, stream::Stream, watch};
   91use rand::prelude::*;
   92use rpc::{
   93    AnyProtoClient, ErrorCode, ErrorExt as _,
   94    proto::{LspRequestId, LspRequestMessage as _},
   95};
   96use serde::Serialize;
   97use serde_json::Value;
   98use settings::{Settings, SettingsLocation, SettingsStore};
   99use sha2::{Digest, Sha256};
  100use snippet::Snippet;
  101use std::{
  102    any::TypeId,
  103    borrow::Cow,
  104    cell::RefCell,
  105    cmp::{Ordering, Reverse},
  106    collections::hash_map,
  107    convert::TryInto,
  108    ffi::OsStr,
  109    future::ready,
  110    iter, mem,
  111    ops::{ControlFlow, Range},
  112    path::{self, Path, PathBuf},
  113    pin::pin,
  114    rc::Rc,
  115    sync::{
  116        Arc,
  117        atomic::{self, AtomicUsize},
  118    },
  119    time::{Duration, Instant},
  120    vec,
  121};
  122use sum_tree::Dimensions;
  123use text::{Anchor, BufferId, LineEnding, OffsetRangeExt, ToPoint as _};
  124
  125use util::{
  126    ConnectionResult, ResultExt as _, debug_panic, defer, maybe, merge_json_value_into,
  127    paths::{PathStyle, SanitizedPath},
  128    post_inc,
  129    rel_path::RelPath,
  130};
  131
  132pub use fs::*;
  133pub use language::Location;
  134pub use lsp_store::inlay_hint_cache::{CacheInlayHints, InvalidationStrategy};
  135#[cfg(any(test, feature = "test-support"))]
  136pub use prettier::FORMAT_SUFFIX as TEST_PRETTIER_FORMAT_SUFFIX;
  137pub use worktree::{
  138    Entry, EntryKind, FS_WATCH_LATENCY, File, LocalWorktree, PathChange, ProjectEntryId,
  139    UpdatedEntriesSet, UpdatedGitRepositoriesSet, Worktree, WorktreeId, WorktreeSettings,
  140};
  141
  142const SERVER_LAUNCHING_BEFORE_SHUTDOWN_TIMEOUT: Duration = Duration::from_secs(5);
  143pub const SERVER_PROGRESS_THROTTLE_TIMEOUT: Duration = Duration::from_millis(100);
  144const WORKSPACE_DIAGNOSTICS_TOKEN_START: &str = "id:";
  145const SERVER_DOWNLOAD_TIMEOUT: Duration = Duration::from_secs(10);
  146
  147#[derive(Debug, Clone, PartialEq, Eq, PartialOrd, Ord, Hash, Serialize)]
  148pub enum ProgressToken {
  149    Number(i32),
  150    String(SharedString),
  151}
  152
  153impl std::fmt::Display for ProgressToken {
  154    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
  155        match self {
  156            Self::Number(number) => write!(f, "{number}"),
  157            Self::String(string) => write!(f, "{string}"),
  158        }
  159    }
  160}
  161
  162impl ProgressToken {
  163    fn from_lsp(value: lsp::NumberOrString) -> Self {
  164        match value {
  165            lsp::NumberOrString::Number(number) => Self::Number(number),
  166            lsp::NumberOrString::String(string) => Self::String(SharedString::new(string)),
  167        }
  168    }
  169
  170    fn to_lsp(&self) -> lsp::NumberOrString {
  171        match self {
  172            Self::Number(number) => lsp::NumberOrString::Number(*number),
  173            Self::String(string) => lsp::NumberOrString::String(string.to_string()),
  174        }
  175    }
  176
  177    fn from_proto(value: proto::ProgressToken) -> Option<Self> {
  178        Some(match value.value? {
  179            proto::progress_token::Value::Number(number) => Self::Number(number),
  180            proto::progress_token::Value::String(string) => Self::String(SharedString::new(string)),
  181        })
  182    }
  183
  184    fn to_proto(&self) -> proto::ProgressToken {
  185        proto::ProgressToken {
  186            value: Some(match self {
  187                Self::Number(number) => proto::progress_token::Value::Number(*number),
  188                Self::String(string) => proto::progress_token::Value::String(string.to_string()),
  189            }),
  190        }
  191    }
  192}
  193
  194#[derive(Debug, Clone, Copy, PartialEq, Eq)]
  195pub enum FormatTrigger {
  196    Save,
  197    Manual,
  198}
  199
  200pub enum LspFormatTarget {
  201    Buffers,
  202    Ranges(BTreeMap<BufferId, Vec<Range<Anchor>>>),
  203}
  204
  205#[derive(Clone, PartialEq, Eq, Hash)]
  206pub struct OpenLspBufferHandle(Entity<OpenLspBuffer>);
  207
  208struct OpenLspBuffer(Entity<Buffer>);
  209
  210impl FormatTrigger {
  211    fn from_proto(value: i32) -> FormatTrigger {
  212        match value {
  213            0 => FormatTrigger::Save,
  214            1 => FormatTrigger::Manual,
  215            _ => FormatTrigger::Save,
  216        }
  217    }
  218}
  219
  220#[derive(Clone)]
  221struct UnifiedLanguageServer {
  222    id: LanguageServerId,
  223    project_roots: HashSet<Arc<RelPath>>,
  224}
  225
  226#[derive(Clone, Debug, Hash, PartialEq, Eq)]
  227struct LanguageServerSeed {
  228    worktree_id: WorktreeId,
  229    name: LanguageServerName,
  230    toolchain: Option<Toolchain>,
  231    settings: Arc<LspSettings>,
  232}
  233
  234#[derive(Debug)]
  235pub struct DocumentDiagnosticsUpdate<'a, D> {
  236    pub diagnostics: D,
  237    pub result_id: Option<SharedString>,
  238    pub registration_id: Option<SharedString>,
  239    pub server_id: LanguageServerId,
  240    pub disk_based_sources: Cow<'a, [String]>,
  241}
  242
  243pub struct DocumentDiagnostics {
  244    diagnostics: Vec<DiagnosticEntry<Unclipped<PointUtf16>>>,
  245    document_abs_path: PathBuf,
  246    version: Option<i32>,
  247}
  248
  249#[derive(Default, Debug)]
  250struct DynamicRegistrations {
  251    did_change_watched_files: HashMap<String, Vec<FileSystemWatcher>>,
  252    diagnostics: HashMap<Option<String>, DiagnosticServerCapabilities>,
  253}
  254
  255pub struct LocalLspStore {
  256    weak: WeakEntity<LspStore>,
  257    worktree_store: Entity<WorktreeStore>,
  258    toolchain_store: Entity<LocalToolchainStore>,
  259    http_client: Arc<dyn HttpClient>,
  260    environment: Entity<ProjectEnvironment>,
  261    fs: Arc<dyn Fs>,
  262    languages: Arc<LanguageRegistry>,
  263    language_server_ids: HashMap<LanguageServerSeed, UnifiedLanguageServer>,
  264    yarn: Entity<YarnPathStore>,
  265    pub language_servers: HashMap<LanguageServerId, LanguageServerState>,
  266    buffers_being_formatted: HashSet<BufferId>,
  267    last_workspace_edits_by_language_server: HashMap<LanguageServerId, ProjectTransaction>,
  268    language_server_watched_paths: HashMap<LanguageServerId, LanguageServerWatchedPaths>,
  269    watched_manifest_filenames: HashSet<ManifestName>,
  270    language_server_paths_watched_for_rename:
  271        HashMap<LanguageServerId, RenamePathsWatchedForServer>,
  272    language_server_dynamic_registrations: HashMap<LanguageServerId, DynamicRegistrations>,
  273    supplementary_language_servers:
  274        HashMap<LanguageServerId, (LanguageServerName, Arc<LanguageServer>)>,
  275    prettier_store: Entity<PrettierStore>,
  276    next_diagnostic_group_id: usize,
  277    diagnostics: HashMap<
  278        WorktreeId,
  279        HashMap<
  280            Arc<RelPath>,
  281            Vec<(
  282                LanguageServerId,
  283                Vec<DiagnosticEntry<Unclipped<PointUtf16>>>,
  284            )>,
  285        >,
  286    >,
  287    buffer_snapshots: HashMap<BufferId, HashMap<LanguageServerId, Vec<LspBufferSnapshot>>>, // buffer_id -> server_id -> vec of snapshots
  288    _subscription: gpui::Subscription,
  289    lsp_tree: LanguageServerTree,
  290    registered_buffers: HashMap<BufferId, usize>,
  291    buffers_opened_in_servers: HashMap<BufferId, HashSet<LanguageServerId>>,
  292    buffer_pull_diagnostics_result_ids: HashMap<
  293        LanguageServerId,
  294        HashMap<Option<SharedString>, HashMap<PathBuf, Option<SharedString>>>,
  295    >,
  296    workspace_pull_diagnostics_result_ids: HashMap<
  297        LanguageServerId,
  298        HashMap<Option<SharedString>, HashMap<PathBuf, Option<SharedString>>>,
  299    >,
  300    restricted_worktrees_tasks: HashMap<WorktreeId, (Subscription, watch::Receiver<bool>)>,
  301}
  302
  303impl LocalLspStore {
  304    /// Returns the running language server for the given ID. Note if the language server is starting, it will not be returned.
  305    pub fn running_language_server_for_id(
  306        &self,
  307        id: LanguageServerId,
  308    ) -> Option<&Arc<LanguageServer>> {
  309        let language_server_state = self.language_servers.get(&id)?;
  310
  311        match language_server_state {
  312            LanguageServerState::Running { server, .. } => Some(server),
  313            LanguageServerState::Starting { .. } => None,
  314        }
  315    }
  316
  317    fn get_or_insert_language_server(
  318        &mut self,
  319        worktree_handle: &Entity<Worktree>,
  320        delegate: Arc<LocalLspAdapterDelegate>,
  321        disposition: &Arc<LaunchDisposition>,
  322        language_name: &LanguageName,
  323        cx: &mut App,
  324    ) -> LanguageServerId {
  325        let key = LanguageServerSeed {
  326            worktree_id: worktree_handle.read(cx).id(),
  327            name: disposition.server_name.clone(),
  328            settings: disposition.settings.clone(),
  329            toolchain: disposition.toolchain.clone(),
  330        };
  331        if let Some(state) = self.language_server_ids.get_mut(&key) {
  332            state.project_roots.insert(disposition.path.path.clone());
  333            state.id
  334        } else {
  335            let adapter = self
  336                .languages
  337                .lsp_adapters(language_name)
  338                .into_iter()
  339                .find(|adapter| adapter.name() == disposition.server_name)
  340                .expect("To find LSP adapter");
  341            let new_language_server_id = self.start_language_server(
  342                worktree_handle,
  343                delegate,
  344                adapter,
  345                disposition.settings.clone(),
  346                key.clone(),
  347                cx,
  348            );
  349            if let Some(state) = self.language_server_ids.get_mut(&key) {
  350                state.project_roots.insert(disposition.path.path.clone());
  351            } else {
  352                debug_assert!(
  353                    false,
  354                    "Expected `start_language_server` to ensure that `key` exists in a map"
  355                );
  356            }
  357            new_language_server_id
  358        }
  359    }
  360
  361    fn start_language_server(
  362        &mut self,
  363        worktree_handle: &Entity<Worktree>,
  364        delegate: Arc<LocalLspAdapterDelegate>,
  365        adapter: Arc<CachedLspAdapter>,
  366        settings: Arc<LspSettings>,
  367        key: LanguageServerSeed,
  368        cx: &mut App,
  369    ) -> LanguageServerId {
  370        let worktree = worktree_handle.read(cx);
  371
  372        let worktree_id = worktree.id();
  373        let worktree_abs_path = worktree.abs_path();
  374        let toolchain = key.toolchain.clone();
  375        let override_options = settings.initialization_options.clone();
  376
  377        let stderr_capture = Arc::new(Mutex::new(Some(String::new())));
  378
  379        let server_id = self.languages.next_language_server_id();
  380        log::trace!(
  381            "attempting to start language server {:?}, path: {worktree_abs_path:?}, id: {server_id}",
  382            adapter.name.0
  383        );
  384
  385        let wait_until_worktree_trust =
  386            TrustedWorktrees::try_get_global(cx).and_then(|trusted_worktrees| {
  387                let can_trust = trusted_worktrees.update(cx, |trusted_worktrees, cx| {
  388                    trusted_worktrees.can_trust(&self.worktree_store, worktree_id, cx)
  389                });
  390                if can_trust {
  391                    self.restricted_worktrees_tasks.remove(&worktree_id);
  392                    None
  393                } else {
  394                    match self.restricted_worktrees_tasks.entry(worktree_id) {
  395                        hash_map::Entry::Occupied(o) => Some(o.get().1.clone()),
  396                        hash_map::Entry::Vacant(v) => {
  397                            let (mut tx, rx) = watch::channel::<bool>();
  398                            let lsp_store = self.weak.clone();
  399                            let subscription = cx.subscribe(&trusted_worktrees, move |_, e, cx| {
  400                                if let TrustedWorktreesEvent::Trusted(_, trusted_paths) = e {
  401                                    if trusted_paths.contains(&PathTrust::Worktree(worktree_id)) {
  402                                        tx.blocking_send(true).ok();
  403                                        lsp_store
  404                                            .update(cx, |lsp_store, _| {
  405                                                if let Some(local_lsp_store) =
  406                                                    lsp_store.as_local_mut()
  407                                                {
  408                                                    local_lsp_store
  409                                                        .restricted_worktrees_tasks
  410                                                        .remove(&worktree_id);
  411                                                }
  412                                            })
  413                                            .ok();
  414                                    }
  415                                }
  416                            });
  417                            v.insert((subscription, rx.clone()));
  418                            Some(rx)
  419                        }
  420                    }
  421                }
  422            });
  423        let update_binary_status = wait_until_worktree_trust.is_none();
  424
  425        let binary = self.get_language_server_binary(
  426            worktree_abs_path.clone(),
  427            adapter.clone(),
  428            settings,
  429            toolchain.clone(),
  430            delegate.clone(),
  431            true,
  432            wait_until_worktree_trust,
  433            cx,
  434        );
  435        let pending_workspace_folders = Arc::<Mutex<BTreeSet<Uri>>>::default();
  436
  437        let pending_server = cx.spawn({
  438            let adapter = adapter.clone();
  439            let server_name = adapter.name.clone();
  440            let stderr_capture = stderr_capture.clone();
  441            #[cfg(any(test, feature = "test-support"))]
  442            let lsp_store = self.weak.clone();
  443            let pending_workspace_folders = pending_workspace_folders.clone();
  444            async move |cx| {
  445                let binary = binary.await?;
  446                #[cfg(any(test, feature = "test-support"))]
  447                if let Some(server) = lsp_store
  448                    .update(&mut cx.clone(), |this, cx| {
  449                        this.languages.create_fake_language_server(
  450                            server_id,
  451                            &server_name,
  452                            binary.clone(),
  453                            &mut cx.to_async(),
  454                        )
  455                    })
  456                    .ok()
  457                    .flatten()
  458                {
  459                    return Ok(server);
  460                }
  461
  462                let code_action_kinds = adapter.code_action_kinds();
  463                lsp::LanguageServer::new(
  464                    stderr_capture,
  465                    server_id,
  466                    server_name,
  467                    binary,
  468                    &worktree_abs_path,
  469                    code_action_kinds,
  470                    Some(pending_workspace_folders),
  471                    cx,
  472                )
  473            }
  474        });
  475
  476        let startup = {
  477            let server_name = adapter.name.0.clone();
  478            let delegate = delegate as Arc<dyn LspAdapterDelegate>;
  479            let key = key.clone();
  480            let adapter = adapter.clone();
  481            let lsp_store = self.weak.clone();
  482            let pending_workspace_folders = pending_workspace_folders.clone();
  483
  484            let pull_diagnostics = ProjectSettings::get_global(cx)
  485                .diagnostics
  486                .lsp_pull_diagnostics
  487                .enabled;
  488            cx.spawn(async move |cx| {
  489                let result = async {
  490                    let language_server = pending_server.await?;
  491
  492                    let workspace_config = Self::workspace_configuration_for_adapter(
  493                        adapter.adapter.clone(),
  494                        &delegate,
  495                        toolchain,
  496                        None,
  497                        cx,
  498                    )
  499                    .await?;
  500
  501                    let mut initialization_options = Self::initialization_options_for_adapter(
  502                        adapter.adapter.clone(),
  503                        &delegate,
  504                    )
  505                    .await?;
  506
  507                    match (&mut initialization_options, override_options) {
  508                        (Some(initialization_options), Some(override_options)) => {
  509                            merge_json_value_into(override_options, initialization_options);
  510                        }
  511                        (None, override_options) => initialization_options = override_options,
  512                        _ => {}
  513                    }
  514
  515                    let initialization_params = cx.update(|cx| {
  516                        let mut params =
  517                            language_server.default_initialize_params(pull_diagnostics, cx);
  518                        params.initialization_options = initialization_options;
  519                        adapter.adapter.prepare_initialize_params(params, cx)
  520                    })??;
  521
  522                    Self::setup_lsp_messages(
  523                        lsp_store.clone(),
  524                        &language_server,
  525                        delegate.clone(),
  526                        adapter.clone(),
  527                    );
  528
  529                    let did_change_configuration_params = lsp::DidChangeConfigurationParams {
  530                        settings: workspace_config,
  531                    };
  532                    let language_server = cx
  533                        .update(|cx| {
  534                            language_server.initialize(
  535                                initialization_params,
  536                                Arc::new(did_change_configuration_params.clone()),
  537                                cx,
  538                            )
  539                        })?
  540                        .await
  541                        .inspect_err(|_| {
  542                            if let Some(lsp_store) = lsp_store.upgrade() {
  543                                lsp_store
  544                                    .update(cx, |lsp_store, cx| {
  545                                        lsp_store.cleanup_lsp_data(server_id);
  546                                        cx.emit(LspStoreEvent::LanguageServerRemoved(server_id))
  547                                    })
  548                                    .ok();
  549                            }
  550                        })?;
  551
  552                    language_server.notify::<lsp::notification::DidChangeConfiguration>(
  553                        did_change_configuration_params,
  554                    )?;
  555
  556                    anyhow::Ok(language_server)
  557                }
  558                .await;
  559
  560                match result {
  561                    Ok(server) => {
  562                        lsp_store
  563                            .update(cx, |lsp_store, cx| {
  564                                lsp_store.insert_newly_running_language_server(
  565                                    adapter,
  566                                    server.clone(),
  567                                    server_id,
  568                                    key,
  569                                    pending_workspace_folders,
  570                                    cx,
  571                                );
  572                            })
  573                            .ok();
  574                        stderr_capture.lock().take();
  575                        Some(server)
  576                    }
  577
  578                    Err(err) => {
  579                        let log = stderr_capture.lock().take().unwrap_or_default();
  580                        delegate.update_status(
  581                            adapter.name(),
  582                            BinaryStatus::Failed {
  583                                error: if log.is_empty() {
  584                                    format!("{err:#}")
  585                                } else {
  586                                    format!("{err:#}\n-- stderr --\n{log}")
  587                                },
  588                            },
  589                        );
  590                        log::error!("Failed to start language server {server_name:?}: {err:?}");
  591                        if !log.is_empty() {
  592                            log::error!("server stderr: {log}");
  593                        }
  594                        None
  595                    }
  596                }
  597            })
  598        };
  599        let state = LanguageServerState::Starting {
  600            startup,
  601            pending_workspace_folders,
  602        };
  603
  604        if update_binary_status {
  605            self.languages
  606                .update_lsp_binary_status(adapter.name(), BinaryStatus::Starting);
  607        }
  608
  609        self.language_servers.insert(server_id, state);
  610        self.language_server_ids
  611            .entry(key)
  612            .or_insert(UnifiedLanguageServer {
  613                id: server_id,
  614                project_roots: Default::default(),
  615            });
  616        server_id
  617    }
  618
  619    fn get_language_server_binary(
  620        &self,
  621        worktree_abs_path: Arc<Path>,
  622        adapter: Arc<CachedLspAdapter>,
  623        settings: Arc<LspSettings>,
  624        toolchain: Option<Toolchain>,
  625        delegate: Arc<dyn LspAdapterDelegate>,
  626        allow_binary_download: bool,
  627        wait_until_worktree_trust: Option<watch::Receiver<bool>>,
  628        cx: &mut App,
  629    ) -> Task<Result<LanguageServerBinary>> {
  630        if let Some(settings) = &settings.binary
  631            && let Some(path) = settings.path.as_ref().map(PathBuf::from)
  632        {
  633            let settings = settings.clone();
  634            let languages = self.languages.clone();
  635            return cx.background_spawn(async move {
  636                if let Some(mut wait_until_worktree_trust) = wait_until_worktree_trust {
  637                    let already_trusted =  *wait_until_worktree_trust.borrow();
  638                    if !already_trusted {
  639                        log::info!(
  640                            "Waiting for worktree {worktree_abs_path:?} to be trusted, before starting language server {}",
  641                            adapter.name(),
  642                        );
  643                        while let Some(worktree_trusted) = wait_until_worktree_trust.recv().await {
  644                            if worktree_trusted {
  645                                break;
  646                            }
  647                        }
  648                        log::info!(
  649                            "Worktree {worktree_abs_path:?} is trusted, starting language server {}",
  650                            adapter.name(),
  651                        );
  652                    }
  653                    languages
  654                        .update_lsp_binary_status(adapter.name(), BinaryStatus::Starting);
  655                }
  656                let mut env = delegate.shell_env().await;
  657                env.extend(settings.env.unwrap_or_default());
  658
  659                Ok(LanguageServerBinary {
  660                    path: delegate.resolve_executable_path(path),
  661                    env: Some(env),
  662                    arguments: settings
  663                        .arguments
  664                        .unwrap_or_default()
  665                        .iter()
  666                        .map(Into::into)
  667                        .collect(),
  668                })
  669            });
  670        }
  671        let lsp_binary_options = LanguageServerBinaryOptions {
  672            allow_path_lookup: !settings
  673                .binary
  674                .as_ref()
  675                .and_then(|b| b.ignore_system_version)
  676                .unwrap_or_default(),
  677            allow_binary_download,
  678            pre_release: settings
  679                .fetch
  680                .as_ref()
  681                .and_then(|f| f.pre_release)
  682                .unwrap_or(false),
  683        };
  684
  685        cx.spawn(async move |cx| {
  686            if let Some(mut wait_until_worktree_trust) = wait_until_worktree_trust {
  687                let already_trusted =  *wait_until_worktree_trust.borrow();
  688                if !already_trusted {
  689                    log::info!(
  690                        "Waiting for worktree {worktree_abs_path:?} to be trusted, before starting language server {}",
  691                        adapter.name(),
  692                    );
  693                    while let Some(worktree_trusted) = wait_until_worktree_trust.recv().await {
  694                        if worktree_trusted {
  695                            break;
  696                        }
  697                    }
  698                    log::info!(
  699                        "Worktree {worktree_abs_path:?} is trusted, starting language server {}",
  700                            adapter.name(),
  701                    );
  702                }
  703            }
  704
  705            let (existing_binary, maybe_download_binary) = adapter
  706                .clone()
  707                .get_language_server_command(delegate.clone(), toolchain, lsp_binary_options, cx)
  708                .await
  709                .await;
  710
  711            delegate.update_status(adapter.name.clone(), BinaryStatus::None);
  712
  713            let mut binary = match (existing_binary, maybe_download_binary) {
  714                (binary, None) => binary?,
  715                (Err(_), Some(downloader)) => downloader.await?,
  716                (Ok(existing_binary), Some(downloader)) => {
  717                    let mut download_timeout = cx
  718                        .background_executor()
  719                        .timer(SERVER_DOWNLOAD_TIMEOUT)
  720                        .fuse();
  721                    let mut downloader = downloader.fuse();
  722                    futures::select! {
  723                        _ = download_timeout => {
  724                            // Return existing binary and kick the existing work to the background.
  725                            cx.spawn(async move |_| downloader.await).detach();
  726                            Ok(existing_binary)
  727                        },
  728                        downloaded_or_existing_binary = downloader => {
  729                            // If download fails, this results in the existing binary.
  730                            downloaded_or_existing_binary
  731                        }
  732                    }?
  733                }
  734            };
  735            let mut shell_env = delegate.shell_env().await;
  736
  737            shell_env.extend(binary.env.unwrap_or_default());
  738
  739            if let Some(settings) = settings.binary.as_ref() {
  740                if let Some(arguments) = &settings.arguments {
  741                    binary.arguments = arguments.iter().map(Into::into).collect();
  742                }
  743                if let Some(env) = &settings.env {
  744                    shell_env.extend(env.iter().map(|(k, v)| (k.clone(), v.clone())));
  745                }
  746            }
  747
  748            binary.env = Some(shell_env);
  749            Ok(binary)
  750        })
  751    }
  752
  753    fn setup_lsp_messages(
  754        lsp_store: WeakEntity<LspStore>,
  755        language_server: &LanguageServer,
  756        delegate: Arc<dyn LspAdapterDelegate>,
  757        adapter: Arc<CachedLspAdapter>,
  758    ) {
  759        let name = language_server.name();
  760        let server_id = language_server.server_id();
  761        language_server
  762            .on_notification::<lsp::notification::PublishDiagnostics, _>({
  763                let adapter = adapter.clone();
  764                let this = lsp_store.clone();
  765                move |mut params, cx| {
  766                    let adapter = adapter.clone();
  767                    if let Some(this) = this.upgrade() {
  768                        this.update(cx, |this, cx| {
  769                            {
  770                                let buffer = params
  771                                    .uri
  772                                    .to_file_path()
  773                                    .map(|file_path| this.get_buffer(&file_path, cx))
  774                                    .ok()
  775                                    .flatten();
  776                                adapter.process_diagnostics(&mut params, server_id, buffer);
  777                            }
  778
  779                            this.merge_lsp_diagnostics(
  780                                DiagnosticSourceKind::Pushed,
  781                                vec![DocumentDiagnosticsUpdate {
  782                                    server_id,
  783                                    diagnostics: params,
  784                                    result_id: None,
  785                                    disk_based_sources: Cow::Borrowed(
  786                                        &adapter.disk_based_diagnostic_sources,
  787                                    ),
  788                                    registration_id: None,
  789                                }],
  790                                |_, diagnostic, cx| match diagnostic.source_kind {
  791                                    DiagnosticSourceKind::Other | DiagnosticSourceKind::Pushed => {
  792                                        adapter.retain_old_diagnostic(diagnostic, cx)
  793                                    }
  794                                    DiagnosticSourceKind::Pulled => true,
  795                                },
  796                                cx,
  797                            )
  798                            .log_err();
  799                        })
  800                        .ok();
  801                    }
  802                }
  803            })
  804            .detach();
  805        language_server
  806            .on_request::<lsp::request::WorkspaceConfiguration, _, _>({
  807                let adapter = adapter.adapter.clone();
  808                let delegate = delegate.clone();
  809                let this = lsp_store.clone();
  810                move |params, cx| {
  811                    let adapter = adapter.clone();
  812                    let delegate = delegate.clone();
  813                    let this = this.clone();
  814                    let mut cx = cx.clone();
  815                    async move {
  816                        let toolchain_for_id = this
  817                            .update(&mut cx, |this, _| {
  818                                this.as_local()?.language_server_ids.iter().find_map(
  819                                    |(seed, value)| {
  820                                        (value.id == server_id).then(|| seed.toolchain.clone())
  821                                    },
  822                                )
  823                            })?
  824                            .context("Expected the LSP store to be in a local mode")?;
  825
  826                        let mut scope_uri_to_workspace_config = BTreeMap::new();
  827                        for item in &params.items {
  828                            let scope_uri = item.scope_uri.clone();
  829                            let std::collections::btree_map::Entry::Vacant(new_scope_uri) =
  830                                scope_uri_to_workspace_config.entry(scope_uri.clone())
  831                            else {
  832                                // We've already queried workspace configuration of this URI.
  833                                continue;
  834                            };
  835                            let workspace_config = Self::workspace_configuration_for_adapter(
  836                                adapter.clone(),
  837                                &delegate,
  838                                toolchain_for_id.clone(),
  839                                scope_uri,
  840                                &mut cx,
  841                            )
  842                            .await?;
  843                            new_scope_uri.insert(workspace_config);
  844                        }
  845
  846                        Ok(params
  847                            .items
  848                            .into_iter()
  849                            .filter_map(|item| {
  850                                let workspace_config =
  851                                    scope_uri_to_workspace_config.get(&item.scope_uri)?;
  852                                if let Some(section) = &item.section {
  853                                    Some(
  854                                        workspace_config
  855                                            .get(section)
  856                                            .cloned()
  857                                            .unwrap_or(serde_json::Value::Null),
  858                                    )
  859                                } else {
  860                                    Some(workspace_config.clone())
  861                                }
  862                            })
  863                            .collect())
  864                    }
  865                }
  866            })
  867            .detach();
  868
  869        language_server
  870            .on_request::<lsp::request::WorkspaceFoldersRequest, _, _>({
  871                let this = lsp_store.clone();
  872                move |_, cx| {
  873                    let this = this.clone();
  874                    let cx = cx.clone();
  875                    async move {
  876                        let Some(server) =
  877                            this.read_with(&cx, |this, _| this.language_server_for_id(server_id))?
  878                        else {
  879                            return Ok(None);
  880                        };
  881                        let root = server.workspace_folders();
  882                        Ok(Some(
  883                            root.into_iter()
  884                                .map(|uri| WorkspaceFolder {
  885                                    uri,
  886                                    name: Default::default(),
  887                                })
  888                                .collect(),
  889                        ))
  890                    }
  891                }
  892            })
  893            .detach();
  894        // Even though we don't have handling for these requests, respond to them to
  895        // avoid stalling any language server like `gopls` which waits for a response
  896        // to these requests when initializing.
  897        language_server
  898            .on_request::<lsp::request::WorkDoneProgressCreate, _, _>({
  899                let this = lsp_store.clone();
  900                move |params, cx| {
  901                    let this = this.clone();
  902                    let mut cx = cx.clone();
  903                    async move {
  904                        this.update(&mut cx, |this, _| {
  905                            if let Some(status) = this.language_server_statuses.get_mut(&server_id)
  906                            {
  907                                status
  908                                    .progress_tokens
  909                                    .insert(ProgressToken::from_lsp(params.token));
  910                            }
  911                        })?;
  912
  913                        Ok(())
  914                    }
  915                }
  916            })
  917            .detach();
  918
  919        language_server
  920            .on_request::<lsp::request::RegisterCapability, _, _>({
  921                let lsp_store = lsp_store.clone();
  922                move |params, cx| {
  923                    let lsp_store = lsp_store.clone();
  924                    let mut cx = cx.clone();
  925                    async move {
  926                        lsp_store
  927                            .update(&mut cx, |lsp_store, cx| {
  928                                if lsp_store.as_local().is_some() {
  929                                    match lsp_store
  930                                        .register_server_capabilities(server_id, params, cx)
  931                                    {
  932                                        Ok(()) => {}
  933                                        Err(e) => {
  934                                            log::error!(
  935                                                "Failed to register server capabilities: {e:#}"
  936                                            );
  937                                        }
  938                                    };
  939                                }
  940                            })
  941                            .ok();
  942                        Ok(())
  943                    }
  944                }
  945            })
  946            .detach();
  947
  948        language_server
  949            .on_request::<lsp::request::UnregisterCapability, _, _>({
  950                let lsp_store = lsp_store.clone();
  951                move |params, cx| {
  952                    let lsp_store = lsp_store.clone();
  953                    let mut cx = cx.clone();
  954                    async move {
  955                        lsp_store
  956                            .update(&mut cx, |lsp_store, cx| {
  957                                if lsp_store.as_local().is_some() {
  958                                    match lsp_store
  959                                        .unregister_server_capabilities(server_id, params, cx)
  960                                    {
  961                                        Ok(()) => {}
  962                                        Err(e) => {
  963                                            log::error!(
  964                                                "Failed to unregister server capabilities: {e:#}"
  965                                            );
  966                                        }
  967                                    }
  968                                }
  969                            })
  970                            .ok();
  971                        Ok(())
  972                    }
  973                }
  974            })
  975            .detach();
  976
  977        language_server
  978            .on_request::<lsp::request::ApplyWorkspaceEdit, _, _>({
  979                let this = lsp_store.clone();
  980                move |params, cx| {
  981                    let mut cx = cx.clone();
  982                    let this = this.clone();
  983                    async move {
  984                        LocalLspStore::on_lsp_workspace_edit(
  985                            this.clone(),
  986                            params,
  987                            server_id,
  988                            &mut cx,
  989                        )
  990                        .await
  991                    }
  992                }
  993            })
  994            .detach();
  995
  996        language_server
  997            .on_request::<lsp::request::InlayHintRefreshRequest, _, _>({
  998                let lsp_store = lsp_store.clone();
  999                let request_id = Arc::new(AtomicUsize::new(0));
 1000                move |(), cx| {
 1001                    let lsp_store = lsp_store.clone();
 1002                    let request_id = request_id.clone();
 1003                    let mut cx = cx.clone();
 1004                    async move {
 1005                        lsp_store
 1006                            .update(&mut cx, |lsp_store, cx| {
 1007                                let request_id =
 1008                                    Some(request_id.fetch_add(1, atomic::Ordering::AcqRel));
 1009                                cx.emit(LspStoreEvent::RefreshInlayHints {
 1010                                    server_id,
 1011                                    request_id,
 1012                                });
 1013                                lsp_store
 1014                                    .downstream_client
 1015                                    .as_ref()
 1016                                    .map(|(client, project_id)| {
 1017                                        client.send(proto::RefreshInlayHints {
 1018                                            project_id: *project_id,
 1019                                            server_id: server_id.to_proto(),
 1020                                            request_id: request_id.map(|id| id as u64),
 1021                                        })
 1022                                    })
 1023                            })?
 1024                            .transpose()?;
 1025                        Ok(())
 1026                    }
 1027                }
 1028            })
 1029            .detach();
 1030
 1031        language_server
 1032            .on_request::<lsp::request::CodeLensRefresh, _, _>({
 1033                let this = lsp_store.clone();
 1034                move |(), cx| {
 1035                    let this = this.clone();
 1036                    let mut cx = cx.clone();
 1037                    async move {
 1038                        this.update(&mut cx, |this, cx| {
 1039                            cx.emit(LspStoreEvent::RefreshCodeLens);
 1040                            this.downstream_client.as_ref().map(|(client, project_id)| {
 1041                                client.send(proto::RefreshCodeLens {
 1042                                    project_id: *project_id,
 1043                                })
 1044                            })
 1045                        })?
 1046                        .transpose()?;
 1047                        Ok(())
 1048                    }
 1049                }
 1050            })
 1051            .detach();
 1052
 1053        language_server
 1054            .on_request::<lsp::request::WorkspaceDiagnosticRefresh, _, _>({
 1055                let this = lsp_store.clone();
 1056                move |(), cx| {
 1057                    let this = this.clone();
 1058                    let mut cx = cx.clone();
 1059                    async move {
 1060                        this.update(&mut cx, |lsp_store, _| {
 1061                            lsp_store.pull_workspace_diagnostics(server_id);
 1062                            lsp_store
 1063                                .downstream_client
 1064                                .as_ref()
 1065                                .map(|(client, project_id)| {
 1066                                    client.send(proto::PullWorkspaceDiagnostics {
 1067                                        project_id: *project_id,
 1068                                        server_id: server_id.to_proto(),
 1069                                    })
 1070                                })
 1071                        })?
 1072                        .transpose()?;
 1073                        Ok(())
 1074                    }
 1075                }
 1076            })
 1077            .detach();
 1078
 1079        language_server
 1080            .on_request::<lsp::request::ShowMessageRequest, _, _>({
 1081                let this = lsp_store.clone();
 1082                let name = name.to_string();
 1083                move |params, cx| {
 1084                    let this = this.clone();
 1085                    let name = name.to_string();
 1086                    let mut cx = cx.clone();
 1087                    async move {
 1088                        let actions = params.actions.unwrap_or_default();
 1089                        let (tx, rx) = smol::channel::bounded(1);
 1090                        let request = LanguageServerPromptRequest {
 1091                            level: match params.typ {
 1092                                lsp::MessageType::ERROR => PromptLevel::Critical,
 1093                                lsp::MessageType::WARNING => PromptLevel::Warning,
 1094                                _ => PromptLevel::Info,
 1095                            },
 1096                            message: params.message,
 1097                            actions,
 1098                            response_channel: tx,
 1099                            lsp_name: name.clone(),
 1100                        };
 1101
 1102                        let did_update = this
 1103                            .update(&mut cx, |_, cx| {
 1104                                cx.emit(LspStoreEvent::LanguageServerPrompt(request));
 1105                            })
 1106                            .is_ok();
 1107                        if did_update {
 1108                            let response = rx.recv().await.ok();
 1109                            Ok(response)
 1110                        } else {
 1111                            Ok(None)
 1112                        }
 1113                    }
 1114                }
 1115            })
 1116            .detach();
 1117        language_server
 1118            .on_notification::<lsp::notification::ShowMessage, _>({
 1119                let this = lsp_store.clone();
 1120                let name = name.to_string();
 1121                move |params, cx| {
 1122                    let this = this.clone();
 1123                    let name = name.to_string();
 1124                    let mut cx = cx.clone();
 1125
 1126                    let (tx, _) = smol::channel::bounded(1);
 1127                    let request = LanguageServerPromptRequest {
 1128                        level: match params.typ {
 1129                            lsp::MessageType::ERROR => PromptLevel::Critical,
 1130                            lsp::MessageType::WARNING => PromptLevel::Warning,
 1131                            _ => PromptLevel::Info,
 1132                        },
 1133                        message: params.message,
 1134                        actions: vec![],
 1135                        response_channel: tx,
 1136                        lsp_name: name,
 1137                    };
 1138
 1139                    let _ = this.update(&mut cx, |_, cx| {
 1140                        cx.emit(LspStoreEvent::LanguageServerPrompt(request));
 1141                    });
 1142                }
 1143            })
 1144            .detach();
 1145
 1146        let disk_based_diagnostics_progress_token =
 1147            adapter.disk_based_diagnostics_progress_token.clone();
 1148
 1149        language_server
 1150            .on_notification::<lsp::notification::Progress, _>({
 1151                let this = lsp_store.clone();
 1152                move |params, cx| {
 1153                    if let Some(this) = this.upgrade() {
 1154                        this.update(cx, |this, cx| {
 1155                            this.on_lsp_progress(
 1156                                params,
 1157                                server_id,
 1158                                disk_based_diagnostics_progress_token.clone(),
 1159                                cx,
 1160                            );
 1161                        })
 1162                        .ok();
 1163                    }
 1164                }
 1165            })
 1166            .detach();
 1167
 1168        language_server
 1169            .on_notification::<lsp::notification::LogMessage, _>({
 1170                let this = lsp_store.clone();
 1171                move |params, cx| {
 1172                    if let Some(this) = this.upgrade() {
 1173                        this.update(cx, |_, cx| {
 1174                            cx.emit(LspStoreEvent::LanguageServerLog(
 1175                                server_id,
 1176                                LanguageServerLogType::Log(params.typ),
 1177                                params.message,
 1178                            ));
 1179                        })
 1180                        .ok();
 1181                    }
 1182                }
 1183            })
 1184            .detach();
 1185
 1186        language_server
 1187            .on_notification::<lsp::notification::LogTrace, _>({
 1188                let this = lsp_store.clone();
 1189                move |params, cx| {
 1190                    let mut cx = cx.clone();
 1191                    if let Some(this) = this.upgrade() {
 1192                        this.update(&mut cx, |_, cx| {
 1193                            cx.emit(LspStoreEvent::LanguageServerLog(
 1194                                server_id,
 1195                                LanguageServerLogType::Trace {
 1196                                    verbose_info: params.verbose,
 1197                                },
 1198                                params.message,
 1199                            ));
 1200                        })
 1201                        .ok();
 1202                    }
 1203                }
 1204            })
 1205            .detach();
 1206
 1207        vue_language_server_ext::register_requests(lsp_store.clone(), language_server);
 1208        json_language_server_ext::register_requests(lsp_store.clone(), language_server);
 1209        rust_analyzer_ext::register_notifications(lsp_store.clone(), language_server);
 1210        clangd_ext::register_notifications(lsp_store, language_server, adapter);
 1211    }
 1212
 1213    fn shutdown_language_servers_on_quit(
 1214        &mut self,
 1215        _: &mut Context<LspStore>,
 1216    ) -> impl Future<Output = ()> + use<> {
 1217        let shutdown_futures = self
 1218            .language_servers
 1219            .drain()
 1220            .map(|(_, server_state)| Self::shutdown_server(server_state))
 1221            .collect::<Vec<_>>();
 1222
 1223        async move {
 1224            join_all(shutdown_futures).await;
 1225        }
 1226    }
 1227
 1228    async fn shutdown_server(server_state: LanguageServerState) -> anyhow::Result<()> {
 1229        match server_state {
 1230            LanguageServerState::Running { server, .. } => {
 1231                if let Some(shutdown) = server.shutdown() {
 1232                    shutdown.await;
 1233                }
 1234            }
 1235            LanguageServerState::Starting { startup, .. } => {
 1236                if let Some(server) = startup.await
 1237                    && let Some(shutdown) = server.shutdown()
 1238                {
 1239                    shutdown.await;
 1240                }
 1241            }
 1242        }
 1243        Ok(())
 1244    }
 1245
 1246    fn language_servers_for_worktree(
 1247        &self,
 1248        worktree_id: WorktreeId,
 1249    ) -> impl Iterator<Item = &Arc<LanguageServer>> {
 1250        self.language_server_ids
 1251            .iter()
 1252            .filter_map(move |(seed, state)| {
 1253                if seed.worktree_id != worktree_id {
 1254                    return None;
 1255                }
 1256
 1257                if let Some(LanguageServerState::Running { server, .. }) =
 1258                    self.language_servers.get(&state.id)
 1259                {
 1260                    Some(server)
 1261                } else {
 1262                    None
 1263                }
 1264            })
 1265    }
 1266
 1267    fn language_server_ids_for_project_path(
 1268        &self,
 1269        project_path: ProjectPath,
 1270        language: &Language,
 1271        cx: &mut App,
 1272    ) -> Vec<LanguageServerId> {
 1273        let Some(worktree) = self
 1274            .worktree_store
 1275            .read(cx)
 1276            .worktree_for_id(project_path.worktree_id, cx)
 1277        else {
 1278            return Vec::new();
 1279        };
 1280        let delegate: Arc<dyn ManifestDelegate> =
 1281            Arc::new(ManifestQueryDelegate::new(worktree.read(cx).snapshot()));
 1282
 1283        self.lsp_tree
 1284            .get(
 1285                project_path,
 1286                language.name(),
 1287                language.manifest(),
 1288                &delegate,
 1289                cx,
 1290            )
 1291            .collect::<Vec<_>>()
 1292    }
 1293
 1294    fn language_server_ids_for_buffer(
 1295        &self,
 1296        buffer: &Buffer,
 1297        cx: &mut App,
 1298    ) -> Vec<LanguageServerId> {
 1299        if let Some((file, language)) = File::from_dyn(buffer.file()).zip(buffer.language()) {
 1300            let worktree_id = file.worktree_id(cx);
 1301
 1302            let path: Arc<RelPath> = file
 1303                .path()
 1304                .parent()
 1305                .map(Arc::from)
 1306                .unwrap_or_else(|| file.path().clone());
 1307            let worktree_path = ProjectPath { worktree_id, path };
 1308            self.language_server_ids_for_project_path(worktree_path, language, cx)
 1309        } else {
 1310            Vec::new()
 1311        }
 1312    }
 1313
 1314    fn language_servers_for_buffer<'a>(
 1315        &'a self,
 1316        buffer: &'a Buffer,
 1317        cx: &'a mut App,
 1318    ) -> impl Iterator<Item = (&'a Arc<CachedLspAdapter>, &'a Arc<LanguageServer>)> {
 1319        self.language_server_ids_for_buffer(buffer, cx)
 1320            .into_iter()
 1321            .filter_map(|server_id| match self.language_servers.get(&server_id)? {
 1322                LanguageServerState::Running {
 1323                    adapter, server, ..
 1324                } => Some((adapter, server)),
 1325                _ => None,
 1326            })
 1327    }
 1328
 1329    async fn execute_code_action_kind_locally(
 1330        lsp_store: WeakEntity<LspStore>,
 1331        mut buffers: Vec<Entity<Buffer>>,
 1332        kind: CodeActionKind,
 1333        push_to_history: bool,
 1334        cx: &mut AsyncApp,
 1335    ) -> anyhow::Result<ProjectTransaction> {
 1336        // Do not allow multiple concurrent code actions requests for the
 1337        // same buffer.
 1338        lsp_store.update(cx, |this, cx| {
 1339            let this = this.as_local_mut().unwrap();
 1340            buffers.retain(|buffer| {
 1341                this.buffers_being_formatted
 1342                    .insert(buffer.read(cx).remote_id())
 1343            });
 1344        })?;
 1345        let _cleanup = defer({
 1346            let this = lsp_store.clone();
 1347            let mut cx = cx.clone();
 1348            let buffers = &buffers;
 1349            move || {
 1350                this.update(&mut cx, |this, cx| {
 1351                    let this = this.as_local_mut().unwrap();
 1352                    for buffer in buffers {
 1353                        this.buffers_being_formatted
 1354                            .remove(&buffer.read(cx).remote_id());
 1355                    }
 1356                })
 1357                .ok();
 1358            }
 1359        });
 1360        let mut project_transaction = ProjectTransaction::default();
 1361
 1362        for buffer in &buffers {
 1363            let adapters_and_servers = lsp_store.update(cx, |lsp_store, cx| {
 1364                buffer.update(cx, |buffer, cx| {
 1365                    lsp_store
 1366                        .as_local()
 1367                        .unwrap()
 1368                        .language_servers_for_buffer(buffer, cx)
 1369                        .map(|(adapter, lsp)| (adapter.clone(), lsp.clone()))
 1370                        .collect::<Vec<_>>()
 1371                })
 1372            })?;
 1373            for (_, language_server) in adapters_and_servers.iter() {
 1374                let actions = Self::get_server_code_actions_from_action_kinds(
 1375                    &lsp_store,
 1376                    language_server.server_id(),
 1377                    vec![kind.clone()],
 1378                    buffer,
 1379                    cx,
 1380                )
 1381                .await?;
 1382                Self::execute_code_actions_on_server(
 1383                    &lsp_store,
 1384                    language_server,
 1385                    actions,
 1386                    push_to_history,
 1387                    &mut project_transaction,
 1388                    cx,
 1389                )
 1390                .await?;
 1391            }
 1392        }
 1393        Ok(project_transaction)
 1394    }
 1395
 1396    async fn format_locally(
 1397        lsp_store: WeakEntity<LspStore>,
 1398        mut buffers: Vec<FormattableBuffer>,
 1399        push_to_history: bool,
 1400        trigger: FormatTrigger,
 1401        logger: zlog::Logger,
 1402        cx: &mut AsyncApp,
 1403    ) -> anyhow::Result<ProjectTransaction> {
 1404        // Do not allow multiple concurrent formatting requests for the
 1405        // same buffer.
 1406        lsp_store.update(cx, |this, cx| {
 1407            let this = this.as_local_mut().unwrap();
 1408            buffers.retain(|buffer| {
 1409                this.buffers_being_formatted
 1410                    .insert(buffer.handle.read(cx).remote_id())
 1411            });
 1412        })?;
 1413
 1414        let _cleanup = defer({
 1415            let this = lsp_store.clone();
 1416            let mut cx = cx.clone();
 1417            let buffers = &buffers;
 1418            move || {
 1419                this.update(&mut cx, |this, cx| {
 1420                    let this = this.as_local_mut().unwrap();
 1421                    for buffer in buffers {
 1422                        this.buffers_being_formatted
 1423                            .remove(&buffer.handle.read(cx).remote_id());
 1424                    }
 1425                })
 1426                .ok();
 1427            }
 1428        });
 1429
 1430        let mut project_transaction = ProjectTransaction::default();
 1431
 1432        for buffer in &buffers {
 1433            zlog::debug!(
 1434                logger =>
 1435                "formatting buffer '{:?}'",
 1436                buffer.abs_path.as_ref().unwrap_or(&PathBuf::from("unknown")).display()
 1437            );
 1438            // Create an empty transaction to hold all of the formatting edits.
 1439            let formatting_transaction_id = buffer.handle.update(cx, |buffer, cx| {
 1440                // ensure no transactions created while formatting are
 1441                // grouped with the previous transaction in the history
 1442                // based on the transaction group interval
 1443                buffer.finalize_last_transaction();
 1444                buffer
 1445                    .start_transaction()
 1446                    .context("transaction already open")?;
 1447                buffer.end_transaction(cx);
 1448                let transaction_id = buffer.push_empty_transaction(cx.background_executor().now());
 1449                buffer.finalize_last_transaction();
 1450                anyhow::Ok(transaction_id)
 1451            })??;
 1452
 1453            let result = Self::format_buffer_locally(
 1454                lsp_store.clone(),
 1455                buffer,
 1456                formatting_transaction_id,
 1457                trigger,
 1458                logger,
 1459                cx,
 1460            )
 1461            .await;
 1462
 1463            buffer.handle.update(cx, |buffer, cx| {
 1464                let Some(formatting_transaction) =
 1465                    buffer.get_transaction(formatting_transaction_id).cloned()
 1466                else {
 1467                    zlog::warn!(logger => "no formatting transaction");
 1468                    return;
 1469                };
 1470                if formatting_transaction.edit_ids.is_empty() {
 1471                    zlog::debug!(logger => "no changes made while formatting");
 1472                    buffer.forget_transaction(formatting_transaction_id);
 1473                    return;
 1474                }
 1475                if !push_to_history {
 1476                    zlog::trace!(logger => "forgetting format transaction");
 1477                    buffer.forget_transaction(formatting_transaction.id);
 1478                }
 1479                project_transaction
 1480                    .0
 1481                    .insert(cx.entity(), formatting_transaction);
 1482            })?;
 1483
 1484            result?;
 1485        }
 1486
 1487        Ok(project_transaction)
 1488    }
 1489
 1490    async fn format_buffer_locally(
 1491        lsp_store: WeakEntity<LspStore>,
 1492        buffer: &FormattableBuffer,
 1493        formatting_transaction_id: clock::Lamport,
 1494        trigger: FormatTrigger,
 1495        logger: zlog::Logger,
 1496        cx: &mut AsyncApp,
 1497    ) -> Result<()> {
 1498        let (adapters_and_servers, settings) = lsp_store.update(cx, |lsp_store, cx| {
 1499            buffer.handle.update(cx, |buffer, cx| {
 1500                let adapters_and_servers = lsp_store
 1501                    .as_local()
 1502                    .unwrap()
 1503                    .language_servers_for_buffer(buffer, cx)
 1504                    .map(|(adapter, lsp)| (adapter.clone(), lsp.clone()))
 1505                    .collect::<Vec<_>>();
 1506                let settings =
 1507                    language_settings(buffer.language().map(|l| l.name()), buffer.file(), cx)
 1508                        .into_owned();
 1509                (adapters_and_servers, settings)
 1510            })
 1511        })?;
 1512
 1513        /// Apply edits to the buffer that will become part of the formatting transaction.
 1514        /// Fails if the buffer has been edited since the start of that transaction.
 1515        fn extend_formatting_transaction(
 1516            buffer: &FormattableBuffer,
 1517            formatting_transaction_id: text::TransactionId,
 1518            cx: &mut AsyncApp,
 1519            operation: impl FnOnce(&mut Buffer, &mut Context<Buffer>),
 1520        ) -> anyhow::Result<()> {
 1521            buffer.handle.update(cx, |buffer, cx| {
 1522                let last_transaction_id = buffer.peek_undo_stack().map(|t| t.transaction_id());
 1523                if last_transaction_id != Some(formatting_transaction_id) {
 1524                    anyhow::bail!("Buffer edited while formatting. Aborting")
 1525                }
 1526                buffer.start_transaction();
 1527                operation(buffer, cx);
 1528                if let Some(transaction_id) = buffer.end_transaction(cx) {
 1529                    buffer.merge_transactions(transaction_id, formatting_transaction_id);
 1530                }
 1531                Ok(())
 1532            })?
 1533        }
 1534
 1535        // handle whitespace formatting
 1536        if settings.remove_trailing_whitespace_on_save {
 1537            zlog::trace!(logger => "removing trailing whitespace");
 1538            let diff = buffer
 1539                .handle
 1540                .read_with(cx, |buffer, cx| buffer.remove_trailing_whitespace(cx))?
 1541                .await;
 1542            extend_formatting_transaction(buffer, formatting_transaction_id, cx, |buffer, cx| {
 1543                buffer.apply_diff(diff, cx);
 1544            })?;
 1545        }
 1546
 1547        if settings.ensure_final_newline_on_save {
 1548            zlog::trace!(logger => "ensuring final newline");
 1549            extend_formatting_transaction(buffer, formatting_transaction_id, cx, |buffer, cx| {
 1550                buffer.ensure_final_newline(cx);
 1551            })?;
 1552        }
 1553
 1554        // Formatter for `code_actions_on_format` that runs before
 1555        // the rest of the formatters
 1556        let mut code_actions_on_format_formatters = None;
 1557        let should_run_code_actions_on_format = !matches!(
 1558            (trigger, &settings.format_on_save),
 1559            (FormatTrigger::Save, &FormatOnSave::Off)
 1560        );
 1561        if should_run_code_actions_on_format {
 1562            let have_code_actions_to_run_on_format = settings
 1563                .code_actions_on_format
 1564                .values()
 1565                .any(|enabled| *enabled);
 1566            if have_code_actions_to_run_on_format {
 1567                zlog::trace!(logger => "going to run code actions on format");
 1568                code_actions_on_format_formatters = Some(
 1569                    settings
 1570                        .code_actions_on_format
 1571                        .iter()
 1572                        .filter_map(|(action, enabled)| enabled.then_some(action))
 1573                        .cloned()
 1574                        .map(Formatter::CodeAction)
 1575                        .collect::<Vec<_>>(),
 1576                );
 1577            }
 1578        }
 1579
 1580        let formatters = match (trigger, &settings.format_on_save) {
 1581            (FormatTrigger::Save, FormatOnSave::Off) => &[],
 1582            (FormatTrigger::Manual, _) | (FormatTrigger::Save, FormatOnSave::On) => {
 1583                settings.formatter.as_ref()
 1584            }
 1585        };
 1586
 1587        let formatters = code_actions_on_format_formatters
 1588            .iter()
 1589            .flatten()
 1590            .chain(formatters);
 1591
 1592        for formatter in formatters {
 1593            let formatter = if formatter == &Formatter::Auto {
 1594                if settings.prettier.allowed {
 1595                    zlog::trace!(logger => "Formatter set to auto: defaulting to prettier");
 1596                    &Formatter::Prettier
 1597                } else {
 1598                    zlog::trace!(logger => "Formatter set to auto: defaulting to primary language server");
 1599                    &Formatter::LanguageServer(settings::LanguageServerFormatterSpecifier::Current)
 1600                }
 1601            } else {
 1602                formatter
 1603            };
 1604            match formatter {
 1605                Formatter::Auto => unreachable!("Auto resolved above"),
 1606                Formatter::Prettier => {
 1607                    let logger = zlog::scoped!(logger => "prettier");
 1608                    zlog::trace!(logger => "formatting");
 1609                    let _timer = zlog::time!(logger => "Formatting buffer via prettier");
 1610
 1611                    let prettier = lsp_store.read_with(cx, |lsp_store, _cx| {
 1612                        lsp_store.prettier_store().unwrap().downgrade()
 1613                    })?;
 1614                    let diff = prettier_store::format_with_prettier(&prettier, &buffer.handle, cx)
 1615                        .await
 1616                        .transpose()?;
 1617                    let Some(diff) = diff else {
 1618                        zlog::trace!(logger => "No changes");
 1619                        continue;
 1620                    };
 1621
 1622                    extend_formatting_transaction(
 1623                        buffer,
 1624                        formatting_transaction_id,
 1625                        cx,
 1626                        |buffer, cx| {
 1627                            buffer.apply_diff(diff, cx);
 1628                        },
 1629                    )?;
 1630                }
 1631                Formatter::External { command, arguments } => {
 1632                    let logger = zlog::scoped!(logger => "command");
 1633                    zlog::trace!(logger => "formatting");
 1634                    let _timer = zlog::time!(logger => "Formatting buffer via external command");
 1635
 1636                    let diff = Self::format_via_external_command(
 1637                        buffer,
 1638                        command.as_ref(),
 1639                        arguments.as_deref(),
 1640                        cx,
 1641                    )
 1642                    .await
 1643                    .with_context(|| {
 1644                        format!("Failed to format buffer via external command: {}", command)
 1645                    })?;
 1646                    let Some(diff) = diff else {
 1647                        zlog::trace!(logger => "No changes");
 1648                        continue;
 1649                    };
 1650
 1651                    extend_formatting_transaction(
 1652                        buffer,
 1653                        formatting_transaction_id,
 1654                        cx,
 1655                        |buffer, cx| {
 1656                            buffer.apply_diff(diff, cx);
 1657                        },
 1658                    )?;
 1659                }
 1660                Formatter::LanguageServer(specifier) => {
 1661                    let logger = zlog::scoped!(logger => "language-server");
 1662                    zlog::trace!(logger => "formatting");
 1663                    let _timer = zlog::time!(logger => "Formatting buffer using language server");
 1664
 1665                    let Some(buffer_path_abs) = buffer.abs_path.as_ref() else {
 1666                        zlog::warn!(logger => "Cannot format buffer that is not backed by a file on disk using language servers. Skipping");
 1667                        continue;
 1668                    };
 1669
 1670                    let language_server = match specifier {
 1671                        settings::LanguageServerFormatterSpecifier::Specific { name } => {
 1672                            adapters_and_servers.iter().find_map(|(adapter, server)| {
 1673                                if adapter.name.0.as_ref() == name {
 1674                                    Some(server.clone())
 1675                                } else {
 1676                                    None
 1677                                }
 1678                            })
 1679                        }
 1680                        settings::LanguageServerFormatterSpecifier::Current => {
 1681                            adapters_and_servers.first().map(|e| e.1.clone())
 1682                        }
 1683                    };
 1684
 1685                    let Some(language_server) = language_server else {
 1686                        log::debug!(
 1687                            "No language server found to format buffer '{:?}'. Skipping",
 1688                            buffer_path_abs.as_path().to_string_lossy()
 1689                        );
 1690                        continue;
 1691                    };
 1692
 1693                    zlog::trace!(
 1694                        logger =>
 1695                        "Formatting buffer '{:?}' using language server '{:?}'",
 1696                        buffer_path_abs.as_path().to_string_lossy(),
 1697                        language_server.name()
 1698                    );
 1699
 1700                    let edits = if let Some(ranges) = buffer.ranges.as_ref() {
 1701                        zlog::trace!(logger => "formatting ranges");
 1702                        Self::format_ranges_via_lsp(
 1703                            &lsp_store,
 1704                            &buffer.handle,
 1705                            ranges,
 1706                            buffer_path_abs,
 1707                            &language_server,
 1708                            &settings,
 1709                            cx,
 1710                        )
 1711                        .await
 1712                        .context("Failed to format ranges via language server")?
 1713                    } else {
 1714                        zlog::trace!(logger => "formatting full");
 1715                        Self::format_via_lsp(
 1716                            &lsp_store,
 1717                            &buffer.handle,
 1718                            buffer_path_abs,
 1719                            &language_server,
 1720                            &settings,
 1721                            cx,
 1722                        )
 1723                        .await
 1724                        .context("failed to format via language server")?
 1725                    };
 1726
 1727                    if edits.is_empty() {
 1728                        zlog::trace!(logger => "No changes");
 1729                        continue;
 1730                    }
 1731                    extend_formatting_transaction(
 1732                        buffer,
 1733                        formatting_transaction_id,
 1734                        cx,
 1735                        |buffer, cx| {
 1736                            buffer.edit(edits, None, cx);
 1737                        },
 1738                    )?;
 1739                }
 1740                Formatter::CodeAction(code_action_name) => {
 1741                    let logger = zlog::scoped!(logger => "code-actions");
 1742                    zlog::trace!(logger => "formatting");
 1743                    let _timer = zlog::time!(logger => "Formatting buffer using code actions");
 1744
 1745                    let Some(buffer_path_abs) = buffer.abs_path.as_ref() else {
 1746                        zlog::warn!(logger => "Cannot format buffer that is not backed by a file on disk using code actions. Skipping");
 1747                        continue;
 1748                    };
 1749
 1750                    let code_action_kind: CodeActionKind = code_action_name.clone().into();
 1751                    zlog::trace!(logger => "Attempting to resolve code actions {:?}", &code_action_kind);
 1752
 1753                    let mut actions_and_servers = Vec::new();
 1754
 1755                    for (index, (_, language_server)) in adapters_and_servers.iter().enumerate() {
 1756                        let actions_result = Self::get_server_code_actions_from_action_kinds(
 1757                            &lsp_store,
 1758                            language_server.server_id(),
 1759                            vec![code_action_kind.clone()],
 1760                            &buffer.handle,
 1761                            cx,
 1762                        )
 1763                        .await
 1764                        .with_context(|| {
 1765                            format!(
 1766                                "Failed to resolve code action {:?} with language server {}",
 1767                                code_action_kind,
 1768                                language_server.name()
 1769                            )
 1770                        });
 1771                        let Ok(actions) = actions_result else {
 1772                            // note: it may be better to set result to the error and break formatters here
 1773                            // but for now we try to execute the actions that we can resolve and skip the rest
 1774                            zlog::error!(
 1775                                logger =>
 1776                                "Failed to resolve code action {:?} with language server {}",
 1777                                code_action_kind,
 1778                                language_server.name()
 1779                            );
 1780                            continue;
 1781                        };
 1782                        for action in actions {
 1783                            actions_and_servers.push((action, index));
 1784                        }
 1785                    }
 1786
 1787                    if actions_and_servers.is_empty() {
 1788                        zlog::warn!(logger => "No code actions were resolved, continuing");
 1789                        continue;
 1790                    }
 1791
 1792                    'actions: for (mut action, server_index) in actions_and_servers {
 1793                        let server = &adapters_and_servers[server_index].1;
 1794
 1795                        let describe_code_action = |action: &CodeAction| {
 1796                            format!(
 1797                                "code action '{}' with title \"{}\" on server {}",
 1798                                action
 1799                                    .lsp_action
 1800                                    .action_kind()
 1801                                    .unwrap_or("unknown".into())
 1802                                    .as_str(),
 1803                                action.lsp_action.title(),
 1804                                server.name(),
 1805                            )
 1806                        };
 1807
 1808                        zlog::trace!(logger => "Executing {}", describe_code_action(&action));
 1809
 1810                        if let Err(err) = Self::try_resolve_code_action(server, &mut action).await {
 1811                            zlog::error!(
 1812                                logger =>
 1813                                "Failed to resolve {}. Error: {}",
 1814                                describe_code_action(&action),
 1815                                err
 1816                            );
 1817                            continue;
 1818                        }
 1819
 1820                        if let Some(edit) = action.lsp_action.edit().cloned() {
 1821                            // NOTE: code below duplicated from `Self::deserialize_workspace_edit`
 1822                            // but filters out and logs warnings for code actions that require unreasonably
 1823                            // difficult handling on our part, such as:
 1824                            // - applying edits that call commands
 1825                            //   which can result in arbitrary workspace edits being sent from the server that
 1826                            //   have no way of being tied back to the command that initiated them (i.e. we
 1827                            //   can't know which edits are part of the format request, or if the server is done sending
 1828                            //   actions in response to the command)
 1829                            // - actions that create/delete/modify/rename files other than the one we are formatting
 1830                            //   as we then would need to handle such changes correctly in the local history as well
 1831                            //   as the remote history through the ProjectTransaction
 1832                            // - actions with snippet edits, as these simply don't make sense in the context of a format request
 1833                            // Supporting these actions is not impossible, but not supported as of yet.
 1834                            if edit.changes.is_none() && edit.document_changes.is_none() {
 1835                                zlog::trace!(
 1836                                    logger =>
 1837                                    "No changes for code action. Skipping {}",
 1838                                    describe_code_action(&action),
 1839                                );
 1840                                continue;
 1841                            }
 1842
 1843                            let mut operations = Vec::new();
 1844                            if let Some(document_changes) = edit.document_changes {
 1845                                match document_changes {
 1846                                    lsp::DocumentChanges::Edits(edits) => operations.extend(
 1847                                        edits.into_iter().map(lsp::DocumentChangeOperation::Edit),
 1848                                    ),
 1849                                    lsp::DocumentChanges::Operations(ops) => operations = ops,
 1850                                }
 1851                            } else if let Some(changes) = edit.changes {
 1852                                operations.extend(changes.into_iter().map(|(uri, edits)| {
 1853                                    lsp::DocumentChangeOperation::Edit(lsp::TextDocumentEdit {
 1854                                        text_document:
 1855                                            lsp::OptionalVersionedTextDocumentIdentifier {
 1856                                                uri,
 1857                                                version: None,
 1858                                            },
 1859                                        edits: edits.into_iter().map(Edit::Plain).collect(),
 1860                                    })
 1861                                }));
 1862                            }
 1863
 1864                            let mut edits = Vec::with_capacity(operations.len());
 1865
 1866                            if operations.is_empty() {
 1867                                zlog::trace!(
 1868                                    logger =>
 1869                                    "No changes for code action. Skipping {}",
 1870                                    describe_code_action(&action),
 1871                                );
 1872                                continue;
 1873                            }
 1874                            for operation in operations {
 1875                                let op = match operation {
 1876                                    lsp::DocumentChangeOperation::Edit(op) => op,
 1877                                    lsp::DocumentChangeOperation::Op(_) => {
 1878                                        zlog::warn!(
 1879                                            logger =>
 1880                                            "Code actions which create, delete, or rename files are not supported on format. Skipping {}",
 1881                                            describe_code_action(&action),
 1882                                        );
 1883                                        continue 'actions;
 1884                                    }
 1885                                };
 1886                                let Ok(file_path) = op.text_document.uri.to_file_path() else {
 1887                                    zlog::warn!(
 1888                                        logger =>
 1889                                        "Failed to convert URI '{:?}' to file path. Skipping {}",
 1890                                        &op.text_document.uri,
 1891                                        describe_code_action(&action),
 1892                                    );
 1893                                    continue 'actions;
 1894                                };
 1895                                if &file_path != buffer_path_abs {
 1896                                    zlog::warn!(
 1897                                        logger =>
 1898                                        "File path '{:?}' does not match buffer path '{:?}'. Skipping {}",
 1899                                        file_path,
 1900                                        buffer_path_abs,
 1901                                        describe_code_action(&action),
 1902                                    );
 1903                                    continue 'actions;
 1904                                }
 1905
 1906                                let mut lsp_edits = Vec::new();
 1907                                for edit in op.edits {
 1908                                    match edit {
 1909                                        Edit::Plain(edit) => {
 1910                                            if !lsp_edits.contains(&edit) {
 1911                                                lsp_edits.push(edit);
 1912                                            }
 1913                                        }
 1914                                        Edit::Annotated(edit) => {
 1915                                            if !lsp_edits.contains(&edit.text_edit) {
 1916                                                lsp_edits.push(edit.text_edit);
 1917                                            }
 1918                                        }
 1919                                        Edit::Snippet(_) => {
 1920                                            zlog::warn!(
 1921                                                logger =>
 1922                                                "Code actions which produce snippet edits are not supported during formatting. Skipping {}",
 1923                                                describe_code_action(&action),
 1924                                            );
 1925                                            continue 'actions;
 1926                                        }
 1927                                    }
 1928                                }
 1929                                let edits_result = lsp_store
 1930                                    .update(cx, |lsp_store, cx| {
 1931                                        lsp_store.as_local_mut().unwrap().edits_from_lsp(
 1932                                            &buffer.handle,
 1933                                            lsp_edits,
 1934                                            server.server_id(),
 1935                                            op.text_document.version,
 1936                                            cx,
 1937                                        )
 1938                                    })?
 1939                                    .await;
 1940                                let Ok(resolved_edits) = edits_result else {
 1941                                    zlog::warn!(
 1942                                        logger =>
 1943                                        "Failed to resolve edits from LSP for buffer {:?} while handling {}",
 1944                                        buffer_path_abs.as_path(),
 1945                                        describe_code_action(&action),
 1946                                    );
 1947                                    continue 'actions;
 1948                                };
 1949                                edits.extend(resolved_edits);
 1950                            }
 1951
 1952                            if edits.is_empty() {
 1953                                zlog::warn!(logger => "No edits resolved from LSP");
 1954                                continue;
 1955                            }
 1956
 1957                            extend_formatting_transaction(
 1958                                buffer,
 1959                                formatting_transaction_id,
 1960                                cx,
 1961                                |buffer, cx| {
 1962                                    zlog::info!(
 1963                                        "Applying edits {edits:?}. Content: {:?}",
 1964                                        buffer.text()
 1965                                    );
 1966                                    buffer.edit(edits, None, cx);
 1967                                    zlog::info!("Applied edits. New Content: {:?}", buffer.text());
 1968                                },
 1969                            )?;
 1970                        }
 1971
 1972                        if let Some(command) = action.lsp_action.command() {
 1973                            zlog::warn!(
 1974                                logger =>
 1975                                "Executing code action command '{}'. This may cause formatting to abort unnecessarily as well as splitting formatting into two entries in the undo history",
 1976                                &command.command,
 1977                            );
 1978
 1979                            // bail early if command is invalid
 1980                            let server_capabilities = server.capabilities();
 1981                            let available_commands = server_capabilities
 1982                                .execute_command_provider
 1983                                .as_ref()
 1984                                .map(|options| options.commands.as_slice())
 1985                                .unwrap_or_default();
 1986                            if !available_commands.contains(&command.command) {
 1987                                zlog::warn!(
 1988                                    logger =>
 1989                                    "Cannot execute a command {} not listed in the language server capabilities of server {}",
 1990                                    command.command,
 1991                                    server.name(),
 1992                                );
 1993                                continue;
 1994                            }
 1995
 1996                            // noop so we just ensure buffer hasn't been edited since resolving code actions
 1997                            extend_formatting_transaction(
 1998                                buffer,
 1999                                formatting_transaction_id,
 2000                                cx,
 2001                                |_, _| {},
 2002                            )?;
 2003                            zlog::info!(logger => "Executing command {}", &command.command);
 2004
 2005                            lsp_store.update(cx, |this, _| {
 2006                                this.as_local_mut()
 2007                                    .unwrap()
 2008                                    .last_workspace_edits_by_language_server
 2009                                    .remove(&server.server_id());
 2010                            })?;
 2011
 2012                            let execute_command_result = server
 2013                                .request::<lsp::request::ExecuteCommand>(
 2014                                    lsp::ExecuteCommandParams {
 2015                                        command: command.command.clone(),
 2016                                        arguments: command.arguments.clone().unwrap_or_default(),
 2017                                        ..Default::default()
 2018                                    },
 2019                                )
 2020                                .await
 2021                                .into_response();
 2022
 2023                            if execute_command_result.is_err() {
 2024                                zlog::error!(
 2025                                    logger =>
 2026                                    "Failed to execute command '{}' as part of {}",
 2027                                    &command.command,
 2028                                    describe_code_action(&action),
 2029                                );
 2030                                continue 'actions;
 2031                            }
 2032
 2033                            let mut project_transaction_command =
 2034                                lsp_store.update(cx, |this, _| {
 2035                                    this.as_local_mut()
 2036                                        .unwrap()
 2037                                        .last_workspace_edits_by_language_server
 2038                                        .remove(&server.server_id())
 2039                                        .unwrap_or_default()
 2040                                })?;
 2041
 2042                            if let Some(transaction) =
 2043                                project_transaction_command.0.remove(&buffer.handle)
 2044                            {
 2045                                zlog::trace!(
 2046                                    logger =>
 2047                                    "Successfully captured {} edits that resulted from command {}",
 2048                                    transaction.edit_ids.len(),
 2049                                    &command.command,
 2050                                );
 2051                                let transaction_id_project_transaction = transaction.id;
 2052                                buffer.handle.update(cx, |buffer, _| {
 2053                                    // it may have been removed from history if push_to_history was
 2054                                    // false in deserialize_workspace_edit. If so push it so we
 2055                                    // can merge it with the format transaction
 2056                                    // and pop the combined transaction off the history stack
 2057                                    // later if push_to_history is false
 2058                                    if buffer.get_transaction(transaction.id).is_none() {
 2059                                        buffer.push_transaction(transaction, Instant::now());
 2060                                    }
 2061                                    buffer.merge_transactions(
 2062                                        transaction_id_project_transaction,
 2063                                        formatting_transaction_id,
 2064                                    );
 2065                                })?;
 2066                            }
 2067
 2068                            if !project_transaction_command.0.is_empty() {
 2069                                let mut extra_buffers = String::new();
 2070                                for buffer in project_transaction_command.0.keys() {
 2071                                    buffer
 2072                                        .read_with(cx, |b, cx| {
 2073                                            if let Some(path) = b.project_path(cx) {
 2074                                                if !extra_buffers.is_empty() {
 2075                                                    extra_buffers.push_str(", ");
 2076                                                }
 2077                                                extra_buffers.push_str(path.path.as_unix_str());
 2078                                            }
 2079                                        })
 2080                                        .ok();
 2081                                }
 2082                                zlog::warn!(
 2083                                    logger =>
 2084                                    "Unexpected edits to buffers other than the buffer actively being formatted due to command {}. Impacted buffers: [{}].",
 2085                                    &command.command,
 2086                                    extra_buffers,
 2087                                );
 2088                                // NOTE: if this case is hit, the proper thing to do is to for each buffer, merge the extra transaction
 2089                                // into the existing transaction in project_transaction if there is one, and if there isn't one in project_transaction,
 2090                                // add it so it's included, and merge it into the format transaction when its created later
 2091                            }
 2092                        }
 2093                    }
 2094                }
 2095            }
 2096        }
 2097
 2098        Ok(())
 2099    }
 2100
 2101    pub async fn format_ranges_via_lsp(
 2102        this: &WeakEntity<LspStore>,
 2103        buffer_handle: &Entity<Buffer>,
 2104        ranges: &[Range<Anchor>],
 2105        abs_path: &Path,
 2106        language_server: &Arc<LanguageServer>,
 2107        settings: &LanguageSettings,
 2108        cx: &mut AsyncApp,
 2109    ) -> Result<Vec<(Range<Anchor>, Arc<str>)>> {
 2110        let capabilities = &language_server.capabilities();
 2111        let range_formatting_provider = capabilities.document_range_formatting_provider.as_ref();
 2112        if range_formatting_provider == Some(&OneOf::Left(false)) {
 2113            anyhow::bail!(
 2114                "{} language server does not support range formatting",
 2115                language_server.name()
 2116            );
 2117        }
 2118
 2119        let uri = file_path_to_lsp_url(abs_path)?;
 2120        let text_document = lsp::TextDocumentIdentifier::new(uri);
 2121
 2122        let lsp_edits = {
 2123            let mut lsp_ranges = Vec::new();
 2124            this.update(cx, |_this, cx| {
 2125                // TODO(#22930): In the case of formatting multibuffer selections, this buffer may
 2126                // not have been sent to the language server. This seems like a fairly systemic
 2127                // issue, though, the resolution probably is not specific to formatting.
 2128                //
 2129                // TODO: Instead of using current snapshot, should use the latest snapshot sent to
 2130                // LSP.
 2131                let snapshot = buffer_handle.read(cx).snapshot();
 2132                for range in ranges {
 2133                    lsp_ranges.push(range_to_lsp(range.to_point_utf16(&snapshot))?);
 2134                }
 2135                anyhow::Ok(())
 2136            })??;
 2137
 2138            let mut edits = None;
 2139            for range in lsp_ranges {
 2140                if let Some(mut edit) = language_server
 2141                    .request::<lsp::request::RangeFormatting>(lsp::DocumentRangeFormattingParams {
 2142                        text_document: text_document.clone(),
 2143                        range,
 2144                        options: lsp_command::lsp_formatting_options(settings),
 2145                        work_done_progress_params: Default::default(),
 2146                    })
 2147                    .await
 2148                    .into_response()?
 2149                {
 2150                    edits.get_or_insert_with(Vec::new).append(&mut edit);
 2151                }
 2152            }
 2153            edits
 2154        };
 2155
 2156        if let Some(lsp_edits) = lsp_edits {
 2157            this.update(cx, |this, cx| {
 2158                this.as_local_mut().unwrap().edits_from_lsp(
 2159                    buffer_handle,
 2160                    lsp_edits,
 2161                    language_server.server_id(),
 2162                    None,
 2163                    cx,
 2164                )
 2165            })?
 2166            .await
 2167        } else {
 2168            Ok(Vec::with_capacity(0))
 2169        }
 2170    }
 2171
 2172    async fn format_via_lsp(
 2173        this: &WeakEntity<LspStore>,
 2174        buffer: &Entity<Buffer>,
 2175        abs_path: &Path,
 2176        language_server: &Arc<LanguageServer>,
 2177        settings: &LanguageSettings,
 2178        cx: &mut AsyncApp,
 2179    ) -> Result<Vec<(Range<Anchor>, Arc<str>)>> {
 2180        let logger = zlog::scoped!("lsp_format");
 2181        zlog::debug!(logger => "Formatting via LSP");
 2182
 2183        let uri = file_path_to_lsp_url(abs_path)?;
 2184        let text_document = lsp::TextDocumentIdentifier::new(uri);
 2185        let capabilities = &language_server.capabilities();
 2186
 2187        let formatting_provider = capabilities.document_formatting_provider.as_ref();
 2188        let range_formatting_provider = capabilities.document_range_formatting_provider.as_ref();
 2189
 2190        let lsp_edits = if matches!(formatting_provider, Some(p) if *p != OneOf::Left(false)) {
 2191            let _timer = zlog::time!(logger => "format-full");
 2192            language_server
 2193                .request::<lsp::request::Formatting>(lsp::DocumentFormattingParams {
 2194                    text_document,
 2195                    options: lsp_command::lsp_formatting_options(settings),
 2196                    work_done_progress_params: Default::default(),
 2197                })
 2198                .await
 2199                .into_response()?
 2200        } else if matches!(range_formatting_provider, Some(p) if *p != OneOf::Left(false)) {
 2201            let _timer = zlog::time!(logger => "format-range");
 2202            let buffer_start = lsp::Position::new(0, 0);
 2203            let buffer_end = buffer.read_with(cx, |b, _| point_to_lsp(b.max_point_utf16()))?;
 2204            language_server
 2205                .request::<lsp::request::RangeFormatting>(lsp::DocumentRangeFormattingParams {
 2206                    text_document: text_document.clone(),
 2207                    range: lsp::Range::new(buffer_start, buffer_end),
 2208                    options: lsp_command::lsp_formatting_options(settings),
 2209                    work_done_progress_params: Default::default(),
 2210                })
 2211                .await
 2212                .into_response()?
 2213        } else {
 2214            None
 2215        };
 2216
 2217        if let Some(lsp_edits) = lsp_edits {
 2218            this.update(cx, |this, cx| {
 2219                this.as_local_mut().unwrap().edits_from_lsp(
 2220                    buffer,
 2221                    lsp_edits,
 2222                    language_server.server_id(),
 2223                    None,
 2224                    cx,
 2225                )
 2226            })?
 2227            .await
 2228        } else {
 2229            Ok(Vec::with_capacity(0))
 2230        }
 2231    }
 2232
 2233    async fn format_via_external_command(
 2234        buffer: &FormattableBuffer,
 2235        command: &str,
 2236        arguments: Option<&[String]>,
 2237        cx: &mut AsyncApp,
 2238    ) -> Result<Option<Diff>> {
 2239        let working_dir_path = buffer.handle.update(cx, |buffer, cx| {
 2240            let file = File::from_dyn(buffer.file())?;
 2241            let worktree = file.worktree.read(cx);
 2242            let mut worktree_path = worktree.abs_path().to_path_buf();
 2243            if worktree.root_entry()?.is_file() {
 2244                worktree_path.pop();
 2245            }
 2246            Some(worktree_path)
 2247        })?;
 2248
 2249        let mut child = util::command::new_smol_command(command);
 2250
 2251        if let Some(buffer_env) = buffer.env.as_ref() {
 2252            child.envs(buffer_env);
 2253        }
 2254
 2255        if let Some(working_dir_path) = working_dir_path {
 2256            child.current_dir(working_dir_path);
 2257        }
 2258
 2259        if let Some(arguments) = arguments {
 2260            child.args(arguments.iter().map(|arg| {
 2261                if let Some(buffer_abs_path) = buffer.abs_path.as_ref() {
 2262                    arg.replace("{buffer_path}", &buffer_abs_path.to_string_lossy())
 2263                } else {
 2264                    arg.replace("{buffer_path}", "Untitled")
 2265                }
 2266            }));
 2267        }
 2268
 2269        let mut child = child
 2270            .stdin(smol::process::Stdio::piped())
 2271            .stdout(smol::process::Stdio::piped())
 2272            .stderr(smol::process::Stdio::piped())
 2273            .spawn()?;
 2274
 2275        let stdin = child.stdin.as_mut().context("failed to acquire stdin")?;
 2276        let text = buffer
 2277            .handle
 2278            .read_with(cx, |buffer, _| buffer.as_rope().clone())?;
 2279        for chunk in text.chunks() {
 2280            stdin.write_all(chunk.as_bytes()).await?;
 2281        }
 2282        stdin.flush().await?;
 2283
 2284        let output = child.output().await?;
 2285        anyhow::ensure!(
 2286            output.status.success(),
 2287            "command failed with exit code {:?}:\nstdout: {}\nstderr: {}",
 2288            output.status.code(),
 2289            String::from_utf8_lossy(&output.stdout),
 2290            String::from_utf8_lossy(&output.stderr),
 2291        );
 2292
 2293        let stdout = String::from_utf8(output.stdout)?;
 2294        Ok(Some(
 2295            buffer
 2296                .handle
 2297                .update(cx, |buffer, cx| buffer.diff(stdout, cx))?
 2298                .await,
 2299        ))
 2300    }
 2301
 2302    async fn try_resolve_code_action(
 2303        lang_server: &LanguageServer,
 2304        action: &mut CodeAction,
 2305    ) -> anyhow::Result<()> {
 2306        match &mut action.lsp_action {
 2307            LspAction::Action(lsp_action) => {
 2308                if !action.resolved
 2309                    && GetCodeActions::can_resolve_actions(&lang_server.capabilities())
 2310                    && lsp_action.data.is_some()
 2311                    && (lsp_action.command.is_none() || lsp_action.edit.is_none())
 2312                {
 2313                    *lsp_action = Box::new(
 2314                        lang_server
 2315                            .request::<lsp::request::CodeActionResolveRequest>(*lsp_action.clone())
 2316                            .await
 2317                            .into_response()?,
 2318                    );
 2319                }
 2320            }
 2321            LspAction::CodeLens(lens) => {
 2322                if !action.resolved && GetCodeLens::can_resolve_lens(&lang_server.capabilities()) {
 2323                    *lens = lang_server
 2324                        .request::<lsp::request::CodeLensResolve>(lens.clone())
 2325                        .await
 2326                        .into_response()?;
 2327                }
 2328            }
 2329            LspAction::Command(_) => {}
 2330        }
 2331
 2332        action.resolved = true;
 2333        anyhow::Ok(())
 2334    }
 2335
 2336    fn initialize_buffer(&mut self, buffer_handle: &Entity<Buffer>, cx: &mut Context<LspStore>) {
 2337        let buffer = buffer_handle.read(cx);
 2338
 2339        let file = buffer.file().cloned();
 2340
 2341        let Some(file) = File::from_dyn(file.as_ref()) else {
 2342            return;
 2343        };
 2344        if !file.is_local() {
 2345            return;
 2346        }
 2347        let path = ProjectPath::from_file(file, cx);
 2348        let worktree_id = file.worktree_id(cx);
 2349        let language = buffer.language().cloned();
 2350
 2351        if let Some(diagnostics) = self.diagnostics.get(&worktree_id) {
 2352            for (server_id, diagnostics) in
 2353                diagnostics.get(file.path()).cloned().unwrap_or_default()
 2354            {
 2355                self.update_buffer_diagnostics(
 2356                    buffer_handle,
 2357                    server_id,
 2358                    None,
 2359                    None,
 2360                    None,
 2361                    Vec::new(),
 2362                    diagnostics,
 2363                    cx,
 2364                )
 2365                .log_err();
 2366            }
 2367        }
 2368        let Some(language) = language else {
 2369            return;
 2370        };
 2371        let Some(snapshot) = self
 2372            .worktree_store
 2373            .read(cx)
 2374            .worktree_for_id(worktree_id, cx)
 2375            .map(|worktree| worktree.read(cx).snapshot())
 2376        else {
 2377            return;
 2378        };
 2379        let delegate: Arc<dyn ManifestDelegate> = Arc::new(ManifestQueryDelegate::new(snapshot));
 2380
 2381        for server_id in
 2382            self.lsp_tree
 2383                .get(path, language.name(), language.manifest(), &delegate, cx)
 2384        {
 2385            let server = self
 2386                .language_servers
 2387                .get(&server_id)
 2388                .and_then(|server_state| {
 2389                    if let LanguageServerState::Running { server, .. } = server_state {
 2390                        Some(server.clone())
 2391                    } else {
 2392                        None
 2393                    }
 2394                });
 2395            let server = match server {
 2396                Some(server) => server,
 2397                None => continue,
 2398            };
 2399
 2400            buffer_handle.update(cx, |buffer, cx| {
 2401                buffer.set_completion_triggers(
 2402                    server.server_id(),
 2403                    server
 2404                        .capabilities()
 2405                        .completion_provider
 2406                        .as_ref()
 2407                        .and_then(|provider| {
 2408                            provider
 2409                                .trigger_characters
 2410                                .as_ref()
 2411                                .map(|characters| characters.iter().cloned().collect())
 2412                        })
 2413                        .unwrap_or_default(),
 2414                    cx,
 2415                );
 2416            });
 2417        }
 2418    }
 2419
 2420    pub(crate) fn reset_buffer(&mut self, buffer: &Entity<Buffer>, old_file: &File, cx: &mut App) {
 2421        buffer.update(cx, |buffer, cx| {
 2422            let Some(language) = buffer.language() else {
 2423                return;
 2424            };
 2425            let path = ProjectPath {
 2426                worktree_id: old_file.worktree_id(cx),
 2427                path: old_file.path.clone(),
 2428            };
 2429            for server_id in self.language_server_ids_for_project_path(path, language, cx) {
 2430                buffer.update_diagnostics(server_id, DiagnosticSet::new([], buffer), cx);
 2431                buffer.set_completion_triggers(server_id, Default::default(), cx);
 2432            }
 2433        });
 2434    }
 2435
 2436    fn update_buffer_diagnostics(
 2437        &mut self,
 2438        buffer: &Entity<Buffer>,
 2439        server_id: LanguageServerId,
 2440        registration_id: Option<Option<SharedString>>,
 2441        result_id: Option<SharedString>,
 2442        version: Option<i32>,
 2443        new_diagnostics: Vec<DiagnosticEntry<Unclipped<PointUtf16>>>,
 2444        reused_diagnostics: Vec<DiagnosticEntry<Unclipped<PointUtf16>>>,
 2445        cx: &mut Context<LspStore>,
 2446    ) -> Result<()> {
 2447        fn compare_diagnostics(a: &Diagnostic, b: &Diagnostic) -> Ordering {
 2448            Ordering::Equal
 2449                .then_with(|| b.is_primary.cmp(&a.is_primary))
 2450                .then_with(|| a.is_disk_based.cmp(&b.is_disk_based))
 2451                .then_with(|| a.severity.cmp(&b.severity))
 2452                .then_with(|| a.message.cmp(&b.message))
 2453        }
 2454
 2455        let mut diagnostics = Vec::with_capacity(new_diagnostics.len() + reused_diagnostics.len());
 2456        diagnostics.extend(new_diagnostics.into_iter().map(|d| (true, d)));
 2457        diagnostics.extend(reused_diagnostics.into_iter().map(|d| (false, d)));
 2458
 2459        diagnostics.sort_unstable_by(|(_, a), (_, b)| {
 2460            Ordering::Equal
 2461                .then_with(|| a.range.start.cmp(&b.range.start))
 2462                .then_with(|| b.range.end.cmp(&a.range.end))
 2463                .then_with(|| compare_diagnostics(&a.diagnostic, &b.diagnostic))
 2464        });
 2465
 2466        let snapshot = self.buffer_snapshot_for_lsp_version(buffer, server_id, version, cx)?;
 2467
 2468        let edits_since_save = std::cell::LazyCell::new(|| {
 2469            let saved_version = buffer.read(cx).saved_version();
 2470            Patch::new(snapshot.edits_since::<PointUtf16>(saved_version).collect())
 2471        });
 2472
 2473        let mut sanitized_diagnostics = Vec::with_capacity(diagnostics.len());
 2474
 2475        for (new_diagnostic, entry) in diagnostics {
 2476            let start;
 2477            let end;
 2478            if new_diagnostic && entry.diagnostic.is_disk_based {
 2479                // Some diagnostics are based on files on disk instead of buffers'
 2480                // current contents. Adjust these diagnostics' ranges to reflect
 2481                // any unsaved edits.
 2482                // Do not alter the reused ones though, as their coordinates were stored as anchors
 2483                // and were properly adjusted on reuse.
 2484                start = Unclipped((*edits_since_save).old_to_new(entry.range.start.0));
 2485                end = Unclipped((*edits_since_save).old_to_new(entry.range.end.0));
 2486            } else {
 2487                start = entry.range.start;
 2488                end = entry.range.end;
 2489            }
 2490
 2491            let mut range = snapshot.clip_point_utf16(start, Bias::Left)
 2492                ..snapshot.clip_point_utf16(end, Bias::Right);
 2493
 2494            // Expand empty ranges by one codepoint
 2495            if range.start == range.end {
 2496                // This will be go to the next boundary when being clipped
 2497                range.end.column += 1;
 2498                range.end = snapshot.clip_point_utf16(Unclipped(range.end), Bias::Right);
 2499                if range.start == range.end && range.end.column > 0 {
 2500                    range.start.column -= 1;
 2501                    range.start = snapshot.clip_point_utf16(Unclipped(range.start), Bias::Left);
 2502                }
 2503            }
 2504
 2505            sanitized_diagnostics.push(DiagnosticEntry {
 2506                range,
 2507                diagnostic: entry.diagnostic,
 2508            });
 2509        }
 2510        drop(edits_since_save);
 2511
 2512        let set = DiagnosticSet::new(sanitized_diagnostics, &snapshot);
 2513        buffer.update(cx, |buffer, cx| {
 2514            if let Some(registration_id) = registration_id {
 2515                if let Some(abs_path) = File::from_dyn(buffer.file()).map(|f| f.abs_path(cx)) {
 2516                    self.buffer_pull_diagnostics_result_ids
 2517                        .entry(server_id)
 2518                        .or_default()
 2519                        .entry(registration_id)
 2520                        .or_default()
 2521                        .insert(abs_path, result_id);
 2522                }
 2523            }
 2524
 2525            buffer.update_diagnostics(server_id, set, cx)
 2526        });
 2527
 2528        Ok(())
 2529    }
 2530
 2531    fn register_language_server_for_invisible_worktree(
 2532        &mut self,
 2533        worktree: &Entity<Worktree>,
 2534        language_server_id: LanguageServerId,
 2535        cx: &mut App,
 2536    ) {
 2537        let worktree = worktree.read(cx);
 2538        let worktree_id = worktree.id();
 2539        debug_assert!(!worktree.is_visible());
 2540        let Some(mut origin_seed) = self
 2541            .language_server_ids
 2542            .iter()
 2543            .find_map(|(seed, state)| (state.id == language_server_id).then(|| seed.clone()))
 2544        else {
 2545            return;
 2546        };
 2547        origin_seed.worktree_id = worktree_id;
 2548        self.language_server_ids
 2549            .entry(origin_seed)
 2550            .or_insert_with(|| UnifiedLanguageServer {
 2551                id: language_server_id,
 2552                project_roots: Default::default(),
 2553            });
 2554    }
 2555
 2556    fn register_buffer_with_language_servers(
 2557        &mut self,
 2558        buffer_handle: &Entity<Buffer>,
 2559        only_register_servers: HashSet<LanguageServerSelector>,
 2560        cx: &mut Context<LspStore>,
 2561    ) {
 2562        let buffer = buffer_handle.read(cx);
 2563        let buffer_id = buffer.remote_id();
 2564
 2565        let Some(file) = File::from_dyn(buffer.file()) else {
 2566            return;
 2567        };
 2568        if !file.is_local() {
 2569            return;
 2570        }
 2571
 2572        let abs_path = file.abs_path(cx);
 2573        let Some(uri) = file_path_to_lsp_url(&abs_path).log_err() else {
 2574            return;
 2575        };
 2576        let initial_snapshot = buffer.text_snapshot();
 2577        let worktree_id = file.worktree_id(cx);
 2578
 2579        let Some(language) = buffer.language().cloned() else {
 2580            return;
 2581        };
 2582        let path: Arc<RelPath> = file
 2583            .path()
 2584            .parent()
 2585            .map(Arc::from)
 2586            .unwrap_or_else(|| file.path().clone());
 2587        let Some(worktree) = self
 2588            .worktree_store
 2589            .read(cx)
 2590            .worktree_for_id(worktree_id, cx)
 2591        else {
 2592            return;
 2593        };
 2594        let language_name = language.name();
 2595        let (reused, delegate, servers) = self
 2596            .reuse_existing_language_server(&self.lsp_tree, &worktree, &language_name, cx)
 2597            .map(|(delegate, apply)| (true, delegate, apply(&mut self.lsp_tree)))
 2598            .unwrap_or_else(|| {
 2599                let lsp_delegate = LocalLspAdapterDelegate::from_local_lsp(self, &worktree, cx);
 2600                let delegate: Arc<dyn ManifestDelegate> =
 2601                    Arc::new(ManifestQueryDelegate::new(worktree.read(cx).snapshot()));
 2602
 2603                let servers = self
 2604                    .lsp_tree
 2605                    .walk(
 2606                        ProjectPath { worktree_id, path },
 2607                        language.name(),
 2608                        language.manifest(),
 2609                        &delegate,
 2610                        cx,
 2611                    )
 2612                    .collect::<Vec<_>>();
 2613                (false, lsp_delegate, servers)
 2614            });
 2615        let servers_and_adapters = servers
 2616            .into_iter()
 2617            .filter_map(|server_node| {
 2618                if reused && server_node.server_id().is_none() {
 2619                    return None;
 2620                }
 2621                if !only_register_servers.is_empty() {
 2622                    if let Some(server_id) = server_node.server_id()
 2623                        && !only_register_servers.contains(&LanguageServerSelector::Id(server_id))
 2624                    {
 2625                        return None;
 2626                    }
 2627                    if let Some(name) = server_node.name()
 2628                        && !only_register_servers.contains(&LanguageServerSelector::Name(name))
 2629                    {
 2630                        return None;
 2631                    }
 2632                }
 2633
 2634                let server_id = server_node.server_id_or_init(|disposition| {
 2635                    let path = &disposition.path;
 2636
 2637                    {
 2638                        let uri = Uri::from_file_path(worktree.read(cx).absolutize(&path.path));
 2639
 2640                        let server_id = self.get_or_insert_language_server(
 2641                            &worktree,
 2642                            delegate.clone(),
 2643                            disposition,
 2644                            &language_name,
 2645                            cx,
 2646                        );
 2647
 2648                        if let Some(state) = self.language_servers.get(&server_id)
 2649                            && let Ok(uri) = uri
 2650                        {
 2651                            state.add_workspace_folder(uri);
 2652                        };
 2653                        server_id
 2654                    }
 2655                })?;
 2656                let server_state = self.language_servers.get(&server_id)?;
 2657                if let LanguageServerState::Running {
 2658                    server, adapter, ..
 2659                } = server_state
 2660                {
 2661                    Some((server.clone(), adapter.clone()))
 2662                } else {
 2663                    None
 2664                }
 2665            })
 2666            .collect::<Vec<_>>();
 2667        for (server, adapter) in servers_and_adapters {
 2668            buffer_handle.update(cx, |buffer, cx| {
 2669                buffer.set_completion_triggers(
 2670                    server.server_id(),
 2671                    server
 2672                        .capabilities()
 2673                        .completion_provider
 2674                        .as_ref()
 2675                        .and_then(|provider| {
 2676                            provider
 2677                                .trigger_characters
 2678                                .as_ref()
 2679                                .map(|characters| characters.iter().cloned().collect())
 2680                        })
 2681                        .unwrap_or_default(),
 2682                    cx,
 2683                );
 2684            });
 2685
 2686            let snapshot = LspBufferSnapshot {
 2687                version: 0,
 2688                snapshot: initial_snapshot.clone(),
 2689            };
 2690
 2691            let mut registered = false;
 2692            self.buffer_snapshots
 2693                .entry(buffer_id)
 2694                .or_default()
 2695                .entry(server.server_id())
 2696                .or_insert_with(|| {
 2697                    registered = true;
 2698                    server.register_buffer(
 2699                        uri.clone(),
 2700                        adapter.language_id(&language.name()),
 2701                        0,
 2702                        initial_snapshot.text(),
 2703                    );
 2704
 2705                    vec![snapshot]
 2706                });
 2707
 2708            self.buffers_opened_in_servers
 2709                .entry(buffer_id)
 2710                .or_default()
 2711                .insert(server.server_id());
 2712            if registered {
 2713                cx.emit(LspStoreEvent::LanguageServerUpdate {
 2714                    language_server_id: server.server_id(),
 2715                    name: None,
 2716                    message: proto::update_language_server::Variant::RegisteredForBuffer(
 2717                        proto::RegisteredForBuffer {
 2718                            buffer_abs_path: abs_path.to_string_lossy().into_owned(),
 2719                            buffer_id: buffer_id.to_proto(),
 2720                        },
 2721                    ),
 2722                });
 2723            }
 2724        }
 2725    }
 2726
 2727    fn reuse_existing_language_server<'lang_name>(
 2728        &self,
 2729        server_tree: &LanguageServerTree,
 2730        worktree: &Entity<Worktree>,
 2731        language_name: &'lang_name LanguageName,
 2732        cx: &mut App,
 2733    ) -> Option<(
 2734        Arc<LocalLspAdapterDelegate>,
 2735        impl FnOnce(&mut LanguageServerTree) -> Vec<LanguageServerTreeNode> + use<'lang_name>,
 2736    )> {
 2737        if worktree.read(cx).is_visible() {
 2738            return None;
 2739        }
 2740
 2741        let worktree_store = self.worktree_store.read(cx);
 2742        let servers = server_tree
 2743            .instances
 2744            .iter()
 2745            .filter(|(worktree_id, _)| {
 2746                worktree_store
 2747                    .worktree_for_id(**worktree_id, cx)
 2748                    .is_some_and(|worktree| worktree.read(cx).is_visible())
 2749            })
 2750            .flat_map(|(worktree_id, servers)| {
 2751                servers
 2752                    .roots
 2753                    .iter()
 2754                    .flat_map(|(_, language_servers)| language_servers)
 2755                    .map(move |(_, (server_node, server_languages))| {
 2756                        (worktree_id, server_node, server_languages)
 2757                    })
 2758                    .filter(|(_, _, server_languages)| server_languages.contains(language_name))
 2759                    .map(|(worktree_id, server_node, _)| {
 2760                        (
 2761                            *worktree_id,
 2762                            LanguageServerTreeNode::from(Arc::downgrade(server_node)),
 2763                        )
 2764                    })
 2765            })
 2766            .fold(HashMap::default(), |mut acc, (worktree_id, server_node)| {
 2767                acc.entry(worktree_id)
 2768                    .or_insert_with(Vec::new)
 2769                    .push(server_node);
 2770                acc
 2771            })
 2772            .into_values()
 2773            .max_by_key(|servers| servers.len())?;
 2774
 2775        let worktree_id = worktree.read(cx).id();
 2776        let apply = move |tree: &mut LanguageServerTree| {
 2777            for server_node in &servers {
 2778                tree.register_reused(worktree_id, language_name.clone(), server_node.clone());
 2779            }
 2780            servers
 2781        };
 2782
 2783        let delegate = LocalLspAdapterDelegate::from_local_lsp(self, worktree, cx);
 2784        Some((delegate, apply))
 2785    }
 2786
 2787    pub(crate) fn unregister_old_buffer_from_language_servers(
 2788        &mut self,
 2789        buffer: &Entity<Buffer>,
 2790        old_file: &File,
 2791        cx: &mut App,
 2792    ) {
 2793        let old_path = match old_file.as_local() {
 2794            Some(local) => local.abs_path(cx),
 2795            None => return,
 2796        };
 2797
 2798        let Ok(file_url) = lsp::Uri::from_file_path(old_path.as_path()) else {
 2799            debug_panic!("{old_path:?} is not parseable as an URI");
 2800            return;
 2801        };
 2802        self.unregister_buffer_from_language_servers(buffer, &file_url, cx);
 2803    }
 2804
 2805    pub(crate) fn unregister_buffer_from_language_servers(
 2806        &mut self,
 2807        buffer: &Entity<Buffer>,
 2808        file_url: &lsp::Uri,
 2809        cx: &mut App,
 2810    ) {
 2811        buffer.update(cx, |buffer, cx| {
 2812            let mut snapshots = self.buffer_snapshots.remove(&buffer.remote_id());
 2813
 2814            for (_, language_server) in self.language_servers_for_buffer(buffer, cx) {
 2815                if snapshots
 2816                    .as_mut()
 2817                    .is_some_and(|map| map.remove(&language_server.server_id()).is_some())
 2818                {
 2819                    language_server.unregister_buffer(file_url.clone());
 2820                }
 2821            }
 2822        });
 2823    }
 2824
 2825    fn buffer_snapshot_for_lsp_version(
 2826        &mut self,
 2827        buffer: &Entity<Buffer>,
 2828        server_id: LanguageServerId,
 2829        version: Option<i32>,
 2830        cx: &App,
 2831    ) -> Result<TextBufferSnapshot> {
 2832        const OLD_VERSIONS_TO_RETAIN: i32 = 10;
 2833
 2834        if let Some(version) = version {
 2835            let buffer_id = buffer.read(cx).remote_id();
 2836            let snapshots = if let Some(snapshots) = self
 2837                .buffer_snapshots
 2838                .get_mut(&buffer_id)
 2839                .and_then(|m| m.get_mut(&server_id))
 2840            {
 2841                snapshots
 2842            } else if version == 0 {
 2843                // Some language servers report version 0 even if the buffer hasn't been opened yet.
 2844                // We detect this case and treat it as if the version was `None`.
 2845                return Ok(buffer.read(cx).text_snapshot());
 2846            } else {
 2847                anyhow::bail!("no snapshots found for buffer {buffer_id} and server {server_id}");
 2848            };
 2849
 2850            let found_snapshot = snapshots
 2851                    .binary_search_by_key(&version, |e| e.version)
 2852                    .map(|ix| snapshots[ix].snapshot.clone())
 2853                    .map_err(|_| {
 2854                        anyhow!("snapshot not found for buffer {buffer_id} server {server_id} at version {version}")
 2855                    })?;
 2856
 2857            snapshots.retain(|snapshot| snapshot.version + OLD_VERSIONS_TO_RETAIN >= version);
 2858            Ok(found_snapshot)
 2859        } else {
 2860            Ok((buffer.read(cx)).text_snapshot())
 2861        }
 2862    }
 2863
 2864    async fn get_server_code_actions_from_action_kinds(
 2865        lsp_store: &WeakEntity<LspStore>,
 2866        language_server_id: LanguageServerId,
 2867        code_action_kinds: Vec<lsp::CodeActionKind>,
 2868        buffer: &Entity<Buffer>,
 2869        cx: &mut AsyncApp,
 2870    ) -> Result<Vec<CodeAction>> {
 2871        let actions = lsp_store
 2872            .update(cx, move |this, cx| {
 2873                let request = GetCodeActions {
 2874                    range: text::Anchor::min_max_range_for_buffer(buffer.read(cx).remote_id()),
 2875                    kinds: Some(code_action_kinds),
 2876                };
 2877                let server = LanguageServerToQuery::Other(language_server_id);
 2878                this.request_lsp(buffer.clone(), server, request, cx)
 2879            })?
 2880            .await?;
 2881        Ok(actions)
 2882    }
 2883
 2884    pub async fn execute_code_actions_on_server(
 2885        lsp_store: &WeakEntity<LspStore>,
 2886        language_server: &Arc<LanguageServer>,
 2887
 2888        actions: Vec<CodeAction>,
 2889        push_to_history: bool,
 2890        project_transaction: &mut ProjectTransaction,
 2891        cx: &mut AsyncApp,
 2892    ) -> anyhow::Result<()> {
 2893        for mut action in actions {
 2894            Self::try_resolve_code_action(language_server, &mut action)
 2895                .await
 2896                .context("resolving a formatting code action")?;
 2897
 2898            if let Some(edit) = action.lsp_action.edit() {
 2899                if edit.changes.is_none() && edit.document_changes.is_none() {
 2900                    continue;
 2901                }
 2902
 2903                let new = Self::deserialize_workspace_edit(
 2904                    lsp_store.upgrade().context("project dropped")?,
 2905                    edit.clone(),
 2906                    push_to_history,
 2907                    language_server.clone(),
 2908                    cx,
 2909                )
 2910                .await?;
 2911                project_transaction.0.extend(new.0);
 2912            }
 2913
 2914            if let Some(command) = action.lsp_action.command() {
 2915                let server_capabilities = language_server.capabilities();
 2916                let available_commands = server_capabilities
 2917                    .execute_command_provider
 2918                    .as_ref()
 2919                    .map(|options| options.commands.as_slice())
 2920                    .unwrap_or_default();
 2921                if available_commands.contains(&command.command) {
 2922                    lsp_store.update(cx, |lsp_store, _| {
 2923                        if let LspStoreMode::Local(mode) = &mut lsp_store.mode {
 2924                            mode.last_workspace_edits_by_language_server
 2925                                .remove(&language_server.server_id());
 2926                        }
 2927                    })?;
 2928
 2929                    language_server
 2930                        .request::<lsp::request::ExecuteCommand>(lsp::ExecuteCommandParams {
 2931                            command: command.command.clone(),
 2932                            arguments: command.arguments.clone().unwrap_or_default(),
 2933                            ..Default::default()
 2934                        })
 2935                        .await
 2936                        .into_response()
 2937                        .context("execute command")?;
 2938
 2939                    lsp_store.update(cx, |this, _| {
 2940                        if let LspStoreMode::Local(mode) = &mut this.mode {
 2941                            project_transaction.0.extend(
 2942                                mode.last_workspace_edits_by_language_server
 2943                                    .remove(&language_server.server_id())
 2944                                    .unwrap_or_default()
 2945                                    .0,
 2946                            )
 2947                        }
 2948                    })?;
 2949                } else {
 2950                    log::warn!(
 2951                        "Cannot execute a command {} not listed in the language server capabilities",
 2952                        command.command
 2953                    )
 2954                }
 2955            }
 2956        }
 2957        Ok(())
 2958    }
 2959
 2960    pub async fn deserialize_text_edits(
 2961        this: Entity<LspStore>,
 2962        buffer_to_edit: Entity<Buffer>,
 2963        edits: Vec<lsp::TextEdit>,
 2964        push_to_history: bool,
 2965        _: Arc<CachedLspAdapter>,
 2966        language_server: Arc<LanguageServer>,
 2967        cx: &mut AsyncApp,
 2968    ) -> Result<Option<Transaction>> {
 2969        let edits = this
 2970            .update(cx, |this, cx| {
 2971                this.as_local_mut().unwrap().edits_from_lsp(
 2972                    &buffer_to_edit,
 2973                    edits,
 2974                    language_server.server_id(),
 2975                    None,
 2976                    cx,
 2977                )
 2978            })?
 2979            .await?;
 2980
 2981        let transaction = buffer_to_edit.update(cx, |buffer, cx| {
 2982            buffer.finalize_last_transaction();
 2983            buffer.start_transaction();
 2984            for (range, text) in edits {
 2985                buffer.edit([(range, text)], None, cx);
 2986            }
 2987
 2988            if buffer.end_transaction(cx).is_some() {
 2989                let transaction = buffer.finalize_last_transaction().unwrap().clone();
 2990                if !push_to_history {
 2991                    buffer.forget_transaction(transaction.id);
 2992                }
 2993                Some(transaction)
 2994            } else {
 2995                None
 2996            }
 2997        })?;
 2998
 2999        Ok(transaction)
 3000    }
 3001
 3002    #[allow(clippy::type_complexity)]
 3003    pub(crate) fn edits_from_lsp(
 3004        &mut self,
 3005        buffer: &Entity<Buffer>,
 3006        lsp_edits: impl 'static + Send + IntoIterator<Item = lsp::TextEdit>,
 3007        server_id: LanguageServerId,
 3008        version: Option<i32>,
 3009        cx: &mut Context<LspStore>,
 3010    ) -> Task<Result<Vec<(Range<Anchor>, Arc<str>)>>> {
 3011        let snapshot = self.buffer_snapshot_for_lsp_version(buffer, server_id, version, cx);
 3012        cx.background_spawn(async move {
 3013            let snapshot = snapshot?;
 3014            let mut lsp_edits = lsp_edits
 3015                .into_iter()
 3016                .map(|edit| (range_from_lsp(edit.range), edit.new_text))
 3017                .collect::<Vec<_>>();
 3018
 3019            lsp_edits.sort_by_key(|(range, _)| (range.start, range.end));
 3020
 3021            let mut lsp_edits = lsp_edits.into_iter().peekable();
 3022            let mut edits = Vec::new();
 3023            while let Some((range, mut new_text)) = lsp_edits.next() {
 3024                // Clip invalid ranges provided by the language server.
 3025                let mut range = snapshot.clip_point_utf16(range.start, Bias::Left)
 3026                    ..snapshot.clip_point_utf16(range.end, Bias::Left);
 3027
 3028                // Combine any LSP edits that are adjacent.
 3029                //
 3030                // Also, combine LSP edits that are separated from each other by only
 3031                // a newline. This is important because for some code actions,
 3032                // Rust-analyzer rewrites the entire buffer via a series of edits that
 3033                // are separated by unchanged newline characters.
 3034                //
 3035                // In order for the diffing logic below to work properly, any edits that
 3036                // cancel each other out must be combined into one.
 3037                while let Some((next_range, next_text)) = lsp_edits.peek() {
 3038                    if next_range.start.0 > range.end {
 3039                        if next_range.start.0.row > range.end.row + 1
 3040                            || next_range.start.0.column > 0
 3041                            || snapshot.clip_point_utf16(
 3042                                Unclipped(PointUtf16::new(range.end.row, u32::MAX)),
 3043                                Bias::Left,
 3044                            ) > range.end
 3045                        {
 3046                            break;
 3047                        }
 3048                        new_text.push('\n');
 3049                    }
 3050                    range.end = snapshot.clip_point_utf16(next_range.end, Bias::Left);
 3051                    new_text.push_str(next_text);
 3052                    lsp_edits.next();
 3053                }
 3054
 3055                // For multiline edits, perform a diff of the old and new text so that
 3056                // we can identify the changes more precisely, preserving the locations
 3057                // of any anchors positioned in the unchanged regions.
 3058                if range.end.row > range.start.row {
 3059                    let offset = range.start.to_offset(&snapshot);
 3060                    let old_text = snapshot.text_for_range(range).collect::<String>();
 3061                    let range_edits = language::text_diff(old_text.as_str(), &new_text);
 3062                    edits.extend(range_edits.into_iter().map(|(range, replacement)| {
 3063                        (
 3064                            snapshot.anchor_after(offset + range.start)
 3065                                ..snapshot.anchor_before(offset + range.end),
 3066                            replacement,
 3067                        )
 3068                    }));
 3069                } else if range.end == range.start {
 3070                    let anchor = snapshot.anchor_after(range.start);
 3071                    edits.push((anchor..anchor, new_text.into()));
 3072                } else {
 3073                    let edit_start = snapshot.anchor_after(range.start);
 3074                    let edit_end = snapshot.anchor_before(range.end);
 3075                    edits.push((edit_start..edit_end, new_text.into()));
 3076                }
 3077            }
 3078
 3079            Ok(edits)
 3080        })
 3081    }
 3082
 3083    pub(crate) async fn deserialize_workspace_edit(
 3084        this: Entity<LspStore>,
 3085        edit: lsp::WorkspaceEdit,
 3086        push_to_history: bool,
 3087        language_server: Arc<LanguageServer>,
 3088        cx: &mut AsyncApp,
 3089    ) -> Result<ProjectTransaction> {
 3090        let fs = this.read_with(cx, |this, _| this.as_local().unwrap().fs.clone())?;
 3091
 3092        let mut operations = Vec::new();
 3093        if let Some(document_changes) = edit.document_changes {
 3094            match document_changes {
 3095                lsp::DocumentChanges::Edits(edits) => {
 3096                    operations.extend(edits.into_iter().map(lsp::DocumentChangeOperation::Edit))
 3097                }
 3098                lsp::DocumentChanges::Operations(ops) => operations = ops,
 3099            }
 3100        } else if let Some(changes) = edit.changes {
 3101            operations.extend(changes.into_iter().map(|(uri, edits)| {
 3102                lsp::DocumentChangeOperation::Edit(lsp::TextDocumentEdit {
 3103                    text_document: lsp::OptionalVersionedTextDocumentIdentifier {
 3104                        uri,
 3105                        version: None,
 3106                    },
 3107                    edits: edits.into_iter().map(Edit::Plain).collect(),
 3108                })
 3109            }));
 3110        }
 3111
 3112        let mut project_transaction = ProjectTransaction::default();
 3113        for operation in operations {
 3114            match operation {
 3115                lsp::DocumentChangeOperation::Op(lsp::ResourceOp::Create(op)) => {
 3116                    let abs_path = op
 3117                        .uri
 3118                        .to_file_path()
 3119                        .map_err(|()| anyhow!("can't convert URI to path"))?;
 3120
 3121                    if let Some(parent_path) = abs_path.parent() {
 3122                        fs.create_dir(parent_path).await?;
 3123                    }
 3124                    if abs_path.ends_with("/") {
 3125                        fs.create_dir(&abs_path).await?;
 3126                    } else {
 3127                        fs.create_file(
 3128                            &abs_path,
 3129                            op.options
 3130                                .map(|options| fs::CreateOptions {
 3131                                    overwrite: options.overwrite.unwrap_or(false),
 3132                                    ignore_if_exists: options.ignore_if_exists.unwrap_or(false),
 3133                                })
 3134                                .unwrap_or_default(),
 3135                        )
 3136                        .await?;
 3137                    }
 3138                }
 3139
 3140                lsp::DocumentChangeOperation::Op(lsp::ResourceOp::Rename(op)) => {
 3141                    let source_abs_path = op
 3142                        .old_uri
 3143                        .to_file_path()
 3144                        .map_err(|()| anyhow!("can't convert URI to path"))?;
 3145                    let target_abs_path = op
 3146                        .new_uri
 3147                        .to_file_path()
 3148                        .map_err(|()| anyhow!("can't convert URI to path"))?;
 3149
 3150                    let options = fs::RenameOptions {
 3151                        overwrite: op
 3152                            .options
 3153                            .as_ref()
 3154                            .and_then(|options| options.overwrite)
 3155                            .unwrap_or(false),
 3156                        ignore_if_exists: op
 3157                            .options
 3158                            .as_ref()
 3159                            .and_then(|options| options.ignore_if_exists)
 3160                            .unwrap_or(false),
 3161                        create_parents: true,
 3162                    };
 3163
 3164                    fs.rename(&source_abs_path, &target_abs_path, options)
 3165                        .await?;
 3166                }
 3167
 3168                lsp::DocumentChangeOperation::Op(lsp::ResourceOp::Delete(op)) => {
 3169                    let abs_path = op
 3170                        .uri
 3171                        .to_file_path()
 3172                        .map_err(|()| anyhow!("can't convert URI to path"))?;
 3173                    let options = op
 3174                        .options
 3175                        .map(|options| fs::RemoveOptions {
 3176                            recursive: options.recursive.unwrap_or(false),
 3177                            ignore_if_not_exists: options.ignore_if_not_exists.unwrap_or(false),
 3178                        })
 3179                        .unwrap_or_default();
 3180                    if abs_path.ends_with("/") {
 3181                        fs.remove_dir(&abs_path, options).await?;
 3182                    } else {
 3183                        fs.remove_file(&abs_path, options).await?;
 3184                    }
 3185                }
 3186
 3187                lsp::DocumentChangeOperation::Edit(op) => {
 3188                    let buffer_to_edit = this
 3189                        .update(cx, |this, cx| {
 3190                            this.open_local_buffer_via_lsp(
 3191                                op.text_document.uri.clone(),
 3192                                language_server.server_id(),
 3193                                cx,
 3194                            )
 3195                        })?
 3196                        .await?;
 3197
 3198                    let edits = this
 3199                        .update(cx, |this, cx| {
 3200                            let path = buffer_to_edit.read(cx).project_path(cx);
 3201                            let active_entry = this.active_entry;
 3202                            let is_active_entry = path.is_some_and(|project_path| {
 3203                                this.worktree_store
 3204                                    .read(cx)
 3205                                    .entry_for_path(&project_path, cx)
 3206                                    .is_some_and(|entry| Some(entry.id) == active_entry)
 3207                            });
 3208                            let local = this.as_local_mut().unwrap();
 3209
 3210                            let (mut edits, mut snippet_edits) = (vec![], vec![]);
 3211                            for edit in op.edits {
 3212                                match edit {
 3213                                    Edit::Plain(edit) => {
 3214                                        if !edits.contains(&edit) {
 3215                                            edits.push(edit)
 3216                                        }
 3217                                    }
 3218                                    Edit::Annotated(edit) => {
 3219                                        if !edits.contains(&edit.text_edit) {
 3220                                            edits.push(edit.text_edit)
 3221                                        }
 3222                                    }
 3223                                    Edit::Snippet(edit) => {
 3224                                        let Ok(snippet) = Snippet::parse(&edit.snippet.value)
 3225                                        else {
 3226                                            continue;
 3227                                        };
 3228
 3229                                        if is_active_entry {
 3230                                            snippet_edits.push((edit.range, snippet));
 3231                                        } else {
 3232                                            // Since this buffer is not focused, apply a normal edit.
 3233                                            let new_edit = TextEdit {
 3234                                                range: edit.range,
 3235                                                new_text: snippet.text,
 3236                                            };
 3237                                            if !edits.contains(&new_edit) {
 3238                                                edits.push(new_edit);
 3239                                            }
 3240                                        }
 3241                                    }
 3242                                }
 3243                            }
 3244                            if !snippet_edits.is_empty() {
 3245                                let buffer_id = buffer_to_edit.read(cx).remote_id();
 3246                                let version = if let Some(buffer_version) = op.text_document.version
 3247                                {
 3248                                    local
 3249                                        .buffer_snapshot_for_lsp_version(
 3250                                            &buffer_to_edit,
 3251                                            language_server.server_id(),
 3252                                            Some(buffer_version),
 3253                                            cx,
 3254                                        )
 3255                                        .ok()
 3256                                        .map(|snapshot| snapshot.version)
 3257                                } else {
 3258                                    Some(buffer_to_edit.read(cx).saved_version().clone())
 3259                                };
 3260
 3261                                let most_recent_edit =
 3262                                    version.and_then(|version| version.most_recent());
 3263                                // Check if the edit that triggered that edit has been made by this participant.
 3264
 3265                                if let Some(most_recent_edit) = most_recent_edit {
 3266                                    cx.emit(LspStoreEvent::SnippetEdit {
 3267                                        buffer_id,
 3268                                        edits: snippet_edits,
 3269                                        most_recent_edit,
 3270                                    });
 3271                                }
 3272                            }
 3273
 3274                            local.edits_from_lsp(
 3275                                &buffer_to_edit,
 3276                                edits,
 3277                                language_server.server_id(),
 3278                                op.text_document.version,
 3279                                cx,
 3280                            )
 3281                        })?
 3282                        .await?;
 3283
 3284                    let transaction = buffer_to_edit.update(cx, |buffer, cx| {
 3285                        buffer.finalize_last_transaction();
 3286                        buffer.start_transaction();
 3287                        for (range, text) in edits {
 3288                            buffer.edit([(range, text)], None, cx);
 3289                        }
 3290
 3291                        buffer.end_transaction(cx).and_then(|transaction_id| {
 3292                            if push_to_history {
 3293                                buffer.finalize_last_transaction();
 3294                                buffer.get_transaction(transaction_id).cloned()
 3295                            } else {
 3296                                buffer.forget_transaction(transaction_id)
 3297                            }
 3298                        })
 3299                    })?;
 3300                    if let Some(transaction) = transaction {
 3301                        project_transaction.0.insert(buffer_to_edit, transaction);
 3302                    }
 3303                }
 3304            }
 3305        }
 3306
 3307        Ok(project_transaction)
 3308    }
 3309
 3310    async fn on_lsp_workspace_edit(
 3311        this: WeakEntity<LspStore>,
 3312        params: lsp::ApplyWorkspaceEditParams,
 3313        server_id: LanguageServerId,
 3314        cx: &mut AsyncApp,
 3315    ) -> Result<lsp::ApplyWorkspaceEditResponse> {
 3316        let this = this.upgrade().context("project project closed")?;
 3317        let language_server = this
 3318            .read_with(cx, |this, _| this.language_server_for_id(server_id))?
 3319            .context("language server not found")?;
 3320        let transaction = Self::deserialize_workspace_edit(
 3321            this.clone(),
 3322            params.edit,
 3323            true,
 3324            language_server.clone(),
 3325            cx,
 3326        )
 3327        .await
 3328        .log_err();
 3329        this.update(cx, |this, _| {
 3330            if let Some(transaction) = transaction {
 3331                this.as_local_mut()
 3332                    .unwrap()
 3333                    .last_workspace_edits_by_language_server
 3334                    .insert(server_id, transaction);
 3335            }
 3336        })?;
 3337        Ok(lsp::ApplyWorkspaceEditResponse {
 3338            applied: true,
 3339            failed_change: None,
 3340            failure_reason: None,
 3341        })
 3342    }
 3343
 3344    fn remove_worktree(
 3345        &mut self,
 3346        id_to_remove: WorktreeId,
 3347        cx: &mut Context<LspStore>,
 3348    ) -> Vec<LanguageServerId> {
 3349        self.restricted_worktrees_tasks.remove(&id_to_remove);
 3350        self.diagnostics.remove(&id_to_remove);
 3351        self.prettier_store.update(cx, |prettier_store, cx| {
 3352            prettier_store.remove_worktree(id_to_remove, cx);
 3353        });
 3354
 3355        let mut servers_to_remove = BTreeSet::default();
 3356        let mut servers_to_preserve = HashSet::default();
 3357        for (seed, state) in &self.language_server_ids {
 3358            if seed.worktree_id == id_to_remove {
 3359                servers_to_remove.insert(state.id);
 3360            } else {
 3361                servers_to_preserve.insert(state.id);
 3362            }
 3363        }
 3364        servers_to_remove.retain(|server_id| !servers_to_preserve.contains(server_id));
 3365        self.language_server_ids
 3366            .retain(|_, state| !servers_to_remove.contains(&state.id));
 3367        for server_id_to_remove in &servers_to_remove {
 3368            self.language_server_watched_paths
 3369                .remove(server_id_to_remove);
 3370            self.language_server_paths_watched_for_rename
 3371                .remove(server_id_to_remove);
 3372            self.last_workspace_edits_by_language_server
 3373                .remove(server_id_to_remove);
 3374            self.language_servers.remove(server_id_to_remove);
 3375            self.buffer_pull_diagnostics_result_ids
 3376                .remove(server_id_to_remove);
 3377            self.workspace_pull_diagnostics_result_ids
 3378                .remove(server_id_to_remove);
 3379            for buffer_servers in self.buffers_opened_in_servers.values_mut() {
 3380                buffer_servers.remove(server_id_to_remove);
 3381            }
 3382            cx.emit(LspStoreEvent::LanguageServerRemoved(*server_id_to_remove));
 3383        }
 3384        servers_to_remove.into_iter().collect()
 3385    }
 3386
 3387    fn rebuild_watched_paths_inner<'a>(
 3388        &'a self,
 3389        language_server_id: LanguageServerId,
 3390        watchers: impl Iterator<Item = &'a FileSystemWatcher>,
 3391        cx: &mut Context<LspStore>,
 3392    ) -> LanguageServerWatchedPathsBuilder {
 3393        let worktrees = self
 3394            .worktree_store
 3395            .read(cx)
 3396            .worktrees()
 3397            .filter_map(|worktree| {
 3398                self.language_servers_for_worktree(worktree.read(cx).id())
 3399                    .find(|server| server.server_id() == language_server_id)
 3400                    .map(|_| worktree)
 3401            })
 3402            .collect::<Vec<_>>();
 3403
 3404        let mut worktree_globs = HashMap::default();
 3405        let mut abs_globs = HashMap::default();
 3406        log::trace!(
 3407            "Processing new watcher paths for language server with id {}",
 3408            language_server_id
 3409        );
 3410
 3411        for watcher in watchers {
 3412            if let Some((worktree, literal_prefix, pattern)) =
 3413                Self::worktree_and_path_for_file_watcher(&worktrees, watcher, cx)
 3414            {
 3415                worktree.update(cx, |worktree, _| {
 3416                    if let Some((tree, glob)) =
 3417                        worktree.as_local_mut().zip(Glob::new(&pattern).log_err())
 3418                    {
 3419                        tree.add_path_prefix_to_scan(literal_prefix);
 3420                        worktree_globs
 3421                            .entry(tree.id())
 3422                            .or_insert_with(GlobSetBuilder::new)
 3423                            .add(glob);
 3424                    }
 3425                });
 3426            } else {
 3427                let (path, pattern) = match &watcher.glob_pattern {
 3428                    lsp::GlobPattern::String(s) => {
 3429                        let watcher_path = SanitizedPath::new(s);
 3430                        let path = glob_literal_prefix(watcher_path.as_path());
 3431                        let pattern = watcher_path
 3432                            .as_path()
 3433                            .strip_prefix(&path)
 3434                            .map(|p| p.to_string_lossy().into_owned())
 3435                            .unwrap_or_else(|e| {
 3436                                debug_panic!(
 3437                                    "Failed to strip prefix for string pattern: {}, with prefix: {}, with error: {}",
 3438                                    s,
 3439                                    path.display(),
 3440                                    e
 3441                                );
 3442                                watcher_path.as_path().to_string_lossy().into_owned()
 3443                            });
 3444                        (path, pattern)
 3445                    }
 3446                    lsp::GlobPattern::Relative(rp) => {
 3447                        let Ok(mut base_uri) = match &rp.base_uri {
 3448                            lsp::OneOf::Left(workspace_folder) => &workspace_folder.uri,
 3449                            lsp::OneOf::Right(base_uri) => base_uri,
 3450                        }
 3451                        .to_file_path() else {
 3452                            continue;
 3453                        };
 3454
 3455                        let path = glob_literal_prefix(Path::new(&rp.pattern));
 3456                        let pattern = Path::new(&rp.pattern)
 3457                            .strip_prefix(&path)
 3458                            .map(|p| p.to_string_lossy().into_owned())
 3459                            .unwrap_or_else(|e| {
 3460                                debug_panic!(
 3461                                    "Failed to strip prefix for relative pattern: {}, with prefix: {}, with error: {}",
 3462                                    rp.pattern,
 3463                                    path.display(),
 3464                                    e
 3465                                );
 3466                                rp.pattern.clone()
 3467                            });
 3468                        base_uri.push(path);
 3469                        (base_uri, pattern)
 3470                    }
 3471                };
 3472
 3473                if let Some(glob) = Glob::new(&pattern).log_err() {
 3474                    if !path
 3475                        .components()
 3476                        .any(|c| matches!(c, path::Component::Normal(_)))
 3477                    {
 3478                        // For an unrooted glob like `**/Cargo.toml`, watch it within each worktree,
 3479                        // rather than adding a new watcher for `/`.
 3480                        for worktree in &worktrees {
 3481                            worktree_globs
 3482                                .entry(worktree.read(cx).id())
 3483                                .or_insert_with(GlobSetBuilder::new)
 3484                                .add(glob.clone());
 3485                        }
 3486                    } else {
 3487                        abs_globs
 3488                            .entry(path.into())
 3489                            .or_insert_with(GlobSetBuilder::new)
 3490                            .add(glob);
 3491                    }
 3492                }
 3493            }
 3494        }
 3495
 3496        let mut watch_builder = LanguageServerWatchedPathsBuilder::default();
 3497        for (worktree_id, builder) in worktree_globs {
 3498            if let Ok(globset) = builder.build() {
 3499                watch_builder.watch_worktree(worktree_id, globset);
 3500            }
 3501        }
 3502        for (abs_path, builder) in abs_globs {
 3503            if let Ok(globset) = builder.build() {
 3504                watch_builder.watch_abs_path(abs_path, globset);
 3505            }
 3506        }
 3507        watch_builder
 3508    }
 3509
 3510    fn worktree_and_path_for_file_watcher(
 3511        worktrees: &[Entity<Worktree>],
 3512        watcher: &FileSystemWatcher,
 3513        cx: &App,
 3514    ) -> Option<(Entity<Worktree>, Arc<RelPath>, String)> {
 3515        worktrees.iter().find_map(|worktree| {
 3516            let tree = worktree.read(cx);
 3517            let worktree_root_path = tree.abs_path();
 3518            let path_style = tree.path_style();
 3519            match &watcher.glob_pattern {
 3520                lsp::GlobPattern::String(s) => {
 3521                    let watcher_path = SanitizedPath::new(s);
 3522                    let relative = watcher_path
 3523                        .as_path()
 3524                        .strip_prefix(&worktree_root_path)
 3525                        .ok()?;
 3526                    let literal_prefix = glob_literal_prefix(relative);
 3527                    Some((
 3528                        worktree.clone(),
 3529                        RelPath::new(&literal_prefix, path_style).ok()?.into_arc(),
 3530                        relative.to_string_lossy().into_owned(),
 3531                    ))
 3532                }
 3533                lsp::GlobPattern::Relative(rp) => {
 3534                    let base_uri = match &rp.base_uri {
 3535                        lsp::OneOf::Left(workspace_folder) => &workspace_folder.uri,
 3536                        lsp::OneOf::Right(base_uri) => base_uri,
 3537                    }
 3538                    .to_file_path()
 3539                    .ok()?;
 3540                    let relative = base_uri.strip_prefix(&worktree_root_path).ok()?;
 3541                    let mut literal_prefix = relative.to_owned();
 3542                    literal_prefix.push(glob_literal_prefix(Path::new(&rp.pattern)));
 3543                    Some((
 3544                        worktree.clone(),
 3545                        RelPath::new(&literal_prefix, path_style).ok()?.into_arc(),
 3546                        rp.pattern.clone(),
 3547                    ))
 3548                }
 3549            }
 3550        })
 3551    }
 3552
 3553    fn rebuild_watched_paths(
 3554        &mut self,
 3555        language_server_id: LanguageServerId,
 3556        cx: &mut Context<LspStore>,
 3557    ) {
 3558        let Some(registrations) = self
 3559            .language_server_dynamic_registrations
 3560            .get(&language_server_id)
 3561        else {
 3562            return;
 3563        };
 3564
 3565        let watch_builder = self.rebuild_watched_paths_inner(
 3566            language_server_id,
 3567            registrations.did_change_watched_files.values().flatten(),
 3568            cx,
 3569        );
 3570        let watcher = watch_builder.build(self.fs.clone(), language_server_id, cx);
 3571        self.language_server_watched_paths
 3572            .insert(language_server_id, watcher);
 3573
 3574        cx.notify();
 3575    }
 3576
 3577    fn on_lsp_did_change_watched_files(
 3578        &mut self,
 3579        language_server_id: LanguageServerId,
 3580        registration_id: &str,
 3581        params: DidChangeWatchedFilesRegistrationOptions,
 3582        cx: &mut Context<LspStore>,
 3583    ) {
 3584        let registrations = self
 3585            .language_server_dynamic_registrations
 3586            .entry(language_server_id)
 3587            .or_default();
 3588
 3589        registrations
 3590            .did_change_watched_files
 3591            .insert(registration_id.to_string(), params.watchers);
 3592
 3593        self.rebuild_watched_paths(language_server_id, cx);
 3594    }
 3595
 3596    fn on_lsp_unregister_did_change_watched_files(
 3597        &mut self,
 3598        language_server_id: LanguageServerId,
 3599        registration_id: &str,
 3600        cx: &mut Context<LspStore>,
 3601    ) {
 3602        let registrations = self
 3603            .language_server_dynamic_registrations
 3604            .entry(language_server_id)
 3605            .or_default();
 3606
 3607        if registrations
 3608            .did_change_watched_files
 3609            .remove(registration_id)
 3610            .is_some()
 3611        {
 3612            log::info!(
 3613                "language server {}: unregistered workspace/DidChangeWatchedFiles capability with id {}",
 3614                language_server_id,
 3615                registration_id
 3616            );
 3617        } else {
 3618            log::warn!(
 3619                "language server {}: failed to unregister workspace/DidChangeWatchedFiles capability with id {}. not registered.",
 3620                language_server_id,
 3621                registration_id
 3622            );
 3623        }
 3624
 3625        self.rebuild_watched_paths(language_server_id, cx);
 3626    }
 3627
 3628    async fn initialization_options_for_adapter(
 3629        adapter: Arc<dyn LspAdapter>,
 3630        delegate: &Arc<dyn LspAdapterDelegate>,
 3631    ) -> Result<Option<serde_json::Value>> {
 3632        let Some(mut initialization_config) =
 3633            adapter.clone().initialization_options(delegate).await?
 3634        else {
 3635            return Ok(None);
 3636        };
 3637
 3638        for other_adapter in delegate.registered_lsp_adapters() {
 3639            if other_adapter.name() == adapter.name() {
 3640                continue;
 3641            }
 3642            if let Ok(Some(target_config)) = other_adapter
 3643                .clone()
 3644                .additional_initialization_options(adapter.name(), delegate)
 3645                .await
 3646            {
 3647                merge_json_value_into(target_config.clone(), &mut initialization_config);
 3648            }
 3649        }
 3650
 3651        Ok(Some(initialization_config))
 3652    }
 3653
 3654    async fn workspace_configuration_for_adapter(
 3655        adapter: Arc<dyn LspAdapter>,
 3656        delegate: &Arc<dyn LspAdapterDelegate>,
 3657        toolchain: Option<Toolchain>,
 3658        requested_uri: Option<Uri>,
 3659        cx: &mut AsyncApp,
 3660    ) -> Result<serde_json::Value> {
 3661        let mut workspace_config = adapter
 3662            .clone()
 3663            .workspace_configuration(delegate, toolchain, requested_uri, cx)
 3664            .await?;
 3665
 3666        for other_adapter in delegate.registered_lsp_adapters() {
 3667            if other_adapter.name() == adapter.name() {
 3668                continue;
 3669            }
 3670            if let Ok(Some(target_config)) = other_adapter
 3671                .clone()
 3672                .additional_workspace_configuration(adapter.name(), delegate, cx)
 3673                .await
 3674            {
 3675                merge_json_value_into(target_config.clone(), &mut workspace_config);
 3676            }
 3677        }
 3678
 3679        Ok(workspace_config)
 3680    }
 3681
 3682    fn language_server_for_id(&self, id: LanguageServerId) -> Option<Arc<LanguageServer>> {
 3683        if let Some(LanguageServerState::Running { server, .. }) = self.language_servers.get(&id) {
 3684            Some(server.clone())
 3685        } else if let Some((_, server)) = self.supplementary_language_servers.get(&id) {
 3686            Some(Arc::clone(server))
 3687        } else {
 3688            None
 3689        }
 3690    }
 3691}
 3692
 3693fn notify_server_capabilities_updated(server: &LanguageServer, cx: &mut Context<LspStore>) {
 3694    if let Some(capabilities) = serde_json::to_string(&server.capabilities()).ok() {
 3695        cx.emit(LspStoreEvent::LanguageServerUpdate {
 3696            language_server_id: server.server_id(),
 3697            name: Some(server.name()),
 3698            message: proto::update_language_server::Variant::MetadataUpdated(
 3699                proto::ServerMetadataUpdated {
 3700                    capabilities: Some(capabilities),
 3701                    binary: Some(proto::LanguageServerBinaryInfo {
 3702                        path: server.binary().path.to_string_lossy().into_owned(),
 3703                        arguments: server
 3704                            .binary()
 3705                            .arguments
 3706                            .iter()
 3707                            .map(|arg| arg.to_string_lossy().into_owned())
 3708                            .collect(),
 3709                    }),
 3710                    configuration: serde_json::to_string(server.configuration()).ok(),
 3711                    workspace_folders: server
 3712                        .workspace_folders()
 3713                        .iter()
 3714                        .map(|uri| uri.to_string())
 3715                        .collect(),
 3716                },
 3717            ),
 3718        });
 3719    }
 3720}
 3721
 3722#[derive(Debug)]
 3723pub struct FormattableBuffer {
 3724    handle: Entity<Buffer>,
 3725    abs_path: Option<PathBuf>,
 3726    env: Option<HashMap<String, String>>,
 3727    ranges: Option<Vec<Range<Anchor>>>,
 3728}
 3729
 3730pub struct RemoteLspStore {
 3731    upstream_client: Option<AnyProtoClient>,
 3732    upstream_project_id: u64,
 3733}
 3734
 3735pub(crate) enum LspStoreMode {
 3736    Local(LocalLspStore),   // ssh host and collab host
 3737    Remote(RemoteLspStore), // collab guest
 3738}
 3739
 3740impl LspStoreMode {
 3741    fn is_local(&self) -> bool {
 3742        matches!(self, LspStoreMode::Local(_))
 3743    }
 3744}
 3745
 3746pub struct LspStore {
 3747    mode: LspStoreMode,
 3748    last_formatting_failure: Option<String>,
 3749    downstream_client: Option<(AnyProtoClient, u64)>,
 3750    nonce: u128,
 3751    buffer_store: Entity<BufferStore>,
 3752    worktree_store: Entity<WorktreeStore>,
 3753    pub languages: Arc<LanguageRegistry>,
 3754    pub language_server_statuses: BTreeMap<LanguageServerId, LanguageServerStatus>,
 3755    active_entry: Option<ProjectEntryId>,
 3756    _maintain_workspace_config: (Task<Result<()>>, watch::Sender<()>),
 3757    _maintain_buffer_languages: Task<()>,
 3758    diagnostic_summaries:
 3759        HashMap<WorktreeId, HashMap<Arc<RelPath>, HashMap<LanguageServerId, DiagnosticSummary>>>,
 3760    pub lsp_server_capabilities: HashMap<LanguageServerId, lsp::ServerCapabilities>,
 3761    lsp_data: HashMap<BufferId, BufferLspData>,
 3762    next_hint_id: Arc<AtomicUsize>,
 3763}
 3764
 3765#[derive(Debug)]
 3766pub struct BufferLspData {
 3767    buffer_version: Global,
 3768    document_colors: Option<DocumentColorData>,
 3769    code_lens: Option<CodeLensData>,
 3770    inlay_hints: BufferInlayHints,
 3771    lsp_requests: HashMap<LspKey, HashMap<LspRequestId, Task<()>>>,
 3772    chunk_lsp_requests: HashMap<LspKey, HashMap<RowChunk, LspRequestId>>,
 3773}
 3774
 3775#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
 3776struct LspKey {
 3777    request_type: TypeId,
 3778    server_queried: Option<LanguageServerId>,
 3779}
 3780
 3781impl BufferLspData {
 3782    fn new(buffer: &Entity<Buffer>, cx: &mut App) -> Self {
 3783        Self {
 3784            buffer_version: buffer.read(cx).version(),
 3785            document_colors: None,
 3786            code_lens: None,
 3787            inlay_hints: BufferInlayHints::new(buffer, cx),
 3788            lsp_requests: HashMap::default(),
 3789            chunk_lsp_requests: HashMap::default(),
 3790        }
 3791    }
 3792
 3793    fn remove_server_data(&mut self, for_server: LanguageServerId) {
 3794        if let Some(document_colors) = &mut self.document_colors {
 3795            document_colors.colors.remove(&for_server);
 3796            document_colors.cache_version += 1;
 3797        }
 3798
 3799        if let Some(code_lens) = &mut self.code_lens {
 3800            code_lens.lens.remove(&for_server);
 3801        }
 3802
 3803        self.inlay_hints.remove_server_data(for_server);
 3804    }
 3805
 3806    #[cfg(any(test, feature = "test-support"))]
 3807    pub fn inlay_hints(&self) -> &BufferInlayHints {
 3808        &self.inlay_hints
 3809    }
 3810}
 3811
 3812#[derive(Debug, Default, Clone)]
 3813pub struct DocumentColors {
 3814    pub colors: HashSet<DocumentColor>,
 3815    pub cache_version: Option<usize>,
 3816}
 3817
 3818type DocumentColorTask = Shared<Task<std::result::Result<DocumentColors, Arc<anyhow::Error>>>>;
 3819type CodeLensTask = Shared<Task<std::result::Result<Option<Vec<CodeAction>>, Arc<anyhow::Error>>>>;
 3820
 3821#[derive(Debug, Default)]
 3822struct DocumentColorData {
 3823    colors: HashMap<LanguageServerId, HashSet<DocumentColor>>,
 3824    cache_version: usize,
 3825    colors_update: Option<(Global, DocumentColorTask)>,
 3826}
 3827
 3828#[derive(Debug, Default)]
 3829struct CodeLensData {
 3830    lens: HashMap<LanguageServerId, Vec<CodeAction>>,
 3831    update: Option<(Global, CodeLensTask)>,
 3832}
 3833
 3834#[derive(Debug)]
 3835pub enum LspStoreEvent {
 3836    LanguageServerAdded(LanguageServerId, LanguageServerName, Option<WorktreeId>),
 3837    LanguageServerRemoved(LanguageServerId),
 3838    LanguageServerUpdate {
 3839        language_server_id: LanguageServerId,
 3840        name: Option<LanguageServerName>,
 3841        message: proto::update_language_server::Variant,
 3842    },
 3843    LanguageServerLog(LanguageServerId, LanguageServerLogType, String),
 3844    LanguageServerPrompt(LanguageServerPromptRequest),
 3845    LanguageDetected {
 3846        buffer: Entity<Buffer>,
 3847        new_language: Option<Arc<Language>>,
 3848    },
 3849    Notification(String),
 3850    RefreshInlayHints {
 3851        server_id: LanguageServerId,
 3852        request_id: Option<usize>,
 3853    },
 3854    RefreshCodeLens,
 3855    DiagnosticsUpdated {
 3856        server_id: LanguageServerId,
 3857        paths: Vec<ProjectPath>,
 3858    },
 3859    DiskBasedDiagnosticsStarted {
 3860        language_server_id: LanguageServerId,
 3861    },
 3862    DiskBasedDiagnosticsFinished {
 3863        language_server_id: LanguageServerId,
 3864    },
 3865    SnippetEdit {
 3866        buffer_id: BufferId,
 3867        edits: Vec<(lsp::Range, Snippet)>,
 3868        most_recent_edit: clock::Lamport,
 3869    },
 3870}
 3871
 3872#[derive(Clone, Debug, Serialize)]
 3873pub struct LanguageServerStatus {
 3874    pub name: LanguageServerName,
 3875    pub pending_work: BTreeMap<ProgressToken, LanguageServerProgress>,
 3876    pub has_pending_diagnostic_updates: bool,
 3877    pub progress_tokens: HashSet<ProgressToken>,
 3878    pub worktree: Option<WorktreeId>,
 3879    pub binary: Option<LanguageServerBinary>,
 3880    pub configuration: Option<Value>,
 3881    pub workspace_folders: BTreeSet<Uri>,
 3882}
 3883
 3884#[derive(Clone, Debug)]
 3885struct CoreSymbol {
 3886    pub language_server_name: LanguageServerName,
 3887    pub source_worktree_id: WorktreeId,
 3888    pub source_language_server_id: LanguageServerId,
 3889    pub path: SymbolLocation,
 3890    pub name: String,
 3891    pub kind: lsp::SymbolKind,
 3892    pub range: Range<Unclipped<PointUtf16>>,
 3893}
 3894
 3895#[derive(Clone, Debug, PartialEq, Eq)]
 3896pub enum SymbolLocation {
 3897    InProject(ProjectPath),
 3898    OutsideProject {
 3899        abs_path: Arc<Path>,
 3900        signature: [u8; 32],
 3901    },
 3902}
 3903
 3904impl SymbolLocation {
 3905    fn file_name(&self) -> Option<&str> {
 3906        match self {
 3907            Self::InProject(path) => path.path.file_name(),
 3908            Self::OutsideProject { abs_path, .. } => abs_path.file_name()?.to_str(),
 3909        }
 3910    }
 3911}
 3912
 3913impl LspStore {
 3914    pub fn init(client: &AnyProtoClient) {
 3915        client.add_entity_request_handler(Self::handle_lsp_query);
 3916        client.add_entity_message_handler(Self::handle_lsp_query_response);
 3917        client.add_entity_request_handler(Self::handle_restart_language_servers);
 3918        client.add_entity_request_handler(Self::handle_stop_language_servers);
 3919        client.add_entity_request_handler(Self::handle_cancel_language_server_work);
 3920        client.add_entity_message_handler(Self::handle_start_language_server);
 3921        client.add_entity_message_handler(Self::handle_update_language_server);
 3922        client.add_entity_message_handler(Self::handle_language_server_log);
 3923        client.add_entity_message_handler(Self::handle_update_diagnostic_summary);
 3924        client.add_entity_request_handler(Self::handle_format_buffers);
 3925        client.add_entity_request_handler(Self::handle_apply_code_action_kind);
 3926        client.add_entity_request_handler(Self::handle_resolve_completion_documentation);
 3927        client.add_entity_request_handler(Self::handle_apply_code_action);
 3928        client.add_entity_request_handler(Self::handle_get_project_symbols);
 3929        client.add_entity_request_handler(Self::handle_resolve_inlay_hint);
 3930        client.add_entity_request_handler(Self::handle_get_color_presentation);
 3931        client.add_entity_request_handler(Self::handle_open_buffer_for_symbol);
 3932        client.add_entity_request_handler(Self::handle_refresh_inlay_hints);
 3933        client.add_entity_request_handler(Self::handle_refresh_code_lens);
 3934        client.add_entity_request_handler(Self::handle_on_type_formatting);
 3935        client.add_entity_request_handler(Self::handle_apply_additional_edits_for_completion);
 3936        client.add_entity_request_handler(Self::handle_register_buffer_with_language_servers);
 3937        client.add_entity_request_handler(Self::handle_rename_project_entry);
 3938        client.add_entity_request_handler(Self::handle_pull_workspace_diagnostics);
 3939        client.add_entity_request_handler(Self::handle_lsp_get_completions);
 3940        client.add_entity_request_handler(Self::handle_lsp_command::<GetDocumentHighlights>);
 3941        client.add_entity_request_handler(Self::handle_lsp_command::<GetDocumentSymbols>);
 3942        client.add_entity_request_handler(Self::handle_lsp_command::<PrepareRename>);
 3943        client.add_entity_request_handler(Self::handle_lsp_command::<PerformRename>);
 3944        client.add_entity_request_handler(Self::handle_lsp_command::<LinkedEditingRange>);
 3945
 3946        client.add_entity_request_handler(Self::handle_lsp_ext_cancel_flycheck);
 3947        client.add_entity_request_handler(Self::handle_lsp_ext_run_flycheck);
 3948        client.add_entity_request_handler(Self::handle_lsp_ext_clear_flycheck);
 3949        client.add_entity_request_handler(Self::handle_lsp_command::<lsp_ext_command::ExpandMacro>);
 3950        client.add_entity_request_handler(Self::handle_lsp_command::<lsp_ext_command::OpenDocs>);
 3951        client.add_entity_request_handler(
 3952            Self::handle_lsp_command::<lsp_ext_command::GoToParentModule>,
 3953        );
 3954        client.add_entity_request_handler(
 3955            Self::handle_lsp_command::<lsp_ext_command::GetLspRunnables>,
 3956        );
 3957        client.add_entity_request_handler(
 3958            Self::handle_lsp_command::<lsp_ext_command::SwitchSourceHeader>,
 3959        );
 3960    }
 3961
 3962    pub fn as_remote(&self) -> Option<&RemoteLspStore> {
 3963        match &self.mode {
 3964            LspStoreMode::Remote(remote_lsp_store) => Some(remote_lsp_store),
 3965            _ => None,
 3966        }
 3967    }
 3968
 3969    pub fn as_local(&self) -> Option<&LocalLspStore> {
 3970        match &self.mode {
 3971            LspStoreMode::Local(local_lsp_store) => Some(local_lsp_store),
 3972            _ => None,
 3973        }
 3974    }
 3975
 3976    pub fn as_local_mut(&mut self) -> Option<&mut LocalLspStore> {
 3977        match &mut self.mode {
 3978            LspStoreMode::Local(local_lsp_store) => Some(local_lsp_store),
 3979            _ => None,
 3980        }
 3981    }
 3982
 3983    pub fn upstream_client(&self) -> Option<(AnyProtoClient, u64)> {
 3984        match &self.mode {
 3985            LspStoreMode::Remote(RemoteLspStore {
 3986                upstream_client: Some(upstream_client),
 3987                upstream_project_id,
 3988                ..
 3989            }) => Some((upstream_client.clone(), *upstream_project_id)),
 3990
 3991            LspStoreMode::Remote(RemoteLspStore {
 3992                upstream_client: None,
 3993                ..
 3994            }) => None,
 3995            LspStoreMode::Local(_) => None,
 3996        }
 3997    }
 3998
 3999    pub fn new_local(
 4000        buffer_store: Entity<BufferStore>,
 4001        worktree_store: Entity<WorktreeStore>,
 4002        prettier_store: Entity<PrettierStore>,
 4003        toolchain_store: Entity<LocalToolchainStore>,
 4004        environment: Entity<ProjectEnvironment>,
 4005        manifest_tree: Entity<ManifestTree>,
 4006        languages: Arc<LanguageRegistry>,
 4007        http_client: Arc<dyn HttpClient>,
 4008        fs: Arc<dyn Fs>,
 4009        cx: &mut Context<Self>,
 4010    ) -> Self {
 4011        let yarn = YarnPathStore::new(fs.clone(), cx);
 4012        cx.subscribe(&buffer_store, Self::on_buffer_store_event)
 4013            .detach();
 4014        cx.subscribe(&worktree_store, Self::on_worktree_store_event)
 4015            .detach();
 4016        cx.subscribe(&prettier_store, Self::on_prettier_store_event)
 4017            .detach();
 4018        cx.subscribe(&toolchain_store, Self::on_toolchain_store_event)
 4019            .detach();
 4020        cx.observe_global::<SettingsStore>(Self::on_settings_changed)
 4021            .detach();
 4022        subscribe_to_binary_statuses(&languages, cx).detach();
 4023
 4024        let _maintain_workspace_config = {
 4025            let (sender, receiver) = watch::channel();
 4026            (Self::maintain_workspace_config(receiver, cx), sender)
 4027        };
 4028
 4029        Self {
 4030            mode: LspStoreMode::Local(LocalLspStore {
 4031                weak: cx.weak_entity(),
 4032                worktree_store: worktree_store.clone(),
 4033
 4034                supplementary_language_servers: Default::default(),
 4035                languages: languages.clone(),
 4036                language_server_ids: Default::default(),
 4037                language_servers: Default::default(),
 4038                last_workspace_edits_by_language_server: Default::default(),
 4039                language_server_watched_paths: Default::default(),
 4040                language_server_paths_watched_for_rename: Default::default(),
 4041                language_server_dynamic_registrations: Default::default(),
 4042                buffers_being_formatted: Default::default(),
 4043                buffer_snapshots: Default::default(),
 4044                prettier_store,
 4045                environment,
 4046                http_client,
 4047                fs,
 4048                yarn,
 4049                next_diagnostic_group_id: Default::default(),
 4050                diagnostics: Default::default(),
 4051                _subscription: cx.on_app_quit(|this, cx| {
 4052                    this.as_local_mut()
 4053                        .unwrap()
 4054                        .shutdown_language_servers_on_quit(cx)
 4055                }),
 4056                lsp_tree: LanguageServerTree::new(
 4057                    manifest_tree,
 4058                    languages.clone(),
 4059                    toolchain_store.clone(),
 4060                ),
 4061                toolchain_store,
 4062                registered_buffers: HashMap::default(),
 4063                buffers_opened_in_servers: HashMap::default(),
 4064                buffer_pull_diagnostics_result_ids: HashMap::default(),
 4065                workspace_pull_diagnostics_result_ids: HashMap::default(),
 4066                restricted_worktrees_tasks: HashMap::default(),
 4067                watched_manifest_filenames: ManifestProvidersStore::global(cx)
 4068                    .manifest_file_names(),
 4069            }),
 4070            last_formatting_failure: None,
 4071            downstream_client: None,
 4072            buffer_store,
 4073            worktree_store,
 4074            languages: languages.clone(),
 4075            language_server_statuses: Default::default(),
 4076            nonce: StdRng::from_os_rng().random(),
 4077            diagnostic_summaries: HashMap::default(),
 4078            lsp_server_capabilities: HashMap::default(),
 4079            lsp_data: HashMap::default(),
 4080            next_hint_id: Arc::default(),
 4081            active_entry: None,
 4082            _maintain_workspace_config,
 4083            _maintain_buffer_languages: Self::maintain_buffer_languages(languages, cx),
 4084        }
 4085    }
 4086
 4087    fn send_lsp_proto_request<R: LspCommand>(
 4088        &self,
 4089        buffer: Entity<Buffer>,
 4090        client: AnyProtoClient,
 4091        upstream_project_id: u64,
 4092        request: R,
 4093        cx: &mut Context<LspStore>,
 4094    ) -> Task<anyhow::Result<<R as LspCommand>::Response>> {
 4095        if !self.is_capable_for_proto_request(&buffer, &request, cx) {
 4096            return Task::ready(Ok(R::Response::default()));
 4097        }
 4098        let message = request.to_proto(upstream_project_id, buffer.read(cx));
 4099        cx.spawn(async move |this, cx| {
 4100            let response = client.request(message).await?;
 4101            let this = this.upgrade().context("project dropped")?;
 4102            request
 4103                .response_from_proto(response, this, buffer, cx.clone())
 4104                .await
 4105        })
 4106    }
 4107
 4108    pub(super) fn new_remote(
 4109        buffer_store: Entity<BufferStore>,
 4110        worktree_store: Entity<WorktreeStore>,
 4111        languages: Arc<LanguageRegistry>,
 4112        upstream_client: AnyProtoClient,
 4113        project_id: u64,
 4114        cx: &mut Context<Self>,
 4115    ) -> Self {
 4116        cx.subscribe(&buffer_store, Self::on_buffer_store_event)
 4117            .detach();
 4118        cx.subscribe(&worktree_store, Self::on_worktree_store_event)
 4119            .detach();
 4120        subscribe_to_binary_statuses(&languages, cx).detach();
 4121        let _maintain_workspace_config = {
 4122            let (sender, receiver) = watch::channel();
 4123            (Self::maintain_workspace_config(receiver, cx), sender)
 4124        };
 4125        Self {
 4126            mode: LspStoreMode::Remote(RemoteLspStore {
 4127                upstream_client: Some(upstream_client),
 4128                upstream_project_id: project_id,
 4129            }),
 4130            downstream_client: None,
 4131            last_formatting_failure: None,
 4132            buffer_store,
 4133            worktree_store,
 4134            languages: languages.clone(),
 4135            language_server_statuses: Default::default(),
 4136            nonce: StdRng::from_os_rng().random(),
 4137            diagnostic_summaries: HashMap::default(),
 4138            lsp_server_capabilities: HashMap::default(),
 4139            next_hint_id: Arc::default(),
 4140            lsp_data: HashMap::default(),
 4141            active_entry: None,
 4142
 4143            _maintain_workspace_config,
 4144            _maintain_buffer_languages: Self::maintain_buffer_languages(languages.clone(), cx),
 4145        }
 4146    }
 4147
 4148    fn on_buffer_store_event(
 4149        &mut self,
 4150        _: Entity<BufferStore>,
 4151        event: &BufferStoreEvent,
 4152        cx: &mut Context<Self>,
 4153    ) {
 4154        match event {
 4155            BufferStoreEvent::BufferAdded(buffer) => {
 4156                self.on_buffer_added(buffer, cx).log_err();
 4157            }
 4158            BufferStoreEvent::BufferChangedFilePath { buffer, old_file } => {
 4159                let buffer_id = buffer.read(cx).remote_id();
 4160                if let Some(local) = self.as_local_mut()
 4161                    && let Some(old_file) = File::from_dyn(old_file.as_ref())
 4162                {
 4163                    local.reset_buffer(buffer, old_file, cx);
 4164
 4165                    if local.registered_buffers.contains_key(&buffer_id) {
 4166                        local.unregister_old_buffer_from_language_servers(buffer, old_file, cx);
 4167                    }
 4168                }
 4169
 4170                self.detect_language_for_buffer(buffer, cx);
 4171                if let Some(local) = self.as_local_mut() {
 4172                    local.initialize_buffer(buffer, cx);
 4173                    if local.registered_buffers.contains_key(&buffer_id) {
 4174                        local.register_buffer_with_language_servers(buffer, HashSet::default(), cx);
 4175                    }
 4176                }
 4177            }
 4178            _ => {}
 4179        }
 4180    }
 4181
 4182    fn on_worktree_store_event(
 4183        &mut self,
 4184        _: Entity<WorktreeStore>,
 4185        event: &WorktreeStoreEvent,
 4186        cx: &mut Context<Self>,
 4187    ) {
 4188        match event {
 4189            WorktreeStoreEvent::WorktreeAdded(worktree) => {
 4190                if !worktree.read(cx).is_local() {
 4191                    return;
 4192                }
 4193                cx.subscribe(worktree, |this, worktree, event, cx| match event {
 4194                    worktree::Event::UpdatedEntries(changes) => {
 4195                        this.update_local_worktree_language_servers(&worktree, changes, cx);
 4196                    }
 4197                    worktree::Event::UpdatedGitRepositories(_)
 4198                    | worktree::Event::DeletedEntry(_) => {}
 4199                })
 4200                .detach()
 4201            }
 4202            WorktreeStoreEvent::WorktreeRemoved(_, id) => self.remove_worktree(*id, cx),
 4203            WorktreeStoreEvent::WorktreeUpdateSent(worktree) => {
 4204                worktree.update(cx, |worktree, _cx| self.send_diagnostic_summaries(worktree));
 4205            }
 4206            WorktreeStoreEvent::WorktreeReleased(..)
 4207            | WorktreeStoreEvent::WorktreeOrderChanged
 4208            | WorktreeStoreEvent::WorktreeUpdatedEntries(..)
 4209            | WorktreeStoreEvent::WorktreeUpdatedGitRepositories(..)
 4210            | WorktreeStoreEvent::WorktreeDeletedEntry(..) => {}
 4211        }
 4212    }
 4213
 4214    fn on_prettier_store_event(
 4215        &mut self,
 4216        _: Entity<PrettierStore>,
 4217        event: &PrettierStoreEvent,
 4218        cx: &mut Context<Self>,
 4219    ) {
 4220        match event {
 4221            PrettierStoreEvent::LanguageServerRemoved(prettier_server_id) => {
 4222                self.unregister_supplementary_language_server(*prettier_server_id, cx);
 4223            }
 4224            PrettierStoreEvent::LanguageServerAdded {
 4225                new_server_id,
 4226                name,
 4227                prettier_server,
 4228            } => {
 4229                self.register_supplementary_language_server(
 4230                    *new_server_id,
 4231                    name.clone(),
 4232                    prettier_server.clone(),
 4233                    cx,
 4234                );
 4235            }
 4236        }
 4237    }
 4238
 4239    fn on_toolchain_store_event(
 4240        &mut self,
 4241        _: Entity<LocalToolchainStore>,
 4242        event: &ToolchainStoreEvent,
 4243        _: &mut Context<Self>,
 4244    ) {
 4245        if let ToolchainStoreEvent::ToolchainActivated = event {
 4246            self.request_workspace_config_refresh()
 4247        }
 4248    }
 4249
 4250    fn request_workspace_config_refresh(&mut self) {
 4251        *self._maintain_workspace_config.1.borrow_mut() = ();
 4252    }
 4253
 4254    pub fn prettier_store(&self) -> Option<Entity<PrettierStore>> {
 4255        self.as_local().map(|local| local.prettier_store.clone())
 4256    }
 4257
 4258    fn on_buffer_event(
 4259        &mut self,
 4260        buffer: Entity<Buffer>,
 4261        event: &language::BufferEvent,
 4262        cx: &mut Context<Self>,
 4263    ) {
 4264        match event {
 4265            language::BufferEvent::Edited => {
 4266                self.on_buffer_edited(buffer, cx);
 4267            }
 4268
 4269            language::BufferEvent::Saved => {
 4270                self.on_buffer_saved(buffer, cx);
 4271            }
 4272
 4273            _ => {}
 4274        }
 4275    }
 4276
 4277    fn on_buffer_added(&mut self, buffer: &Entity<Buffer>, cx: &mut Context<Self>) -> Result<()> {
 4278        buffer
 4279            .read(cx)
 4280            .set_language_registry(self.languages.clone());
 4281
 4282        cx.subscribe(buffer, |this, buffer, event, cx| {
 4283            this.on_buffer_event(buffer, event, cx);
 4284        })
 4285        .detach();
 4286
 4287        self.detect_language_for_buffer(buffer, cx);
 4288        if let Some(local) = self.as_local_mut() {
 4289            local.initialize_buffer(buffer, cx);
 4290        }
 4291
 4292        Ok(())
 4293    }
 4294
 4295    pub(crate) fn register_buffer_with_language_servers(
 4296        &mut self,
 4297        buffer: &Entity<Buffer>,
 4298        only_register_servers: HashSet<LanguageServerSelector>,
 4299        ignore_refcounts: bool,
 4300        cx: &mut Context<Self>,
 4301    ) -> OpenLspBufferHandle {
 4302        let buffer_id = buffer.read(cx).remote_id();
 4303        let handle = OpenLspBufferHandle(cx.new(|_| OpenLspBuffer(buffer.clone())));
 4304        if let Some(local) = self.as_local_mut() {
 4305            let refcount = local.registered_buffers.entry(buffer_id).or_insert(0);
 4306            if !ignore_refcounts {
 4307                *refcount += 1;
 4308            }
 4309
 4310            // We run early exits on non-existing buffers AFTER we mark the buffer as registered in order to handle buffer saving.
 4311            // 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
 4312            // 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
 4313            // servers in practice (we don't support non-file URI schemes in our LSP impl).
 4314            let Some(file) = File::from_dyn(buffer.read(cx).file()) else {
 4315                return handle;
 4316            };
 4317            if !file.is_local() {
 4318                return handle;
 4319            }
 4320
 4321            if ignore_refcounts || *refcount == 1 {
 4322                local.register_buffer_with_language_servers(buffer, only_register_servers, cx);
 4323            }
 4324            if !ignore_refcounts {
 4325                cx.observe_release(&handle.0, move |lsp_store, buffer, cx| {
 4326                    let refcount = {
 4327                        let local = lsp_store.as_local_mut().unwrap();
 4328                        let Some(refcount) = local.registered_buffers.get_mut(&buffer_id) else {
 4329                            debug_panic!("bad refcounting");
 4330                            return;
 4331                        };
 4332
 4333                        *refcount -= 1;
 4334                        *refcount
 4335                    };
 4336                    if refcount == 0 {
 4337                        lsp_store.lsp_data.remove(&buffer_id);
 4338                        let local = lsp_store.as_local_mut().unwrap();
 4339                        local.registered_buffers.remove(&buffer_id);
 4340
 4341                        local.buffers_opened_in_servers.remove(&buffer_id);
 4342                        if let Some(file) = File::from_dyn(buffer.0.read(cx).file()).cloned() {
 4343                            local.unregister_old_buffer_from_language_servers(&buffer.0, &file, cx);
 4344
 4345                            let buffer_abs_path = file.abs_path(cx);
 4346                            for (_, buffer_pull_diagnostics_result_ids) in
 4347                                &mut local.buffer_pull_diagnostics_result_ids
 4348                            {
 4349                                buffer_pull_diagnostics_result_ids.retain(
 4350                                    |_, buffer_result_ids| {
 4351                                        buffer_result_ids.remove(&buffer_abs_path);
 4352                                        !buffer_result_ids.is_empty()
 4353                                    },
 4354                                );
 4355                            }
 4356
 4357                            let diagnostic_updates = local
 4358                                .language_servers
 4359                                .keys()
 4360                                .cloned()
 4361                                .map(|server_id| DocumentDiagnosticsUpdate {
 4362                                    diagnostics: DocumentDiagnostics {
 4363                                        document_abs_path: buffer_abs_path.clone(),
 4364                                        version: None,
 4365                                        diagnostics: Vec::new(),
 4366                                    },
 4367                                    result_id: None,
 4368                                    registration_id: None,
 4369                                    server_id: server_id,
 4370                                    disk_based_sources: Cow::Borrowed(&[]),
 4371                                })
 4372                                .collect::<Vec<_>>();
 4373
 4374                            lsp_store
 4375                                .merge_diagnostic_entries(
 4376                                    diagnostic_updates,
 4377                                    |_, diagnostic, _| {
 4378                                        diagnostic.source_kind != DiagnosticSourceKind::Pulled
 4379                                    },
 4380                                    cx,
 4381                                )
 4382                                .context("Clearing diagnostics for the closed buffer")
 4383                                .log_err();
 4384                        }
 4385                    }
 4386                })
 4387                .detach();
 4388            }
 4389        } else if let Some((upstream_client, upstream_project_id)) = self.upstream_client() {
 4390            let buffer_id = buffer.read(cx).remote_id().to_proto();
 4391            cx.background_spawn(async move {
 4392                upstream_client
 4393                    .request(proto::RegisterBufferWithLanguageServers {
 4394                        project_id: upstream_project_id,
 4395                        buffer_id,
 4396                        only_servers: only_register_servers
 4397                            .into_iter()
 4398                            .map(|selector| {
 4399                                let selector = match selector {
 4400                                    LanguageServerSelector::Id(language_server_id) => {
 4401                                        proto::language_server_selector::Selector::ServerId(
 4402                                            language_server_id.to_proto(),
 4403                                        )
 4404                                    }
 4405                                    LanguageServerSelector::Name(language_server_name) => {
 4406                                        proto::language_server_selector::Selector::Name(
 4407                                            language_server_name.to_string(),
 4408                                        )
 4409                                    }
 4410                                };
 4411                                proto::LanguageServerSelector {
 4412                                    selector: Some(selector),
 4413                                }
 4414                            })
 4415                            .collect(),
 4416                    })
 4417                    .await
 4418            })
 4419            .detach();
 4420        } else {
 4421            // Our remote connection got closed
 4422        }
 4423        handle
 4424    }
 4425
 4426    fn maintain_buffer_languages(
 4427        languages: Arc<LanguageRegistry>,
 4428        cx: &mut Context<Self>,
 4429    ) -> Task<()> {
 4430        let mut subscription = languages.subscribe();
 4431        let mut prev_reload_count = languages.reload_count();
 4432        cx.spawn(async move |this, cx| {
 4433            while let Some(()) = subscription.next().await {
 4434                if let Some(this) = this.upgrade() {
 4435                    // If the language registry has been reloaded, then remove and
 4436                    // re-assign the languages on all open buffers.
 4437                    let reload_count = languages.reload_count();
 4438                    if reload_count > prev_reload_count {
 4439                        prev_reload_count = reload_count;
 4440                        this.update(cx, |this, cx| {
 4441                            this.buffer_store.clone().update(cx, |buffer_store, cx| {
 4442                                for buffer in buffer_store.buffers() {
 4443                                    if let Some(f) = File::from_dyn(buffer.read(cx).file()).cloned()
 4444                                    {
 4445                                        buffer.update(cx, |buffer, cx| {
 4446                                            buffer.set_language_async(None, cx)
 4447                                        });
 4448                                        if let Some(local) = this.as_local_mut() {
 4449                                            local.reset_buffer(&buffer, &f, cx);
 4450
 4451                                            if local
 4452                                                .registered_buffers
 4453                                                .contains_key(&buffer.read(cx).remote_id())
 4454                                                && let Some(file_url) =
 4455                                                    file_path_to_lsp_url(&f.abs_path(cx)).log_err()
 4456                                            {
 4457                                                local.unregister_buffer_from_language_servers(
 4458                                                    &buffer, &file_url, cx,
 4459                                                );
 4460                                            }
 4461                                        }
 4462                                    }
 4463                                }
 4464                            });
 4465                        })
 4466                        .ok();
 4467                    }
 4468
 4469                    this.update(cx, |this, cx| {
 4470                        let mut plain_text_buffers = Vec::new();
 4471                        let mut buffers_with_unknown_injections = Vec::new();
 4472                        for handle in this.buffer_store.read(cx).buffers() {
 4473                            let buffer = handle.read(cx);
 4474                            if buffer.language().is_none()
 4475                                || buffer.language() == Some(&*language::PLAIN_TEXT)
 4476                            {
 4477                                plain_text_buffers.push(handle);
 4478                            } else if buffer.contains_unknown_injections() {
 4479                                buffers_with_unknown_injections.push(handle);
 4480                            }
 4481                        }
 4482
 4483                        // Deprioritize the invisible worktrees so main worktrees' language servers can be started first,
 4484                        // and reused later in the invisible worktrees.
 4485                        plain_text_buffers.sort_by_key(|buffer| {
 4486                            Reverse(
 4487                                File::from_dyn(buffer.read(cx).file())
 4488                                    .map(|file| file.worktree.read(cx).is_visible()),
 4489                            )
 4490                        });
 4491
 4492                        for buffer in plain_text_buffers {
 4493                            this.detect_language_for_buffer(&buffer, cx);
 4494                            if let Some(local) = this.as_local_mut() {
 4495                                local.initialize_buffer(&buffer, cx);
 4496                                if local
 4497                                    .registered_buffers
 4498                                    .contains_key(&buffer.read(cx).remote_id())
 4499                                {
 4500                                    local.register_buffer_with_language_servers(
 4501                                        &buffer,
 4502                                        HashSet::default(),
 4503                                        cx,
 4504                                    );
 4505                                }
 4506                            }
 4507                        }
 4508
 4509                        for buffer in buffers_with_unknown_injections {
 4510                            buffer.update(cx, |buffer, cx| buffer.reparse(cx, false));
 4511                        }
 4512                    })
 4513                    .ok();
 4514                }
 4515            }
 4516        })
 4517    }
 4518
 4519    fn detect_language_for_buffer(
 4520        &mut self,
 4521        buffer_handle: &Entity<Buffer>,
 4522        cx: &mut Context<Self>,
 4523    ) -> Option<language::AvailableLanguage> {
 4524        // If the buffer has a language, set it and start the language server if we haven't already.
 4525        let buffer = buffer_handle.read(cx);
 4526        let file = buffer.file()?;
 4527
 4528        let content = buffer.as_rope();
 4529        let available_language = self.languages.language_for_file(file, Some(content), cx);
 4530        if let Some(available_language) = &available_language {
 4531            if let Some(Ok(Ok(new_language))) = self
 4532                .languages
 4533                .load_language(available_language)
 4534                .now_or_never()
 4535            {
 4536                self.set_language_for_buffer(buffer_handle, new_language, cx);
 4537            }
 4538        } else {
 4539            cx.emit(LspStoreEvent::LanguageDetected {
 4540                buffer: buffer_handle.clone(),
 4541                new_language: None,
 4542            });
 4543        }
 4544
 4545        available_language
 4546    }
 4547
 4548    pub(crate) fn set_language_for_buffer(
 4549        &mut self,
 4550        buffer_entity: &Entity<Buffer>,
 4551        new_language: Arc<Language>,
 4552        cx: &mut Context<Self>,
 4553    ) {
 4554        let buffer = buffer_entity.read(cx);
 4555        let buffer_file = buffer.file().cloned();
 4556        let buffer_id = buffer.remote_id();
 4557        if let Some(local_store) = self.as_local_mut()
 4558            && local_store.registered_buffers.contains_key(&buffer_id)
 4559            && let Some(abs_path) =
 4560                File::from_dyn(buffer_file.as_ref()).map(|file| file.abs_path(cx))
 4561            && let Some(file_url) = file_path_to_lsp_url(&abs_path).log_err()
 4562        {
 4563            local_store.unregister_buffer_from_language_servers(buffer_entity, &file_url, cx);
 4564        }
 4565        buffer_entity.update(cx, |buffer, cx| {
 4566            if buffer
 4567                .language()
 4568                .is_none_or(|old_language| !Arc::ptr_eq(old_language, &new_language))
 4569            {
 4570                buffer.set_language_async(Some(new_language.clone()), cx);
 4571            }
 4572        });
 4573
 4574        let settings =
 4575            language_settings(Some(new_language.name()), buffer_file.as_ref(), cx).into_owned();
 4576        let buffer_file = File::from_dyn(buffer_file.as_ref());
 4577
 4578        let worktree_id = if let Some(file) = buffer_file {
 4579            let worktree = file.worktree.clone();
 4580
 4581            if let Some(local) = self.as_local_mut()
 4582                && local.registered_buffers.contains_key(&buffer_id)
 4583            {
 4584                local.register_buffer_with_language_servers(buffer_entity, HashSet::default(), cx);
 4585            }
 4586            Some(worktree.read(cx).id())
 4587        } else {
 4588            None
 4589        };
 4590
 4591        if settings.prettier.allowed
 4592            && let Some(prettier_plugins) = prettier_store::prettier_plugins_for_language(&settings)
 4593        {
 4594            let prettier_store = self.as_local().map(|s| s.prettier_store.clone());
 4595            if let Some(prettier_store) = prettier_store {
 4596                prettier_store.update(cx, |prettier_store, cx| {
 4597                    prettier_store.install_default_prettier(
 4598                        worktree_id,
 4599                        prettier_plugins.iter().map(|s| Arc::from(s.as_str())),
 4600                        cx,
 4601                    )
 4602                })
 4603            }
 4604        }
 4605
 4606        cx.emit(LspStoreEvent::LanguageDetected {
 4607            buffer: buffer_entity.clone(),
 4608            new_language: Some(new_language),
 4609        })
 4610    }
 4611
 4612    pub fn buffer_store(&self) -> Entity<BufferStore> {
 4613        self.buffer_store.clone()
 4614    }
 4615
 4616    pub fn set_active_entry(&mut self, active_entry: Option<ProjectEntryId>) {
 4617        self.active_entry = active_entry;
 4618    }
 4619
 4620    pub(crate) fn send_diagnostic_summaries(&self, worktree: &mut Worktree) {
 4621        if let Some((client, downstream_project_id)) = self.downstream_client.clone()
 4622            && let Some(diangostic_summaries) = self.diagnostic_summaries.get(&worktree.id())
 4623        {
 4624            let mut summaries = diangostic_summaries.iter().flat_map(|(path, summaries)| {
 4625                summaries
 4626                    .iter()
 4627                    .map(|(server_id, summary)| summary.to_proto(*server_id, path.as_ref()))
 4628            });
 4629            if let Some(summary) = summaries.next() {
 4630                client
 4631                    .send(proto::UpdateDiagnosticSummary {
 4632                        project_id: downstream_project_id,
 4633                        worktree_id: worktree.id().to_proto(),
 4634                        summary: Some(summary),
 4635                        more_summaries: summaries.collect(),
 4636                    })
 4637                    .log_err();
 4638            }
 4639        }
 4640    }
 4641
 4642    fn is_capable_for_proto_request<R>(
 4643        &self,
 4644        buffer: &Entity<Buffer>,
 4645        request: &R,
 4646        cx: &App,
 4647    ) -> bool
 4648    where
 4649        R: LspCommand,
 4650    {
 4651        self.check_if_capable_for_proto_request(
 4652            buffer,
 4653            |capabilities| {
 4654                request.check_capabilities(AdapterServerCapabilities {
 4655                    server_capabilities: capabilities.clone(),
 4656                    code_action_kinds: None,
 4657                })
 4658            },
 4659            cx,
 4660        )
 4661    }
 4662
 4663    fn check_if_capable_for_proto_request<F>(
 4664        &self,
 4665        buffer: &Entity<Buffer>,
 4666        check: F,
 4667        cx: &App,
 4668    ) -> bool
 4669    where
 4670        F: FnMut(&lsp::ServerCapabilities) -> bool,
 4671    {
 4672        let Some(language) = buffer.read(cx).language().cloned() else {
 4673            return false;
 4674        };
 4675        let relevant_language_servers = self
 4676            .languages
 4677            .lsp_adapters(&language.name())
 4678            .into_iter()
 4679            .map(|lsp_adapter| lsp_adapter.name())
 4680            .collect::<HashSet<_>>();
 4681        self.language_server_statuses
 4682            .iter()
 4683            .filter_map(|(server_id, server_status)| {
 4684                relevant_language_servers
 4685                    .contains(&server_status.name)
 4686                    .then_some(server_id)
 4687            })
 4688            .filter_map(|server_id| self.lsp_server_capabilities.get(server_id))
 4689            .any(check)
 4690    }
 4691
 4692    fn all_capable_for_proto_request<F>(
 4693        &self,
 4694        buffer: &Entity<Buffer>,
 4695        mut check: F,
 4696        cx: &App,
 4697    ) -> Vec<lsp::LanguageServerId>
 4698    where
 4699        F: FnMut(&lsp::LanguageServerName, &lsp::ServerCapabilities) -> bool,
 4700    {
 4701        let Some(language) = buffer.read(cx).language().cloned() else {
 4702            return Vec::default();
 4703        };
 4704        let relevant_language_servers = self
 4705            .languages
 4706            .lsp_adapters(&language.name())
 4707            .into_iter()
 4708            .map(|lsp_adapter| lsp_adapter.name())
 4709            .collect::<HashSet<_>>();
 4710        self.language_server_statuses
 4711            .iter()
 4712            .filter_map(|(server_id, server_status)| {
 4713                relevant_language_servers
 4714                    .contains(&server_status.name)
 4715                    .then_some((server_id, &server_status.name))
 4716            })
 4717            .filter_map(|(server_id, server_name)| {
 4718                self.lsp_server_capabilities
 4719                    .get(server_id)
 4720                    .map(|c| (server_id, server_name, c))
 4721            })
 4722            .filter(|(_, server_name, capabilities)| check(server_name, capabilities))
 4723            .map(|(server_id, _, _)| *server_id)
 4724            .collect()
 4725    }
 4726
 4727    pub fn request_lsp<R>(
 4728        &mut self,
 4729        buffer: Entity<Buffer>,
 4730        server: LanguageServerToQuery,
 4731        request: R,
 4732        cx: &mut Context<Self>,
 4733    ) -> Task<Result<R::Response>>
 4734    where
 4735        R: LspCommand,
 4736        <R::LspRequest as lsp::request::Request>::Result: Send,
 4737        <R::LspRequest as lsp::request::Request>::Params: Send,
 4738    {
 4739        if let Some((upstream_client, upstream_project_id)) = self.upstream_client() {
 4740            return self.send_lsp_proto_request(
 4741                buffer,
 4742                upstream_client,
 4743                upstream_project_id,
 4744                request,
 4745                cx,
 4746            );
 4747        }
 4748
 4749        let Some(language_server) = buffer.update(cx, |buffer, cx| match server {
 4750            LanguageServerToQuery::FirstCapable => self.as_local().and_then(|local| {
 4751                local
 4752                    .language_servers_for_buffer(buffer, cx)
 4753                    .find(|(_, server)| {
 4754                        request.check_capabilities(server.adapter_server_capabilities())
 4755                    })
 4756                    .map(|(_, server)| server.clone())
 4757            }),
 4758            LanguageServerToQuery::Other(id) => self
 4759                .language_server_for_local_buffer(buffer, id, cx)
 4760                .and_then(|(_, server)| {
 4761                    request
 4762                        .check_capabilities(server.adapter_server_capabilities())
 4763                        .then(|| Arc::clone(server))
 4764                }),
 4765        }) else {
 4766            return Task::ready(Ok(Default::default()));
 4767        };
 4768
 4769        let file = File::from_dyn(buffer.read(cx).file()).and_then(File::as_local);
 4770
 4771        let Some(file) = file else {
 4772            return Task::ready(Ok(Default::default()));
 4773        };
 4774
 4775        let lsp_params = match request.to_lsp_params_or_response(
 4776            &file.abs_path(cx),
 4777            buffer.read(cx),
 4778            &language_server,
 4779            cx,
 4780        ) {
 4781            Ok(LspParamsOrResponse::Params(lsp_params)) => lsp_params,
 4782            Ok(LspParamsOrResponse::Response(response)) => return Task::ready(Ok(response)),
 4783            Err(err) => {
 4784                let message = format!(
 4785                    "{} via {} failed: {}",
 4786                    request.display_name(),
 4787                    language_server.name(),
 4788                    err
 4789                );
 4790                // rust-analyzer likes to error with this when its still loading up
 4791                if !message.ends_with("content modified") {
 4792                    log::warn!("{message}");
 4793                }
 4794                return Task::ready(Err(anyhow!(message)));
 4795            }
 4796        };
 4797
 4798        let status = request.status();
 4799        if !request.check_capabilities(language_server.adapter_server_capabilities()) {
 4800            return Task::ready(Ok(Default::default()));
 4801        }
 4802        cx.spawn(async move |this, cx| {
 4803            let lsp_request = language_server.request::<R::LspRequest>(lsp_params);
 4804
 4805            let id = lsp_request.id();
 4806            let _cleanup = if status.is_some() {
 4807                cx.update(|cx| {
 4808                    this.update(cx, |this, cx| {
 4809                        this.on_lsp_work_start(
 4810                            language_server.server_id(),
 4811                            ProgressToken::Number(id),
 4812                            LanguageServerProgress {
 4813                                is_disk_based_diagnostics_progress: false,
 4814                                is_cancellable: false,
 4815                                title: None,
 4816                                message: status.clone(),
 4817                                percentage: None,
 4818                                last_update_at: cx.background_executor().now(),
 4819                            },
 4820                            cx,
 4821                        );
 4822                    })
 4823                })
 4824                .log_err();
 4825
 4826                Some(defer(|| {
 4827                    cx.update(|cx| {
 4828                        this.update(cx, |this, cx| {
 4829                            this.on_lsp_work_end(
 4830                                language_server.server_id(),
 4831                                ProgressToken::Number(id),
 4832                                cx,
 4833                            );
 4834                        })
 4835                    })
 4836                    .log_err();
 4837                }))
 4838            } else {
 4839                None
 4840            };
 4841
 4842            let result = lsp_request.await.into_response();
 4843
 4844            let response = result.map_err(|err| {
 4845                let message = format!(
 4846                    "{} via {} failed: {}",
 4847                    request.display_name(),
 4848                    language_server.name(),
 4849                    err
 4850                );
 4851                // rust-analyzer likes to error with this when its still loading up
 4852                if !message.ends_with("content modified") {
 4853                    log::warn!("{message}");
 4854                }
 4855                anyhow::anyhow!(message)
 4856            })?;
 4857
 4858            request
 4859                .response_from_lsp(
 4860                    response,
 4861                    this.upgrade().context("no app context")?,
 4862                    buffer,
 4863                    language_server.server_id(),
 4864                    cx.clone(),
 4865                )
 4866                .await
 4867        })
 4868    }
 4869
 4870    fn on_settings_changed(&mut self, cx: &mut Context<Self>) {
 4871        let mut language_formatters_to_check = Vec::new();
 4872        for buffer in self.buffer_store.read(cx).buffers() {
 4873            let buffer = buffer.read(cx);
 4874            let buffer_file = File::from_dyn(buffer.file());
 4875            let buffer_language = buffer.language();
 4876            let settings = language_settings(buffer_language.map(|l| l.name()), buffer.file(), cx);
 4877            if buffer_language.is_some() {
 4878                language_formatters_to_check.push((
 4879                    buffer_file.map(|f| f.worktree_id(cx)),
 4880                    settings.into_owned(),
 4881                ));
 4882            }
 4883        }
 4884
 4885        self.request_workspace_config_refresh();
 4886
 4887        if let Some(prettier_store) = self.as_local().map(|s| s.prettier_store.clone()) {
 4888            prettier_store.update(cx, |prettier_store, cx| {
 4889                prettier_store.on_settings_changed(language_formatters_to_check, cx)
 4890            })
 4891        }
 4892
 4893        cx.notify();
 4894    }
 4895
 4896    fn refresh_server_tree(&mut self, cx: &mut Context<Self>) {
 4897        let buffer_store = self.buffer_store.clone();
 4898        let Some(local) = self.as_local_mut() else {
 4899            return;
 4900        };
 4901        let mut adapters = BTreeMap::default();
 4902        let get_adapter = {
 4903            let languages = local.languages.clone();
 4904            let environment = local.environment.clone();
 4905            let weak = local.weak.clone();
 4906            let worktree_store = local.worktree_store.clone();
 4907            let http_client = local.http_client.clone();
 4908            let fs = local.fs.clone();
 4909            move |worktree_id, cx: &mut App| {
 4910                let worktree = worktree_store.read(cx).worktree_for_id(worktree_id, cx)?;
 4911                Some(LocalLspAdapterDelegate::new(
 4912                    languages.clone(),
 4913                    &environment,
 4914                    weak.clone(),
 4915                    &worktree,
 4916                    http_client.clone(),
 4917                    fs.clone(),
 4918                    cx,
 4919                ))
 4920            }
 4921        };
 4922
 4923        let mut messages_to_report = Vec::new();
 4924        let (new_tree, to_stop) = {
 4925            let mut rebase = local.lsp_tree.rebase();
 4926            let buffers = buffer_store
 4927                .read(cx)
 4928                .buffers()
 4929                .filter_map(|buffer| {
 4930                    let raw_buffer = buffer.read(cx);
 4931                    if !local
 4932                        .registered_buffers
 4933                        .contains_key(&raw_buffer.remote_id())
 4934                    {
 4935                        return None;
 4936                    }
 4937                    let file = File::from_dyn(raw_buffer.file()).cloned()?;
 4938                    let language = raw_buffer.language().cloned()?;
 4939                    Some((file, language, raw_buffer.remote_id()))
 4940                })
 4941                .sorted_by_key(|(file, _, _)| Reverse(file.worktree.read(cx).is_visible()));
 4942            for (file, language, buffer_id) in buffers {
 4943                let worktree_id = file.worktree_id(cx);
 4944                let Some(worktree) = local
 4945                    .worktree_store
 4946                    .read(cx)
 4947                    .worktree_for_id(worktree_id, cx)
 4948                else {
 4949                    continue;
 4950                };
 4951
 4952                if let Some((_, apply)) = local.reuse_existing_language_server(
 4953                    rebase.server_tree(),
 4954                    &worktree,
 4955                    &language.name(),
 4956                    cx,
 4957                ) {
 4958                    (apply)(rebase.server_tree());
 4959                } else if let Some(lsp_delegate) = adapters
 4960                    .entry(worktree_id)
 4961                    .or_insert_with(|| get_adapter(worktree_id, cx))
 4962                    .clone()
 4963                {
 4964                    let delegate =
 4965                        Arc::new(ManifestQueryDelegate::new(worktree.read(cx).snapshot()));
 4966                    let path = file
 4967                        .path()
 4968                        .parent()
 4969                        .map(Arc::from)
 4970                        .unwrap_or_else(|| file.path().clone());
 4971                    let worktree_path = ProjectPath { worktree_id, path };
 4972                    let abs_path = file.abs_path(cx);
 4973                    let nodes = rebase
 4974                        .walk(
 4975                            worktree_path,
 4976                            language.name(),
 4977                            language.manifest(),
 4978                            delegate.clone(),
 4979                            cx,
 4980                        )
 4981                        .collect::<Vec<_>>();
 4982                    for node in nodes {
 4983                        let server_id = node.server_id_or_init(|disposition| {
 4984                            let path = &disposition.path;
 4985                            let uri = Uri::from_file_path(worktree.read(cx).absolutize(&path.path));
 4986                            let key = LanguageServerSeed {
 4987                                worktree_id,
 4988                                name: disposition.server_name.clone(),
 4989                                settings: disposition.settings.clone(),
 4990                                toolchain: local.toolchain_store.read(cx).active_toolchain(
 4991                                    path.worktree_id,
 4992                                    &path.path,
 4993                                    language.name(),
 4994                                ),
 4995                            };
 4996                            local.language_server_ids.remove(&key);
 4997
 4998                            let server_id = local.get_or_insert_language_server(
 4999                                &worktree,
 5000                                lsp_delegate.clone(),
 5001                                disposition,
 5002                                &language.name(),
 5003                                cx,
 5004                            );
 5005                            if let Some(state) = local.language_servers.get(&server_id)
 5006                                && let Ok(uri) = uri
 5007                            {
 5008                                state.add_workspace_folder(uri);
 5009                            };
 5010                            server_id
 5011                        });
 5012
 5013                        if let Some(language_server_id) = server_id {
 5014                            messages_to_report.push(LspStoreEvent::LanguageServerUpdate {
 5015                                language_server_id,
 5016                                name: node.name(),
 5017                                message:
 5018                                    proto::update_language_server::Variant::RegisteredForBuffer(
 5019                                        proto::RegisteredForBuffer {
 5020                                            buffer_abs_path: abs_path
 5021                                                .to_string_lossy()
 5022                                                .into_owned(),
 5023                                            buffer_id: buffer_id.to_proto(),
 5024                                        },
 5025                                    ),
 5026                            });
 5027                        }
 5028                    }
 5029                } else {
 5030                    continue;
 5031                }
 5032            }
 5033            rebase.finish()
 5034        };
 5035        for message in messages_to_report {
 5036            cx.emit(message);
 5037        }
 5038        local.lsp_tree = new_tree;
 5039        for (id, _) in to_stop {
 5040            self.stop_local_language_server(id, cx).detach();
 5041        }
 5042    }
 5043
 5044    pub fn apply_code_action(
 5045        &self,
 5046        buffer_handle: Entity<Buffer>,
 5047        mut action: CodeAction,
 5048        push_to_history: bool,
 5049        cx: &mut Context<Self>,
 5050    ) -> Task<Result<ProjectTransaction>> {
 5051        if let Some((upstream_client, project_id)) = self.upstream_client() {
 5052            let request = proto::ApplyCodeAction {
 5053                project_id,
 5054                buffer_id: buffer_handle.read(cx).remote_id().into(),
 5055                action: Some(Self::serialize_code_action(&action)),
 5056            };
 5057            let buffer_store = self.buffer_store();
 5058            cx.spawn(async move |_, cx| {
 5059                let response = upstream_client
 5060                    .request(request)
 5061                    .await?
 5062                    .transaction
 5063                    .context("missing transaction")?;
 5064
 5065                buffer_store
 5066                    .update(cx, |buffer_store, cx| {
 5067                        buffer_store.deserialize_project_transaction(response, push_to_history, cx)
 5068                    })?
 5069                    .await
 5070            })
 5071        } else if self.mode.is_local() {
 5072            let Some((_, lang_server)) = buffer_handle.update(cx, |buffer, cx| {
 5073                self.language_server_for_local_buffer(buffer, action.server_id, cx)
 5074                    .map(|(adapter, server)| (adapter.clone(), server.clone()))
 5075            }) else {
 5076                return Task::ready(Ok(ProjectTransaction::default()));
 5077            };
 5078            cx.spawn(async move |this,  cx| {
 5079                LocalLspStore::try_resolve_code_action(&lang_server, &mut action)
 5080                    .await
 5081                    .context("resolving a code action")?;
 5082                if let Some(edit) = action.lsp_action.edit()
 5083                    && (edit.changes.is_some() || edit.document_changes.is_some()) {
 5084                        return LocalLspStore::deserialize_workspace_edit(
 5085                            this.upgrade().context("no app present")?,
 5086                            edit.clone(),
 5087                            push_to_history,
 5088
 5089                            lang_server.clone(),
 5090                            cx,
 5091                        )
 5092                        .await;
 5093                    }
 5094
 5095                if let Some(command) = action.lsp_action.command() {
 5096                    let server_capabilities = lang_server.capabilities();
 5097                    let available_commands = server_capabilities
 5098                        .execute_command_provider
 5099                        .as_ref()
 5100                        .map(|options| options.commands.as_slice())
 5101                        .unwrap_or_default();
 5102                    if available_commands.contains(&command.command) {
 5103                        this.update(cx, |this, _| {
 5104                            this.as_local_mut()
 5105                                .unwrap()
 5106                                .last_workspace_edits_by_language_server
 5107                                .remove(&lang_server.server_id());
 5108                        })?;
 5109
 5110                        let _result = lang_server
 5111                            .request::<lsp::request::ExecuteCommand>(lsp::ExecuteCommandParams {
 5112                                command: command.command.clone(),
 5113                                arguments: command.arguments.clone().unwrap_or_default(),
 5114                                ..lsp::ExecuteCommandParams::default()
 5115                            })
 5116                            .await.into_response()
 5117                            .context("execute command")?;
 5118
 5119                        return this.update(cx, |this, _| {
 5120                            this.as_local_mut()
 5121                                .unwrap()
 5122                                .last_workspace_edits_by_language_server
 5123                                .remove(&lang_server.server_id())
 5124                                .unwrap_or_default()
 5125                        });
 5126                    } else {
 5127                        log::warn!("Cannot execute a command {} not listed in the language server capabilities", command.command);
 5128                    }
 5129                }
 5130
 5131                Ok(ProjectTransaction::default())
 5132            })
 5133        } else {
 5134            Task::ready(Err(anyhow!("no upstream client and not local")))
 5135        }
 5136    }
 5137
 5138    pub fn apply_code_action_kind(
 5139        &mut self,
 5140        buffers: HashSet<Entity<Buffer>>,
 5141        kind: CodeActionKind,
 5142        push_to_history: bool,
 5143        cx: &mut Context<Self>,
 5144    ) -> Task<anyhow::Result<ProjectTransaction>> {
 5145        if self.as_local().is_some() {
 5146            cx.spawn(async move |lsp_store, cx| {
 5147                let buffers = buffers.into_iter().collect::<Vec<_>>();
 5148                let result = LocalLspStore::execute_code_action_kind_locally(
 5149                    lsp_store.clone(),
 5150                    buffers,
 5151                    kind,
 5152                    push_to_history,
 5153                    cx,
 5154                )
 5155                .await;
 5156                lsp_store.update(cx, |lsp_store, _| {
 5157                    lsp_store.update_last_formatting_failure(&result);
 5158                })?;
 5159                result
 5160            })
 5161        } else if let Some((client, project_id)) = self.upstream_client() {
 5162            let buffer_store = self.buffer_store();
 5163            cx.spawn(async move |lsp_store, cx| {
 5164                let result = client
 5165                    .request(proto::ApplyCodeActionKind {
 5166                        project_id,
 5167                        kind: kind.as_str().to_owned(),
 5168                        buffer_ids: buffers
 5169                            .iter()
 5170                            .map(|buffer| {
 5171                                buffer.read_with(cx, |buffer, _| buffer.remote_id().into())
 5172                            })
 5173                            .collect::<Result<_>>()?,
 5174                    })
 5175                    .await
 5176                    .and_then(|result| result.transaction.context("missing transaction"));
 5177                lsp_store.update(cx, |lsp_store, _| {
 5178                    lsp_store.update_last_formatting_failure(&result);
 5179                })?;
 5180
 5181                let transaction_response = result?;
 5182                buffer_store
 5183                    .update(cx, |buffer_store, cx| {
 5184                        buffer_store.deserialize_project_transaction(
 5185                            transaction_response,
 5186                            push_to_history,
 5187                            cx,
 5188                        )
 5189                    })?
 5190                    .await
 5191            })
 5192        } else {
 5193            Task::ready(Ok(ProjectTransaction::default()))
 5194        }
 5195    }
 5196
 5197    pub fn resolved_hint(
 5198        &mut self,
 5199        buffer_id: BufferId,
 5200        id: InlayId,
 5201        cx: &mut Context<Self>,
 5202    ) -> Option<ResolvedHint> {
 5203        let buffer = self.buffer_store.read(cx).get(buffer_id)?;
 5204
 5205        let lsp_data = self.lsp_data.get_mut(&buffer_id)?;
 5206        let buffer_lsp_hints = &mut lsp_data.inlay_hints;
 5207        let hint = buffer_lsp_hints.hint_for_id(id)?.clone();
 5208        let (server_id, resolve_data) = match &hint.resolve_state {
 5209            ResolveState::Resolved => return Some(ResolvedHint::Resolved(hint)),
 5210            ResolveState::Resolving => {
 5211                return Some(ResolvedHint::Resolving(
 5212                    buffer_lsp_hints.hint_resolves.get(&id)?.clone(),
 5213                ));
 5214            }
 5215            ResolveState::CanResolve(server_id, resolve_data) => (*server_id, resolve_data.clone()),
 5216        };
 5217
 5218        let resolve_task = self.resolve_inlay_hint(hint, buffer, server_id, cx);
 5219        let buffer_lsp_hints = &mut self.lsp_data.get_mut(&buffer_id)?.inlay_hints;
 5220        let previous_task = buffer_lsp_hints.hint_resolves.insert(
 5221            id,
 5222            cx.spawn(async move |lsp_store, cx| {
 5223                let resolved_hint = resolve_task.await;
 5224                lsp_store
 5225                    .update(cx, |lsp_store, _| {
 5226                        if let Some(old_inlay_hint) = lsp_store
 5227                            .lsp_data
 5228                            .get_mut(&buffer_id)
 5229                            .and_then(|buffer_lsp_data| buffer_lsp_data.inlay_hints.hint_for_id(id))
 5230                        {
 5231                            match resolved_hint {
 5232                                Ok(resolved_hint) => {
 5233                                    *old_inlay_hint = resolved_hint;
 5234                                }
 5235                                Err(e) => {
 5236                                    old_inlay_hint.resolve_state =
 5237                                        ResolveState::CanResolve(server_id, resolve_data);
 5238                                    log::error!("Inlay hint resolve failed: {e:#}");
 5239                                }
 5240                            }
 5241                        }
 5242                    })
 5243                    .ok();
 5244            })
 5245            .shared(),
 5246        );
 5247        debug_assert!(
 5248            previous_task.is_none(),
 5249            "Did not change hint's resolve state after spawning its resolve"
 5250        );
 5251        buffer_lsp_hints.hint_for_id(id)?.resolve_state = ResolveState::Resolving;
 5252        None
 5253    }
 5254
 5255    fn resolve_inlay_hint(
 5256        &self,
 5257        mut hint: InlayHint,
 5258        buffer: Entity<Buffer>,
 5259        server_id: LanguageServerId,
 5260        cx: &mut Context<Self>,
 5261    ) -> Task<anyhow::Result<InlayHint>> {
 5262        if let Some((upstream_client, project_id)) = self.upstream_client() {
 5263            if !self.check_if_capable_for_proto_request(&buffer, InlayHints::can_resolve_inlays, cx)
 5264            {
 5265                hint.resolve_state = ResolveState::Resolved;
 5266                return Task::ready(Ok(hint));
 5267            }
 5268            let request = proto::ResolveInlayHint {
 5269                project_id,
 5270                buffer_id: buffer.read(cx).remote_id().into(),
 5271                language_server_id: server_id.0 as u64,
 5272                hint: Some(InlayHints::project_to_proto_hint(hint.clone())),
 5273            };
 5274            cx.background_spawn(async move {
 5275                let response = upstream_client
 5276                    .request(request)
 5277                    .await
 5278                    .context("inlay hints proto request")?;
 5279                match response.hint {
 5280                    Some(resolved_hint) => InlayHints::proto_to_project_hint(resolved_hint)
 5281                        .context("inlay hints proto resolve response conversion"),
 5282                    None => Ok(hint),
 5283                }
 5284            })
 5285        } else {
 5286            let Some(lang_server) = buffer.update(cx, |buffer, cx| {
 5287                self.language_server_for_local_buffer(buffer, server_id, cx)
 5288                    .map(|(_, server)| server.clone())
 5289            }) else {
 5290                return Task::ready(Ok(hint));
 5291            };
 5292            if !InlayHints::can_resolve_inlays(&lang_server.capabilities()) {
 5293                return Task::ready(Ok(hint));
 5294            }
 5295            let buffer_snapshot = buffer.read(cx).snapshot();
 5296            cx.spawn(async move |_, cx| {
 5297                let resolve_task = lang_server.request::<lsp::request::InlayHintResolveRequest>(
 5298                    InlayHints::project_to_lsp_hint(hint, &buffer_snapshot),
 5299                );
 5300                let resolved_hint = resolve_task
 5301                    .await
 5302                    .into_response()
 5303                    .context("inlay hint resolve LSP request")?;
 5304                let resolved_hint = InlayHints::lsp_to_project_hint(
 5305                    resolved_hint,
 5306                    &buffer,
 5307                    server_id,
 5308                    ResolveState::Resolved,
 5309                    false,
 5310                    cx,
 5311                )
 5312                .await?;
 5313                Ok(resolved_hint)
 5314            })
 5315        }
 5316    }
 5317
 5318    pub fn resolve_color_presentation(
 5319        &mut self,
 5320        mut color: DocumentColor,
 5321        buffer: Entity<Buffer>,
 5322        server_id: LanguageServerId,
 5323        cx: &mut Context<Self>,
 5324    ) -> Task<Result<DocumentColor>> {
 5325        if color.resolved {
 5326            return Task::ready(Ok(color));
 5327        }
 5328
 5329        if let Some((upstream_client, project_id)) = self.upstream_client() {
 5330            let start = color.lsp_range.start;
 5331            let end = color.lsp_range.end;
 5332            let request = proto::GetColorPresentation {
 5333                project_id,
 5334                server_id: server_id.to_proto(),
 5335                buffer_id: buffer.read(cx).remote_id().into(),
 5336                color: Some(proto::ColorInformation {
 5337                    red: color.color.red,
 5338                    green: color.color.green,
 5339                    blue: color.color.blue,
 5340                    alpha: color.color.alpha,
 5341                    lsp_range_start: Some(proto::PointUtf16 {
 5342                        row: start.line,
 5343                        column: start.character,
 5344                    }),
 5345                    lsp_range_end: Some(proto::PointUtf16 {
 5346                        row: end.line,
 5347                        column: end.character,
 5348                    }),
 5349                }),
 5350            };
 5351            cx.background_spawn(async move {
 5352                let response = upstream_client
 5353                    .request(request)
 5354                    .await
 5355                    .context("color presentation proto request")?;
 5356                color.resolved = true;
 5357                color.color_presentations = response
 5358                    .presentations
 5359                    .into_iter()
 5360                    .map(|presentation| ColorPresentation {
 5361                        label: SharedString::from(presentation.label),
 5362                        text_edit: presentation.text_edit.and_then(deserialize_lsp_edit),
 5363                        additional_text_edits: presentation
 5364                            .additional_text_edits
 5365                            .into_iter()
 5366                            .filter_map(deserialize_lsp_edit)
 5367                            .collect(),
 5368                    })
 5369                    .collect();
 5370                Ok(color)
 5371            })
 5372        } else {
 5373            let path = match buffer
 5374                .update(cx, |buffer, cx| {
 5375                    Some(File::from_dyn(buffer.file())?.abs_path(cx))
 5376                })
 5377                .context("buffer with the missing path")
 5378            {
 5379                Ok(path) => path,
 5380                Err(e) => return Task::ready(Err(e)),
 5381            };
 5382            let Some(lang_server) = buffer.update(cx, |buffer, cx| {
 5383                self.language_server_for_local_buffer(buffer, server_id, cx)
 5384                    .map(|(_, server)| server.clone())
 5385            }) else {
 5386                return Task::ready(Ok(color));
 5387            };
 5388            cx.background_spawn(async move {
 5389                let resolve_task = lang_server.request::<lsp::request::ColorPresentationRequest>(
 5390                    lsp::ColorPresentationParams {
 5391                        text_document: make_text_document_identifier(&path)?,
 5392                        color: color.color,
 5393                        range: color.lsp_range,
 5394                        work_done_progress_params: Default::default(),
 5395                        partial_result_params: Default::default(),
 5396                    },
 5397                );
 5398                color.color_presentations = resolve_task
 5399                    .await
 5400                    .into_response()
 5401                    .context("color presentation resolve LSP request")?
 5402                    .into_iter()
 5403                    .map(|presentation| ColorPresentation {
 5404                        label: SharedString::from(presentation.label),
 5405                        text_edit: presentation.text_edit,
 5406                        additional_text_edits: presentation
 5407                            .additional_text_edits
 5408                            .unwrap_or_default(),
 5409                    })
 5410                    .collect();
 5411                color.resolved = true;
 5412                Ok(color)
 5413            })
 5414        }
 5415    }
 5416
 5417    pub(crate) fn linked_edits(
 5418        &mut self,
 5419        buffer: &Entity<Buffer>,
 5420        position: Anchor,
 5421        cx: &mut Context<Self>,
 5422    ) -> Task<Result<Vec<Range<Anchor>>>> {
 5423        let snapshot = buffer.read(cx).snapshot();
 5424        let scope = snapshot.language_scope_at(position);
 5425        let Some(server_id) = self
 5426            .as_local()
 5427            .and_then(|local| {
 5428                buffer.update(cx, |buffer, cx| {
 5429                    local
 5430                        .language_servers_for_buffer(buffer, cx)
 5431                        .filter(|(_, server)| {
 5432                            LinkedEditingRange::check_server_capabilities(server.capabilities())
 5433                        })
 5434                        .filter(|(adapter, _)| {
 5435                            scope
 5436                                .as_ref()
 5437                                .map(|scope| scope.language_allowed(&adapter.name))
 5438                                .unwrap_or(true)
 5439                        })
 5440                        .map(|(_, server)| LanguageServerToQuery::Other(server.server_id()))
 5441                        .next()
 5442                })
 5443            })
 5444            .or_else(|| {
 5445                self.upstream_client()
 5446                    .is_some()
 5447                    .then_some(LanguageServerToQuery::FirstCapable)
 5448            })
 5449            .filter(|_| {
 5450                maybe!({
 5451                    let language = buffer.read(cx).language_at(position)?;
 5452                    Some(
 5453                        language_settings(Some(language.name()), buffer.read(cx).file(), cx)
 5454                            .linked_edits,
 5455                    )
 5456                }) == Some(true)
 5457            })
 5458        else {
 5459            return Task::ready(Ok(Vec::new()));
 5460        };
 5461
 5462        self.request_lsp(
 5463            buffer.clone(),
 5464            server_id,
 5465            LinkedEditingRange { position },
 5466            cx,
 5467        )
 5468    }
 5469
 5470    fn apply_on_type_formatting(
 5471        &mut self,
 5472        buffer: Entity<Buffer>,
 5473        position: Anchor,
 5474        trigger: String,
 5475        cx: &mut Context<Self>,
 5476    ) -> Task<Result<Option<Transaction>>> {
 5477        if let Some((client, project_id)) = self.upstream_client() {
 5478            if !self.check_if_capable_for_proto_request(
 5479                &buffer,
 5480                |capabilities| {
 5481                    OnTypeFormatting::supports_on_type_formatting(&trigger, capabilities)
 5482                },
 5483                cx,
 5484            ) {
 5485                return Task::ready(Ok(None));
 5486            }
 5487            let request = proto::OnTypeFormatting {
 5488                project_id,
 5489                buffer_id: buffer.read(cx).remote_id().into(),
 5490                position: Some(serialize_anchor(&position)),
 5491                trigger,
 5492                version: serialize_version(&buffer.read(cx).version()),
 5493            };
 5494            cx.background_spawn(async move {
 5495                client
 5496                    .request(request)
 5497                    .await?
 5498                    .transaction
 5499                    .map(language::proto::deserialize_transaction)
 5500                    .transpose()
 5501            })
 5502        } else if let Some(local) = self.as_local_mut() {
 5503            let buffer_id = buffer.read(cx).remote_id();
 5504            local.buffers_being_formatted.insert(buffer_id);
 5505            cx.spawn(async move |this, cx| {
 5506                let _cleanup = defer({
 5507                    let this = this.clone();
 5508                    let mut cx = cx.clone();
 5509                    move || {
 5510                        this.update(&mut cx, |this, _| {
 5511                            if let Some(local) = this.as_local_mut() {
 5512                                local.buffers_being_formatted.remove(&buffer_id);
 5513                            }
 5514                        })
 5515                        .ok();
 5516                    }
 5517                });
 5518
 5519                buffer
 5520                    .update(cx, |buffer, _| {
 5521                        buffer.wait_for_edits(Some(position.timestamp))
 5522                    })?
 5523                    .await?;
 5524                this.update(cx, |this, cx| {
 5525                    let position = position.to_point_utf16(buffer.read(cx));
 5526                    this.on_type_format(buffer, position, trigger, false, cx)
 5527                })?
 5528                .await
 5529            })
 5530        } else {
 5531            Task::ready(Err(anyhow!("No upstream client or local language server")))
 5532        }
 5533    }
 5534
 5535    pub fn on_type_format<T: ToPointUtf16>(
 5536        &mut self,
 5537        buffer: Entity<Buffer>,
 5538        position: T,
 5539        trigger: String,
 5540        push_to_history: bool,
 5541        cx: &mut Context<Self>,
 5542    ) -> Task<Result<Option<Transaction>>> {
 5543        let position = position.to_point_utf16(buffer.read(cx));
 5544        self.on_type_format_impl(buffer, position, trigger, push_to_history, cx)
 5545    }
 5546
 5547    fn on_type_format_impl(
 5548        &mut self,
 5549        buffer: Entity<Buffer>,
 5550        position: PointUtf16,
 5551        trigger: String,
 5552        push_to_history: bool,
 5553        cx: &mut Context<Self>,
 5554    ) -> Task<Result<Option<Transaction>>> {
 5555        let options = buffer.update(cx, |buffer, cx| {
 5556            lsp_command::lsp_formatting_options(
 5557                language_settings(
 5558                    buffer.language_at(position).map(|l| l.name()),
 5559                    buffer.file(),
 5560                    cx,
 5561                )
 5562                .as_ref(),
 5563            )
 5564        });
 5565
 5566        cx.spawn(async move |this, cx| {
 5567            if let Some(waiter) =
 5568                buffer.update(cx, |buffer, _| buffer.wait_for_autoindent_applied())?
 5569            {
 5570                waiter.await?;
 5571            }
 5572            cx.update(|cx| {
 5573                this.update(cx, |this, cx| {
 5574                    this.request_lsp(
 5575                        buffer.clone(),
 5576                        LanguageServerToQuery::FirstCapable,
 5577                        OnTypeFormatting {
 5578                            position,
 5579                            trigger,
 5580                            options,
 5581                            push_to_history,
 5582                        },
 5583                        cx,
 5584                    )
 5585                })
 5586            })??
 5587            .await
 5588        })
 5589    }
 5590
 5591    pub fn definitions(
 5592        &mut self,
 5593        buffer: &Entity<Buffer>,
 5594        position: PointUtf16,
 5595        cx: &mut Context<Self>,
 5596    ) -> Task<Result<Option<Vec<LocationLink>>>> {
 5597        if let Some((upstream_client, project_id)) = self.upstream_client() {
 5598            let request = GetDefinitions { position };
 5599            if !self.is_capable_for_proto_request(buffer, &request, cx) {
 5600                return Task::ready(Ok(None));
 5601            }
 5602            let request_task = upstream_client.request_lsp(
 5603                project_id,
 5604                None,
 5605                LSP_REQUEST_TIMEOUT,
 5606                cx.background_executor().clone(),
 5607                request.to_proto(project_id, buffer.read(cx)),
 5608            );
 5609            let buffer = buffer.clone();
 5610            cx.spawn(async move |weak_lsp_store, cx| {
 5611                let Some(lsp_store) = weak_lsp_store.upgrade() else {
 5612                    return Ok(None);
 5613                };
 5614                let Some(responses) = request_task.await? else {
 5615                    return Ok(None);
 5616                };
 5617                let actions = join_all(responses.payload.into_iter().map(|response| {
 5618                    GetDefinitions { position }.response_from_proto(
 5619                        response.response,
 5620                        lsp_store.clone(),
 5621                        buffer.clone(),
 5622                        cx.clone(),
 5623                    )
 5624                }))
 5625                .await;
 5626
 5627                Ok(Some(
 5628                    actions
 5629                        .into_iter()
 5630                        .collect::<Result<Vec<Vec<_>>>>()?
 5631                        .into_iter()
 5632                        .flatten()
 5633                        .dedup()
 5634                        .collect(),
 5635                ))
 5636            })
 5637        } else {
 5638            let definitions_task = self.request_multiple_lsp_locally(
 5639                buffer,
 5640                Some(position),
 5641                GetDefinitions { position },
 5642                cx,
 5643            );
 5644            cx.background_spawn(async move {
 5645                Ok(Some(
 5646                    definitions_task
 5647                        .await
 5648                        .into_iter()
 5649                        .flat_map(|(_, definitions)| definitions)
 5650                        .dedup()
 5651                        .collect(),
 5652                ))
 5653            })
 5654        }
 5655    }
 5656
 5657    pub fn declarations(
 5658        &mut self,
 5659        buffer: &Entity<Buffer>,
 5660        position: PointUtf16,
 5661        cx: &mut Context<Self>,
 5662    ) -> Task<Result<Option<Vec<LocationLink>>>> {
 5663        if let Some((upstream_client, project_id)) = self.upstream_client() {
 5664            let request = GetDeclarations { position };
 5665            if !self.is_capable_for_proto_request(buffer, &request, cx) {
 5666                return Task::ready(Ok(None));
 5667            }
 5668            let request_task = upstream_client.request_lsp(
 5669                project_id,
 5670                None,
 5671                LSP_REQUEST_TIMEOUT,
 5672                cx.background_executor().clone(),
 5673                request.to_proto(project_id, buffer.read(cx)),
 5674            );
 5675            let buffer = buffer.clone();
 5676            cx.spawn(async move |weak_lsp_store, cx| {
 5677                let Some(lsp_store) = weak_lsp_store.upgrade() else {
 5678                    return Ok(None);
 5679                };
 5680                let Some(responses) = request_task.await? else {
 5681                    return Ok(None);
 5682                };
 5683                let actions = join_all(responses.payload.into_iter().map(|response| {
 5684                    GetDeclarations { position }.response_from_proto(
 5685                        response.response,
 5686                        lsp_store.clone(),
 5687                        buffer.clone(),
 5688                        cx.clone(),
 5689                    )
 5690                }))
 5691                .await;
 5692
 5693                Ok(Some(
 5694                    actions
 5695                        .into_iter()
 5696                        .collect::<Result<Vec<Vec<_>>>>()?
 5697                        .into_iter()
 5698                        .flatten()
 5699                        .dedup()
 5700                        .collect(),
 5701                ))
 5702            })
 5703        } else {
 5704            let declarations_task = self.request_multiple_lsp_locally(
 5705                buffer,
 5706                Some(position),
 5707                GetDeclarations { position },
 5708                cx,
 5709            );
 5710            cx.background_spawn(async move {
 5711                Ok(Some(
 5712                    declarations_task
 5713                        .await
 5714                        .into_iter()
 5715                        .flat_map(|(_, declarations)| declarations)
 5716                        .dedup()
 5717                        .collect(),
 5718                ))
 5719            })
 5720        }
 5721    }
 5722
 5723    pub fn type_definitions(
 5724        &mut self,
 5725        buffer: &Entity<Buffer>,
 5726        position: PointUtf16,
 5727        cx: &mut Context<Self>,
 5728    ) -> Task<Result<Option<Vec<LocationLink>>>> {
 5729        if let Some((upstream_client, project_id)) = self.upstream_client() {
 5730            let request = GetTypeDefinitions { position };
 5731            if !self.is_capable_for_proto_request(buffer, &request, cx) {
 5732                return Task::ready(Ok(None));
 5733            }
 5734            let request_task = upstream_client.request_lsp(
 5735                project_id,
 5736                None,
 5737                LSP_REQUEST_TIMEOUT,
 5738                cx.background_executor().clone(),
 5739                request.to_proto(project_id, buffer.read(cx)),
 5740            );
 5741            let buffer = buffer.clone();
 5742            cx.spawn(async move |weak_lsp_store, cx| {
 5743                let Some(lsp_store) = weak_lsp_store.upgrade() else {
 5744                    return Ok(None);
 5745                };
 5746                let Some(responses) = request_task.await? else {
 5747                    return Ok(None);
 5748                };
 5749                let actions = join_all(responses.payload.into_iter().map(|response| {
 5750                    GetTypeDefinitions { position }.response_from_proto(
 5751                        response.response,
 5752                        lsp_store.clone(),
 5753                        buffer.clone(),
 5754                        cx.clone(),
 5755                    )
 5756                }))
 5757                .await;
 5758
 5759                Ok(Some(
 5760                    actions
 5761                        .into_iter()
 5762                        .collect::<Result<Vec<Vec<_>>>>()?
 5763                        .into_iter()
 5764                        .flatten()
 5765                        .dedup()
 5766                        .collect(),
 5767                ))
 5768            })
 5769        } else {
 5770            let type_definitions_task = self.request_multiple_lsp_locally(
 5771                buffer,
 5772                Some(position),
 5773                GetTypeDefinitions { position },
 5774                cx,
 5775            );
 5776            cx.background_spawn(async move {
 5777                Ok(Some(
 5778                    type_definitions_task
 5779                        .await
 5780                        .into_iter()
 5781                        .flat_map(|(_, type_definitions)| type_definitions)
 5782                        .dedup()
 5783                        .collect(),
 5784                ))
 5785            })
 5786        }
 5787    }
 5788
 5789    pub fn implementations(
 5790        &mut self,
 5791        buffer: &Entity<Buffer>,
 5792        position: PointUtf16,
 5793        cx: &mut Context<Self>,
 5794    ) -> Task<Result<Option<Vec<LocationLink>>>> {
 5795        if let Some((upstream_client, project_id)) = self.upstream_client() {
 5796            let request = GetImplementations { position };
 5797            if !self.is_capable_for_proto_request(buffer, &request, cx) {
 5798                return Task::ready(Ok(None));
 5799            }
 5800            let request_task = upstream_client.request_lsp(
 5801                project_id,
 5802                None,
 5803                LSP_REQUEST_TIMEOUT,
 5804                cx.background_executor().clone(),
 5805                request.to_proto(project_id, buffer.read(cx)),
 5806            );
 5807            let buffer = buffer.clone();
 5808            cx.spawn(async move |weak_lsp_store, cx| {
 5809                let Some(lsp_store) = weak_lsp_store.upgrade() else {
 5810                    return Ok(None);
 5811                };
 5812                let Some(responses) = request_task.await? else {
 5813                    return Ok(None);
 5814                };
 5815                let actions = join_all(responses.payload.into_iter().map(|response| {
 5816                    GetImplementations { position }.response_from_proto(
 5817                        response.response,
 5818                        lsp_store.clone(),
 5819                        buffer.clone(),
 5820                        cx.clone(),
 5821                    )
 5822                }))
 5823                .await;
 5824
 5825                Ok(Some(
 5826                    actions
 5827                        .into_iter()
 5828                        .collect::<Result<Vec<Vec<_>>>>()?
 5829                        .into_iter()
 5830                        .flatten()
 5831                        .dedup()
 5832                        .collect(),
 5833                ))
 5834            })
 5835        } else {
 5836            let implementations_task = self.request_multiple_lsp_locally(
 5837                buffer,
 5838                Some(position),
 5839                GetImplementations { position },
 5840                cx,
 5841            );
 5842            cx.background_spawn(async move {
 5843                Ok(Some(
 5844                    implementations_task
 5845                        .await
 5846                        .into_iter()
 5847                        .flat_map(|(_, implementations)| implementations)
 5848                        .dedup()
 5849                        .collect(),
 5850                ))
 5851            })
 5852        }
 5853    }
 5854
 5855    pub fn references(
 5856        &mut self,
 5857        buffer: &Entity<Buffer>,
 5858        position: PointUtf16,
 5859        cx: &mut Context<Self>,
 5860    ) -> Task<Result<Option<Vec<Location>>>> {
 5861        if let Some((upstream_client, project_id)) = self.upstream_client() {
 5862            let request = GetReferences { position };
 5863            if !self.is_capable_for_proto_request(buffer, &request, cx) {
 5864                return Task::ready(Ok(None));
 5865            }
 5866
 5867            let request_task = upstream_client.request_lsp(
 5868                project_id,
 5869                None,
 5870                LSP_REQUEST_TIMEOUT,
 5871                cx.background_executor().clone(),
 5872                request.to_proto(project_id, buffer.read(cx)),
 5873            );
 5874            let buffer = buffer.clone();
 5875            cx.spawn(async move |weak_lsp_store, cx| {
 5876                let Some(lsp_store) = weak_lsp_store.upgrade() else {
 5877                    return Ok(None);
 5878                };
 5879                let Some(responses) = request_task.await? else {
 5880                    return Ok(None);
 5881                };
 5882
 5883                let locations = join_all(responses.payload.into_iter().map(|lsp_response| {
 5884                    GetReferences { position }.response_from_proto(
 5885                        lsp_response.response,
 5886                        lsp_store.clone(),
 5887                        buffer.clone(),
 5888                        cx.clone(),
 5889                    )
 5890                }))
 5891                .await
 5892                .into_iter()
 5893                .collect::<Result<Vec<Vec<_>>>>()?
 5894                .into_iter()
 5895                .flatten()
 5896                .dedup()
 5897                .collect();
 5898                Ok(Some(locations))
 5899            })
 5900        } else {
 5901            let references_task = self.request_multiple_lsp_locally(
 5902                buffer,
 5903                Some(position),
 5904                GetReferences { position },
 5905                cx,
 5906            );
 5907            cx.background_spawn(async move {
 5908                Ok(Some(
 5909                    references_task
 5910                        .await
 5911                        .into_iter()
 5912                        .flat_map(|(_, references)| references)
 5913                        .dedup()
 5914                        .collect(),
 5915                ))
 5916            })
 5917        }
 5918    }
 5919
 5920    pub fn code_actions(
 5921        &mut self,
 5922        buffer: &Entity<Buffer>,
 5923        range: Range<Anchor>,
 5924        kinds: Option<Vec<CodeActionKind>>,
 5925        cx: &mut Context<Self>,
 5926    ) -> Task<Result<Option<Vec<CodeAction>>>> {
 5927        if let Some((upstream_client, project_id)) = self.upstream_client() {
 5928            let request = GetCodeActions {
 5929                range: range.clone(),
 5930                kinds: kinds.clone(),
 5931            };
 5932            if !self.is_capable_for_proto_request(buffer, &request, cx) {
 5933                return Task::ready(Ok(None));
 5934            }
 5935            let request_task = upstream_client.request_lsp(
 5936                project_id,
 5937                None,
 5938                LSP_REQUEST_TIMEOUT,
 5939                cx.background_executor().clone(),
 5940                request.to_proto(project_id, buffer.read(cx)),
 5941            );
 5942            let buffer = buffer.clone();
 5943            cx.spawn(async move |weak_lsp_store, cx| {
 5944                let Some(lsp_store) = weak_lsp_store.upgrade() else {
 5945                    return Ok(None);
 5946                };
 5947                let Some(responses) = request_task.await? else {
 5948                    return Ok(None);
 5949                };
 5950                let actions = join_all(responses.payload.into_iter().map(|response| {
 5951                    GetCodeActions {
 5952                        range: range.clone(),
 5953                        kinds: kinds.clone(),
 5954                    }
 5955                    .response_from_proto(
 5956                        response.response,
 5957                        lsp_store.clone(),
 5958                        buffer.clone(),
 5959                        cx.clone(),
 5960                    )
 5961                }))
 5962                .await;
 5963
 5964                Ok(Some(
 5965                    actions
 5966                        .into_iter()
 5967                        .collect::<Result<Vec<Vec<_>>>>()?
 5968                        .into_iter()
 5969                        .flatten()
 5970                        .collect(),
 5971                ))
 5972            })
 5973        } else {
 5974            let all_actions_task = self.request_multiple_lsp_locally(
 5975                buffer,
 5976                Some(range.start),
 5977                GetCodeActions { range, kinds },
 5978                cx,
 5979            );
 5980            cx.background_spawn(async move {
 5981                Ok(Some(
 5982                    all_actions_task
 5983                        .await
 5984                        .into_iter()
 5985                        .flat_map(|(_, actions)| actions)
 5986                        .collect(),
 5987                ))
 5988            })
 5989        }
 5990    }
 5991
 5992    pub fn code_lens_actions(
 5993        &mut self,
 5994        buffer: &Entity<Buffer>,
 5995        cx: &mut Context<Self>,
 5996    ) -> CodeLensTask {
 5997        let version_queried_for = buffer.read(cx).version();
 5998        let buffer_id = buffer.read(cx).remote_id();
 5999        let existing_servers = self.as_local().map(|local| {
 6000            local
 6001                .buffers_opened_in_servers
 6002                .get(&buffer_id)
 6003                .cloned()
 6004                .unwrap_or_default()
 6005        });
 6006
 6007        if let Some(lsp_data) = self.current_lsp_data(buffer_id) {
 6008            if let Some(cached_lens) = &lsp_data.code_lens {
 6009                if !version_queried_for.changed_since(&lsp_data.buffer_version) {
 6010                    let has_different_servers = existing_servers.is_some_and(|existing_servers| {
 6011                        existing_servers != cached_lens.lens.keys().copied().collect()
 6012                    });
 6013                    if !has_different_servers {
 6014                        return Task::ready(Ok(Some(
 6015                            cached_lens.lens.values().flatten().cloned().collect(),
 6016                        )))
 6017                        .shared();
 6018                    }
 6019                } else if let Some((updating_for, running_update)) = cached_lens.update.as_ref() {
 6020                    if !version_queried_for.changed_since(updating_for) {
 6021                        return running_update.clone();
 6022                    }
 6023                }
 6024            }
 6025        }
 6026
 6027        let lens_lsp_data = self
 6028            .latest_lsp_data(buffer, cx)
 6029            .code_lens
 6030            .get_or_insert_default();
 6031        let buffer = buffer.clone();
 6032        let query_version_queried_for = version_queried_for.clone();
 6033        let new_task = cx
 6034            .spawn(async move |lsp_store, cx| {
 6035                cx.background_executor()
 6036                    .timer(Duration::from_millis(30))
 6037                    .await;
 6038                let fetched_lens = lsp_store
 6039                    .update(cx, |lsp_store, cx| lsp_store.fetch_code_lens(&buffer, cx))
 6040                    .map_err(Arc::new)?
 6041                    .await
 6042                    .context("fetching code lens")
 6043                    .map_err(Arc::new);
 6044                let fetched_lens = match fetched_lens {
 6045                    Ok(fetched_lens) => fetched_lens,
 6046                    Err(e) => {
 6047                        lsp_store
 6048                            .update(cx, |lsp_store, _| {
 6049                                if let Some(lens_lsp_data) = lsp_store
 6050                                    .lsp_data
 6051                                    .get_mut(&buffer_id)
 6052                                    .and_then(|lsp_data| lsp_data.code_lens.as_mut())
 6053                                {
 6054                                    lens_lsp_data.update = None;
 6055                                }
 6056                            })
 6057                            .ok();
 6058                        return Err(e);
 6059                    }
 6060                };
 6061
 6062                lsp_store
 6063                    .update(cx, |lsp_store, _| {
 6064                        let lsp_data = lsp_store.current_lsp_data(buffer_id)?;
 6065                        let code_lens = lsp_data.code_lens.as_mut()?;
 6066                        if let Some(fetched_lens) = fetched_lens {
 6067                            if lsp_data.buffer_version == query_version_queried_for {
 6068                                code_lens.lens.extend(fetched_lens);
 6069                            } else if !lsp_data
 6070                                .buffer_version
 6071                                .changed_since(&query_version_queried_for)
 6072                            {
 6073                                lsp_data.buffer_version = query_version_queried_for;
 6074                                code_lens.lens = fetched_lens;
 6075                            }
 6076                        }
 6077                        code_lens.update = None;
 6078                        Some(code_lens.lens.values().flatten().cloned().collect())
 6079                    })
 6080                    .map_err(Arc::new)
 6081            })
 6082            .shared();
 6083        lens_lsp_data.update = Some((version_queried_for, new_task.clone()));
 6084        new_task
 6085    }
 6086
 6087    fn fetch_code_lens(
 6088        &mut self,
 6089        buffer: &Entity<Buffer>,
 6090        cx: &mut Context<Self>,
 6091    ) -> Task<Result<Option<HashMap<LanguageServerId, Vec<CodeAction>>>>> {
 6092        if let Some((upstream_client, project_id)) = self.upstream_client() {
 6093            let request = GetCodeLens;
 6094            if !self.is_capable_for_proto_request(buffer, &request, cx) {
 6095                return Task::ready(Ok(None));
 6096            }
 6097            let request_task = upstream_client.request_lsp(
 6098                project_id,
 6099                None,
 6100                LSP_REQUEST_TIMEOUT,
 6101                cx.background_executor().clone(),
 6102                request.to_proto(project_id, buffer.read(cx)),
 6103            );
 6104            let buffer = buffer.clone();
 6105            cx.spawn(async move |weak_lsp_store, cx| {
 6106                let Some(lsp_store) = weak_lsp_store.upgrade() else {
 6107                    return Ok(None);
 6108                };
 6109                let Some(responses) = request_task.await? else {
 6110                    return Ok(None);
 6111                };
 6112
 6113                let code_lens_actions = join_all(responses.payload.into_iter().map(|response| {
 6114                    let lsp_store = lsp_store.clone();
 6115                    let buffer = buffer.clone();
 6116                    let cx = cx.clone();
 6117                    async move {
 6118                        (
 6119                            LanguageServerId::from_proto(response.server_id),
 6120                            GetCodeLens
 6121                                .response_from_proto(response.response, lsp_store, buffer, cx)
 6122                                .await,
 6123                        )
 6124                    }
 6125                }))
 6126                .await;
 6127
 6128                let mut has_errors = false;
 6129                let code_lens_actions = code_lens_actions
 6130                    .into_iter()
 6131                    .filter_map(|(server_id, code_lens)| match code_lens {
 6132                        Ok(code_lens) => Some((server_id, code_lens)),
 6133                        Err(e) => {
 6134                            has_errors = true;
 6135                            log::error!("{e:#}");
 6136                            None
 6137                        }
 6138                    })
 6139                    .collect::<HashMap<_, _>>();
 6140                anyhow::ensure!(
 6141                    !has_errors || !code_lens_actions.is_empty(),
 6142                    "Failed to fetch code lens"
 6143                );
 6144                Ok(Some(code_lens_actions))
 6145            })
 6146        } else {
 6147            let code_lens_actions_task =
 6148                self.request_multiple_lsp_locally(buffer, None::<usize>, GetCodeLens, cx);
 6149            cx.background_spawn(async move {
 6150                Ok(Some(code_lens_actions_task.await.into_iter().collect()))
 6151            })
 6152        }
 6153    }
 6154
 6155    #[inline(never)]
 6156    pub fn completions(
 6157        &self,
 6158        buffer: &Entity<Buffer>,
 6159        position: PointUtf16,
 6160        context: CompletionContext,
 6161        cx: &mut Context<Self>,
 6162    ) -> Task<Result<Vec<CompletionResponse>>> {
 6163        let language_registry = self.languages.clone();
 6164
 6165        if let Some((upstream_client, project_id)) = self.upstream_client() {
 6166            let snapshot = buffer.read(cx).snapshot();
 6167            let offset = position.to_offset(&snapshot);
 6168            let scope = snapshot.language_scope_at(offset);
 6169            let capable_lsps = self.all_capable_for_proto_request(
 6170                buffer,
 6171                |server_name, capabilities| {
 6172                    capabilities.completion_provider.is_some()
 6173                        && scope
 6174                            .as_ref()
 6175                            .map(|scope| scope.language_allowed(server_name))
 6176                            .unwrap_or(true)
 6177                },
 6178                cx,
 6179            );
 6180            if capable_lsps.is_empty() {
 6181                return Task::ready(Ok(Vec::new()));
 6182            }
 6183
 6184            let language = buffer.read(cx).language().cloned();
 6185
 6186            // In the future, we should provide project guests with the names of LSP adapters,
 6187            // so that they can use the correct LSP adapter when computing labels. For now,
 6188            // guests just use the first LSP adapter associated with the buffer's language.
 6189            let lsp_adapter = language.as_ref().and_then(|language| {
 6190                language_registry
 6191                    .lsp_adapters(&language.name())
 6192                    .first()
 6193                    .cloned()
 6194            });
 6195
 6196            let buffer = buffer.clone();
 6197
 6198            cx.spawn(async move |this, cx| {
 6199                let requests = join_all(
 6200                    capable_lsps
 6201                        .into_iter()
 6202                        .map(|id| {
 6203                            let request = GetCompletions {
 6204                                position,
 6205                                context: context.clone(),
 6206                                server_id: Some(id),
 6207                            };
 6208                            let buffer = buffer.clone();
 6209                            let language = language.clone();
 6210                            let lsp_adapter = lsp_adapter.clone();
 6211                            let upstream_client = upstream_client.clone();
 6212                            let response = this
 6213                                .update(cx, |this, cx| {
 6214                                    this.send_lsp_proto_request(
 6215                                        buffer,
 6216                                        upstream_client,
 6217                                        project_id,
 6218                                        request,
 6219                                        cx,
 6220                                    )
 6221                                })
 6222                                .log_err();
 6223                            async move {
 6224                                let response = response?.await.log_err()?;
 6225
 6226                                let completions = populate_labels_for_completions(
 6227                                    response.completions,
 6228                                    language,
 6229                                    lsp_adapter,
 6230                                )
 6231                                .await;
 6232
 6233                                Some(CompletionResponse {
 6234                                    completions,
 6235                                    display_options: CompletionDisplayOptions::default(),
 6236                                    is_incomplete: response.is_incomplete,
 6237                                })
 6238                            }
 6239                        })
 6240                        .collect::<Vec<_>>(),
 6241                );
 6242                Ok(requests.await.into_iter().flatten().collect::<Vec<_>>())
 6243            })
 6244        } else if let Some(local) = self.as_local() {
 6245            let snapshot = buffer.read(cx).snapshot();
 6246            let offset = position.to_offset(&snapshot);
 6247            let scope = snapshot.language_scope_at(offset);
 6248            let language = snapshot.language().cloned();
 6249            let completion_settings = language_settings(
 6250                language.as_ref().map(|language| language.name()),
 6251                buffer.read(cx).file(),
 6252                cx,
 6253            )
 6254            .completions
 6255            .clone();
 6256            if !completion_settings.lsp {
 6257                return Task::ready(Ok(Vec::new()));
 6258            }
 6259
 6260            let server_ids: Vec<_> = buffer.update(cx, |buffer, cx| {
 6261                local
 6262                    .language_servers_for_buffer(buffer, cx)
 6263                    .filter(|(_, server)| server.capabilities().completion_provider.is_some())
 6264                    .filter(|(adapter, _)| {
 6265                        scope
 6266                            .as_ref()
 6267                            .map(|scope| scope.language_allowed(&adapter.name))
 6268                            .unwrap_or(true)
 6269                    })
 6270                    .map(|(_, server)| server.server_id())
 6271                    .collect()
 6272            });
 6273
 6274            let buffer = buffer.clone();
 6275            let lsp_timeout = completion_settings.lsp_fetch_timeout_ms;
 6276            let lsp_timeout = if lsp_timeout > 0 {
 6277                Some(Duration::from_millis(lsp_timeout))
 6278            } else {
 6279                None
 6280            };
 6281            cx.spawn(async move |this,  cx| {
 6282                let mut tasks = Vec::with_capacity(server_ids.len());
 6283                this.update(cx, |lsp_store, cx| {
 6284                    for server_id in server_ids {
 6285                        let lsp_adapter = lsp_store.language_server_adapter_for_id(server_id);
 6286                        let lsp_timeout = lsp_timeout
 6287                            .map(|lsp_timeout| cx.background_executor().timer(lsp_timeout));
 6288                        let mut timeout = cx.background_spawn(async move {
 6289                            match lsp_timeout {
 6290                                Some(lsp_timeout) => {
 6291                                    lsp_timeout.await;
 6292                                    true
 6293                                },
 6294                                None => false,
 6295                            }
 6296                        }).fuse();
 6297                        let mut lsp_request = lsp_store.request_lsp(
 6298                            buffer.clone(),
 6299                            LanguageServerToQuery::Other(server_id),
 6300                            GetCompletions {
 6301                                position,
 6302                                context: context.clone(),
 6303                                server_id: Some(server_id),
 6304                            },
 6305                            cx,
 6306                        ).fuse();
 6307                        let new_task = cx.background_spawn(async move {
 6308                            select_biased! {
 6309                                response = lsp_request => anyhow::Ok(Some(response?)),
 6310                                timeout_happened = timeout => {
 6311                                    if timeout_happened {
 6312                                        log::warn!("Fetching completions from server {server_id} timed out, timeout ms: {}", completion_settings.lsp_fetch_timeout_ms);
 6313                                        Ok(None)
 6314                                    } else {
 6315                                        let completions = lsp_request.await?;
 6316                                        Ok(Some(completions))
 6317                                    }
 6318                                },
 6319                            }
 6320                        });
 6321                        tasks.push((lsp_adapter, new_task));
 6322                    }
 6323                })?;
 6324
 6325                let futures = tasks.into_iter().map(async |(lsp_adapter, task)| {
 6326                    let completion_response = task.await.ok()??;
 6327                    let completions = populate_labels_for_completions(
 6328                            completion_response.completions,
 6329                            language.clone(),
 6330                            lsp_adapter,
 6331                        )
 6332                        .await;
 6333                    Some(CompletionResponse {
 6334                        completions,
 6335                        display_options: CompletionDisplayOptions::default(),
 6336                        is_incomplete: completion_response.is_incomplete,
 6337                    })
 6338                });
 6339
 6340                let responses: Vec<Option<CompletionResponse>> = join_all(futures).await;
 6341
 6342                Ok(responses.into_iter().flatten().collect())
 6343            })
 6344        } else {
 6345            Task::ready(Err(anyhow!("No upstream client or local language server")))
 6346        }
 6347    }
 6348
 6349    pub fn resolve_completions(
 6350        &self,
 6351        buffer: Entity<Buffer>,
 6352        completion_indices: Vec<usize>,
 6353        completions: Rc<RefCell<Box<[Completion]>>>,
 6354        cx: &mut Context<Self>,
 6355    ) -> Task<Result<bool>> {
 6356        let client = self.upstream_client();
 6357        let buffer_id = buffer.read(cx).remote_id();
 6358        let buffer_snapshot = buffer.read(cx).snapshot();
 6359
 6360        if !self.check_if_capable_for_proto_request(
 6361            &buffer,
 6362            GetCompletions::can_resolve_completions,
 6363            cx,
 6364        ) {
 6365            return Task::ready(Ok(false));
 6366        }
 6367        cx.spawn(async move |lsp_store, cx| {
 6368            let mut did_resolve = false;
 6369            if let Some((client, project_id)) = client {
 6370                for completion_index in completion_indices {
 6371                    let server_id = {
 6372                        let completion = &completions.borrow()[completion_index];
 6373                        completion.source.server_id()
 6374                    };
 6375                    if let Some(server_id) = server_id {
 6376                        if Self::resolve_completion_remote(
 6377                            project_id,
 6378                            server_id,
 6379                            buffer_id,
 6380                            completions.clone(),
 6381                            completion_index,
 6382                            client.clone(),
 6383                        )
 6384                        .await
 6385                        .log_err()
 6386                        .is_some()
 6387                        {
 6388                            did_resolve = true;
 6389                        }
 6390                    } else {
 6391                        resolve_word_completion(
 6392                            &buffer_snapshot,
 6393                            &mut completions.borrow_mut()[completion_index],
 6394                        );
 6395                    }
 6396                }
 6397            } else {
 6398                for completion_index in completion_indices {
 6399                    let server_id = {
 6400                        let completion = &completions.borrow()[completion_index];
 6401                        completion.source.server_id()
 6402                    };
 6403                    if let Some(server_id) = server_id {
 6404                        let server_and_adapter = lsp_store
 6405                            .read_with(cx, |lsp_store, _| {
 6406                                let server = lsp_store.language_server_for_id(server_id)?;
 6407                                let adapter =
 6408                                    lsp_store.language_server_adapter_for_id(server.server_id())?;
 6409                                Some((server, adapter))
 6410                            })
 6411                            .ok()
 6412                            .flatten();
 6413                        let Some((server, adapter)) = server_and_adapter else {
 6414                            continue;
 6415                        };
 6416
 6417                        let resolved = Self::resolve_completion_local(
 6418                            server,
 6419                            completions.clone(),
 6420                            completion_index,
 6421                        )
 6422                        .await
 6423                        .log_err()
 6424                        .is_some();
 6425                        if resolved {
 6426                            Self::regenerate_completion_labels(
 6427                                adapter,
 6428                                &buffer_snapshot,
 6429                                completions.clone(),
 6430                                completion_index,
 6431                            )
 6432                            .await
 6433                            .log_err();
 6434                            did_resolve = true;
 6435                        }
 6436                    } else {
 6437                        resolve_word_completion(
 6438                            &buffer_snapshot,
 6439                            &mut completions.borrow_mut()[completion_index],
 6440                        );
 6441                    }
 6442                }
 6443            }
 6444
 6445            Ok(did_resolve)
 6446        })
 6447    }
 6448
 6449    async fn resolve_completion_local(
 6450        server: Arc<lsp::LanguageServer>,
 6451        completions: Rc<RefCell<Box<[Completion]>>>,
 6452        completion_index: usize,
 6453    ) -> Result<()> {
 6454        let server_id = server.server_id();
 6455        if !GetCompletions::can_resolve_completions(&server.capabilities()) {
 6456            return Ok(());
 6457        }
 6458
 6459        let request = {
 6460            let completion = &completions.borrow()[completion_index];
 6461            match &completion.source {
 6462                CompletionSource::Lsp {
 6463                    lsp_completion,
 6464                    resolved,
 6465                    server_id: completion_server_id,
 6466                    ..
 6467                } => {
 6468                    if *resolved {
 6469                        return Ok(());
 6470                    }
 6471                    anyhow::ensure!(
 6472                        server_id == *completion_server_id,
 6473                        "server_id mismatch, querying completion resolve for {server_id} but completion server id is {completion_server_id}"
 6474                    );
 6475                    server.request::<lsp::request::ResolveCompletionItem>(*lsp_completion.clone())
 6476                }
 6477                CompletionSource::BufferWord { .. }
 6478                | CompletionSource::Dap { .. }
 6479                | CompletionSource::Custom => {
 6480                    return Ok(());
 6481                }
 6482            }
 6483        };
 6484        let resolved_completion = request
 6485            .await
 6486            .into_response()
 6487            .context("resolve completion")?;
 6488
 6489        // We must not use any data such as sortText, filterText, insertText and textEdit to edit `Completion` since they are not suppose change during resolve.
 6490        // Refer: https://microsoft.github.io/language-server-protocol/specifications/lsp/3.17/specification/#textDocument_completion
 6491
 6492        let mut completions = completions.borrow_mut();
 6493        let completion = &mut completions[completion_index];
 6494        if let CompletionSource::Lsp {
 6495            lsp_completion,
 6496            resolved,
 6497            server_id: completion_server_id,
 6498            ..
 6499        } = &mut completion.source
 6500        {
 6501            if *resolved {
 6502                return Ok(());
 6503            }
 6504            anyhow::ensure!(
 6505                server_id == *completion_server_id,
 6506                "server_id mismatch, applying completion resolve for {server_id} but completion server id is {completion_server_id}"
 6507            );
 6508            *lsp_completion = Box::new(resolved_completion);
 6509            *resolved = true;
 6510        }
 6511        Ok(())
 6512    }
 6513
 6514    async fn regenerate_completion_labels(
 6515        adapter: Arc<CachedLspAdapter>,
 6516        snapshot: &BufferSnapshot,
 6517        completions: Rc<RefCell<Box<[Completion]>>>,
 6518        completion_index: usize,
 6519    ) -> Result<()> {
 6520        let completion_item = completions.borrow()[completion_index]
 6521            .source
 6522            .lsp_completion(true)
 6523            .map(Cow::into_owned);
 6524        if let Some(lsp_documentation) = completion_item
 6525            .as_ref()
 6526            .and_then(|completion_item| completion_item.documentation.clone())
 6527        {
 6528            let mut completions = completions.borrow_mut();
 6529            let completion = &mut completions[completion_index];
 6530            completion.documentation = Some(lsp_documentation.into());
 6531        } else {
 6532            let mut completions = completions.borrow_mut();
 6533            let completion = &mut completions[completion_index];
 6534            completion.documentation = Some(CompletionDocumentation::Undocumented);
 6535        }
 6536
 6537        let mut new_label = match completion_item {
 6538            Some(completion_item) => {
 6539                // 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
 6540                // So we have to update the label here anyway...
 6541                let language = snapshot.language();
 6542                match language {
 6543                    Some(language) => {
 6544                        adapter
 6545                            .labels_for_completions(
 6546                                std::slice::from_ref(&completion_item),
 6547                                language,
 6548                            )
 6549                            .await?
 6550                    }
 6551                    None => Vec::new(),
 6552                }
 6553                .pop()
 6554                .flatten()
 6555                .unwrap_or_else(|| {
 6556                    CodeLabel::fallback_for_completion(
 6557                        &completion_item,
 6558                        language.map(|language| language.as_ref()),
 6559                    )
 6560                })
 6561            }
 6562            None => CodeLabel::plain(
 6563                completions.borrow()[completion_index].new_text.clone(),
 6564                None,
 6565            ),
 6566        };
 6567        ensure_uniform_list_compatible_label(&mut new_label);
 6568
 6569        let mut completions = completions.borrow_mut();
 6570        let completion = &mut completions[completion_index];
 6571        if completion.label.filter_text() == new_label.filter_text() {
 6572            completion.label = new_label;
 6573        } else {
 6574            log::error!(
 6575                "Resolved completion changed display label from {} to {}. \
 6576                 Refusing to apply this because it changes the fuzzy match text from {} to {}",
 6577                completion.label.text(),
 6578                new_label.text(),
 6579                completion.label.filter_text(),
 6580                new_label.filter_text()
 6581            );
 6582        }
 6583
 6584        Ok(())
 6585    }
 6586
 6587    async fn resolve_completion_remote(
 6588        project_id: u64,
 6589        server_id: LanguageServerId,
 6590        buffer_id: BufferId,
 6591        completions: Rc<RefCell<Box<[Completion]>>>,
 6592        completion_index: usize,
 6593        client: AnyProtoClient,
 6594    ) -> Result<()> {
 6595        let lsp_completion = {
 6596            let completion = &completions.borrow()[completion_index];
 6597            match &completion.source {
 6598                CompletionSource::Lsp {
 6599                    lsp_completion,
 6600                    resolved,
 6601                    server_id: completion_server_id,
 6602                    ..
 6603                } => {
 6604                    anyhow::ensure!(
 6605                        server_id == *completion_server_id,
 6606                        "remote server_id mismatch, querying completion resolve for {server_id} but completion server id is {completion_server_id}"
 6607                    );
 6608                    if *resolved {
 6609                        return Ok(());
 6610                    }
 6611                    serde_json::to_string(lsp_completion).unwrap().into_bytes()
 6612                }
 6613                CompletionSource::Custom
 6614                | CompletionSource::Dap { .. }
 6615                | CompletionSource::BufferWord { .. } => {
 6616                    return Ok(());
 6617                }
 6618            }
 6619        };
 6620        let request = proto::ResolveCompletionDocumentation {
 6621            project_id,
 6622            language_server_id: server_id.0 as u64,
 6623            lsp_completion,
 6624            buffer_id: buffer_id.into(),
 6625        };
 6626
 6627        let response = client
 6628            .request(request)
 6629            .await
 6630            .context("completion documentation resolve proto request")?;
 6631        let resolved_lsp_completion = serde_json::from_slice(&response.lsp_completion)?;
 6632
 6633        let documentation = if response.documentation.is_empty() {
 6634            CompletionDocumentation::Undocumented
 6635        } else if response.documentation_is_markdown {
 6636            CompletionDocumentation::MultiLineMarkdown(response.documentation.into())
 6637        } else if response.documentation.lines().count() <= 1 {
 6638            CompletionDocumentation::SingleLine(response.documentation.into())
 6639        } else {
 6640            CompletionDocumentation::MultiLinePlainText(response.documentation.into())
 6641        };
 6642
 6643        let mut completions = completions.borrow_mut();
 6644        let completion = &mut completions[completion_index];
 6645        completion.documentation = Some(documentation);
 6646        if let CompletionSource::Lsp {
 6647            insert_range,
 6648            lsp_completion,
 6649            resolved,
 6650            server_id: completion_server_id,
 6651            lsp_defaults: _,
 6652        } = &mut completion.source
 6653        {
 6654            let completion_insert_range = response
 6655                .old_insert_start
 6656                .and_then(deserialize_anchor)
 6657                .zip(response.old_insert_end.and_then(deserialize_anchor));
 6658            *insert_range = completion_insert_range.map(|(start, end)| start..end);
 6659
 6660            if *resolved {
 6661                return Ok(());
 6662            }
 6663            anyhow::ensure!(
 6664                server_id == *completion_server_id,
 6665                "remote server_id mismatch, applying completion resolve for {server_id} but completion server id is {completion_server_id}"
 6666            );
 6667            *lsp_completion = Box::new(resolved_lsp_completion);
 6668            *resolved = true;
 6669        }
 6670
 6671        let replace_range = response
 6672            .old_replace_start
 6673            .and_then(deserialize_anchor)
 6674            .zip(response.old_replace_end.and_then(deserialize_anchor));
 6675        if let Some((old_replace_start, old_replace_end)) = replace_range
 6676            && !response.new_text.is_empty()
 6677        {
 6678            completion.new_text = response.new_text;
 6679            completion.replace_range = old_replace_start..old_replace_end;
 6680        }
 6681
 6682        Ok(())
 6683    }
 6684
 6685    pub fn apply_additional_edits_for_completion(
 6686        &self,
 6687        buffer_handle: Entity<Buffer>,
 6688        completions: Rc<RefCell<Box<[Completion]>>>,
 6689        completion_index: usize,
 6690        push_to_history: bool,
 6691        cx: &mut Context<Self>,
 6692    ) -> Task<Result<Option<Transaction>>> {
 6693        if let Some((client, project_id)) = self.upstream_client() {
 6694            let buffer = buffer_handle.read(cx);
 6695            let buffer_id = buffer.remote_id();
 6696            cx.spawn(async move |_, cx| {
 6697                let request = {
 6698                    let completion = completions.borrow()[completion_index].clone();
 6699                    proto::ApplyCompletionAdditionalEdits {
 6700                        project_id,
 6701                        buffer_id: buffer_id.into(),
 6702                        completion: Some(Self::serialize_completion(&CoreCompletion {
 6703                            replace_range: completion.replace_range,
 6704                            new_text: completion.new_text,
 6705                            source: completion.source,
 6706                        })),
 6707                    }
 6708                };
 6709
 6710                if let Some(transaction) = client.request(request).await?.transaction {
 6711                    let transaction = language::proto::deserialize_transaction(transaction)?;
 6712                    buffer_handle
 6713                        .update(cx, |buffer, _| {
 6714                            buffer.wait_for_edits(transaction.edit_ids.iter().copied())
 6715                        })?
 6716                        .await?;
 6717                    if push_to_history {
 6718                        buffer_handle.update(cx, |buffer, _| {
 6719                            buffer.push_transaction(transaction.clone(), Instant::now());
 6720                            buffer.finalize_last_transaction();
 6721                        })?;
 6722                    }
 6723                    Ok(Some(transaction))
 6724                } else {
 6725                    Ok(None)
 6726                }
 6727            })
 6728        } else {
 6729            let Some(server) = buffer_handle.update(cx, |buffer, cx| {
 6730                let completion = &completions.borrow()[completion_index];
 6731                let server_id = completion.source.server_id()?;
 6732                Some(
 6733                    self.language_server_for_local_buffer(buffer, server_id, cx)?
 6734                        .1
 6735                        .clone(),
 6736                )
 6737            }) else {
 6738                return Task::ready(Ok(None));
 6739            };
 6740
 6741            cx.spawn(async move |this, cx| {
 6742                Self::resolve_completion_local(
 6743                    server.clone(),
 6744                    completions.clone(),
 6745                    completion_index,
 6746                )
 6747                .await
 6748                .context("resolving completion")?;
 6749                let completion = completions.borrow()[completion_index].clone();
 6750                let additional_text_edits = completion
 6751                    .source
 6752                    .lsp_completion(true)
 6753                    .as_ref()
 6754                    .and_then(|lsp_completion| lsp_completion.additional_text_edits.clone());
 6755                if let Some(edits) = additional_text_edits {
 6756                    let edits = this
 6757                        .update(cx, |this, cx| {
 6758                            this.as_local_mut().unwrap().edits_from_lsp(
 6759                                &buffer_handle,
 6760                                edits,
 6761                                server.server_id(),
 6762                                None,
 6763                                cx,
 6764                            )
 6765                        })?
 6766                        .await?;
 6767
 6768                    buffer_handle.update(cx, |buffer, cx| {
 6769                        buffer.finalize_last_transaction();
 6770                        buffer.start_transaction();
 6771
 6772                        for (range, text) in edits {
 6773                            let primary = &completion.replace_range;
 6774
 6775                            // Special case: if both ranges start at the very beginning of the file (line 0, column 0),
 6776                            // and the primary completion is just an insertion (empty range), then this is likely
 6777                            // an auto-import scenario and should not be considered overlapping
 6778                            // https://github.com/zed-industries/zed/issues/26136
 6779                            let is_file_start_auto_import = {
 6780                                let snapshot = buffer.snapshot();
 6781                                let primary_start_point = primary.start.to_point(&snapshot);
 6782                                let range_start_point = range.start.to_point(&snapshot);
 6783
 6784                                let result = primary_start_point.row == 0
 6785                                    && primary_start_point.column == 0
 6786                                    && range_start_point.row == 0
 6787                                    && range_start_point.column == 0;
 6788
 6789                                result
 6790                            };
 6791
 6792                            let has_overlap = if is_file_start_auto_import {
 6793                                false
 6794                            } else {
 6795                                let start_within = primary.start.cmp(&range.start, buffer).is_le()
 6796                                    && primary.end.cmp(&range.start, buffer).is_ge();
 6797                                let end_within = range.start.cmp(&primary.end, buffer).is_le()
 6798                                    && range.end.cmp(&primary.end, buffer).is_ge();
 6799                                let result = start_within || end_within;
 6800                                result
 6801                            };
 6802
 6803                            //Skip additional edits which overlap with the primary completion edit
 6804                            //https://github.com/zed-industries/zed/pull/1871
 6805                            if !has_overlap {
 6806                                buffer.edit([(range, text)], None, cx);
 6807                            }
 6808                        }
 6809
 6810                        let transaction = if buffer.end_transaction(cx).is_some() {
 6811                            let transaction = buffer.finalize_last_transaction().unwrap().clone();
 6812                            if !push_to_history {
 6813                                buffer.forget_transaction(transaction.id);
 6814                            }
 6815                            Some(transaction)
 6816                        } else {
 6817                            None
 6818                        };
 6819                        Ok(transaction)
 6820                    })?
 6821                } else {
 6822                    Ok(None)
 6823                }
 6824            })
 6825        }
 6826    }
 6827
 6828    pub fn pull_diagnostics(
 6829        &mut self,
 6830        buffer: Entity<Buffer>,
 6831        cx: &mut Context<Self>,
 6832    ) -> Task<Result<Option<Vec<LspPullDiagnostics>>>> {
 6833        let buffer_id = buffer.read(cx).remote_id();
 6834
 6835        if let Some((client, upstream_project_id)) = self.upstream_client() {
 6836            let mut suitable_capabilities = None;
 6837            // Are we capable for proto request?
 6838            let any_server_has_diagnostics_provider = self.check_if_capable_for_proto_request(
 6839                &buffer,
 6840                |capabilities| {
 6841                    if let Some(caps) = &capabilities.diagnostic_provider {
 6842                        suitable_capabilities = Some(caps.clone());
 6843                        true
 6844                    } else {
 6845                        false
 6846                    }
 6847                },
 6848                cx,
 6849            );
 6850            // We don't really care which caps are passed into the request, as they're ignored by RPC anyways.
 6851            let Some(dynamic_caps) = suitable_capabilities else {
 6852                return Task::ready(Ok(None));
 6853            };
 6854            assert!(any_server_has_diagnostics_provider);
 6855
 6856            let identifier = buffer_diagnostic_identifier(&dynamic_caps);
 6857            let request = GetDocumentDiagnostics {
 6858                previous_result_id: None,
 6859                identifier,
 6860                registration_id: None,
 6861            };
 6862            let request_task = client.request_lsp(
 6863                upstream_project_id,
 6864                None,
 6865                LSP_REQUEST_TIMEOUT,
 6866                cx.background_executor().clone(),
 6867                request.to_proto(upstream_project_id, buffer.read(cx)),
 6868            );
 6869            cx.background_spawn(async move {
 6870                // Proto requests cause the diagnostics to be pulled from language server(s) on the local side
 6871                // and then, buffer state updated with the diagnostics received, which will be later propagated to the client.
 6872                // Do not attempt to further process the dummy responses here.
 6873                let _response = request_task.await?;
 6874                Ok(None)
 6875            })
 6876        } else {
 6877            let servers = buffer.update(cx, |buffer, cx| {
 6878                self.running_language_servers_for_local_buffer(buffer, cx)
 6879                    .map(|(_, server)| server.clone())
 6880                    .collect::<Vec<_>>()
 6881            });
 6882
 6883            let pull_diagnostics = servers
 6884                .into_iter()
 6885                .flat_map(|server| {
 6886                    let result = maybe!({
 6887                        let local = self.as_local()?;
 6888                        let server_id = server.server_id();
 6889                        let providers_with_identifiers = local
 6890                            .language_server_dynamic_registrations
 6891                            .get(&server_id)
 6892                            .into_iter()
 6893                            .flat_map(|registrations| registrations.diagnostics.clone())
 6894                            .collect::<Vec<_>>();
 6895                        Some(
 6896                            providers_with_identifiers
 6897                                .into_iter()
 6898                                .map(|(registration_id, dynamic_caps)| {
 6899                                    let identifier = buffer_diagnostic_identifier(&dynamic_caps);
 6900                                    let registration_id = registration_id.map(SharedString::from);
 6901                                    let result_id = self.result_id_for_buffer_pull(
 6902                                        server_id,
 6903                                        buffer_id,
 6904                                        &registration_id,
 6905                                        cx,
 6906                                    );
 6907                                    self.request_lsp(
 6908                                        buffer.clone(),
 6909                                        LanguageServerToQuery::Other(server_id),
 6910                                        GetDocumentDiagnostics {
 6911                                            previous_result_id: result_id,
 6912                                            registration_id,
 6913                                            identifier,
 6914                                        },
 6915                                        cx,
 6916                                    )
 6917                                })
 6918                                .collect::<Vec<_>>(),
 6919                        )
 6920                    });
 6921
 6922                    result.unwrap_or_default()
 6923                })
 6924                .collect::<Vec<_>>();
 6925
 6926            cx.background_spawn(async move {
 6927                let mut responses = Vec::new();
 6928                for diagnostics in join_all(pull_diagnostics).await {
 6929                    responses.extend(diagnostics?);
 6930                }
 6931                Ok(Some(responses))
 6932            })
 6933        }
 6934    }
 6935
 6936    pub fn applicable_inlay_chunks(
 6937        &mut self,
 6938        buffer: &Entity<Buffer>,
 6939        ranges: &[Range<text::Anchor>],
 6940        cx: &mut Context<Self>,
 6941    ) -> Vec<Range<BufferRow>> {
 6942        let buffer_snapshot = buffer.read(cx).snapshot();
 6943        let ranges = ranges
 6944            .iter()
 6945            .map(|range| range.to_point(&buffer_snapshot))
 6946            .collect::<Vec<_>>();
 6947
 6948        self.latest_lsp_data(buffer, cx)
 6949            .inlay_hints
 6950            .applicable_chunks(ranges.as_slice())
 6951            .map(|chunk| chunk.row_range())
 6952            .collect()
 6953    }
 6954
 6955    pub fn invalidate_inlay_hints<'a>(
 6956        &'a mut self,
 6957        for_buffers: impl IntoIterator<Item = &'a BufferId> + 'a,
 6958    ) {
 6959        for buffer_id in for_buffers {
 6960            if let Some(lsp_data) = self.lsp_data.get_mut(buffer_id) {
 6961                lsp_data.inlay_hints.clear();
 6962            }
 6963        }
 6964    }
 6965
 6966    pub fn inlay_hints(
 6967        &mut self,
 6968        invalidate: InvalidationStrategy,
 6969        buffer: Entity<Buffer>,
 6970        ranges: Vec<Range<text::Anchor>>,
 6971        known_chunks: Option<(clock::Global, HashSet<Range<BufferRow>>)>,
 6972        cx: &mut Context<Self>,
 6973    ) -> HashMap<Range<BufferRow>, Task<Result<CacheInlayHints>>> {
 6974        let next_hint_id = self.next_hint_id.clone();
 6975        let lsp_data = self.latest_lsp_data(&buffer, cx);
 6976        let query_version = lsp_data.buffer_version.clone();
 6977        let mut lsp_refresh_requested = false;
 6978        let for_server = if let InvalidationStrategy::RefreshRequested {
 6979            server_id,
 6980            request_id,
 6981        } = invalidate
 6982        {
 6983            let invalidated = lsp_data
 6984                .inlay_hints
 6985                .invalidate_for_server_refresh(server_id, request_id);
 6986            lsp_refresh_requested = invalidated;
 6987            Some(server_id)
 6988        } else {
 6989            None
 6990        };
 6991        let existing_inlay_hints = &mut lsp_data.inlay_hints;
 6992        let known_chunks = known_chunks
 6993            .filter(|(known_version, _)| !lsp_data.buffer_version.changed_since(known_version))
 6994            .map(|(_, known_chunks)| known_chunks)
 6995            .unwrap_or_default();
 6996
 6997        let buffer_snapshot = buffer.read(cx).snapshot();
 6998        let ranges = ranges
 6999            .iter()
 7000            .map(|range| range.to_point(&buffer_snapshot))
 7001            .collect::<Vec<_>>();
 7002
 7003        let mut hint_fetch_tasks = Vec::new();
 7004        let mut cached_inlay_hints = None;
 7005        let mut ranges_to_query = None;
 7006        let applicable_chunks = existing_inlay_hints
 7007            .applicable_chunks(ranges.as_slice())
 7008            .filter(|chunk| !known_chunks.contains(&chunk.row_range()))
 7009            .collect::<Vec<_>>();
 7010        if applicable_chunks.is_empty() {
 7011            return HashMap::default();
 7012        }
 7013
 7014        for row_chunk in applicable_chunks {
 7015            match (
 7016                existing_inlay_hints
 7017                    .cached_hints(&row_chunk)
 7018                    .filter(|_| !lsp_refresh_requested)
 7019                    .cloned(),
 7020                existing_inlay_hints
 7021                    .fetched_hints(&row_chunk)
 7022                    .as_ref()
 7023                    .filter(|_| !lsp_refresh_requested)
 7024                    .cloned(),
 7025            ) {
 7026                (None, None) => {
 7027                    let chunk_range = row_chunk.anchor_range();
 7028                    ranges_to_query
 7029                        .get_or_insert_with(Vec::new)
 7030                        .push((row_chunk, chunk_range));
 7031                }
 7032                (None, Some(fetched_hints)) => hint_fetch_tasks.push((row_chunk, fetched_hints)),
 7033                (Some(cached_hints), None) => {
 7034                    for (server_id, cached_hints) in cached_hints {
 7035                        if for_server.is_none_or(|for_server| for_server == server_id) {
 7036                            cached_inlay_hints
 7037                                .get_or_insert_with(HashMap::default)
 7038                                .entry(row_chunk.row_range())
 7039                                .or_insert_with(HashMap::default)
 7040                                .entry(server_id)
 7041                                .or_insert_with(Vec::new)
 7042                                .extend(cached_hints);
 7043                        }
 7044                    }
 7045                }
 7046                (Some(cached_hints), Some(fetched_hints)) => {
 7047                    hint_fetch_tasks.push((row_chunk, fetched_hints));
 7048                    for (server_id, cached_hints) in cached_hints {
 7049                        if for_server.is_none_or(|for_server| for_server == server_id) {
 7050                            cached_inlay_hints
 7051                                .get_or_insert_with(HashMap::default)
 7052                                .entry(row_chunk.row_range())
 7053                                .or_insert_with(HashMap::default)
 7054                                .entry(server_id)
 7055                                .or_insert_with(Vec::new)
 7056                                .extend(cached_hints);
 7057                        }
 7058                    }
 7059                }
 7060            }
 7061        }
 7062
 7063        if hint_fetch_tasks.is_empty()
 7064            && ranges_to_query
 7065                .as_ref()
 7066                .is_none_or(|ranges| ranges.is_empty())
 7067            && let Some(cached_inlay_hints) = cached_inlay_hints
 7068        {
 7069            cached_inlay_hints
 7070                .into_iter()
 7071                .map(|(row_chunk, hints)| (row_chunk, Task::ready(Ok(hints))))
 7072                .collect()
 7073        } else {
 7074            for (chunk, range_to_query) in ranges_to_query.into_iter().flatten() {
 7075                let next_hint_id = next_hint_id.clone();
 7076                let buffer = buffer.clone();
 7077                let query_version = query_version.clone();
 7078                let new_inlay_hints = cx
 7079                    .spawn(async move |lsp_store, cx| {
 7080                        let new_fetch_task = lsp_store.update(cx, |lsp_store, cx| {
 7081                            lsp_store.fetch_inlay_hints(for_server, &buffer, range_to_query, cx)
 7082                        })?;
 7083                        new_fetch_task
 7084                            .await
 7085                            .and_then(|new_hints_by_server| {
 7086                                lsp_store.update(cx, |lsp_store, cx| {
 7087                                    let lsp_data = lsp_store.latest_lsp_data(&buffer, cx);
 7088                                    let update_cache = lsp_data.buffer_version == query_version;
 7089                                    if new_hints_by_server.is_empty() {
 7090                                        if update_cache {
 7091                                            lsp_data.inlay_hints.invalidate_for_chunk(chunk);
 7092                                        }
 7093                                        HashMap::default()
 7094                                    } else {
 7095                                        new_hints_by_server
 7096                                            .into_iter()
 7097                                            .map(|(server_id, new_hints)| {
 7098                                                let new_hints = new_hints
 7099                                                    .into_iter()
 7100                                                    .map(|new_hint| {
 7101                                                        (
 7102                                                            InlayId::Hint(next_hint_id.fetch_add(
 7103                                                                1,
 7104                                                                atomic::Ordering::AcqRel,
 7105                                                            )),
 7106                                                            new_hint,
 7107                                                        )
 7108                                                    })
 7109                                                    .collect::<Vec<_>>();
 7110                                                if update_cache {
 7111                                                    lsp_data.inlay_hints.insert_new_hints(
 7112                                                        chunk,
 7113                                                        server_id,
 7114                                                        new_hints.clone(),
 7115                                                    );
 7116                                                }
 7117                                                (server_id, new_hints)
 7118                                            })
 7119                                            .collect()
 7120                                    }
 7121                                })
 7122                            })
 7123                            .map_err(Arc::new)
 7124                    })
 7125                    .shared();
 7126
 7127                let fetch_task = lsp_data.inlay_hints.fetched_hints(&chunk);
 7128                *fetch_task = Some(new_inlay_hints.clone());
 7129                hint_fetch_tasks.push((chunk, new_inlay_hints));
 7130            }
 7131
 7132            cached_inlay_hints
 7133                .unwrap_or_default()
 7134                .into_iter()
 7135                .map(|(row_chunk, hints)| (row_chunk, Task::ready(Ok(hints))))
 7136                .chain(hint_fetch_tasks.into_iter().map(|(chunk, hints_fetch)| {
 7137                    (
 7138                        chunk.row_range(),
 7139                        cx.spawn(async move |_, _| {
 7140                            hints_fetch.await.map_err(|e| {
 7141                                if e.error_code() != ErrorCode::Internal {
 7142                                    anyhow!(e.error_code())
 7143                                } else {
 7144                                    anyhow!("{e:#}")
 7145                                }
 7146                            })
 7147                        }),
 7148                    )
 7149                }))
 7150                .collect()
 7151        }
 7152    }
 7153
 7154    fn fetch_inlay_hints(
 7155        &mut self,
 7156        for_server: Option<LanguageServerId>,
 7157        buffer: &Entity<Buffer>,
 7158        range: Range<Anchor>,
 7159        cx: &mut Context<Self>,
 7160    ) -> Task<Result<HashMap<LanguageServerId, Vec<InlayHint>>>> {
 7161        let request = InlayHints {
 7162            range: range.clone(),
 7163        };
 7164        if let Some((upstream_client, project_id)) = self.upstream_client() {
 7165            if !self.is_capable_for_proto_request(buffer, &request, cx) {
 7166                return Task::ready(Ok(HashMap::default()));
 7167            }
 7168            let request_task = upstream_client.request_lsp(
 7169                project_id,
 7170                for_server.map(|id| id.to_proto()),
 7171                LSP_REQUEST_TIMEOUT,
 7172                cx.background_executor().clone(),
 7173                request.to_proto(project_id, buffer.read(cx)),
 7174            );
 7175            let buffer = buffer.clone();
 7176            cx.spawn(async move |weak_lsp_store, cx| {
 7177                let Some(lsp_store) = weak_lsp_store.upgrade() else {
 7178                    return Ok(HashMap::default());
 7179                };
 7180                let Some(responses) = request_task.await? else {
 7181                    return Ok(HashMap::default());
 7182                };
 7183
 7184                let inlay_hints = join_all(responses.payload.into_iter().map(|response| {
 7185                    let lsp_store = lsp_store.clone();
 7186                    let buffer = buffer.clone();
 7187                    let cx = cx.clone();
 7188                    let request = request.clone();
 7189                    async move {
 7190                        (
 7191                            LanguageServerId::from_proto(response.server_id),
 7192                            request
 7193                                .response_from_proto(response.response, lsp_store, buffer, cx)
 7194                                .await,
 7195                        )
 7196                    }
 7197                }))
 7198                .await;
 7199
 7200                let buffer_snapshot = buffer.read_with(cx, |buffer, _| buffer.snapshot())?;
 7201                let mut has_errors = false;
 7202                let inlay_hints = inlay_hints
 7203                    .into_iter()
 7204                    .filter_map(|(server_id, inlay_hints)| match inlay_hints {
 7205                        Ok(inlay_hints) => Some((server_id, inlay_hints)),
 7206                        Err(e) => {
 7207                            has_errors = true;
 7208                            log::error!("{e:#}");
 7209                            None
 7210                        }
 7211                    })
 7212                    .map(|(server_id, mut new_hints)| {
 7213                        new_hints.retain(|hint| {
 7214                            hint.position.is_valid(&buffer_snapshot)
 7215                                && range.start.is_valid(&buffer_snapshot)
 7216                                && range.end.is_valid(&buffer_snapshot)
 7217                                && hint.position.cmp(&range.start, &buffer_snapshot).is_ge()
 7218                                && hint.position.cmp(&range.end, &buffer_snapshot).is_lt()
 7219                        });
 7220                        (server_id, new_hints)
 7221                    })
 7222                    .collect::<HashMap<_, _>>();
 7223                anyhow::ensure!(
 7224                    !has_errors || !inlay_hints.is_empty(),
 7225                    "Failed to fetch inlay hints"
 7226                );
 7227                Ok(inlay_hints)
 7228            })
 7229        } else {
 7230            let inlay_hints_task = match for_server {
 7231                Some(server_id) => {
 7232                    let server_task = self.request_lsp(
 7233                        buffer.clone(),
 7234                        LanguageServerToQuery::Other(server_id),
 7235                        request,
 7236                        cx,
 7237                    );
 7238                    cx.background_spawn(async move {
 7239                        let mut responses = Vec::new();
 7240                        match server_task.await {
 7241                            Ok(response) => responses.push((server_id, response)),
 7242                            // rust-analyzer likes to error with this when its still loading up
 7243                            Err(e) if format!("{e:#}").ends_with("content modified") => (),
 7244                            Err(e) => log::error!(
 7245                                "Error handling response for inlay hints request: {e:#}"
 7246                            ),
 7247                        }
 7248                        responses
 7249                    })
 7250                }
 7251                None => self.request_multiple_lsp_locally(buffer, None::<usize>, request, cx),
 7252            };
 7253            let buffer_snapshot = buffer.read_with(cx, |buffer, _| buffer.snapshot());
 7254            cx.background_spawn(async move {
 7255                Ok(inlay_hints_task
 7256                    .await
 7257                    .into_iter()
 7258                    .map(|(server_id, mut new_hints)| {
 7259                        new_hints.retain(|hint| {
 7260                            hint.position.is_valid(&buffer_snapshot)
 7261                                && range.start.is_valid(&buffer_snapshot)
 7262                                && range.end.is_valid(&buffer_snapshot)
 7263                                && hint.position.cmp(&range.start, &buffer_snapshot).is_ge()
 7264                                && hint.position.cmp(&range.end, &buffer_snapshot).is_lt()
 7265                        });
 7266                        (server_id, new_hints)
 7267                    })
 7268                    .collect())
 7269            })
 7270        }
 7271    }
 7272
 7273    fn diagnostic_registration_exists(
 7274        &self,
 7275        server_id: LanguageServerId,
 7276        registration_id: &Option<SharedString>,
 7277    ) -> bool {
 7278        let Some(local) = self.as_local() else {
 7279            return false;
 7280        };
 7281        let Some(registrations) = local.language_server_dynamic_registrations.get(&server_id)
 7282        else {
 7283            return false;
 7284        };
 7285        let registration_key = registration_id.as_ref().map(|s| s.to_string());
 7286        registrations.diagnostics.contains_key(&registration_key)
 7287    }
 7288
 7289    pub fn pull_diagnostics_for_buffer(
 7290        &mut self,
 7291        buffer: Entity<Buffer>,
 7292        cx: &mut Context<Self>,
 7293    ) -> Task<anyhow::Result<()>> {
 7294        let diagnostics = self.pull_diagnostics(buffer, cx);
 7295        cx.spawn(async move |lsp_store, cx| {
 7296            let Some(diagnostics) = diagnostics.await.context("pulling diagnostics")? else {
 7297                return Ok(());
 7298            };
 7299            lsp_store.update(cx, |lsp_store, cx| {
 7300                if lsp_store.as_local().is_none() {
 7301                    return;
 7302                }
 7303
 7304                let mut unchanged_buffers = HashMap::default();
 7305                let server_diagnostics_updates = diagnostics
 7306                    .into_iter()
 7307                    .filter_map(|diagnostics_set| match diagnostics_set {
 7308                        LspPullDiagnostics::Response {
 7309                            server_id,
 7310                            uri,
 7311                            diagnostics,
 7312                            registration_id,
 7313                        } => Some((server_id, uri, diagnostics, registration_id)),
 7314                        LspPullDiagnostics::Default => None,
 7315                    })
 7316                    .filter(|(server_id, _, _, registration_id)| {
 7317                        lsp_store.diagnostic_registration_exists(*server_id, registration_id)
 7318                    })
 7319                    .fold(
 7320                        HashMap::default(),
 7321                        |mut acc, (server_id, uri, diagnostics, new_registration_id)| {
 7322                            let (result_id, diagnostics) = match diagnostics {
 7323                                PulledDiagnostics::Unchanged { result_id } => {
 7324                                    unchanged_buffers
 7325                                        .entry(new_registration_id.clone())
 7326                                        .or_insert_with(HashSet::default)
 7327                                        .insert(uri.clone());
 7328                                    (Some(result_id), Vec::new())
 7329                                }
 7330                                PulledDiagnostics::Changed {
 7331                                    result_id,
 7332                                    diagnostics,
 7333                                } => (result_id, diagnostics),
 7334                            };
 7335                            let disk_based_sources = Cow::Owned(
 7336                                lsp_store
 7337                                    .language_server_adapter_for_id(server_id)
 7338                                    .as_ref()
 7339                                    .map(|adapter| adapter.disk_based_diagnostic_sources.as_slice())
 7340                                    .unwrap_or(&[])
 7341                                    .to_vec(),
 7342                            );
 7343                            acc.entry(server_id)
 7344                                .or_insert_with(HashMap::default)
 7345                                .entry(new_registration_id.clone())
 7346                                .or_insert_with(Vec::new)
 7347                                .push(DocumentDiagnosticsUpdate {
 7348                                    server_id,
 7349                                    diagnostics: lsp::PublishDiagnosticsParams {
 7350                                        uri,
 7351                                        diagnostics,
 7352                                        version: None,
 7353                                    },
 7354                                    result_id,
 7355                                    disk_based_sources,
 7356                                    registration_id: new_registration_id,
 7357                                });
 7358                            acc
 7359                        },
 7360                    );
 7361
 7362                for diagnostic_updates in server_diagnostics_updates.into_values() {
 7363                    for (registration_id, diagnostic_updates) in diagnostic_updates {
 7364                        lsp_store
 7365                            .merge_lsp_diagnostics(
 7366                                DiagnosticSourceKind::Pulled,
 7367                                diagnostic_updates,
 7368                                |document_uri, old_diagnostic, _| match old_diagnostic.source_kind {
 7369                                    DiagnosticSourceKind::Pulled => {
 7370                                        old_diagnostic.registration_id != registration_id
 7371                                            || unchanged_buffers
 7372                                                .get(&old_diagnostic.registration_id)
 7373                                                .is_some_and(|unchanged_buffers| {
 7374                                                    unchanged_buffers.contains(&document_uri)
 7375                                                })
 7376                                    }
 7377                                    DiagnosticSourceKind::Other | DiagnosticSourceKind::Pushed => {
 7378                                        true
 7379                                    }
 7380                                },
 7381                                cx,
 7382                            )
 7383                            .log_err();
 7384                    }
 7385                }
 7386            })
 7387        })
 7388    }
 7389
 7390    pub fn document_colors(
 7391        &mut self,
 7392        known_cache_version: Option<usize>,
 7393        buffer: Entity<Buffer>,
 7394        cx: &mut Context<Self>,
 7395    ) -> Option<DocumentColorTask> {
 7396        let version_queried_for = buffer.read(cx).version();
 7397        let buffer_id = buffer.read(cx).remote_id();
 7398
 7399        let current_language_servers = self.as_local().map(|local| {
 7400            local
 7401                .buffers_opened_in_servers
 7402                .get(&buffer_id)
 7403                .cloned()
 7404                .unwrap_or_default()
 7405        });
 7406
 7407        if let Some(lsp_data) = self.current_lsp_data(buffer_id) {
 7408            if let Some(cached_colors) = &lsp_data.document_colors {
 7409                if !version_queried_for.changed_since(&lsp_data.buffer_version) {
 7410                    let has_different_servers =
 7411                        current_language_servers.is_some_and(|current_language_servers| {
 7412                            current_language_servers
 7413                                != cached_colors.colors.keys().copied().collect()
 7414                        });
 7415                    if !has_different_servers {
 7416                        let cache_version = cached_colors.cache_version;
 7417                        if Some(cache_version) == known_cache_version {
 7418                            return None;
 7419                        } else {
 7420                            return Some(
 7421                                Task::ready(Ok(DocumentColors {
 7422                                    colors: cached_colors
 7423                                        .colors
 7424                                        .values()
 7425                                        .flatten()
 7426                                        .cloned()
 7427                                        .collect(),
 7428                                    cache_version: Some(cache_version),
 7429                                }))
 7430                                .shared(),
 7431                            );
 7432                        }
 7433                    }
 7434                }
 7435            }
 7436        }
 7437
 7438        let color_lsp_data = self
 7439            .latest_lsp_data(&buffer, cx)
 7440            .document_colors
 7441            .get_or_insert_default();
 7442        if let Some((updating_for, running_update)) = &color_lsp_data.colors_update
 7443            && !version_queried_for.changed_since(updating_for)
 7444        {
 7445            return Some(running_update.clone());
 7446        }
 7447        let buffer_version_queried_for = version_queried_for.clone();
 7448        let new_task = cx
 7449            .spawn(async move |lsp_store, cx| {
 7450                cx.background_executor()
 7451                    .timer(Duration::from_millis(30))
 7452                    .await;
 7453                let fetched_colors = lsp_store
 7454                    .update(cx, |lsp_store, cx| {
 7455                        lsp_store.fetch_document_colors_for_buffer(&buffer, cx)
 7456                    })?
 7457                    .await
 7458                    .context("fetching document colors")
 7459                    .map_err(Arc::new);
 7460                let fetched_colors = match fetched_colors {
 7461                    Ok(fetched_colors) => {
 7462                        if Some(true)
 7463                            == buffer
 7464                                .update(cx, |buffer, _| {
 7465                                    buffer.version() != buffer_version_queried_for
 7466                                })
 7467                                .ok()
 7468                        {
 7469                            return Ok(DocumentColors::default());
 7470                        }
 7471                        fetched_colors
 7472                    }
 7473                    Err(e) => {
 7474                        lsp_store
 7475                            .update(cx, |lsp_store, _| {
 7476                                if let Some(lsp_data) = lsp_store.lsp_data.get_mut(&buffer_id) {
 7477                                    if let Some(document_colors) = &mut lsp_data.document_colors {
 7478                                        document_colors.colors_update = None;
 7479                                    }
 7480                                }
 7481                            })
 7482                            .ok();
 7483                        return Err(e);
 7484                    }
 7485                };
 7486
 7487                lsp_store
 7488                    .update(cx, |lsp_store, cx| {
 7489                        let lsp_data = lsp_store.latest_lsp_data(&buffer, cx);
 7490                        let lsp_colors = lsp_data.document_colors.get_or_insert_default();
 7491
 7492                        if let Some(fetched_colors) = fetched_colors {
 7493                            if lsp_data.buffer_version == buffer_version_queried_for {
 7494                                lsp_colors.colors.extend(fetched_colors);
 7495                                lsp_colors.cache_version += 1;
 7496                            } else if !lsp_data
 7497                                .buffer_version
 7498                                .changed_since(&buffer_version_queried_for)
 7499                            {
 7500                                lsp_data.buffer_version = buffer_version_queried_for;
 7501                                lsp_colors.colors = fetched_colors;
 7502                                lsp_colors.cache_version += 1;
 7503                            }
 7504                        }
 7505                        lsp_colors.colors_update = None;
 7506                        let colors = lsp_colors
 7507                            .colors
 7508                            .values()
 7509                            .flatten()
 7510                            .cloned()
 7511                            .collect::<HashSet<_>>();
 7512                        DocumentColors {
 7513                            colors,
 7514                            cache_version: Some(lsp_colors.cache_version),
 7515                        }
 7516                    })
 7517                    .map_err(Arc::new)
 7518            })
 7519            .shared();
 7520        color_lsp_data.colors_update = Some((version_queried_for, new_task.clone()));
 7521        Some(new_task)
 7522    }
 7523
 7524    fn fetch_document_colors_for_buffer(
 7525        &mut self,
 7526        buffer: &Entity<Buffer>,
 7527        cx: &mut Context<Self>,
 7528    ) -> Task<anyhow::Result<Option<HashMap<LanguageServerId, HashSet<DocumentColor>>>>> {
 7529        if let Some((client, project_id)) = self.upstream_client() {
 7530            let request = GetDocumentColor {};
 7531            if !self.is_capable_for_proto_request(buffer, &request, cx) {
 7532                return Task::ready(Ok(None));
 7533            }
 7534
 7535            let request_task = client.request_lsp(
 7536                project_id,
 7537                None,
 7538                LSP_REQUEST_TIMEOUT,
 7539                cx.background_executor().clone(),
 7540                request.to_proto(project_id, buffer.read(cx)),
 7541            );
 7542            let buffer = buffer.clone();
 7543            cx.spawn(async move |lsp_store, cx| {
 7544                let Some(lsp_store) = lsp_store.upgrade() else {
 7545                    return Ok(None);
 7546                };
 7547                let colors = join_all(
 7548                    request_task
 7549                        .await
 7550                        .log_err()
 7551                        .flatten()
 7552                        .map(|response| response.payload)
 7553                        .unwrap_or_default()
 7554                        .into_iter()
 7555                        .map(|color_response| {
 7556                            let response = request.response_from_proto(
 7557                                color_response.response,
 7558                                lsp_store.clone(),
 7559                                buffer.clone(),
 7560                                cx.clone(),
 7561                            );
 7562                            async move {
 7563                                (
 7564                                    LanguageServerId::from_proto(color_response.server_id),
 7565                                    response.await.log_err().unwrap_or_default(),
 7566                                )
 7567                            }
 7568                        }),
 7569                )
 7570                .await
 7571                .into_iter()
 7572                .fold(HashMap::default(), |mut acc, (server_id, colors)| {
 7573                    acc.entry(server_id)
 7574                        .or_insert_with(HashSet::default)
 7575                        .extend(colors);
 7576                    acc
 7577                });
 7578                Ok(Some(colors))
 7579            })
 7580        } else {
 7581            let document_colors_task =
 7582                self.request_multiple_lsp_locally(buffer, None::<usize>, GetDocumentColor, cx);
 7583            cx.background_spawn(async move {
 7584                Ok(Some(
 7585                    document_colors_task
 7586                        .await
 7587                        .into_iter()
 7588                        .fold(HashMap::default(), |mut acc, (server_id, colors)| {
 7589                            acc.entry(server_id)
 7590                                .or_insert_with(HashSet::default)
 7591                                .extend(colors);
 7592                            acc
 7593                        })
 7594                        .into_iter()
 7595                        .collect(),
 7596                ))
 7597            })
 7598        }
 7599    }
 7600
 7601    pub fn signature_help<T: ToPointUtf16>(
 7602        &mut self,
 7603        buffer: &Entity<Buffer>,
 7604        position: T,
 7605        cx: &mut Context<Self>,
 7606    ) -> Task<Option<Vec<SignatureHelp>>> {
 7607        let position = position.to_point_utf16(buffer.read(cx));
 7608
 7609        if let Some((client, upstream_project_id)) = self.upstream_client() {
 7610            let request = GetSignatureHelp { position };
 7611            if !self.is_capable_for_proto_request(buffer, &request, cx) {
 7612                return Task::ready(None);
 7613            }
 7614            let request_task = client.request_lsp(
 7615                upstream_project_id,
 7616                None,
 7617                LSP_REQUEST_TIMEOUT,
 7618                cx.background_executor().clone(),
 7619                request.to_proto(upstream_project_id, buffer.read(cx)),
 7620            );
 7621            let buffer = buffer.clone();
 7622            cx.spawn(async move |weak_lsp_store, cx| {
 7623                let lsp_store = weak_lsp_store.upgrade()?;
 7624                let signatures = join_all(
 7625                    request_task
 7626                        .await
 7627                        .log_err()
 7628                        .flatten()
 7629                        .map(|response| response.payload)
 7630                        .unwrap_or_default()
 7631                        .into_iter()
 7632                        .map(|response| {
 7633                            let response = GetSignatureHelp { position }.response_from_proto(
 7634                                response.response,
 7635                                lsp_store.clone(),
 7636                                buffer.clone(),
 7637                                cx.clone(),
 7638                            );
 7639                            async move { response.await.log_err().flatten() }
 7640                        }),
 7641                )
 7642                .await
 7643                .into_iter()
 7644                .flatten()
 7645                .collect();
 7646                Some(signatures)
 7647            })
 7648        } else {
 7649            let all_actions_task = self.request_multiple_lsp_locally(
 7650                buffer,
 7651                Some(position),
 7652                GetSignatureHelp { position },
 7653                cx,
 7654            );
 7655            cx.background_spawn(async move {
 7656                Some(
 7657                    all_actions_task
 7658                        .await
 7659                        .into_iter()
 7660                        .flat_map(|(_, actions)| actions)
 7661                        .collect::<Vec<_>>(),
 7662                )
 7663            })
 7664        }
 7665    }
 7666
 7667    pub fn hover(
 7668        &mut self,
 7669        buffer: &Entity<Buffer>,
 7670        position: PointUtf16,
 7671        cx: &mut Context<Self>,
 7672    ) -> Task<Option<Vec<Hover>>> {
 7673        if let Some((client, upstream_project_id)) = self.upstream_client() {
 7674            let request = GetHover { position };
 7675            if !self.is_capable_for_proto_request(buffer, &request, cx) {
 7676                return Task::ready(None);
 7677            }
 7678            let request_task = client.request_lsp(
 7679                upstream_project_id,
 7680                None,
 7681                LSP_REQUEST_TIMEOUT,
 7682                cx.background_executor().clone(),
 7683                request.to_proto(upstream_project_id, buffer.read(cx)),
 7684            );
 7685            let buffer = buffer.clone();
 7686            cx.spawn(async move |weak_lsp_store, cx| {
 7687                let lsp_store = weak_lsp_store.upgrade()?;
 7688                let hovers = join_all(
 7689                    request_task
 7690                        .await
 7691                        .log_err()
 7692                        .flatten()
 7693                        .map(|response| response.payload)
 7694                        .unwrap_or_default()
 7695                        .into_iter()
 7696                        .map(|response| {
 7697                            let response = GetHover { position }.response_from_proto(
 7698                                response.response,
 7699                                lsp_store.clone(),
 7700                                buffer.clone(),
 7701                                cx.clone(),
 7702                            );
 7703                            async move {
 7704                                response
 7705                                    .await
 7706                                    .log_err()
 7707                                    .flatten()
 7708                                    .and_then(remove_empty_hover_blocks)
 7709                            }
 7710                        }),
 7711                )
 7712                .await
 7713                .into_iter()
 7714                .flatten()
 7715                .collect();
 7716                Some(hovers)
 7717            })
 7718        } else {
 7719            let all_actions_task = self.request_multiple_lsp_locally(
 7720                buffer,
 7721                Some(position),
 7722                GetHover { position },
 7723                cx,
 7724            );
 7725            cx.background_spawn(async move {
 7726                Some(
 7727                    all_actions_task
 7728                        .await
 7729                        .into_iter()
 7730                        .filter_map(|(_, hover)| remove_empty_hover_blocks(hover?))
 7731                        .collect::<Vec<Hover>>(),
 7732                )
 7733            })
 7734        }
 7735    }
 7736
 7737    pub fn symbols(&self, query: &str, cx: &mut Context<Self>) -> Task<Result<Vec<Symbol>>> {
 7738        let language_registry = self.languages.clone();
 7739
 7740        if let Some((upstream_client, project_id)) = self.upstream_client().as_ref() {
 7741            let request = upstream_client.request(proto::GetProjectSymbols {
 7742                project_id: *project_id,
 7743                query: query.to_string(),
 7744            });
 7745            cx.foreground_executor().spawn(async move {
 7746                let response = request.await?;
 7747                let mut symbols = Vec::new();
 7748                let core_symbols = response
 7749                    .symbols
 7750                    .into_iter()
 7751                    .filter_map(|symbol| Self::deserialize_symbol(symbol).log_err())
 7752                    .collect::<Vec<_>>();
 7753                populate_labels_for_symbols(core_symbols, &language_registry, None, &mut symbols)
 7754                    .await;
 7755                Ok(symbols)
 7756            })
 7757        } else if let Some(local) = self.as_local() {
 7758            struct WorkspaceSymbolsResult {
 7759                server_id: LanguageServerId,
 7760                lsp_adapter: Arc<CachedLspAdapter>,
 7761                worktree: WeakEntity<Worktree>,
 7762                lsp_symbols: Vec<(String, SymbolKind, lsp::Location)>,
 7763            }
 7764
 7765            let mut requests = Vec::new();
 7766            let mut requested_servers = BTreeSet::new();
 7767            for (seed, state) in local.language_server_ids.iter() {
 7768                let Some(worktree_handle) = self
 7769                    .worktree_store
 7770                    .read(cx)
 7771                    .worktree_for_id(seed.worktree_id, cx)
 7772                else {
 7773                    continue;
 7774                };
 7775                let worktree = worktree_handle.read(cx);
 7776                if !worktree.is_visible() {
 7777                    continue;
 7778                }
 7779
 7780                if !requested_servers.insert(state.id) {
 7781                    continue;
 7782                }
 7783
 7784                let (lsp_adapter, server) = match local.language_servers.get(&state.id) {
 7785                    Some(LanguageServerState::Running {
 7786                        adapter, server, ..
 7787                    }) => (adapter.clone(), server),
 7788
 7789                    _ => continue,
 7790                };
 7791                let supports_workspace_symbol_request =
 7792                    match server.capabilities().workspace_symbol_provider {
 7793                        Some(OneOf::Left(supported)) => supported,
 7794                        Some(OneOf::Right(_)) => true,
 7795                        None => false,
 7796                    };
 7797                if !supports_workspace_symbol_request {
 7798                    continue;
 7799                }
 7800                let worktree_handle = worktree_handle.clone();
 7801                let server_id = server.server_id();
 7802                requests.push(
 7803                        server
 7804                            .request::<lsp::request::WorkspaceSymbolRequest>(
 7805                                lsp::WorkspaceSymbolParams {
 7806                                    query: query.to_string(),
 7807                                    ..Default::default()
 7808                                },
 7809                            )
 7810                            .map(move |response| {
 7811                                let lsp_symbols = response.into_response()
 7812                                    .context("workspace symbols request")
 7813                                    .log_err()
 7814                                    .flatten()
 7815                                    .map(|symbol_response| match symbol_response {
 7816                                        lsp::WorkspaceSymbolResponse::Flat(flat_responses) => {
 7817                                            flat_responses.into_iter().map(|lsp_symbol| {
 7818                                            (lsp_symbol.name, lsp_symbol.kind, lsp_symbol.location)
 7819                                            }).collect::<Vec<_>>()
 7820                                        }
 7821                                        lsp::WorkspaceSymbolResponse::Nested(nested_responses) => {
 7822                                            nested_responses.into_iter().filter_map(|lsp_symbol| {
 7823                                                let location = match lsp_symbol.location {
 7824                                                    OneOf::Left(location) => location,
 7825                                                    OneOf::Right(_) => {
 7826                                                        log::error!("Unexpected: client capabilities forbid symbol resolutions in workspace.symbol.resolveSupport");
 7827                                                        return None
 7828                                                    }
 7829                                                };
 7830                                                Some((lsp_symbol.name, lsp_symbol.kind, location))
 7831                                            }).collect::<Vec<_>>()
 7832                                        }
 7833                                    }).unwrap_or_default();
 7834
 7835                                WorkspaceSymbolsResult {
 7836                                    server_id,
 7837                                    lsp_adapter,
 7838                                    worktree: worktree_handle.downgrade(),
 7839                                    lsp_symbols,
 7840                                }
 7841                            }),
 7842                    );
 7843            }
 7844
 7845            cx.spawn(async move |this, cx| {
 7846                let responses = futures::future::join_all(requests).await;
 7847                let this = match this.upgrade() {
 7848                    Some(this) => this,
 7849                    None => return Ok(Vec::new()),
 7850                };
 7851
 7852                let mut symbols = Vec::new();
 7853                for result in responses {
 7854                    let core_symbols = this.update(cx, |this, cx| {
 7855                        result
 7856                            .lsp_symbols
 7857                            .into_iter()
 7858                            .filter_map(|(symbol_name, symbol_kind, symbol_location)| {
 7859                                let abs_path = symbol_location.uri.to_file_path().ok()?;
 7860                                let source_worktree = result.worktree.upgrade()?;
 7861                                let source_worktree_id = source_worktree.read(cx).id();
 7862
 7863                                let path = if let Some((tree, rel_path)) =
 7864                                    this.worktree_store.read(cx).find_worktree(&abs_path, cx)
 7865                                {
 7866                                    let worktree_id = tree.read(cx).id();
 7867                                    SymbolLocation::InProject(ProjectPath {
 7868                                        worktree_id,
 7869                                        path: rel_path,
 7870                                    })
 7871                                } else {
 7872                                    SymbolLocation::OutsideProject {
 7873                                        signature: this.symbol_signature(&abs_path),
 7874                                        abs_path: abs_path.into(),
 7875                                    }
 7876                                };
 7877
 7878                                Some(CoreSymbol {
 7879                                    source_language_server_id: result.server_id,
 7880                                    language_server_name: result.lsp_adapter.name.clone(),
 7881                                    source_worktree_id,
 7882                                    path,
 7883                                    kind: symbol_kind,
 7884                                    name: symbol_name,
 7885                                    range: range_from_lsp(symbol_location.range),
 7886                                })
 7887                            })
 7888                            .collect()
 7889                    })?;
 7890
 7891                    populate_labels_for_symbols(
 7892                        core_symbols,
 7893                        &language_registry,
 7894                        Some(result.lsp_adapter),
 7895                        &mut symbols,
 7896                    )
 7897                    .await;
 7898                }
 7899
 7900                Ok(symbols)
 7901            })
 7902        } else {
 7903            Task::ready(Err(anyhow!("No upstream client or local language server")))
 7904        }
 7905    }
 7906
 7907    pub fn diagnostic_summary(&self, include_ignored: bool, cx: &App) -> DiagnosticSummary {
 7908        let mut summary = DiagnosticSummary::default();
 7909        for (_, _, path_summary) in self.diagnostic_summaries(include_ignored, cx) {
 7910            summary.error_count += path_summary.error_count;
 7911            summary.warning_count += path_summary.warning_count;
 7912        }
 7913        summary
 7914    }
 7915
 7916    /// Returns the diagnostic summary for a specific project path.
 7917    pub fn diagnostic_summary_for_path(
 7918        &self,
 7919        project_path: &ProjectPath,
 7920        _: &App,
 7921    ) -> DiagnosticSummary {
 7922        if let Some(summaries) = self
 7923            .diagnostic_summaries
 7924            .get(&project_path.worktree_id)
 7925            .and_then(|map| map.get(&project_path.path))
 7926        {
 7927            let (error_count, warning_count) = summaries.iter().fold(
 7928                (0, 0),
 7929                |(error_count, warning_count), (_language_server_id, summary)| {
 7930                    (
 7931                        error_count + summary.error_count,
 7932                        warning_count + summary.warning_count,
 7933                    )
 7934                },
 7935            );
 7936
 7937            DiagnosticSummary {
 7938                error_count,
 7939                warning_count,
 7940            }
 7941        } else {
 7942            DiagnosticSummary::default()
 7943        }
 7944    }
 7945
 7946    pub fn diagnostic_summaries<'a>(
 7947        &'a self,
 7948        include_ignored: bool,
 7949        cx: &'a App,
 7950    ) -> impl Iterator<Item = (ProjectPath, LanguageServerId, DiagnosticSummary)> + 'a {
 7951        self.worktree_store
 7952            .read(cx)
 7953            .visible_worktrees(cx)
 7954            .filter_map(|worktree| {
 7955                let worktree = worktree.read(cx);
 7956                Some((worktree, self.diagnostic_summaries.get(&worktree.id())?))
 7957            })
 7958            .flat_map(move |(worktree, summaries)| {
 7959                let worktree_id = worktree.id();
 7960                summaries
 7961                    .iter()
 7962                    .filter(move |(path, _)| {
 7963                        include_ignored
 7964                            || worktree
 7965                                .entry_for_path(path.as_ref())
 7966                                .is_some_and(|entry| !entry.is_ignored)
 7967                    })
 7968                    .flat_map(move |(path, summaries)| {
 7969                        summaries.iter().map(move |(server_id, summary)| {
 7970                            (
 7971                                ProjectPath {
 7972                                    worktree_id,
 7973                                    path: path.clone(),
 7974                                },
 7975                                *server_id,
 7976                                *summary,
 7977                            )
 7978                        })
 7979                    })
 7980            })
 7981    }
 7982
 7983    pub fn on_buffer_edited(
 7984        &mut self,
 7985        buffer: Entity<Buffer>,
 7986        cx: &mut Context<Self>,
 7987    ) -> Option<()> {
 7988        let language_servers: Vec<_> = buffer.update(cx, |buffer, cx| {
 7989            Some(
 7990                self.as_local()?
 7991                    .language_servers_for_buffer(buffer, cx)
 7992                    .map(|i| i.1.clone())
 7993                    .collect(),
 7994            )
 7995        })?;
 7996
 7997        let buffer = buffer.read(cx);
 7998        let file = File::from_dyn(buffer.file())?;
 7999        let abs_path = file.as_local()?.abs_path(cx);
 8000        let uri = lsp::Uri::from_file_path(&abs_path)
 8001            .ok()
 8002            .with_context(|| format!("Failed to convert path to URI: {}", abs_path.display()))
 8003            .log_err()?;
 8004        let next_snapshot = buffer.text_snapshot();
 8005        for language_server in language_servers {
 8006            let language_server = language_server.clone();
 8007
 8008            let buffer_snapshots = self
 8009                .as_local_mut()?
 8010                .buffer_snapshots
 8011                .get_mut(&buffer.remote_id())
 8012                .and_then(|m| m.get_mut(&language_server.server_id()))?;
 8013            let previous_snapshot = buffer_snapshots.last()?;
 8014
 8015            let build_incremental_change = || {
 8016                buffer
 8017                    .edits_since::<Dimensions<PointUtf16, usize>>(
 8018                        previous_snapshot.snapshot.version(),
 8019                    )
 8020                    .map(|edit| {
 8021                        let edit_start = edit.new.start.0;
 8022                        let edit_end = edit_start + (edit.old.end.0 - edit.old.start.0);
 8023                        let new_text = next_snapshot
 8024                            .text_for_range(edit.new.start.1..edit.new.end.1)
 8025                            .collect();
 8026                        lsp::TextDocumentContentChangeEvent {
 8027                            range: Some(lsp::Range::new(
 8028                                point_to_lsp(edit_start),
 8029                                point_to_lsp(edit_end),
 8030                            )),
 8031                            range_length: None,
 8032                            text: new_text,
 8033                        }
 8034                    })
 8035                    .collect()
 8036            };
 8037
 8038            let document_sync_kind = language_server
 8039                .capabilities()
 8040                .text_document_sync
 8041                .as_ref()
 8042                .and_then(|sync| match sync {
 8043                    lsp::TextDocumentSyncCapability::Kind(kind) => Some(*kind),
 8044                    lsp::TextDocumentSyncCapability::Options(options) => options.change,
 8045                });
 8046
 8047            let content_changes: Vec<_> = match document_sync_kind {
 8048                Some(lsp::TextDocumentSyncKind::FULL) => {
 8049                    vec![lsp::TextDocumentContentChangeEvent {
 8050                        range: None,
 8051                        range_length: None,
 8052                        text: next_snapshot.text(),
 8053                    }]
 8054                }
 8055                Some(lsp::TextDocumentSyncKind::INCREMENTAL) => build_incremental_change(),
 8056                _ => {
 8057                    #[cfg(any(test, feature = "test-support"))]
 8058                    {
 8059                        build_incremental_change()
 8060                    }
 8061
 8062                    #[cfg(not(any(test, feature = "test-support")))]
 8063                    {
 8064                        continue;
 8065                    }
 8066                }
 8067            };
 8068
 8069            let next_version = previous_snapshot.version + 1;
 8070            buffer_snapshots.push(LspBufferSnapshot {
 8071                version: next_version,
 8072                snapshot: next_snapshot.clone(),
 8073            });
 8074
 8075            language_server
 8076                .notify::<lsp::notification::DidChangeTextDocument>(
 8077                    lsp::DidChangeTextDocumentParams {
 8078                        text_document: lsp::VersionedTextDocumentIdentifier::new(
 8079                            uri.clone(),
 8080                            next_version,
 8081                        ),
 8082                        content_changes,
 8083                    },
 8084                )
 8085                .ok();
 8086            self.pull_workspace_diagnostics(language_server.server_id());
 8087        }
 8088
 8089        None
 8090    }
 8091
 8092    pub fn on_buffer_saved(
 8093        &mut self,
 8094        buffer: Entity<Buffer>,
 8095        cx: &mut Context<Self>,
 8096    ) -> Option<()> {
 8097        let file = File::from_dyn(buffer.read(cx).file())?;
 8098        let worktree_id = file.worktree_id(cx);
 8099        let abs_path = file.as_local()?.abs_path(cx);
 8100        let text_document = lsp::TextDocumentIdentifier {
 8101            uri: file_path_to_lsp_url(&abs_path).log_err()?,
 8102        };
 8103        let local = self.as_local()?;
 8104
 8105        for server in local.language_servers_for_worktree(worktree_id) {
 8106            if let Some(include_text) = include_text(server.as_ref()) {
 8107                let text = if include_text {
 8108                    Some(buffer.read(cx).text())
 8109                } else {
 8110                    None
 8111                };
 8112                server
 8113                    .notify::<lsp::notification::DidSaveTextDocument>(
 8114                        lsp::DidSaveTextDocumentParams {
 8115                            text_document: text_document.clone(),
 8116                            text,
 8117                        },
 8118                    )
 8119                    .ok();
 8120            }
 8121        }
 8122
 8123        let language_servers = buffer.update(cx, |buffer, cx| {
 8124            local.language_server_ids_for_buffer(buffer, cx)
 8125        });
 8126        for language_server_id in language_servers {
 8127            self.simulate_disk_based_diagnostics_events_if_needed(language_server_id, cx);
 8128        }
 8129
 8130        None
 8131    }
 8132
 8133    async fn refresh_workspace_configurations(lsp_store: &WeakEntity<Self>, cx: &mut AsyncApp) {
 8134        maybe!(async move {
 8135            let mut refreshed_servers = HashSet::default();
 8136            let servers = lsp_store
 8137                .update(cx, |lsp_store, cx| {
 8138                    let local = lsp_store.as_local()?;
 8139
 8140                    let servers = local
 8141                        .language_server_ids
 8142                        .iter()
 8143                        .filter_map(|(seed, state)| {
 8144                            let worktree = lsp_store
 8145                                .worktree_store
 8146                                .read(cx)
 8147                                .worktree_for_id(seed.worktree_id, cx);
 8148                            let delegate: Arc<dyn LspAdapterDelegate> =
 8149                                worktree.map(|worktree| {
 8150                                    LocalLspAdapterDelegate::new(
 8151                                        local.languages.clone(),
 8152                                        &local.environment,
 8153                                        cx.weak_entity(),
 8154                                        &worktree,
 8155                                        local.http_client.clone(),
 8156                                        local.fs.clone(),
 8157                                        cx,
 8158                                    )
 8159                                })?;
 8160                            let server_id = state.id;
 8161
 8162                            let states = local.language_servers.get(&server_id)?;
 8163
 8164                            match states {
 8165                                LanguageServerState::Starting { .. } => None,
 8166                                LanguageServerState::Running {
 8167                                    adapter, server, ..
 8168                                } => {
 8169                                    let adapter = adapter.clone();
 8170                                    let server = server.clone();
 8171                                    refreshed_servers.insert(server.name());
 8172                                    let toolchain = seed.toolchain.clone();
 8173                                    Some(cx.spawn(async move |_, cx| {
 8174                                        let settings =
 8175                                            LocalLspStore::workspace_configuration_for_adapter(
 8176                                                adapter.adapter.clone(),
 8177                                                &delegate,
 8178                                                toolchain,
 8179                                                None,
 8180                                                cx,
 8181                                            )
 8182                                            .await
 8183                                            .ok()?;
 8184                                        server
 8185                                            .notify::<lsp::notification::DidChangeConfiguration>(
 8186                                                lsp::DidChangeConfigurationParams { settings },
 8187                                            )
 8188                                            .ok()?;
 8189                                        Some(())
 8190                                    }))
 8191                                }
 8192                            }
 8193                        })
 8194                        .collect::<Vec<_>>();
 8195
 8196                    Some(servers)
 8197                })
 8198                .ok()
 8199                .flatten()?;
 8200
 8201            log::debug!("Refreshing workspace configurations for servers {refreshed_servers:?}");
 8202            // TODO this asynchronous job runs concurrently with extension (de)registration and may take enough time for a certain extension
 8203            // to stop and unregister its language server wrapper.
 8204            // This is racy : an extension might have already removed all `local.language_servers` state, but here we `.clone()` and hold onto it anyway.
 8205            // This now causes errors in the logs, we should find a way to remove such servers from the processing everywhere.
 8206            let _: Vec<Option<()>> = join_all(servers).await;
 8207
 8208            Some(())
 8209        })
 8210        .await;
 8211    }
 8212
 8213    fn maintain_workspace_config(
 8214        external_refresh_requests: watch::Receiver<()>,
 8215        cx: &mut Context<Self>,
 8216    ) -> Task<Result<()>> {
 8217        let (mut settings_changed_tx, mut settings_changed_rx) = watch::channel();
 8218        let _ = postage::stream::Stream::try_recv(&mut settings_changed_rx);
 8219
 8220        let settings_observation = cx.observe_global::<SettingsStore>(move |_, _| {
 8221            *settings_changed_tx.borrow_mut() = ();
 8222        });
 8223
 8224        let mut joint_future =
 8225            futures::stream::select(settings_changed_rx, external_refresh_requests);
 8226        // Multiple things can happen when a workspace environment (selected toolchain + settings) change:
 8227        // - 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).
 8228        // - 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.
 8229        // - In the same vein, we might also decide to start a new language server if the workspace configuration *diverges* from the other.
 8230        // - 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,
 8231        // but it is still different to what we had before, we're gonna send out a workspace configuration update.
 8232        cx.spawn(async move |this, cx| {
 8233            while let Some(()) = joint_future.next().await {
 8234                this.update(cx, |this, cx| {
 8235                    this.refresh_server_tree(cx);
 8236                })
 8237                .ok();
 8238
 8239                Self::refresh_workspace_configurations(&this, cx).await;
 8240            }
 8241
 8242            drop(settings_observation);
 8243            anyhow::Ok(())
 8244        })
 8245    }
 8246
 8247    pub fn running_language_servers_for_local_buffer<'a>(
 8248        &'a self,
 8249        buffer: &Buffer,
 8250        cx: &mut App,
 8251    ) -> impl Iterator<Item = (&'a Arc<CachedLspAdapter>, &'a Arc<LanguageServer>)> {
 8252        let local = self.as_local();
 8253        let language_server_ids = local
 8254            .map(|local| local.language_server_ids_for_buffer(buffer, cx))
 8255            .unwrap_or_default();
 8256
 8257        language_server_ids
 8258            .into_iter()
 8259            .filter_map(
 8260                move |server_id| match local?.language_servers.get(&server_id)? {
 8261                    LanguageServerState::Running {
 8262                        adapter, server, ..
 8263                    } => Some((adapter, server)),
 8264                    _ => None,
 8265                },
 8266            )
 8267    }
 8268
 8269    pub fn language_servers_for_local_buffer(
 8270        &self,
 8271        buffer: &Buffer,
 8272        cx: &mut App,
 8273    ) -> Vec<LanguageServerId> {
 8274        let local = self.as_local();
 8275        local
 8276            .map(|local| local.language_server_ids_for_buffer(buffer, cx))
 8277            .unwrap_or_default()
 8278    }
 8279
 8280    pub fn language_server_for_local_buffer<'a>(
 8281        &'a self,
 8282        buffer: &'a Buffer,
 8283        server_id: LanguageServerId,
 8284        cx: &'a mut App,
 8285    ) -> Option<(&'a Arc<CachedLspAdapter>, &'a Arc<LanguageServer>)> {
 8286        self.as_local()?
 8287            .language_servers_for_buffer(buffer, cx)
 8288            .find(|(_, s)| s.server_id() == server_id)
 8289    }
 8290
 8291    fn remove_worktree(&mut self, id_to_remove: WorktreeId, cx: &mut Context<Self>) {
 8292        self.diagnostic_summaries.remove(&id_to_remove);
 8293        if let Some(local) = self.as_local_mut() {
 8294            let to_remove = local.remove_worktree(id_to_remove, cx);
 8295            for server in to_remove {
 8296                self.language_server_statuses.remove(&server);
 8297            }
 8298        }
 8299    }
 8300
 8301    pub fn shared(
 8302        &mut self,
 8303        project_id: u64,
 8304        downstream_client: AnyProtoClient,
 8305        _: &mut Context<Self>,
 8306    ) {
 8307        self.downstream_client = Some((downstream_client.clone(), project_id));
 8308
 8309        for (server_id, status) in &self.language_server_statuses {
 8310            if let Some(server) = self.language_server_for_id(*server_id) {
 8311                downstream_client
 8312                    .send(proto::StartLanguageServer {
 8313                        project_id,
 8314                        server: Some(proto::LanguageServer {
 8315                            id: server_id.to_proto(),
 8316                            name: status.name.to_string(),
 8317                            worktree_id: status.worktree.map(|id| id.to_proto()),
 8318                        }),
 8319                        capabilities: serde_json::to_string(&server.capabilities())
 8320                            .expect("serializing server LSP capabilities"),
 8321                    })
 8322                    .log_err();
 8323            }
 8324        }
 8325    }
 8326
 8327    pub fn disconnected_from_host(&mut self) {
 8328        self.downstream_client.take();
 8329    }
 8330
 8331    pub fn disconnected_from_ssh_remote(&mut self) {
 8332        if let LspStoreMode::Remote(RemoteLspStore {
 8333            upstream_client, ..
 8334        }) = &mut self.mode
 8335        {
 8336            upstream_client.take();
 8337        }
 8338    }
 8339
 8340    pub(crate) fn set_language_server_statuses_from_proto(
 8341        &mut self,
 8342        project: WeakEntity<Project>,
 8343        language_servers: Vec<proto::LanguageServer>,
 8344        server_capabilities: Vec<String>,
 8345        cx: &mut Context<Self>,
 8346    ) {
 8347        let lsp_logs = cx
 8348            .try_global::<GlobalLogStore>()
 8349            .map(|lsp_store| lsp_store.0.clone());
 8350
 8351        self.language_server_statuses = language_servers
 8352            .into_iter()
 8353            .zip(server_capabilities)
 8354            .map(|(server, server_capabilities)| {
 8355                let server_id = LanguageServerId(server.id as usize);
 8356                if let Ok(server_capabilities) = serde_json::from_str(&server_capabilities) {
 8357                    self.lsp_server_capabilities
 8358                        .insert(server_id, server_capabilities);
 8359                }
 8360
 8361                let name = LanguageServerName::from_proto(server.name);
 8362                let worktree = server.worktree_id.map(WorktreeId::from_proto);
 8363
 8364                if let Some(lsp_logs) = &lsp_logs {
 8365                    lsp_logs.update(cx, |lsp_logs, cx| {
 8366                        lsp_logs.add_language_server(
 8367                            // Only remote clients get their language servers set from proto
 8368                            LanguageServerKind::Remote {
 8369                                project: project.clone(),
 8370                            },
 8371                            server_id,
 8372                            Some(name.clone()),
 8373                            worktree,
 8374                            None,
 8375                            cx,
 8376                        );
 8377                    });
 8378                }
 8379
 8380                (
 8381                    server_id,
 8382                    LanguageServerStatus {
 8383                        name,
 8384                        pending_work: Default::default(),
 8385                        has_pending_diagnostic_updates: false,
 8386                        progress_tokens: Default::default(),
 8387                        worktree,
 8388                        binary: None,
 8389                        configuration: None,
 8390                        workspace_folders: BTreeSet::new(),
 8391                    },
 8392                )
 8393            })
 8394            .collect();
 8395    }
 8396
 8397    #[cfg(test)]
 8398    pub fn update_diagnostic_entries(
 8399        &mut self,
 8400        server_id: LanguageServerId,
 8401        abs_path: PathBuf,
 8402        result_id: Option<SharedString>,
 8403        version: Option<i32>,
 8404        diagnostics: Vec<DiagnosticEntry<Unclipped<PointUtf16>>>,
 8405        cx: &mut Context<Self>,
 8406    ) -> anyhow::Result<()> {
 8407        self.merge_diagnostic_entries(
 8408            vec![DocumentDiagnosticsUpdate {
 8409                diagnostics: DocumentDiagnostics {
 8410                    diagnostics,
 8411                    document_abs_path: abs_path,
 8412                    version,
 8413                },
 8414                result_id,
 8415                server_id,
 8416                disk_based_sources: Cow::Borrowed(&[]),
 8417                registration_id: None,
 8418            }],
 8419            |_, _, _| false,
 8420            cx,
 8421        )?;
 8422        Ok(())
 8423    }
 8424
 8425    pub fn merge_diagnostic_entries<'a>(
 8426        &mut self,
 8427        diagnostic_updates: Vec<DocumentDiagnosticsUpdate<'a, DocumentDiagnostics>>,
 8428        merge: impl Fn(&lsp::Uri, &Diagnostic, &App) -> bool + Clone,
 8429        cx: &mut Context<Self>,
 8430    ) -> anyhow::Result<()> {
 8431        let mut diagnostics_summary = None::<proto::UpdateDiagnosticSummary>;
 8432        let mut updated_diagnostics_paths = HashMap::default();
 8433        for mut update in diagnostic_updates {
 8434            let abs_path = &update.diagnostics.document_abs_path;
 8435            let server_id = update.server_id;
 8436            let Some((worktree, relative_path)) =
 8437                self.worktree_store.read(cx).find_worktree(abs_path, cx)
 8438            else {
 8439                log::warn!("skipping diagnostics update, no worktree found for path {abs_path:?}");
 8440                return Ok(());
 8441            };
 8442
 8443            let worktree_id = worktree.read(cx).id();
 8444            let project_path = ProjectPath {
 8445                worktree_id,
 8446                path: relative_path,
 8447            };
 8448
 8449            let document_uri = lsp::Uri::from_file_path(abs_path)
 8450                .map_err(|()| anyhow!("Failed to convert buffer path {abs_path:?} to lsp Uri"))?;
 8451            if let Some(buffer_handle) = self.buffer_store.read(cx).get_by_path(&project_path) {
 8452                let snapshot = buffer_handle.read(cx).snapshot();
 8453                let buffer = buffer_handle.read(cx);
 8454                let reused_diagnostics = buffer
 8455                    .buffer_diagnostics(Some(server_id))
 8456                    .iter()
 8457                    .filter(|v| merge(&document_uri, &v.diagnostic, cx))
 8458                    .map(|v| {
 8459                        let start = Unclipped(v.range.start.to_point_utf16(&snapshot));
 8460                        let end = Unclipped(v.range.end.to_point_utf16(&snapshot));
 8461                        DiagnosticEntry {
 8462                            range: start..end,
 8463                            diagnostic: v.diagnostic.clone(),
 8464                        }
 8465                    })
 8466                    .collect::<Vec<_>>();
 8467
 8468                self.as_local_mut()
 8469                    .context("cannot merge diagnostics on a remote LspStore")?
 8470                    .update_buffer_diagnostics(
 8471                        &buffer_handle,
 8472                        server_id,
 8473                        Some(update.registration_id),
 8474                        update.result_id,
 8475                        update.diagnostics.version,
 8476                        update.diagnostics.diagnostics.clone(),
 8477                        reused_diagnostics.clone(),
 8478                        cx,
 8479                    )?;
 8480
 8481                update.diagnostics.diagnostics.extend(reused_diagnostics);
 8482            } else if let Some(local) = self.as_local() {
 8483                let reused_diagnostics = local
 8484                    .diagnostics
 8485                    .get(&worktree_id)
 8486                    .and_then(|diagnostics_for_tree| diagnostics_for_tree.get(&project_path.path))
 8487                    .and_then(|diagnostics_by_server_id| {
 8488                        diagnostics_by_server_id
 8489                            .binary_search_by_key(&server_id, |e| e.0)
 8490                            .ok()
 8491                            .map(|ix| &diagnostics_by_server_id[ix].1)
 8492                    })
 8493                    .into_iter()
 8494                    .flatten()
 8495                    .filter(|v| merge(&document_uri, &v.diagnostic, cx));
 8496
 8497                update
 8498                    .diagnostics
 8499                    .diagnostics
 8500                    .extend(reused_diagnostics.cloned());
 8501            }
 8502
 8503            let updated = worktree.update(cx, |worktree, cx| {
 8504                self.update_worktree_diagnostics(
 8505                    worktree.id(),
 8506                    server_id,
 8507                    project_path.path.clone(),
 8508                    update.diagnostics.diagnostics,
 8509                    cx,
 8510                )
 8511            })?;
 8512            match updated {
 8513                ControlFlow::Continue(new_summary) => {
 8514                    if let Some((project_id, new_summary)) = new_summary {
 8515                        match &mut diagnostics_summary {
 8516                            Some(diagnostics_summary) => {
 8517                                diagnostics_summary
 8518                                    .more_summaries
 8519                                    .push(proto::DiagnosticSummary {
 8520                                        path: project_path.path.as_ref().to_proto(),
 8521                                        language_server_id: server_id.0 as u64,
 8522                                        error_count: new_summary.error_count,
 8523                                        warning_count: new_summary.warning_count,
 8524                                    })
 8525                            }
 8526                            None => {
 8527                                diagnostics_summary = Some(proto::UpdateDiagnosticSummary {
 8528                                    project_id,
 8529                                    worktree_id: worktree_id.to_proto(),
 8530                                    summary: Some(proto::DiagnosticSummary {
 8531                                        path: project_path.path.as_ref().to_proto(),
 8532                                        language_server_id: server_id.0 as u64,
 8533                                        error_count: new_summary.error_count,
 8534                                        warning_count: new_summary.warning_count,
 8535                                    }),
 8536                                    more_summaries: Vec::new(),
 8537                                })
 8538                            }
 8539                        }
 8540                    }
 8541                    updated_diagnostics_paths
 8542                        .entry(server_id)
 8543                        .or_insert_with(Vec::new)
 8544                        .push(project_path);
 8545                }
 8546                ControlFlow::Break(()) => {}
 8547            }
 8548        }
 8549
 8550        if let Some((diagnostics_summary, (downstream_client, _))) =
 8551            diagnostics_summary.zip(self.downstream_client.as_ref())
 8552        {
 8553            downstream_client.send(diagnostics_summary).log_err();
 8554        }
 8555        for (server_id, paths) in updated_diagnostics_paths {
 8556            cx.emit(LspStoreEvent::DiagnosticsUpdated { server_id, paths });
 8557        }
 8558        Ok(())
 8559    }
 8560
 8561    fn update_worktree_diagnostics(
 8562        &mut self,
 8563        worktree_id: WorktreeId,
 8564        server_id: LanguageServerId,
 8565        path_in_worktree: Arc<RelPath>,
 8566        diagnostics: Vec<DiagnosticEntry<Unclipped<PointUtf16>>>,
 8567        _: &mut Context<Worktree>,
 8568    ) -> Result<ControlFlow<(), Option<(u64, proto::DiagnosticSummary)>>> {
 8569        let local = match &mut self.mode {
 8570            LspStoreMode::Local(local_lsp_store) => local_lsp_store,
 8571            _ => anyhow::bail!("update_worktree_diagnostics called on remote"),
 8572        };
 8573
 8574        let summaries_for_tree = self.diagnostic_summaries.entry(worktree_id).or_default();
 8575        let diagnostics_for_tree = local.diagnostics.entry(worktree_id).or_default();
 8576        let summaries_by_server_id = summaries_for_tree
 8577            .entry(path_in_worktree.clone())
 8578            .or_default();
 8579
 8580        let old_summary = summaries_by_server_id
 8581            .remove(&server_id)
 8582            .unwrap_or_default();
 8583
 8584        let new_summary = DiagnosticSummary::new(&diagnostics);
 8585        if diagnostics.is_empty() {
 8586            if let Some(diagnostics_by_server_id) = diagnostics_for_tree.get_mut(&path_in_worktree)
 8587            {
 8588                if let Ok(ix) = diagnostics_by_server_id.binary_search_by_key(&server_id, |e| e.0) {
 8589                    diagnostics_by_server_id.remove(ix);
 8590                }
 8591                if diagnostics_by_server_id.is_empty() {
 8592                    diagnostics_for_tree.remove(&path_in_worktree);
 8593                }
 8594            }
 8595        } else {
 8596            summaries_by_server_id.insert(server_id, new_summary);
 8597            let diagnostics_by_server_id = diagnostics_for_tree
 8598                .entry(path_in_worktree.clone())
 8599                .or_default();
 8600            match diagnostics_by_server_id.binary_search_by_key(&server_id, |e| e.0) {
 8601                Ok(ix) => {
 8602                    diagnostics_by_server_id[ix] = (server_id, diagnostics);
 8603                }
 8604                Err(ix) => {
 8605                    diagnostics_by_server_id.insert(ix, (server_id, diagnostics));
 8606                }
 8607            }
 8608        }
 8609
 8610        if !old_summary.is_empty() || !new_summary.is_empty() {
 8611            if let Some((_, project_id)) = &self.downstream_client {
 8612                Ok(ControlFlow::Continue(Some((
 8613                    *project_id,
 8614                    proto::DiagnosticSummary {
 8615                        path: path_in_worktree.to_proto(),
 8616                        language_server_id: server_id.0 as u64,
 8617                        error_count: new_summary.error_count as u32,
 8618                        warning_count: new_summary.warning_count as u32,
 8619                    },
 8620                ))))
 8621            } else {
 8622                Ok(ControlFlow::Continue(None))
 8623            }
 8624        } else {
 8625            Ok(ControlFlow::Break(()))
 8626        }
 8627    }
 8628
 8629    pub fn open_buffer_for_symbol(
 8630        &mut self,
 8631        symbol: &Symbol,
 8632        cx: &mut Context<Self>,
 8633    ) -> Task<Result<Entity<Buffer>>> {
 8634        if let Some((client, project_id)) = self.upstream_client() {
 8635            let request = client.request(proto::OpenBufferForSymbol {
 8636                project_id,
 8637                symbol: Some(Self::serialize_symbol(symbol)),
 8638            });
 8639            cx.spawn(async move |this, cx| {
 8640                let response = request.await?;
 8641                let buffer_id = BufferId::new(response.buffer_id)?;
 8642                this.update(cx, |this, cx| this.wait_for_remote_buffer(buffer_id, cx))?
 8643                    .await
 8644            })
 8645        } else if let Some(local) = self.as_local() {
 8646            let is_valid = local.language_server_ids.iter().any(|(seed, state)| {
 8647                seed.worktree_id == symbol.source_worktree_id
 8648                    && state.id == symbol.source_language_server_id
 8649                    && symbol.language_server_name == seed.name
 8650            });
 8651            if !is_valid {
 8652                return Task::ready(Err(anyhow!(
 8653                    "language server for worktree and language not found"
 8654                )));
 8655            };
 8656
 8657            let symbol_abs_path = match &symbol.path {
 8658                SymbolLocation::InProject(project_path) => self
 8659                    .worktree_store
 8660                    .read(cx)
 8661                    .absolutize(&project_path, cx)
 8662                    .context("no such worktree"),
 8663                SymbolLocation::OutsideProject {
 8664                    abs_path,
 8665                    signature: _,
 8666                } => Ok(abs_path.to_path_buf()),
 8667            };
 8668            let symbol_abs_path = match symbol_abs_path {
 8669                Ok(abs_path) => abs_path,
 8670                Err(err) => return Task::ready(Err(err)),
 8671            };
 8672            let symbol_uri = if let Ok(uri) = lsp::Uri::from_file_path(symbol_abs_path) {
 8673                uri
 8674            } else {
 8675                return Task::ready(Err(anyhow!("invalid symbol path")));
 8676            };
 8677
 8678            self.open_local_buffer_via_lsp(symbol_uri, symbol.source_language_server_id, cx)
 8679        } else {
 8680            Task::ready(Err(anyhow!("no upstream client or local store")))
 8681        }
 8682    }
 8683
 8684    pub(crate) fn open_local_buffer_via_lsp(
 8685        &mut self,
 8686        abs_path: lsp::Uri,
 8687        language_server_id: LanguageServerId,
 8688        cx: &mut Context<Self>,
 8689    ) -> Task<Result<Entity<Buffer>>> {
 8690        cx.spawn(async move |lsp_store, cx| {
 8691            // Escape percent-encoded string.
 8692            let current_scheme = abs_path.scheme().to_owned();
 8693            // Uri is immutable, so we can't modify the scheme
 8694
 8695            let abs_path = abs_path
 8696                .to_file_path()
 8697                .map_err(|()| anyhow!("can't convert URI to path"))?;
 8698            let p = abs_path.clone();
 8699            let yarn_worktree = lsp_store
 8700                .update(cx, move |lsp_store, cx| match lsp_store.as_local() {
 8701                    Some(local_lsp_store) => local_lsp_store.yarn.update(cx, |_, cx| {
 8702                        cx.spawn(async move |this, cx| {
 8703                            let t = this
 8704                                .update(cx, |this, cx| this.process_path(&p, &current_scheme, cx))
 8705                                .ok()?;
 8706                            t.await
 8707                        })
 8708                    }),
 8709                    None => Task::ready(None),
 8710                })?
 8711                .await;
 8712            let (worktree_root_target, known_relative_path) =
 8713                if let Some((zip_root, relative_path)) = yarn_worktree {
 8714                    (zip_root, Some(relative_path))
 8715                } else {
 8716                    (Arc::<Path>::from(abs_path.as_path()), None)
 8717                };
 8718            let (worktree, relative_path) = if let Some(result) =
 8719                lsp_store.update(cx, |lsp_store, cx| {
 8720                    lsp_store.worktree_store.update(cx, |worktree_store, cx| {
 8721                        worktree_store.find_worktree(&worktree_root_target, cx)
 8722                    })
 8723                })? {
 8724                let relative_path = known_relative_path.unwrap_or_else(|| result.1.clone());
 8725                (result.0, relative_path)
 8726            } else {
 8727                let worktree = lsp_store
 8728                    .update(cx, |lsp_store, cx| {
 8729                        lsp_store.worktree_store.update(cx, |worktree_store, cx| {
 8730                            worktree_store.create_worktree(&worktree_root_target, false, cx)
 8731                        })
 8732                    })?
 8733                    .await?;
 8734                if worktree.read_with(cx, |worktree, _| worktree.is_local())? {
 8735                    lsp_store
 8736                        .update(cx, |lsp_store, cx| {
 8737                            if let Some(local) = lsp_store.as_local_mut() {
 8738                                local.register_language_server_for_invisible_worktree(
 8739                                    &worktree,
 8740                                    language_server_id,
 8741                                    cx,
 8742                                )
 8743                            }
 8744                        })
 8745                        .ok();
 8746                }
 8747                let worktree_root = worktree.read_with(cx, |worktree, _| worktree.abs_path())?;
 8748                let relative_path = if let Some(known_path) = known_relative_path {
 8749                    known_path
 8750                } else {
 8751                    RelPath::new(abs_path.strip_prefix(worktree_root)?, PathStyle::local())?
 8752                        .into_arc()
 8753                };
 8754                (worktree, relative_path)
 8755            };
 8756            let project_path = ProjectPath {
 8757                worktree_id: worktree.read_with(cx, |worktree, _| worktree.id())?,
 8758                path: relative_path,
 8759            };
 8760            lsp_store
 8761                .update(cx, |lsp_store, cx| {
 8762                    lsp_store.buffer_store().update(cx, |buffer_store, cx| {
 8763                        buffer_store.open_buffer(project_path, cx)
 8764                    })
 8765                })?
 8766                .await
 8767        })
 8768    }
 8769
 8770    fn request_multiple_lsp_locally<P, R>(
 8771        &mut self,
 8772        buffer: &Entity<Buffer>,
 8773        position: Option<P>,
 8774        request: R,
 8775        cx: &mut Context<Self>,
 8776    ) -> Task<Vec<(LanguageServerId, R::Response)>>
 8777    where
 8778        P: ToOffset,
 8779        R: LspCommand + Clone,
 8780        <R::LspRequest as lsp::request::Request>::Result: Send,
 8781        <R::LspRequest as lsp::request::Request>::Params: Send,
 8782    {
 8783        let Some(local) = self.as_local() else {
 8784            return Task::ready(Vec::new());
 8785        };
 8786
 8787        let snapshot = buffer.read(cx).snapshot();
 8788        let scope = position.and_then(|position| snapshot.language_scope_at(position));
 8789
 8790        let server_ids = buffer.update(cx, |buffer, cx| {
 8791            local
 8792                .language_servers_for_buffer(buffer, cx)
 8793                .filter(|(adapter, _)| {
 8794                    scope
 8795                        .as_ref()
 8796                        .map(|scope| scope.language_allowed(&adapter.name))
 8797                        .unwrap_or(true)
 8798                })
 8799                .map(|(_, server)| server.server_id())
 8800                .filter(|server_id| {
 8801                    self.as_local().is_none_or(|local| {
 8802                        local
 8803                            .buffers_opened_in_servers
 8804                            .get(&snapshot.remote_id())
 8805                            .is_some_and(|servers| servers.contains(server_id))
 8806                    })
 8807                })
 8808                .collect::<Vec<_>>()
 8809        });
 8810
 8811        let mut response_results = server_ids
 8812            .into_iter()
 8813            .map(|server_id| {
 8814                let task = self.request_lsp(
 8815                    buffer.clone(),
 8816                    LanguageServerToQuery::Other(server_id),
 8817                    request.clone(),
 8818                    cx,
 8819                );
 8820                async move { (server_id, task.await) }
 8821            })
 8822            .collect::<FuturesUnordered<_>>();
 8823
 8824        cx.background_spawn(async move {
 8825            let mut responses = Vec::with_capacity(response_results.len());
 8826            while let Some((server_id, response_result)) = response_results.next().await {
 8827                match response_result {
 8828                    Ok(response) => responses.push((server_id, response)),
 8829                    // rust-analyzer likes to error with this when its still loading up
 8830                    Err(e) if format!("{e:#}").ends_with("content modified") => (),
 8831                    Err(e) => log::error!("Error handling response for request {request:?}: {e:#}"),
 8832                }
 8833            }
 8834            responses
 8835        })
 8836    }
 8837
 8838    async fn handle_lsp_get_completions(
 8839        this: Entity<Self>,
 8840        envelope: TypedEnvelope<proto::GetCompletions>,
 8841        mut cx: AsyncApp,
 8842    ) -> Result<proto::GetCompletionsResponse> {
 8843        let sender_id = envelope.original_sender_id().unwrap_or_default();
 8844
 8845        let buffer_id = GetCompletions::buffer_id_from_proto(&envelope.payload)?;
 8846        let buffer_handle = this.update(&mut cx, |this, cx| {
 8847            this.buffer_store.read(cx).get_existing(buffer_id)
 8848        })??;
 8849        let request = GetCompletions::from_proto(
 8850            envelope.payload,
 8851            this.clone(),
 8852            buffer_handle.clone(),
 8853            cx.clone(),
 8854        )
 8855        .await?;
 8856
 8857        let server_to_query = match request.server_id {
 8858            Some(server_id) => LanguageServerToQuery::Other(server_id),
 8859            None => LanguageServerToQuery::FirstCapable,
 8860        };
 8861
 8862        let response = this
 8863            .update(&mut cx, |this, cx| {
 8864                this.request_lsp(buffer_handle.clone(), server_to_query, request, cx)
 8865            })?
 8866            .await?;
 8867        this.update(&mut cx, |this, cx| {
 8868            Ok(GetCompletions::response_to_proto(
 8869                response,
 8870                this,
 8871                sender_id,
 8872                &buffer_handle.read(cx).version(),
 8873                cx,
 8874            ))
 8875        })?
 8876    }
 8877
 8878    async fn handle_lsp_command<T: LspCommand>(
 8879        this: Entity<Self>,
 8880        envelope: TypedEnvelope<T::ProtoRequest>,
 8881        mut cx: AsyncApp,
 8882    ) -> Result<<T::ProtoRequest as proto::RequestMessage>::Response>
 8883    where
 8884        <T::LspRequest as lsp::request::Request>::Params: Send,
 8885        <T::LspRequest as lsp::request::Request>::Result: Send,
 8886    {
 8887        let sender_id = envelope.original_sender_id().unwrap_or_default();
 8888        let buffer_id = T::buffer_id_from_proto(&envelope.payload)?;
 8889        let buffer_handle = this.update(&mut cx, |this, cx| {
 8890            this.buffer_store.read(cx).get_existing(buffer_id)
 8891        })??;
 8892        let request = T::from_proto(
 8893            envelope.payload,
 8894            this.clone(),
 8895            buffer_handle.clone(),
 8896            cx.clone(),
 8897        )
 8898        .await?;
 8899        let response = this
 8900            .update(&mut cx, |this, cx| {
 8901                this.request_lsp(
 8902                    buffer_handle.clone(),
 8903                    LanguageServerToQuery::FirstCapable,
 8904                    request,
 8905                    cx,
 8906                )
 8907            })?
 8908            .await?;
 8909        this.update(&mut cx, |this, cx| {
 8910            Ok(T::response_to_proto(
 8911                response,
 8912                this,
 8913                sender_id,
 8914                &buffer_handle.read(cx).version(),
 8915                cx,
 8916            ))
 8917        })?
 8918    }
 8919
 8920    async fn handle_lsp_query(
 8921        lsp_store: Entity<Self>,
 8922        envelope: TypedEnvelope<proto::LspQuery>,
 8923        mut cx: AsyncApp,
 8924    ) -> Result<proto::Ack> {
 8925        use proto::lsp_query::Request;
 8926        let sender_id = envelope.original_sender_id().unwrap_or_default();
 8927        let lsp_query = envelope.payload;
 8928        let lsp_request_id = LspRequestId(lsp_query.lsp_request_id);
 8929        let server_id = lsp_query.server_id.map(LanguageServerId::from_proto);
 8930        match lsp_query.request.context("invalid LSP query request")? {
 8931            Request::GetReferences(get_references) => {
 8932                let position = get_references.position.clone().and_then(deserialize_anchor);
 8933                Self::query_lsp_locally::<GetReferences>(
 8934                    lsp_store,
 8935                    server_id,
 8936                    sender_id,
 8937                    lsp_request_id,
 8938                    get_references,
 8939                    position,
 8940                    &mut cx,
 8941                )
 8942                .await?;
 8943            }
 8944            Request::GetDocumentColor(get_document_color) => {
 8945                Self::query_lsp_locally::<GetDocumentColor>(
 8946                    lsp_store,
 8947                    server_id,
 8948                    sender_id,
 8949                    lsp_request_id,
 8950                    get_document_color,
 8951                    None,
 8952                    &mut cx,
 8953                )
 8954                .await?;
 8955            }
 8956            Request::GetHover(get_hover) => {
 8957                let position = get_hover.position.clone().and_then(deserialize_anchor);
 8958                Self::query_lsp_locally::<GetHover>(
 8959                    lsp_store,
 8960                    server_id,
 8961                    sender_id,
 8962                    lsp_request_id,
 8963                    get_hover,
 8964                    position,
 8965                    &mut cx,
 8966                )
 8967                .await?;
 8968            }
 8969            Request::GetCodeActions(get_code_actions) => {
 8970                Self::query_lsp_locally::<GetCodeActions>(
 8971                    lsp_store,
 8972                    server_id,
 8973                    sender_id,
 8974                    lsp_request_id,
 8975                    get_code_actions,
 8976                    None,
 8977                    &mut cx,
 8978                )
 8979                .await?;
 8980            }
 8981            Request::GetSignatureHelp(get_signature_help) => {
 8982                let position = get_signature_help
 8983                    .position
 8984                    .clone()
 8985                    .and_then(deserialize_anchor);
 8986                Self::query_lsp_locally::<GetSignatureHelp>(
 8987                    lsp_store,
 8988                    server_id,
 8989                    sender_id,
 8990                    lsp_request_id,
 8991                    get_signature_help,
 8992                    position,
 8993                    &mut cx,
 8994                )
 8995                .await?;
 8996            }
 8997            Request::GetCodeLens(get_code_lens) => {
 8998                Self::query_lsp_locally::<GetCodeLens>(
 8999                    lsp_store,
 9000                    server_id,
 9001                    sender_id,
 9002                    lsp_request_id,
 9003                    get_code_lens,
 9004                    None,
 9005                    &mut cx,
 9006                )
 9007                .await?;
 9008            }
 9009            Request::GetDefinition(get_definition) => {
 9010                let position = get_definition.position.clone().and_then(deserialize_anchor);
 9011                Self::query_lsp_locally::<GetDefinitions>(
 9012                    lsp_store,
 9013                    server_id,
 9014                    sender_id,
 9015                    lsp_request_id,
 9016                    get_definition,
 9017                    position,
 9018                    &mut cx,
 9019                )
 9020                .await?;
 9021            }
 9022            Request::GetDeclaration(get_declaration) => {
 9023                let position = get_declaration
 9024                    .position
 9025                    .clone()
 9026                    .and_then(deserialize_anchor);
 9027                Self::query_lsp_locally::<GetDeclarations>(
 9028                    lsp_store,
 9029                    server_id,
 9030                    sender_id,
 9031                    lsp_request_id,
 9032                    get_declaration,
 9033                    position,
 9034                    &mut cx,
 9035                )
 9036                .await?;
 9037            }
 9038            Request::GetTypeDefinition(get_type_definition) => {
 9039                let position = get_type_definition
 9040                    .position
 9041                    .clone()
 9042                    .and_then(deserialize_anchor);
 9043                Self::query_lsp_locally::<GetTypeDefinitions>(
 9044                    lsp_store,
 9045                    server_id,
 9046                    sender_id,
 9047                    lsp_request_id,
 9048                    get_type_definition,
 9049                    position,
 9050                    &mut cx,
 9051                )
 9052                .await?;
 9053            }
 9054            Request::GetImplementation(get_implementation) => {
 9055                let position = get_implementation
 9056                    .position
 9057                    .clone()
 9058                    .and_then(deserialize_anchor);
 9059                Self::query_lsp_locally::<GetImplementations>(
 9060                    lsp_store,
 9061                    server_id,
 9062                    sender_id,
 9063                    lsp_request_id,
 9064                    get_implementation,
 9065                    position,
 9066                    &mut cx,
 9067                )
 9068                .await?;
 9069            }
 9070            Request::GetDocumentDiagnostics(get_document_diagnostics) => {
 9071                let buffer_id = BufferId::new(get_document_diagnostics.buffer_id())?;
 9072                let version = deserialize_version(get_document_diagnostics.buffer_version());
 9073                let buffer = lsp_store.update(&mut cx, |this, cx| {
 9074                    this.buffer_store.read(cx).get_existing(buffer_id)
 9075                })??;
 9076                buffer
 9077                    .update(&mut cx, |buffer, _| {
 9078                        buffer.wait_for_version(version.clone())
 9079                    })?
 9080                    .await?;
 9081                lsp_store.update(&mut cx, |lsp_store, cx| {
 9082                    let lsp_data = lsp_store.latest_lsp_data(&buffer, cx);
 9083                    let key = LspKey {
 9084                        request_type: TypeId::of::<GetDocumentDiagnostics>(),
 9085                        server_queried: server_id,
 9086                    };
 9087                    if <GetDocumentDiagnostics as LspCommand>::ProtoRequest::stop_previous_requests(
 9088                    ) {
 9089                        if let Some(lsp_requests) = lsp_data.lsp_requests.get_mut(&key) {
 9090                            lsp_requests.clear();
 9091                        };
 9092                    }
 9093
 9094                    let existing_queries = lsp_data.lsp_requests.entry(key).or_default();
 9095                    existing_queries.insert(
 9096                        lsp_request_id,
 9097                        cx.spawn(async move |lsp_store, cx| {
 9098                            let diagnostics_pull = lsp_store
 9099                                .update(cx, |lsp_store, cx| {
 9100                                    lsp_store.pull_diagnostics_for_buffer(buffer, cx)
 9101                                })
 9102                                .ok();
 9103                            if let Some(diagnostics_pull) = diagnostics_pull {
 9104                                match diagnostics_pull.await {
 9105                                    Ok(()) => {}
 9106                                    Err(e) => log::error!("Failed to pull diagnostics: {e:#}"),
 9107                                };
 9108                            }
 9109                        }),
 9110                    );
 9111                })?;
 9112            }
 9113            Request::InlayHints(inlay_hints) => {
 9114                let query_start = inlay_hints
 9115                    .start
 9116                    .clone()
 9117                    .and_then(deserialize_anchor)
 9118                    .context("invalid inlay hints range start")?;
 9119                let query_end = inlay_hints
 9120                    .end
 9121                    .clone()
 9122                    .and_then(deserialize_anchor)
 9123                    .context("invalid inlay hints range end")?;
 9124                Self::deduplicate_range_based_lsp_requests::<InlayHints>(
 9125                    &lsp_store,
 9126                    server_id,
 9127                    lsp_request_id,
 9128                    &inlay_hints,
 9129                    query_start..query_end,
 9130                    &mut cx,
 9131                )
 9132                .await
 9133                .context("preparing inlay hints request")?;
 9134                Self::query_lsp_locally::<InlayHints>(
 9135                    lsp_store,
 9136                    server_id,
 9137                    sender_id,
 9138                    lsp_request_id,
 9139                    inlay_hints,
 9140                    None,
 9141                    &mut cx,
 9142                )
 9143                .await
 9144                .context("querying for inlay hints")?
 9145            }
 9146        }
 9147        Ok(proto::Ack {})
 9148    }
 9149
 9150    async fn handle_lsp_query_response(
 9151        lsp_store: Entity<Self>,
 9152        envelope: TypedEnvelope<proto::LspQueryResponse>,
 9153        cx: AsyncApp,
 9154    ) -> Result<()> {
 9155        lsp_store.read_with(&cx, |lsp_store, _| {
 9156            if let Some((upstream_client, _)) = lsp_store.upstream_client() {
 9157                upstream_client.handle_lsp_response(envelope.clone());
 9158            }
 9159        })?;
 9160        Ok(())
 9161    }
 9162
 9163    async fn handle_apply_code_action(
 9164        this: Entity<Self>,
 9165        envelope: TypedEnvelope<proto::ApplyCodeAction>,
 9166        mut cx: AsyncApp,
 9167    ) -> Result<proto::ApplyCodeActionResponse> {
 9168        let sender_id = envelope.original_sender_id().unwrap_or_default();
 9169        let action =
 9170            Self::deserialize_code_action(envelope.payload.action.context("invalid action")?)?;
 9171        let apply_code_action = this.update(&mut cx, |this, cx| {
 9172            let buffer_id = BufferId::new(envelope.payload.buffer_id)?;
 9173            let buffer = this.buffer_store.read(cx).get_existing(buffer_id)?;
 9174            anyhow::Ok(this.apply_code_action(buffer, action, false, cx))
 9175        })??;
 9176
 9177        let project_transaction = apply_code_action.await?;
 9178        let project_transaction = this.update(&mut cx, |this, cx| {
 9179            this.buffer_store.update(cx, |buffer_store, cx| {
 9180                buffer_store.serialize_project_transaction_for_peer(
 9181                    project_transaction,
 9182                    sender_id,
 9183                    cx,
 9184                )
 9185            })
 9186        })?;
 9187        Ok(proto::ApplyCodeActionResponse {
 9188            transaction: Some(project_transaction),
 9189        })
 9190    }
 9191
 9192    async fn handle_register_buffer_with_language_servers(
 9193        this: Entity<Self>,
 9194        envelope: TypedEnvelope<proto::RegisterBufferWithLanguageServers>,
 9195        mut cx: AsyncApp,
 9196    ) -> Result<proto::Ack> {
 9197        let buffer_id = BufferId::new(envelope.payload.buffer_id)?;
 9198        let peer_id = envelope.original_sender_id.unwrap_or(envelope.sender_id);
 9199        this.update(&mut cx, |this, cx| {
 9200            if let Some((upstream_client, upstream_project_id)) = this.upstream_client() {
 9201                return upstream_client.send(proto::RegisterBufferWithLanguageServers {
 9202                    project_id: upstream_project_id,
 9203                    buffer_id: buffer_id.to_proto(),
 9204                    only_servers: envelope.payload.only_servers,
 9205                });
 9206            }
 9207
 9208            let Some(buffer) = this.buffer_store().read(cx).get(buffer_id) else {
 9209                anyhow::bail!("buffer is not open");
 9210            };
 9211
 9212            let handle = this.register_buffer_with_language_servers(
 9213                &buffer,
 9214                envelope
 9215                    .payload
 9216                    .only_servers
 9217                    .into_iter()
 9218                    .filter_map(|selector| {
 9219                        Some(match selector.selector? {
 9220                            proto::language_server_selector::Selector::ServerId(server_id) => {
 9221                                LanguageServerSelector::Id(LanguageServerId::from_proto(server_id))
 9222                            }
 9223                            proto::language_server_selector::Selector::Name(name) => {
 9224                                LanguageServerSelector::Name(LanguageServerName(
 9225                                    SharedString::from(name),
 9226                                ))
 9227                            }
 9228                        })
 9229                    })
 9230                    .collect(),
 9231                false,
 9232                cx,
 9233            );
 9234            this.buffer_store().update(cx, |buffer_store, _| {
 9235                buffer_store.register_shared_lsp_handle(peer_id, buffer_id, handle);
 9236            });
 9237
 9238            Ok(())
 9239        })??;
 9240        Ok(proto::Ack {})
 9241    }
 9242
 9243    async fn handle_rename_project_entry(
 9244        this: Entity<Self>,
 9245        envelope: TypedEnvelope<proto::RenameProjectEntry>,
 9246        mut cx: AsyncApp,
 9247    ) -> Result<proto::ProjectEntryResponse> {
 9248        let entry_id = ProjectEntryId::from_proto(envelope.payload.entry_id);
 9249        let new_worktree_id = WorktreeId::from_proto(envelope.payload.new_worktree_id);
 9250        let new_path =
 9251            RelPath::from_proto(&envelope.payload.new_path).context("invalid relative path")?;
 9252
 9253        let (worktree_store, old_worktree, new_worktree, old_entry) = this
 9254            .update(&mut cx, |this, cx| {
 9255                let (worktree, entry) = this
 9256                    .worktree_store
 9257                    .read(cx)
 9258                    .worktree_and_entry_for_id(entry_id, cx)?;
 9259                let new_worktree = this
 9260                    .worktree_store
 9261                    .read(cx)
 9262                    .worktree_for_id(new_worktree_id, cx)?;
 9263                Some((
 9264                    this.worktree_store.clone(),
 9265                    worktree,
 9266                    new_worktree,
 9267                    entry.clone(),
 9268                ))
 9269            })?
 9270            .context("worktree not found")?;
 9271        let (old_abs_path, old_worktree_id) = old_worktree.read_with(&cx, |worktree, _| {
 9272            (worktree.absolutize(&old_entry.path), worktree.id())
 9273        })?;
 9274        let new_abs_path =
 9275            new_worktree.read_with(&cx, |worktree, _| worktree.absolutize(&new_path))?;
 9276
 9277        let _transaction = Self::will_rename_entry(
 9278            this.downgrade(),
 9279            old_worktree_id,
 9280            &old_abs_path,
 9281            &new_abs_path,
 9282            old_entry.is_dir(),
 9283            cx.clone(),
 9284        )
 9285        .await;
 9286        let response = WorktreeStore::handle_rename_project_entry(
 9287            worktree_store,
 9288            envelope.payload,
 9289            cx.clone(),
 9290        )
 9291        .await;
 9292        this.read_with(&cx, |this, _| {
 9293            this.did_rename_entry(
 9294                old_worktree_id,
 9295                &old_abs_path,
 9296                &new_abs_path,
 9297                old_entry.is_dir(),
 9298            );
 9299        })
 9300        .ok();
 9301        response
 9302    }
 9303
 9304    async fn handle_update_diagnostic_summary(
 9305        this: Entity<Self>,
 9306        envelope: TypedEnvelope<proto::UpdateDiagnosticSummary>,
 9307        mut cx: AsyncApp,
 9308    ) -> Result<()> {
 9309        this.update(&mut cx, |lsp_store, cx| {
 9310            let worktree_id = WorktreeId::from_proto(envelope.payload.worktree_id);
 9311            let mut updated_diagnostics_paths = HashMap::default();
 9312            let mut diagnostics_summary = None::<proto::UpdateDiagnosticSummary>;
 9313            for message_summary in envelope
 9314                .payload
 9315                .summary
 9316                .into_iter()
 9317                .chain(envelope.payload.more_summaries)
 9318            {
 9319                let project_path = ProjectPath {
 9320                    worktree_id,
 9321                    path: RelPath::from_proto(&message_summary.path).context("invalid path")?,
 9322                };
 9323                let path = project_path.path.clone();
 9324                let server_id = LanguageServerId(message_summary.language_server_id as usize);
 9325                let summary = DiagnosticSummary {
 9326                    error_count: message_summary.error_count as usize,
 9327                    warning_count: message_summary.warning_count as usize,
 9328                };
 9329
 9330                if summary.is_empty() {
 9331                    if let Some(worktree_summaries) =
 9332                        lsp_store.diagnostic_summaries.get_mut(&worktree_id)
 9333                        && let Some(summaries) = worktree_summaries.get_mut(&path)
 9334                    {
 9335                        summaries.remove(&server_id);
 9336                        if summaries.is_empty() {
 9337                            worktree_summaries.remove(&path);
 9338                        }
 9339                    }
 9340                } else {
 9341                    lsp_store
 9342                        .diagnostic_summaries
 9343                        .entry(worktree_id)
 9344                        .or_default()
 9345                        .entry(path)
 9346                        .or_default()
 9347                        .insert(server_id, summary);
 9348                }
 9349
 9350                if let Some((_, project_id)) = &lsp_store.downstream_client {
 9351                    match &mut diagnostics_summary {
 9352                        Some(diagnostics_summary) => {
 9353                            diagnostics_summary
 9354                                .more_summaries
 9355                                .push(proto::DiagnosticSummary {
 9356                                    path: project_path.path.as_ref().to_proto(),
 9357                                    language_server_id: server_id.0 as u64,
 9358                                    error_count: summary.error_count as u32,
 9359                                    warning_count: summary.warning_count as u32,
 9360                                })
 9361                        }
 9362                        None => {
 9363                            diagnostics_summary = Some(proto::UpdateDiagnosticSummary {
 9364                                project_id: *project_id,
 9365                                worktree_id: worktree_id.to_proto(),
 9366                                summary: Some(proto::DiagnosticSummary {
 9367                                    path: project_path.path.as_ref().to_proto(),
 9368                                    language_server_id: server_id.0 as u64,
 9369                                    error_count: summary.error_count as u32,
 9370                                    warning_count: summary.warning_count as u32,
 9371                                }),
 9372                                more_summaries: Vec::new(),
 9373                            })
 9374                        }
 9375                    }
 9376                }
 9377                updated_diagnostics_paths
 9378                    .entry(server_id)
 9379                    .or_insert_with(Vec::new)
 9380                    .push(project_path);
 9381            }
 9382
 9383            if let Some((diagnostics_summary, (downstream_client, _))) =
 9384                diagnostics_summary.zip(lsp_store.downstream_client.as_ref())
 9385            {
 9386                downstream_client.send(diagnostics_summary).log_err();
 9387            }
 9388            for (server_id, paths) in updated_diagnostics_paths {
 9389                cx.emit(LspStoreEvent::DiagnosticsUpdated { server_id, paths });
 9390            }
 9391            Ok(())
 9392        })?
 9393    }
 9394
 9395    async fn handle_start_language_server(
 9396        lsp_store: Entity<Self>,
 9397        envelope: TypedEnvelope<proto::StartLanguageServer>,
 9398        mut cx: AsyncApp,
 9399    ) -> Result<()> {
 9400        let server = envelope.payload.server.context("invalid server")?;
 9401        let server_capabilities =
 9402            serde_json::from_str::<lsp::ServerCapabilities>(&envelope.payload.capabilities)
 9403                .with_context(|| {
 9404                    format!(
 9405                        "incorrect server capabilities {}",
 9406                        envelope.payload.capabilities
 9407                    )
 9408                })?;
 9409        lsp_store.update(&mut cx, |lsp_store, cx| {
 9410            let server_id = LanguageServerId(server.id as usize);
 9411            let server_name = LanguageServerName::from_proto(server.name.clone());
 9412            lsp_store
 9413                .lsp_server_capabilities
 9414                .insert(server_id, server_capabilities);
 9415            lsp_store.language_server_statuses.insert(
 9416                server_id,
 9417                LanguageServerStatus {
 9418                    name: server_name.clone(),
 9419                    pending_work: Default::default(),
 9420                    has_pending_diagnostic_updates: false,
 9421                    progress_tokens: Default::default(),
 9422                    worktree: server.worktree_id.map(WorktreeId::from_proto),
 9423                    binary: None,
 9424                    configuration: None,
 9425                    workspace_folders: BTreeSet::new(),
 9426                },
 9427            );
 9428            cx.emit(LspStoreEvent::LanguageServerAdded(
 9429                server_id,
 9430                server_name,
 9431                server.worktree_id.map(WorktreeId::from_proto),
 9432            ));
 9433            cx.notify();
 9434        })?;
 9435        Ok(())
 9436    }
 9437
 9438    async fn handle_update_language_server(
 9439        lsp_store: Entity<Self>,
 9440        envelope: TypedEnvelope<proto::UpdateLanguageServer>,
 9441        mut cx: AsyncApp,
 9442    ) -> Result<()> {
 9443        lsp_store.update(&mut cx, |lsp_store, cx| {
 9444            let language_server_id = LanguageServerId(envelope.payload.language_server_id as usize);
 9445
 9446            match envelope.payload.variant.context("invalid variant")? {
 9447                proto::update_language_server::Variant::WorkStart(payload) => {
 9448                    lsp_store.on_lsp_work_start(
 9449                        language_server_id,
 9450                        ProgressToken::from_proto(payload.token.context("missing progress token")?)
 9451                            .context("invalid progress token value")?,
 9452                        LanguageServerProgress {
 9453                            title: payload.title,
 9454                            is_disk_based_diagnostics_progress: false,
 9455                            is_cancellable: payload.is_cancellable.unwrap_or(false),
 9456                            message: payload.message,
 9457                            percentage: payload.percentage.map(|p| p as usize),
 9458                            last_update_at: cx.background_executor().now(),
 9459                        },
 9460                        cx,
 9461                    );
 9462                }
 9463                proto::update_language_server::Variant::WorkProgress(payload) => {
 9464                    lsp_store.on_lsp_work_progress(
 9465                        language_server_id,
 9466                        ProgressToken::from_proto(payload.token.context("missing progress token")?)
 9467                            .context("invalid progress token value")?,
 9468                        LanguageServerProgress {
 9469                            title: None,
 9470                            is_disk_based_diagnostics_progress: false,
 9471                            is_cancellable: payload.is_cancellable.unwrap_or(false),
 9472                            message: payload.message,
 9473                            percentage: payload.percentage.map(|p| p as usize),
 9474                            last_update_at: cx.background_executor().now(),
 9475                        },
 9476                        cx,
 9477                    );
 9478                }
 9479
 9480                proto::update_language_server::Variant::WorkEnd(payload) => {
 9481                    lsp_store.on_lsp_work_end(
 9482                        language_server_id,
 9483                        ProgressToken::from_proto(payload.token.context("missing progress token")?)
 9484                            .context("invalid progress token value")?,
 9485                        cx,
 9486                    );
 9487                }
 9488
 9489                proto::update_language_server::Variant::DiskBasedDiagnosticsUpdating(_) => {
 9490                    lsp_store.disk_based_diagnostics_started(language_server_id, cx);
 9491                }
 9492
 9493                proto::update_language_server::Variant::DiskBasedDiagnosticsUpdated(_) => {
 9494                    lsp_store.disk_based_diagnostics_finished(language_server_id, cx)
 9495                }
 9496
 9497                non_lsp @ proto::update_language_server::Variant::StatusUpdate(_)
 9498                | non_lsp @ proto::update_language_server::Variant::RegisteredForBuffer(_)
 9499                | non_lsp @ proto::update_language_server::Variant::MetadataUpdated(_) => {
 9500                    cx.emit(LspStoreEvent::LanguageServerUpdate {
 9501                        language_server_id,
 9502                        name: envelope
 9503                            .payload
 9504                            .server_name
 9505                            .map(SharedString::new)
 9506                            .map(LanguageServerName),
 9507                        message: non_lsp,
 9508                    });
 9509                }
 9510            }
 9511
 9512            Ok(())
 9513        })?
 9514    }
 9515
 9516    async fn handle_language_server_log(
 9517        this: Entity<Self>,
 9518        envelope: TypedEnvelope<proto::LanguageServerLog>,
 9519        mut cx: AsyncApp,
 9520    ) -> Result<()> {
 9521        let language_server_id = LanguageServerId(envelope.payload.language_server_id as usize);
 9522        let log_type = envelope
 9523            .payload
 9524            .log_type
 9525            .map(LanguageServerLogType::from_proto)
 9526            .context("invalid language server log type")?;
 9527
 9528        let message = envelope.payload.message;
 9529
 9530        this.update(&mut cx, |_, cx| {
 9531            cx.emit(LspStoreEvent::LanguageServerLog(
 9532                language_server_id,
 9533                log_type,
 9534                message,
 9535            ));
 9536        })
 9537    }
 9538
 9539    async fn handle_lsp_ext_cancel_flycheck(
 9540        lsp_store: Entity<Self>,
 9541        envelope: TypedEnvelope<proto::LspExtCancelFlycheck>,
 9542        cx: AsyncApp,
 9543    ) -> Result<proto::Ack> {
 9544        let server_id = LanguageServerId(envelope.payload.language_server_id as usize);
 9545        let task = lsp_store.read_with(&cx, |lsp_store, _| {
 9546            if let Some(server) = lsp_store.language_server_for_id(server_id) {
 9547                Some(server.notify::<lsp_store::lsp_ext_command::LspExtCancelFlycheck>(()))
 9548            } else {
 9549                None
 9550            }
 9551        })?;
 9552        if let Some(task) = task {
 9553            task.context("handling lsp ext cancel flycheck")?;
 9554        }
 9555
 9556        Ok(proto::Ack {})
 9557    }
 9558
 9559    async fn handle_lsp_ext_run_flycheck(
 9560        lsp_store: Entity<Self>,
 9561        envelope: TypedEnvelope<proto::LspExtRunFlycheck>,
 9562        mut cx: AsyncApp,
 9563    ) -> Result<proto::Ack> {
 9564        let server_id = LanguageServerId(envelope.payload.language_server_id as usize);
 9565        lsp_store.update(&mut cx, |lsp_store, cx| {
 9566            if let Some(server) = lsp_store.language_server_for_id(server_id) {
 9567                let text_document = if envelope.payload.current_file_only {
 9568                    let buffer_id = envelope
 9569                        .payload
 9570                        .buffer_id
 9571                        .map(|id| BufferId::new(id))
 9572                        .transpose()?;
 9573                    buffer_id
 9574                        .and_then(|buffer_id| {
 9575                            lsp_store
 9576                                .buffer_store()
 9577                                .read(cx)
 9578                                .get(buffer_id)
 9579                                .and_then(|buffer| {
 9580                                    Some(buffer.read(cx).file()?.as_local()?.abs_path(cx))
 9581                                })
 9582                                .map(|path| make_text_document_identifier(&path))
 9583                        })
 9584                        .transpose()?
 9585                } else {
 9586                    None
 9587                };
 9588                server.notify::<lsp_store::lsp_ext_command::LspExtRunFlycheck>(
 9589                    lsp_store::lsp_ext_command::RunFlycheckParams { text_document },
 9590                )?;
 9591            }
 9592            anyhow::Ok(())
 9593        })??;
 9594
 9595        Ok(proto::Ack {})
 9596    }
 9597
 9598    async fn handle_lsp_ext_clear_flycheck(
 9599        lsp_store: Entity<Self>,
 9600        envelope: TypedEnvelope<proto::LspExtClearFlycheck>,
 9601        cx: AsyncApp,
 9602    ) -> Result<proto::Ack> {
 9603        let server_id = LanguageServerId(envelope.payload.language_server_id as usize);
 9604        lsp_store
 9605            .read_with(&cx, |lsp_store, _| {
 9606                if let Some(server) = lsp_store.language_server_for_id(server_id) {
 9607                    Some(server.notify::<lsp_store::lsp_ext_command::LspExtClearFlycheck>(()))
 9608                } else {
 9609                    None
 9610                }
 9611            })
 9612            .context("handling lsp ext clear flycheck")?;
 9613
 9614        Ok(proto::Ack {})
 9615    }
 9616
 9617    pub fn disk_based_diagnostics_started(
 9618        &mut self,
 9619        language_server_id: LanguageServerId,
 9620        cx: &mut Context<Self>,
 9621    ) {
 9622        if let Some(language_server_status) =
 9623            self.language_server_statuses.get_mut(&language_server_id)
 9624        {
 9625            language_server_status.has_pending_diagnostic_updates = true;
 9626        }
 9627
 9628        cx.emit(LspStoreEvent::DiskBasedDiagnosticsStarted { language_server_id });
 9629        cx.emit(LspStoreEvent::LanguageServerUpdate {
 9630            language_server_id,
 9631            name: self
 9632                .language_server_adapter_for_id(language_server_id)
 9633                .map(|adapter| adapter.name()),
 9634            message: proto::update_language_server::Variant::DiskBasedDiagnosticsUpdating(
 9635                Default::default(),
 9636            ),
 9637        })
 9638    }
 9639
 9640    pub fn disk_based_diagnostics_finished(
 9641        &mut self,
 9642        language_server_id: LanguageServerId,
 9643        cx: &mut Context<Self>,
 9644    ) {
 9645        if let Some(language_server_status) =
 9646            self.language_server_statuses.get_mut(&language_server_id)
 9647        {
 9648            language_server_status.has_pending_diagnostic_updates = false;
 9649        }
 9650
 9651        cx.emit(LspStoreEvent::DiskBasedDiagnosticsFinished { language_server_id });
 9652        cx.emit(LspStoreEvent::LanguageServerUpdate {
 9653            language_server_id,
 9654            name: self
 9655                .language_server_adapter_for_id(language_server_id)
 9656                .map(|adapter| adapter.name()),
 9657            message: proto::update_language_server::Variant::DiskBasedDiagnosticsUpdated(
 9658                Default::default(),
 9659            ),
 9660        })
 9661    }
 9662
 9663    // After saving a buffer using a language server that doesn't provide a disk-based progress token,
 9664    // kick off a timer that will reset every time the buffer is saved. If the timer eventually fires,
 9665    // simulate disk-based diagnostics being finished so that other pieces of UI (e.g., project
 9666    // diagnostics view, diagnostic status bar) can update. We don't emit an event right away because
 9667    // the language server might take some time to publish diagnostics.
 9668    fn simulate_disk_based_diagnostics_events_if_needed(
 9669        &mut self,
 9670        language_server_id: LanguageServerId,
 9671        cx: &mut Context<Self>,
 9672    ) {
 9673        const DISK_BASED_DIAGNOSTICS_DEBOUNCE: Duration = Duration::from_secs(1);
 9674
 9675        let Some(LanguageServerState::Running {
 9676            simulate_disk_based_diagnostics_completion,
 9677            adapter,
 9678            ..
 9679        }) = self
 9680            .as_local_mut()
 9681            .and_then(|local_store| local_store.language_servers.get_mut(&language_server_id))
 9682        else {
 9683            return;
 9684        };
 9685
 9686        if adapter.disk_based_diagnostics_progress_token.is_some() {
 9687            return;
 9688        }
 9689
 9690        let prev_task =
 9691            simulate_disk_based_diagnostics_completion.replace(cx.spawn(async move |this, cx| {
 9692                cx.background_executor()
 9693                    .timer(DISK_BASED_DIAGNOSTICS_DEBOUNCE)
 9694                    .await;
 9695
 9696                this.update(cx, |this, cx| {
 9697                    this.disk_based_diagnostics_finished(language_server_id, cx);
 9698
 9699                    if let Some(LanguageServerState::Running {
 9700                        simulate_disk_based_diagnostics_completion,
 9701                        ..
 9702                    }) = this.as_local_mut().and_then(|local_store| {
 9703                        local_store.language_servers.get_mut(&language_server_id)
 9704                    }) {
 9705                        *simulate_disk_based_diagnostics_completion = None;
 9706                    }
 9707                })
 9708                .ok();
 9709            }));
 9710
 9711        if prev_task.is_none() {
 9712            self.disk_based_diagnostics_started(language_server_id, cx);
 9713        }
 9714    }
 9715
 9716    pub fn language_server_statuses(
 9717        &self,
 9718    ) -> impl DoubleEndedIterator<Item = (LanguageServerId, &LanguageServerStatus)> {
 9719        self.language_server_statuses
 9720            .iter()
 9721            .map(|(key, value)| (*key, value))
 9722    }
 9723
 9724    pub(super) fn did_rename_entry(
 9725        &self,
 9726        worktree_id: WorktreeId,
 9727        old_path: &Path,
 9728        new_path: &Path,
 9729        is_dir: bool,
 9730    ) {
 9731        maybe!({
 9732            let local_store = self.as_local()?;
 9733
 9734            let old_uri = lsp::Uri::from_file_path(old_path)
 9735                .ok()
 9736                .map(|uri| uri.to_string())?;
 9737            let new_uri = lsp::Uri::from_file_path(new_path)
 9738                .ok()
 9739                .map(|uri| uri.to_string())?;
 9740
 9741            for language_server in local_store.language_servers_for_worktree(worktree_id) {
 9742                let Some(filter) = local_store
 9743                    .language_server_paths_watched_for_rename
 9744                    .get(&language_server.server_id())
 9745                else {
 9746                    continue;
 9747                };
 9748
 9749                if filter.should_send_did_rename(&old_uri, is_dir) {
 9750                    language_server
 9751                        .notify::<DidRenameFiles>(RenameFilesParams {
 9752                            files: vec![FileRename {
 9753                                old_uri: old_uri.clone(),
 9754                                new_uri: new_uri.clone(),
 9755                            }],
 9756                        })
 9757                        .ok();
 9758                }
 9759            }
 9760            Some(())
 9761        });
 9762    }
 9763
 9764    pub(super) fn will_rename_entry(
 9765        this: WeakEntity<Self>,
 9766        worktree_id: WorktreeId,
 9767        old_path: &Path,
 9768        new_path: &Path,
 9769        is_dir: bool,
 9770        cx: AsyncApp,
 9771    ) -> Task<ProjectTransaction> {
 9772        let old_uri = lsp::Uri::from_file_path(old_path)
 9773            .ok()
 9774            .map(|uri| uri.to_string());
 9775        let new_uri = lsp::Uri::from_file_path(new_path)
 9776            .ok()
 9777            .map(|uri| uri.to_string());
 9778        cx.spawn(async move |cx| {
 9779            let mut tasks = vec![];
 9780            this.update(cx, |this, cx| {
 9781                let local_store = this.as_local()?;
 9782                let old_uri = old_uri?;
 9783                let new_uri = new_uri?;
 9784                for language_server in local_store.language_servers_for_worktree(worktree_id) {
 9785                    let Some(filter) = local_store
 9786                        .language_server_paths_watched_for_rename
 9787                        .get(&language_server.server_id())
 9788                    else {
 9789                        continue;
 9790                    };
 9791
 9792                    if filter.should_send_will_rename(&old_uri, is_dir) {
 9793                        let apply_edit = cx.spawn({
 9794                            let old_uri = old_uri.clone();
 9795                            let new_uri = new_uri.clone();
 9796                            let language_server = language_server.clone();
 9797                            async move |this, cx| {
 9798                                let edit = language_server
 9799                                    .request::<WillRenameFiles>(RenameFilesParams {
 9800                                        files: vec![FileRename { old_uri, new_uri }],
 9801                                    })
 9802                                    .await
 9803                                    .into_response()
 9804                                    .context("will rename files")
 9805                                    .log_err()
 9806                                    .flatten()?;
 9807
 9808                                let transaction = LocalLspStore::deserialize_workspace_edit(
 9809                                    this.upgrade()?,
 9810                                    edit,
 9811                                    false,
 9812                                    language_server.clone(),
 9813                                    cx,
 9814                                )
 9815                                .await
 9816                                .ok()?;
 9817                                Some(transaction)
 9818                            }
 9819                        });
 9820                        tasks.push(apply_edit);
 9821                    }
 9822                }
 9823                Some(())
 9824            })
 9825            .ok()
 9826            .flatten();
 9827            let mut merged_transaction = ProjectTransaction::default();
 9828            for task in tasks {
 9829                // Await on tasks sequentially so that the order of application of edits is deterministic
 9830                // (at least with regards to the order of registration of language servers)
 9831                if let Some(transaction) = task.await {
 9832                    for (buffer, buffer_transaction) in transaction.0 {
 9833                        merged_transaction.0.insert(buffer, buffer_transaction);
 9834                    }
 9835                }
 9836            }
 9837            merged_transaction
 9838        })
 9839    }
 9840
 9841    fn lsp_notify_abs_paths_changed(
 9842        &mut self,
 9843        server_id: LanguageServerId,
 9844        changes: Vec<PathEvent>,
 9845    ) {
 9846        maybe!({
 9847            let server = self.language_server_for_id(server_id)?;
 9848            let changes = changes
 9849                .into_iter()
 9850                .filter_map(|event| {
 9851                    let typ = match event.kind? {
 9852                        PathEventKind::Created => lsp::FileChangeType::CREATED,
 9853                        PathEventKind::Removed => lsp::FileChangeType::DELETED,
 9854                        PathEventKind::Changed => lsp::FileChangeType::CHANGED,
 9855                    };
 9856                    Some(lsp::FileEvent {
 9857                        uri: file_path_to_lsp_url(&event.path).log_err()?,
 9858                        typ,
 9859                    })
 9860                })
 9861                .collect::<Vec<_>>();
 9862            if !changes.is_empty() {
 9863                server
 9864                    .notify::<lsp::notification::DidChangeWatchedFiles>(
 9865                        lsp::DidChangeWatchedFilesParams { changes },
 9866                    )
 9867                    .ok();
 9868            }
 9869            Some(())
 9870        });
 9871    }
 9872
 9873    pub fn language_server_for_id(&self, id: LanguageServerId) -> Option<Arc<LanguageServer>> {
 9874        self.as_local()?.language_server_for_id(id)
 9875    }
 9876
 9877    fn on_lsp_progress(
 9878        &mut self,
 9879        progress_params: lsp::ProgressParams,
 9880        language_server_id: LanguageServerId,
 9881        disk_based_diagnostics_progress_token: Option<String>,
 9882        cx: &mut Context<Self>,
 9883    ) {
 9884        match progress_params.value {
 9885            lsp::ProgressParamsValue::WorkDone(progress) => {
 9886                self.handle_work_done_progress(
 9887                    progress,
 9888                    language_server_id,
 9889                    disk_based_diagnostics_progress_token,
 9890                    ProgressToken::from_lsp(progress_params.token),
 9891                    cx,
 9892                );
 9893            }
 9894            lsp::ProgressParamsValue::WorkspaceDiagnostic(report) => {
 9895                let registration_id = match progress_params.token {
 9896                    lsp::NumberOrString::Number(_) => None,
 9897                    lsp::NumberOrString::String(token) => token
 9898                        .split_once(WORKSPACE_DIAGNOSTICS_TOKEN_START)
 9899                        .map(|(_, id)| id.to_owned()),
 9900                };
 9901                if let Some(LanguageServerState::Running {
 9902                    workspace_diagnostics_refresh_tasks,
 9903                    ..
 9904                }) = self
 9905                    .as_local_mut()
 9906                    .and_then(|local| local.language_servers.get_mut(&language_server_id))
 9907                    && let Some(workspace_diagnostics) =
 9908                        workspace_diagnostics_refresh_tasks.get_mut(&registration_id)
 9909                {
 9910                    workspace_diagnostics.progress_tx.try_send(()).ok();
 9911                    self.apply_workspace_diagnostic_report(
 9912                        language_server_id,
 9913                        report,
 9914                        registration_id.map(SharedString::from),
 9915                        cx,
 9916                    )
 9917                }
 9918            }
 9919        }
 9920    }
 9921
 9922    fn handle_work_done_progress(
 9923        &mut self,
 9924        progress: lsp::WorkDoneProgress,
 9925        language_server_id: LanguageServerId,
 9926        disk_based_diagnostics_progress_token: Option<String>,
 9927        token: ProgressToken,
 9928        cx: &mut Context<Self>,
 9929    ) {
 9930        let language_server_status =
 9931            if let Some(status) = self.language_server_statuses.get_mut(&language_server_id) {
 9932                status
 9933            } else {
 9934                return;
 9935            };
 9936
 9937        if !language_server_status.progress_tokens.contains(&token) {
 9938            return;
 9939        }
 9940
 9941        let is_disk_based_diagnostics_progress =
 9942            if let (Some(disk_based_token), ProgressToken::String(token)) =
 9943                (&disk_based_diagnostics_progress_token, &token)
 9944            {
 9945                token.starts_with(disk_based_token)
 9946            } else {
 9947                false
 9948            };
 9949
 9950        match progress {
 9951            lsp::WorkDoneProgress::Begin(report) => {
 9952                if is_disk_based_diagnostics_progress {
 9953                    self.disk_based_diagnostics_started(language_server_id, cx);
 9954                }
 9955                self.on_lsp_work_start(
 9956                    language_server_id,
 9957                    token.clone(),
 9958                    LanguageServerProgress {
 9959                        title: Some(report.title),
 9960                        is_disk_based_diagnostics_progress,
 9961                        is_cancellable: report.cancellable.unwrap_or(false),
 9962                        message: report.message.clone(),
 9963                        percentage: report.percentage.map(|p| p as usize),
 9964                        last_update_at: cx.background_executor().now(),
 9965                    },
 9966                    cx,
 9967                );
 9968            }
 9969            lsp::WorkDoneProgress::Report(report) => self.on_lsp_work_progress(
 9970                language_server_id,
 9971                token,
 9972                LanguageServerProgress {
 9973                    title: None,
 9974                    is_disk_based_diagnostics_progress,
 9975                    is_cancellable: report.cancellable.unwrap_or(false),
 9976                    message: report.message,
 9977                    percentage: report.percentage.map(|p| p as usize),
 9978                    last_update_at: cx.background_executor().now(),
 9979                },
 9980                cx,
 9981            ),
 9982            lsp::WorkDoneProgress::End(_) => {
 9983                language_server_status.progress_tokens.remove(&token);
 9984                self.on_lsp_work_end(language_server_id, token.clone(), cx);
 9985                if is_disk_based_diagnostics_progress {
 9986                    self.disk_based_diagnostics_finished(language_server_id, cx);
 9987                }
 9988            }
 9989        }
 9990    }
 9991
 9992    fn on_lsp_work_start(
 9993        &mut self,
 9994        language_server_id: LanguageServerId,
 9995        token: ProgressToken,
 9996        progress: LanguageServerProgress,
 9997        cx: &mut Context<Self>,
 9998    ) {
 9999        if let Some(status) = self.language_server_statuses.get_mut(&language_server_id) {
10000            status.pending_work.insert(token.clone(), progress.clone());
10001            cx.notify();
10002        }
10003        cx.emit(LspStoreEvent::LanguageServerUpdate {
10004            language_server_id,
10005            name: self
10006                .language_server_adapter_for_id(language_server_id)
10007                .map(|adapter| adapter.name()),
10008            message: proto::update_language_server::Variant::WorkStart(proto::LspWorkStart {
10009                token: Some(token.to_proto()),
10010                title: progress.title,
10011                message: progress.message,
10012                percentage: progress.percentage.map(|p| p as u32),
10013                is_cancellable: Some(progress.is_cancellable),
10014            }),
10015        })
10016    }
10017
10018    fn on_lsp_work_progress(
10019        &mut self,
10020        language_server_id: LanguageServerId,
10021        token: ProgressToken,
10022        progress: LanguageServerProgress,
10023        cx: &mut Context<Self>,
10024    ) {
10025        let mut did_update = false;
10026        if let Some(status) = self.language_server_statuses.get_mut(&language_server_id) {
10027            match status.pending_work.entry(token.clone()) {
10028                btree_map::Entry::Vacant(entry) => {
10029                    entry.insert(progress.clone());
10030                    did_update = true;
10031                }
10032                btree_map::Entry::Occupied(mut entry) => {
10033                    let entry = entry.get_mut();
10034                    if (progress.last_update_at - entry.last_update_at)
10035                        >= SERVER_PROGRESS_THROTTLE_TIMEOUT
10036                    {
10037                        entry.last_update_at = progress.last_update_at;
10038                        if progress.message.is_some() {
10039                            entry.message = progress.message.clone();
10040                        }
10041                        if progress.percentage.is_some() {
10042                            entry.percentage = progress.percentage;
10043                        }
10044                        if progress.is_cancellable != entry.is_cancellable {
10045                            entry.is_cancellable = progress.is_cancellable;
10046                        }
10047                        did_update = true;
10048                    }
10049                }
10050            }
10051        }
10052
10053        if did_update {
10054            cx.emit(LspStoreEvent::LanguageServerUpdate {
10055                language_server_id,
10056                name: self
10057                    .language_server_adapter_for_id(language_server_id)
10058                    .map(|adapter| adapter.name()),
10059                message: proto::update_language_server::Variant::WorkProgress(
10060                    proto::LspWorkProgress {
10061                        token: Some(token.to_proto()),
10062                        message: progress.message,
10063                        percentage: progress.percentage.map(|p| p as u32),
10064                        is_cancellable: Some(progress.is_cancellable),
10065                    },
10066                ),
10067            })
10068        }
10069    }
10070
10071    fn on_lsp_work_end(
10072        &mut self,
10073        language_server_id: LanguageServerId,
10074        token: ProgressToken,
10075        cx: &mut Context<Self>,
10076    ) {
10077        if let Some(status) = self.language_server_statuses.get_mut(&language_server_id) {
10078            if let Some(work) = status.pending_work.remove(&token)
10079                && !work.is_disk_based_diagnostics_progress
10080            {
10081                cx.emit(LspStoreEvent::RefreshInlayHints {
10082                    server_id: language_server_id,
10083                    request_id: None,
10084                });
10085            }
10086            cx.notify();
10087        }
10088
10089        cx.emit(LspStoreEvent::LanguageServerUpdate {
10090            language_server_id,
10091            name: self
10092                .language_server_adapter_for_id(language_server_id)
10093                .map(|adapter| adapter.name()),
10094            message: proto::update_language_server::Variant::WorkEnd(proto::LspWorkEnd {
10095                token: Some(token.to_proto()),
10096            }),
10097        })
10098    }
10099
10100    pub async fn handle_resolve_completion_documentation(
10101        this: Entity<Self>,
10102        envelope: TypedEnvelope<proto::ResolveCompletionDocumentation>,
10103        mut cx: AsyncApp,
10104    ) -> Result<proto::ResolveCompletionDocumentationResponse> {
10105        let lsp_completion = serde_json::from_slice(&envelope.payload.lsp_completion)?;
10106
10107        let completion = this
10108            .read_with(&cx, |this, cx| {
10109                let id = LanguageServerId(envelope.payload.language_server_id as usize);
10110                let server = this
10111                    .language_server_for_id(id)
10112                    .with_context(|| format!("No language server {id}"))?;
10113
10114                anyhow::Ok(cx.background_spawn(async move {
10115                    let can_resolve = server
10116                        .capabilities()
10117                        .completion_provider
10118                        .as_ref()
10119                        .and_then(|options| options.resolve_provider)
10120                        .unwrap_or(false);
10121                    if can_resolve {
10122                        server
10123                            .request::<lsp::request::ResolveCompletionItem>(lsp_completion)
10124                            .await
10125                            .into_response()
10126                            .context("resolve completion item")
10127                    } else {
10128                        anyhow::Ok(lsp_completion)
10129                    }
10130                }))
10131            })??
10132            .await?;
10133
10134        let mut documentation_is_markdown = false;
10135        let lsp_completion = serde_json::to_string(&completion)?.into_bytes();
10136        let documentation = match completion.documentation {
10137            Some(lsp::Documentation::String(text)) => text,
10138
10139            Some(lsp::Documentation::MarkupContent(lsp::MarkupContent { kind, value })) => {
10140                documentation_is_markdown = kind == lsp::MarkupKind::Markdown;
10141                value
10142            }
10143
10144            _ => String::new(),
10145        };
10146
10147        // If we have a new buffer_id, that means we're talking to a new client
10148        // and want to check for new text_edits in the completion too.
10149        let mut old_replace_start = None;
10150        let mut old_replace_end = None;
10151        let mut old_insert_start = None;
10152        let mut old_insert_end = None;
10153        let mut new_text = String::default();
10154        if let Ok(buffer_id) = BufferId::new(envelope.payload.buffer_id) {
10155            let buffer_snapshot = this.update(&mut cx, |this, cx| {
10156                let buffer = this.buffer_store.read(cx).get_existing(buffer_id)?;
10157                anyhow::Ok(buffer.read(cx).snapshot())
10158            })??;
10159
10160            if let Some(text_edit) = completion.text_edit.as_ref() {
10161                let edit = parse_completion_text_edit(text_edit, &buffer_snapshot);
10162
10163                if let Some(mut edit) = edit {
10164                    LineEnding::normalize(&mut edit.new_text);
10165
10166                    new_text = edit.new_text;
10167                    old_replace_start = Some(serialize_anchor(&edit.replace_range.start));
10168                    old_replace_end = Some(serialize_anchor(&edit.replace_range.end));
10169                    if let Some(insert_range) = edit.insert_range {
10170                        old_insert_start = Some(serialize_anchor(&insert_range.start));
10171                        old_insert_end = Some(serialize_anchor(&insert_range.end));
10172                    }
10173                }
10174            }
10175        }
10176
10177        Ok(proto::ResolveCompletionDocumentationResponse {
10178            documentation,
10179            documentation_is_markdown,
10180            old_replace_start,
10181            old_replace_end,
10182            new_text,
10183            lsp_completion,
10184            old_insert_start,
10185            old_insert_end,
10186        })
10187    }
10188
10189    async fn handle_on_type_formatting(
10190        this: Entity<Self>,
10191        envelope: TypedEnvelope<proto::OnTypeFormatting>,
10192        mut cx: AsyncApp,
10193    ) -> Result<proto::OnTypeFormattingResponse> {
10194        let on_type_formatting = this.update(&mut cx, |this, cx| {
10195            let buffer_id = BufferId::new(envelope.payload.buffer_id)?;
10196            let buffer = this.buffer_store.read(cx).get_existing(buffer_id)?;
10197            let position = envelope
10198                .payload
10199                .position
10200                .and_then(deserialize_anchor)
10201                .context("invalid position")?;
10202            anyhow::Ok(this.apply_on_type_formatting(
10203                buffer,
10204                position,
10205                envelope.payload.trigger.clone(),
10206                cx,
10207            ))
10208        })??;
10209
10210        let transaction = on_type_formatting
10211            .await?
10212            .as_ref()
10213            .map(language::proto::serialize_transaction);
10214        Ok(proto::OnTypeFormattingResponse { transaction })
10215    }
10216
10217    async fn handle_refresh_inlay_hints(
10218        lsp_store: Entity<Self>,
10219        envelope: TypedEnvelope<proto::RefreshInlayHints>,
10220        mut cx: AsyncApp,
10221    ) -> Result<proto::Ack> {
10222        lsp_store.update(&mut cx, |_, cx| {
10223            cx.emit(LspStoreEvent::RefreshInlayHints {
10224                server_id: LanguageServerId::from_proto(envelope.payload.server_id),
10225                request_id: envelope.payload.request_id.map(|id| id as usize),
10226            });
10227        })?;
10228        Ok(proto::Ack {})
10229    }
10230
10231    async fn handle_pull_workspace_diagnostics(
10232        lsp_store: Entity<Self>,
10233        envelope: TypedEnvelope<proto::PullWorkspaceDiagnostics>,
10234        mut cx: AsyncApp,
10235    ) -> Result<proto::Ack> {
10236        let server_id = LanguageServerId::from_proto(envelope.payload.server_id);
10237        lsp_store.update(&mut cx, |lsp_store, _| {
10238            lsp_store.pull_workspace_diagnostics(server_id);
10239        })?;
10240        Ok(proto::Ack {})
10241    }
10242
10243    async fn handle_get_color_presentation(
10244        lsp_store: Entity<Self>,
10245        envelope: TypedEnvelope<proto::GetColorPresentation>,
10246        mut cx: AsyncApp,
10247    ) -> Result<proto::GetColorPresentationResponse> {
10248        let buffer_id = BufferId::new(envelope.payload.buffer_id)?;
10249        let buffer = lsp_store.update(&mut cx, |lsp_store, cx| {
10250            lsp_store.buffer_store.read(cx).get_existing(buffer_id)
10251        })??;
10252
10253        let color = envelope
10254            .payload
10255            .color
10256            .context("invalid color resolve request")?;
10257        let start = color
10258            .lsp_range_start
10259            .context("invalid color resolve request")?;
10260        let end = color
10261            .lsp_range_end
10262            .context("invalid color resolve request")?;
10263
10264        let color = DocumentColor {
10265            lsp_range: lsp::Range {
10266                start: point_to_lsp(PointUtf16::new(start.row, start.column)),
10267                end: point_to_lsp(PointUtf16::new(end.row, end.column)),
10268            },
10269            color: lsp::Color {
10270                red: color.red,
10271                green: color.green,
10272                blue: color.blue,
10273                alpha: color.alpha,
10274            },
10275            resolved: false,
10276            color_presentations: Vec::new(),
10277        };
10278        let resolved_color = lsp_store
10279            .update(&mut cx, |lsp_store, cx| {
10280                lsp_store.resolve_color_presentation(
10281                    color,
10282                    buffer.clone(),
10283                    LanguageServerId(envelope.payload.server_id as usize),
10284                    cx,
10285                )
10286            })?
10287            .await
10288            .context("resolving color presentation")?;
10289
10290        Ok(proto::GetColorPresentationResponse {
10291            presentations: resolved_color
10292                .color_presentations
10293                .into_iter()
10294                .map(|presentation| proto::ColorPresentation {
10295                    label: presentation.label.to_string(),
10296                    text_edit: presentation.text_edit.map(serialize_lsp_edit),
10297                    additional_text_edits: presentation
10298                        .additional_text_edits
10299                        .into_iter()
10300                        .map(serialize_lsp_edit)
10301                        .collect(),
10302                })
10303                .collect(),
10304        })
10305    }
10306
10307    async fn handle_resolve_inlay_hint(
10308        lsp_store: Entity<Self>,
10309        envelope: TypedEnvelope<proto::ResolveInlayHint>,
10310        mut cx: AsyncApp,
10311    ) -> Result<proto::ResolveInlayHintResponse> {
10312        let proto_hint = envelope
10313            .payload
10314            .hint
10315            .expect("incorrect protobuf resolve inlay hint message: missing the inlay hint");
10316        let hint = InlayHints::proto_to_project_hint(proto_hint)
10317            .context("resolved proto inlay hint conversion")?;
10318        let buffer = lsp_store.update(&mut cx, |lsp_store, cx| {
10319            let buffer_id = BufferId::new(envelope.payload.buffer_id)?;
10320            lsp_store.buffer_store.read(cx).get_existing(buffer_id)
10321        })??;
10322        let response_hint = lsp_store
10323            .update(&mut cx, |lsp_store, cx| {
10324                lsp_store.resolve_inlay_hint(
10325                    hint,
10326                    buffer,
10327                    LanguageServerId(envelope.payload.language_server_id as usize),
10328                    cx,
10329                )
10330            })?
10331            .await
10332            .context("inlay hints fetch")?;
10333        Ok(proto::ResolveInlayHintResponse {
10334            hint: Some(InlayHints::project_to_proto_hint(response_hint)),
10335        })
10336    }
10337
10338    async fn handle_refresh_code_lens(
10339        this: Entity<Self>,
10340        _: TypedEnvelope<proto::RefreshCodeLens>,
10341        mut cx: AsyncApp,
10342    ) -> Result<proto::Ack> {
10343        this.update(&mut cx, |_, cx| {
10344            cx.emit(LspStoreEvent::RefreshCodeLens);
10345        })?;
10346        Ok(proto::Ack {})
10347    }
10348
10349    async fn handle_open_buffer_for_symbol(
10350        this: Entity<Self>,
10351        envelope: TypedEnvelope<proto::OpenBufferForSymbol>,
10352        mut cx: AsyncApp,
10353    ) -> Result<proto::OpenBufferForSymbolResponse> {
10354        let peer_id = envelope.original_sender_id().unwrap_or_default();
10355        let symbol = envelope.payload.symbol.context("invalid symbol")?;
10356        let symbol = Self::deserialize_symbol(symbol)?;
10357        this.read_with(&cx, |this, _| {
10358            if let SymbolLocation::OutsideProject {
10359                abs_path,
10360                signature,
10361            } = &symbol.path
10362            {
10363                let new_signature = this.symbol_signature(&abs_path);
10364                anyhow::ensure!(&new_signature == signature, "invalid symbol signature");
10365            }
10366            Ok(())
10367        })??;
10368        let buffer = this
10369            .update(&mut cx, |this, cx| {
10370                this.open_buffer_for_symbol(
10371                    &Symbol {
10372                        language_server_name: symbol.language_server_name,
10373                        source_worktree_id: symbol.source_worktree_id,
10374                        source_language_server_id: symbol.source_language_server_id,
10375                        path: symbol.path,
10376                        name: symbol.name,
10377                        kind: symbol.kind,
10378                        range: symbol.range,
10379                        label: CodeLabel::default(),
10380                    },
10381                    cx,
10382                )
10383            })?
10384            .await?;
10385
10386        this.update(&mut cx, |this, cx| {
10387            let is_private = buffer
10388                .read(cx)
10389                .file()
10390                .map(|f| f.is_private())
10391                .unwrap_or_default();
10392            if is_private {
10393                Err(anyhow!(rpc::ErrorCode::UnsharedItem))
10394            } else {
10395                this.buffer_store
10396                    .update(cx, |buffer_store, cx| {
10397                        buffer_store.create_buffer_for_peer(&buffer, peer_id, cx)
10398                    })
10399                    .detach_and_log_err(cx);
10400                let buffer_id = buffer.read(cx).remote_id().to_proto();
10401                Ok(proto::OpenBufferForSymbolResponse { buffer_id })
10402            }
10403        })?
10404    }
10405
10406    fn symbol_signature(&self, abs_path: &Path) -> [u8; 32] {
10407        let mut hasher = Sha256::new();
10408        hasher.update(abs_path.to_string_lossy().as_bytes());
10409        hasher.update(self.nonce.to_be_bytes());
10410        hasher.finalize().as_slice().try_into().unwrap()
10411    }
10412
10413    pub async fn handle_get_project_symbols(
10414        this: Entity<Self>,
10415        envelope: TypedEnvelope<proto::GetProjectSymbols>,
10416        mut cx: AsyncApp,
10417    ) -> Result<proto::GetProjectSymbolsResponse> {
10418        let symbols = this
10419            .update(&mut cx, |this, cx| {
10420                this.symbols(&envelope.payload.query, cx)
10421            })?
10422            .await?;
10423
10424        Ok(proto::GetProjectSymbolsResponse {
10425            symbols: symbols.iter().map(Self::serialize_symbol).collect(),
10426        })
10427    }
10428
10429    pub async fn handle_restart_language_servers(
10430        this: Entity<Self>,
10431        envelope: TypedEnvelope<proto::RestartLanguageServers>,
10432        mut cx: AsyncApp,
10433    ) -> Result<proto::Ack> {
10434        this.update(&mut cx, |lsp_store, cx| {
10435            let buffers =
10436                lsp_store.buffer_ids_to_buffers(envelope.payload.buffer_ids.into_iter(), cx);
10437            lsp_store.restart_language_servers_for_buffers(
10438                buffers,
10439                envelope
10440                    .payload
10441                    .only_servers
10442                    .into_iter()
10443                    .filter_map(|selector| {
10444                        Some(match selector.selector? {
10445                            proto::language_server_selector::Selector::ServerId(server_id) => {
10446                                LanguageServerSelector::Id(LanguageServerId::from_proto(server_id))
10447                            }
10448                            proto::language_server_selector::Selector::Name(name) => {
10449                                LanguageServerSelector::Name(LanguageServerName(
10450                                    SharedString::from(name),
10451                                ))
10452                            }
10453                        })
10454                    })
10455                    .collect(),
10456                cx,
10457            );
10458        })?;
10459
10460        Ok(proto::Ack {})
10461    }
10462
10463    pub async fn handle_stop_language_servers(
10464        lsp_store: Entity<Self>,
10465        envelope: TypedEnvelope<proto::StopLanguageServers>,
10466        mut cx: AsyncApp,
10467    ) -> Result<proto::Ack> {
10468        lsp_store.update(&mut cx, |lsp_store, cx| {
10469            if envelope.payload.all
10470                && envelope.payload.also_servers.is_empty()
10471                && envelope.payload.buffer_ids.is_empty()
10472            {
10473                lsp_store.stop_all_language_servers(cx);
10474            } else {
10475                let buffers =
10476                    lsp_store.buffer_ids_to_buffers(envelope.payload.buffer_ids.into_iter(), cx);
10477                lsp_store
10478                    .stop_language_servers_for_buffers(
10479                        buffers,
10480                        envelope
10481                            .payload
10482                            .also_servers
10483                            .into_iter()
10484                            .filter_map(|selector| {
10485                                Some(match selector.selector? {
10486                                    proto::language_server_selector::Selector::ServerId(
10487                                        server_id,
10488                                    ) => LanguageServerSelector::Id(LanguageServerId::from_proto(
10489                                        server_id,
10490                                    )),
10491                                    proto::language_server_selector::Selector::Name(name) => {
10492                                        LanguageServerSelector::Name(LanguageServerName(
10493                                            SharedString::from(name),
10494                                        ))
10495                                    }
10496                                })
10497                            })
10498                            .collect(),
10499                        cx,
10500                    )
10501                    .detach_and_log_err(cx);
10502            }
10503        })?;
10504
10505        Ok(proto::Ack {})
10506    }
10507
10508    pub async fn handle_cancel_language_server_work(
10509        lsp_store: Entity<Self>,
10510        envelope: TypedEnvelope<proto::CancelLanguageServerWork>,
10511        mut cx: AsyncApp,
10512    ) -> Result<proto::Ack> {
10513        lsp_store.update(&mut cx, |lsp_store, cx| {
10514            if let Some(work) = envelope.payload.work {
10515                match work {
10516                    proto::cancel_language_server_work::Work::Buffers(buffers) => {
10517                        let buffers =
10518                            lsp_store.buffer_ids_to_buffers(buffers.buffer_ids.into_iter(), cx);
10519                        lsp_store.cancel_language_server_work_for_buffers(buffers, cx);
10520                    }
10521                    proto::cancel_language_server_work::Work::LanguageServerWork(work) => {
10522                        let server_id = LanguageServerId::from_proto(work.language_server_id);
10523                        let token = work
10524                            .token
10525                            .map(|token| {
10526                                ProgressToken::from_proto(token)
10527                                    .context("invalid work progress token")
10528                            })
10529                            .transpose()?;
10530                        lsp_store.cancel_language_server_work(server_id, token, cx);
10531                    }
10532                }
10533            }
10534            anyhow::Ok(())
10535        })??;
10536
10537        Ok(proto::Ack {})
10538    }
10539
10540    fn buffer_ids_to_buffers(
10541        &mut self,
10542        buffer_ids: impl Iterator<Item = u64>,
10543        cx: &mut Context<Self>,
10544    ) -> Vec<Entity<Buffer>> {
10545        buffer_ids
10546            .into_iter()
10547            .flat_map(|buffer_id| {
10548                self.buffer_store
10549                    .read(cx)
10550                    .get(BufferId::new(buffer_id).log_err()?)
10551            })
10552            .collect::<Vec<_>>()
10553    }
10554
10555    async fn handle_apply_additional_edits_for_completion(
10556        this: Entity<Self>,
10557        envelope: TypedEnvelope<proto::ApplyCompletionAdditionalEdits>,
10558        mut cx: AsyncApp,
10559    ) -> Result<proto::ApplyCompletionAdditionalEditsResponse> {
10560        let (buffer, completion) = this.update(&mut cx, |this, cx| {
10561            let buffer_id = BufferId::new(envelope.payload.buffer_id)?;
10562            let buffer = this.buffer_store.read(cx).get_existing(buffer_id)?;
10563            let completion = Self::deserialize_completion(
10564                envelope.payload.completion.context("invalid completion")?,
10565            )?;
10566            anyhow::Ok((buffer, completion))
10567        })??;
10568
10569        let apply_additional_edits = this.update(&mut cx, |this, cx| {
10570            this.apply_additional_edits_for_completion(
10571                buffer,
10572                Rc::new(RefCell::new(Box::new([Completion {
10573                    replace_range: completion.replace_range,
10574                    new_text: completion.new_text,
10575                    source: completion.source,
10576                    documentation: None,
10577                    label: CodeLabel::default(),
10578                    match_start: None,
10579                    snippet_deduplication_key: None,
10580                    insert_text_mode: None,
10581                    icon_path: None,
10582                    confirm: None,
10583                }]))),
10584                0,
10585                false,
10586                cx,
10587            )
10588        })?;
10589
10590        Ok(proto::ApplyCompletionAdditionalEditsResponse {
10591            transaction: apply_additional_edits
10592                .await?
10593                .as_ref()
10594                .map(language::proto::serialize_transaction),
10595        })
10596    }
10597
10598    pub fn last_formatting_failure(&self) -> Option<&str> {
10599        self.last_formatting_failure.as_deref()
10600    }
10601
10602    pub fn reset_last_formatting_failure(&mut self) {
10603        self.last_formatting_failure = None;
10604    }
10605
10606    pub fn environment_for_buffer(
10607        &self,
10608        buffer: &Entity<Buffer>,
10609        cx: &mut Context<Self>,
10610    ) -> Shared<Task<Option<HashMap<String, String>>>> {
10611        if let Some(environment) = &self.as_local().map(|local| local.environment.clone()) {
10612            environment.update(cx, |env, cx| {
10613                env.buffer_environment(buffer, &self.worktree_store, cx)
10614            })
10615        } else {
10616            Task::ready(None).shared()
10617        }
10618    }
10619
10620    pub fn format(
10621        &mut self,
10622        buffers: HashSet<Entity<Buffer>>,
10623        target: LspFormatTarget,
10624        push_to_history: bool,
10625        trigger: FormatTrigger,
10626        cx: &mut Context<Self>,
10627    ) -> Task<anyhow::Result<ProjectTransaction>> {
10628        let logger = zlog::scoped!("format");
10629        if self.as_local().is_some() {
10630            zlog::trace!(logger => "Formatting locally");
10631            let logger = zlog::scoped!(logger => "local");
10632            let buffers = buffers
10633                .into_iter()
10634                .map(|buffer_handle| {
10635                    let buffer = buffer_handle.read(cx);
10636                    let buffer_abs_path = File::from_dyn(buffer.file())
10637                        .and_then(|file| file.as_local().map(|f| f.abs_path(cx)));
10638
10639                    (buffer_handle, buffer_abs_path, buffer.remote_id())
10640                })
10641                .collect::<Vec<_>>();
10642
10643            cx.spawn(async move |lsp_store, cx| {
10644                let mut formattable_buffers = Vec::with_capacity(buffers.len());
10645
10646                for (handle, abs_path, id) in buffers {
10647                    let env = lsp_store
10648                        .update(cx, |lsp_store, cx| {
10649                            lsp_store.environment_for_buffer(&handle, cx)
10650                        })?
10651                        .await;
10652
10653                    let ranges = match &target {
10654                        LspFormatTarget::Buffers => None,
10655                        LspFormatTarget::Ranges(ranges) => {
10656                            Some(ranges.get(&id).context("No format ranges provided for buffer")?.clone())
10657                        }
10658                    };
10659
10660                    formattable_buffers.push(FormattableBuffer {
10661                        handle,
10662                        abs_path,
10663                        env,
10664                        ranges,
10665                    });
10666                }
10667                zlog::trace!(logger => "Formatting {:?} buffers", formattable_buffers.len());
10668
10669                let format_timer = zlog::time!(logger => "Formatting buffers");
10670                let result = LocalLspStore::format_locally(
10671                    lsp_store.clone(),
10672                    formattable_buffers,
10673                    push_to_history,
10674                    trigger,
10675                    logger,
10676                    cx,
10677                )
10678                .await;
10679                format_timer.end();
10680
10681                zlog::trace!(logger => "Formatting completed with result {:?}", result.as_ref().map(|_| "<project-transaction>"));
10682
10683                lsp_store.update(cx, |lsp_store, _| {
10684                    lsp_store.update_last_formatting_failure(&result);
10685                })?;
10686
10687                result
10688            })
10689        } else if let Some((client, project_id)) = self.upstream_client() {
10690            zlog::trace!(logger => "Formatting remotely");
10691            let logger = zlog::scoped!(logger => "remote");
10692            // Don't support formatting ranges via remote
10693            match target {
10694                LspFormatTarget::Buffers => {}
10695                LspFormatTarget::Ranges(_) => {
10696                    zlog::trace!(logger => "Ignoring unsupported remote range formatting request");
10697                    return Task::ready(Ok(ProjectTransaction::default()));
10698                }
10699            }
10700
10701            let buffer_store = self.buffer_store();
10702            cx.spawn(async move |lsp_store, cx| {
10703                zlog::trace!(logger => "Sending remote format request");
10704                let request_timer = zlog::time!(logger => "remote format request");
10705                let result = client
10706                    .request(proto::FormatBuffers {
10707                        project_id,
10708                        trigger: trigger as i32,
10709                        buffer_ids: buffers
10710                            .iter()
10711                            .map(|buffer| buffer.read_with(cx, |buffer, _| buffer.remote_id().into()))
10712                            .collect::<Result<_>>()?,
10713                    })
10714                    .await
10715                    .and_then(|result| result.transaction.context("missing transaction"));
10716                request_timer.end();
10717
10718                zlog::trace!(logger => "Remote format request resolved to {:?}", result.as_ref().map(|_| "<project_transaction>"));
10719
10720                lsp_store.update(cx, |lsp_store, _| {
10721                    lsp_store.update_last_formatting_failure(&result);
10722                })?;
10723
10724                let transaction_response = result?;
10725                let _timer = zlog::time!(logger => "deserializing project transaction");
10726                buffer_store
10727                    .update(cx, |buffer_store, cx| {
10728                        buffer_store.deserialize_project_transaction(
10729                            transaction_response,
10730                            push_to_history,
10731                            cx,
10732                        )
10733                    })?
10734                    .await
10735            })
10736        } else {
10737            zlog::trace!(logger => "Not formatting");
10738            Task::ready(Ok(ProjectTransaction::default()))
10739        }
10740    }
10741
10742    async fn handle_format_buffers(
10743        this: Entity<Self>,
10744        envelope: TypedEnvelope<proto::FormatBuffers>,
10745        mut cx: AsyncApp,
10746    ) -> Result<proto::FormatBuffersResponse> {
10747        let sender_id = envelope.original_sender_id().unwrap_or_default();
10748        let format = this.update(&mut cx, |this, cx| {
10749            let mut buffers = HashSet::default();
10750            for buffer_id in &envelope.payload.buffer_ids {
10751                let buffer_id = BufferId::new(*buffer_id)?;
10752                buffers.insert(this.buffer_store.read(cx).get_existing(buffer_id)?);
10753            }
10754            let trigger = FormatTrigger::from_proto(envelope.payload.trigger);
10755            anyhow::Ok(this.format(buffers, LspFormatTarget::Buffers, false, trigger, cx))
10756        })??;
10757
10758        let project_transaction = format.await?;
10759        let project_transaction = this.update(&mut cx, |this, cx| {
10760            this.buffer_store.update(cx, |buffer_store, cx| {
10761                buffer_store.serialize_project_transaction_for_peer(
10762                    project_transaction,
10763                    sender_id,
10764                    cx,
10765                )
10766            })
10767        })?;
10768        Ok(proto::FormatBuffersResponse {
10769            transaction: Some(project_transaction),
10770        })
10771    }
10772
10773    async fn handle_apply_code_action_kind(
10774        this: Entity<Self>,
10775        envelope: TypedEnvelope<proto::ApplyCodeActionKind>,
10776        mut cx: AsyncApp,
10777    ) -> Result<proto::ApplyCodeActionKindResponse> {
10778        let sender_id = envelope.original_sender_id().unwrap_or_default();
10779        let format = this.update(&mut cx, |this, cx| {
10780            let mut buffers = HashSet::default();
10781            for buffer_id in &envelope.payload.buffer_ids {
10782                let buffer_id = BufferId::new(*buffer_id)?;
10783                buffers.insert(this.buffer_store.read(cx).get_existing(buffer_id)?);
10784            }
10785            let kind = match envelope.payload.kind.as_str() {
10786                "" => CodeActionKind::EMPTY,
10787                "quickfix" => CodeActionKind::QUICKFIX,
10788                "refactor" => CodeActionKind::REFACTOR,
10789                "refactor.extract" => CodeActionKind::REFACTOR_EXTRACT,
10790                "refactor.inline" => CodeActionKind::REFACTOR_INLINE,
10791                "refactor.rewrite" => CodeActionKind::REFACTOR_REWRITE,
10792                "source" => CodeActionKind::SOURCE,
10793                "source.organizeImports" => CodeActionKind::SOURCE_ORGANIZE_IMPORTS,
10794                "source.fixAll" => CodeActionKind::SOURCE_FIX_ALL,
10795                _ => anyhow::bail!(
10796                    "Invalid code action kind {}",
10797                    envelope.payload.kind.as_str()
10798                ),
10799            };
10800            anyhow::Ok(this.apply_code_action_kind(buffers, kind, false, cx))
10801        })??;
10802
10803        let project_transaction = format.await?;
10804        let project_transaction = this.update(&mut cx, |this, cx| {
10805            this.buffer_store.update(cx, |buffer_store, cx| {
10806                buffer_store.serialize_project_transaction_for_peer(
10807                    project_transaction,
10808                    sender_id,
10809                    cx,
10810                )
10811            })
10812        })?;
10813        Ok(proto::ApplyCodeActionKindResponse {
10814            transaction: Some(project_transaction),
10815        })
10816    }
10817
10818    async fn shutdown_language_server(
10819        server_state: Option<LanguageServerState>,
10820        name: LanguageServerName,
10821        cx: &mut AsyncApp,
10822    ) {
10823        let server = match server_state {
10824            Some(LanguageServerState::Starting { startup, .. }) => {
10825                let mut timer = cx
10826                    .background_executor()
10827                    .timer(SERVER_LAUNCHING_BEFORE_SHUTDOWN_TIMEOUT)
10828                    .fuse();
10829
10830                select! {
10831                    server = startup.fuse() => server,
10832                    () = timer => {
10833                        log::info!("timeout waiting for language server {name} to finish launching before stopping");
10834                        None
10835                    },
10836                }
10837            }
10838
10839            Some(LanguageServerState::Running { server, .. }) => Some(server),
10840
10841            None => None,
10842        };
10843
10844        if let Some(server) = server
10845            && let Some(shutdown) = server.shutdown()
10846        {
10847            shutdown.await;
10848        }
10849    }
10850
10851    // Returns a list of all of the worktrees which no longer have a language server and the root path
10852    // for the stopped server
10853    fn stop_local_language_server(
10854        &mut self,
10855        server_id: LanguageServerId,
10856        cx: &mut Context<Self>,
10857    ) -> Task<()> {
10858        let local = match &mut self.mode {
10859            LspStoreMode::Local(local) => local,
10860            _ => {
10861                return Task::ready(());
10862            }
10863        };
10864
10865        // Remove this server ID from all entries in the given worktree.
10866        local
10867            .language_server_ids
10868            .retain(|_, state| state.id != server_id);
10869        self.buffer_store.update(cx, |buffer_store, cx| {
10870            for buffer in buffer_store.buffers() {
10871                buffer.update(cx, |buffer, cx| {
10872                    buffer.update_diagnostics(server_id, DiagnosticSet::new([], buffer), cx);
10873                    buffer.set_completion_triggers(server_id, Default::default(), cx);
10874                });
10875            }
10876        });
10877
10878        for (worktree_id, summaries) in self.diagnostic_summaries.iter_mut() {
10879            summaries.retain(|path, summaries_by_server_id| {
10880                if summaries_by_server_id.remove(&server_id).is_some() {
10881                    if let Some((client, project_id)) = self.downstream_client.clone() {
10882                        client
10883                            .send(proto::UpdateDiagnosticSummary {
10884                                project_id,
10885                                worktree_id: worktree_id.to_proto(),
10886                                summary: Some(proto::DiagnosticSummary {
10887                                    path: path.as_ref().to_proto(),
10888                                    language_server_id: server_id.0 as u64,
10889                                    error_count: 0,
10890                                    warning_count: 0,
10891                                }),
10892                                more_summaries: Vec::new(),
10893                            })
10894                            .log_err();
10895                    }
10896                    !summaries_by_server_id.is_empty()
10897                } else {
10898                    true
10899                }
10900            });
10901        }
10902
10903        let local = self.as_local_mut().unwrap();
10904        for diagnostics in local.diagnostics.values_mut() {
10905            diagnostics.retain(|_, diagnostics_by_server_id| {
10906                if let Ok(ix) = diagnostics_by_server_id.binary_search_by_key(&server_id, |e| e.0) {
10907                    diagnostics_by_server_id.remove(ix);
10908                    !diagnostics_by_server_id.is_empty()
10909                } else {
10910                    true
10911                }
10912            });
10913        }
10914        local.language_server_watched_paths.remove(&server_id);
10915
10916        let server_state = local.language_servers.remove(&server_id);
10917        self.cleanup_lsp_data(server_id);
10918        let name = self
10919            .language_server_statuses
10920            .remove(&server_id)
10921            .map(|status| status.name)
10922            .or_else(|| {
10923                if let Some(LanguageServerState::Running { adapter, .. }) = server_state.as_ref() {
10924                    Some(adapter.name())
10925                } else {
10926                    None
10927                }
10928            });
10929
10930        if let Some(name) = name {
10931            log::info!("stopping language server {name}");
10932            self.languages
10933                .update_lsp_binary_status(name.clone(), BinaryStatus::Stopping);
10934            cx.notify();
10935
10936            return cx.spawn(async move |lsp_store, cx| {
10937                Self::shutdown_language_server(server_state, name.clone(), cx).await;
10938                lsp_store
10939                    .update(cx, |lsp_store, cx| {
10940                        lsp_store
10941                            .languages
10942                            .update_lsp_binary_status(name, BinaryStatus::Stopped);
10943                        cx.emit(LspStoreEvent::LanguageServerRemoved(server_id));
10944                        cx.notify();
10945                    })
10946                    .ok();
10947            });
10948        }
10949
10950        if server_state.is_some() {
10951            cx.emit(LspStoreEvent::LanguageServerRemoved(server_id));
10952        }
10953        Task::ready(())
10954    }
10955
10956    pub fn stop_all_language_servers(&mut self, cx: &mut Context<Self>) {
10957        if let Some((client, project_id)) = self.upstream_client() {
10958            let request = client.request(proto::StopLanguageServers {
10959                project_id,
10960                buffer_ids: Vec::new(),
10961                also_servers: Vec::new(),
10962                all: true,
10963            });
10964            cx.background_spawn(request).detach_and_log_err(cx);
10965        } else {
10966            let Some(local) = self.as_local_mut() else {
10967                return;
10968            };
10969            let language_servers_to_stop = local
10970                .language_server_ids
10971                .values()
10972                .map(|state| state.id)
10973                .collect();
10974            local.lsp_tree.remove_nodes(&language_servers_to_stop);
10975            let tasks = language_servers_to_stop
10976                .into_iter()
10977                .map(|server| self.stop_local_language_server(server, cx))
10978                .collect::<Vec<_>>();
10979            cx.background_spawn(async move {
10980                futures::future::join_all(tasks).await;
10981            })
10982            .detach();
10983        }
10984    }
10985
10986    pub fn restart_language_servers_for_buffers(
10987        &mut self,
10988        buffers: Vec<Entity<Buffer>>,
10989        only_restart_servers: HashSet<LanguageServerSelector>,
10990        cx: &mut Context<Self>,
10991    ) {
10992        if let Some((client, project_id)) = self.upstream_client() {
10993            let request = client.request(proto::RestartLanguageServers {
10994                project_id,
10995                buffer_ids: buffers
10996                    .into_iter()
10997                    .map(|b| b.read(cx).remote_id().to_proto())
10998                    .collect(),
10999                only_servers: only_restart_servers
11000                    .into_iter()
11001                    .map(|selector| {
11002                        let selector = match selector {
11003                            LanguageServerSelector::Id(language_server_id) => {
11004                                proto::language_server_selector::Selector::ServerId(
11005                                    language_server_id.to_proto(),
11006                                )
11007                            }
11008                            LanguageServerSelector::Name(language_server_name) => {
11009                                proto::language_server_selector::Selector::Name(
11010                                    language_server_name.to_string(),
11011                                )
11012                            }
11013                        };
11014                        proto::LanguageServerSelector {
11015                            selector: Some(selector),
11016                        }
11017                    })
11018                    .collect(),
11019                all: false,
11020            });
11021            cx.background_spawn(request).detach_and_log_err(cx);
11022        } else {
11023            let stop_task = if only_restart_servers.is_empty() {
11024                self.stop_local_language_servers_for_buffers(&buffers, HashSet::default(), cx)
11025            } else {
11026                self.stop_local_language_servers_for_buffers(&[], only_restart_servers.clone(), cx)
11027            };
11028            cx.spawn(async move |lsp_store, cx| {
11029                stop_task.await;
11030                lsp_store
11031                    .update(cx, |lsp_store, cx| {
11032                        for buffer in buffers {
11033                            lsp_store.register_buffer_with_language_servers(
11034                                &buffer,
11035                                only_restart_servers.clone(),
11036                                true,
11037                                cx,
11038                            );
11039                        }
11040                    })
11041                    .ok()
11042            })
11043            .detach();
11044        }
11045    }
11046
11047    pub fn stop_language_servers_for_buffers(
11048        &mut self,
11049        buffers: Vec<Entity<Buffer>>,
11050        also_stop_servers: HashSet<LanguageServerSelector>,
11051        cx: &mut Context<Self>,
11052    ) -> Task<Result<()>> {
11053        if let Some((client, project_id)) = self.upstream_client() {
11054            let request = client.request(proto::StopLanguageServers {
11055                project_id,
11056                buffer_ids: buffers
11057                    .into_iter()
11058                    .map(|b| b.read(cx).remote_id().to_proto())
11059                    .collect(),
11060                also_servers: also_stop_servers
11061                    .into_iter()
11062                    .map(|selector| {
11063                        let selector = match selector {
11064                            LanguageServerSelector::Id(language_server_id) => {
11065                                proto::language_server_selector::Selector::ServerId(
11066                                    language_server_id.to_proto(),
11067                                )
11068                            }
11069                            LanguageServerSelector::Name(language_server_name) => {
11070                                proto::language_server_selector::Selector::Name(
11071                                    language_server_name.to_string(),
11072                                )
11073                            }
11074                        };
11075                        proto::LanguageServerSelector {
11076                            selector: Some(selector),
11077                        }
11078                    })
11079                    .collect(),
11080                all: false,
11081            });
11082            cx.background_spawn(async move {
11083                let _ = request.await?;
11084                Ok(())
11085            })
11086        } else {
11087            let task =
11088                self.stop_local_language_servers_for_buffers(&buffers, also_stop_servers, cx);
11089            cx.background_spawn(async move {
11090                task.await;
11091                Ok(())
11092            })
11093        }
11094    }
11095
11096    fn stop_local_language_servers_for_buffers(
11097        &mut self,
11098        buffers: &[Entity<Buffer>],
11099        also_stop_servers: HashSet<LanguageServerSelector>,
11100        cx: &mut Context<Self>,
11101    ) -> Task<()> {
11102        let Some(local) = self.as_local_mut() else {
11103            return Task::ready(());
11104        };
11105        let mut language_server_names_to_stop = BTreeSet::default();
11106        let mut language_servers_to_stop = also_stop_servers
11107            .into_iter()
11108            .flat_map(|selector| match selector {
11109                LanguageServerSelector::Id(id) => Some(id),
11110                LanguageServerSelector::Name(name) => {
11111                    language_server_names_to_stop.insert(name);
11112                    None
11113                }
11114            })
11115            .collect::<BTreeSet<_>>();
11116
11117        let mut covered_worktrees = HashSet::default();
11118        for buffer in buffers {
11119            buffer.update(cx, |buffer, cx| {
11120                language_servers_to_stop.extend(local.language_server_ids_for_buffer(buffer, cx));
11121                if let Some(worktree_id) = buffer.file().map(|f| f.worktree_id(cx))
11122                    && covered_worktrees.insert(worktree_id)
11123                {
11124                    language_server_names_to_stop.retain(|name| {
11125                        let old_ids_count = language_servers_to_stop.len();
11126                        let all_language_servers_with_this_name = local
11127                            .language_server_ids
11128                            .iter()
11129                            .filter_map(|(seed, state)| seed.name.eq(name).then(|| state.id));
11130                        language_servers_to_stop.extend(all_language_servers_with_this_name);
11131                        old_ids_count == language_servers_to_stop.len()
11132                    });
11133                }
11134            });
11135        }
11136        for name in language_server_names_to_stop {
11137            language_servers_to_stop.extend(
11138                local
11139                    .language_server_ids
11140                    .iter()
11141                    .filter_map(|(seed, v)| seed.name.eq(&name).then(|| v.id)),
11142            );
11143        }
11144
11145        local.lsp_tree.remove_nodes(&language_servers_to_stop);
11146        let tasks = language_servers_to_stop
11147            .into_iter()
11148            .map(|server| self.stop_local_language_server(server, cx))
11149            .collect::<Vec<_>>();
11150
11151        cx.background_spawn(futures::future::join_all(tasks).map(|_| ()))
11152    }
11153
11154    fn get_buffer<'a>(&self, abs_path: &Path, cx: &'a App) -> Option<&'a Buffer> {
11155        let (worktree, relative_path) =
11156            self.worktree_store.read(cx).find_worktree(&abs_path, cx)?;
11157
11158        let project_path = ProjectPath {
11159            worktree_id: worktree.read(cx).id(),
11160            path: relative_path,
11161        };
11162
11163        Some(
11164            self.buffer_store()
11165                .read(cx)
11166                .get_by_path(&project_path)?
11167                .read(cx),
11168        )
11169    }
11170
11171    #[cfg(any(test, feature = "test-support"))]
11172    pub fn update_diagnostics(
11173        &mut self,
11174        server_id: LanguageServerId,
11175        diagnostics: lsp::PublishDiagnosticsParams,
11176        result_id: Option<SharedString>,
11177        source_kind: DiagnosticSourceKind,
11178        disk_based_sources: &[String],
11179        cx: &mut Context<Self>,
11180    ) -> Result<()> {
11181        self.merge_lsp_diagnostics(
11182            source_kind,
11183            vec![DocumentDiagnosticsUpdate {
11184                diagnostics,
11185                result_id,
11186                server_id,
11187                disk_based_sources: Cow::Borrowed(disk_based_sources),
11188                registration_id: None,
11189            }],
11190            |_, _, _| false,
11191            cx,
11192        )
11193    }
11194
11195    pub fn merge_lsp_diagnostics(
11196        &mut self,
11197        source_kind: DiagnosticSourceKind,
11198        lsp_diagnostics: Vec<DocumentDiagnosticsUpdate<lsp::PublishDiagnosticsParams>>,
11199        merge: impl Fn(&lsp::Uri, &Diagnostic, &App) -> bool + Clone,
11200        cx: &mut Context<Self>,
11201    ) -> Result<()> {
11202        anyhow::ensure!(self.mode.is_local(), "called update_diagnostics on remote");
11203        let updates = lsp_diagnostics
11204            .into_iter()
11205            .filter_map(|update| {
11206                let abs_path = update.diagnostics.uri.to_file_path().ok()?;
11207                Some(DocumentDiagnosticsUpdate {
11208                    diagnostics: self.lsp_to_document_diagnostics(
11209                        abs_path,
11210                        source_kind,
11211                        update.server_id,
11212                        update.diagnostics,
11213                        &update.disk_based_sources,
11214                        update.registration_id.clone(),
11215                    ),
11216                    result_id: update.result_id,
11217                    server_id: update.server_id,
11218                    disk_based_sources: update.disk_based_sources,
11219                    registration_id: update.registration_id,
11220                })
11221            })
11222            .collect();
11223        self.merge_diagnostic_entries(updates, merge, cx)?;
11224        Ok(())
11225    }
11226
11227    fn lsp_to_document_diagnostics(
11228        &mut self,
11229        document_abs_path: PathBuf,
11230        source_kind: DiagnosticSourceKind,
11231        server_id: LanguageServerId,
11232        mut lsp_diagnostics: lsp::PublishDiagnosticsParams,
11233        disk_based_sources: &[String],
11234        registration_id: Option<SharedString>,
11235    ) -> DocumentDiagnostics {
11236        let mut diagnostics = Vec::default();
11237        let mut primary_diagnostic_group_ids = HashMap::default();
11238        let mut sources_by_group_id = HashMap::default();
11239        let mut supporting_diagnostics = HashMap::default();
11240
11241        let adapter = self.language_server_adapter_for_id(server_id);
11242
11243        // Ensure that primary diagnostics are always the most severe
11244        lsp_diagnostics
11245            .diagnostics
11246            .sort_by_key(|item| item.severity);
11247
11248        for diagnostic in &lsp_diagnostics.diagnostics {
11249            let source = diagnostic.source.as_ref();
11250            let range = range_from_lsp(diagnostic.range);
11251            let is_supporting = diagnostic
11252                .related_information
11253                .as_ref()
11254                .is_some_and(|infos| {
11255                    infos.iter().any(|info| {
11256                        primary_diagnostic_group_ids.contains_key(&(
11257                            source,
11258                            diagnostic.code.clone(),
11259                            range_from_lsp(info.location.range),
11260                        ))
11261                    })
11262                });
11263
11264            let is_unnecessary = diagnostic
11265                .tags
11266                .as_ref()
11267                .is_some_and(|tags| tags.contains(&DiagnosticTag::UNNECESSARY));
11268
11269            let underline = self
11270                .language_server_adapter_for_id(server_id)
11271                .is_none_or(|adapter| adapter.underline_diagnostic(diagnostic));
11272
11273            if is_supporting {
11274                supporting_diagnostics.insert(
11275                    (source, diagnostic.code.clone(), range),
11276                    (diagnostic.severity, is_unnecessary),
11277                );
11278            } else {
11279                let group_id = post_inc(&mut self.as_local_mut().unwrap().next_diagnostic_group_id);
11280                let is_disk_based =
11281                    source.is_some_and(|source| disk_based_sources.contains(source));
11282
11283                sources_by_group_id.insert(group_id, source);
11284                primary_diagnostic_group_ids
11285                    .insert((source, diagnostic.code.clone(), range.clone()), group_id);
11286
11287                diagnostics.push(DiagnosticEntry {
11288                    range,
11289                    diagnostic: Diagnostic {
11290                        source: diagnostic.source.clone(),
11291                        source_kind,
11292                        code: diagnostic.code.clone(),
11293                        code_description: diagnostic
11294                            .code_description
11295                            .as_ref()
11296                            .and_then(|d| d.href.clone()),
11297                        severity: diagnostic.severity.unwrap_or(DiagnosticSeverity::ERROR),
11298                        markdown: adapter.as_ref().and_then(|adapter| {
11299                            adapter.diagnostic_message_to_markdown(&diagnostic.message)
11300                        }),
11301                        message: diagnostic.message.trim().to_string(),
11302                        group_id,
11303                        is_primary: true,
11304                        is_disk_based,
11305                        is_unnecessary,
11306                        underline,
11307                        data: diagnostic.data.clone(),
11308                        registration_id: registration_id.clone(),
11309                    },
11310                });
11311                if let Some(infos) = &diagnostic.related_information {
11312                    for info in infos {
11313                        if info.location.uri == lsp_diagnostics.uri && !info.message.is_empty() {
11314                            let range = range_from_lsp(info.location.range);
11315                            diagnostics.push(DiagnosticEntry {
11316                                range,
11317                                diagnostic: Diagnostic {
11318                                    source: diagnostic.source.clone(),
11319                                    source_kind,
11320                                    code: diagnostic.code.clone(),
11321                                    code_description: diagnostic
11322                                        .code_description
11323                                        .as_ref()
11324                                        .and_then(|d| d.href.clone()),
11325                                    severity: DiagnosticSeverity::INFORMATION,
11326                                    markdown: adapter.as_ref().and_then(|adapter| {
11327                                        adapter.diagnostic_message_to_markdown(&info.message)
11328                                    }),
11329                                    message: info.message.trim().to_string(),
11330                                    group_id,
11331                                    is_primary: false,
11332                                    is_disk_based,
11333                                    is_unnecessary: false,
11334                                    underline,
11335                                    data: diagnostic.data.clone(),
11336                                    registration_id: registration_id.clone(),
11337                                },
11338                            });
11339                        }
11340                    }
11341                }
11342            }
11343        }
11344
11345        for entry in &mut diagnostics {
11346            let diagnostic = &mut entry.diagnostic;
11347            if !diagnostic.is_primary {
11348                let source = *sources_by_group_id.get(&diagnostic.group_id).unwrap();
11349                if let Some(&(severity, is_unnecessary)) = supporting_diagnostics.get(&(
11350                    source,
11351                    diagnostic.code.clone(),
11352                    entry.range.clone(),
11353                )) {
11354                    if let Some(severity) = severity {
11355                        diagnostic.severity = severity;
11356                    }
11357                    diagnostic.is_unnecessary = is_unnecessary;
11358                }
11359            }
11360        }
11361
11362        DocumentDiagnostics {
11363            diagnostics,
11364            document_abs_path,
11365            version: lsp_diagnostics.version,
11366        }
11367    }
11368
11369    fn insert_newly_running_language_server(
11370        &mut self,
11371        adapter: Arc<CachedLspAdapter>,
11372        language_server: Arc<LanguageServer>,
11373        server_id: LanguageServerId,
11374        key: LanguageServerSeed,
11375        workspace_folders: Arc<Mutex<BTreeSet<Uri>>>,
11376        cx: &mut Context<Self>,
11377    ) {
11378        let Some(local) = self.as_local_mut() else {
11379            return;
11380        };
11381        // If the language server for this key doesn't match the server id, don't store the
11382        // server. Which will cause it to be dropped, killing the process
11383        if local
11384            .language_server_ids
11385            .get(&key)
11386            .map(|state| state.id != server_id)
11387            .unwrap_or(false)
11388        {
11389            return;
11390        }
11391
11392        // Update language_servers collection with Running variant of LanguageServerState
11393        // indicating that the server is up and running and ready
11394        let workspace_folders = workspace_folders.lock().clone();
11395        language_server.set_workspace_folders(workspace_folders);
11396
11397        let workspace_diagnostics_refresh_tasks = language_server
11398            .capabilities()
11399            .diagnostic_provider
11400            .and_then(|provider| {
11401                local
11402                    .language_server_dynamic_registrations
11403                    .entry(server_id)
11404                    .or_default()
11405                    .diagnostics
11406                    .entry(None)
11407                    .or_insert(provider.clone());
11408                let workspace_refresher =
11409                    lsp_workspace_diagnostics_refresh(None, provider, language_server.clone(), cx)?;
11410
11411                Some((None, workspace_refresher))
11412            })
11413            .into_iter()
11414            .collect();
11415        local.language_servers.insert(
11416            server_id,
11417            LanguageServerState::Running {
11418                workspace_diagnostics_refresh_tasks,
11419                adapter: adapter.clone(),
11420                server: language_server.clone(),
11421                simulate_disk_based_diagnostics_completion: None,
11422            },
11423        );
11424        local
11425            .languages
11426            .update_lsp_binary_status(adapter.name(), BinaryStatus::None);
11427        if let Some(file_ops_caps) = language_server
11428            .capabilities()
11429            .workspace
11430            .as_ref()
11431            .and_then(|ws| ws.file_operations.as_ref())
11432        {
11433            let did_rename_caps = file_ops_caps.did_rename.as_ref();
11434            let will_rename_caps = file_ops_caps.will_rename.as_ref();
11435            if did_rename_caps.or(will_rename_caps).is_some() {
11436                let watcher = RenamePathsWatchedForServer::default()
11437                    .with_did_rename_patterns(did_rename_caps)
11438                    .with_will_rename_patterns(will_rename_caps);
11439                local
11440                    .language_server_paths_watched_for_rename
11441                    .insert(server_id, watcher);
11442            }
11443        }
11444
11445        self.language_server_statuses.insert(
11446            server_id,
11447            LanguageServerStatus {
11448                name: language_server.name(),
11449                pending_work: Default::default(),
11450                has_pending_diagnostic_updates: false,
11451                progress_tokens: Default::default(),
11452                worktree: Some(key.worktree_id),
11453                binary: Some(language_server.binary().clone()),
11454                configuration: Some(language_server.configuration().clone()),
11455                workspace_folders: language_server.workspace_folders(),
11456            },
11457        );
11458
11459        cx.emit(LspStoreEvent::LanguageServerAdded(
11460            server_id,
11461            language_server.name(),
11462            Some(key.worktree_id),
11463        ));
11464
11465        let server_capabilities = language_server.capabilities();
11466        if let Some((downstream_client, project_id)) = self.downstream_client.as_ref() {
11467            downstream_client
11468                .send(proto::StartLanguageServer {
11469                    project_id: *project_id,
11470                    server: Some(proto::LanguageServer {
11471                        id: server_id.to_proto(),
11472                        name: language_server.name().to_string(),
11473                        worktree_id: Some(key.worktree_id.to_proto()),
11474                    }),
11475                    capabilities: serde_json::to_string(&server_capabilities)
11476                        .expect("serializing server LSP capabilities"),
11477                })
11478                .log_err();
11479        }
11480        self.lsp_server_capabilities
11481            .insert(server_id, server_capabilities);
11482
11483        // Tell the language server about every open buffer in the worktree that matches the language.
11484        // Also check for buffers in worktrees that reused this server
11485        let mut worktrees_using_server = vec![key.worktree_id];
11486        if let Some(local) = self.as_local() {
11487            // Find all worktrees that have this server in their language server tree
11488            for (worktree_id, servers) in &local.lsp_tree.instances {
11489                if *worktree_id != key.worktree_id {
11490                    for server_map in servers.roots.values() {
11491                        if server_map
11492                            .values()
11493                            .any(|(node, _)| node.id() == Some(server_id))
11494                        {
11495                            worktrees_using_server.push(*worktree_id);
11496                        }
11497                    }
11498                }
11499            }
11500        }
11501
11502        let mut buffer_paths_registered = Vec::new();
11503        self.buffer_store.clone().update(cx, |buffer_store, cx| {
11504            let mut lsp_adapters = HashMap::default();
11505            for buffer_handle in buffer_store.buffers() {
11506                let buffer = buffer_handle.read(cx);
11507                let file = match File::from_dyn(buffer.file()) {
11508                    Some(file) => file,
11509                    None => continue,
11510                };
11511                let language = match buffer.language() {
11512                    Some(language) => language,
11513                    None => continue,
11514                };
11515
11516                if !worktrees_using_server.contains(&file.worktree.read(cx).id())
11517                    || !lsp_adapters
11518                        .entry(language.name())
11519                        .or_insert_with(|| self.languages.lsp_adapters(&language.name()))
11520                        .iter()
11521                        .any(|a| a.name == key.name)
11522                {
11523                    continue;
11524                }
11525                // didOpen
11526                let file = match file.as_local() {
11527                    Some(file) => file,
11528                    None => continue,
11529                };
11530
11531                let local = self.as_local_mut().unwrap();
11532
11533                let buffer_id = buffer.remote_id();
11534                if local.registered_buffers.contains_key(&buffer_id) {
11535                    let versions = local
11536                        .buffer_snapshots
11537                        .entry(buffer_id)
11538                        .or_default()
11539                        .entry(server_id)
11540                        .and_modify(|_| {
11541                            assert!(
11542                            false,
11543                            "There should not be an existing snapshot for a newly inserted buffer"
11544                        )
11545                        })
11546                        .or_insert_with(|| {
11547                            vec![LspBufferSnapshot {
11548                                version: 0,
11549                                snapshot: buffer.text_snapshot(),
11550                            }]
11551                        });
11552
11553                    let snapshot = versions.last().unwrap();
11554                    let version = snapshot.version;
11555                    let initial_snapshot = &snapshot.snapshot;
11556                    let uri = lsp::Uri::from_file_path(file.abs_path(cx)).unwrap();
11557                    language_server.register_buffer(
11558                        uri,
11559                        adapter.language_id(&language.name()),
11560                        version,
11561                        initial_snapshot.text(),
11562                    );
11563                    buffer_paths_registered.push((buffer_id, file.abs_path(cx)));
11564                    local
11565                        .buffers_opened_in_servers
11566                        .entry(buffer_id)
11567                        .or_default()
11568                        .insert(server_id);
11569                }
11570                buffer_handle.update(cx, |buffer, cx| {
11571                    buffer.set_completion_triggers(
11572                        server_id,
11573                        language_server
11574                            .capabilities()
11575                            .completion_provider
11576                            .as_ref()
11577                            .and_then(|provider| {
11578                                provider
11579                                    .trigger_characters
11580                                    .as_ref()
11581                                    .map(|characters| characters.iter().cloned().collect())
11582                            })
11583                            .unwrap_or_default(),
11584                        cx,
11585                    )
11586                });
11587            }
11588        });
11589
11590        for (buffer_id, abs_path) in buffer_paths_registered {
11591            cx.emit(LspStoreEvent::LanguageServerUpdate {
11592                language_server_id: server_id,
11593                name: Some(adapter.name()),
11594                message: proto::update_language_server::Variant::RegisteredForBuffer(
11595                    proto::RegisteredForBuffer {
11596                        buffer_abs_path: abs_path.to_string_lossy().into_owned(),
11597                        buffer_id: buffer_id.to_proto(),
11598                    },
11599                ),
11600            });
11601        }
11602
11603        cx.notify();
11604    }
11605
11606    pub fn language_servers_running_disk_based_diagnostics(
11607        &self,
11608    ) -> impl Iterator<Item = LanguageServerId> + '_ {
11609        self.language_server_statuses
11610            .iter()
11611            .filter_map(|(id, status)| {
11612                if status.has_pending_diagnostic_updates {
11613                    Some(*id)
11614                } else {
11615                    None
11616                }
11617            })
11618    }
11619
11620    pub(crate) fn cancel_language_server_work_for_buffers(
11621        &mut self,
11622        buffers: impl IntoIterator<Item = Entity<Buffer>>,
11623        cx: &mut Context<Self>,
11624    ) {
11625        if let Some((client, project_id)) = self.upstream_client() {
11626            let request = client.request(proto::CancelLanguageServerWork {
11627                project_id,
11628                work: Some(proto::cancel_language_server_work::Work::Buffers(
11629                    proto::cancel_language_server_work::Buffers {
11630                        buffer_ids: buffers
11631                            .into_iter()
11632                            .map(|b| b.read(cx).remote_id().to_proto())
11633                            .collect(),
11634                    },
11635                )),
11636            });
11637            cx.background_spawn(request).detach_and_log_err(cx);
11638        } else if let Some(local) = self.as_local() {
11639            let servers = buffers
11640                .into_iter()
11641                .flat_map(|buffer| {
11642                    buffer.update(cx, |buffer, cx| {
11643                        local.language_server_ids_for_buffer(buffer, cx).into_iter()
11644                    })
11645                })
11646                .collect::<HashSet<_>>();
11647            for server_id in servers {
11648                self.cancel_language_server_work(server_id, None, cx);
11649            }
11650        }
11651    }
11652
11653    pub(crate) fn cancel_language_server_work(
11654        &mut self,
11655        server_id: LanguageServerId,
11656        token_to_cancel: Option<ProgressToken>,
11657        cx: &mut Context<Self>,
11658    ) {
11659        if let Some(local) = self.as_local() {
11660            let status = self.language_server_statuses.get(&server_id);
11661            let server = local.language_servers.get(&server_id);
11662            if let Some((LanguageServerState::Running { server, .. }, status)) = server.zip(status)
11663            {
11664                for (token, progress) in &status.pending_work {
11665                    if let Some(token_to_cancel) = token_to_cancel.as_ref()
11666                        && token != token_to_cancel
11667                    {
11668                        continue;
11669                    }
11670                    if progress.is_cancellable {
11671                        server
11672                            .notify::<lsp::notification::WorkDoneProgressCancel>(
11673                                WorkDoneProgressCancelParams {
11674                                    token: token.to_lsp(),
11675                                },
11676                            )
11677                            .ok();
11678                    }
11679                }
11680            }
11681        } else if let Some((client, project_id)) = self.upstream_client() {
11682            let request = client.request(proto::CancelLanguageServerWork {
11683                project_id,
11684                work: Some(
11685                    proto::cancel_language_server_work::Work::LanguageServerWork(
11686                        proto::cancel_language_server_work::LanguageServerWork {
11687                            language_server_id: server_id.to_proto(),
11688                            token: token_to_cancel.map(|token| token.to_proto()),
11689                        },
11690                    ),
11691                ),
11692            });
11693            cx.background_spawn(request).detach_and_log_err(cx);
11694        }
11695    }
11696
11697    fn register_supplementary_language_server(
11698        &mut self,
11699        id: LanguageServerId,
11700        name: LanguageServerName,
11701        server: Arc<LanguageServer>,
11702        cx: &mut Context<Self>,
11703    ) {
11704        if let Some(local) = self.as_local_mut() {
11705            local
11706                .supplementary_language_servers
11707                .insert(id, (name.clone(), server));
11708            cx.emit(LspStoreEvent::LanguageServerAdded(id, name, None));
11709        }
11710    }
11711
11712    fn unregister_supplementary_language_server(
11713        &mut self,
11714        id: LanguageServerId,
11715        cx: &mut Context<Self>,
11716    ) {
11717        if let Some(local) = self.as_local_mut() {
11718            local.supplementary_language_servers.remove(&id);
11719            cx.emit(LspStoreEvent::LanguageServerRemoved(id));
11720        }
11721    }
11722
11723    pub(crate) fn supplementary_language_servers(
11724        &self,
11725    ) -> impl '_ + Iterator<Item = (LanguageServerId, LanguageServerName)> {
11726        self.as_local().into_iter().flat_map(|local| {
11727            local
11728                .supplementary_language_servers
11729                .iter()
11730                .map(|(id, (name, _))| (*id, name.clone()))
11731        })
11732    }
11733
11734    pub fn language_server_adapter_for_id(
11735        &self,
11736        id: LanguageServerId,
11737    ) -> Option<Arc<CachedLspAdapter>> {
11738        self.as_local()
11739            .and_then(|local| local.language_servers.get(&id))
11740            .and_then(|language_server_state| match language_server_state {
11741                LanguageServerState::Running { adapter, .. } => Some(adapter.clone()),
11742                _ => None,
11743            })
11744    }
11745
11746    pub(super) fn update_local_worktree_language_servers(
11747        &mut self,
11748        worktree_handle: &Entity<Worktree>,
11749        changes: &[(Arc<RelPath>, ProjectEntryId, PathChange)],
11750        cx: &mut Context<Self>,
11751    ) {
11752        if changes.is_empty() {
11753            return;
11754        }
11755
11756        let Some(local) = self.as_local() else { return };
11757
11758        local.prettier_store.update(cx, |prettier_store, cx| {
11759            prettier_store.update_prettier_settings(worktree_handle, changes, cx)
11760        });
11761
11762        let worktree_id = worktree_handle.read(cx).id();
11763        let mut language_server_ids = local
11764            .language_server_ids
11765            .iter()
11766            .filter_map(|(seed, v)| seed.worktree_id.eq(&worktree_id).then(|| v.id))
11767            .collect::<Vec<_>>();
11768        language_server_ids.sort();
11769        language_server_ids.dedup();
11770
11771        // let abs_path = worktree_handle.read(cx).abs_path();
11772        for server_id in &language_server_ids {
11773            if let Some(LanguageServerState::Running { server, .. }) =
11774                local.language_servers.get(server_id)
11775                && let Some(watched_paths) = local
11776                    .language_server_watched_paths
11777                    .get(server_id)
11778                    .and_then(|paths| paths.worktree_paths.get(&worktree_id))
11779            {
11780                let params = lsp::DidChangeWatchedFilesParams {
11781                    changes: changes
11782                        .iter()
11783                        .filter_map(|(path, _, change)| {
11784                            if !watched_paths.is_match(path.as_std_path()) {
11785                                return None;
11786                            }
11787                            let typ = match change {
11788                                PathChange::Loaded => return None,
11789                                PathChange::Added => lsp::FileChangeType::CREATED,
11790                                PathChange::Removed => lsp::FileChangeType::DELETED,
11791                                PathChange::Updated => lsp::FileChangeType::CHANGED,
11792                                PathChange::AddedOrUpdated => lsp::FileChangeType::CHANGED,
11793                            };
11794                            let uri = lsp::Uri::from_file_path(
11795                                worktree_handle.read(cx).absolutize(&path),
11796                            )
11797                            .ok()?;
11798                            Some(lsp::FileEvent { uri, typ })
11799                        })
11800                        .collect(),
11801                };
11802                if !params.changes.is_empty() {
11803                    server
11804                        .notify::<lsp::notification::DidChangeWatchedFiles>(params)
11805                        .ok();
11806                }
11807            }
11808        }
11809        for (path, _, _) in changes {
11810            if let Some(file_name) = path.file_name()
11811                && local.watched_manifest_filenames.contains(file_name)
11812            {
11813                self.request_workspace_config_refresh();
11814                break;
11815            }
11816        }
11817    }
11818
11819    pub fn wait_for_remote_buffer(
11820        &mut self,
11821        id: BufferId,
11822        cx: &mut Context<Self>,
11823    ) -> Task<Result<Entity<Buffer>>> {
11824        self.buffer_store.update(cx, |buffer_store, cx| {
11825            buffer_store.wait_for_remote_buffer(id, cx)
11826        })
11827    }
11828
11829    fn serialize_symbol(symbol: &Symbol) -> proto::Symbol {
11830        let mut result = proto::Symbol {
11831            language_server_name: symbol.language_server_name.0.to_string(),
11832            source_worktree_id: symbol.source_worktree_id.to_proto(),
11833            language_server_id: symbol.source_language_server_id.to_proto(),
11834            name: symbol.name.clone(),
11835            kind: unsafe { mem::transmute::<lsp::SymbolKind, i32>(symbol.kind) },
11836            start: Some(proto::PointUtf16 {
11837                row: symbol.range.start.0.row,
11838                column: symbol.range.start.0.column,
11839            }),
11840            end: Some(proto::PointUtf16 {
11841                row: symbol.range.end.0.row,
11842                column: symbol.range.end.0.column,
11843            }),
11844            worktree_id: Default::default(),
11845            path: Default::default(),
11846            signature: Default::default(),
11847        };
11848        match &symbol.path {
11849            SymbolLocation::InProject(path) => {
11850                result.worktree_id = path.worktree_id.to_proto();
11851                result.path = path.path.to_proto();
11852            }
11853            SymbolLocation::OutsideProject {
11854                abs_path,
11855                signature,
11856            } => {
11857                result.path = abs_path.to_string_lossy().into_owned();
11858                result.signature = signature.to_vec();
11859            }
11860        }
11861        result
11862    }
11863
11864    fn deserialize_symbol(serialized_symbol: proto::Symbol) -> Result<CoreSymbol> {
11865        let source_worktree_id = WorktreeId::from_proto(serialized_symbol.source_worktree_id);
11866        let worktree_id = WorktreeId::from_proto(serialized_symbol.worktree_id);
11867        let kind = unsafe { mem::transmute::<i32, lsp::SymbolKind>(serialized_symbol.kind) };
11868
11869        let path = if serialized_symbol.signature.is_empty() {
11870            SymbolLocation::InProject(ProjectPath {
11871                worktree_id,
11872                path: RelPath::from_proto(&serialized_symbol.path)
11873                    .context("invalid symbol path")?,
11874            })
11875        } else {
11876            SymbolLocation::OutsideProject {
11877                abs_path: Path::new(&serialized_symbol.path).into(),
11878                signature: serialized_symbol
11879                    .signature
11880                    .try_into()
11881                    .map_err(|_| anyhow!("invalid signature"))?,
11882            }
11883        };
11884
11885        let start = serialized_symbol.start.context("invalid start")?;
11886        let end = serialized_symbol.end.context("invalid end")?;
11887        Ok(CoreSymbol {
11888            language_server_name: LanguageServerName(serialized_symbol.language_server_name.into()),
11889            source_worktree_id,
11890            source_language_server_id: LanguageServerId::from_proto(
11891                serialized_symbol.language_server_id,
11892            ),
11893            path,
11894            name: serialized_symbol.name,
11895            range: Unclipped(PointUtf16::new(start.row, start.column))
11896                ..Unclipped(PointUtf16::new(end.row, end.column)),
11897            kind,
11898        })
11899    }
11900
11901    pub(crate) fn serialize_completion(completion: &CoreCompletion) -> proto::Completion {
11902        let mut serialized_completion = proto::Completion {
11903            old_replace_start: Some(serialize_anchor(&completion.replace_range.start)),
11904            old_replace_end: Some(serialize_anchor(&completion.replace_range.end)),
11905            new_text: completion.new_text.clone(),
11906            ..proto::Completion::default()
11907        };
11908        match &completion.source {
11909            CompletionSource::Lsp {
11910                insert_range,
11911                server_id,
11912                lsp_completion,
11913                lsp_defaults,
11914                resolved,
11915            } => {
11916                let (old_insert_start, old_insert_end) = insert_range
11917                    .as_ref()
11918                    .map(|range| (serialize_anchor(&range.start), serialize_anchor(&range.end)))
11919                    .unzip();
11920
11921                serialized_completion.old_insert_start = old_insert_start;
11922                serialized_completion.old_insert_end = old_insert_end;
11923                serialized_completion.source = proto::completion::Source::Lsp as i32;
11924                serialized_completion.server_id = server_id.0 as u64;
11925                serialized_completion.lsp_completion = serde_json::to_vec(lsp_completion).unwrap();
11926                serialized_completion.lsp_defaults = lsp_defaults
11927                    .as_deref()
11928                    .map(|lsp_defaults| serde_json::to_vec(lsp_defaults).unwrap());
11929                serialized_completion.resolved = *resolved;
11930            }
11931            CompletionSource::BufferWord {
11932                word_range,
11933                resolved,
11934            } => {
11935                serialized_completion.source = proto::completion::Source::BufferWord as i32;
11936                serialized_completion.buffer_word_start = Some(serialize_anchor(&word_range.start));
11937                serialized_completion.buffer_word_end = Some(serialize_anchor(&word_range.end));
11938                serialized_completion.resolved = *resolved;
11939            }
11940            CompletionSource::Custom => {
11941                serialized_completion.source = proto::completion::Source::Custom as i32;
11942                serialized_completion.resolved = true;
11943            }
11944            CompletionSource::Dap { sort_text } => {
11945                serialized_completion.source = proto::completion::Source::Dap as i32;
11946                serialized_completion.sort_text = Some(sort_text.clone());
11947            }
11948        }
11949
11950        serialized_completion
11951    }
11952
11953    pub(crate) fn deserialize_completion(completion: proto::Completion) -> Result<CoreCompletion> {
11954        let old_replace_start = completion
11955            .old_replace_start
11956            .and_then(deserialize_anchor)
11957            .context("invalid old start")?;
11958        let old_replace_end = completion
11959            .old_replace_end
11960            .and_then(deserialize_anchor)
11961            .context("invalid old end")?;
11962        let insert_range = {
11963            match completion.old_insert_start.zip(completion.old_insert_end) {
11964                Some((start, end)) => {
11965                    let start = deserialize_anchor(start).context("invalid insert old start")?;
11966                    let end = deserialize_anchor(end).context("invalid insert old end")?;
11967                    Some(start..end)
11968                }
11969                None => None,
11970            }
11971        };
11972        Ok(CoreCompletion {
11973            replace_range: old_replace_start..old_replace_end,
11974            new_text: completion.new_text,
11975            source: match proto::completion::Source::from_i32(completion.source) {
11976                Some(proto::completion::Source::Custom) => CompletionSource::Custom,
11977                Some(proto::completion::Source::Lsp) => CompletionSource::Lsp {
11978                    insert_range,
11979                    server_id: LanguageServerId::from_proto(completion.server_id),
11980                    lsp_completion: serde_json::from_slice(&completion.lsp_completion)?,
11981                    lsp_defaults: completion
11982                        .lsp_defaults
11983                        .as_deref()
11984                        .map(serde_json::from_slice)
11985                        .transpose()?,
11986                    resolved: completion.resolved,
11987                },
11988                Some(proto::completion::Source::BufferWord) => {
11989                    let word_range = completion
11990                        .buffer_word_start
11991                        .and_then(deserialize_anchor)
11992                        .context("invalid buffer word start")?
11993                        ..completion
11994                            .buffer_word_end
11995                            .and_then(deserialize_anchor)
11996                            .context("invalid buffer word end")?;
11997                    CompletionSource::BufferWord {
11998                        word_range,
11999                        resolved: completion.resolved,
12000                    }
12001                }
12002                Some(proto::completion::Source::Dap) => CompletionSource::Dap {
12003                    sort_text: completion
12004                        .sort_text
12005                        .context("expected sort text to exist")?,
12006                },
12007                _ => anyhow::bail!("Unexpected completion source {}", completion.source),
12008            },
12009        })
12010    }
12011
12012    pub(crate) fn serialize_code_action(action: &CodeAction) -> proto::CodeAction {
12013        let (kind, lsp_action) = match &action.lsp_action {
12014            LspAction::Action(code_action) => (
12015                proto::code_action::Kind::Action as i32,
12016                serde_json::to_vec(code_action).unwrap(),
12017            ),
12018            LspAction::Command(command) => (
12019                proto::code_action::Kind::Command as i32,
12020                serde_json::to_vec(command).unwrap(),
12021            ),
12022            LspAction::CodeLens(code_lens) => (
12023                proto::code_action::Kind::CodeLens as i32,
12024                serde_json::to_vec(code_lens).unwrap(),
12025            ),
12026        };
12027
12028        proto::CodeAction {
12029            server_id: action.server_id.0 as u64,
12030            start: Some(serialize_anchor(&action.range.start)),
12031            end: Some(serialize_anchor(&action.range.end)),
12032            lsp_action,
12033            kind,
12034            resolved: action.resolved,
12035        }
12036    }
12037
12038    pub(crate) fn deserialize_code_action(action: proto::CodeAction) -> Result<CodeAction> {
12039        let start = action
12040            .start
12041            .and_then(deserialize_anchor)
12042            .context("invalid start")?;
12043        let end = action
12044            .end
12045            .and_then(deserialize_anchor)
12046            .context("invalid end")?;
12047        let lsp_action = match proto::code_action::Kind::from_i32(action.kind) {
12048            Some(proto::code_action::Kind::Action) => {
12049                LspAction::Action(serde_json::from_slice(&action.lsp_action)?)
12050            }
12051            Some(proto::code_action::Kind::Command) => {
12052                LspAction::Command(serde_json::from_slice(&action.lsp_action)?)
12053            }
12054            Some(proto::code_action::Kind::CodeLens) => {
12055                LspAction::CodeLens(serde_json::from_slice(&action.lsp_action)?)
12056            }
12057            None => anyhow::bail!("Unknown action kind {}", action.kind),
12058        };
12059        Ok(CodeAction {
12060            server_id: LanguageServerId(action.server_id as usize),
12061            range: start..end,
12062            resolved: action.resolved,
12063            lsp_action,
12064        })
12065    }
12066
12067    fn update_last_formatting_failure<T>(&mut self, formatting_result: &anyhow::Result<T>) {
12068        match &formatting_result {
12069            Ok(_) => self.last_formatting_failure = None,
12070            Err(error) => {
12071                let error_string = format!("{error:#}");
12072                log::error!("Formatting failed: {error_string}");
12073                self.last_formatting_failure
12074                    .replace(error_string.lines().join(" "));
12075            }
12076        }
12077    }
12078
12079    fn cleanup_lsp_data(&mut self, for_server: LanguageServerId) {
12080        self.lsp_server_capabilities.remove(&for_server);
12081        for lsp_data in self.lsp_data.values_mut() {
12082            lsp_data.remove_server_data(for_server);
12083        }
12084        if let Some(local) = self.as_local_mut() {
12085            local.buffer_pull_diagnostics_result_ids.remove(&for_server);
12086            local
12087                .workspace_pull_diagnostics_result_ids
12088                .remove(&for_server);
12089            for buffer_servers in local.buffers_opened_in_servers.values_mut() {
12090                buffer_servers.remove(&for_server);
12091            }
12092        }
12093    }
12094
12095    pub fn result_id_for_buffer_pull(
12096        &self,
12097        server_id: LanguageServerId,
12098        buffer_id: BufferId,
12099        registration_id: &Option<SharedString>,
12100        cx: &App,
12101    ) -> Option<SharedString> {
12102        let abs_path = self
12103            .buffer_store
12104            .read(cx)
12105            .get(buffer_id)
12106            .and_then(|b| File::from_dyn(b.read(cx).file()))
12107            .map(|f| f.abs_path(cx))?;
12108        self.as_local()?
12109            .buffer_pull_diagnostics_result_ids
12110            .get(&server_id)?
12111            .get(registration_id)?
12112            .get(&abs_path)?
12113            .clone()
12114    }
12115
12116    /// Gets all result_ids for a workspace diagnostics pull request.
12117    /// First, it tries to find buffer's result_id retrieved via the diagnostics pull; if it fails, it falls back to the workspace disagnostics pull result_id.
12118    /// The latter is supposed to be of lower priority as we keep on pulling diagnostics for open buffers eagerly.
12119    pub fn result_ids_for_workspace_refresh(
12120        &self,
12121        server_id: LanguageServerId,
12122        registration_id: &Option<SharedString>,
12123    ) -> HashMap<PathBuf, SharedString> {
12124        let Some(local) = self.as_local() else {
12125            return HashMap::default();
12126        };
12127        local
12128            .workspace_pull_diagnostics_result_ids
12129            .get(&server_id)
12130            .into_iter()
12131            .filter_map(|diagnostics| diagnostics.get(registration_id))
12132            .flatten()
12133            .filter_map(|(abs_path, result_id)| {
12134                let result_id = local
12135                    .buffer_pull_diagnostics_result_ids
12136                    .get(&server_id)
12137                    .and_then(|buffer_ids_result_ids| {
12138                        buffer_ids_result_ids.get(registration_id)?.get(abs_path)
12139                    })
12140                    .cloned()
12141                    .flatten()
12142                    .or_else(|| result_id.clone())?;
12143                Some((abs_path.clone(), result_id))
12144            })
12145            .collect()
12146    }
12147
12148    pub fn pull_workspace_diagnostics(&mut self, server_id: LanguageServerId) {
12149        if let Some(LanguageServerState::Running {
12150            workspace_diagnostics_refresh_tasks,
12151            ..
12152        }) = self
12153            .as_local_mut()
12154            .and_then(|local| local.language_servers.get_mut(&server_id))
12155        {
12156            for diagnostics in workspace_diagnostics_refresh_tasks.values_mut() {
12157                diagnostics.refresh_tx.try_send(()).ok();
12158            }
12159        }
12160    }
12161
12162    pub fn pull_workspace_diagnostics_for_buffer(&mut self, buffer_id: BufferId, cx: &mut App) {
12163        let Some(buffer) = self.buffer_store().read(cx).get_existing(buffer_id).ok() else {
12164            return;
12165        };
12166        let Some(local) = self.as_local_mut() else {
12167            return;
12168        };
12169
12170        for server_id in buffer.update(cx, |buffer, cx| {
12171            local.language_server_ids_for_buffer(buffer, cx)
12172        }) {
12173            if let Some(LanguageServerState::Running {
12174                workspace_diagnostics_refresh_tasks,
12175                ..
12176            }) = local.language_servers.get_mut(&server_id)
12177            {
12178                for diagnostics in workspace_diagnostics_refresh_tasks.values_mut() {
12179                    diagnostics.refresh_tx.try_send(()).ok();
12180                }
12181            }
12182        }
12183    }
12184
12185    fn apply_workspace_diagnostic_report(
12186        &mut self,
12187        server_id: LanguageServerId,
12188        report: lsp::WorkspaceDiagnosticReportResult,
12189        registration_id: Option<SharedString>,
12190        cx: &mut Context<Self>,
12191    ) {
12192        let mut workspace_diagnostics =
12193            GetDocumentDiagnostics::deserialize_workspace_diagnostics_report(
12194                report,
12195                server_id,
12196                registration_id,
12197            );
12198        workspace_diagnostics.retain(|d| match &d.diagnostics {
12199            LspPullDiagnostics::Response {
12200                server_id,
12201                registration_id,
12202                ..
12203            } => self.diagnostic_registration_exists(*server_id, registration_id),
12204            LspPullDiagnostics::Default => false,
12205        });
12206        let mut unchanged_buffers = HashMap::default();
12207        let workspace_diagnostics_updates = workspace_diagnostics
12208            .into_iter()
12209            .filter_map(
12210                |workspace_diagnostics| match workspace_diagnostics.diagnostics {
12211                    LspPullDiagnostics::Response {
12212                        server_id,
12213                        uri,
12214                        diagnostics,
12215                        registration_id,
12216                    } => Some((
12217                        server_id,
12218                        uri,
12219                        diagnostics,
12220                        workspace_diagnostics.version,
12221                        registration_id,
12222                    )),
12223                    LspPullDiagnostics::Default => None,
12224                },
12225            )
12226            .fold(
12227                HashMap::default(),
12228                |mut acc, (server_id, uri, diagnostics, version, new_registration_id)| {
12229                    let (result_id, diagnostics) = match diagnostics {
12230                        PulledDiagnostics::Unchanged { result_id } => {
12231                            unchanged_buffers
12232                                .entry(new_registration_id.clone())
12233                                .or_insert_with(HashSet::default)
12234                                .insert(uri.clone());
12235                            (Some(result_id), Vec::new())
12236                        }
12237                        PulledDiagnostics::Changed {
12238                            result_id,
12239                            diagnostics,
12240                        } => (result_id, diagnostics),
12241                    };
12242                    let disk_based_sources = Cow::Owned(
12243                        self.language_server_adapter_for_id(server_id)
12244                            .as_ref()
12245                            .map(|adapter| adapter.disk_based_diagnostic_sources.as_slice())
12246                            .unwrap_or(&[])
12247                            .to_vec(),
12248                    );
12249
12250                    let Some(abs_path) = uri.to_file_path().ok() else {
12251                        return acc;
12252                    };
12253                    let Some((worktree, relative_path)) =
12254                        self.worktree_store.read(cx).find_worktree(abs_path.clone(), cx)
12255                    else {
12256                        log::warn!("skipping workspace diagnostics update, no worktree found for path {abs_path:?}");
12257                        return acc;
12258                    };
12259                    let worktree_id = worktree.read(cx).id();
12260                    let project_path = ProjectPath {
12261                        worktree_id,
12262                        path: relative_path,
12263                    };
12264                    if let Some(local_lsp_store) = self.as_local_mut() {
12265                        local_lsp_store.workspace_pull_diagnostics_result_ids.entry(server_id)
12266                            .or_default().entry(new_registration_id.clone()).or_default().insert(abs_path, result_id.clone());
12267                    }
12268                    // The LSP spec recommends that "diagnostics from a document pull should win over diagnostics from a workspace pull."
12269                    // Since we actively pull diagnostics for documents with open buffers, we ignore contents of workspace pulls for these documents.
12270                    if self.buffer_store.read(cx).get_by_path(&project_path).is_none() {
12271                        acc.entry(server_id)
12272                            .or_insert_with(HashMap::default)
12273                            .entry(new_registration_id.clone())
12274                            .or_insert_with(Vec::new)
12275                            .push(DocumentDiagnosticsUpdate {
12276                                server_id,
12277                                diagnostics: lsp::PublishDiagnosticsParams {
12278                                    uri,
12279                                    diagnostics,
12280                                    version,
12281                                },
12282                                result_id,
12283                                disk_based_sources,
12284                                registration_id: new_registration_id,
12285                            });
12286                    }
12287                    acc
12288                },
12289            );
12290
12291        for diagnostic_updates in workspace_diagnostics_updates.into_values() {
12292            for (registration_id, diagnostic_updates) in diagnostic_updates {
12293                self.merge_lsp_diagnostics(
12294                    DiagnosticSourceKind::Pulled,
12295                    diagnostic_updates,
12296                    |document_uri, old_diagnostic, _| match old_diagnostic.source_kind {
12297                        DiagnosticSourceKind::Pulled => {
12298                            old_diagnostic.registration_id != registration_id
12299                                || unchanged_buffers
12300                                    .get(&old_diagnostic.registration_id)
12301                                    .is_some_and(|unchanged_buffers| {
12302                                        unchanged_buffers.contains(&document_uri)
12303                                    })
12304                        }
12305                        DiagnosticSourceKind::Other | DiagnosticSourceKind::Pushed => true,
12306                    },
12307                    cx,
12308                )
12309                .log_err();
12310            }
12311        }
12312    }
12313
12314    fn register_server_capabilities(
12315        &mut self,
12316        server_id: LanguageServerId,
12317        params: lsp::RegistrationParams,
12318        cx: &mut Context<Self>,
12319    ) -> anyhow::Result<()> {
12320        let server = self
12321            .language_server_for_id(server_id)
12322            .with_context(|| format!("no server {server_id} found"))?;
12323        for reg in params.registrations {
12324            match reg.method.as_str() {
12325                "workspace/didChangeWatchedFiles" => {
12326                    if let Some(options) = reg.register_options {
12327                        let notify = if let Some(local_lsp_store) = self.as_local_mut() {
12328                            let caps = serde_json::from_value(options)?;
12329                            local_lsp_store
12330                                .on_lsp_did_change_watched_files(server_id, &reg.id, caps, cx);
12331                            true
12332                        } else {
12333                            false
12334                        };
12335                        if notify {
12336                            notify_server_capabilities_updated(&server, cx);
12337                        }
12338                    }
12339                }
12340                "workspace/didChangeConfiguration" => {
12341                    // Ignore payload since we notify clients of setting changes unconditionally, relying on them pulling the latest settings.
12342                }
12343                "workspace/didChangeWorkspaceFolders" => {
12344                    // In this case register options is an empty object, we can ignore it
12345                    let caps = lsp::WorkspaceFoldersServerCapabilities {
12346                        supported: Some(true),
12347                        change_notifications: Some(OneOf::Right(reg.id)),
12348                    };
12349                    server.update_capabilities(|capabilities| {
12350                        capabilities
12351                            .workspace
12352                            .get_or_insert_default()
12353                            .workspace_folders = Some(caps);
12354                    });
12355                    notify_server_capabilities_updated(&server, cx);
12356                }
12357                "workspace/symbol" => {
12358                    let options = parse_register_capabilities(reg)?;
12359                    server.update_capabilities(|capabilities| {
12360                        capabilities.workspace_symbol_provider = Some(options);
12361                    });
12362                    notify_server_capabilities_updated(&server, cx);
12363                }
12364                "workspace/fileOperations" => {
12365                    if let Some(options) = reg.register_options {
12366                        let caps = serde_json::from_value(options)?;
12367                        server.update_capabilities(|capabilities| {
12368                            capabilities
12369                                .workspace
12370                                .get_or_insert_default()
12371                                .file_operations = Some(caps);
12372                        });
12373                        notify_server_capabilities_updated(&server, cx);
12374                    }
12375                }
12376                "workspace/executeCommand" => {
12377                    if let Some(options) = reg.register_options {
12378                        let options = serde_json::from_value(options)?;
12379                        server.update_capabilities(|capabilities| {
12380                            capabilities.execute_command_provider = Some(options);
12381                        });
12382                        notify_server_capabilities_updated(&server, cx);
12383                    }
12384                }
12385                "textDocument/rangeFormatting" => {
12386                    let options = parse_register_capabilities(reg)?;
12387                    server.update_capabilities(|capabilities| {
12388                        capabilities.document_range_formatting_provider = Some(options);
12389                    });
12390                    notify_server_capabilities_updated(&server, cx);
12391                }
12392                "textDocument/onTypeFormatting" => {
12393                    if let Some(options) = reg
12394                        .register_options
12395                        .map(serde_json::from_value)
12396                        .transpose()?
12397                    {
12398                        server.update_capabilities(|capabilities| {
12399                            capabilities.document_on_type_formatting_provider = Some(options);
12400                        });
12401                        notify_server_capabilities_updated(&server, cx);
12402                    }
12403                }
12404                "textDocument/formatting" => {
12405                    let options = parse_register_capabilities(reg)?;
12406                    server.update_capabilities(|capabilities| {
12407                        capabilities.document_formatting_provider = Some(options);
12408                    });
12409                    notify_server_capabilities_updated(&server, cx);
12410                }
12411                "textDocument/rename" => {
12412                    let options = parse_register_capabilities(reg)?;
12413                    server.update_capabilities(|capabilities| {
12414                        capabilities.rename_provider = Some(options);
12415                    });
12416                    notify_server_capabilities_updated(&server, cx);
12417                }
12418                "textDocument/inlayHint" => {
12419                    let options = parse_register_capabilities(reg)?;
12420                    server.update_capabilities(|capabilities| {
12421                        capabilities.inlay_hint_provider = Some(options);
12422                    });
12423                    notify_server_capabilities_updated(&server, cx);
12424                }
12425                "textDocument/documentSymbol" => {
12426                    let options = parse_register_capabilities(reg)?;
12427                    server.update_capabilities(|capabilities| {
12428                        capabilities.document_symbol_provider = Some(options);
12429                    });
12430                    notify_server_capabilities_updated(&server, cx);
12431                }
12432                "textDocument/codeAction" => {
12433                    let options = parse_register_capabilities(reg)?;
12434                    let provider = match options {
12435                        OneOf::Left(value) => lsp::CodeActionProviderCapability::Simple(value),
12436                        OneOf::Right(caps) => caps,
12437                    };
12438                    server.update_capabilities(|capabilities| {
12439                        capabilities.code_action_provider = Some(provider);
12440                    });
12441                    notify_server_capabilities_updated(&server, cx);
12442                }
12443                "textDocument/definition" => {
12444                    let options = parse_register_capabilities(reg)?;
12445                    server.update_capabilities(|capabilities| {
12446                        capabilities.definition_provider = Some(options);
12447                    });
12448                    notify_server_capabilities_updated(&server, cx);
12449                }
12450                "textDocument/completion" => {
12451                    if let Some(caps) = reg
12452                        .register_options
12453                        .map(serde_json::from_value::<CompletionOptions>)
12454                        .transpose()?
12455                    {
12456                        server.update_capabilities(|capabilities| {
12457                            capabilities.completion_provider = Some(caps.clone());
12458                        });
12459
12460                        if let Some(local) = self.as_local() {
12461                            let mut buffers_with_language_server = Vec::new();
12462                            for handle in self.buffer_store.read(cx).buffers() {
12463                                let buffer_id = handle.read(cx).remote_id();
12464                                if local
12465                                    .buffers_opened_in_servers
12466                                    .get(&buffer_id)
12467                                    .filter(|s| s.contains(&server_id))
12468                                    .is_some()
12469                                {
12470                                    buffers_with_language_server.push(handle);
12471                                }
12472                            }
12473                            let triggers = caps
12474                                .trigger_characters
12475                                .unwrap_or_default()
12476                                .into_iter()
12477                                .collect::<BTreeSet<_>>();
12478                            for handle in buffers_with_language_server {
12479                                let triggers = triggers.clone();
12480                                let _ = handle.update(cx, move |buffer, cx| {
12481                                    buffer.set_completion_triggers(server_id, triggers, cx);
12482                                });
12483                            }
12484                        }
12485                        notify_server_capabilities_updated(&server, cx);
12486                    }
12487                }
12488                "textDocument/hover" => {
12489                    let options = parse_register_capabilities(reg)?;
12490                    let provider = match options {
12491                        OneOf::Left(value) => lsp::HoverProviderCapability::Simple(value),
12492                        OneOf::Right(caps) => caps,
12493                    };
12494                    server.update_capabilities(|capabilities| {
12495                        capabilities.hover_provider = Some(provider);
12496                    });
12497                    notify_server_capabilities_updated(&server, cx);
12498                }
12499                "textDocument/signatureHelp" => {
12500                    if let Some(caps) = reg
12501                        .register_options
12502                        .map(serde_json::from_value)
12503                        .transpose()?
12504                    {
12505                        server.update_capabilities(|capabilities| {
12506                            capabilities.signature_help_provider = Some(caps);
12507                        });
12508                        notify_server_capabilities_updated(&server, cx);
12509                    }
12510                }
12511                "textDocument/didChange" => {
12512                    if let Some(sync_kind) = reg
12513                        .register_options
12514                        .and_then(|opts| opts.get("syncKind").cloned())
12515                        .map(serde_json::from_value::<lsp::TextDocumentSyncKind>)
12516                        .transpose()?
12517                    {
12518                        server.update_capabilities(|capabilities| {
12519                            let mut sync_options =
12520                                Self::take_text_document_sync_options(capabilities);
12521                            sync_options.change = Some(sync_kind);
12522                            capabilities.text_document_sync =
12523                                Some(lsp::TextDocumentSyncCapability::Options(sync_options));
12524                        });
12525                        notify_server_capabilities_updated(&server, cx);
12526                    }
12527                }
12528                "textDocument/didSave" => {
12529                    if let Some(include_text) = reg
12530                        .register_options
12531                        .map(|opts| {
12532                            let transpose = opts
12533                                .get("includeText")
12534                                .cloned()
12535                                .map(serde_json::from_value::<Option<bool>>)
12536                                .transpose();
12537                            match transpose {
12538                                Ok(value) => Ok(value.flatten()),
12539                                Err(e) => Err(e),
12540                            }
12541                        })
12542                        .transpose()?
12543                    {
12544                        server.update_capabilities(|capabilities| {
12545                            let mut sync_options =
12546                                Self::take_text_document_sync_options(capabilities);
12547                            sync_options.save =
12548                                Some(TextDocumentSyncSaveOptions::SaveOptions(lsp::SaveOptions {
12549                                    include_text,
12550                                }));
12551                            capabilities.text_document_sync =
12552                                Some(lsp::TextDocumentSyncCapability::Options(sync_options));
12553                        });
12554                        notify_server_capabilities_updated(&server, cx);
12555                    }
12556                }
12557                "textDocument/codeLens" => {
12558                    if let Some(caps) = reg
12559                        .register_options
12560                        .map(serde_json::from_value)
12561                        .transpose()?
12562                    {
12563                        server.update_capabilities(|capabilities| {
12564                            capabilities.code_lens_provider = Some(caps);
12565                        });
12566                        notify_server_capabilities_updated(&server, cx);
12567                    }
12568                }
12569                "textDocument/diagnostic" => {
12570                    if let Some(caps) = reg
12571                        .register_options
12572                        .map(serde_json::from_value::<DiagnosticServerCapabilities>)
12573                        .transpose()?
12574                    {
12575                        let local = self
12576                            .as_local_mut()
12577                            .context("Expected LSP Store to be local")?;
12578                        let state = local
12579                            .language_servers
12580                            .get_mut(&server_id)
12581                            .context("Could not obtain Language Servers state")?;
12582                        local
12583                            .language_server_dynamic_registrations
12584                            .entry(server_id)
12585                            .or_default()
12586                            .diagnostics
12587                            .insert(Some(reg.id.clone()), caps.clone());
12588
12589                        let supports_workspace_diagnostics =
12590                            |capabilities: &DiagnosticServerCapabilities| match capabilities {
12591                                DiagnosticServerCapabilities::Options(diagnostic_options) => {
12592                                    diagnostic_options.workspace_diagnostics
12593                                }
12594                                DiagnosticServerCapabilities::RegistrationOptions(
12595                                    diagnostic_registration_options,
12596                                ) => {
12597                                    diagnostic_registration_options
12598                                        .diagnostic_options
12599                                        .workspace_diagnostics
12600                                }
12601                            };
12602
12603                        if supports_workspace_diagnostics(&caps) {
12604                            if let LanguageServerState::Running {
12605                                workspace_diagnostics_refresh_tasks,
12606                                ..
12607                            } = state
12608                                && let Some(task) = lsp_workspace_diagnostics_refresh(
12609                                    Some(reg.id.clone()),
12610                                    caps.clone(),
12611                                    server.clone(),
12612                                    cx,
12613                                )
12614                            {
12615                                workspace_diagnostics_refresh_tasks.insert(Some(reg.id), task);
12616                            }
12617                        }
12618
12619                        server.update_capabilities(|capabilities| {
12620                            capabilities.diagnostic_provider = Some(caps);
12621                        });
12622
12623                        notify_server_capabilities_updated(&server, cx);
12624
12625                        let buffers_to_pull: Vec<_> = self
12626                            .as_local()
12627                            .into_iter()
12628                            .flat_map(|local| {
12629                                self.buffer_store.read(cx).buffers().filter(|buffer| {
12630                                    let buffer_id = buffer.read(cx).remote_id();
12631                                    local
12632                                        .buffers_opened_in_servers
12633                                        .get(&buffer_id)
12634                                        .is_some_and(|servers| servers.contains(&server_id))
12635                                })
12636                            })
12637                            .collect();
12638                        for buffer in buffers_to_pull {
12639                            self.pull_diagnostics_for_buffer(buffer, cx).detach();
12640                        }
12641                    }
12642                }
12643                "textDocument/documentColor" => {
12644                    let options = parse_register_capabilities(reg)?;
12645                    let provider = match options {
12646                        OneOf::Left(value) => lsp::ColorProviderCapability::Simple(value),
12647                        OneOf::Right(caps) => caps,
12648                    };
12649                    server.update_capabilities(|capabilities| {
12650                        capabilities.color_provider = Some(provider);
12651                    });
12652                    notify_server_capabilities_updated(&server, cx);
12653                }
12654                _ => log::warn!("unhandled capability registration: {reg:?}"),
12655            }
12656        }
12657
12658        Ok(())
12659    }
12660
12661    fn unregister_server_capabilities(
12662        &mut self,
12663        server_id: LanguageServerId,
12664        params: lsp::UnregistrationParams,
12665        cx: &mut Context<Self>,
12666    ) -> anyhow::Result<()> {
12667        let server = self
12668            .language_server_for_id(server_id)
12669            .with_context(|| format!("no server {server_id} found"))?;
12670        for unreg in params.unregisterations.iter() {
12671            match unreg.method.as_str() {
12672                "workspace/didChangeWatchedFiles" => {
12673                    let notify = if let Some(local_lsp_store) = self.as_local_mut() {
12674                        local_lsp_store
12675                            .on_lsp_unregister_did_change_watched_files(server_id, &unreg.id, cx);
12676                        true
12677                    } else {
12678                        false
12679                    };
12680                    if notify {
12681                        notify_server_capabilities_updated(&server, cx);
12682                    }
12683                }
12684                "workspace/didChangeConfiguration" => {
12685                    // Ignore payload since we notify clients of setting changes unconditionally, relying on them pulling the latest settings.
12686                }
12687                "workspace/didChangeWorkspaceFolders" => {
12688                    server.update_capabilities(|capabilities| {
12689                        capabilities
12690                            .workspace
12691                            .get_or_insert_with(|| lsp::WorkspaceServerCapabilities {
12692                                workspace_folders: None,
12693                                file_operations: None,
12694                            })
12695                            .workspace_folders = None;
12696                    });
12697                    notify_server_capabilities_updated(&server, cx);
12698                }
12699                "workspace/symbol" => {
12700                    server.update_capabilities(|capabilities| {
12701                        capabilities.workspace_symbol_provider = None
12702                    });
12703                    notify_server_capabilities_updated(&server, cx);
12704                }
12705                "workspace/fileOperations" => {
12706                    server.update_capabilities(|capabilities| {
12707                        capabilities
12708                            .workspace
12709                            .get_or_insert_with(|| lsp::WorkspaceServerCapabilities {
12710                                workspace_folders: None,
12711                                file_operations: None,
12712                            })
12713                            .file_operations = None;
12714                    });
12715                    notify_server_capabilities_updated(&server, cx);
12716                }
12717                "workspace/executeCommand" => {
12718                    server.update_capabilities(|capabilities| {
12719                        capabilities.execute_command_provider = None;
12720                    });
12721                    notify_server_capabilities_updated(&server, cx);
12722                }
12723                "textDocument/rangeFormatting" => {
12724                    server.update_capabilities(|capabilities| {
12725                        capabilities.document_range_formatting_provider = None
12726                    });
12727                    notify_server_capabilities_updated(&server, cx);
12728                }
12729                "textDocument/onTypeFormatting" => {
12730                    server.update_capabilities(|capabilities| {
12731                        capabilities.document_on_type_formatting_provider = None;
12732                    });
12733                    notify_server_capabilities_updated(&server, cx);
12734                }
12735                "textDocument/formatting" => {
12736                    server.update_capabilities(|capabilities| {
12737                        capabilities.document_formatting_provider = None;
12738                    });
12739                    notify_server_capabilities_updated(&server, cx);
12740                }
12741                "textDocument/rename" => {
12742                    server.update_capabilities(|capabilities| capabilities.rename_provider = None);
12743                    notify_server_capabilities_updated(&server, cx);
12744                }
12745                "textDocument/codeAction" => {
12746                    server.update_capabilities(|capabilities| {
12747                        capabilities.code_action_provider = None;
12748                    });
12749                    notify_server_capabilities_updated(&server, cx);
12750                }
12751                "textDocument/definition" => {
12752                    server.update_capabilities(|capabilities| {
12753                        capabilities.definition_provider = None;
12754                    });
12755                    notify_server_capabilities_updated(&server, cx);
12756                }
12757                "textDocument/completion" => {
12758                    server.update_capabilities(|capabilities| {
12759                        capabilities.completion_provider = None;
12760                    });
12761                    notify_server_capabilities_updated(&server, cx);
12762                }
12763                "textDocument/hover" => {
12764                    server.update_capabilities(|capabilities| {
12765                        capabilities.hover_provider = None;
12766                    });
12767                    notify_server_capabilities_updated(&server, cx);
12768                }
12769                "textDocument/signatureHelp" => {
12770                    server.update_capabilities(|capabilities| {
12771                        capabilities.signature_help_provider = None;
12772                    });
12773                    notify_server_capabilities_updated(&server, cx);
12774                }
12775                "textDocument/didChange" => {
12776                    server.update_capabilities(|capabilities| {
12777                        let mut sync_options = Self::take_text_document_sync_options(capabilities);
12778                        sync_options.change = None;
12779                        capabilities.text_document_sync =
12780                            Some(lsp::TextDocumentSyncCapability::Options(sync_options));
12781                    });
12782                    notify_server_capabilities_updated(&server, cx);
12783                }
12784                "textDocument/didSave" => {
12785                    server.update_capabilities(|capabilities| {
12786                        let mut sync_options = Self::take_text_document_sync_options(capabilities);
12787                        sync_options.save = None;
12788                        capabilities.text_document_sync =
12789                            Some(lsp::TextDocumentSyncCapability::Options(sync_options));
12790                    });
12791                    notify_server_capabilities_updated(&server, cx);
12792                }
12793                "textDocument/codeLens" => {
12794                    server.update_capabilities(|capabilities| {
12795                        capabilities.code_lens_provider = None;
12796                    });
12797                    notify_server_capabilities_updated(&server, cx);
12798                }
12799                "textDocument/diagnostic" => {
12800                    let local = self
12801                        .as_local_mut()
12802                        .context("Expected LSP Store to be local")?;
12803
12804                    let state = local
12805                        .language_servers
12806                        .get_mut(&server_id)
12807                        .context("Could not obtain Language Servers state")?;
12808                    let registrations = local
12809                        .language_server_dynamic_registrations
12810                        .get_mut(&server_id)
12811                        .with_context(|| {
12812                            format!("Expected dynamic registration to exist for server {server_id}")
12813                        })?;
12814                    registrations.diagnostics
12815                        .remove(&Some(unreg.id.clone()))
12816                        .with_context(|| format!(
12817                            "Attempted to unregister non-existent diagnostic registration with ID {}",
12818                            unreg.id)
12819                        )?;
12820                    let removed_last_diagnostic_provider = registrations.diagnostics.is_empty();
12821
12822                    if let LanguageServerState::Running {
12823                        workspace_diagnostics_refresh_tasks,
12824                        ..
12825                    } = state
12826                    {
12827                        workspace_diagnostics_refresh_tasks.remove(&Some(unreg.id.clone()));
12828                    }
12829
12830                    self.clear_unregistered_diagnostics(
12831                        server_id,
12832                        SharedString::from(unreg.id.clone()),
12833                        cx,
12834                    )?;
12835
12836                    if removed_last_diagnostic_provider {
12837                        server.update_capabilities(|capabilities| {
12838                            debug_assert!(capabilities.diagnostic_provider.is_some());
12839                            capabilities.diagnostic_provider = None;
12840                        });
12841                    }
12842
12843                    notify_server_capabilities_updated(&server, cx);
12844                }
12845                "textDocument/documentColor" => {
12846                    server.update_capabilities(|capabilities| {
12847                        capabilities.color_provider = None;
12848                    });
12849                    notify_server_capabilities_updated(&server, cx);
12850                }
12851                _ => log::warn!("unhandled capability unregistration: {unreg:?}"),
12852            }
12853        }
12854
12855        Ok(())
12856    }
12857
12858    fn clear_unregistered_diagnostics(
12859        &mut self,
12860        server_id: LanguageServerId,
12861        cleared_registration_id: SharedString,
12862        cx: &mut Context<Self>,
12863    ) -> anyhow::Result<()> {
12864        let mut affected_abs_paths: HashSet<PathBuf> = HashSet::default();
12865
12866        self.buffer_store.update(cx, |buffer_store, cx| {
12867            for buffer_handle in buffer_store.buffers() {
12868                let buffer = buffer_handle.read(cx);
12869                let abs_path = File::from_dyn(buffer.file()).map(|f| f.abs_path(cx));
12870                let Some(abs_path) = abs_path else {
12871                    continue;
12872                };
12873                affected_abs_paths.insert(abs_path);
12874            }
12875        });
12876
12877        let local = self.as_local().context("Expected LSP Store to be local")?;
12878        for (worktree_id, diagnostics_for_tree) in local.diagnostics.iter() {
12879            let Some(worktree) = self
12880                .worktree_store
12881                .read(cx)
12882                .worktree_for_id(*worktree_id, cx)
12883            else {
12884                continue;
12885            };
12886
12887            for (rel_path, diagnostics_by_server_id) in diagnostics_for_tree.iter() {
12888                if let Ok(ix) = diagnostics_by_server_id.binary_search_by_key(&server_id, |e| e.0) {
12889                    let has_matching_registration =
12890                        diagnostics_by_server_id[ix].1.iter().any(|entry| {
12891                            entry.diagnostic.registration_id.as_ref()
12892                                == Some(&cleared_registration_id)
12893                        });
12894                    if has_matching_registration {
12895                        let abs_path = worktree.read(cx).absolutize(rel_path);
12896                        affected_abs_paths.insert(abs_path);
12897                    }
12898                }
12899            }
12900        }
12901
12902        if affected_abs_paths.is_empty() {
12903            return Ok(());
12904        }
12905
12906        // Send a fake diagnostic update which clears the state for the registration ID
12907        let clears: Vec<DocumentDiagnosticsUpdate<'static, DocumentDiagnostics>> =
12908            affected_abs_paths
12909                .into_iter()
12910                .map(|abs_path| DocumentDiagnosticsUpdate {
12911                    diagnostics: DocumentDiagnostics {
12912                        diagnostics: Vec::new(),
12913                        document_abs_path: abs_path,
12914                        version: None,
12915                    },
12916                    result_id: None,
12917                    registration_id: Some(cleared_registration_id.clone()),
12918                    server_id,
12919                    disk_based_sources: Cow::Borrowed(&[]),
12920                })
12921                .collect();
12922
12923        let merge_registration_id = cleared_registration_id.clone();
12924        self.merge_diagnostic_entries(
12925            clears,
12926            move |_, diagnostic, _| {
12927                if diagnostic.source_kind == DiagnosticSourceKind::Pulled {
12928                    diagnostic.registration_id != Some(merge_registration_id.clone())
12929                } else {
12930                    true
12931                }
12932            },
12933            cx,
12934        )?;
12935
12936        Ok(())
12937    }
12938
12939    async fn deduplicate_range_based_lsp_requests<T>(
12940        lsp_store: &Entity<Self>,
12941        server_id: Option<LanguageServerId>,
12942        lsp_request_id: LspRequestId,
12943        proto_request: &T::ProtoRequest,
12944        range: Range<Anchor>,
12945        cx: &mut AsyncApp,
12946    ) -> Result<()>
12947    where
12948        T: LspCommand,
12949        T::ProtoRequest: proto::LspRequestMessage,
12950    {
12951        let buffer_id = BufferId::new(proto_request.buffer_id())?;
12952        let version = deserialize_version(proto_request.buffer_version());
12953        let buffer = lsp_store.update(cx, |this, cx| {
12954            this.buffer_store.read(cx).get_existing(buffer_id)
12955        })??;
12956        buffer
12957            .update(cx, |buffer, _| buffer.wait_for_version(version))?
12958            .await?;
12959        lsp_store.update(cx, |lsp_store, cx| {
12960            let buffer_snapshot = buffer.read(cx).snapshot();
12961            let lsp_data = lsp_store.latest_lsp_data(&buffer, cx);
12962            let chunks_queried_for = lsp_data
12963                .inlay_hints
12964                .applicable_chunks(&[range.to_point(&buffer_snapshot)])
12965                .collect::<Vec<_>>();
12966            match chunks_queried_for.as_slice() {
12967                &[chunk] => {
12968                    let key = LspKey {
12969                        request_type: TypeId::of::<T>(),
12970                        server_queried: server_id,
12971                    };
12972                    let previous_request = lsp_data
12973                        .chunk_lsp_requests
12974                        .entry(key)
12975                        .or_default()
12976                        .insert(chunk, lsp_request_id);
12977                    if let Some((previous_request, running_requests)) =
12978                        previous_request.zip(lsp_data.lsp_requests.get_mut(&key))
12979                    {
12980                        running_requests.remove(&previous_request);
12981                    }
12982                }
12983                _ambiguous_chunks => {
12984                    // Have not found a unique chunk for the query range — be lenient and let the query to be spawned,
12985                    // there, a buffer version-based check will be performed and outdated requests discarded.
12986                }
12987            }
12988            anyhow::Ok(())
12989        })??;
12990
12991        Ok(())
12992    }
12993
12994    async fn query_lsp_locally<T>(
12995        lsp_store: Entity<Self>,
12996        for_server_id: Option<LanguageServerId>,
12997        sender_id: proto::PeerId,
12998        lsp_request_id: LspRequestId,
12999        proto_request: T::ProtoRequest,
13000        position: Option<Anchor>,
13001        cx: &mut AsyncApp,
13002    ) -> Result<()>
13003    where
13004        T: LspCommand + Clone,
13005        T::ProtoRequest: proto::LspRequestMessage,
13006        <T::ProtoRequest as proto::RequestMessage>::Response:
13007            Into<<T::ProtoRequest as proto::LspRequestMessage>::Response>,
13008    {
13009        let buffer_id = BufferId::new(proto_request.buffer_id())?;
13010        let version = deserialize_version(proto_request.buffer_version());
13011        let buffer = lsp_store.update(cx, |this, cx| {
13012            this.buffer_store.read(cx).get_existing(buffer_id)
13013        })??;
13014        buffer
13015            .update(cx, |buffer, _| buffer.wait_for_version(version.clone()))?
13016            .await?;
13017        let buffer_version = buffer.read_with(cx, |buffer, _| buffer.version())?;
13018        let request =
13019            T::from_proto(proto_request, lsp_store.clone(), buffer.clone(), cx.clone()).await?;
13020        let key = LspKey {
13021            request_type: TypeId::of::<T>(),
13022            server_queried: for_server_id,
13023        };
13024        lsp_store.update(cx, |lsp_store, cx| {
13025            let request_task = match for_server_id {
13026                Some(server_id) => {
13027                    let server_task = lsp_store.request_lsp(
13028                        buffer.clone(),
13029                        LanguageServerToQuery::Other(server_id),
13030                        request.clone(),
13031                        cx,
13032                    );
13033                    cx.background_spawn(async move {
13034                        let mut responses = Vec::new();
13035                        match server_task.await {
13036                            Ok(response) => responses.push((server_id, response)),
13037                            // rust-analyzer likes to error with this when its still loading up
13038                            Err(e) if format!("{e:#}").ends_with("content modified") => (),
13039                            Err(e) => log::error!(
13040                                "Error handling response for request {request:?}: {e:#}"
13041                            ),
13042                        }
13043                        responses
13044                    })
13045                }
13046                None => lsp_store.request_multiple_lsp_locally(&buffer, position, request, cx),
13047            };
13048            let lsp_data = lsp_store.latest_lsp_data(&buffer, cx);
13049            if T::ProtoRequest::stop_previous_requests() {
13050                if let Some(lsp_requests) = lsp_data.lsp_requests.get_mut(&key) {
13051                    lsp_requests.clear();
13052                }
13053            }
13054            lsp_data.lsp_requests.entry(key).or_default().insert(
13055                lsp_request_id,
13056                cx.spawn(async move |lsp_store, cx| {
13057                    let response = request_task.await;
13058                    lsp_store
13059                        .update(cx, |lsp_store, cx| {
13060                            if let Some((client, project_id)) = lsp_store.downstream_client.clone()
13061                            {
13062                                let response = response
13063                                    .into_iter()
13064                                    .map(|(server_id, response)| {
13065                                        (
13066                                            server_id.to_proto(),
13067                                            T::response_to_proto(
13068                                                response,
13069                                                lsp_store,
13070                                                sender_id,
13071                                                &buffer_version,
13072                                                cx,
13073                                            )
13074                                            .into(),
13075                                        )
13076                                    })
13077                                    .collect::<HashMap<_, _>>();
13078                                match client.send_lsp_response::<T::ProtoRequest>(
13079                                    project_id,
13080                                    lsp_request_id,
13081                                    response,
13082                                ) {
13083                                    Ok(()) => {}
13084                                    Err(e) => {
13085                                        log::error!("Failed to send LSP response: {e:#}",)
13086                                    }
13087                                }
13088                            }
13089                        })
13090                        .ok();
13091                }),
13092            );
13093        })?;
13094        Ok(())
13095    }
13096
13097    fn take_text_document_sync_options(
13098        capabilities: &mut lsp::ServerCapabilities,
13099    ) -> lsp::TextDocumentSyncOptions {
13100        match capabilities.text_document_sync.take() {
13101            Some(lsp::TextDocumentSyncCapability::Options(sync_options)) => sync_options,
13102            Some(lsp::TextDocumentSyncCapability::Kind(sync_kind)) => {
13103                let mut sync_options = lsp::TextDocumentSyncOptions::default();
13104                sync_options.change = Some(sync_kind);
13105                sync_options
13106            }
13107            None => lsp::TextDocumentSyncOptions::default(),
13108        }
13109    }
13110
13111    #[cfg(any(test, feature = "test-support"))]
13112    pub fn forget_code_lens_task(&mut self, buffer_id: BufferId) -> Option<CodeLensTask> {
13113        Some(
13114            self.lsp_data
13115                .get_mut(&buffer_id)?
13116                .code_lens
13117                .take()?
13118                .update
13119                .take()?
13120                .1,
13121        )
13122    }
13123
13124    pub fn downstream_client(&self) -> Option<(AnyProtoClient, u64)> {
13125        self.downstream_client.clone()
13126    }
13127
13128    pub fn worktree_store(&self) -> Entity<WorktreeStore> {
13129        self.worktree_store.clone()
13130    }
13131
13132    /// Gets what's stored in the LSP data for the given buffer.
13133    pub fn current_lsp_data(&mut self, buffer_id: BufferId) -> Option<&mut BufferLspData> {
13134        self.lsp_data.get_mut(&buffer_id)
13135    }
13136
13137    /// Gets the most recent LSP data for the given buffer: if the data is absent or out of date,
13138    /// new [`BufferLspData`] will be created to replace the previous state.
13139    pub fn latest_lsp_data(&mut self, buffer: &Entity<Buffer>, cx: &mut App) -> &mut BufferLspData {
13140        let (buffer_id, buffer_version) =
13141            buffer.read_with(cx, |buffer, _| (buffer.remote_id(), buffer.version()));
13142        let lsp_data = self
13143            .lsp_data
13144            .entry(buffer_id)
13145            .or_insert_with(|| BufferLspData::new(buffer, cx));
13146        if buffer_version.changed_since(&lsp_data.buffer_version) {
13147            *lsp_data = BufferLspData::new(buffer, cx);
13148        }
13149        lsp_data
13150    }
13151}
13152
13153// Registration with registerOptions as null, should fallback to true.
13154// https://github.com/microsoft/vscode-languageserver-node/blob/d90a87f9557a0df9142cfb33e251cfa6fe27d970/client/src/common/client.ts#L2133
13155fn parse_register_capabilities<T: serde::de::DeserializeOwned>(
13156    reg: lsp::Registration,
13157) -> Result<OneOf<bool, T>> {
13158    Ok(match reg.register_options {
13159        Some(options) => OneOf::Right(serde_json::from_value::<T>(options)?),
13160        None => OneOf::Left(true),
13161    })
13162}
13163
13164fn subscribe_to_binary_statuses(
13165    languages: &Arc<LanguageRegistry>,
13166    cx: &mut Context<'_, LspStore>,
13167) -> Task<()> {
13168    let mut server_statuses = languages.language_server_binary_statuses();
13169    cx.spawn(async move |lsp_store, cx| {
13170        while let Some((server_name, binary_status)) = server_statuses.next().await {
13171            if lsp_store
13172                .update(cx, |_, cx| {
13173                    let mut message = None;
13174                    let binary_status = match binary_status {
13175                        BinaryStatus::None => proto::ServerBinaryStatus::None,
13176                        BinaryStatus::CheckingForUpdate => {
13177                            proto::ServerBinaryStatus::CheckingForUpdate
13178                        }
13179                        BinaryStatus::Downloading => proto::ServerBinaryStatus::Downloading,
13180                        BinaryStatus::Starting => proto::ServerBinaryStatus::Starting,
13181                        BinaryStatus::Stopping => proto::ServerBinaryStatus::Stopping,
13182                        BinaryStatus::Stopped => proto::ServerBinaryStatus::Stopped,
13183                        BinaryStatus::Failed { error } => {
13184                            message = Some(error);
13185                            proto::ServerBinaryStatus::Failed
13186                        }
13187                    };
13188                    cx.emit(LspStoreEvent::LanguageServerUpdate {
13189                        // Binary updates are about the binary that might not have any language server id at that point.
13190                        // Reuse `LanguageServerUpdate` for them and provide a fake id that won't be used on the receiver side.
13191                        language_server_id: LanguageServerId(0),
13192                        name: Some(server_name),
13193                        message: proto::update_language_server::Variant::StatusUpdate(
13194                            proto::StatusUpdate {
13195                                message,
13196                                status: Some(proto::status_update::Status::Binary(
13197                                    binary_status as i32,
13198                                )),
13199                            },
13200                        ),
13201                    });
13202                })
13203                .is_err()
13204            {
13205                break;
13206            }
13207        }
13208    })
13209}
13210
13211fn lsp_workspace_diagnostics_refresh(
13212    registration_id: Option<String>,
13213    options: DiagnosticServerCapabilities,
13214    server: Arc<LanguageServer>,
13215    cx: &mut Context<'_, LspStore>,
13216) -> Option<WorkspaceRefreshTask> {
13217    let identifier = workspace_diagnostic_identifier(&options)?;
13218    let registration_id_shared = registration_id.as_ref().map(SharedString::from);
13219
13220    let (progress_tx, mut progress_rx) = mpsc::channel(1);
13221    let (mut refresh_tx, mut refresh_rx) = mpsc::channel(1);
13222    refresh_tx.try_send(()).ok();
13223
13224    let workspace_query_language_server = cx.spawn(async move |lsp_store, cx| {
13225        let mut attempts = 0;
13226        let max_attempts = 50;
13227        let mut requests = 0;
13228
13229        loop {
13230            let Some(()) = refresh_rx.recv().await else {
13231                return;
13232            };
13233
13234            'request: loop {
13235                requests += 1;
13236                if attempts > max_attempts {
13237                    log::error!(
13238                        "Failed to pull workspace diagnostics {max_attempts} times, aborting"
13239                    );
13240                    return;
13241                }
13242                let backoff_millis = (50 * (1 << attempts)).clamp(30, 1000);
13243                cx.background_executor()
13244                    .timer(Duration::from_millis(backoff_millis))
13245                    .await;
13246                attempts += 1;
13247
13248                let Ok(previous_result_ids) = lsp_store.update(cx, |lsp_store, _| {
13249                    lsp_store
13250                        .result_ids_for_workspace_refresh(server.server_id(), &registration_id_shared)
13251                        .into_iter()
13252                        .filter_map(|(abs_path, result_id)| {
13253                            let uri = file_path_to_lsp_url(&abs_path).ok()?;
13254                            Some(lsp::PreviousResultId {
13255                                uri,
13256                                value: result_id.to_string(),
13257                            })
13258                        })
13259                        .collect()
13260                }) else {
13261                    return;
13262                };
13263
13264                let token = if let Some(registration_id) = &registration_id {
13265                    format!(
13266                        "workspace/diagnostic/{}/{requests}/{WORKSPACE_DIAGNOSTICS_TOKEN_START}{registration_id}",
13267                        server.server_id(),
13268                    )
13269                } else {
13270                    format!("workspace/diagnostic/{}/{requests}", server.server_id())
13271                };
13272
13273                progress_rx.try_recv().ok();
13274                let timer =
13275                    LanguageServer::default_request_timer(cx.background_executor().clone()).fuse();
13276                let progress = pin!(progress_rx.recv().fuse());
13277                let response_result = server
13278                    .request_with_timer::<lsp::WorkspaceDiagnosticRequest, _>(
13279                        lsp::WorkspaceDiagnosticParams {
13280                            previous_result_ids,
13281                            identifier: identifier.clone(),
13282                            work_done_progress_params: Default::default(),
13283                            partial_result_params: lsp::PartialResultParams {
13284                                partial_result_token: Some(lsp::ProgressToken::String(token)),
13285                            },
13286                        },
13287                        select(timer, progress).then(|either| match either {
13288                            Either::Left((message, ..)) => ready(message).left_future(),
13289                            Either::Right(..) => pending::<String>().right_future(),
13290                        }),
13291                    )
13292                    .await;
13293
13294                // https://microsoft.github.io/language-server-protocol/specifications/lsp/3.17/specification/#diagnostic_refresh
13295                // >  If a server closes a workspace diagnostic pull request the client should re-trigger the request.
13296                match response_result {
13297                    ConnectionResult::Timeout => {
13298                        log::error!("Timeout during workspace diagnostics pull");
13299                        continue 'request;
13300                    }
13301                    ConnectionResult::ConnectionReset => {
13302                        log::error!("Server closed a workspace diagnostics pull request");
13303                        continue 'request;
13304                    }
13305                    ConnectionResult::Result(Err(e)) => {
13306                        log::error!("Error during workspace diagnostics pull: {e:#}");
13307                        break 'request;
13308                    }
13309                    ConnectionResult::Result(Ok(pulled_diagnostics)) => {
13310                        attempts = 0;
13311                        if lsp_store
13312                            .update(cx, |lsp_store, cx| {
13313                                lsp_store.apply_workspace_diagnostic_report(
13314                                    server.server_id(),
13315                                    pulled_diagnostics,
13316                                    registration_id_shared.clone(),
13317                                    cx,
13318                                )
13319                            })
13320                            .is_err()
13321                        {
13322                            return;
13323                        }
13324                        break 'request;
13325                    }
13326                }
13327            }
13328        }
13329    });
13330
13331    Some(WorkspaceRefreshTask {
13332        refresh_tx,
13333        progress_tx,
13334        task: workspace_query_language_server,
13335    })
13336}
13337
13338fn buffer_diagnostic_identifier(options: &DiagnosticServerCapabilities) -> Option<String> {
13339    match &options {
13340        lsp::DiagnosticServerCapabilities::Options(diagnostic_options) => {
13341            diagnostic_options.identifier.clone()
13342        }
13343        lsp::DiagnosticServerCapabilities::RegistrationOptions(registration_options) => {
13344            let diagnostic_options = &registration_options.diagnostic_options;
13345            diagnostic_options.identifier.clone()
13346        }
13347    }
13348}
13349
13350fn workspace_diagnostic_identifier(
13351    options: &DiagnosticServerCapabilities,
13352) -> Option<Option<String>> {
13353    match &options {
13354        lsp::DiagnosticServerCapabilities::Options(diagnostic_options) => {
13355            if !diagnostic_options.workspace_diagnostics {
13356                return None;
13357            }
13358            Some(diagnostic_options.identifier.clone())
13359        }
13360        lsp::DiagnosticServerCapabilities::RegistrationOptions(registration_options) => {
13361            let diagnostic_options = &registration_options.diagnostic_options;
13362            if !diagnostic_options.workspace_diagnostics {
13363                return None;
13364            }
13365            Some(diagnostic_options.identifier.clone())
13366        }
13367    }
13368}
13369
13370fn resolve_word_completion(snapshot: &BufferSnapshot, completion: &mut Completion) {
13371    let CompletionSource::BufferWord {
13372        word_range,
13373        resolved,
13374    } = &mut completion.source
13375    else {
13376        return;
13377    };
13378    if *resolved {
13379        return;
13380    }
13381
13382    if completion.new_text
13383        != snapshot
13384            .text_for_range(word_range.clone())
13385            .collect::<String>()
13386    {
13387        return;
13388    }
13389
13390    let mut offset = 0;
13391    for chunk in snapshot.chunks(word_range.clone(), true) {
13392        let end_offset = offset + chunk.text.len();
13393        if let Some(highlight_id) = chunk.syntax_highlight_id {
13394            completion
13395                .label
13396                .runs
13397                .push((offset..end_offset, highlight_id));
13398        }
13399        offset = end_offset;
13400    }
13401    *resolved = true;
13402}
13403
13404impl EventEmitter<LspStoreEvent> for LspStore {}
13405
13406fn remove_empty_hover_blocks(mut hover: Hover) -> Option<Hover> {
13407    hover
13408        .contents
13409        .retain(|hover_block| !hover_block.text.trim().is_empty());
13410    if hover.contents.is_empty() {
13411        None
13412    } else {
13413        Some(hover)
13414    }
13415}
13416
13417async fn populate_labels_for_completions(
13418    new_completions: Vec<CoreCompletion>,
13419    language: Option<Arc<Language>>,
13420    lsp_adapter: Option<Arc<CachedLspAdapter>>,
13421) -> Vec<Completion> {
13422    let lsp_completions = new_completions
13423        .iter()
13424        .filter_map(|new_completion| {
13425            new_completion
13426                .source
13427                .lsp_completion(true)
13428                .map(|lsp_completion| lsp_completion.into_owned())
13429        })
13430        .collect::<Vec<_>>();
13431
13432    let mut labels = if let Some((language, lsp_adapter)) = language.as_ref().zip(lsp_adapter) {
13433        lsp_adapter
13434            .labels_for_completions(&lsp_completions, language)
13435            .await
13436            .log_err()
13437            .unwrap_or_default()
13438    } else {
13439        Vec::new()
13440    }
13441    .into_iter()
13442    .fuse();
13443
13444    let mut completions = Vec::new();
13445    for completion in new_completions {
13446        match completion.source.lsp_completion(true) {
13447            Some(lsp_completion) => {
13448                let documentation = lsp_completion.documentation.clone().map(|docs| docs.into());
13449
13450                let mut label = labels.next().flatten().unwrap_or_else(|| {
13451                    CodeLabel::fallback_for_completion(&lsp_completion, language.as_deref())
13452                });
13453                ensure_uniform_list_compatible_label(&mut label);
13454                completions.push(Completion {
13455                    label,
13456                    documentation,
13457                    replace_range: completion.replace_range,
13458                    new_text: completion.new_text,
13459                    insert_text_mode: lsp_completion.insert_text_mode,
13460                    source: completion.source,
13461                    icon_path: None,
13462                    confirm: None,
13463                    match_start: None,
13464                    snippet_deduplication_key: None,
13465                });
13466            }
13467            None => {
13468                let mut label = CodeLabel::plain(completion.new_text.clone(), None);
13469                ensure_uniform_list_compatible_label(&mut label);
13470                completions.push(Completion {
13471                    label,
13472                    documentation: None,
13473                    replace_range: completion.replace_range,
13474                    new_text: completion.new_text,
13475                    source: completion.source,
13476                    insert_text_mode: None,
13477                    icon_path: None,
13478                    confirm: None,
13479                    match_start: None,
13480                    snippet_deduplication_key: None,
13481                });
13482            }
13483        }
13484    }
13485    completions
13486}
13487
13488#[derive(Debug)]
13489pub enum LanguageServerToQuery {
13490    /// Query language servers in order of users preference, up until one capable of handling the request is found.
13491    FirstCapable,
13492    /// Query a specific language server.
13493    Other(LanguageServerId),
13494}
13495
13496#[derive(Default)]
13497struct RenamePathsWatchedForServer {
13498    did_rename: Vec<RenameActionPredicate>,
13499    will_rename: Vec<RenameActionPredicate>,
13500}
13501
13502impl RenamePathsWatchedForServer {
13503    fn with_did_rename_patterns(
13504        mut self,
13505        did_rename: Option<&FileOperationRegistrationOptions>,
13506    ) -> Self {
13507        if let Some(did_rename) = did_rename {
13508            self.did_rename = did_rename
13509                .filters
13510                .iter()
13511                .filter_map(|filter| filter.try_into().log_err())
13512                .collect();
13513        }
13514        self
13515    }
13516    fn with_will_rename_patterns(
13517        mut self,
13518        will_rename: Option<&FileOperationRegistrationOptions>,
13519    ) -> Self {
13520        if let Some(will_rename) = will_rename {
13521            self.will_rename = will_rename
13522                .filters
13523                .iter()
13524                .filter_map(|filter| filter.try_into().log_err())
13525                .collect();
13526        }
13527        self
13528    }
13529
13530    fn should_send_did_rename(&self, path: &str, is_dir: bool) -> bool {
13531        self.did_rename.iter().any(|pred| pred.eval(path, is_dir))
13532    }
13533    fn should_send_will_rename(&self, path: &str, is_dir: bool) -> bool {
13534        self.will_rename.iter().any(|pred| pred.eval(path, is_dir))
13535    }
13536}
13537
13538impl TryFrom<&FileOperationFilter> for RenameActionPredicate {
13539    type Error = globset::Error;
13540    fn try_from(ops: &FileOperationFilter) -> Result<Self, globset::Error> {
13541        Ok(Self {
13542            kind: ops.pattern.matches.clone(),
13543            glob: GlobBuilder::new(&ops.pattern.glob)
13544                .case_insensitive(
13545                    ops.pattern
13546                        .options
13547                        .as_ref()
13548                        .is_some_and(|ops| ops.ignore_case.unwrap_or(false)),
13549                )
13550                .build()?
13551                .compile_matcher(),
13552        })
13553    }
13554}
13555struct RenameActionPredicate {
13556    glob: GlobMatcher,
13557    kind: Option<FileOperationPatternKind>,
13558}
13559
13560impl RenameActionPredicate {
13561    // Returns true if language server should be notified
13562    fn eval(&self, path: &str, is_dir: bool) -> bool {
13563        self.kind.as_ref().is_none_or(|kind| {
13564            let expected_kind = if is_dir {
13565                FileOperationPatternKind::Folder
13566            } else {
13567                FileOperationPatternKind::File
13568            };
13569            kind == &expected_kind
13570        }) && self.glob.is_match(path)
13571    }
13572}
13573
13574#[derive(Default)]
13575struct LanguageServerWatchedPaths {
13576    worktree_paths: HashMap<WorktreeId, GlobSet>,
13577    abs_paths: HashMap<Arc<Path>, (GlobSet, Task<()>)>,
13578}
13579
13580#[derive(Default)]
13581struct LanguageServerWatchedPathsBuilder {
13582    worktree_paths: HashMap<WorktreeId, GlobSet>,
13583    abs_paths: HashMap<Arc<Path>, GlobSet>,
13584}
13585
13586impl LanguageServerWatchedPathsBuilder {
13587    fn watch_worktree(&mut self, worktree_id: WorktreeId, glob_set: GlobSet) {
13588        self.worktree_paths.insert(worktree_id, glob_set);
13589    }
13590    fn watch_abs_path(&mut self, path: Arc<Path>, glob_set: GlobSet) {
13591        self.abs_paths.insert(path, glob_set);
13592    }
13593    fn build(
13594        self,
13595        fs: Arc<dyn Fs>,
13596        language_server_id: LanguageServerId,
13597        cx: &mut Context<LspStore>,
13598    ) -> LanguageServerWatchedPaths {
13599        let lsp_store = cx.weak_entity();
13600
13601        const LSP_ABS_PATH_OBSERVE: Duration = Duration::from_millis(100);
13602        let abs_paths = self
13603            .abs_paths
13604            .into_iter()
13605            .map(|(abs_path, globset)| {
13606                let task = cx.spawn({
13607                    let abs_path = abs_path.clone();
13608                    let fs = fs.clone();
13609
13610                    let lsp_store = lsp_store.clone();
13611                    async move |_, cx| {
13612                        maybe!(async move {
13613                            let mut push_updates = fs.watch(&abs_path, LSP_ABS_PATH_OBSERVE).await;
13614                            while let Some(update) = push_updates.0.next().await {
13615                                let action = lsp_store
13616                                    .update(cx, |this, _| {
13617                                        let Some(local) = this.as_local() else {
13618                                            return ControlFlow::Break(());
13619                                        };
13620                                        let Some(watcher) = local
13621                                            .language_server_watched_paths
13622                                            .get(&language_server_id)
13623                                        else {
13624                                            return ControlFlow::Break(());
13625                                        };
13626                                        let (globs, _) = watcher.abs_paths.get(&abs_path).expect(
13627                                            "Watched abs path is not registered with a watcher",
13628                                        );
13629                                        let matching_entries = update
13630                                            .into_iter()
13631                                            .filter(|event| globs.is_match(&event.path))
13632                                            .collect::<Vec<_>>();
13633                                        this.lsp_notify_abs_paths_changed(
13634                                            language_server_id,
13635                                            matching_entries,
13636                                        );
13637                                        ControlFlow::Continue(())
13638                                    })
13639                                    .ok()?;
13640
13641                                if action.is_break() {
13642                                    break;
13643                                }
13644                            }
13645                            Some(())
13646                        })
13647                        .await;
13648                    }
13649                });
13650                (abs_path, (globset, task))
13651            })
13652            .collect();
13653        LanguageServerWatchedPaths {
13654            worktree_paths: self.worktree_paths,
13655            abs_paths,
13656        }
13657    }
13658}
13659
13660struct LspBufferSnapshot {
13661    version: i32,
13662    snapshot: TextBufferSnapshot,
13663}
13664
13665/// A prompt requested by LSP server.
13666#[derive(Clone, Debug)]
13667pub struct LanguageServerPromptRequest {
13668    pub level: PromptLevel,
13669    pub message: String,
13670    pub actions: Vec<MessageActionItem>,
13671    pub lsp_name: String,
13672    pub(crate) response_channel: smol::channel::Sender<MessageActionItem>,
13673}
13674
13675impl LanguageServerPromptRequest {
13676    pub async fn respond(self, index: usize) -> Option<()> {
13677        if let Some(response) = self.actions.into_iter().nth(index) {
13678            self.response_channel.send(response).await.ok()
13679        } else {
13680            None
13681        }
13682    }
13683}
13684impl PartialEq for LanguageServerPromptRequest {
13685    fn eq(&self, other: &Self) -> bool {
13686        self.message == other.message && self.actions == other.actions
13687    }
13688}
13689
13690#[derive(Clone, Debug, PartialEq)]
13691pub enum LanguageServerLogType {
13692    Log(MessageType),
13693    Trace { verbose_info: Option<String> },
13694    Rpc { received: bool },
13695}
13696
13697impl LanguageServerLogType {
13698    pub fn to_proto(&self) -> proto::language_server_log::LogType {
13699        match self {
13700            Self::Log(log_type) => {
13701                use proto::log_message::LogLevel;
13702                let level = match *log_type {
13703                    MessageType::ERROR => LogLevel::Error,
13704                    MessageType::WARNING => LogLevel::Warning,
13705                    MessageType::INFO => LogLevel::Info,
13706                    MessageType::LOG => LogLevel::Log,
13707                    other => {
13708                        log::warn!("Unknown lsp log message type: {other:?}");
13709                        LogLevel::Log
13710                    }
13711                };
13712                proto::language_server_log::LogType::Log(proto::LogMessage {
13713                    level: level as i32,
13714                })
13715            }
13716            Self::Trace { verbose_info } => {
13717                proto::language_server_log::LogType::Trace(proto::TraceMessage {
13718                    verbose_info: verbose_info.to_owned(),
13719                })
13720            }
13721            Self::Rpc { received } => {
13722                let kind = if *received {
13723                    proto::rpc_message::Kind::Received
13724                } else {
13725                    proto::rpc_message::Kind::Sent
13726                };
13727                let kind = kind as i32;
13728                proto::language_server_log::LogType::Rpc(proto::RpcMessage { kind })
13729            }
13730        }
13731    }
13732
13733    pub fn from_proto(log_type: proto::language_server_log::LogType) -> Self {
13734        use proto::log_message::LogLevel;
13735        use proto::rpc_message;
13736        match log_type {
13737            proto::language_server_log::LogType::Log(message_type) => Self::Log(
13738                match LogLevel::from_i32(message_type.level).unwrap_or(LogLevel::Log) {
13739                    LogLevel::Error => MessageType::ERROR,
13740                    LogLevel::Warning => MessageType::WARNING,
13741                    LogLevel::Info => MessageType::INFO,
13742                    LogLevel::Log => MessageType::LOG,
13743                },
13744            ),
13745            proto::language_server_log::LogType::Trace(trace_message) => Self::Trace {
13746                verbose_info: trace_message.verbose_info,
13747            },
13748            proto::language_server_log::LogType::Rpc(message) => Self::Rpc {
13749                received: match rpc_message::Kind::from_i32(message.kind)
13750                    .unwrap_or(rpc_message::Kind::Received)
13751                {
13752                    rpc_message::Kind::Received => true,
13753                    rpc_message::Kind::Sent => false,
13754                },
13755            },
13756        }
13757    }
13758}
13759
13760pub struct WorkspaceRefreshTask {
13761    refresh_tx: mpsc::Sender<()>,
13762    progress_tx: mpsc::Sender<()>,
13763    #[allow(dead_code)]
13764    task: Task<()>,
13765}
13766
13767pub enum LanguageServerState {
13768    Starting {
13769        startup: Task<Option<Arc<LanguageServer>>>,
13770        /// List of language servers that will be added to the workspace once it's initialization completes.
13771        pending_workspace_folders: Arc<Mutex<BTreeSet<Uri>>>,
13772    },
13773
13774    Running {
13775        adapter: Arc<CachedLspAdapter>,
13776        server: Arc<LanguageServer>,
13777        simulate_disk_based_diagnostics_completion: Option<Task<()>>,
13778        workspace_diagnostics_refresh_tasks: HashMap<Option<String>, WorkspaceRefreshTask>,
13779    },
13780}
13781
13782impl LanguageServerState {
13783    fn add_workspace_folder(&self, uri: Uri) {
13784        match self {
13785            LanguageServerState::Starting {
13786                pending_workspace_folders,
13787                ..
13788            } => {
13789                pending_workspace_folders.lock().insert(uri);
13790            }
13791            LanguageServerState::Running { server, .. } => {
13792                server.add_workspace_folder(uri);
13793            }
13794        }
13795    }
13796    fn _remove_workspace_folder(&self, uri: Uri) {
13797        match self {
13798            LanguageServerState::Starting {
13799                pending_workspace_folders,
13800                ..
13801            } => {
13802                pending_workspace_folders.lock().remove(&uri);
13803            }
13804            LanguageServerState::Running { server, .. } => server.remove_workspace_folder(uri),
13805        }
13806    }
13807}
13808
13809impl std::fmt::Debug for LanguageServerState {
13810    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
13811        match self {
13812            LanguageServerState::Starting { .. } => {
13813                f.debug_struct("LanguageServerState::Starting").finish()
13814            }
13815            LanguageServerState::Running { .. } => {
13816                f.debug_struct("LanguageServerState::Running").finish()
13817            }
13818        }
13819    }
13820}
13821
13822#[derive(Clone, Debug, Serialize)]
13823pub struct LanguageServerProgress {
13824    pub is_disk_based_diagnostics_progress: bool,
13825    pub is_cancellable: bool,
13826    pub title: Option<String>,
13827    pub message: Option<String>,
13828    pub percentage: Option<usize>,
13829    #[serde(skip_serializing)]
13830    pub last_update_at: Instant,
13831}
13832
13833#[derive(Copy, Clone, Debug, Default, PartialEq, Serialize)]
13834pub struct DiagnosticSummary {
13835    pub error_count: usize,
13836    pub warning_count: usize,
13837}
13838
13839impl DiagnosticSummary {
13840    pub fn new<'a, T: 'a>(diagnostics: impl IntoIterator<Item = &'a DiagnosticEntry<T>>) -> Self {
13841        let mut this = Self {
13842            error_count: 0,
13843            warning_count: 0,
13844        };
13845
13846        for entry in diagnostics {
13847            if entry.diagnostic.is_primary {
13848                match entry.diagnostic.severity {
13849                    DiagnosticSeverity::ERROR => this.error_count += 1,
13850                    DiagnosticSeverity::WARNING => this.warning_count += 1,
13851                    _ => {}
13852                }
13853            }
13854        }
13855
13856        this
13857    }
13858
13859    pub fn is_empty(&self) -> bool {
13860        self.error_count == 0 && self.warning_count == 0
13861    }
13862
13863    pub fn to_proto(
13864        self,
13865        language_server_id: LanguageServerId,
13866        path: &RelPath,
13867    ) -> proto::DiagnosticSummary {
13868        proto::DiagnosticSummary {
13869            path: path.to_proto(),
13870            language_server_id: language_server_id.0 as u64,
13871            error_count: self.error_count as u32,
13872            warning_count: self.warning_count as u32,
13873        }
13874    }
13875}
13876
13877#[derive(Clone, Debug)]
13878pub enum CompletionDocumentation {
13879    /// There is no documentation for this completion.
13880    Undocumented,
13881    /// A single line of documentation.
13882    SingleLine(SharedString),
13883    /// Multiple lines of plain text documentation.
13884    MultiLinePlainText(SharedString),
13885    /// Markdown documentation.
13886    MultiLineMarkdown(SharedString),
13887    /// Both single line and multiple lines of plain text documentation.
13888    SingleLineAndMultiLinePlainText {
13889        single_line: SharedString,
13890        plain_text: Option<SharedString>,
13891    },
13892}
13893
13894impl CompletionDocumentation {
13895    #[cfg(any(test, feature = "test-support"))]
13896    pub fn text(&self) -> SharedString {
13897        match self {
13898            CompletionDocumentation::Undocumented => "".into(),
13899            CompletionDocumentation::SingleLine(s) => s.clone(),
13900            CompletionDocumentation::MultiLinePlainText(s) => s.clone(),
13901            CompletionDocumentation::MultiLineMarkdown(s) => s.clone(),
13902            CompletionDocumentation::SingleLineAndMultiLinePlainText { single_line, .. } => {
13903                single_line.clone()
13904            }
13905        }
13906    }
13907}
13908
13909impl From<lsp::Documentation> for CompletionDocumentation {
13910    fn from(docs: lsp::Documentation) -> Self {
13911        match docs {
13912            lsp::Documentation::String(text) => {
13913                if text.lines().count() <= 1 {
13914                    CompletionDocumentation::SingleLine(text.into())
13915                } else {
13916                    CompletionDocumentation::MultiLinePlainText(text.into())
13917                }
13918            }
13919
13920            lsp::Documentation::MarkupContent(lsp::MarkupContent { kind, value }) => match kind {
13921                lsp::MarkupKind::PlainText => {
13922                    if value.lines().count() <= 1 {
13923                        CompletionDocumentation::SingleLine(value.into())
13924                    } else {
13925                        CompletionDocumentation::MultiLinePlainText(value.into())
13926                    }
13927                }
13928
13929                lsp::MarkupKind::Markdown => {
13930                    CompletionDocumentation::MultiLineMarkdown(value.into())
13931                }
13932            },
13933        }
13934    }
13935}
13936
13937pub enum ResolvedHint {
13938    Resolved(InlayHint),
13939    Resolving(Shared<Task<()>>),
13940}
13941
13942fn glob_literal_prefix(glob: &Path) -> PathBuf {
13943    glob.components()
13944        .take_while(|component| match component {
13945            path::Component::Normal(part) => !part.to_string_lossy().contains(['*', '?', '{', '}']),
13946            _ => true,
13947        })
13948        .collect()
13949}
13950
13951pub struct SshLspAdapter {
13952    name: LanguageServerName,
13953    binary: LanguageServerBinary,
13954    initialization_options: Option<String>,
13955    code_action_kinds: Option<Vec<CodeActionKind>>,
13956}
13957
13958impl SshLspAdapter {
13959    pub fn new(
13960        name: LanguageServerName,
13961        binary: LanguageServerBinary,
13962        initialization_options: Option<String>,
13963        code_action_kinds: Option<String>,
13964    ) -> Self {
13965        Self {
13966            name,
13967            binary,
13968            initialization_options,
13969            code_action_kinds: code_action_kinds
13970                .as_ref()
13971                .and_then(|c| serde_json::from_str(c).ok()),
13972        }
13973    }
13974}
13975
13976impl LspInstaller for SshLspAdapter {
13977    type BinaryVersion = ();
13978    async fn check_if_user_installed(
13979        &self,
13980        _: &dyn LspAdapterDelegate,
13981        _: Option<Toolchain>,
13982        _: &AsyncApp,
13983    ) -> Option<LanguageServerBinary> {
13984        Some(self.binary.clone())
13985    }
13986
13987    async fn cached_server_binary(
13988        &self,
13989        _: PathBuf,
13990        _: &dyn LspAdapterDelegate,
13991    ) -> Option<LanguageServerBinary> {
13992        None
13993    }
13994
13995    async fn fetch_latest_server_version(
13996        &self,
13997        _: &dyn LspAdapterDelegate,
13998        _: bool,
13999        _: &mut AsyncApp,
14000    ) -> Result<()> {
14001        anyhow::bail!("SshLspAdapter does not support fetch_latest_server_version")
14002    }
14003
14004    async fn fetch_server_binary(
14005        &self,
14006        _: (),
14007        _: PathBuf,
14008        _: &dyn LspAdapterDelegate,
14009    ) -> Result<LanguageServerBinary> {
14010        anyhow::bail!("SshLspAdapter does not support fetch_server_binary")
14011    }
14012}
14013
14014#[async_trait(?Send)]
14015impl LspAdapter for SshLspAdapter {
14016    fn name(&self) -> LanguageServerName {
14017        self.name.clone()
14018    }
14019
14020    async fn initialization_options(
14021        self: Arc<Self>,
14022        _: &Arc<dyn LspAdapterDelegate>,
14023    ) -> Result<Option<serde_json::Value>> {
14024        let Some(options) = &self.initialization_options else {
14025            return Ok(None);
14026        };
14027        let result = serde_json::from_str(options)?;
14028        Ok(result)
14029    }
14030
14031    fn code_action_kinds(&self) -> Option<Vec<CodeActionKind>> {
14032        self.code_action_kinds.clone()
14033    }
14034}
14035
14036pub fn language_server_settings<'a>(
14037    delegate: &'a dyn LspAdapterDelegate,
14038    language: &LanguageServerName,
14039    cx: &'a App,
14040) -> Option<&'a LspSettings> {
14041    language_server_settings_for(
14042        SettingsLocation {
14043            worktree_id: delegate.worktree_id(),
14044            path: RelPath::empty(),
14045        },
14046        language,
14047        cx,
14048    )
14049}
14050
14051pub fn language_server_settings_for<'a>(
14052    location: SettingsLocation<'a>,
14053    language: &LanguageServerName,
14054    cx: &'a App,
14055) -> Option<&'a LspSettings> {
14056    ProjectSettings::get(Some(location), cx).lsp.get(language)
14057}
14058
14059pub struct LocalLspAdapterDelegate {
14060    lsp_store: WeakEntity<LspStore>,
14061    worktree: worktree::Snapshot,
14062    fs: Arc<dyn Fs>,
14063    http_client: Arc<dyn HttpClient>,
14064    language_registry: Arc<LanguageRegistry>,
14065    load_shell_env_task: Shared<Task<Option<HashMap<String, String>>>>,
14066}
14067
14068impl LocalLspAdapterDelegate {
14069    pub fn new(
14070        language_registry: Arc<LanguageRegistry>,
14071        environment: &Entity<ProjectEnvironment>,
14072        lsp_store: WeakEntity<LspStore>,
14073        worktree: &Entity<Worktree>,
14074        http_client: Arc<dyn HttpClient>,
14075        fs: Arc<dyn Fs>,
14076        cx: &mut App,
14077    ) -> Arc<Self> {
14078        let load_shell_env_task =
14079            environment.update(cx, |env, cx| env.worktree_environment(worktree.clone(), cx));
14080
14081        Arc::new(Self {
14082            lsp_store,
14083            worktree: worktree.read(cx).snapshot(),
14084            fs,
14085            http_client,
14086            language_registry,
14087            load_shell_env_task,
14088        })
14089    }
14090
14091    fn from_local_lsp(
14092        local: &LocalLspStore,
14093        worktree: &Entity<Worktree>,
14094        cx: &mut App,
14095    ) -> Arc<Self> {
14096        Self::new(
14097            local.languages.clone(),
14098            &local.environment,
14099            local.weak.clone(),
14100            worktree,
14101            local.http_client.clone(),
14102            local.fs.clone(),
14103            cx,
14104        )
14105    }
14106}
14107
14108#[async_trait]
14109impl LspAdapterDelegate for LocalLspAdapterDelegate {
14110    fn show_notification(&self, message: &str, cx: &mut App) {
14111        self.lsp_store
14112            .update(cx, |_, cx| {
14113                cx.emit(LspStoreEvent::Notification(message.to_owned()))
14114            })
14115            .ok();
14116    }
14117
14118    fn http_client(&self) -> Arc<dyn HttpClient> {
14119        self.http_client.clone()
14120    }
14121
14122    fn worktree_id(&self) -> WorktreeId {
14123        self.worktree.id()
14124    }
14125
14126    fn worktree_root_path(&self) -> &Path {
14127        self.worktree.abs_path().as_ref()
14128    }
14129
14130    fn resolve_executable_path(&self, path: PathBuf) -> PathBuf {
14131        self.worktree.resolve_executable_path(path)
14132    }
14133
14134    async fn shell_env(&self) -> HashMap<String, String> {
14135        let task = self.load_shell_env_task.clone();
14136        task.await.unwrap_or_default()
14137    }
14138
14139    async fn npm_package_installed_version(
14140        &self,
14141        package_name: &str,
14142    ) -> Result<Option<(PathBuf, String)>> {
14143        let local_package_directory = self.worktree_root_path();
14144        let node_modules_directory = local_package_directory.join("node_modules");
14145
14146        if let Some(version) =
14147            read_package_installed_version(node_modules_directory.clone(), package_name).await?
14148        {
14149            return Ok(Some((node_modules_directory, version)));
14150        }
14151        let Some(npm) = self.which("npm".as_ref()).await else {
14152            log::warn!(
14153                "Failed to find npm executable for {:?}",
14154                local_package_directory
14155            );
14156            return Ok(None);
14157        };
14158
14159        let env = self.shell_env().await;
14160        let output = util::command::new_smol_command(&npm)
14161            .args(["root", "-g"])
14162            .envs(env)
14163            .current_dir(local_package_directory)
14164            .output()
14165            .await?;
14166        let global_node_modules =
14167            PathBuf::from(String::from_utf8_lossy(&output.stdout).to_string());
14168
14169        if let Some(version) =
14170            read_package_installed_version(global_node_modules.clone(), package_name).await?
14171        {
14172            return Ok(Some((global_node_modules, version)));
14173        }
14174        return Ok(None);
14175    }
14176
14177    async fn which(&self, command: &OsStr) -> Option<PathBuf> {
14178        let mut worktree_abs_path = self.worktree_root_path().to_path_buf();
14179        if self.fs.is_file(&worktree_abs_path).await {
14180            worktree_abs_path.pop();
14181        }
14182
14183        let env = self.shell_env().await;
14184
14185        let shell_path = env.get("PATH").cloned();
14186
14187        which::which_in(command, shell_path.as_ref(), worktree_abs_path).ok()
14188    }
14189
14190    async fn try_exec(&self, command: LanguageServerBinary) -> Result<()> {
14191        let mut working_dir = self.worktree_root_path().to_path_buf();
14192        if self.fs.is_file(&working_dir).await {
14193            working_dir.pop();
14194        }
14195        let output = util::command::new_smol_command(&command.path)
14196            .args(command.arguments)
14197            .envs(command.env.clone().unwrap_or_default())
14198            .current_dir(working_dir)
14199            .output()
14200            .await?;
14201
14202        anyhow::ensure!(
14203            output.status.success(),
14204            "{}, stdout: {:?}, stderr: {:?}",
14205            output.status,
14206            String::from_utf8_lossy(&output.stdout),
14207            String::from_utf8_lossy(&output.stderr)
14208        );
14209        Ok(())
14210    }
14211
14212    fn update_status(&self, server_name: LanguageServerName, status: language::BinaryStatus) {
14213        self.language_registry
14214            .update_lsp_binary_status(server_name, status);
14215    }
14216
14217    fn registered_lsp_adapters(&self) -> Vec<Arc<dyn LspAdapter>> {
14218        self.language_registry
14219            .all_lsp_adapters()
14220            .into_iter()
14221            .map(|adapter| adapter.adapter.clone() as Arc<dyn LspAdapter>)
14222            .collect()
14223    }
14224
14225    async fn language_server_download_dir(&self, name: &LanguageServerName) -> Option<Arc<Path>> {
14226        let dir = self.language_registry.language_server_download_dir(name)?;
14227
14228        if !dir.exists() {
14229            smol::fs::create_dir_all(&dir)
14230                .await
14231                .context("failed to create container directory")
14232                .log_err()?;
14233        }
14234
14235        Some(dir)
14236    }
14237
14238    async fn read_text_file(&self, path: &RelPath) -> Result<String> {
14239        let entry = self
14240            .worktree
14241            .entry_for_path(path)
14242            .with_context(|| format!("no worktree entry for path {path:?}"))?;
14243        let abs_path = self.worktree.absolutize(&entry.path);
14244        self.fs.load(&abs_path).await
14245    }
14246}
14247
14248async fn populate_labels_for_symbols(
14249    symbols: Vec<CoreSymbol>,
14250    language_registry: &Arc<LanguageRegistry>,
14251    lsp_adapter: Option<Arc<CachedLspAdapter>>,
14252    output: &mut Vec<Symbol>,
14253) {
14254    #[allow(clippy::mutable_key_type)]
14255    let mut symbols_by_language = HashMap::<Option<Arc<Language>>, Vec<CoreSymbol>>::default();
14256
14257    let mut unknown_paths = BTreeSet::<Arc<str>>::new();
14258    for symbol in symbols {
14259        let Some(file_name) = symbol.path.file_name() else {
14260            continue;
14261        };
14262        let language = language_registry
14263            .load_language_for_file_path(Path::new(file_name))
14264            .await
14265            .ok()
14266            .or_else(|| {
14267                unknown_paths.insert(file_name.into());
14268                None
14269            });
14270        symbols_by_language
14271            .entry(language)
14272            .or_default()
14273            .push(symbol);
14274    }
14275
14276    for unknown_path in unknown_paths {
14277        log::info!("no language found for symbol in file {unknown_path:?}");
14278    }
14279
14280    let mut label_params = Vec::new();
14281    for (language, mut symbols) in symbols_by_language {
14282        label_params.clear();
14283        label_params.extend(
14284            symbols
14285                .iter_mut()
14286                .map(|symbol| (mem::take(&mut symbol.name), symbol.kind)),
14287        );
14288
14289        let mut labels = Vec::new();
14290        if let Some(language) = language {
14291            let lsp_adapter = lsp_adapter.clone().or_else(|| {
14292                language_registry
14293                    .lsp_adapters(&language.name())
14294                    .first()
14295                    .cloned()
14296            });
14297            if let Some(lsp_adapter) = lsp_adapter {
14298                labels = lsp_adapter
14299                    .labels_for_symbols(&label_params, &language)
14300                    .await
14301                    .log_err()
14302                    .unwrap_or_default();
14303            }
14304        }
14305
14306        for ((symbol, (name, _)), label) in symbols
14307            .into_iter()
14308            .zip(label_params.drain(..))
14309            .zip(labels.into_iter().chain(iter::repeat(None)))
14310        {
14311            output.push(Symbol {
14312                language_server_name: symbol.language_server_name,
14313                source_worktree_id: symbol.source_worktree_id,
14314                source_language_server_id: symbol.source_language_server_id,
14315                path: symbol.path,
14316                label: label.unwrap_or_else(|| CodeLabel::plain(name.clone(), None)),
14317                name,
14318                kind: symbol.kind,
14319                range: symbol.range,
14320            });
14321        }
14322    }
14323}
14324
14325fn include_text(server: &lsp::LanguageServer) -> Option<bool> {
14326    match server.capabilities().text_document_sync.as_ref()? {
14327        lsp::TextDocumentSyncCapability::Options(opts) => match opts.save.as_ref()? {
14328            // Server wants didSave but didn't specify includeText.
14329            lsp::TextDocumentSyncSaveOptions::Supported(true) => Some(false),
14330            // Server doesn't want didSave at all.
14331            lsp::TextDocumentSyncSaveOptions::Supported(false) => None,
14332            // Server provided SaveOptions.
14333            lsp::TextDocumentSyncSaveOptions::SaveOptions(save_options) => {
14334                Some(save_options.include_text.unwrap_or(false))
14335            }
14336        },
14337        // We do not have any save info. Kind affects didChange only.
14338        lsp::TextDocumentSyncCapability::Kind(_) => None,
14339    }
14340}
14341
14342/// Completion items are displayed in a `UniformList`.
14343/// Usually, those items are single-line strings, but in LSP responses,
14344/// completion items `label`, `detail` and `label_details.description` may contain newlines or long spaces.
14345/// Many language plugins construct these items by joining these parts together, and we may use `CodeLabel::fallback_for_completion` that uses `label` at least.
14346/// 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,
14347/// breaking the completions menu presentation.
14348///
14349/// 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.
14350fn ensure_uniform_list_compatible_label(label: &mut CodeLabel) {
14351    let mut new_text = String::with_capacity(label.text.len());
14352    let mut offset_map = vec![0; label.text.len() + 1];
14353    let mut last_char_was_space = false;
14354    let mut new_idx = 0;
14355    let chars = label.text.char_indices().fuse();
14356    let mut newlines_removed = false;
14357
14358    for (idx, c) in chars {
14359        offset_map[idx] = new_idx;
14360
14361        match c {
14362            '\n' if last_char_was_space => {
14363                newlines_removed = true;
14364            }
14365            '\t' | ' ' if last_char_was_space => {}
14366            '\n' if !last_char_was_space => {
14367                new_text.push(' ');
14368                new_idx += 1;
14369                last_char_was_space = true;
14370                newlines_removed = true;
14371            }
14372            ' ' | '\t' => {
14373                new_text.push(' ');
14374                new_idx += 1;
14375                last_char_was_space = true;
14376            }
14377            _ => {
14378                new_text.push(c);
14379                new_idx += c.len_utf8();
14380                last_char_was_space = false;
14381            }
14382        }
14383    }
14384    offset_map[label.text.len()] = new_idx;
14385
14386    // Only modify the label if newlines were removed.
14387    if !newlines_removed {
14388        return;
14389    }
14390
14391    let last_index = new_idx;
14392    let mut run_ranges_errors = Vec::new();
14393    label.runs.retain_mut(|(range, _)| {
14394        match offset_map.get(range.start) {
14395            Some(&start) => range.start = start,
14396            None => {
14397                run_ranges_errors.push(range.clone());
14398                return false;
14399            }
14400        }
14401
14402        match offset_map.get(range.end) {
14403            Some(&end) => range.end = end,
14404            None => {
14405                run_ranges_errors.push(range.clone());
14406                range.end = last_index;
14407            }
14408        }
14409        true
14410    });
14411    if !run_ranges_errors.is_empty() {
14412        log::error!(
14413            "Completion label has errors in its run ranges: {run_ranges_errors:?}, label text: {}",
14414            label.text
14415        );
14416    }
14417
14418    let mut wrong_filter_range = None;
14419    if label.filter_range == (0..label.text.len()) {
14420        label.filter_range = 0..new_text.len();
14421    } else {
14422        let mut original_filter_range = Some(label.filter_range.clone());
14423        match offset_map.get(label.filter_range.start) {
14424            Some(&start) => label.filter_range.start = start,
14425            None => {
14426                wrong_filter_range = original_filter_range.take();
14427                label.filter_range.start = last_index;
14428            }
14429        }
14430
14431        match offset_map.get(label.filter_range.end) {
14432            Some(&end) => label.filter_range.end = end,
14433            None => {
14434                wrong_filter_range = original_filter_range.take();
14435                label.filter_range.end = last_index;
14436            }
14437        }
14438    }
14439    if let Some(wrong_filter_range) = wrong_filter_range {
14440        log::error!(
14441            "Completion label has an invalid filter range: {wrong_filter_range:?}, label text: {}",
14442            label.text
14443        );
14444    }
14445
14446    label.text = new_text;
14447}
14448
14449#[cfg(test)]
14450mod tests {
14451    use language::HighlightId;
14452
14453    use super::*;
14454
14455    #[test]
14456    fn test_glob_literal_prefix() {
14457        assert_eq!(glob_literal_prefix(Path::new("**/*.js")), Path::new(""));
14458        assert_eq!(
14459            glob_literal_prefix(Path::new("node_modules/**/*.js")),
14460            Path::new("node_modules")
14461        );
14462        assert_eq!(
14463            glob_literal_prefix(Path::new("foo/{bar,baz}.js")),
14464            Path::new("foo")
14465        );
14466        assert_eq!(
14467            glob_literal_prefix(Path::new("foo/bar/baz.js")),
14468            Path::new("foo/bar/baz.js")
14469        );
14470
14471        #[cfg(target_os = "windows")]
14472        {
14473            assert_eq!(glob_literal_prefix(Path::new("**\\*.js")), Path::new(""));
14474            assert_eq!(
14475                glob_literal_prefix(Path::new("node_modules\\**/*.js")),
14476                Path::new("node_modules")
14477            );
14478            assert_eq!(
14479                glob_literal_prefix(Path::new("foo/{bar,baz}.js")),
14480                Path::new("foo")
14481            );
14482            assert_eq!(
14483                glob_literal_prefix(Path::new("foo\\bar\\baz.js")),
14484                Path::new("foo/bar/baz.js")
14485            );
14486        }
14487    }
14488
14489    #[test]
14490    fn test_multi_len_chars_normalization() {
14491        let mut label = CodeLabel::new(
14492            "myElˇ (parameter) myElˇ: {\n    foo: string;\n}".to_string(),
14493            0..6,
14494            vec![(0..6, HighlightId(1))],
14495        );
14496        ensure_uniform_list_compatible_label(&mut label);
14497        assert_eq!(
14498            label,
14499            CodeLabel::new(
14500                "myElˇ (parameter) myElˇ: { foo: string; }".to_string(),
14501                0..6,
14502                vec![(0..6, HighlightId(1))],
14503            )
14504        );
14505    }
14506}