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::{BinarySettings, 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, Capability, CodeLabel,
   65    Diagnostic, DiagnosticEntry, DiagnosticSet, DiagnosticSourceKind, Diff, File as _, Language,
   66    LanguageName, LanguageRegistry, LocalFile, LspAdapter, LspAdapterDelegate, LspInstaller,
   67    ManifestDelegate, ManifestName, Patch, PointUtf16, TextBufferSnapshot, ToOffset, ToPointUtf16,
   68    Toolchain, Transaction, Unclipped,
   69    language_settings::{FormatOnSave, Formatter, LanguageSettings, language_settings},
   70    point_to_lsp,
   71    proto::{
   72        deserialize_anchor, deserialize_anchor_range, deserialize_lsp_edit, deserialize_version,
   73        serialize_anchor, serialize_anchor_range, 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 semver::Version;
   97use serde::Serialize;
   98use serde_json::Value;
   99use settings::{Settings, SettingsLocation, SettingsStore};
  100use sha2::{Digest, Sha256};
  101use snippet::Snippet;
  102use std::{
  103    any::TypeId,
  104    borrow::Cow,
  105    cell::RefCell,
  106    cmp::{Ordering, Reverse},
  107    collections::{VecDeque, hash_map},
  108    convert::TryInto,
  109    ffi::OsStr,
  110    future::ready,
  111    iter, mem,
  112    ops::{ControlFlow, Range},
  113    path::{self, Path, PathBuf},
  114    pin::pin,
  115    rc::Rc,
  116    sync::{
  117        Arc,
  118        atomic::{self, AtomicUsize},
  119    },
  120    time::{Duration, Instant},
  121    vec,
  122};
  123use sum_tree::Dimensions;
  124use text::{Anchor, BufferId, LineEnding, OffsetRangeExt, ToPoint as _};
  125
  126use util::{
  127    ConnectionResult, ResultExt as _, debug_panic, defer, maybe, merge_json_value_into,
  128    paths::{PathStyle, SanitizedPath, UrlExt},
  129    post_inc,
  130    redact::redact_command,
  131    rel_path::RelPath,
  132};
  133
  134pub use fs::*;
  135pub use language::Location;
  136pub use lsp_store::inlay_hint_cache::{CacheInlayHints, InvalidationStrategy};
  137#[cfg(any(test, feature = "test-support"))]
  138pub use prettier::FORMAT_SUFFIX as TEST_PRETTIER_FORMAT_SUFFIX;
  139pub use worktree::{
  140    Entry, EntryKind, FS_WATCH_LATENCY, File, LocalWorktree, PathChange, ProjectEntryId,
  141    UpdatedEntriesSet, UpdatedGitRepositoriesSet, Worktree, WorktreeId, WorktreeSettings,
  142};
  143
  144const SERVER_LAUNCHING_BEFORE_SHUTDOWN_TIMEOUT: Duration = Duration::from_secs(5);
  145pub const SERVER_PROGRESS_THROTTLE_TIMEOUT: Duration = Duration::from_millis(100);
  146const WORKSPACE_DIAGNOSTICS_TOKEN_START: &str = "id:";
  147const SERVER_DOWNLOAD_TIMEOUT: Duration = Duration::from_secs(10);
  148static NEXT_PROMPT_REQUEST_ID: AtomicUsize = AtomicUsize::new(0);
  149
  150#[derive(Debug, Clone, PartialEq, Eq, PartialOrd, Ord, Hash, Serialize)]
  151pub enum ProgressToken {
  152    Number(i32),
  153    String(SharedString),
  154}
  155
  156impl std::fmt::Display for ProgressToken {
  157    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
  158        match self {
  159            Self::Number(number) => write!(f, "{number}"),
  160            Self::String(string) => write!(f, "{string}"),
  161        }
  162    }
  163}
  164
  165impl ProgressToken {
  166    fn from_lsp(value: lsp::NumberOrString) -> Self {
  167        match value {
  168            lsp::NumberOrString::Number(number) => Self::Number(number),
  169            lsp::NumberOrString::String(string) => Self::String(SharedString::new(string)),
  170        }
  171    }
  172
  173    fn to_lsp(&self) -> lsp::NumberOrString {
  174        match self {
  175            Self::Number(number) => lsp::NumberOrString::Number(*number),
  176            Self::String(string) => lsp::NumberOrString::String(string.to_string()),
  177        }
  178    }
  179
  180    fn from_proto(value: proto::ProgressToken) -> Option<Self> {
  181        Some(match value.value? {
  182            proto::progress_token::Value::Number(number) => Self::Number(number),
  183            proto::progress_token::Value::String(string) => Self::String(SharedString::new(string)),
  184        })
  185    }
  186
  187    fn to_proto(&self) -> proto::ProgressToken {
  188        proto::ProgressToken {
  189            value: Some(match self {
  190                Self::Number(number) => proto::progress_token::Value::Number(*number),
  191                Self::String(string) => proto::progress_token::Value::String(string.to_string()),
  192            }),
  193        }
  194    }
  195}
  196
  197#[derive(Debug, Clone, Copy, PartialEq, Eq)]
  198pub enum FormatTrigger {
  199    Save,
  200    Manual,
  201}
  202
  203pub enum LspFormatTarget {
  204    Buffers,
  205    Ranges(BTreeMap<BufferId, Vec<Range<Anchor>>>),
  206}
  207
  208#[derive(Clone, PartialEq, Eq, Hash)]
  209pub struct OpenLspBufferHandle(Entity<OpenLspBuffer>);
  210
  211struct OpenLspBuffer(Entity<Buffer>);
  212
  213impl FormatTrigger {
  214    fn from_proto(value: i32) -> FormatTrigger {
  215        match value {
  216            0 => FormatTrigger::Save,
  217            1 => FormatTrigger::Manual,
  218            _ => FormatTrigger::Save,
  219        }
  220    }
  221}
  222
  223#[derive(Clone)]
  224struct UnifiedLanguageServer {
  225    id: LanguageServerId,
  226    project_roots: HashSet<Arc<RelPath>>,
  227}
  228
  229/// Settings that affect language server identity.
  230///
  231/// Dynamic settings (`LspSettings::settings`) are excluded because they can be
  232/// updated via `workspace/didChangeConfiguration` without restarting the server.
  233#[derive(Clone, Debug, Hash, PartialEq, Eq)]
  234struct LanguageServerSeedSettings {
  235    binary: Option<BinarySettings>,
  236    initialization_options: Option<serde_json::Value>,
  237}
  238
  239#[derive(Clone, Debug, Hash, PartialEq, Eq)]
  240struct LanguageServerSeed {
  241    worktree_id: WorktreeId,
  242    name: LanguageServerName,
  243    toolchain: Option<Toolchain>,
  244    settings: LanguageServerSeedSettings,
  245}
  246
  247#[derive(Debug)]
  248pub struct DocumentDiagnosticsUpdate<'a, D> {
  249    pub diagnostics: D,
  250    pub result_id: Option<SharedString>,
  251    pub registration_id: Option<SharedString>,
  252    pub server_id: LanguageServerId,
  253    pub disk_based_sources: Cow<'a, [String]>,
  254}
  255
  256pub struct DocumentDiagnostics {
  257    diagnostics: Vec<DiagnosticEntry<Unclipped<PointUtf16>>>,
  258    document_abs_path: PathBuf,
  259    version: Option<i32>,
  260}
  261
  262#[derive(Default, Debug)]
  263struct DynamicRegistrations {
  264    did_change_watched_files: HashMap<String, Vec<FileSystemWatcher>>,
  265    diagnostics: HashMap<Option<String>, DiagnosticServerCapabilities>,
  266}
  267
  268pub struct LocalLspStore {
  269    weak: WeakEntity<LspStore>,
  270    pub worktree_store: Entity<WorktreeStore>,
  271    toolchain_store: Entity<LocalToolchainStore>,
  272    http_client: Arc<dyn HttpClient>,
  273    environment: Entity<ProjectEnvironment>,
  274    fs: Arc<dyn Fs>,
  275    languages: Arc<LanguageRegistry>,
  276    language_server_ids: HashMap<LanguageServerSeed, UnifiedLanguageServer>,
  277    yarn: Entity<YarnPathStore>,
  278    pub language_servers: HashMap<LanguageServerId, LanguageServerState>,
  279    buffers_being_formatted: HashSet<BufferId>,
  280    last_workspace_edits_by_language_server: HashMap<LanguageServerId, ProjectTransaction>,
  281    language_server_watched_paths: HashMap<LanguageServerId, LanguageServerWatchedPaths>,
  282    watched_manifest_filenames: HashSet<ManifestName>,
  283    language_server_paths_watched_for_rename:
  284        HashMap<LanguageServerId, RenamePathsWatchedForServer>,
  285    language_server_dynamic_registrations: HashMap<LanguageServerId, DynamicRegistrations>,
  286    supplementary_language_servers:
  287        HashMap<LanguageServerId, (LanguageServerName, Arc<LanguageServer>)>,
  288    prettier_store: Entity<PrettierStore>,
  289    next_diagnostic_group_id: usize,
  290    diagnostics: HashMap<
  291        WorktreeId,
  292        HashMap<
  293            Arc<RelPath>,
  294            Vec<(
  295                LanguageServerId,
  296                Vec<DiagnosticEntry<Unclipped<PointUtf16>>>,
  297            )>,
  298        >,
  299    >,
  300    buffer_snapshots: HashMap<BufferId, HashMap<LanguageServerId, Vec<LspBufferSnapshot>>>, // buffer_id -> server_id -> vec of snapshots
  301    _subscription: gpui::Subscription,
  302    lsp_tree: LanguageServerTree,
  303    registered_buffers: HashMap<BufferId, usize>,
  304    buffers_opened_in_servers: HashMap<BufferId, HashSet<LanguageServerId>>,
  305    buffer_pull_diagnostics_result_ids: HashMap<
  306        LanguageServerId,
  307        HashMap<Option<SharedString>, HashMap<PathBuf, Option<SharedString>>>,
  308    >,
  309    workspace_pull_diagnostics_result_ids: HashMap<
  310        LanguageServerId,
  311        HashMap<Option<SharedString>, HashMap<PathBuf, Option<SharedString>>>,
  312    >,
  313    restricted_worktrees_tasks: HashMap<WorktreeId, (Subscription, watch::Receiver<bool>)>,
  314
  315    buffers_to_refresh_hash_set: HashSet<BufferId>,
  316    buffers_to_refresh_queue: VecDeque<BufferId>,
  317    _background_diagnostics_worker: Shared<Task<()>>,
  318}
  319
  320impl LocalLspStore {
  321    /// Returns the running language server for the given ID. Note if the language server is starting, it will not be returned.
  322    pub fn running_language_server_for_id(
  323        &self,
  324        id: LanguageServerId,
  325    ) -> Option<&Arc<LanguageServer>> {
  326        let language_server_state = self.language_servers.get(&id)?;
  327
  328        match language_server_state {
  329            LanguageServerState::Running { server, .. } => Some(server),
  330            LanguageServerState::Starting { .. } => None,
  331        }
  332    }
  333
  334    fn get_or_insert_language_server(
  335        &mut self,
  336        worktree_handle: &Entity<Worktree>,
  337        delegate: Arc<LocalLspAdapterDelegate>,
  338        disposition: &Arc<LaunchDisposition>,
  339        language_name: &LanguageName,
  340        cx: &mut App,
  341    ) -> LanguageServerId {
  342        let key = LanguageServerSeed {
  343            worktree_id: worktree_handle.read(cx).id(),
  344            name: disposition.server_name.clone(),
  345            settings: LanguageServerSeedSettings {
  346                binary: disposition.settings.binary.clone(),
  347                initialization_options: disposition.settings.initialization_options.clone(),
  348            },
  349            toolchain: disposition.toolchain.clone(),
  350        };
  351        if let Some(state) = self.language_server_ids.get_mut(&key) {
  352            state.project_roots.insert(disposition.path.path.clone());
  353            state.id
  354        } else {
  355            let adapter = self
  356                .languages
  357                .lsp_adapters(language_name)
  358                .into_iter()
  359                .find(|adapter| adapter.name() == disposition.server_name)
  360                .expect("To find LSP adapter");
  361            let new_language_server_id = self.start_language_server(
  362                worktree_handle,
  363                delegate,
  364                adapter,
  365                disposition.settings.clone(),
  366                key.clone(),
  367                cx,
  368            );
  369            if let Some(state) = self.language_server_ids.get_mut(&key) {
  370                state.project_roots.insert(disposition.path.path.clone());
  371            } else {
  372                debug_assert!(
  373                    false,
  374                    "Expected `start_language_server` to ensure that `key` exists in a map"
  375                );
  376            }
  377            new_language_server_id
  378        }
  379    }
  380
  381    fn start_language_server(
  382        &mut self,
  383        worktree_handle: &Entity<Worktree>,
  384        delegate: Arc<LocalLspAdapterDelegate>,
  385        adapter: Arc<CachedLspAdapter>,
  386        settings: Arc<LspSettings>,
  387        key: LanguageServerSeed,
  388        cx: &mut App,
  389    ) -> LanguageServerId {
  390        let worktree = worktree_handle.read(cx);
  391
  392        let worktree_id = worktree.id();
  393        let worktree_abs_path = worktree.abs_path();
  394        let toolchain = key.toolchain.clone();
  395        let override_options = settings.initialization_options.clone();
  396
  397        let stderr_capture = Arc::new(Mutex::new(Some(String::new())));
  398
  399        let server_id = self.languages.next_language_server_id();
  400        log::trace!(
  401            "attempting to start language server {:?}, path: {worktree_abs_path:?}, id: {server_id}",
  402            adapter.name.0
  403        );
  404
  405        let wait_until_worktree_trust =
  406            TrustedWorktrees::try_get_global(cx).and_then(|trusted_worktrees| {
  407                let can_trust = trusted_worktrees.update(cx, |trusted_worktrees, cx| {
  408                    trusted_worktrees.can_trust(&self.worktree_store, worktree_id, cx)
  409                });
  410                if can_trust {
  411                    self.restricted_worktrees_tasks.remove(&worktree_id);
  412                    None
  413                } else {
  414                    match self.restricted_worktrees_tasks.entry(worktree_id) {
  415                        hash_map::Entry::Occupied(o) => Some(o.get().1.clone()),
  416                        hash_map::Entry::Vacant(v) => {
  417                            let (mut tx, rx) = watch::channel::<bool>();
  418                            let lsp_store = self.weak.clone();
  419                            let subscription = cx.subscribe(&trusted_worktrees, move |_, e, cx| {
  420                                if let TrustedWorktreesEvent::Trusted(_, trusted_paths) = e {
  421                                    if trusted_paths.contains(&PathTrust::Worktree(worktree_id)) {
  422                                        tx.blocking_send(true).ok();
  423                                        lsp_store
  424                                            .update(cx, |lsp_store, _| {
  425                                                if let Some(local_lsp_store) =
  426                                                    lsp_store.as_local_mut()
  427                                                {
  428                                                    local_lsp_store
  429                                                        .restricted_worktrees_tasks
  430                                                        .remove(&worktree_id);
  431                                                }
  432                                            })
  433                                            .ok();
  434                                    }
  435                                }
  436                            });
  437                            v.insert((subscription, rx.clone()));
  438                            Some(rx)
  439                        }
  440                    }
  441                }
  442            });
  443        let update_binary_status = wait_until_worktree_trust.is_none();
  444
  445        let binary = self.get_language_server_binary(
  446            worktree_abs_path.clone(),
  447            adapter.clone(),
  448            settings,
  449            toolchain.clone(),
  450            delegate.clone(),
  451            true,
  452            wait_until_worktree_trust,
  453            cx,
  454        );
  455        let pending_workspace_folders = Arc::<Mutex<BTreeSet<Uri>>>::default();
  456
  457        let pending_server = cx.spawn({
  458            let adapter = adapter.clone();
  459            let server_name = adapter.name.clone();
  460            let stderr_capture = stderr_capture.clone();
  461            #[cfg(any(test, feature = "test-support"))]
  462            let lsp_store = self.weak.clone();
  463            let pending_workspace_folders = pending_workspace_folders.clone();
  464            async move |cx| {
  465                let binary = binary.await?;
  466                #[cfg(any(test, feature = "test-support"))]
  467                if let Some(server) = lsp_store
  468                    .update(&mut cx.clone(), |this, cx| {
  469                        this.languages.create_fake_language_server(
  470                            server_id,
  471                            &server_name,
  472                            binary.clone(),
  473                            &mut cx.to_async(),
  474                        )
  475                    })
  476                    .ok()
  477                    .flatten()
  478                {
  479                    return Ok(server);
  480                }
  481
  482                let code_action_kinds = adapter.code_action_kinds();
  483                lsp::LanguageServer::new(
  484                    stderr_capture,
  485                    server_id,
  486                    server_name,
  487                    binary,
  488                    &worktree_abs_path,
  489                    code_action_kinds,
  490                    Some(pending_workspace_folders),
  491                    cx,
  492                )
  493            }
  494        });
  495
  496        let startup = {
  497            let server_name = adapter.name.0.clone();
  498            let delegate = delegate as Arc<dyn LspAdapterDelegate>;
  499            let key = key.clone();
  500            let adapter = adapter.clone();
  501            let lsp_store = self.weak.clone();
  502            let pending_workspace_folders = pending_workspace_folders.clone();
  503
  504            let pull_diagnostics = ProjectSettings::get_global(cx)
  505                .diagnostics
  506                .lsp_pull_diagnostics
  507                .enabled;
  508            cx.spawn(async move |cx| {
  509                let result = async {
  510                    let language_server = pending_server.await?;
  511
  512                    let workspace_config = Self::workspace_configuration_for_adapter(
  513                        adapter.adapter.clone(),
  514                        &delegate,
  515                        toolchain,
  516                        None,
  517                        cx,
  518                    )
  519                    .await?;
  520
  521                    let mut initialization_options = Self::initialization_options_for_adapter(
  522                        adapter.adapter.clone(),
  523                        &delegate,
  524                    )
  525                    .await?;
  526
  527                    match (&mut initialization_options, override_options) {
  528                        (Some(initialization_options), Some(override_options)) => {
  529                            merge_json_value_into(override_options, initialization_options);
  530                        }
  531                        (None, override_options) => initialization_options = override_options,
  532                        _ => {}
  533                    }
  534
  535                    let initialization_params = cx.update(|cx| {
  536                        let mut params =
  537                            language_server.default_initialize_params(pull_diagnostics, cx);
  538                        params.initialization_options = initialization_options;
  539                        adapter.adapter.prepare_initialize_params(params, cx)
  540                    })?;
  541
  542                    Self::setup_lsp_messages(
  543                        lsp_store.clone(),
  544                        &language_server,
  545                        delegate.clone(),
  546                        adapter.clone(),
  547                    );
  548
  549                    let did_change_configuration_params = lsp::DidChangeConfigurationParams {
  550                        settings: workspace_config,
  551                    };
  552                    let language_server = cx
  553                        .update(|cx| {
  554                            language_server.initialize(
  555                                initialization_params,
  556                                Arc::new(did_change_configuration_params.clone()),
  557                                cx,
  558                            )
  559                        })
  560                        .await
  561                        .inspect_err(|_| {
  562                            if let Some(lsp_store) = lsp_store.upgrade() {
  563                                lsp_store.update(cx, |lsp_store, cx| {
  564                                    lsp_store.cleanup_lsp_data(server_id);
  565                                    cx.emit(LspStoreEvent::LanguageServerRemoved(server_id))
  566                                });
  567                            }
  568                        })?;
  569
  570                    language_server.notify::<lsp::notification::DidChangeConfiguration>(
  571                        did_change_configuration_params,
  572                    )?;
  573
  574                    anyhow::Ok(language_server)
  575                }
  576                .await;
  577
  578                match result {
  579                    Ok(server) => {
  580                        lsp_store
  581                            .update(cx, |lsp_store, cx| {
  582                                lsp_store.insert_newly_running_language_server(
  583                                    adapter,
  584                                    server.clone(),
  585                                    server_id,
  586                                    key,
  587                                    pending_workspace_folders,
  588                                    cx,
  589                                );
  590                            })
  591                            .ok();
  592                        stderr_capture.lock().take();
  593                        Some(server)
  594                    }
  595
  596                    Err(err) => {
  597                        let log = stderr_capture.lock().take().unwrap_or_default();
  598                        delegate.update_status(
  599                            adapter.name(),
  600                            BinaryStatus::Failed {
  601                                error: if log.is_empty() {
  602                                    format!("{err:#}")
  603                                } else {
  604                                    format!("{err:#}\n-- stderr --\n{log}")
  605                                },
  606                            },
  607                        );
  608                        log::error!(
  609                            "Failed to start language server {server_name:?}: {}",
  610                            redact_command(&format!("{err:?}"))
  611                        );
  612                        if !log.is_empty() {
  613                            log::error!("server stderr: {}", redact_command(&log));
  614                        }
  615                        None
  616                    }
  617                }
  618            })
  619        };
  620        let state = LanguageServerState::Starting {
  621            startup,
  622            pending_workspace_folders,
  623        };
  624
  625        if update_binary_status {
  626            self.languages
  627                .update_lsp_binary_status(adapter.name(), BinaryStatus::Starting);
  628        }
  629
  630        self.language_servers.insert(server_id, state);
  631        self.language_server_ids
  632            .entry(key)
  633            .or_insert(UnifiedLanguageServer {
  634                id: server_id,
  635                project_roots: Default::default(),
  636            });
  637        server_id
  638    }
  639
  640    fn get_language_server_binary(
  641        &self,
  642        worktree_abs_path: Arc<Path>,
  643        adapter: Arc<CachedLspAdapter>,
  644        settings: Arc<LspSettings>,
  645        toolchain: Option<Toolchain>,
  646        delegate: Arc<dyn LspAdapterDelegate>,
  647        allow_binary_download: bool,
  648        wait_until_worktree_trust: Option<watch::Receiver<bool>>,
  649        cx: &mut App,
  650    ) -> Task<Result<LanguageServerBinary>> {
  651        if let Some(settings) = &settings.binary
  652            && let Some(path) = settings.path.as_ref().map(PathBuf::from)
  653        {
  654            let settings = settings.clone();
  655            let languages = self.languages.clone();
  656            return cx.background_spawn(async move {
  657                if let Some(mut wait_until_worktree_trust) = wait_until_worktree_trust {
  658                    let already_trusted =  *wait_until_worktree_trust.borrow();
  659                    if !already_trusted {
  660                        log::info!(
  661                            "Waiting for worktree {worktree_abs_path:?} to be trusted, before starting language server {}",
  662                            adapter.name(),
  663                        );
  664                        while let Some(worktree_trusted) = wait_until_worktree_trust.recv().await {
  665                            if worktree_trusted {
  666                                break;
  667                            }
  668                        }
  669                        log::info!(
  670                            "Worktree {worktree_abs_path:?} is trusted, starting language server {}",
  671                            adapter.name(),
  672                        );
  673                    }
  674                    languages
  675                        .update_lsp_binary_status(adapter.name(), BinaryStatus::Starting);
  676                }
  677                let mut env = delegate.shell_env().await;
  678                env.extend(settings.env.unwrap_or_default());
  679
  680                Ok(LanguageServerBinary {
  681                    path: delegate.resolve_executable_path(path),
  682                    env: Some(env),
  683                    arguments: settings
  684                        .arguments
  685                        .unwrap_or_default()
  686                        .iter()
  687                        .map(Into::into)
  688                        .collect(),
  689                })
  690            });
  691        }
  692        let lsp_binary_options = LanguageServerBinaryOptions {
  693            allow_path_lookup: !settings
  694                .binary
  695                .as_ref()
  696                .and_then(|b| b.ignore_system_version)
  697                .unwrap_or_default(),
  698            allow_binary_download,
  699            pre_release: settings
  700                .fetch
  701                .as_ref()
  702                .and_then(|f| f.pre_release)
  703                .unwrap_or(false),
  704        };
  705
  706        cx.spawn(async move |cx| {
  707            if let Some(mut wait_until_worktree_trust) = wait_until_worktree_trust {
  708                let already_trusted =  *wait_until_worktree_trust.borrow();
  709                if !already_trusted {
  710                    log::info!(
  711                        "Waiting for worktree {worktree_abs_path:?} to be trusted, before starting language server {}",
  712                        adapter.name(),
  713                    );
  714                    while let Some(worktree_trusted) = wait_until_worktree_trust.recv().await {
  715                        if worktree_trusted {
  716                            break;
  717                        }
  718                    }
  719                    log::info!(
  720                        "Worktree {worktree_abs_path:?} is trusted, starting language server {}",
  721                            adapter.name(),
  722                    );
  723                }
  724            }
  725
  726            let (existing_binary, maybe_download_binary) = adapter
  727                .clone()
  728                .get_language_server_command(delegate.clone(), toolchain, lsp_binary_options, cx)
  729                .await
  730                .await;
  731
  732            delegate.update_status(adapter.name.clone(), BinaryStatus::None);
  733
  734            let mut binary = match (existing_binary, maybe_download_binary) {
  735                (binary, None) => binary?,
  736                (Err(_), Some(downloader)) => downloader.await?,
  737                (Ok(existing_binary), Some(downloader)) => {
  738                    let mut download_timeout = cx
  739                        .background_executor()
  740                        .timer(SERVER_DOWNLOAD_TIMEOUT)
  741                        .fuse();
  742                    let mut downloader = downloader.fuse();
  743                    futures::select! {
  744                        _ = download_timeout => {
  745                            // Return existing binary and kick the existing work to the background.
  746                            cx.spawn(async move |_| downloader.await).detach();
  747                            Ok(existing_binary)
  748                        },
  749                        downloaded_or_existing_binary = downloader => {
  750                            // If download fails, this results in the existing binary.
  751                            downloaded_or_existing_binary
  752                        }
  753                    }?
  754                }
  755            };
  756            let mut shell_env = delegate.shell_env().await;
  757
  758            shell_env.extend(binary.env.unwrap_or_default());
  759
  760            if let Some(settings) = settings.binary.as_ref() {
  761                if let Some(arguments) = &settings.arguments {
  762                    binary.arguments = arguments.iter().map(Into::into).collect();
  763                }
  764                if let Some(env) = &settings.env {
  765                    shell_env.extend(env.iter().map(|(k, v)| (k.clone(), v.clone())));
  766                }
  767            }
  768
  769            binary.env = Some(shell_env);
  770            Ok(binary)
  771        })
  772    }
  773
  774    fn setup_lsp_messages(
  775        lsp_store: WeakEntity<LspStore>,
  776        language_server: &LanguageServer,
  777        delegate: Arc<dyn LspAdapterDelegate>,
  778        adapter: Arc<CachedLspAdapter>,
  779    ) {
  780        let name = language_server.name();
  781        let server_id = language_server.server_id();
  782        language_server
  783            .on_notification::<lsp::notification::PublishDiagnostics, _>({
  784                let adapter = adapter.clone();
  785                let this = lsp_store.clone();
  786                move |mut params, cx| {
  787                    let adapter = adapter.clone();
  788                    if let Some(this) = this.upgrade() {
  789                        this.update(cx, |this, cx| {
  790                            {
  791                                let buffer = params
  792                                    .uri
  793                                    .to_file_path()
  794                                    .map(|file_path| this.get_buffer(&file_path, cx))
  795                                    .ok()
  796                                    .flatten();
  797                                adapter.process_diagnostics(&mut params, server_id, buffer);
  798                            }
  799
  800                            this.merge_lsp_diagnostics(
  801                                DiagnosticSourceKind::Pushed,
  802                                vec![DocumentDiagnosticsUpdate {
  803                                    server_id,
  804                                    diagnostics: params,
  805                                    result_id: None,
  806                                    disk_based_sources: Cow::Borrowed(
  807                                        &adapter.disk_based_diagnostic_sources,
  808                                    ),
  809                                    registration_id: None,
  810                                }],
  811                                |_, diagnostic, cx| match diagnostic.source_kind {
  812                                    DiagnosticSourceKind::Other | DiagnosticSourceKind::Pushed => {
  813                                        adapter.retain_old_diagnostic(diagnostic, cx)
  814                                    }
  815                                    DiagnosticSourceKind::Pulled => true,
  816                                },
  817                                cx,
  818                            )
  819                            .log_err();
  820                        });
  821                    }
  822                }
  823            })
  824            .detach();
  825        language_server
  826            .on_request::<lsp::request::WorkspaceConfiguration, _, _>({
  827                let adapter = adapter.adapter.clone();
  828                let delegate = delegate.clone();
  829                let this = lsp_store.clone();
  830                move |params, cx| {
  831                    let adapter = adapter.clone();
  832                    let delegate = delegate.clone();
  833                    let this = this.clone();
  834                    let mut cx = cx.clone();
  835                    async move {
  836                        let toolchain_for_id = this
  837                            .update(&mut cx, |this, _| {
  838                                this.as_local()?.language_server_ids.iter().find_map(
  839                                    |(seed, value)| {
  840                                        (value.id == server_id).then(|| seed.toolchain.clone())
  841                                    },
  842                                )
  843                            })?
  844                            .context("Expected the LSP store to be in a local mode")?;
  845
  846                        let mut scope_uri_to_workspace_config = BTreeMap::new();
  847                        for item in &params.items {
  848                            let scope_uri = item.scope_uri.clone();
  849                            let std::collections::btree_map::Entry::Vacant(new_scope_uri) =
  850                                scope_uri_to_workspace_config.entry(scope_uri.clone())
  851                            else {
  852                                // We've already queried workspace configuration of this URI.
  853                                continue;
  854                            };
  855                            let workspace_config = Self::workspace_configuration_for_adapter(
  856                                adapter.clone(),
  857                                &delegate,
  858                                toolchain_for_id.clone(),
  859                                scope_uri,
  860                                &mut cx,
  861                            )
  862                            .await?;
  863                            new_scope_uri.insert(workspace_config);
  864                        }
  865
  866                        Ok(params
  867                            .items
  868                            .into_iter()
  869                            .filter_map(|item| {
  870                                let workspace_config =
  871                                    scope_uri_to_workspace_config.get(&item.scope_uri)?;
  872                                if let Some(section) = &item.section {
  873                                    Some(
  874                                        workspace_config
  875                                            .get(section)
  876                                            .cloned()
  877                                            .unwrap_or(serde_json::Value::Null),
  878                                    )
  879                                } else {
  880                                    Some(workspace_config.clone())
  881                                }
  882                            })
  883                            .collect())
  884                    }
  885                }
  886            })
  887            .detach();
  888
  889        language_server
  890            .on_request::<lsp::request::WorkspaceFoldersRequest, _, _>({
  891                let this = lsp_store.clone();
  892                move |_, cx| {
  893                    let this = this.clone();
  894                    let cx = cx.clone();
  895                    async move {
  896                        let Some(server) =
  897                            this.read_with(&cx, |this, _| this.language_server_for_id(server_id))?
  898                        else {
  899                            return Ok(None);
  900                        };
  901                        let root = server.workspace_folders();
  902                        Ok(Some(
  903                            root.into_iter()
  904                                .map(|uri| WorkspaceFolder {
  905                                    uri,
  906                                    name: Default::default(),
  907                                })
  908                                .collect(),
  909                        ))
  910                    }
  911                }
  912            })
  913            .detach();
  914        // Even though we don't have handling for these requests, respond to them to
  915        // avoid stalling any language server like `gopls` which waits for a response
  916        // to these requests when initializing.
  917        language_server
  918            .on_request::<lsp::request::WorkDoneProgressCreate, _, _>({
  919                let this = lsp_store.clone();
  920                move |params, cx| {
  921                    let this = this.clone();
  922                    let mut cx = cx.clone();
  923                    async move {
  924                        this.update(&mut cx, |this, _| {
  925                            if let Some(status) = this.language_server_statuses.get_mut(&server_id)
  926                            {
  927                                status
  928                                    .progress_tokens
  929                                    .insert(ProgressToken::from_lsp(params.token));
  930                            }
  931                        })?;
  932
  933                        Ok(())
  934                    }
  935                }
  936            })
  937            .detach();
  938
  939        language_server
  940            .on_request::<lsp::request::RegisterCapability, _, _>({
  941                let lsp_store = lsp_store.clone();
  942                move |params, cx| {
  943                    let lsp_store = lsp_store.clone();
  944                    let mut cx = cx.clone();
  945                    async move {
  946                        lsp_store
  947                            .update(&mut cx, |lsp_store, cx| {
  948                                if lsp_store.as_local().is_some() {
  949                                    match lsp_store
  950                                        .register_server_capabilities(server_id, params, cx)
  951                                    {
  952                                        Ok(()) => {}
  953                                        Err(e) => {
  954                                            log::error!(
  955                                                "Failed to register server capabilities: {e:#}"
  956                                            );
  957                                        }
  958                                    };
  959                                }
  960                            })
  961                            .ok();
  962                        Ok(())
  963                    }
  964                }
  965            })
  966            .detach();
  967
  968        language_server
  969            .on_request::<lsp::request::UnregisterCapability, _, _>({
  970                let lsp_store = lsp_store.clone();
  971                move |params, cx| {
  972                    let lsp_store = lsp_store.clone();
  973                    let mut cx = cx.clone();
  974                    async move {
  975                        lsp_store
  976                            .update(&mut cx, |lsp_store, cx| {
  977                                if lsp_store.as_local().is_some() {
  978                                    match lsp_store
  979                                        .unregister_server_capabilities(server_id, params, cx)
  980                                    {
  981                                        Ok(()) => {}
  982                                        Err(e) => {
  983                                            log::error!(
  984                                                "Failed to unregister server capabilities: {e:#}"
  985                                            );
  986                                        }
  987                                    }
  988                                }
  989                            })
  990                            .ok();
  991                        Ok(())
  992                    }
  993                }
  994            })
  995            .detach();
  996
  997        language_server
  998            .on_request::<lsp::request::ApplyWorkspaceEdit, _, _>({
  999                let this = lsp_store.clone();
 1000                move |params, cx| {
 1001                    let mut cx = cx.clone();
 1002                    let this = this.clone();
 1003                    async move {
 1004                        LocalLspStore::on_lsp_workspace_edit(
 1005                            this.clone(),
 1006                            params,
 1007                            server_id,
 1008                            &mut cx,
 1009                        )
 1010                        .await
 1011                    }
 1012                }
 1013            })
 1014            .detach();
 1015
 1016        language_server
 1017            .on_request::<lsp::request::InlayHintRefreshRequest, _, _>({
 1018                let lsp_store = lsp_store.clone();
 1019                let request_id = Arc::new(AtomicUsize::new(0));
 1020                move |(), cx| {
 1021                    let lsp_store = lsp_store.clone();
 1022                    let request_id = request_id.clone();
 1023                    let mut cx = cx.clone();
 1024                    async move {
 1025                        lsp_store
 1026                            .update(&mut cx, |lsp_store, cx| {
 1027                                let request_id =
 1028                                    Some(request_id.fetch_add(1, atomic::Ordering::AcqRel));
 1029                                cx.emit(LspStoreEvent::RefreshInlayHints {
 1030                                    server_id,
 1031                                    request_id,
 1032                                });
 1033                                lsp_store
 1034                                    .downstream_client
 1035                                    .as_ref()
 1036                                    .map(|(client, project_id)| {
 1037                                        client.send(proto::RefreshInlayHints {
 1038                                            project_id: *project_id,
 1039                                            server_id: server_id.to_proto(),
 1040                                            request_id: request_id.map(|id| id as u64),
 1041                                        })
 1042                                    })
 1043                            })?
 1044                            .transpose()?;
 1045                        Ok(())
 1046                    }
 1047                }
 1048            })
 1049            .detach();
 1050
 1051        language_server
 1052            .on_request::<lsp::request::CodeLensRefresh, _, _>({
 1053                let this = lsp_store.clone();
 1054                move |(), cx| {
 1055                    let this = this.clone();
 1056                    let mut cx = cx.clone();
 1057                    async move {
 1058                        this.update(&mut cx, |this, cx| {
 1059                            cx.emit(LspStoreEvent::RefreshCodeLens);
 1060                            this.downstream_client.as_ref().map(|(client, project_id)| {
 1061                                client.send(proto::RefreshCodeLens {
 1062                                    project_id: *project_id,
 1063                                })
 1064                            })
 1065                        })?
 1066                        .transpose()?;
 1067                        Ok(())
 1068                    }
 1069                }
 1070            })
 1071            .detach();
 1072
 1073        language_server
 1074            .on_request::<lsp::request::WorkspaceDiagnosticRefresh, _, _>({
 1075                let this = lsp_store.clone();
 1076                move |(), cx| {
 1077                    let this = this.clone();
 1078                    let mut cx = cx.clone();
 1079                    async move {
 1080                        this.update(&mut cx, |lsp_store, cx| {
 1081                            lsp_store.pull_workspace_diagnostics(server_id);
 1082                            lsp_store
 1083                                .downstream_client
 1084                                .as_ref()
 1085                                .map(|(client, project_id)| {
 1086                                    client.send(proto::PullWorkspaceDiagnostics {
 1087                                        project_id: *project_id,
 1088                                        server_id: server_id.to_proto(),
 1089                                    })
 1090                                })
 1091                                .transpose()?;
 1092                            anyhow::Ok(
 1093                                lsp_store.pull_document_diagnostics_for_server(server_id, None, cx),
 1094                            )
 1095                        })??
 1096                        .await;
 1097                        Ok(())
 1098                    }
 1099                }
 1100            })
 1101            .detach();
 1102
 1103        language_server
 1104            .on_request::<lsp::request::ShowMessageRequest, _, _>({
 1105                let this = lsp_store.clone();
 1106                let name = name.to_string();
 1107                let adapter = adapter.clone();
 1108                move |params, cx| {
 1109                    let this = this.clone();
 1110                    let name = name.to_string();
 1111                    let adapter = adapter.clone();
 1112                    let mut cx = cx.clone();
 1113                    async move {
 1114                        let actions = params.actions.unwrap_or_default();
 1115                        let message = params.message.clone();
 1116                        let (tx, rx) = smol::channel::bounded::<MessageActionItem>(1);
 1117                        let level = match params.typ {
 1118                            lsp::MessageType::ERROR => PromptLevel::Critical,
 1119                            lsp::MessageType::WARNING => PromptLevel::Warning,
 1120                            _ => PromptLevel::Info,
 1121                        };
 1122                        let request = LanguageServerPromptRequest::new(
 1123                            level,
 1124                            params.message,
 1125                            actions,
 1126                            name.clone(),
 1127                            tx,
 1128                        );
 1129
 1130                        let did_update = this
 1131                            .update(&mut cx, |_, cx| {
 1132                                cx.emit(LspStoreEvent::LanguageServerPrompt(request));
 1133                            })
 1134                            .is_ok();
 1135                        if did_update {
 1136                            let response = rx.recv().await.ok();
 1137                            if let Some(ref selected_action) = response {
 1138                                let context = language::PromptResponseContext {
 1139                                    message,
 1140                                    selected_action: selected_action.clone(),
 1141                                };
 1142                                adapter.process_prompt_response(&context, &mut cx)
 1143                            }
 1144
 1145                            Ok(response)
 1146                        } else {
 1147                            Ok(None)
 1148                        }
 1149                    }
 1150                }
 1151            })
 1152            .detach();
 1153        language_server
 1154            .on_notification::<lsp::notification::ShowMessage, _>({
 1155                let this = lsp_store.clone();
 1156                let name = name.to_string();
 1157                move |params, cx| {
 1158                    let this = this.clone();
 1159                    let name = name.to_string();
 1160                    let mut cx = cx.clone();
 1161
 1162                    let (tx, _) = smol::channel::bounded(1);
 1163                    let level = match params.typ {
 1164                        lsp::MessageType::ERROR => PromptLevel::Critical,
 1165                        lsp::MessageType::WARNING => PromptLevel::Warning,
 1166                        _ => PromptLevel::Info,
 1167                    };
 1168                    let request =
 1169                        LanguageServerPromptRequest::new(level, params.message, vec![], name, tx);
 1170
 1171                    let _ = this.update(&mut cx, |_, cx| {
 1172                        cx.emit(LspStoreEvent::LanguageServerPrompt(request));
 1173                    });
 1174                }
 1175            })
 1176            .detach();
 1177
 1178        let disk_based_diagnostics_progress_token =
 1179            adapter.disk_based_diagnostics_progress_token.clone();
 1180
 1181        language_server
 1182            .on_notification::<lsp::notification::Progress, _>({
 1183                let this = lsp_store.clone();
 1184                move |params, cx| {
 1185                    if let Some(this) = this.upgrade() {
 1186                        this.update(cx, |this, cx| {
 1187                            this.on_lsp_progress(
 1188                                params,
 1189                                server_id,
 1190                                disk_based_diagnostics_progress_token.clone(),
 1191                                cx,
 1192                            );
 1193                        });
 1194                    }
 1195                }
 1196            })
 1197            .detach();
 1198
 1199        language_server
 1200            .on_notification::<lsp::notification::LogMessage, _>({
 1201                let this = lsp_store.clone();
 1202                move |params, cx| {
 1203                    if let Some(this) = this.upgrade() {
 1204                        this.update(cx, |_, cx| {
 1205                            cx.emit(LspStoreEvent::LanguageServerLog(
 1206                                server_id,
 1207                                LanguageServerLogType::Log(params.typ),
 1208                                params.message,
 1209                            ));
 1210                        });
 1211                    }
 1212                }
 1213            })
 1214            .detach();
 1215
 1216        language_server
 1217            .on_notification::<lsp::notification::LogTrace, _>({
 1218                let this = lsp_store.clone();
 1219                move |params, cx| {
 1220                    let mut cx = cx.clone();
 1221                    if let Some(this) = this.upgrade() {
 1222                        this.update(&mut cx, |_, cx| {
 1223                            cx.emit(LspStoreEvent::LanguageServerLog(
 1224                                server_id,
 1225                                LanguageServerLogType::Trace {
 1226                                    verbose_info: params.verbose,
 1227                                },
 1228                                params.message,
 1229                            ));
 1230                        });
 1231                    }
 1232                }
 1233            })
 1234            .detach();
 1235
 1236        vue_language_server_ext::register_requests(lsp_store.clone(), language_server);
 1237        json_language_server_ext::register_requests(lsp_store.clone(), language_server);
 1238        rust_analyzer_ext::register_notifications(lsp_store.clone(), language_server);
 1239        clangd_ext::register_notifications(lsp_store, language_server, adapter);
 1240    }
 1241
 1242    fn shutdown_language_servers_on_quit(
 1243        &mut self,
 1244        _: &mut Context<LspStore>,
 1245    ) -> impl Future<Output = ()> + use<> {
 1246        let shutdown_futures = self
 1247            .language_servers
 1248            .drain()
 1249            .map(|(_, server_state)| Self::shutdown_server(server_state))
 1250            .collect::<Vec<_>>();
 1251
 1252        async move {
 1253            join_all(shutdown_futures).await;
 1254        }
 1255    }
 1256
 1257    async fn shutdown_server(server_state: LanguageServerState) -> anyhow::Result<()> {
 1258        match server_state {
 1259            LanguageServerState::Running { server, .. } => {
 1260                if let Some(shutdown) = server.shutdown() {
 1261                    shutdown.await;
 1262                }
 1263            }
 1264            LanguageServerState::Starting { startup, .. } => {
 1265                if let Some(server) = startup.await
 1266                    && let Some(shutdown) = server.shutdown()
 1267                {
 1268                    shutdown.await;
 1269                }
 1270            }
 1271        }
 1272        Ok(())
 1273    }
 1274
 1275    fn language_servers_for_worktree(
 1276        &self,
 1277        worktree_id: WorktreeId,
 1278    ) -> impl Iterator<Item = &Arc<LanguageServer>> {
 1279        self.language_server_ids
 1280            .iter()
 1281            .filter_map(move |(seed, state)| {
 1282                if seed.worktree_id != worktree_id {
 1283                    return None;
 1284                }
 1285
 1286                if let Some(LanguageServerState::Running { server, .. }) =
 1287                    self.language_servers.get(&state.id)
 1288                {
 1289                    Some(server)
 1290                } else {
 1291                    None
 1292                }
 1293            })
 1294    }
 1295
 1296    fn language_server_ids_for_project_path(
 1297        &self,
 1298        project_path: ProjectPath,
 1299        language: &Language,
 1300        cx: &mut App,
 1301    ) -> Vec<LanguageServerId> {
 1302        let Some(worktree) = self
 1303            .worktree_store
 1304            .read(cx)
 1305            .worktree_for_id(project_path.worktree_id, cx)
 1306        else {
 1307            return Vec::new();
 1308        };
 1309        let delegate: Arc<dyn ManifestDelegate> =
 1310            Arc::new(ManifestQueryDelegate::new(worktree.read(cx).snapshot()));
 1311
 1312        self.lsp_tree
 1313            .get(
 1314                project_path,
 1315                language.name(),
 1316                language.manifest(),
 1317                &delegate,
 1318                cx,
 1319            )
 1320            .collect::<Vec<_>>()
 1321    }
 1322
 1323    fn language_server_ids_for_buffer(
 1324        &self,
 1325        buffer: &Buffer,
 1326        cx: &mut App,
 1327    ) -> Vec<LanguageServerId> {
 1328        if let Some((file, language)) = File::from_dyn(buffer.file()).zip(buffer.language()) {
 1329            let worktree_id = file.worktree_id(cx);
 1330
 1331            let path: Arc<RelPath> = file
 1332                .path()
 1333                .parent()
 1334                .map(Arc::from)
 1335                .unwrap_or_else(|| file.path().clone());
 1336            let worktree_path = ProjectPath { worktree_id, path };
 1337            self.language_server_ids_for_project_path(worktree_path, language, cx)
 1338        } else {
 1339            Vec::new()
 1340        }
 1341    }
 1342
 1343    fn language_servers_for_buffer<'a>(
 1344        &'a self,
 1345        buffer: &'a Buffer,
 1346        cx: &'a mut App,
 1347    ) -> impl Iterator<Item = (&'a Arc<CachedLspAdapter>, &'a Arc<LanguageServer>)> {
 1348        self.language_server_ids_for_buffer(buffer, cx)
 1349            .into_iter()
 1350            .filter_map(|server_id| match self.language_servers.get(&server_id)? {
 1351                LanguageServerState::Running {
 1352                    adapter, server, ..
 1353                } => Some((adapter, server)),
 1354                _ => None,
 1355            })
 1356    }
 1357
 1358    async fn execute_code_action_kind_locally(
 1359        lsp_store: WeakEntity<LspStore>,
 1360        mut buffers: Vec<Entity<Buffer>>,
 1361        kind: CodeActionKind,
 1362        push_to_history: bool,
 1363        cx: &mut AsyncApp,
 1364    ) -> anyhow::Result<ProjectTransaction> {
 1365        // Do not allow multiple concurrent code actions requests for the
 1366        // same buffer.
 1367        lsp_store.update(cx, |this, cx| {
 1368            let this = this.as_local_mut().unwrap();
 1369            buffers.retain(|buffer| {
 1370                this.buffers_being_formatted
 1371                    .insert(buffer.read(cx).remote_id())
 1372            });
 1373        })?;
 1374        let _cleanup = defer({
 1375            let this = lsp_store.clone();
 1376            let mut cx = cx.clone();
 1377            let buffers = &buffers;
 1378            move || {
 1379                this.update(&mut cx, |this, cx| {
 1380                    let this = this.as_local_mut().unwrap();
 1381                    for buffer in buffers {
 1382                        this.buffers_being_formatted
 1383                            .remove(&buffer.read(cx).remote_id());
 1384                    }
 1385                })
 1386                .ok();
 1387            }
 1388        });
 1389        let mut project_transaction = ProjectTransaction::default();
 1390
 1391        for buffer in &buffers {
 1392            let adapters_and_servers = lsp_store.update(cx, |lsp_store, cx| {
 1393                buffer.update(cx, |buffer, cx| {
 1394                    lsp_store
 1395                        .as_local()
 1396                        .unwrap()
 1397                        .language_servers_for_buffer(buffer, cx)
 1398                        .map(|(adapter, lsp)| (adapter.clone(), lsp.clone()))
 1399                        .collect::<Vec<_>>()
 1400                })
 1401            })?;
 1402            for (_, language_server) in adapters_and_servers.iter() {
 1403                let actions = Self::get_server_code_actions_from_action_kinds(
 1404                    &lsp_store,
 1405                    language_server.server_id(),
 1406                    vec![kind.clone()],
 1407                    buffer,
 1408                    cx,
 1409                )
 1410                .await?;
 1411                Self::execute_code_actions_on_server(
 1412                    &lsp_store,
 1413                    language_server,
 1414                    actions,
 1415                    push_to_history,
 1416                    &mut project_transaction,
 1417                    cx,
 1418                )
 1419                .await?;
 1420            }
 1421        }
 1422        Ok(project_transaction)
 1423    }
 1424
 1425    async fn format_locally(
 1426        lsp_store: WeakEntity<LspStore>,
 1427        mut buffers: Vec<FormattableBuffer>,
 1428        push_to_history: bool,
 1429        trigger: FormatTrigger,
 1430        logger: zlog::Logger,
 1431        cx: &mut AsyncApp,
 1432    ) -> anyhow::Result<ProjectTransaction> {
 1433        // Do not allow multiple concurrent formatting requests for the
 1434        // same buffer.
 1435        lsp_store.update(cx, |this, cx| {
 1436            let this = this.as_local_mut().unwrap();
 1437            buffers.retain(|buffer| {
 1438                this.buffers_being_formatted
 1439                    .insert(buffer.handle.read(cx).remote_id())
 1440            });
 1441        })?;
 1442
 1443        let _cleanup = defer({
 1444            let this = lsp_store.clone();
 1445            let mut cx = cx.clone();
 1446            let buffers = &buffers;
 1447            move || {
 1448                this.update(&mut cx, |this, cx| {
 1449                    let this = this.as_local_mut().unwrap();
 1450                    for buffer in buffers {
 1451                        this.buffers_being_formatted
 1452                            .remove(&buffer.handle.read(cx).remote_id());
 1453                    }
 1454                })
 1455                .ok();
 1456            }
 1457        });
 1458
 1459        let mut project_transaction = ProjectTransaction::default();
 1460
 1461        for buffer in &buffers {
 1462            zlog::debug!(
 1463                logger =>
 1464                "formatting buffer '{:?}'",
 1465                buffer.abs_path.as_ref().unwrap_or(&PathBuf::from("unknown")).display()
 1466            );
 1467            // Create an empty transaction to hold all of the formatting edits.
 1468            let formatting_transaction_id = buffer.handle.update(cx, |buffer, cx| {
 1469                // ensure no transactions created while formatting are
 1470                // grouped with the previous transaction in the history
 1471                // based on the transaction group interval
 1472                buffer.finalize_last_transaction();
 1473                buffer
 1474                    .start_transaction()
 1475                    .context("transaction already open")?;
 1476                buffer.end_transaction(cx);
 1477                let transaction_id = buffer.push_empty_transaction(cx.background_executor().now());
 1478                buffer.finalize_last_transaction();
 1479                anyhow::Ok(transaction_id)
 1480            })?;
 1481
 1482            let result = Self::format_buffer_locally(
 1483                lsp_store.clone(),
 1484                buffer,
 1485                formatting_transaction_id,
 1486                trigger,
 1487                logger,
 1488                cx,
 1489            )
 1490            .await;
 1491
 1492            buffer.handle.update(cx, |buffer, cx| {
 1493                let Some(formatting_transaction) =
 1494                    buffer.get_transaction(formatting_transaction_id).cloned()
 1495                else {
 1496                    zlog::warn!(logger => "no formatting transaction");
 1497                    return;
 1498                };
 1499                if formatting_transaction.edit_ids.is_empty() {
 1500                    zlog::debug!(logger => "no changes made while formatting");
 1501                    buffer.forget_transaction(formatting_transaction_id);
 1502                    return;
 1503                }
 1504                if !push_to_history {
 1505                    zlog::trace!(logger => "forgetting format transaction");
 1506                    buffer.forget_transaction(formatting_transaction.id);
 1507                }
 1508                project_transaction
 1509                    .0
 1510                    .insert(cx.entity(), formatting_transaction);
 1511            });
 1512
 1513            result?;
 1514        }
 1515
 1516        Ok(project_transaction)
 1517    }
 1518
 1519    async fn format_buffer_locally(
 1520        lsp_store: WeakEntity<LspStore>,
 1521        buffer: &FormattableBuffer,
 1522        formatting_transaction_id: clock::Lamport,
 1523        trigger: FormatTrigger,
 1524        logger: zlog::Logger,
 1525        cx: &mut AsyncApp,
 1526    ) -> Result<()> {
 1527        let (adapters_and_servers, settings) = lsp_store.update(cx, |lsp_store, cx| {
 1528            buffer.handle.update(cx, |buffer, cx| {
 1529                let adapters_and_servers = lsp_store
 1530                    .as_local()
 1531                    .unwrap()
 1532                    .language_servers_for_buffer(buffer, cx)
 1533                    .map(|(adapter, lsp)| (adapter.clone(), lsp.clone()))
 1534                    .collect::<Vec<_>>();
 1535                let settings =
 1536                    language_settings(buffer.language().map(|l| l.name()), buffer.file(), cx)
 1537                        .into_owned();
 1538                (adapters_and_servers, settings)
 1539            })
 1540        })?;
 1541
 1542        /// Apply edits to the buffer that will become part of the formatting transaction.
 1543        /// Fails if the buffer has been edited since the start of that transaction.
 1544        fn extend_formatting_transaction(
 1545            buffer: &FormattableBuffer,
 1546            formatting_transaction_id: text::TransactionId,
 1547            cx: &mut AsyncApp,
 1548            operation: impl FnOnce(&mut Buffer, &mut Context<Buffer>),
 1549        ) -> anyhow::Result<()> {
 1550            buffer.handle.update(cx, |buffer, cx| {
 1551                let last_transaction_id = buffer.peek_undo_stack().map(|t| t.transaction_id());
 1552                if last_transaction_id != Some(formatting_transaction_id) {
 1553                    anyhow::bail!("Buffer edited while formatting. Aborting")
 1554                }
 1555                buffer.start_transaction();
 1556                operation(buffer, cx);
 1557                if let Some(transaction_id) = buffer.end_transaction(cx) {
 1558                    buffer.merge_transactions(transaction_id, formatting_transaction_id);
 1559                }
 1560                Ok(())
 1561            })
 1562        }
 1563
 1564        // handle whitespace formatting
 1565        if settings.remove_trailing_whitespace_on_save {
 1566            zlog::trace!(logger => "removing trailing whitespace");
 1567            let diff = buffer
 1568                .handle
 1569                .read_with(cx, |buffer, cx| buffer.remove_trailing_whitespace(cx))
 1570                .await;
 1571            extend_formatting_transaction(buffer, formatting_transaction_id, cx, |buffer, cx| {
 1572                buffer.apply_diff(diff, cx);
 1573            })?;
 1574        }
 1575
 1576        if settings.ensure_final_newline_on_save {
 1577            zlog::trace!(logger => "ensuring final newline");
 1578            extend_formatting_transaction(buffer, formatting_transaction_id, cx, |buffer, cx| {
 1579                buffer.ensure_final_newline(cx);
 1580            })?;
 1581        }
 1582
 1583        // Formatter for `code_actions_on_format` that runs before
 1584        // the rest of the formatters
 1585        let mut code_actions_on_format_formatters = None;
 1586        let should_run_code_actions_on_format = !matches!(
 1587            (trigger, &settings.format_on_save),
 1588            (FormatTrigger::Save, &FormatOnSave::Off)
 1589        );
 1590        if should_run_code_actions_on_format {
 1591            let have_code_actions_to_run_on_format = settings
 1592                .code_actions_on_format
 1593                .values()
 1594                .any(|enabled| *enabled);
 1595            if have_code_actions_to_run_on_format {
 1596                zlog::trace!(logger => "going to run code actions on format");
 1597                code_actions_on_format_formatters = Some(
 1598                    settings
 1599                        .code_actions_on_format
 1600                        .iter()
 1601                        .filter_map(|(action, enabled)| enabled.then_some(action))
 1602                        .cloned()
 1603                        .map(Formatter::CodeAction)
 1604                        .collect::<Vec<_>>(),
 1605                );
 1606            }
 1607        }
 1608
 1609        let formatters = match (trigger, &settings.format_on_save) {
 1610            (FormatTrigger::Save, FormatOnSave::Off) => &[],
 1611            (FormatTrigger::Manual, _) | (FormatTrigger::Save, FormatOnSave::On) => {
 1612                settings.formatter.as_ref()
 1613            }
 1614        };
 1615
 1616        let formatters = code_actions_on_format_formatters
 1617            .iter()
 1618            .flatten()
 1619            .chain(formatters);
 1620
 1621        for formatter in formatters {
 1622            let formatter = if formatter == &Formatter::Auto {
 1623                if settings.prettier.allowed {
 1624                    zlog::trace!(logger => "Formatter set to auto: defaulting to prettier");
 1625                    &Formatter::Prettier
 1626                } else {
 1627                    zlog::trace!(logger => "Formatter set to auto: defaulting to primary language server");
 1628                    &Formatter::LanguageServer(settings::LanguageServerFormatterSpecifier::Current)
 1629                }
 1630            } else {
 1631                formatter
 1632            };
 1633            match formatter {
 1634                Formatter::Auto => unreachable!("Auto resolved above"),
 1635                Formatter::Prettier => {
 1636                    let logger = zlog::scoped!(logger => "prettier");
 1637                    zlog::trace!(logger => "formatting");
 1638                    let _timer = zlog::time!(logger => "Formatting buffer via prettier");
 1639
 1640                    let prettier = lsp_store.read_with(cx, |lsp_store, _cx| {
 1641                        lsp_store.prettier_store().unwrap().downgrade()
 1642                    })?;
 1643                    let diff = prettier_store::format_with_prettier(&prettier, &buffer.handle, cx)
 1644                        .await
 1645                        .transpose()?;
 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::External { command, arguments } => {
 1661                    let logger = zlog::scoped!(logger => "command");
 1662                    zlog::trace!(logger => "formatting");
 1663                    let _timer = zlog::time!(logger => "Formatting buffer via external command");
 1664
 1665                    let diff = Self::format_via_external_command(
 1666                        buffer,
 1667                        &command,
 1668                        arguments.as_deref(),
 1669                        cx,
 1670                    )
 1671                    .await
 1672                    .with_context(|| {
 1673                        format!("Failed to format buffer via external command: {}", command)
 1674                    })?;
 1675                    let Some(diff) = diff else {
 1676                        zlog::trace!(logger => "No changes");
 1677                        continue;
 1678                    };
 1679
 1680                    extend_formatting_transaction(
 1681                        buffer,
 1682                        formatting_transaction_id,
 1683                        cx,
 1684                        |buffer, cx| {
 1685                            buffer.apply_diff(diff, cx);
 1686                        },
 1687                    )?;
 1688                }
 1689                Formatter::LanguageServer(specifier) => {
 1690                    let logger = zlog::scoped!(logger => "language-server");
 1691                    zlog::trace!(logger => "formatting");
 1692                    let _timer = zlog::time!(logger => "Formatting buffer using language server");
 1693
 1694                    let Some(buffer_path_abs) = buffer.abs_path.as_ref() else {
 1695                        zlog::warn!(logger => "Cannot format buffer that is not backed by a file on disk using language servers. Skipping");
 1696                        continue;
 1697                    };
 1698
 1699                    let language_server = match specifier {
 1700                        settings::LanguageServerFormatterSpecifier::Specific { name } => {
 1701                            adapters_and_servers.iter().find_map(|(adapter, server)| {
 1702                                if adapter.name.0.as_ref() == name {
 1703                                    Some(server.clone())
 1704                                } else {
 1705                                    None
 1706                                }
 1707                            })
 1708                        }
 1709                        settings::LanguageServerFormatterSpecifier::Current => {
 1710                            adapters_and_servers.first().map(|e| e.1.clone())
 1711                        }
 1712                    };
 1713
 1714                    let Some(language_server) = language_server else {
 1715                        log::debug!(
 1716                            "No language server found to format buffer '{:?}'. Skipping",
 1717                            buffer_path_abs.as_path().to_string_lossy()
 1718                        );
 1719                        continue;
 1720                    };
 1721
 1722                    zlog::trace!(
 1723                        logger =>
 1724                        "Formatting buffer '{:?}' using language server '{:?}'",
 1725                        buffer_path_abs.as_path().to_string_lossy(),
 1726                        language_server.name()
 1727                    );
 1728
 1729                    let edits = if let Some(ranges) = buffer.ranges.as_ref() {
 1730                        zlog::trace!(logger => "formatting ranges");
 1731                        Self::format_ranges_via_lsp(
 1732                            &lsp_store,
 1733                            &buffer.handle,
 1734                            ranges,
 1735                            buffer_path_abs,
 1736                            &language_server,
 1737                            &settings,
 1738                            cx,
 1739                        )
 1740                        .await
 1741                        .context("Failed to format ranges via language server")?
 1742                    } else {
 1743                        zlog::trace!(logger => "formatting full");
 1744                        Self::format_via_lsp(
 1745                            &lsp_store,
 1746                            &buffer.handle,
 1747                            buffer_path_abs,
 1748                            &language_server,
 1749                            &settings,
 1750                            cx,
 1751                        )
 1752                        .await
 1753                        .context("failed to format via language server")?
 1754                    };
 1755
 1756                    if edits.is_empty() {
 1757                        zlog::trace!(logger => "No changes");
 1758                        continue;
 1759                    }
 1760                    extend_formatting_transaction(
 1761                        buffer,
 1762                        formatting_transaction_id,
 1763                        cx,
 1764                        |buffer, cx| {
 1765                            buffer.edit(edits, None, cx);
 1766                        },
 1767                    )?;
 1768                }
 1769                Formatter::CodeAction(code_action_name) => {
 1770                    let logger = zlog::scoped!(logger => "code-actions");
 1771                    zlog::trace!(logger => "formatting");
 1772                    let _timer = zlog::time!(logger => "Formatting buffer using code actions");
 1773
 1774                    let Some(buffer_path_abs) = buffer.abs_path.as_ref() else {
 1775                        zlog::warn!(logger => "Cannot format buffer that is not backed by a file on disk using code actions. Skipping");
 1776                        continue;
 1777                    };
 1778
 1779                    let code_action_kind: CodeActionKind = code_action_name.clone().into();
 1780                    zlog::trace!(logger => "Attempting to resolve code actions {:?}", &code_action_kind);
 1781
 1782                    let mut actions_and_servers = Vec::new();
 1783
 1784                    for (index, (_, language_server)) in adapters_and_servers.iter().enumerate() {
 1785                        let actions_result = Self::get_server_code_actions_from_action_kinds(
 1786                            &lsp_store,
 1787                            language_server.server_id(),
 1788                            vec![code_action_kind.clone()],
 1789                            &buffer.handle,
 1790                            cx,
 1791                        )
 1792                        .await
 1793                        .with_context(|| {
 1794                            format!(
 1795                                "Failed to resolve code action {:?} with language server {}",
 1796                                code_action_kind,
 1797                                language_server.name()
 1798                            )
 1799                        });
 1800                        let Ok(actions) = actions_result else {
 1801                            // note: it may be better to set result to the error and break formatters here
 1802                            // but for now we try to execute the actions that we can resolve and skip the rest
 1803                            zlog::error!(
 1804                                logger =>
 1805                                "Failed to resolve code action {:?} with language server {}",
 1806                                code_action_kind,
 1807                                language_server.name()
 1808                            );
 1809                            continue;
 1810                        };
 1811                        for action in actions {
 1812                            actions_and_servers.push((action, index));
 1813                        }
 1814                    }
 1815
 1816                    if actions_and_servers.is_empty() {
 1817                        zlog::warn!(logger => "No code actions were resolved, continuing");
 1818                        continue;
 1819                    }
 1820
 1821                    'actions: for (mut action, server_index) in actions_and_servers {
 1822                        let server = &adapters_and_servers[server_index].1;
 1823
 1824                        let describe_code_action = |action: &CodeAction| {
 1825                            format!(
 1826                                "code action '{}' with title \"{}\" on server {}",
 1827                                action
 1828                                    .lsp_action
 1829                                    .action_kind()
 1830                                    .unwrap_or("unknown".into())
 1831                                    .as_str(),
 1832                                action.lsp_action.title(),
 1833                                server.name(),
 1834                            )
 1835                        };
 1836
 1837                        zlog::trace!(logger => "Executing {}", describe_code_action(&action));
 1838
 1839                        if let Err(err) = Self::try_resolve_code_action(server, &mut action).await {
 1840                            zlog::error!(
 1841                                logger =>
 1842                                "Failed to resolve {}. Error: {}",
 1843                                describe_code_action(&action),
 1844                                err
 1845                            );
 1846                            continue;
 1847                        }
 1848
 1849                        if let Some(edit) = action.lsp_action.edit().cloned() {
 1850                            // NOTE: code below duplicated from `Self::deserialize_workspace_edit`
 1851                            // but filters out and logs warnings for code actions that require unreasonably
 1852                            // difficult handling on our part, such as:
 1853                            // - applying edits that call commands
 1854                            //   which can result in arbitrary workspace edits being sent from the server that
 1855                            //   have no way of being tied back to the command that initiated them (i.e. we
 1856                            //   can't know which edits are part of the format request, or if the server is done sending
 1857                            //   actions in response to the command)
 1858                            // - actions that create/delete/modify/rename files other than the one we are formatting
 1859                            //   as we then would need to handle such changes correctly in the local history as well
 1860                            //   as the remote history through the ProjectTransaction
 1861                            // - actions with snippet edits, as these simply don't make sense in the context of a format request
 1862                            // Supporting these actions is not impossible, but not supported as of yet.
 1863                            if edit.changes.is_none() && edit.document_changes.is_none() {
 1864                                zlog::trace!(
 1865                                    logger =>
 1866                                    "No changes for code action. Skipping {}",
 1867                                    describe_code_action(&action),
 1868                                );
 1869                                continue;
 1870                            }
 1871
 1872                            let mut operations = Vec::new();
 1873                            if let Some(document_changes) = edit.document_changes {
 1874                                match document_changes {
 1875                                    lsp::DocumentChanges::Edits(edits) => operations.extend(
 1876                                        edits.into_iter().map(lsp::DocumentChangeOperation::Edit),
 1877                                    ),
 1878                                    lsp::DocumentChanges::Operations(ops) => operations = ops,
 1879                                }
 1880                            } else if let Some(changes) = edit.changes {
 1881                                operations.extend(changes.into_iter().map(|(uri, edits)| {
 1882                                    lsp::DocumentChangeOperation::Edit(lsp::TextDocumentEdit {
 1883                                        text_document:
 1884                                            lsp::OptionalVersionedTextDocumentIdentifier {
 1885                                                uri,
 1886                                                version: None,
 1887                                            },
 1888                                        edits: edits.into_iter().map(Edit::Plain).collect(),
 1889                                    })
 1890                                }));
 1891                            }
 1892
 1893                            let mut edits = Vec::with_capacity(operations.len());
 1894
 1895                            if operations.is_empty() {
 1896                                zlog::trace!(
 1897                                    logger =>
 1898                                    "No changes for code action. Skipping {}",
 1899                                    describe_code_action(&action),
 1900                                );
 1901                                continue;
 1902                            }
 1903                            for operation in operations {
 1904                                let op = match operation {
 1905                                    lsp::DocumentChangeOperation::Edit(op) => op,
 1906                                    lsp::DocumentChangeOperation::Op(_) => {
 1907                                        zlog::warn!(
 1908                                            logger =>
 1909                                            "Code actions which create, delete, or rename files are not supported on format. Skipping {}",
 1910                                            describe_code_action(&action),
 1911                                        );
 1912                                        continue 'actions;
 1913                                    }
 1914                                };
 1915                                let Ok(file_path) = op.text_document.uri.to_file_path() else {
 1916                                    zlog::warn!(
 1917                                        logger =>
 1918                                        "Failed to convert URI '{:?}' to file path. Skipping {}",
 1919                                        &op.text_document.uri,
 1920                                        describe_code_action(&action),
 1921                                    );
 1922                                    continue 'actions;
 1923                                };
 1924                                if &file_path != buffer_path_abs {
 1925                                    zlog::warn!(
 1926                                        logger =>
 1927                                        "File path '{:?}' does not match buffer path '{:?}'. Skipping {}",
 1928                                        file_path,
 1929                                        buffer_path_abs,
 1930                                        describe_code_action(&action),
 1931                                    );
 1932                                    continue 'actions;
 1933                                }
 1934
 1935                                let mut lsp_edits = Vec::new();
 1936                                for edit in op.edits {
 1937                                    match edit {
 1938                                        Edit::Plain(edit) => {
 1939                                            if !lsp_edits.contains(&edit) {
 1940                                                lsp_edits.push(edit);
 1941                                            }
 1942                                        }
 1943                                        Edit::Annotated(edit) => {
 1944                                            if !lsp_edits.contains(&edit.text_edit) {
 1945                                                lsp_edits.push(edit.text_edit);
 1946                                            }
 1947                                        }
 1948                                        Edit::Snippet(_) => {
 1949                                            zlog::warn!(
 1950                                                logger =>
 1951                                                "Code actions which produce snippet edits are not supported during formatting. Skipping {}",
 1952                                                describe_code_action(&action),
 1953                                            );
 1954                                            continue 'actions;
 1955                                        }
 1956                                    }
 1957                                }
 1958                                let edits_result = lsp_store
 1959                                    .update(cx, |lsp_store, cx| {
 1960                                        lsp_store.as_local_mut().unwrap().edits_from_lsp(
 1961                                            &buffer.handle,
 1962                                            lsp_edits,
 1963                                            server.server_id(),
 1964                                            op.text_document.version,
 1965                                            cx,
 1966                                        )
 1967                                    })?
 1968                                    .await;
 1969                                let Ok(resolved_edits) = edits_result else {
 1970                                    zlog::warn!(
 1971                                        logger =>
 1972                                        "Failed to resolve edits from LSP for buffer {:?} while handling {}",
 1973                                        buffer_path_abs.as_path(),
 1974                                        describe_code_action(&action),
 1975                                    );
 1976                                    continue 'actions;
 1977                                };
 1978                                edits.extend(resolved_edits);
 1979                            }
 1980
 1981                            if edits.is_empty() {
 1982                                zlog::warn!(logger => "No edits resolved from LSP");
 1983                                continue;
 1984                            }
 1985
 1986                            extend_formatting_transaction(
 1987                                buffer,
 1988                                formatting_transaction_id,
 1989                                cx,
 1990                                |buffer, cx| {
 1991                                    zlog::info!(
 1992                                        "Applying edits {edits:?}. Content: {:?}",
 1993                                        buffer.text()
 1994                                    );
 1995                                    buffer.edit(edits, None, cx);
 1996                                    zlog::info!("Applied edits. New Content: {:?}", buffer.text());
 1997                                },
 1998                            )?;
 1999                        }
 2000
 2001                        if let Some(command) = action.lsp_action.command() {
 2002                            zlog::warn!(
 2003                                logger =>
 2004                                "Executing code action command '{}'. This may cause formatting to abort unnecessarily as well as splitting formatting into two entries in the undo history",
 2005                                &command.command,
 2006                            );
 2007
 2008                            // bail early if command is invalid
 2009                            let server_capabilities = server.capabilities();
 2010                            let available_commands = server_capabilities
 2011                                .execute_command_provider
 2012                                .as_ref()
 2013                                .map(|options| options.commands.as_slice())
 2014                                .unwrap_or_default();
 2015                            if !available_commands.contains(&command.command) {
 2016                                zlog::warn!(
 2017                                    logger =>
 2018                                    "Cannot execute a command {} not listed in the language server capabilities of server {}",
 2019                                    command.command,
 2020                                    server.name(),
 2021                                );
 2022                                continue;
 2023                            }
 2024
 2025                            // noop so we just ensure buffer hasn't been edited since resolving code actions
 2026                            extend_formatting_transaction(
 2027                                buffer,
 2028                                formatting_transaction_id,
 2029                                cx,
 2030                                |_, _| {},
 2031                            )?;
 2032                            zlog::info!(logger => "Executing command {}", &command.command);
 2033
 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                            })?;
 2040
 2041                            let execute_command_result = server
 2042                                .request::<lsp::request::ExecuteCommand>(
 2043                                    lsp::ExecuteCommandParams {
 2044                                        command: command.command.clone(),
 2045                                        arguments: command.arguments.clone().unwrap_or_default(),
 2046                                        ..Default::default()
 2047                                    },
 2048                                )
 2049                                .await
 2050                                .into_response();
 2051
 2052                            if execute_command_result.is_err() {
 2053                                zlog::error!(
 2054                                    logger =>
 2055                                    "Failed to execute command '{}' as part of {}",
 2056                                    &command.command,
 2057                                    describe_code_action(&action),
 2058                                );
 2059                                continue 'actions;
 2060                            }
 2061
 2062                            let mut project_transaction_command =
 2063                                lsp_store.update(cx, |this, _| {
 2064                                    this.as_local_mut()
 2065                                        .unwrap()
 2066                                        .last_workspace_edits_by_language_server
 2067                                        .remove(&server.server_id())
 2068                                        .unwrap_or_default()
 2069                                })?;
 2070
 2071                            if let Some(transaction) =
 2072                                project_transaction_command.0.remove(&buffer.handle)
 2073                            {
 2074                                zlog::trace!(
 2075                                    logger =>
 2076                                    "Successfully captured {} edits that resulted from command {}",
 2077                                    transaction.edit_ids.len(),
 2078                                    &command.command,
 2079                                );
 2080                                let transaction_id_project_transaction = transaction.id;
 2081                                buffer.handle.update(cx, |buffer, _| {
 2082                                    // it may have been removed from history if push_to_history was
 2083                                    // false in deserialize_workspace_edit. If so push it so we
 2084                                    // can merge it with the format transaction
 2085                                    // and pop the combined transaction off the history stack
 2086                                    // later if push_to_history is false
 2087                                    if buffer.get_transaction(transaction.id).is_none() {
 2088                                        buffer.push_transaction(transaction, Instant::now());
 2089                                    }
 2090                                    buffer.merge_transactions(
 2091                                        transaction_id_project_transaction,
 2092                                        formatting_transaction_id,
 2093                                    );
 2094                                });
 2095                            }
 2096
 2097                            if !project_transaction_command.0.is_empty() {
 2098                                let mut extra_buffers = String::new();
 2099                                for buffer in project_transaction_command.0.keys() {
 2100                                    buffer.read_with(cx, |b, cx| {
 2101                                        if let Some(path) = b.project_path(cx) {
 2102                                            if !extra_buffers.is_empty() {
 2103                                                extra_buffers.push_str(", ");
 2104                                            }
 2105                                            extra_buffers.push_str(path.path.as_unix_str());
 2106                                        }
 2107                                    });
 2108                                }
 2109                                zlog::warn!(
 2110                                    logger =>
 2111                                    "Unexpected edits to buffers other than the buffer actively being formatted due to command {}. Impacted buffers: [{}].",
 2112                                    &command.command,
 2113                                    extra_buffers,
 2114                                );
 2115                                // NOTE: if this case is hit, the proper thing to do is to for each buffer, merge the extra transaction
 2116                                // into the existing transaction in project_transaction if there is one, and if there isn't one in project_transaction,
 2117                                // add it so it's included, and merge it into the format transaction when its created later
 2118                            }
 2119                        }
 2120                    }
 2121                }
 2122            }
 2123        }
 2124
 2125        Ok(())
 2126    }
 2127
 2128    pub async fn format_ranges_via_lsp(
 2129        this: &WeakEntity<LspStore>,
 2130        buffer_handle: &Entity<Buffer>,
 2131        ranges: &[Range<Anchor>],
 2132        abs_path: &Path,
 2133        language_server: &Arc<LanguageServer>,
 2134        settings: &LanguageSettings,
 2135        cx: &mut AsyncApp,
 2136    ) -> Result<Vec<(Range<Anchor>, Arc<str>)>> {
 2137        let capabilities = &language_server.capabilities();
 2138        let range_formatting_provider = capabilities.document_range_formatting_provider.as_ref();
 2139        if range_formatting_provider == Some(&OneOf::Left(false)) {
 2140            anyhow::bail!(
 2141                "{} language server does not support range formatting",
 2142                language_server.name()
 2143            );
 2144        }
 2145
 2146        let uri = file_path_to_lsp_url(abs_path)?;
 2147        let text_document = lsp::TextDocumentIdentifier::new(uri);
 2148
 2149        let lsp_edits = {
 2150            let mut lsp_ranges = Vec::new();
 2151            this.update(cx, |_this, cx| {
 2152                // TODO(#22930): In the case of formatting multibuffer selections, this buffer may
 2153                // not have been sent to the language server. This seems like a fairly systemic
 2154                // issue, though, the resolution probably is not specific to formatting.
 2155                //
 2156                // TODO: Instead of using current snapshot, should use the latest snapshot sent to
 2157                // LSP.
 2158                let snapshot = buffer_handle.read(cx).snapshot();
 2159                for range in ranges {
 2160                    lsp_ranges.push(range_to_lsp(range.to_point_utf16(&snapshot))?);
 2161                }
 2162                anyhow::Ok(())
 2163            })??;
 2164
 2165            let mut edits = None;
 2166            for range in lsp_ranges {
 2167                if let Some(mut edit) = language_server
 2168                    .request::<lsp::request::RangeFormatting>(lsp::DocumentRangeFormattingParams {
 2169                        text_document: text_document.clone(),
 2170                        range,
 2171                        options: lsp_command::lsp_formatting_options(settings),
 2172                        work_done_progress_params: Default::default(),
 2173                    })
 2174                    .await
 2175                    .into_response()?
 2176                {
 2177                    edits.get_or_insert_with(Vec::new).append(&mut edit);
 2178                }
 2179            }
 2180            edits
 2181        };
 2182
 2183        if let Some(lsp_edits) = lsp_edits {
 2184            this.update(cx, |this, cx| {
 2185                this.as_local_mut().unwrap().edits_from_lsp(
 2186                    buffer_handle,
 2187                    lsp_edits,
 2188                    language_server.server_id(),
 2189                    None,
 2190                    cx,
 2191                )
 2192            })?
 2193            .await
 2194        } else {
 2195            Ok(Vec::with_capacity(0))
 2196        }
 2197    }
 2198
 2199    async fn format_via_lsp(
 2200        this: &WeakEntity<LspStore>,
 2201        buffer: &Entity<Buffer>,
 2202        abs_path: &Path,
 2203        language_server: &Arc<LanguageServer>,
 2204        settings: &LanguageSettings,
 2205        cx: &mut AsyncApp,
 2206    ) -> Result<Vec<(Range<Anchor>, Arc<str>)>> {
 2207        let logger = zlog::scoped!("lsp_format");
 2208        zlog::debug!(logger => "Formatting via LSP");
 2209
 2210        let uri = file_path_to_lsp_url(abs_path)?;
 2211        let text_document = lsp::TextDocumentIdentifier::new(uri);
 2212        let capabilities = &language_server.capabilities();
 2213
 2214        let formatting_provider = capabilities.document_formatting_provider.as_ref();
 2215        let range_formatting_provider = capabilities.document_range_formatting_provider.as_ref();
 2216
 2217        let lsp_edits = if matches!(formatting_provider, Some(p) if *p != OneOf::Left(false)) {
 2218            let _timer = zlog::time!(logger => "format-full");
 2219            language_server
 2220                .request::<lsp::request::Formatting>(lsp::DocumentFormattingParams {
 2221                    text_document,
 2222                    options: lsp_command::lsp_formatting_options(settings),
 2223                    work_done_progress_params: Default::default(),
 2224                })
 2225                .await
 2226                .into_response()?
 2227        } else if matches!(range_formatting_provider, Some(p) if *p != OneOf::Left(false)) {
 2228            let _timer = zlog::time!(logger => "format-range");
 2229            let buffer_start = lsp::Position::new(0, 0);
 2230            let buffer_end = buffer.read_with(cx, |b, _| point_to_lsp(b.max_point_utf16()));
 2231            language_server
 2232                .request::<lsp::request::RangeFormatting>(lsp::DocumentRangeFormattingParams {
 2233                    text_document: text_document.clone(),
 2234                    range: lsp::Range::new(buffer_start, buffer_end),
 2235                    options: lsp_command::lsp_formatting_options(settings),
 2236                    work_done_progress_params: Default::default(),
 2237                })
 2238                .await
 2239                .into_response()?
 2240        } else {
 2241            None
 2242        };
 2243
 2244        if let Some(lsp_edits) = lsp_edits {
 2245            this.update(cx, |this, cx| {
 2246                this.as_local_mut().unwrap().edits_from_lsp(
 2247                    buffer,
 2248                    lsp_edits,
 2249                    language_server.server_id(),
 2250                    None,
 2251                    cx,
 2252                )
 2253            })?
 2254            .await
 2255        } else {
 2256            Ok(Vec::with_capacity(0))
 2257        }
 2258    }
 2259
 2260    async fn format_via_external_command(
 2261        buffer: &FormattableBuffer,
 2262        command: &str,
 2263        arguments: Option<&[String]>,
 2264        cx: &mut AsyncApp,
 2265    ) -> Result<Option<Diff>> {
 2266        let working_dir_path = buffer.handle.update(cx, |buffer, cx| {
 2267            let file = File::from_dyn(buffer.file())?;
 2268            let worktree = file.worktree.read(cx);
 2269            let mut worktree_path = worktree.abs_path().to_path_buf();
 2270            if worktree.root_entry()?.is_file() {
 2271                worktree_path.pop();
 2272            }
 2273            Some(worktree_path)
 2274        });
 2275
 2276        let mut child = util::command::new_smol_command(command);
 2277
 2278        if let Some(buffer_env) = buffer.env.as_ref() {
 2279            child.envs(buffer_env);
 2280        }
 2281
 2282        if let Some(working_dir_path) = working_dir_path {
 2283            child.current_dir(working_dir_path);
 2284        }
 2285
 2286        if let Some(arguments) = arguments {
 2287            child.args(arguments.iter().map(|arg| {
 2288                if let Some(buffer_abs_path) = buffer.abs_path.as_ref() {
 2289                    arg.replace("{buffer_path}", &buffer_abs_path.to_string_lossy())
 2290                } else {
 2291                    arg.replace("{buffer_path}", "Untitled")
 2292                }
 2293            }));
 2294        }
 2295
 2296        let mut child = child
 2297            .stdin(smol::process::Stdio::piped())
 2298            .stdout(smol::process::Stdio::piped())
 2299            .stderr(smol::process::Stdio::piped())
 2300            .spawn()?;
 2301
 2302        let stdin = child.stdin.as_mut().context("failed to acquire stdin")?;
 2303        let text = buffer
 2304            .handle
 2305            .read_with(cx, |buffer, _| buffer.as_rope().clone());
 2306        for chunk in text.chunks() {
 2307            stdin.write_all(chunk.as_bytes()).await?;
 2308        }
 2309        stdin.flush().await?;
 2310
 2311        let output = child.output().await?;
 2312        anyhow::ensure!(
 2313            output.status.success(),
 2314            "command failed with exit code {:?}:\nstdout: {}\nstderr: {}",
 2315            output.status.code(),
 2316            String::from_utf8_lossy(&output.stdout),
 2317            String::from_utf8_lossy(&output.stderr),
 2318        );
 2319
 2320        let stdout = String::from_utf8(output.stdout)?;
 2321        Ok(Some(
 2322            buffer
 2323                .handle
 2324                .update(cx, |buffer, cx| buffer.diff(stdout, cx))
 2325                .await,
 2326        ))
 2327    }
 2328
 2329    async fn try_resolve_code_action(
 2330        lang_server: &LanguageServer,
 2331        action: &mut CodeAction,
 2332    ) -> anyhow::Result<()> {
 2333        match &mut action.lsp_action {
 2334            LspAction::Action(lsp_action) => {
 2335                if !action.resolved
 2336                    && GetCodeActions::can_resolve_actions(&lang_server.capabilities())
 2337                    && lsp_action.data.is_some()
 2338                    && (lsp_action.command.is_none() || lsp_action.edit.is_none())
 2339                {
 2340                    **lsp_action = lang_server
 2341                        .request::<lsp::request::CodeActionResolveRequest>(*lsp_action.clone())
 2342                        .await
 2343                        .into_response()?;
 2344                }
 2345            }
 2346            LspAction::CodeLens(lens) => {
 2347                if !action.resolved && GetCodeLens::can_resolve_lens(&lang_server.capabilities()) {
 2348                    *lens = lang_server
 2349                        .request::<lsp::request::CodeLensResolve>(lens.clone())
 2350                        .await
 2351                        .into_response()?;
 2352                }
 2353            }
 2354            LspAction::Command(_) => {}
 2355        }
 2356
 2357        action.resolved = true;
 2358        anyhow::Ok(())
 2359    }
 2360
 2361    fn initialize_buffer(&mut self, buffer_handle: &Entity<Buffer>, cx: &mut Context<LspStore>) {
 2362        let buffer = buffer_handle.read(cx);
 2363
 2364        let file = buffer.file().cloned();
 2365
 2366        let Some(file) = File::from_dyn(file.as_ref()) else {
 2367            return;
 2368        };
 2369        if !file.is_local() {
 2370            return;
 2371        }
 2372        let path = ProjectPath::from_file(file, cx);
 2373        let worktree_id = file.worktree_id(cx);
 2374        let language = buffer.language().cloned();
 2375
 2376        if let Some(diagnostics) = self.diagnostics.get(&worktree_id) {
 2377            for (server_id, diagnostics) in
 2378                diagnostics.get(file.path()).cloned().unwrap_or_default()
 2379            {
 2380                self.update_buffer_diagnostics(
 2381                    buffer_handle,
 2382                    server_id,
 2383                    None,
 2384                    None,
 2385                    None,
 2386                    Vec::new(),
 2387                    diagnostics,
 2388                    cx,
 2389                )
 2390                .log_err();
 2391            }
 2392        }
 2393        let Some(language) = language else {
 2394            return;
 2395        };
 2396        let Some(snapshot) = self
 2397            .worktree_store
 2398            .read(cx)
 2399            .worktree_for_id(worktree_id, cx)
 2400            .map(|worktree| worktree.read(cx).snapshot())
 2401        else {
 2402            return;
 2403        };
 2404        let delegate: Arc<dyn ManifestDelegate> = Arc::new(ManifestQueryDelegate::new(snapshot));
 2405
 2406        for server_id in
 2407            self.lsp_tree
 2408                .get(path, language.name(), language.manifest(), &delegate, cx)
 2409        {
 2410            let server = self
 2411                .language_servers
 2412                .get(&server_id)
 2413                .and_then(|server_state| {
 2414                    if let LanguageServerState::Running { server, .. } = server_state {
 2415                        Some(server.clone())
 2416                    } else {
 2417                        None
 2418                    }
 2419                });
 2420            let server = match server {
 2421                Some(server) => server,
 2422                None => continue,
 2423            };
 2424
 2425            buffer_handle.update(cx, |buffer, cx| {
 2426                buffer.set_completion_triggers(
 2427                    server.server_id(),
 2428                    server
 2429                        .capabilities()
 2430                        .completion_provider
 2431                        .as_ref()
 2432                        .and_then(|provider| {
 2433                            provider
 2434                                .trigger_characters
 2435                                .as_ref()
 2436                                .map(|characters| characters.iter().cloned().collect())
 2437                        })
 2438                        .unwrap_or_default(),
 2439                    cx,
 2440                );
 2441            });
 2442        }
 2443    }
 2444
 2445    pub(crate) fn reset_buffer(&mut self, buffer: &Entity<Buffer>, old_file: &File, cx: &mut App) {
 2446        buffer.update(cx, |buffer, cx| {
 2447            let Some(language) = buffer.language() else {
 2448                return;
 2449            };
 2450            let path = ProjectPath {
 2451                worktree_id: old_file.worktree_id(cx),
 2452                path: old_file.path.clone(),
 2453            };
 2454            for server_id in self.language_server_ids_for_project_path(path, language, cx) {
 2455                buffer.update_diagnostics(server_id, DiagnosticSet::new([], buffer), cx);
 2456                buffer.set_completion_triggers(server_id, Default::default(), cx);
 2457            }
 2458        });
 2459    }
 2460
 2461    fn update_buffer_diagnostics(
 2462        &mut self,
 2463        buffer: &Entity<Buffer>,
 2464        server_id: LanguageServerId,
 2465        registration_id: Option<Option<SharedString>>,
 2466        result_id: Option<SharedString>,
 2467        version: Option<i32>,
 2468        new_diagnostics: Vec<DiagnosticEntry<Unclipped<PointUtf16>>>,
 2469        reused_diagnostics: Vec<DiagnosticEntry<Unclipped<PointUtf16>>>,
 2470        cx: &mut Context<LspStore>,
 2471    ) -> Result<()> {
 2472        fn compare_diagnostics(a: &Diagnostic, b: &Diagnostic) -> Ordering {
 2473            Ordering::Equal
 2474                .then_with(|| b.is_primary.cmp(&a.is_primary))
 2475                .then_with(|| a.is_disk_based.cmp(&b.is_disk_based))
 2476                .then_with(|| a.severity.cmp(&b.severity))
 2477                .then_with(|| a.message.cmp(&b.message))
 2478        }
 2479
 2480        let mut diagnostics = Vec::with_capacity(new_diagnostics.len() + reused_diagnostics.len());
 2481        diagnostics.extend(new_diagnostics.into_iter().map(|d| (true, d)));
 2482        diagnostics.extend(reused_diagnostics.into_iter().map(|d| (false, d)));
 2483
 2484        diagnostics.sort_unstable_by(|(_, a), (_, b)| {
 2485            Ordering::Equal
 2486                .then_with(|| a.range.start.cmp(&b.range.start))
 2487                .then_with(|| b.range.end.cmp(&a.range.end))
 2488                .then_with(|| compare_diagnostics(&a.diagnostic, &b.diagnostic))
 2489        });
 2490
 2491        let snapshot = self.buffer_snapshot_for_lsp_version(buffer, server_id, version, cx)?;
 2492
 2493        let edits_since_save = std::cell::LazyCell::new(|| {
 2494            let saved_version = buffer.read(cx).saved_version();
 2495            Patch::new(snapshot.edits_since::<PointUtf16>(saved_version).collect())
 2496        });
 2497
 2498        let mut sanitized_diagnostics = Vec::with_capacity(diagnostics.len());
 2499
 2500        for (new_diagnostic, entry) in diagnostics {
 2501            let start;
 2502            let end;
 2503            if new_diagnostic && entry.diagnostic.is_disk_based {
 2504                // Some diagnostics are based on files on disk instead of buffers'
 2505                // current contents. Adjust these diagnostics' ranges to reflect
 2506                // any unsaved edits.
 2507                // Do not alter the reused ones though, as their coordinates were stored as anchors
 2508                // and were properly adjusted on reuse.
 2509                start = Unclipped((*edits_since_save).old_to_new(entry.range.start.0));
 2510                end = Unclipped((*edits_since_save).old_to_new(entry.range.end.0));
 2511            } else {
 2512                start = entry.range.start;
 2513                end = entry.range.end;
 2514            }
 2515
 2516            let mut range = snapshot.clip_point_utf16(start, Bias::Left)
 2517                ..snapshot.clip_point_utf16(end, Bias::Right);
 2518
 2519            // Expand empty ranges by one codepoint
 2520            if range.start == range.end {
 2521                // This will be go to the next boundary when being clipped
 2522                range.end.column += 1;
 2523                range.end = snapshot.clip_point_utf16(Unclipped(range.end), Bias::Right);
 2524                if range.start == range.end && range.end.column > 0 {
 2525                    range.start.column -= 1;
 2526                    range.start = snapshot.clip_point_utf16(Unclipped(range.start), Bias::Left);
 2527                }
 2528            }
 2529
 2530            sanitized_diagnostics.push(DiagnosticEntry {
 2531                range,
 2532                diagnostic: entry.diagnostic,
 2533            });
 2534        }
 2535        drop(edits_since_save);
 2536
 2537        let set = DiagnosticSet::new(sanitized_diagnostics, &snapshot);
 2538        buffer.update(cx, |buffer, cx| {
 2539            if let Some(registration_id) = registration_id {
 2540                if let Some(abs_path) = File::from_dyn(buffer.file()).map(|f| f.abs_path(cx)) {
 2541                    self.buffer_pull_diagnostics_result_ids
 2542                        .entry(server_id)
 2543                        .or_default()
 2544                        .entry(registration_id)
 2545                        .or_default()
 2546                        .insert(abs_path, result_id);
 2547                }
 2548            }
 2549
 2550            buffer.update_diagnostics(server_id, set, cx)
 2551        });
 2552
 2553        Ok(())
 2554    }
 2555
 2556    fn register_language_server_for_invisible_worktree(
 2557        &mut self,
 2558        worktree: &Entity<Worktree>,
 2559        language_server_id: LanguageServerId,
 2560        cx: &mut App,
 2561    ) {
 2562        let worktree = worktree.read(cx);
 2563        let worktree_id = worktree.id();
 2564        debug_assert!(!worktree.is_visible());
 2565        let Some(mut origin_seed) = self
 2566            .language_server_ids
 2567            .iter()
 2568            .find_map(|(seed, state)| (state.id == language_server_id).then(|| seed.clone()))
 2569        else {
 2570            return;
 2571        };
 2572        origin_seed.worktree_id = worktree_id;
 2573        self.language_server_ids
 2574            .entry(origin_seed)
 2575            .or_insert_with(|| UnifiedLanguageServer {
 2576                id: language_server_id,
 2577                project_roots: Default::default(),
 2578            });
 2579    }
 2580
 2581    fn register_buffer_with_language_servers(
 2582        &mut self,
 2583        buffer_handle: &Entity<Buffer>,
 2584        only_register_servers: HashSet<LanguageServerSelector>,
 2585        cx: &mut Context<LspStore>,
 2586    ) {
 2587        let buffer = buffer_handle.read(cx);
 2588        let buffer_id = buffer.remote_id();
 2589
 2590        let Some(file) = File::from_dyn(buffer.file()) else {
 2591            return;
 2592        };
 2593        if !file.is_local() {
 2594            return;
 2595        }
 2596
 2597        let abs_path = file.abs_path(cx);
 2598        let Some(uri) = file_path_to_lsp_url(&abs_path).log_err() else {
 2599            return;
 2600        };
 2601        let initial_snapshot = buffer.text_snapshot();
 2602        let worktree_id = file.worktree_id(cx);
 2603
 2604        let Some(language) = buffer.language().cloned() else {
 2605            return;
 2606        };
 2607        let path: Arc<RelPath> = file
 2608            .path()
 2609            .parent()
 2610            .map(Arc::from)
 2611            .unwrap_or_else(|| file.path().clone());
 2612        let Some(worktree) = self
 2613            .worktree_store
 2614            .read(cx)
 2615            .worktree_for_id(worktree_id, cx)
 2616        else {
 2617            return;
 2618        };
 2619        let language_name = language.name();
 2620        let (reused, delegate, servers) = self
 2621            .reuse_existing_language_server(&self.lsp_tree, &worktree, &language_name, cx)
 2622            .map(|(delegate, apply)| (true, delegate, apply(&mut self.lsp_tree)))
 2623            .unwrap_or_else(|| {
 2624                let lsp_delegate = LocalLspAdapterDelegate::from_local_lsp(self, &worktree, cx);
 2625                let delegate: Arc<dyn ManifestDelegate> =
 2626                    Arc::new(ManifestQueryDelegate::new(worktree.read(cx).snapshot()));
 2627
 2628                let servers = self
 2629                    .lsp_tree
 2630                    .walk(
 2631                        ProjectPath { worktree_id, path },
 2632                        language.name(),
 2633                        language.manifest(),
 2634                        &delegate,
 2635                        cx,
 2636                    )
 2637                    .collect::<Vec<_>>();
 2638                (false, lsp_delegate, servers)
 2639            });
 2640        let servers_and_adapters = servers
 2641            .into_iter()
 2642            .filter_map(|server_node| {
 2643                if reused && server_node.server_id().is_none() {
 2644                    return None;
 2645                }
 2646                if !only_register_servers.is_empty() {
 2647                    if let Some(server_id) = server_node.server_id()
 2648                        && !only_register_servers.contains(&LanguageServerSelector::Id(server_id))
 2649                    {
 2650                        return None;
 2651                    }
 2652                    if let Some(name) = server_node.name()
 2653                        && !only_register_servers.contains(&LanguageServerSelector::Name(name))
 2654                    {
 2655                        return None;
 2656                    }
 2657                }
 2658
 2659                let server_id = server_node.server_id_or_init(|disposition| {
 2660                    let path = &disposition.path;
 2661
 2662                    {
 2663                        let uri = Uri::from_file_path(worktree.read(cx).absolutize(&path.path));
 2664
 2665                        let server_id = self.get_or_insert_language_server(
 2666                            &worktree,
 2667                            delegate.clone(),
 2668                            disposition,
 2669                            &language_name,
 2670                            cx,
 2671                        );
 2672
 2673                        if let Some(state) = self.language_servers.get(&server_id)
 2674                            && let Ok(uri) = uri
 2675                        {
 2676                            state.add_workspace_folder(uri);
 2677                        };
 2678                        server_id
 2679                    }
 2680                })?;
 2681                let server_state = self.language_servers.get(&server_id)?;
 2682                if let LanguageServerState::Running {
 2683                    server, adapter, ..
 2684                } = server_state
 2685                {
 2686                    Some((server.clone(), adapter.clone()))
 2687                } else {
 2688                    None
 2689                }
 2690            })
 2691            .collect::<Vec<_>>();
 2692        for (server, adapter) in servers_and_adapters {
 2693            buffer_handle.update(cx, |buffer, cx| {
 2694                buffer.set_completion_triggers(
 2695                    server.server_id(),
 2696                    server
 2697                        .capabilities()
 2698                        .completion_provider
 2699                        .as_ref()
 2700                        .and_then(|provider| {
 2701                            provider
 2702                                .trigger_characters
 2703                                .as_ref()
 2704                                .map(|characters| characters.iter().cloned().collect())
 2705                        })
 2706                        .unwrap_or_default(),
 2707                    cx,
 2708                );
 2709            });
 2710
 2711            let snapshot = LspBufferSnapshot {
 2712                version: 0,
 2713                snapshot: initial_snapshot.clone(),
 2714            };
 2715
 2716            let mut registered = false;
 2717            self.buffer_snapshots
 2718                .entry(buffer_id)
 2719                .or_default()
 2720                .entry(server.server_id())
 2721                .or_insert_with(|| {
 2722                    registered = true;
 2723                    server.register_buffer(
 2724                        uri.clone(),
 2725                        adapter.language_id(&language.name()),
 2726                        0,
 2727                        initial_snapshot.text(),
 2728                    );
 2729
 2730                    vec![snapshot]
 2731                });
 2732
 2733            self.buffers_opened_in_servers
 2734                .entry(buffer_id)
 2735                .or_default()
 2736                .insert(server.server_id());
 2737            if registered {
 2738                cx.emit(LspStoreEvent::LanguageServerUpdate {
 2739                    language_server_id: server.server_id(),
 2740                    name: None,
 2741                    message: proto::update_language_server::Variant::RegisteredForBuffer(
 2742                        proto::RegisteredForBuffer {
 2743                            buffer_abs_path: abs_path.to_string_lossy().into_owned(),
 2744                            buffer_id: buffer_id.to_proto(),
 2745                        },
 2746                    ),
 2747                });
 2748            }
 2749        }
 2750    }
 2751
 2752    fn reuse_existing_language_server<'lang_name>(
 2753        &self,
 2754        server_tree: &LanguageServerTree,
 2755        worktree: &Entity<Worktree>,
 2756        language_name: &'lang_name LanguageName,
 2757        cx: &mut App,
 2758    ) -> Option<(
 2759        Arc<LocalLspAdapterDelegate>,
 2760        impl FnOnce(&mut LanguageServerTree) -> Vec<LanguageServerTreeNode> + use<'lang_name>,
 2761    )> {
 2762        if worktree.read(cx).is_visible() {
 2763            return None;
 2764        }
 2765
 2766        let worktree_store = self.worktree_store.read(cx);
 2767        let servers = server_tree
 2768            .instances
 2769            .iter()
 2770            .filter(|(worktree_id, _)| {
 2771                worktree_store
 2772                    .worktree_for_id(**worktree_id, cx)
 2773                    .is_some_and(|worktree| worktree.read(cx).is_visible())
 2774            })
 2775            .flat_map(|(worktree_id, servers)| {
 2776                servers
 2777                    .roots
 2778                    .iter()
 2779                    .flat_map(|(_, language_servers)| language_servers)
 2780                    .map(move |(_, (server_node, server_languages))| {
 2781                        (worktree_id, server_node, server_languages)
 2782                    })
 2783                    .filter(|(_, _, server_languages)| server_languages.contains(language_name))
 2784                    .map(|(worktree_id, server_node, _)| {
 2785                        (
 2786                            *worktree_id,
 2787                            LanguageServerTreeNode::from(Arc::downgrade(server_node)),
 2788                        )
 2789                    })
 2790            })
 2791            .fold(HashMap::default(), |mut acc, (worktree_id, server_node)| {
 2792                acc.entry(worktree_id)
 2793                    .or_insert_with(Vec::new)
 2794                    .push(server_node);
 2795                acc
 2796            })
 2797            .into_values()
 2798            .max_by_key(|servers| servers.len())?;
 2799
 2800        let worktree_id = worktree.read(cx).id();
 2801        let apply = move |tree: &mut LanguageServerTree| {
 2802            for server_node in &servers {
 2803                tree.register_reused(worktree_id, language_name.clone(), server_node.clone());
 2804            }
 2805            servers
 2806        };
 2807
 2808        let delegate = LocalLspAdapterDelegate::from_local_lsp(self, worktree, cx);
 2809        Some((delegate, apply))
 2810    }
 2811
 2812    pub(crate) fn unregister_old_buffer_from_language_servers(
 2813        &mut self,
 2814        buffer: &Entity<Buffer>,
 2815        old_file: &File,
 2816        cx: &mut App,
 2817    ) {
 2818        let old_path = match old_file.as_local() {
 2819            Some(local) => local.abs_path(cx),
 2820            None => return,
 2821        };
 2822
 2823        let Ok(file_url) = lsp::Uri::from_file_path(old_path.as_path()) else {
 2824            debug_panic!("{old_path:?} is not parseable as an URI");
 2825            return;
 2826        };
 2827        self.unregister_buffer_from_language_servers(buffer, &file_url, cx);
 2828    }
 2829
 2830    pub(crate) fn unregister_buffer_from_language_servers(
 2831        &mut self,
 2832        buffer: &Entity<Buffer>,
 2833        file_url: &lsp::Uri,
 2834        cx: &mut App,
 2835    ) {
 2836        buffer.update(cx, |buffer, cx| {
 2837            let mut snapshots = self.buffer_snapshots.remove(&buffer.remote_id());
 2838
 2839            for (_, language_server) in self.language_servers_for_buffer(buffer, cx) {
 2840                if snapshots
 2841                    .as_mut()
 2842                    .is_some_and(|map| map.remove(&language_server.server_id()).is_some())
 2843                {
 2844                    language_server.unregister_buffer(file_url.clone());
 2845                }
 2846            }
 2847        });
 2848    }
 2849
 2850    fn buffer_snapshot_for_lsp_version(
 2851        &mut self,
 2852        buffer: &Entity<Buffer>,
 2853        server_id: LanguageServerId,
 2854        version: Option<i32>,
 2855        cx: &App,
 2856    ) -> Result<TextBufferSnapshot> {
 2857        const OLD_VERSIONS_TO_RETAIN: i32 = 10;
 2858
 2859        if let Some(version) = version {
 2860            let buffer_id = buffer.read(cx).remote_id();
 2861            let snapshots = if let Some(snapshots) = self
 2862                .buffer_snapshots
 2863                .get_mut(&buffer_id)
 2864                .and_then(|m| m.get_mut(&server_id))
 2865            {
 2866                snapshots
 2867            } else if version == 0 {
 2868                // Some language servers report version 0 even if the buffer hasn't been opened yet.
 2869                // We detect this case and treat it as if the version was `None`.
 2870                return Ok(buffer.read(cx).text_snapshot());
 2871            } else {
 2872                anyhow::bail!("no snapshots found for buffer {buffer_id} and server {server_id}");
 2873            };
 2874
 2875            let found_snapshot = snapshots
 2876                    .binary_search_by_key(&version, |e| e.version)
 2877                    .map(|ix| snapshots[ix].snapshot.clone())
 2878                    .map_err(|_| {
 2879                        anyhow!("snapshot not found for buffer {buffer_id} server {server_id} at version {version}")
 2880                    })?;
 2881
 2882            snapshots.retain(|snapshot| snapshot.version + OLD_VERSIONS_TO_RETAIN >= version);
 2883            Ok(found_snapshot)
 2884        } else {
 2885            Ok((buffer.read(cx)).text_snapshot())
 2886        }
 2887    }
 2888
 2889    async fn get_server_code_actions_from_action_kinds(
 2890        lsp_store: &WeakEntity<LspStore>,
 2891        language_server_id: LanguageServerId,
 2892        code_action_kinds: Vec<lsp::CodeActionKind>,
 2893        buffer: &Entity<Buffer>,
 2894        cx: &mut AsyncApp,
 2895    ) -> Result<Vec<CodeAction>> {
 2896        let actions = lsp_store
 2897            .update(cx, move |this, cx| {
 2898                let request = GetCodeActions {
 2899                    range: text::Anchor::min_max_range_for_buffer(buffer.read(cx).remote_id()),
 2900                    kinds: Some(code_action_kinds),
 2901                };
 2902                let server = LanguageServerToQuery::Other(language_server_id);
 2903                this.request_lsp(buffer.clone(), server, request, cx)
 2904            })?
 2905            .await?;
 2906        Ok(actions)
 2907    }
 2908
 2909    pub async fn execute_code_actions_on_server(
 2910        lsp_store: &WeakEntity<LspStore>,
 2911        language_server: &Arc<LanguageServer>,
 2912
 2913        actions: Vec<CodeAction>,
 2914        push_to_history: bool,
 2915        project_transaction: &mut ProjectTransaction,
 2916        cx: &mut AsyncApp,
 2917    ) -> anyhow::Result<()> {
 2918        for mut action in actions {
 2919            Self::try_resolve_code_action(language_server, &mut action)
 2920                .await
 2921                .context("resolving a formatting code action")?;
 2922
 2923            if let Some(edit) = action.lsp_action.edit() {
 2924                if edit.changes.is_none() && edit.document_changes.is_none() {
 2925                    continue;
 2926                }
 2927
 2928                let new = Self::deserialize_workspace_edit(
 2929                    lsp_store.upgrade().context("project dropped")?,
 2930                    edit.clone(),
 2931                    push_to_history,
 2932                    language_server.clone(),
 2933                    cx,
 2934                )
 2935                .await?;
 2936                project_transaction.0.extend(new.0);
 2937            }
 2938
 2939            if let Some(command) = action.lsp_action.command() {
 2940                let server_capabilities = language_server.capabilities();
 2941                let available_commands = server_capabilities
 2942                    .execute_command_provider
 2943                    .as_ref()
 2944                    .map(|options| options.commands.as_slice())
 2945                    .unwrap_or_default();
 2946                if available_commands.contains(&command.command) {
 2947                    lsp_store.update(cx, |lsp_store, _| {
 2948                        if let LspStoreMode::Local(mode) = &mut lsp_store.mode {
 2949                            mode.last_workspace_edits_by_language_server
 2950                                .remove(&language_server.server_id());
 2951                        }
 2952                    })?;
 2953
 2954                    language_server
 2955                        .request::<lsp::request::ExecuteCommand>(lsp::ExecuteCommandParams {
 2956                            command: command.command.clone(),
 2957                            arguments: command.arguments.clone().unwrap_or_default(),
 2958                            ..Default::default()
 2959                        })
 2960                        .await
 2961                        .into_response()
 2962                        .context("execute command")?;
 2963
 2964                    lsp_store.update(cx, |this, _| {
 2965                        if let LspStoreMode::Local(mode) = &mut this.mode {
 2966                            project_transaction.0.extend(
 2967                                mode.last_workspace_edits_by_language_server
 2968                                    .remove(&language_server.server_id())
 2969                                    .unwrap_or_default()
 2970                                    .0,
 2971                            )
 2972                        }
 2973                    })?;
 2974                } else {
 2975                    log::warn!(
 2976                        "Cannot execute a command {} not listed in the language server capabilities",
 2977                        command.command
 2978                    )
 2979                }
 2980            }
 2981        }
 2982        Ok(())
 2983    }
 2984
 2985    pub async fn deserialize_text_edits(
 2986        this: Entity<LspStore>,
 2987        buffer_to_edit: Entity<Buffer>,
 2988        edits: Vec<lsp::TextEdit>,
 2989        push_to_history: bool,
 2990        _: Arc<CachedLspAdapter>,
 2991        language_server: Arc<LanguageServer>,
 2992        cx: &mut AsyncApp,
 2993    ) -> Result<Option<Transaction>> {
 2994        let edits = this
 2995            .update(cx, |this, cx| {
 2996                this.as_local_mut().unwrap().edits_from_lsp(
 2997                    &buffer_to_edit,
 2998                    edits,
 2999                    language_server.server_id(),
 3000                    None,
 3001                    cx,
 3002                )
 3003            })
 3004            .await?;
 3005
 3006        let transaction = buffer_to_edit.update(cx, |buffer, cx| {
 3007            buffer.finalize_last_transaction();
 3008            buffer.start_transaction();
 3009            for (range, text) in edits {
 3010                buffer.edit([(range, text)], None, cx);
 3011            }
 3012
 3013            if buffer.end_transaction(cx).is_some() {
 3014                let transaction = buffer.finalize_last_transaction().unwrap().clone();
 3015                if !push_to_history {
 3016                    buffer.forget_transaction(transaction.id);
 3017                }
 3018                Some(transaction)
 3019            } else {
 3020                None
 3021            }
 3022        });
 3023
 3024        Ok(transaction)
 3025    }
 3026
 3027    #[allow(clippy::type_complexity)]
 3028    pub fn edits_from_lsp(
 3029        &mut self,
 3030        buffer: &Entity<Buffer>,
 3031        lsp_edits: impl 'static + Send + IntoIterator<Item = lsp::TextEdit>,
 3032        server_id: LanguageServerId,
 3033        version: Option<i32>,
 3034        cx: &mut Context<LspStore>,
 3035    ) -> Task<Result<Vec<(Range<Anchor>, Arc<str>)>>> {
 3036        let snapshot = self.buffer_snapshot_for_lsp_version(buffer, server_id, version, cx);
 3037        cx.background_spawn(async move {
 3038            let snapshot = snapshot?;
 3039            let mut lsp_edits = lsp_edits
 3040                .into_iter()
 3041                .map(|edit| (range_from_lsp(edit.range), edit.new_text))
 3042                .collect::<Vec<_>>();
 3043
 3044            lsp_edits.sort_by_key(|(range, _)| (range.start, range.end));
 3045
 3046            let mut lsp_edits = lsp_edits.into_iter().peekable();
 3047            let mut edits = Vec::new();
 3048            while let Some((range, mut new_text)) = lsp_edits.next() {
 3049                // Clip invalid ranges provided by the language server.
 3050                let mut range = snapshot.clip_point_utf16(range.start, Bias::Left)
 3051                    ..snapshot.clip_point_utf16(range.end, Bias::Left);
 3052
 3053                // Combine any LSP edits that are adjacent.
 3054                //
 3055                // Also, combine LSP edits that are separated from each other by only
 3056                // a newline. This is important because for some code actions,
 3057                // Rust-analyzer rewrites the entire buffer via a series of edits that
 3058                // are separated by unchanged newline characters.
 3059                //
 3060                // In order for the diffing logic below to work properly, any edits that
 3061                // cancel each other out must be combined into one.
 3062                while let Some((next_range, next_text)) = lsp_edits.peek() {
 3063                    if next_range.start.0 > range.end {
 3064                        if next_range.start.0.row > range.end.row + 1
 3065                            || next_range.start.0.column > 0
 3066                            || snapshot.clip_point_utf16(
 3067                                Unclipped(PointUtf16::new(range.end.row, u32::MAX)),
 3068                                Bias::Left,
 3069                            ) > range.end
 3070                        {
 3071                            break;
 3072                        }
 3073                        new_text.push('\n');
 3074                    }
 3075                    range.end = snapshot.clip_point_utf16(next_range.end, Bias::Left);
 3076                    new_text.push_str(next_text);
 3077                    lsp_edits.next();
 3078                }
 3079
 3080                // For multiline edits, perform a diff of the old and new text so that
 3081                // we can identify the changes more precisely, preserving the locations
 3082                // of any anchors positioned in the unchanged regions.
 3083                if range.end.row > range.start.row {
 3084                    let offset = range.start.to_offset(&snapshot);
 3085                    let old_text = snapshot.text_for_range(range).collect::<String>();
 3086                    let range_edits = language::text_diff(old_text.as_str(), &new_text);
 3087                    edits.extend(range_edits.into_iter().map(|(range, replacement)| {
 3088                        (
 3089                            snapshot.anchor_after(offset + range.start)
 3090                                ..snapshot.anchor_before(offset + range.end),
 3091                            replacement,
 3092                        )
 3093                    }));
 3094                } else if range.end == range.start {
 3095                    let anchor = snapshot.anchor_after(range.start);
 3096                    edits.push((anchor..anchor, new_text.into()));
 3097                } else {
 3098                    let edit_start = snapshot.anchor_after(range.start);
 3099                    let edit_end = snapshot.anchor_before(range.end);
 3100                    edits.push((edit_start..edit_end, new_text.into()));
 3101                }
 3102            }
 3103
 3104            Ok(edits)
 3105        })
 3106    }
 3107
 3108    pub(crate) async fn deserialize_workspace_edit(
 3109        this: Entity<LspStore>,
 3110        edit: lsp::WorkspaceEdit,
 3111        push_to_history: bool,
 3112        language_server: Arc<LanguageServer>,
 3113        cx: &mut AsyncApp,
 3114    ) -> Result<ProjectTransaction> {
 3115        let fs = this.read_with(cx, |this, _| this.as_local().unwrap().fs.clone());
 3116
 3117        let mut operations = Vec::new();
 3118        if let Some(document_changes) = edit.document_changes {
 3119            match document_changes {
 3120                lsp::DocumentChanges::Edits(edits) => {
 3121                    operations.extend(edits.into_iter().map(lsp::DocumentChangeOperation::Edit))
 3122                }
 3123                lsp::DocumentChanges::Operations(ops) => operations = ops,
 3124            }
 3125        } else if let Some(changes) = edit.changes {
 3126            operations.extend(changes.into_iter().map(|(uri, edits)| {
 3127                lsp::DocumentChangeOperation::Edit(lsp::TextDocumentEdit {
 3128                    text_document: lsp::OptionalVersionedTextDocumentIdentifier {
 3129                        uri,
 3130                        version: None,
 3131                    },
 3132                    edits: edits.into_iter().map(Edit::Plain).collect(),
 3133                })
 3134            }));
 3135        }
 3136
 3137        let mut project_transaction = ProjectTransaction::default();
 3138        for operation in operations {
 3139            match operation {
 3140                lsp::DocumentChangeOperation::Op(lsp::ResourceOp::Create(op)) => {
 3141                    let abs_path = op
 3142                        .uri
 3143                        .to_file_path()
 3144                        .map_err(|()| anyhow!("can't convert URI to path"))?;
 3145
 3146                    if let Some(parent_path) = abs_path.parent() {
 3147                        fs.create_dir(parent_path).await?;
 3148                    }
 3149                    if abs_path.ends_with("/") {
 3150                        fs.create_dir(&abs_path).await?;
 3151                    } else {
 3152                        fs.create_file(
 3153                            &abs_path,
 3154                            op.options
 3155                                .map(|options| fs::CreateOptions {
 3156                                    overwrite: options.overwrite.unwrap_or(false),
 3157                                    ignore_if_exists: options.ignore_if_exists.unwrap_or(false),
 3158                                })
 3159                                .unwrap_or_default(),
 3160                        )
 3161                        .await?;
 3162                    }
 3163                }
 3164
 3165                lsp::DocumentChangeOperation::Op(lsp::ResourceOp::Rename(op)) => {
 3166                    let source_abs_path = op
 3167                        .old_uri
 3168                        .to_file_path()
 3169                        .map_err(|()| anyhow!("can't convert URI to path"))?;
 3170                    let target_abs_path = op
 3171                        .new_uri
 3172                        .to_file_path()
 3173                        .map_err(|()| anyhow!("can't convert URI to path"))?;
 3174
 3175                    let options = fs::RenameOptions {
 3176                        overwrite: op
 3177                            .options
 3178                            .as_ref()
 3179                            .and_then(|options| options.overwrite)
 3180                            .unwrap_or(false),
 3181                        ignore_if_exists: op
 3182                            .options
 3183                            .as_ref()
 3184                            .and_then(|options| options.ignore_if_exists)
 3185                            .unwrap_or(false),
 3186                        create_parents: true,
 3187                    };
 3188
 3189                    fs.rename(&source_abs_path, &target_abs_path, options)
 3190                        .await?;
 3191                }
 3192
 3193                lsp::DocumentChangeOperation::Op(lsp::ResourceOp::Delete(op)) => {
 3194                    let abs_path = op
 3195                        .uri
 3196                        .to_file_path()
 3197                        .map_err(|()| anyhow!("can't convert URI to path"))?;
 3198                    let options = op
 3199                        .options
 3200                        .map(|options| fs::RemoveOptions {
 3201                            recursive: options.recursive.unwrap_or(false),
 3202                            ignore_if_not_exists: options.ignore_if_not_exists.unwrap_or(false),
 3203                        })
 3204                        .unwrap_or_default();
 3205                    if abs_path.ends_with("/") {
 3206                        fs.remove_dir(&abs_path, options).await?;
 3207                    } else {
 3208                        fs.remove_file(&abs_path, options).await?;
 3209                    }
 3210                }
 3211
 3212                lsp::DocumentChangeOperation::Edit(op) => {
 3213                    let buffer_to_edit = this
 3214                        .update(cx, |this, cx| {
 3215                            this.open_local_buffer_via_lsp(
 3216                                op.text_document.uri.clone(),
 3217                                language_server.server_id(),
 3218                                cx,
 3219                            )
 3220                        })
 3221                        .await?;
 3222
 3223                    let edits = this
 3224                        .update(cx, |this, cx| {
 3225                            let path = buffer_to_edit.read(cx).project_path(cx);
 3226                            let active_entry = this.active_entry;
 3227                            let is_active_entry = path.is_some_and(|project_path| {
 3228                                this.worktree_store
 3229                                    .read(cx)
 3230                                    .entry_for_path(&project_path, cx)
 3231                                    .is_some_and(|entry| Some(entry.id) == active_entry)
 3232                            });
 3233                            let local = this.as_local_mut().unwrap();
 3234
 3235                            let (mut edits, mut snippet_edits) = (vec![], vec![]);
 3236                            for edit in op.edits {
 3237                                match edit {
 3238                                    Edit::Plain(edit) => {
 3239                                        if !edits.contains(&edit) {
 3240                                            edits.push(edit)
 3241                                        }
 3242                                    }
 3243                                    Edit::Annotated(edit) => {
 3244                                        if !edits.contains(&edit.text_edit) {
 3245                                            edits.push(edit.text_edit)
 3246                                        }
 3247                                    }
 3248                                    Edit::Snippet(edit) => {
 3249                                        let Ok(snippet) = Snippet::parse(&edit.snippet.value)
 3250                                        else {
 3251                                            continue;
 3252                                        };
 3253
 3254                                        if is_active_entry {
 3255                                            snippet_edits.push((edit.range, snippet));
 3256                                        } else {
 3257                                            // Since this buffer is not focused, apply a normal edit.
 3258                                            let new_edit = TextEdit {
 3259                                                range: edit.range,
 3260                                                new_text: snippet.text,
 3261                                            };
 3262                                            if !edits.contains(&new_edit) {
 3263                                                edits.push(new_edit);
 3264                                            }
 3265                                        }
 3266                                    }
 3267                                }
 3268                            }
 3269                            if !snippet_edits.is_empty() {
 3270                                let buffer_id = buffer_to_edit.read(cx).remote_id();
 3271                                let version = if let Some(buffer_version) = op.text_document.version
 3272                                {
 3273                                    local
 3274                                        .buffer_snapshot_for_lsp_version(
 3275                                            &buffer_to_edit,
 3276                                            language_server.server_id(),
 3277                                            Some(buffer_version),
 3278                                            cx,
 3279                                        )
 3280                                        .ok()
 3281                                        .map(|snapshot| snapshot.version)
 3282                                } else {
 3283                                    Some(buffer_to_edit.read(cx).saved_version().clone())
 3284                                };
 3285
 3286                                let most_recent_edit =
 3287                                    version.and_then(|version| version.most_recent());
 3288                                // Check if the edit that triggered that edit has been made by this participant.
 3289
 3290                                if let Some(most_recent_edit) = most_recent_edit {
 3291                                    cx.emit(LspStoreEvent::SnippetEdit {
 3292                                        buffer_id,
 3293                                        edits: snippet_edits,
 3294                                        most_recent_edit,
 3295                                    });
 3296                                }
 3297                            }
 3298
 3299                            local.edits_from_lsp(
 3300                                &buffer_to_edit,
 3301                                edits,
 3302                                language_server.server_id(),
 3303                                op.text_document.version,
 3304                                cx,
 3305                            )
 3306                        })
 3307                        .await?;
 3308
 3309                    let transaction = buffer_to_edit.update(cx, |buffer, cx| {
 3310                        buffer.finalize_last_transaction();
 3311                        buffer.start_transaction();
 3312                        for (range, text) in edits {
 3313                            buffer.edit([(range, text)], None, cx);
 3314                        }
 3315
 3316                        buffer.end_transaction(cx).and_then(|transaction_id| {
 3317                            if push_to_history {
 3318                                buffer.finalize_last_transaction();
 3319                                buffer.get_transaction(transaction_id).cloned()
 3320                            } else {
 3321                                buffer.forget_transaction(transaction_id)
 3322                            }
 3323                        })
 3324                    });
 3325                    if let Some(transaction) = transaction {
 3326                        project_transaction.0.insert(buffer_to_edit, transaction);
 3327                    }
 3328                }
 3329            }
 3330        }
 3331
 3332        Ok(project_transaction)
 3333    }
 3334
 3335    async fn on_lsp_workspace_edit(
 3336        this: WeakEntity<LspStore>,
 3337        params: lsp::ApplyWorkspaceEditParams,
 3338        server_id: LanguageServerId,
 3339        cx: &mut AsyncApp,
 3340    ) -> Result<lsp::ApplyWorkspaceEditResponse> {
 3341        let this = this.upgrade().context("project project closed")?;
 3342        let language_server = this
 3343            .read_with(cx, |this, _| this.language_server_for_id(server_id))
 3344            .context("language server not found")?;
 3345        let transaction = Self::deserialize_workspace_edit(
 3346            this.clone(),
 3347            params.edit,
 3348            true,
 3349            language_server.clone(),
 3350            cx,
 3351        )
 3352        .await
 3353        .log_err();
 3354        this.update(cx, |this, cx| {
 3355            if let Some(transaction) = transaction {
 3356                cx.emit(LspStoreEvent::WorkspaceEditApplied(transaction.clone()));
 3357
 3358                this.as_local_mut()
 3359                    .unwrap()
 3360                    .last_workspace_edits_by_language_server
 3361                    .insert(server_id, transaction);
 3362            }
 3363        });
 3364        Ok(lsp::ApplyWorkspaceEditResponse {
 3365            applied: true,
 3366            failed_change: None,
 3367            failure_reason: None,
 3368        })
 3369    }
 3370
 3371    fn remove_worktree(
 3372        &mut self,
 3373        id_to_remove: WorktreeId,
 3374        cx: &mut Context<LspStore>,
 3375    ) -> Vec<LanguageServerId> {
 3376        self.restricted_worktrees_tasks.remove(&id_to_remove);
 3377        self.diagnostics.remove(&id_to_remove);
 3378        self.prettier_store.update(cx, |prettier_store, cx| {
 3379            prettier_store.remove_worktree(id_to_remove, cx);
 3380        });
 3381
 3382        let mut servers_to_remove = BTreeSet::default();
 3383        let mut servers_to_preserve = HashSet::default();
 3384        for (seed, state) in &self.language_server_ids {
 3385            if seed.worktree_id == id_to_remove {
 3386                servers_to_remove.insert(state.id);
 3387            } else {
 3388                servers_to_preserve.insert(state.id);
 3389            }
 3390        }
 3391        servers_to_remove.retain(|server_id| !servers_to_preserve.contains(server_id));
 3392        self.language_server_ids
 3393            .retain(|_, state| !servers_to_remove.contains(&state.id));
 3394        for server_id_to_remove in &servers_to_remove {
 3395            self.language_server_watched_paths
 3396                .remove(server_id_to_remove);
 3397            self.language_server_paths_watched_for_rename
 3398                .remove(server_id_to_remove);
 3399            self.last_workspace_edits_by_language_server
 3400                .remove(server_id_to_remove);
 3401            self.language_servers.remove(server_id_to_remove);
 3402            self.buffer_pull_diagnostics_result_ids
 3403                .remove(server_id_to_remove);
 3404            self.workspace_pull_diagnostics_result_ids
 3405                .remove(server_id_to_remove);
 3406            for buffer_servers in self.buffers_opened_in_servers.values_mut() {
 3407                buffer_servers.remove(server_id_to_remove);
 3408            }
 3409            cx.emit(LspStoreEvent::LanguageServerRemoved(*server_id_to_remove));
 3410        }
 3411        servers_to_remove.into_iter().collect()
 3412    }
 3413
 3414    fn rebuild_watched_paths_inner<'a>(
 3415        &'a self,
 3416        language_server_id: LanguageServerId,
 3417        watchers: impl Iterator<Item = &'a FileSystemWatcher>,
 3418        cx: &mut Context<LspStore>,
 3419    ) -> LanguageServerWatchedPathsBuilder {
 3420        let worktrees = self
 3421            .worktree_store
 3422            .read(cx)
 3423            .worktrees()
 3424            .filter_map(|worktree| {
 3425                self.language_servers_for_worktree(worktree.read(cx).id())
 3426                    .find(|server| server.server_id() == language_server_id)
 3427                    .map(|_| worktree)
 3428            })
 3429            .collect::<Vec<_>>();
 3430
 3431        let mut worktree_globs = HashMap::default();
 3432        let mut abs_globs = HashMap::default();
 3433        log::trace!(
 3434            "Processing new watcher paths for language server with id {}",
 3435            language_server_id
 3436        );
 3437
 3438        for watcher in watchers {
 3439            if let Some((worktree, literal_prefix, pattern)) =
 3440                Self::worktree_and_path_for_file_watcher(&worktrees, watcher, cx)
 3441            {
 3442                worktree.update(cx, |worktree, _| {
 3443                    if let Some((tree, glob)) =
 3444                        worktree.as_local_mut().zip(Glob::new(&pattern).log_err())
 3445                    {
 3446                        tree.add_path_prefix_to_scan(literal_prefix);
 3447                        worktree_globs
 3448                            .entry(tree.id())
 3449                            .or_insert_with(GlobSetBuilder::new)
 3450                            .add(glob);
 3451                    }
 3452                });
 3453            } else {
 3454                let (path, pattern) = match &watcher.glob_pattern {
 3455                    lsp::GlobPattern::String(s) => {
 3456                        let watcher_path = SanitizedPath::new(s);
 3457                        let path = glob_literal_prefix(watcher_path.as_path());
 3458                        let pattern = watcher_path
 3459                            .as_path()
 3460                            .strip_prefix(&path)
 3461                            .map(|p| p.to_string_lossy().into_owned())
 3462                            .unwrap_or_else(|e| {
 3463                                debug_panic!(
 3464                                    "Failed to strip prefix for string pattern: {}, with prefix: {}, with error: {}",
 3465                                    s,
 3466                                    path.display(),
 3467                                    e
 3468                                );
 3469                                watcher_path.as_path().to_string_lossy().into_owned()
 3470                            });
 3471                        (path, pattern)
 3472                    }
 3473                    lsp::GlobPattern::Relative(rp) => {
 3474                        let Ok(mut base_uri) = match &rp.base_uri {
 3475                            lsp::OneOf::Left(workspace_folder) => &workspace_folder.uri,
 3476                            lsp::OneOf::Right(base_uri) => base_uri,
 3477                        }
 3478                        .to_file_path() else {
 3479                            continue;
 3480                        };
 3481
 3482                        let path = glob_literal_prefix(Path::new(&rp.pattern));
 3483                        let pattern = Path::new(&rp.pattern)
 3484                            .strip_prefix(&path)
 3485                            .map(|p| p.to_string_lossy().into_owned())
 3486                            .unwrap_or_else(|e| {
 3487                                debug_panic!(
 3488                                    "Failed to strip prefix for relative pattern: {}, with prefix: {}, with error: {}",
 3489                                    rp.pattern,
 3490                                    path.display(),
 3491                                    e
 3492                                );
 3493                                rp.pattern.clone()
 3494                            });
 3495                        base_uri.push(path);
 3496                        (base_uri, pattern)
 3497                    }
 3498                };
 3499
 3500                if let Some(glob) = Glob::new(&pattern).log_err() {
 3501                    if !path
 3502                        .components()
 3503                        .any(|c| matches!(c, path::Component::Normal(_)))
 3504                    {
 3505                        // For an unrooted glob like `**/Cargo.toml`, watch it within each worktree,
 3506                        // rather than adding a new watcher for `/`.
 3507                        for worktree in &worktrees {
 3508                            worktree_globs
 3509                                .entry(worktree.read(cx).id())
 3510                                .or_insert_with(GlobSetBuilder::new)
 3511                                .add(glob.clone());
 3512                        }
 3513                    } else {
 3514                        abs_globs
 3515                            .entry(path.into())
 3516                            .or_insert_with(GlobSetBuilder::new)
 3517                            .add(glob);
 3518                    }
 3519                }
 3520            }
 3521        }
 3522
 3523        let mut watch_builder = LanguageServerWatchedPathsBuilder::default();
 3524        for (worktree_id, builder) in worktree_globs {
 3525            if let Ok(globset) = builder.build() {
 3526                watch_builder.watch_worktree(worktree_id, globset);
 3527            }
 3528        }
 3529        for (abs_path, builder) in abs_globs {
 3530            if let Ok(globset) = builder.build() {
 3531                watch_builder.watch_abs_path(abs_path, globset);
 3532            }
 3533        }
 3534        watch_builder
 3535    }
 3536
 3537    fn worktree_and_path_for_file_watcher(
 3538        worktrees: &[Entity<Worktree>],
 3539        watcher: &FileSystemWatcher,
 3540        cx: &App,
 3541    ) -> Option<(Entity<Worktree>, Arc<RelPath>, String)> {
 3542        worktrees.iter().find_map(|worktree| {
 3543            let tree = worktree.read(cx);
 3544            let worktree_root_path = tree.abs_path();
 3545            let path_style = tree.path_style();
 3546            match &watcher.glob_pattern {
 3547                lsp::GlobPattern::String(s) => {
 3548                    let watcher_path = SanitizedPath::new(s);
 3549                    let relative = watcher_path
 3550                        .as_path()
 3551                        .strip_prefix(&worktree_root_path)
 3552                        .ok()?;
 3553                    let literal_prefix = glob_literal_prefix(relative);
 3554                    Some((
 3555                        worktree.clone(),
 3556                        RelPath::new(&literal_prefix, path_style).ok()?.into_arc(),
 3557                        relative.to_string_lossy().into_owned(),
 3558                    ))
 3559                }
 3560                lsp::GlobPattern::Relative(rp) => {
 3561                    let base_uri = match &rp.base_uri {
 3562                        lsp::OneOf::Left(workspace_folder) => &workspace_folder.uri,
 3563                        lsp::OneOf::Right(base_uri) => base_uri,
 3564                    }
 3565                    .to_file_path()
 3566                    .ok()?;
 3567                    let relative = base_uri.strip_prefix(&worktree_root_path).ok()?;
 3568                    let mut literal_prefix = relative.to_owned();
 3569                    literal_prefix.push(glob_literal_prefix(Path::new(&rp.pattern)));
 3570                    Some((
 3571                        worktree.clone(),
 3572                        RelPath::new(&literal_prefix, path_style).ok()?.into_arc(),
 3573                        rp.pattern.clone(),
 3574                    ))
 3575                }
 3576            }
 3577        })
 3578    }
 3579
 3580    fn rebuild_watched_paths(
 3581        &mut self,
 3582        language_server_id: LanguageServerId,
 3583        cx: &mut Context<LspStore>,
 3584    ) {
 3585        let Some(registrations) = self
 3586            .language_server_dynamic_registrations
 3587            .get(&language_server_id)
 3588        else {
 3589            return;
 3590        };
 3591
 3592        let watch_builder = self.rebuild_watched_paths_inner(
 3593            language_server_id,
 3594            registrations.did_change_watched_files.values().flatten(),
 3595            cx,
 3596        );
 3597        let watcher = watch_builder.build(self.fs.clone(), language_server_id, cx);
 3598        self.language_server_watched_paths
 3599            .insert(language_server_id, watcher);
 3600
 3601        cx.notify();
 3602    }
 3603
 3604    fn on_lsp_did_change_watched_files(
 3605        &mut self,
 3606        language_server_id: LanguageServerId,
 3607        registration_id: &str,
 3608        params: DidChangeWatchedFilesRegistrationOptions,
 3609        cx: &mut Context<LspStore>,
 3610    ) {
 3611        let registrations = self
 3612            .language_server_dynamic_registrations
 3613            .entry(language_server_id)
 3614            .or_default();
 3615
 3616        registrations
 3617            .did_change_watched_files
 3618            .insert(registration_id.to_string(), params.watchers);
 3619
 3620        self.rebuild_watched_paths(language_server_id, cx);
 3621    }
 3622
 3623    fn on_lsp_unregister_did_change_watched_files(
 3624        &mut self,
 3625        language_server_id: LanguageServerId,
 3626        registration_id: &str,
 3627        cx: &mut Context<LspStore>,
 3628    ) {
 3629        let registrations = self
 3630            .language_server_dynamic_registrations
 3631            .entry(language_server_id)
 3632            .or_default();
 3633
 3634        if registrations
 3635            .did_change_watched_files
 3636            .remove(registration_id)
 3637            .is_some()
 3638        {
 3639            log::info!(
 3640                "language server {}: unregistered workspace/DidChangeWatchedFiles capability with id {}",
 3641                language_server_id,
 3642                registration_id
 3643            );
 3644        } else {
 3645            log::warn!(
 3646                "language server {}: failed to unregister workspace/DidChangeWatchedFiles capability with id {}. not registered.",
 3647                language_server_id,
 3648                registration_id
 3649            );
 3650        }
 3651
 3652        self.rebuild_watched_paths(language_server_id, cx);
 3653    }
 3654
 3655    async fn initialization_options_for_adapter(
 3656        adapter: Arc<dyn LspAdapter>,
 3657        delegate: &Arc<dyn LspAdapterDelegate>,
 3658    ) -> Result<Option<serde_json::Value>> {
 3659        let Some(mut initialization_config) =
 3660            adapter.clone().initialization_options(delegate).await?
 3661        else {
 3662            return Ok(None);
 3663        };
 3664
 3665        for other_adapter in delegate.registered_lsp_adapters() {
 3666            if other_adapter.name() == adapter.name() {
 3667                continue;
 3668            }
 3669            if let Ok(Some(target_config)) = other_adapter
 3670                .clone()
 3671                .additional_initialization_options(adapter.name(), delegate)
 3672                .await
 3673            {
 3674                merge_json_value_into(target_config.clone(), &mut initialization_config);
 3675            }
 3676        }
 3677
 3678        Ok(Some(initialization_config))
 3679    }
 3680
 3681    async fn workspace_configuration_for_adapter(
 3682        adapter: Arc<dyn LspAdapter>,
 3683        delegate: &Arc<dyn LspAdapterDelegate>,
 3684        toolchain: Option<Toolchain>,
 3685        requested_uri: Option<Uri>,
 3686        cx: &mut AsyncApp,
 3687    ) -> Result<serde_json::Value> {
 3688        let mut workspace_config = adapter
 3689            .clone()
 3690            .workspace_configuration(delegate, toolchain, requested_uri, cx)
 3691            .await?;
 3692
 3693        for other_adapter in delegate.registered_lsp_adapters() {
 3694            if other_adapter.name() == adapter.name() {
 3695                continue;
 3696            }
 3697            if let Ok(Some(target_config)) = other_adapter
 3698                .clone()
 3699                .additional_workspace_configuration(adapter.name(), delegate, cx)
 3700                .await
 3701            {
 3702                merge_json_value_into(target_config.clone(), &mut workspace_config);
 3703            }
 3704        }
 3705
 3706        Ok(workspace_config)
 3707    }
 3708
 3709    fn language_server_for_id(&self, id: LanguageServerId) -> Option<Arc<LanguageServer>> {
 3710        if let Some(LanguageServerState::Running { server, .. }) = self.language_servers.get(&id) {
 3711            Some(server.clone())
 3712        } else if let Some((_, server)) = self.supplementary_language_servers.get(&id) {
 3713            Some(Arc::clone(server))
 3714        } else {
 3715            None
 3716        }
 3717    }
 3718}
 3719
 3720fn notify_server_capabilities_updated(server: &LanguageServer, cx: &mut Context<LspStore>) {
 3721    if let Some(capabilities) = serde_json::to_string(&server.capabilities()).ok() {
 3722        cx.emit(LspStoreEvent::LanguageServerUpdate {
 3723            language_server_id: server.server_id(),
 3724            name: Some(server.name()),
 3725            message: proto::update_language_server::Variant::MetadataUpdated(
 3726                proto::ServerMetadataUpdated {
 3727                    capabilities: Some(capabilities),
 3728                    binary: Some(proto::LanguageServerBinaryInfo {
 3729                        path: server.binary().path.to_string_lossy().into_owned(),
 3730                        arguments: server
 3731                            .binary()
 3732                            .arguments
 3733                            .iter()
 3734                            .map(|arg| arg.to_string_lossy().into_owned())
 3735                            .collect(),
 3736                    }),
 3737                    configuration: serde_json::to_string(server.configuration()).ok(),
 3738                    workspace_folders: server
 3739                        .workspace_folders()
 3740                        .iter()
 3741                        .map(|uri| uri.to_string())
 3742                        .collect(),
 3743                },
 3744            ),
 3745        });
 3746    }
 3747}
 3748
 3749#[derive(Debug)]
 3750pub struct FormattableBuffer {
 3751    handle: Entity<Buffer>,
 3752    abs_path: Option<PathBuf>,
 3753    env: Option<HashMap<String, String>>,
 3754    ranges: Option<Vec<Range<Anchor>>>,
 3755}
 3756
 3757pub struct RemoteLspStore {
 3758    upstream_client: Option<AnyProtoClient>,
 3759    upstream_project_id: u64,
 3760}
 3761
 3762pub(crate) enum LspStoreMode {
 3763    Local(LocalLspStore),   // ssh host and collab host
 3764    Remote(RemoteLspStore), // collab guest
 3765}
 3766
 3767impl LspStoreMode {
 3768    fn is_local(&self) -> bool {
 3769        matches!(self, LspStoreMode::Local(_))
 3770    }
 3771}
 3772
 3773pub struct LspStore {
 3774    mode: LspStoreMode,
 3775    last_formatting_failure: Option<String>,
 3776    downstream_client: Option<(AnyProtoClient, u64)>,
 3777    nonce: u128,
 3778    buffer_store: Entity<BufferStore>,
 3779    worktree_store: Entity<WorktreeStore>,
 3780    pub languages: Arc<LanguageRegistry>,
 3781    pub language_server_statuses: BTreeMap<LanguageServerId, LanguageServerStatus>,
 3782    active_entry: Option<ProjectEntryId>,
 3783    _maintain_workspace_config: (Task<Result<()>>, watch::Sender<()>),
 3784    _maintain_buffer_languages: Task<()>,
 3785    diagnostic_summaries:
 3786        HashMap<WorktreeId, HashMap<Arc<RelPath>, HashMap<LanguageServerId, DiagnosticSummary>>>,
 3787    pub lsp_server_capabilities: HashMap<LanguageServerId, lsp::ServerCapabilities>,
 3788    lsp_data: HashMap<BufferId, BufferLspData>,
 3789    next_hint_id: Arc<AtomicUsize>,
 3790}
 3791
 3792#[derive(Debug)]
 3793pub struct BufferLspData {
 3794    buffer_version: Global,
 3795    document_colors: Option<DocumentColorData>,
 3796    code_lens: Option<CodeLensData>,
 3797    inlay_hints: BufferInlayHints,
 3798    lsp_requests: HashMap<LspKey, HashMap<LspRequestId, Task<()>>>,
 3799    chunk_lsp_requests: HashMap<LspKey, HashMap<RowChunk, LspRequestId>>,
 3800}
 3801
 3802#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
 3803struct LspKey {
 3804    request_type: TypeId,
 3805    server_queried: Option<LanguageServerId>,
 3806}
 3807
 3808impl BufferLspData {
 3809    fn new(buffer: &Entity<Buffer>, cx: &mut App) -> Self {
 3810        Self {
 3811            buffer_version: buffer.read(cx).version(),
 3812            document_colors: None,
 3813            code_lens: None,
 3814            inlay_hints: BufferInlayHints::new(buffer, cx),
 3815            lsp_requests: HashMap::default(),
 3816            chunk_lsp_requests: HashMap::default(),
 3817        }
 3818    }
 3819
 3820    fn remove_server_data(&mut self, for_server: LanguageServerId) {
 3821        if let Some(document_colors) = &mut self.document_colors {
 3822            document_colors.colors.remove(&for_server);
 3823            document_colors.cache_version += 1;
 3824        }
 3825
 3826        if let Some(code_lens) = &mut self.code_lens {
 3827            code_lens.lens.remove(&for_server);
 3828        }
 3829
 3830        self.inlay_hints.remove_server_data(for_server);
 3831    }
 3832
 3833    #[cfg(any(test, feature = "test-support"))]
 3834    pub fn inlay_hints(&self) -> &BufferInlayHints {
 3835        &self.inlay_hints
 3836    }
 3837}
 3838
 3839#[derive(Debug, Default, Clone)]
 3840pub struct DocumentColors {
 3841    pub colors: HashSet<DocumentColor>,
 3842    pub cache_version: Option<usize>,
 3843}
 3844
 3845type DocumentColorTask = Shared<Task<std::result::Result<DocumentColors, Arc<anyhow::Error>>>>;
 3846type CodeLensTask = Shared<Task<std::result::Result<Option<Vec<CodeAction>>, Arc<anyhow::Error>>>>;
 3847
 3848#[derive(Debug, Default)]
 3849struct DocumentColorData {
 3850    colors: HashMap<LanguageServerId, HashSet<DocumentColor>>,
 3851    cache_version: usize,
 3852    colors_update: Option<(Global, DocumentColorTask)>,
 3853}
 3854
 3855#[derive(Debug, Default)]
 3856struct CodeLensData {
 3857    lens: HashMap<LanguageServerId, Vec<CodeAction>>,
 3858    update: Option<(Global, CodeLensTask)>,
 3859}
 3860
 3861#[derive(Debug)]
 3862pub enum LspStoreEvent {
 3863    LanguageServerAdded(LanguageServerId, LanguageServerName, Option<WorktreeId>),
 3864    LanguageServerRemoved(LanguageServerId),
 3865    LanguageServerUpdate {
 3866        language_server_id: LanguageServerId,
 3867        name: Option<LanguageServerName>,
 3868        message: proto::update_language_server::Variant,
 3869    },
 3870    LanguageServerLog(LanguageServerId, LanguageServerLogType, String),
 3871    LanguageServerPrompt(LanguageServerPromptRequest),
 3872    LanguageDetected {
 3873        buffer: Entity<Buffer>,
 3874        new_language: Option<Arc<Language>>,
 3875    },
 3876    Notification(String),
 3877    RefreshInlayHints {
 3878        server_id: LanguageServerId,
 3879        request_id: Option<usize>,
 3880    },
 3881    RefreshCodeLens,
 3882    DiagnosticsUpdated {
 3883        server_id: LanguageServerId,
 3884        paths: Vec<ProjectPath>,
 3885    },
 3886    DiskBasedDiagnosticsStarted {
 3887        language_server_id: LanguageServerId,
 3888    },
 3889    DiskBasedDiagnosticsFinished {
 3890        language_server_id: LanguageServerId,
 3891    },
 3892    SnippetEdit {
 3893        buffer_id: BufferId,
 3894        edits: Vec<(lsp::Range, Snippet)>,
 3895        most_recent_edit: clock::Lamport,
 3896    },
 3897    WorkspaceEditApplied(ProjectTransaction),
 3898}
 3899
 3900#[derive(Clone, Debug, Serialize)]
 3901pub struct LanguageServerStatus {
 3902    pub name: LanguageServerName,
 3903    pub server_version: Option<SharedString>,
 3904    pub pending_work: BTreeMap<ProgressToken, LanguageServerProgress>,
 3905    pub has_pending_diagnostic_updates: bool,
 3906    pub progress_tokens: HashSet<ProgressToken>,
 3907    pub worktree: Option<WorktreeId>,
 3908    pub binary: Option<LanguageServerBinary>,
 3909    pub configuration: Option<Value>,
 3910    pub workspace_folders: BTreeSet<Uri>,
 3911}
 3912
 3913#[derive(Clone, Debug)]
 3914struct CoreSymbol {
 3915    pub language_server_name: LanguageServerName,
 3916    pub source_worktree_id: WorktreeId,
 3917    pub source_language_server_id: LanguageServerId,
 3918    pub path: SymbolLocation,
 3919    pub name: String,
 3920    pub kind: lsp::SymbolKind,
 3921    pub range: Range<Unclipped<PointUtf16>>,
 3922}
 3923
 3924#[derive(Clone, Debug, PartialEq, Eq)]
 3925pub enum SymbolLocation {
 3926    InProject(ProjectPath),
 3927    OutsideProject {
 3928        abs_path: Arc<Path>,
 3929        signature: [u8; 32],
 3930    },
 3931}
 3932
 3933impl SymbolLocation {
 3934    fn file_name(&self) -> Option<&str> {
 3935        match self {
 3936            Self::InProject(path) => path.path.file_name(),
 3937            Self::OutsideProject { abs_path, .. } => abs_path.file_name()?.to_str(),
 3938        }
 3939    }
 3940}
 3941
 3942impl LspStore {
 3943    pub fn init(client: &AnyProtoClient) {
 3944        client.add_entity_request_handler(Self::handle_lsp_query);
 3945        client.add_entity_message_handler(Self::handle_lsp_query_response);
 3946        client.add_entity_request_handler(Self::handle_restart_language_servers);
 3947        client.add_entity_request_handler(Self::handle_stop_language_servers);
 3948        client.add_entity_request_handler(Self::handle_cancel_language_server_work);
 3949        client.add_entity_message_handler(Self::handle_start_language_server);
 3950        client.add_entity_message_handler(Self::handle_update_language_server);
 3951        client.add_entity_message_handler(Self::handle_language_server_log);
 3952        client.add_entity_message_handler(Self::handle_update_diagnostic_summary);
 3953        client.add_entity_request_handler(Self::handle_format_buffers);
 3954        client.add_entity_request_handler(Self::handle_apply_code_action_kind);
 3955        client.add_entity_request_handler(Self::handle_resolve_completion_documentation);
 3956        client.add_entity_request_handler(Self::handle_apply_code_action);
 3957        client.add_entity_request_handler(Self::handle_get_project_symbols);
 3958        client.add_entity_request_handler(Self::handle_resolve_inlay_hint);
 3959        client.add_entity_request_handler(Self::handle_get_color_presentation);
 3960        client.add_entity_request_handler(Self::handle_open_buffer_for_symbol);
 3961        client.add_entity_request_handler(Self::handle_refresh_inlay_hints);
 3962        client.add_entity_request_handler(Self::handle_refresh_code_lens);
 3963        client.add_entity_request_handler(Self::handle_on_type_formatting);
 3964        client.add_entity_request_handler(Self::handle_apply_additional_edits_for_completion);
 3965        client.add_entity_request_handler(Self::handle_register_buffer_with_language_servers);
 3966        client.add_entity_request_handler(Self::handle_rename_project_entry);
 3967        client.add_entity_request_handler(Self::handle_pull_workspace_diagnostics);
 3968        client.add_entity_request_handler(Self::handle_lsp_get_completions);
 3969        client.add_entity_request_handler(Self::handle_lsp_command::<GetDocumentHighlights>);
 3970        client.add_entity_request_handler(Self::handle_lsp_command::<GetDocumentSymbols>);
 3971        client.add_entity_request_handler(Self::handle_lsp_command::<PrepareRename>);
 3972        client.add_entity_request_handler(Self::handle_lsp_command::<PerformRename>);
 3973        client.add_entity_request_handler(Self::handle_lsp_command::<LinkedEditingRange>);
 3974
 3975        client.add_entity_request_handler(Self::handle_lsp_ext_cancel_flycheck);
 3976        client.add_entity_request_handler(Self::handle_lsp_ext_run_flycheck);
 3977        client.add_entity_request_handler(Self::handle_lsp_ext_clear_flycheck);
 3978        client.add_entity_request_handler(Self::handle_lsp_command::<lsp_ext_command::ExpandMacro>);
 3979        client.add_entity_request_handler(Self::handle_lsp_command::<lsp_ext_command::OpenDocs>);
 3980        client.add_entity_request_handler(
 3981            Self::handle_lsp_command::<lsp_ext_command::GoToParentModule>,
 3982        );
 3983        client.add_entity_request_handler(
 3984            Self::handle_lsp_command::<lsp_ext_command::GetLspRunnables>,
 3985        );
 3986        client.add_entity_request_handler(
 3987            Self::handle_lsp_command::<lsp_ext_command::SwitchSourceHeader>,
 3988        );
 3989    }
 3990
 3991    pub fn as_remote(&self) -> Option<&RemoteLspStore> {
 3992        match &self.mode {
 3993            LspStoreMode::Remote(remote_lsp_store) => Some(remote_lsp_store),
 3994            _ => None,
 3995        }
 3996    }
 3997
 3998    pub fn as_local(&self) -> Option<&LocalLspStore> {
 3999        match &self.mode {
 4000            LspStoreMode::Local(local_lsp_store) => Some(local_lsp_store),
 4001            _ => None,
 4002        }
 4003    }
 4004
 4005    pub fn as_local_mut(&mut self) -> Option<&mut LocalLspStore> {
 4006        match &mut self.mode {
 4007            LspStoreMode::Local(local_lsp_store) => Some(local_lsp_store),
 4008            _ => None,
 4009        }
 4010    }
 4011
 4012    pub fn upstream_client(&self) -> Option<(AnyProtoClient, u64)> {
 4013        match &self.mode {
 4014            LspStoreMode::Remote(RemoteLspStore {
 4015                upstream_client: Some(upstream_client),
 4016                upstream_project_id,
 4017                ..
 4018            }) => Some((upstream_client.clone(), *upstream_project_id)),
 4019
 4020            LspStoreMode::Remote(RemoteLspStore {
 4021                upstream_client: None,
 4022                ..
 4023            }) => None,
 4024            LspStoreMode::Local(_) => None,
 4025        }
 4026    }
 4027
 4028    pub fn new_local(
 4029        buffer_store: Entity<BufferStore>,
 4030        worktree_store: Entity<WorktreeStore>,
 4031        prettier_store: Entity<PrettierStore>,
 4032        toolchain_store: Entity<LocalToolchainStore>,
 4033        environment: Entity<ProjectEnvironment>,
 4034        manifest_tree: Entity<ManifestTree>,
 4035        languages: Arc<LanguageRegistry>,
 4036        http_client: Arc<dyn HttpClient>,
 4037        fs: Arc<dyn Fs>,
 4038        cx: &mut Context<Self>,
 4039    ) -> Self {
 4040        let yarn = YarnPathStore::new(fs.clone(), cx);
 4041        cx.subscribe(&buffer_store, Self::on_buffer_store_event)
 4042            .detach();
 4043        cx.subscribe(&worktree_store, Self::on_worktree_store_event)
 4044            .detach();
 4045        cx.subscribe(&prettier_store, Self::on_prettier_store_event)
 4046            .detach();
 4047        cx.subscribe(&toolchain_store, Self::on_toolchain_store_event)
 4048            .detach();
 4049        cx.observe_global::<SettingsStore>(Self::on_settings_changed)
 4050            .detach();
 4051        subscribe_to_binary_statuses(&languages, cx).detach();
 4052
 4053        let _maintain_workspace_config = {
 4054            let (sender, receiver) = watch::channel();
 4055            (Self::maintain_workspace_config(receiver, cx), sender)
 4056        };
 4057
 4058        Self {
 4059            mode: LspStoreMode::Local(LocalLspStore {
 4060                weak: cx.weak_entity(),
 4061                worktree_store: worktree_store.clone(),
 4062
 4063                supplementary_language_servers: Default::default(),
 4064                languages: languages.clone(),
 4065                language_server_ids: Default::default(),
 4066                language_servers: Default::default(),
 4067                last_workspace_edits_by_language_server: Default::default(),
 4068                language_server_watched_paths: Default::default(),
 4069                language_server_paths_watched_for_rename: Default::default(),
 4070                language_server_dynamic_registrations: Default::default(),
 4071                buffers_being_formatted: Default::default(),
 4072                buffers_to_refresh_hash_set: HashSet::default(),
 4073                buffers_to_refresh_queue: VecDeque::new(),
 4074                _background_diagnostics_worker: Task::ready(()).shared(),
 4075                buffer_snapshots: Default::default(),
 4076                prettier_store,
 4077                environment,
 4078                http_client,
 4079                fs,
 4080                yarn,
 4081                next_diagnostic_group_id: Default::default(),
 4082                diagnostics: Default::default(),
 4083                _subscription: cx.on_app_quit(|this, cx| {
 4084                    this.as_local_mut()
 4085                        .unwrap()
 4086                        .shutdown_language_servers_on_quit(cx)
 4087                }),
 4088                lsp_tree: LanguageServerTree::new(
 4089                    manifest_tree,
 4090                    languages.clone(),
 4091                    toolchain_store.clone(),
 4092                ),
 4093                toolchain_store,
 4094                registered_buffers: HashMap::default(),
 4095                buffers_opened_in_servers: HashMap::default(),
 4096                buffer_pull_diagnostics_result_ids: HashMap::default(),
 4097                workspace_pull_diagnostics_result_ids: HashMap::default(),
 4098                restricted_worktrees_tasks: HashMap::default(),
 4099                watched_manifest_filenames: ManifestProvidersStore::global(cx)
 4100                    .manifest_file_names(),
 4101            }),
 4102            last_formatting_failure: None,
 4103            downstream_client: None,
 4104            buffer_store,
 4105            worktree_store,
 4106            languages: languages.clone(),
 4107            language_server_statuses: Default::default(),
 4108            nonce: StdRng::from_os_rng().random(),
 4109            diagnostic_summaries: HashMap::default(),
 4110            lsp_server_capabilities: HashMap::default(),
 4111            lsp_data: HashMap::default(),
 4112            next_hint_id: Arc::default(),
 4113            active_entry: None,
 4114            _maintain_workspace_config,
 4115            _maintain_buffer_languages: Self::maintain_buffer_languages(languages, cx),
 4116        }
 4117    }
 4118
 4119    fn send_lsp_proto_request<R: LspCommand>(
 4120        &self,
 4121        buffer: Entity<Buffer>,
 4122        client: AnyProtoClient,
 4123        upstream_project_id: u64,
 4124        request: R,
 4125        cx: &mut Context<LspStore>,
 4126    ) -> Task<anyhow::Result<<R as LspCommand>::Response>> {
 4127        if !self.is_capable_for_proto_request(&buffer, &request, cx) {
 4128            return Task::ready(Ok(R::Response::default()));
 4129        }
 4130        let message = request.to_proto(upstream_project_id, buffer.read(cx));
 4131        cx.spawn(async move |this, cx| {
 4132            let response = client.request(message).await?;
 4133            let this = this.upgrade().context("project dropped")?;
 4134            request
 4135                .response_from_proto(response, this, buffer, cx.clone())
 4136                .await
 4137        })
 4138    }
 4139
 4140    pub(super) fn new_remote(
 4141        buffer_store: Entity<BufferStore>,
 4142        worktree_store: Entity<WorktreeStore>,
 4143        languages: Arc<LanguageRegistry>,
 4144        upstream_client: AnyProtoClient,
 4145        project_id: u64,
 4146        cx: &mut Context<Self>,
 4147    ) -> Self {
 4148        cx.subscribe(&buffer_store, Self::on_buffer_store_event)
 4149            .detach();
 4150        cx.subscribe(&worktree_store, Self::on_worktree_store_event)
 4151            .detach();
 4152        subscribe_to_binary_statuses(&languages, cx).detach();
 4153        let _maintain_workspace_config = {
 4154            let (sender, receiver) = watch::channel();
 4155            (Self::maintain_workspace_config(receiver, cx), sender)
 4156        };
 4157        Self {
 4158            mode: LspStoreMode::Remote(RemoteLspStore {
 4159                upstream_client: Some(upstream_client),
 4160                upstream_project_id: project_id,
 4161            }),
 4162            downstream_client: None,
 4163            last_formatting_failure: None,
 4164            buffer_store,
 4165            worktree_store,
 4166            languages: languages.clone(),
 4167            language_server_statuses: Default::default(),
 4168            nonce: StdRng::from_os_rng().random(),
 4169            diagnostic_summaries: HashMap::default(),
 4170            lsp_server_capabilities: HashMap::default(),
 4171            next_hint_id: Arc::default(),
 4172            lsp_data: HashMap::default(),
 4173            active_entry: None,
 4174
 4175            _maintain_workspace_config,
 4176            _maintain_buffer_languages: Self::maintain_buffer_languages(languages.clone(), cx),
 4177        }
 4178    }
 4179
 4180    fn on_buffer_store_event(
 4181        &mut self,
 4182        _: Entity<BufferStore>,
 4183        event: &BufferStoreEvent,
 4184        cx: &mut Context<Self>,
 4185    ) {
 4186        match event {
 4187            BufferStoreEvent::BufferAdded(buffer) => {
 4188                self.on_buffer_added(buffer, cx).log_err();
 4189            }
 4190            BufferStoreEvent::BufferChangedFilePath { buffer, old_file } => {
 4191                let buffer_id = buffer.read(cx).remote_id();
 4192                if let Some(local) = self.as_local_mut()
 4193                    && let Some(old_file) = File::from_dyn(old_file.as_ref())
 4194                {
 4195                    local.reset_buffer(buffer, old_file, cx);
 4196
 4197                    if local.registered_buffers.contains_key(&buffer_id) {
 4198                        local.unregister_old_buffer_from_language_servers(buffer, old_file, cx);
 4199                    }
 4200                }
 4201
 4202                self.detect_language_for_buffer(buffer, cx);
 4203                if let Some(local) = self.as_local_mut() {
 4204                    local.initialize_buffer(buffer, cx);
 4205                    if local.registered_buffers.contains_key(&buffer_id) {
 4206                        local.register_buffer_with_language_servers(buffer, HashSet::default(), cx);
 4207                    }
 4208                }
 4209            }
 4210            _ => {}
 4211        }
 4212    }
 4213
 4214    fn on_worktree_store_event(
 4215        &mut self,
 4216        _: Entity<WorktreeStore>,
 4217        event: &WorktreeStoreEvent,
 4218        cx: &mut Context<Self>,
 4219    ) {
 4220        match event {
 4221            WorktreeStoreEvent::WorktreeAdded(worktree) => {
 4222                if !worktree.read(cx).is_local() {
 4223                    return;
 4224                }
 4225                cx.subscribe(worktree, |this, worktree, event, cx| match event {
 4226                    worktree::Event::UpdatedEntries(changes) => {
 4227                        this.update_local_worktree_language_servers(&worktree, changes, cx);
 4228                    }
 4229                    worktree::Event::UpdatedGitRepositories(_)
 4230                    | worktree::Event::DeletedEntry(_) => {}
 4231                })
 4232                .detach()
 4233            }
 4234            WorktreeStoreEvent::WorktreeRemoved(_, id) => self.remove_worktree(*id, cx),
 4235            WorktreeStoreEvent::WorktreeUpdateSent(worktree) => {
 4236                worktree.update(cx, |worktree, _cx| self.send_diagnostic_summaries(worktree));
 4237            }
 4238            WorktreeStoreEvent::WorktreeReleased(..)
 4239            | WorktreeStoreEvent::WorktreeOrderChanged
 4240            | WorktreeStoreEvent::WorktreeUpdatedEntries(..)
 4241            | WorktreeStoreEvent::WorktreeUpdatedGitRepositories(..)
 4242            | WorktreeStoreEvent::WorktreeDeletedEntry(..) => {}
 4243        }
 4244    }
 4245
 4246    fn on_prettier_store_event(
 4247        &mut self,
 4248        _: Entity<PrettierStore>,
 4249        event: &PrettierStoreEvent,
 4250        cx: &mut Context<Self>,
 4251    ) {
 4252        match event {
 4253            PrettierStoreEvent::LanguageServerRemoved(prettier_server_id) => {
 4254                self.unregister_supplementary_language_server(*prettier_server_id, cx);
 4255            }
 4256            PrettierStoreEvent::LanguageServerAdded {
 4257                new_server_id,
 4258                name,
 4259                prettier_server,
 4260            } => {
 4261                self.register_supplementary_language_server(
 4262                    *new_server_id,
 4263                    name.clone(),
 4264                    prettier_server.clone(),
 4265                    cx,
 4266                );
 4267            }
 4268        }
 4269    }
 4270
 4271    fn on_toolchain_store_event(
 4272        &mut self,
 4273        _: Entity<LocalToolchainStore>,
 4274        event: &ToolchainStoreEvent,
 4275        _: &mut Context<Self>,
 4276    ) {
 4277        if let ToolchainStoreEvent::ToolchainActivated = event {
 4278            self.request_workspace_config_refresh()
 4279        }
 4280    }
 4281
 4282    fn request_workspace_config_refresh(&mut self) {
 4283        *self._maintain_workspace_config.1.borrow_mut() = ();
 4284    }
 4285
 4286    pub fn prettier_store(&self) -> Option<Entity<PrettierStore>> {
 4287        self.as_local().map(|local| local.prettier_store.clone())
 4288    }
 4289
 4290    fn on_buffer_event(
 4291        &mut self,
 4292        buffer: Entity<Buffer>,
 4293        event: &language::BufferEvent,
 4294        cx: &mut Context<Self>,
 4295    ) {
 4296        match event {
 4297            language::BufferEvent::Edited => {
 4298                self.on_buffer_edited(buffer, cx);
 4299            }
 4300
 4301            language::BufferEvent::Saved => {
 4302                self.on_buffer_saved(buffer, cx);
 4303            }
 4304
 4305            _ => {}
 4306        }
 4307    }
 4308
 4309    fn on_buffer_added(&mut self, buffer: &Entity<Buffer>, cx: &mut Context<Self>) -> Result<()> {
 4310        buffer
 4311            .read(cx)
 4312            .set_language_registry(self.languages.clone());
 4313
 4314        cx.subscribe(buffer, |this, buffer, event, cx| {
 4315            this.on_buffer_event(buffer, event, cx);
 4316        })
 4317        .detach();
 4318
 4319        self.detect_language_for_buffer(buffer, cx);
 4320        if let Some(local) = self.as_local_mut() {
 4321            local.initialize_buffer(buffer, cx);
 4322        }
 4323
 4324        Ok(())
 4325    }
 4326
 4327    pub fn refresh_background_diagnostics_for_buffers(
 4328        &mut self,
 4329        buffers: HashSet<BufferId>,
 4330        cx: &mut Context<Self>,
 4331    ) -> Shared<Task<()>> {
 4332        let Some(local) = self.as_local_mut() else {
 4333            return Task::ready(()).shared();
 4334        };
 4335        for buffer in buffers {
 4336            if local.buffers_to_refresh_hash_set.insert(buffer) {
 4337                local.buffers_to_refresh_queue.push_back(buffer);
 4338                if local.buffers_to_refresh_queue.len() == 1 {
 4339                    local._background_diagnostics_worker =
 4340                        Self::background_diagnostics_worker(cx).shared();
 4341                }
 4342            }
 4343        }
 4344
 4345        local._background_diagnostics_worker.clone()
 4346    }
 4347
 4348    fn refresh_next_buffer(&mut self, cx: &mut Context<Self>) -> Option<Task<Result<()>>> {
 4349        let buffer_store = self.buffer_store.clone();
 4350        let local = self.as_local_mut()?;
 4351        while let Some(buffer_id) = local.buffers_to_refresh_queue.pop_front() {
 4352            local.buffers_to_refresh_hash_set.remove(&buffer_id);
 4353            if let Some(buffer) = buffer_store.read(cx).get(buffer_id) {
 4354                return Some(self.pull_diagnostics_for_buffer(buffer, cx));
 4355            }
 4356        }
 4357        None
 4358    }
 4359
 4360    fn background_diagnostics_worker(cx: &mut Context<Self>) -> Task<()> {
 4361        cx.spawn(async move |this, cx| {
 4362            while let Ok(Some(task)) = this.update(cx, |this, cx| this.refresh_next_buffer(cx)) {
 4363                task.await.log_err();
 4364            }
 4365        })
 4366    }
 4367
 4368    pub(crate) fn register_buffer_with_language_servers(
 4369        &mut self,
 4370        buffer: &Entity<Buffer>,
 4371        only_register_servers: HashSet<LanguageServerSelector>,
 4372        ignore_refcounts: bool,
 4373        cx: &mut Context<Self>,
 4374    ) -> OpenLspBufferHandle {
 4375        let buffer_id = buffer.read(cx).remote_id();
 4376        let handle = OpenLspBufferHandle(cx.new(|_| OpenLspBuffer(buffer.clone())));
 4377        if let Some(local) = self.as_local_mut() {
 4378            let refcount = local.registered_buffers.entry(buffer_id).or_insert(0);
 4379            if !ignore_refcounts {
 4380                *refcount += 1;
 4381            }
 4382
 4383            // We run early exits on non-existing buffers AFTER we mark the buffer as registered in order to handle buffer saving.
 4384            // 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
 4385            // 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
 4386            // servers in practice (we don't support non-file URI schemes in our LSP impl).
 4387            let Some(file) = File::from_dyn(buffer.read(cx).file()) else {
 4388                return handle;
 4389            };
 4390            if !file.is_local() {
 4391                return handle;
 4392            }
 4393
 4394            if ignore_refcounts || *refcount == 1 {
 4395                local.register_buffer_with_language_servers(buffer, only_register_servers, cx);
 4396            }
 4397            if !ignore_refcounts {
 4398                cx.observe_release(&handle.0, move |lsp_store, buffer, cx| {
 4399                    let refcount = {
 4400                        let local = lsp_store.as_local_mut().unwrap();
 4401                        let Some(refcount) = local.registered_buffers.get_mut(&buffer_id) else {
 4402                            debug_panic!("bad refcounting");
 4403                            return;
 4404                        };
 4405
 4406                        *refcount -= 1;
 4407                        *refcount
 4408                    };
 4409                    if refcount == 0 {
 4410                        lsp_store.lsp_data.remove(&buffer_id);
 4411                        let local = lsp_store.as_local_mut().unwrap();
 4412                        local.registered_buffers.remove(&buffer_id);
 4413
 4414                        local.buffers_opened_in_servers.remove(&buffer_id);
 4415                        if let Some(file) = File::from_dyn(buffer.0.read(cx).file()).cloned() {
 4416                            local.unregister_old_buffer_from_language_servers(&buffer.0, &file, cx);
 4417
 4418                            let buffer_abs_path = file.abs_path(cx);
 4419                            for (_, buffer_pull_diagnostics_result_ids) in
 4420                                &mut local.buffer_pull_diagnostics_result_ids
 4421                            {
 4422                                buffer_pull_diagnostics_result_ids.retain(
 4423                                    |_, buffer_result_ids| {
 4424                                        buffer_result_ids.remove(&buffer_abs_path);
 4425                                        !buffer_result_ids.is_empty()
 4426                                    },
 4427                                );
 4428                            }
 4429
 4430                            let diagnostic_updates = local
 4431                                .language_servers
 4432                                .keys()
 4433                                .cloned()
 4434                                .map(|server_id| DocumentDiagnosticsUpdate {
 4435                                    diagnostics: DocumentDiagnostics {
 4436                                        document_abs_path: buffer_abs_path.clone(),
 4437                                        version: None,
 4438                                        diagnostics: Vec::new(),
 4439                                    },
 4440                                    result_id: None,
 4441                                    registration_id: None,
 4442                                    server_id: server_id,
 4443                                    disk_based_sources: Cow::Borrowed(&[]),
 4444                                })
 4445                                .collect::<Vec<_>>();
 4446
 4447                            lsp_store
 4448                                .merge_diagnostic_entries(
 4449                                    diagnostic_updates,
 4450                                    |_, diagnostic, _| {
 4451                                        diagnostic.source_kind != DiagnosticSourceKind::Pulled
 4452                                    },
 4453                                    cx,
 4454                                )
 4455                                .context("Clearing diagnostics for the closed buffer")
 4456                                .log_err();
 4457                        }
 4458                    }
 4459                })
 4460                .detach();
 4461            }
 4462        } else if let Some((upstream_client, upstream_project_id)) = self.upstream_client() {
 4463            let buffer_id = buffer.read(cx).remote_id().to_proto();
 4464            cx.background_spawn(async move {
 4465                upstream_client
 4466                    .request(proto::RegisterBufferWithLanguageServers {
 4467                        project_id: upstream_project_id,
 4468                        buffer_id,
 4469                        only_servers: only_register_servers
 4470                            .into_iter()
 4471                            .map(|selector| {
 4472                                let selector = match selector {
 4473                                    LanguageServerSelector::Id(language_server_id) => {
 4474                                        proto::language_server_selector::Selector::ServerId(
 4475                                            language_server_id.to_proto(),
 4476                                        )
 4477                                    }
 4478                                    LanguageServerSelector::Name(language_server_name) => {
 4479                                        proto::language_server_selector::Selector::Name(
 4480                                            language_server_name.to_string(),
 4481                                        )
 4482                                    }
 4483                                };
 4484                                proto::LanguageServerSelector {
 4485                                    selector: Some(selector),
 4486                                }
 4487                            })
 4488                            .collect(),
 4489                    })
 4490                    .await
 4491            })
 4492            .detach();
 4493        } else {
 4494            // Our remote connection got closed
 4495        }
 4496        handle
 4497    }
 4498
 4499    fn maintain_buffer_languages(
 4500        languages: Arc<LanguageRegistry>,
 4501        cx: &mut Context<Self>,
 4502    ) -> Task<()> {
 4503        let mut subscription = languages.subscribe();
 4504        let mut prev_reload_count = languages.reload_count();
 4505        cx.spawn(async move |this, cx| {
 4506            while let Some(()) = subscription.next().await {
 4507                if let Some(this) = this.upgrade() {
 4508                    // If the language registry has been reloaded, then remove and
 4509                    // re-assign the languages on all open buffers.
 4510                    let reload_count = languages.reload_count();
 4511                    if reload_count > prev_reload_count {
 4512                        prev_reload_count = reload_count;
 4513                        this.update(cx, |this, cx| {
 4514                            this.buffer_store.clone().update(cx, |buffer_store, cx| {
 4515                                for buffer in buffer_store.buffers() {
 4516                                    if let Some(f) = File::from_dyn(buffer.read(cx).file()).cloned()
 4517                                    {
 4518                                        buffer.update(cx, |buffer, cx| {
 4519                                            buffer.set_language_async(None, cx)
 4520                                        });
 4521                                        if let Some(local) = this.as_local_mut() {
 4522                                            local.reset_buffer(&buffer, &f, cx);
 4523
 4524                                            if local
 4525                                                .registered_buffers
 4526                                                .contains_key(&buffer.read(cx).remote_id())
 4527                                                && let Some(file_url) =
 4528                                                    file_path_to_lsp_url(&f.abs_path(cx)).log_err()
 4529                                            {
 4530                                                local.unregister_buffer_from_language_servers(
 4531                                                    &buffer, &file_url, cx,
 4532                                                );
 4533                                            }
 4534                                        }
 4535                                    }
 4536                                }
 4537                            });
 4538                        });
 4539                    }
 4540
 4541                    this.update(cx, |this, cx| {
 4542                        let mut plain_text_buffers = Vec::new();
 4543                        let mut buffers_with_unknown_injections = Vec::new();
 4544                        for handle in this.buffer_store.read(cx).buffers() {
 4545                            let buffer = handle.read(cx);
 4546                            if buffer.language().is_none()
 4547                                || buffer.language() == Some(&*language::PLAIN_TEXT)
 4548                            {
 4549                                plain_text_buffers.push(handle);
 4550                            } else if buffer.contains_unknown_injections() {
 4551                                buffers_with_unknown_injections.push(handle);
 4552                            }
 4553                        }
 4554
 4555                        // Deprioritize the invisible worktrees so main worktrees' language servers can be started first,
 4556                        // and reused later in the invisible worktrees.
 4557                        plain_text_buffers.sort_by_key(|buffer| {
 4558                            Reverse(
 4559                                File::from_dyn(buffer.read(cx).file())
 4560                                    .map(|file| file.worktree.read(cx).is_visible()),
 4561                            )
 4562                        });
 4563
 4564                        for buffer in plain_text_buffers {
 4565                            this.detect_language_for_buffer(&buffer, cx);
 4566                            if let Some(local) = this.as_local_mut() {
 4567                                local.initialize_buffer(&buffer, cx);
 4568                                if local
 4569                                    .registered_buffers
 4570                                    .contains_key(&buffer.read(cx).remote_id())
 4571                                {
 4572                                    local.register_buffer_with_language_servers(
 4573                                        &buffer,
 4574                                        HashSet::default(),
 4575                                        cx,
 4576                                    );
 4577                                }
 4578                            }
 4579                        }
 4580
 4581                        for buffer in buffers_with_unknown_injections {
 4582                            buffer.update(cx, |buffer, cx| buffer.reparse(cx, false));
 4583                        }
 4584                    });
 4585                }
 4586            }
 4587        })
 4588    }
 4589
 4590    fn detect_language_for_buffer(
 4591        &mut self,
 4592        buffer_handle: &Entity<Buffer>,
 4593        cx: &mut Context<Self>,
 4594    ) -> Option<language::AvailableLanguage> {
 4595        // If the buffer has a language, set it and start the language server if we haven't already.
 4596        let buffer = buffer_handle.read(cx);
 4597        let file = buffer.file()?;
 4598
 4599        let content = buffer.as_rope();
 4600        let available_language = self.languages.language_for_file(file, Some(content), cx);
 4601        if let Some(available_language) = &available_language {
 4602            if let Some(Ok(Ok(new_language))) = self
 4603                .languages
 4604                .load_language(available_language)
 4605                .now_or_never()
 4606            {
 4607                self.set_language_for_buffer(buffer_handle, new_language, cx);
 4608            }
 4609        } else {
 4610            cx.emit(LspStoreEvent::LanguageDetected {
 4611                buffer: buffer_handle.clone(),
 4612                new_language: None,
 4613            });
 4614        }
 4615
 4616        available_language
 4617    }
 4618
 4619    pub(crate) fn set_language_for_buffer(
 4620        &mut self,
 4621        buffer_entity: &Entity<Buffer>,
 4622        new_language: Arc<Language>,
 4623        cx: &mut Context<Self>,
 4624    ) {
 4625        let buffer = buffer_entity.read(cx);
 4626        let buffer_file = buffer.file().cloned();
 4627        let buffer_id = buffer.remote_id();
 4628        if let Some(local_store) = self.as_local_mut()
 4629            && local_store.registered_buffers.contains_key(&buffer_id)
 4630            && let Some(abs_path) =
 4631                File::from_dyn(buffer_file.as_ref()).map(|file| file.abs_path(cx))
 4632            && let Some(file_url) = file_path_to_lsp_url(&abs_path).log_err()
 4633        {
 4634            local_store.unregister_buffer_from_language_servers(buffer_entity, &file_url, cx);
 4635        }
 4636        buffer_entity.update(cx, |buffer, cx| {
 4637            if buffer
 4638                .language()
 4639                .is_none_or(|old_language| !Arc::ptr_eq(old_language, &new_language))
 4640            {
 4641                buffer.set_language_async(Some(new_language.clone()), cx);
 4642            }
 4643        });
 4644
 4645        let settings =
 4646            language_settings(Some(new_language.name()), buffer_file.as_ref(), cx).into_owned();
 4647        let buffer_file = File::from_dyn(buffer_file.as_ref());
 4648
 4649        let worktree_id = if let Some(file) = buffer_file {
 4650            let worktree = file.worktree.clone();
 4651
 4652            if let Some(local) = self.as_local_mut()
 4653                && local.registered_buffers.contains_key(&buffer_id)
 4654            {
 4655                local.register_buffer_with_language_servers(buffer_entity, HashSet::default(), cx);
 4656            }
 4657            Some(worktree.read(cx).id())
 4658        } else {
 4659            None
 4660        };
 4661
 4662        if settings.prettier.allowed
 4663            && let Some(prettier_plugins) = prettier_store::prettier_plugins_for_language(&settings)
 4664        {
 4665            let prettier_store = self.as_local().map(|s| s.prettier_store.clone());
 4666            if let Some(prettier_store) = prettier_store {
 4667                prettier_store.update(cx, |prettier_store, cx| {
 4668                    prettier_store.install_default_prettier(
 4669                        worktree_id,
 4670                        prettier_plugins.iter().map(|s| Arc::from(s.as_str())),
 4671                        cx,
 4672                    )
 4673                })
 4674            }
 4675        }
 4676
 4677        cx.emit(LspStoreEvent::LanguageDetected {
 4678            buffer: buffer_entity.clone(),
 4679            new_language: Some(new_language),
 4680        })
 4681    }
 4682
 4683    pub fn buffer_store(&self) -> Entity<BufferStore> {
 4684        self.buffer_store.clone()
 4685    }
 4686
 4687    pub fn set_active_entry(&mut self, active_entry: Option<ProjectEntryId>) {
 4688        self.active_entry = active_entry;
 4689    }
 4690
 4691    pub(crate) fn send_diagnostic_summaries(&self, worktree: &mut Worktree) {
 4692        if let Some((client, downstream_project_id)) = self.downstream_client.clone()
 4693            && let Some(diangostic_summaries) = self.diagnostic_summaries.get(&worktree.id())
 4694        {
 4695            let mut summaries = diangostic_summaries.iter().flat_map(|(path, summaries)| {
 4696                summaries
 4697                    .iter()
 4698                    .map(|(server_id, summary)| summary.to_proto(*server_id, path.as_ref()))
 4699            });
 4700            if let Some(summary) = summaries.next() {
 4701                client
 4702                    .send(proto::UpdateDiagnosticSummary {
 4703                        project_id: downstream_project_id,
 4704                        worktree_id: worktree.id().to_proto(),
 4705                        summary: Some(summary),
 4706                        more_summaries: summaries.collect(),
 4707                    })
 4708                    .log_err();
 4709            }
 4710        }
 4711    }
 4712
 4713    fn is_capable_for_proto_request<R>(
 4714        &self,
 4715        buffer: &Entity<Buffer>,
 4716        request: &R,
 4717        cx: &App,
 4718    ) -> bool
 4719    where
 4720        R: LspCommand,
 4721    {
 4722        self.check_if_capable_for_proto_request(
 4723            buffer,
 4724            |capabilities| {
 4725                request.check_capabilities(AdapterServerCapabilities {
 4726                    server_capabilities: capabilities.clone(),
 4727                    code_action_kinds: None,
 4728                })
 4729            },
 4730            cx,
 4731        )
 4732    }
 4733
 4734    fn check_if_capable_for_proto_request<F>(
 4735        &self,
 4736        buffer: &Entity<Buffer>,
 4737        check: F,
 4738        cx: &App,
 4739    ) -> bool
 4740    where
 4741        F: FnMut(&lsp::ServerCapabilities) -> bool,
 4742    {
 4743        let Some(language) = buffer.read(cx).language().cloned() else {
 4744            return false;
 4745        };
 4746        let registered_language_servers = self
 4747            .languages
 4748            .lsp_adapters(&language.name())
 4749            .into_iter()
 4750            .map(|lsp_adapter| lsp_adapter.name())
 4751            .collect::<HashSet<_>>();
 4752        self.language_server_statuses
 4753            .iter()
 4754            .filter_map(|(server_id, server_status)| {
 4755                // Include servers that are either registered for this language OR
 4756                // available to be loaded (for SSH remote mode where adapters like
 4757                // ty/pylsp/pyright are registered via register_available_lsp_adapter
 4758                // but only loaded on the server side)
 4759                let is_relevant = registered_language_servers.contains(&server_status.name)
 4760                    || self.languages.is_lsp_adapter_available(&server_status.name);
 4761                is_relevant.then_some(server_id)
 4762            })
 4763            .filter_map(|server_id| self.lsp_server_capabilities.get(server_id))
 4764            .any(check)
 4765    }
 4766
 4767    fn all_capable_for_proto_request<F>(
 4768        &self,
 4769        buffer: &Entity<Buffer>,
 4770        mut check: F,
 4771        cx: &App,
 4772    ) -> Vec<lsp::LanguageServerId>
 4773    where
 4774        F: FnMut(&lsp::LanguageServerName, &lsp::ServerCapabilities) -> bool,
 4775    {
 4776        let Some(language) = buffer.read(cx).language().cloned() else {
 4777            return Vec::default();
 4778        };
 4779        let registered_language_servers = self
 4780            .languages
 4781            .lsp_adapters(&language.name())
 4782            .into_iter()
 4783            .map(|lsp_adapter| lsp_adapter.name())
 4784            .collect::<HashSet<_>>();
 4785        self.language_server_statuses
 4786            .iter()
 4787            .filter_map(|(server_id, server_status)| {
 4788                // Include servers that are either registered for this language OR
 4789                // available to be loaded (for SSH remote mode where adapters like
 4790                // ty/pylsp/pyright are registered via register_available_lsp_adapter
 4791                // but only loaded on the server side)
 4792                let is_relevant = registered_language_servers.contains(&server_status.name)
 4793                    || self.languages.is_lsp_adapter_available(&server_status.name);
 4794                is_relevant.then_some((server_id, &server_status.name))
 4795            })
 4796            .filter_map(|(server_id, server_name)| {
 4797                self.lsp_server_capabilities
 4798                    .get(server_id)
 4799                    .map(|c| (server_id, server_name, c))
 4800            })
 4801            .filter(|(_, server_name, capabilities)| check(server_name, capabilities))
 4802            .map(|(server_id, _, _)| *server_id)
 4803            .collect()
 4804    }
 4805
 4806    pub fn request_lsp<R>(
 4807        &mut self,
 4808        buffer: Entity<Buffer>,
 4809        server: LanguageServerToQuery,
 4810        request: R,
 4811        cx: &mut Context<Self>,
 4812    ) -> Task<Result<R::Response>>
 4813    where
 4814        R: LspCommand,
 4815        <R::LspRequest as lsp::request::Request>::Result: Send,
 4816        <R::LspRequest as lsp::request::Request>::Params: Send,
 4817    {
 4818        if let Some((upstream_client, upstream_project_id)) = self.upstream_client() {
 4819            return self.send_lsp_proto_request(
 4820                buffer,
 4821                upstream_client,
 4822                upstream_project_id,
 4823                request,
 4824                cx,
 4825            );
 4826        }
 4827
 4828        let Some(language_server) = buffer.update(cx, |buffer, cx| match server {
 4829            LanguageServerToQuery::FirstCapable => self.as_local().and_then(|local| {
 4830                local
 4831                    .language_servers_for_buffer(buffer, cx)
 4832                    .find(|(_, server)| {
 4833                        request.check_capabilities(server.adapter_server_capabilities())
 4834                    })
 4835                    .map(|(_, server)| server.clone())
 4836            }),
 4837            LanguageServerToQuery::Other(id) => self
 4838                .language_server_for_local_buffer(buffer, id, cx)
 4839                .and_then(|(_, server)| {
 4840                    request
 4841                        .check_capabilities(server.adapter_server_capabilities())
 4842                        .then(|| Arc::clone(server))
 4843                }),
 4844        }) else {
 4845            return Task::ready(Ok(Default::default()));
 4846        };
 4847
 4848        let file = File::from_dyn(buffer.read(cx).file()).and_then(File::as_local);
 4849
 4850        let Some(file) = file else {
 4851            return Task::ready(Ok(Default::default()));
 4852        };
 4853
 4854        let lsp_params = match request.to_lsp_params_or_response(
 4855            &file.abs_path(cx),
 4856            buffer.read(cx),
 4857            &language_server,
 4858            cx,
 4859        ) {
 4860            Ok(LspParamsOrResponse::Params(lsp_params)) => lsp_params,
 4861            Ok(LspParamsOrResponse::Response(response)) => return Task::ready(Ok(response)),
 4862            Err(err) => {
 4863                let message = format!(
 4864                    "{} via {} failed: {}",
 4865                    request.display_name(),
 4866                    language_server.name(),
 4867                    err
 4868                );
 4869                // rust-analyzer likes to error with this when its still loading up
 4870                if !message.ends_with("content modified") {
 4871                    log::warn!("{message}");
 4872                }
 4873                return Task::ready(Err(anyhow!(message)));
 4874            }
 4875        };
 4876
 4877        let status = request.status();
 4878        if !request.check_capabilities(language_server.adapter_server_capabilities()) {
 4879            return Task::ready(Ok(Default::default()));
 4880        }
 4881        cx.spawn(async move |this, cx| {
 4882            let lsp_request = language_server.request::<R::LspRequest>(lsp_params);
 4883
 4884            let id = lsp_request.id();
 4885            let _cleanup = if status.is_some() {
 4886                cx.update(|cx| {
 4887                    this.update(cx, |this, cx| {
 4888                        this.on_lsp_work_start(
 4889                            language_server.server_id(),
 4890                            ProgressToken::Number(id),
 4891                            LanguageServerProgress {
 4892                                is_disk_based_diagnostics_progress: false,
 4893                                is_cancellable: false,
 4894                                title: None,
 4895                                message: status.clone(),
 4896                                percentage: None,
 4897                                last_update_at: cx.background_executor().now(),
 4898                            },
 4899                            cx,
 4900                        );
 4901                    })
 4902                })
 4903                .log_err();
 4904
 4905                Some(defer(|| {
 4906                    cx.update(|cx| {
 4907                        this.update(cx, |this, cx| {
 4908                            this.on_lsp_work_end(
 4909                                language_server.server_id(),
 4910                                ProgressToken::Number(id),
 4911                                cx,
 4912                            );
 4913                        })
 4914                    })
 4915                    .log_err();
 4916                }))
 4917            } else {
 4918                None
 4919            };
 4920
 4921            let result = lsp_request.await.into_response();
 4922
 4923            let response = result.map_err(|err| {
 4924                let message = format!(
 4925                    "{} via {} failed: {}",
 4926                    request.display_name(),
 4927                    language_server.name(),
 4928                    err
 4929                );
 4930                // rust-analyzer likes to error with this when its still loading up
 4931                if !message.ends_with("content modified") {
 4932                    log::warn!("{message}");
 4933                }
 4934                anyhow::anyhow!(message)
 4935            })?;
 4936
 4937            request
 4938                .response_from_lsp(
 4939                    response,
 4940                    this.upgrade().context("no app context")?,
 4941                    buffer,
 4942                    language_server.server_id(),
 4943                    cx.clone(),
 4944                )
 4945                .await
 4946        })
 4947    }
 4948
 4949    fn on_settings_changed(&mut self, cx: &mut Context<Self>) {
 4950        let mut language_formatters_to_check = Vec::new();
 4951        for buffer in self.buffer_store.read(cx).buffers() {
 4952            let buffer = buffer.read(cx);
 4953            let buffer_file = File::from_dyn(buffer.file());
 4954            let buffer_language = buffer.language();
 4955            let settings = language_settings(buffer_language.map(|l| l.name()), buffer.file(), cx);
 4956            if buffer_language.is_some() {
 4957                language_formatters_to_check.push((
 4958                    buffer_file.map(|f| f.worktree_id(cx)),
 4959                    settings.into_owned(),
 4960                ));
 4961            }
 4962        }
 4963
 4964        self.request_workspace_config_refresh();
 4965
 4966        if let Some(prettier_store) = self.as_local().map(|s| s.prettier_store.clone()) {
 4967            prettier_store.update(cx, |prettier_store, cx| {
 4968                prettier_store.on_settings_changed(language_formatters_to_check, cx)
 4969            })
 4970        }
 4971
 4972        cx.notify();
 4973    }
 4974
 4975    fn refresh_server_tree(&mut self, cx: &mut Context<Self>) {
 4976        let buffer_store = self.buffer_store.clone();
 4977        let Some(local) = self.as_local_mut() else {
 4978            return;
 4979        };
 4980        let mut adapters = BTreeMap::default();
 4981        let get_adapter = {
 4982            let languages = local.languages.clone();
 4983            let environment = local.environment.clone();
 4984            let weak = local.weak.clone();
 4985            let worktree_store = local.worktree_store.clone();
 4986            let http_client = local.http_client.clone();
 4987            let fs = local.fs.clone();
 4988            move |worktree_id, cx: &mut App| {
 4989                let worktree = worktree_store.read(cx).worktree_for_id(worktree_id, cx)?;
 4990                Some(LocalLspAdapterDelegate::new(
 4991                    languages.clone(),
 4992                    &environment,
 4993                    weak.clone(),
 4994                    &worktree,
 4995                    http_client.clone(),
 4996                    fs.clone(),
 4997                    cx,
 4998                ))
 4999            }
 5000        };
 5001
 5002        let mut messages_to_report = Vec::new();
 5003        let (new_tree, to_stop) = {
 5004            let mut rebase = local.lsp_tree.rebase();
 5005            let buffers = buffer_store
 5006                .read(cx)
 5007                .buffers()
 5008                .filter_map(|buffer| {
 5009                    let raw_buffer = buffer.read(cx);
 5010                    if !local
 5011                        .registered_buffers
 5012                        .contains_key(&raw_buffer.remote_id())
 5013                    {
 5014                        return None;
 5015                    }
 5016                    let file = File::from_dyn(raw_buffer.file()).cloned()?;
 5017                    let language = raw_buffer.language().cloned()?;
 5018                    Some((file, language, raw_buffer.remote_id()))
 5019                })
 5020                .sorted_by_key(|(file, _, _)| Reverse(file.worktree.read(cx).is_visible()));
 5021            for (file, language, buffer_id) in buffers {
 5022                let worktree_id = file.worktree_id(cx);
 5023                let Some(worktree) = local
 5024                    .worktree_store
 5025                    .read(cx)
 5026                    .worktree_for_id(worktree_id, cx)
 5027                else {
 5028                    continue;
 5029                };
 5030
 5031                if let Some((_, apply)) = local.reuse_existing_language_server(
 5032                    rebase.server_tree(),
 5033                    &worktree,
 5034                    &language.name(),
 5035                    cx,
 5036                ) {
 5037                    (apply)(rebase.server_tree());
 5038                } else if let Some(lsp_delegate) = adapters
 5039                    .entry(worktree_id)
 5040                    .or_insert_with(|| get_adapter(worktree_id, cx))
 5041                    .clone()
 5042                {
 5043                    let delegate =
 5044                        Arc::new(ManifestQueryDelegate::new(worktree.read(cx).snapshot()));
 5045                    let path = file
 5046                        .path()
 5047                        .parent()
 5048                        .map(Arc::from)
 5049                        .unwrap_or_else(|| file.path().clone());
 5050                    let worktree_path = ProjectPath { worktree_id, path };
 5051                    let abs_path = file.abs_path(cx);
 5052                    let nodes = rebase
 5053                        .walk(
 5054                            worktree_path,
 5055                            language.name(),
 5056                            language.manifest(),
 5057                            delegate.clone(),
 5058                            cx,
 5059                        )
 5060                        .collect::<Vec<_>>();
 5061                    for node in nodes {
 5062                        let server_id = node.server_id_or_init(|disposition| {
 5063                            let path = &disposition.path;
 5064                            let uri = Uri::from_file_path(worktree.read(cx).absolutize(&path.path));
 5065                            let key = LanguageServerSeed {
 5066                                worktree_id,
 5067                                name: disposition.server_name.clone(),
 5068                                settings: LanguageServerSeedSettings {
 5069                                    binary: disposition.settings.binary.clone(),
 5070                                    initialization_options: disposition
 5071                                        .settings
 5072                                        .initialization_options
 5073                                        .clone(),
 5074                                },
 5075                                toolchain: local.toolchain_store.read(cx).active_toolchain(
 5076                                    path.worktree_id,
 5077                                    &path.path,
 5078                                    language.name(),
 5079                                ),
 5080                            };
 5081                            local.language_server_ids.remove(&key);
 5082
 5083                            let server_id = local.get_or_insert_language_server(
 5084                                &worktree,
 5085                                lsp_delegate.clone(),
 5086                                disposition,
 5087                                &language.name(),
 5088                                cx,
 5089                            );
 5090                            if let Some(state) = local.language_servers.get(&server_id)
 5091                                && let Ok(uri) = uri
 5092                            {
 5093                                state.add_workspace_folder(uri);
 5094                            };
 5095                            server_id
 5096                        });
 5097
 5098                        if let Some(language_server_id) = server_id {
 5099                            messages_to_report.push(LspStoreEvent::LanguageServerUpdate {
 5100                                language_server_id,
 5101                                name: node.name(),
 5102                                message:
 5103                                    proto::update_language_server::Variant::RegisteredForBuffer(
 5104                                        proto::RegisteredForBuffer {
 5105                                            buffer_abs_path: abs_path
 5106                                                .to_string_lossy()
 5107                                                .into_owned(),
 5108                                            buffer_id: buffer_id.to_proto(),
 5109                                        },
 5110                                    ),
 5111                            });
 5112                        }
 5113                    }
 5114                } else {
 5115                    continue;
 5116                }
 5117            }
 5118            rebase.finish()
 5119        };
 5120        for message in messages_to_report {
 5121            cx.emit(message);
 5122        }
 5123        local.lsp_tree = new_tree;
 5124        for (id, _) in to_stop {
 5125            self.stop_local_language_server(id, cx).detach();
 5126        }
 5127    }
 5128
 5129    pub fn apply_code_action(
 5130        &self,
 5131        buffer_handle: Entity<Buffer>,
 5132        mut action: CodeAction,
 5133        push_to_history: bool,
 5134        cx: &mut Context<Self>,
 5135    ) -> Task<Result<ProjectTransaction>> {
 5136        if let Some((upstream_client, project_id)) = self.upstream_client() {
 5137            let request = proto::ApplyCodeAction {
 5138                project_id,
 5139                buffer_id: buffer_handle.read(cx).remote_id().into(),
 5140                action: Some(Self::serialize_code_action(&action)),
 5141            };
 5142            let buffer_store = self.buffer_store();
 5143            cx.spawn(async move |_, cx| {
 5144                let response = upstream_client
 5145                    .request(request)
 5146                    .await?
 5147                    .transaction
 5148                    .context("missing transaction")?;
 5149
 5150                buffer_store
 5151                    .update(cx, |buffer_store, cx| {
 5152                        buffer_store.deserialize_project_transaction(response, push_to_history, cx)
 5153                    })
 5154                    .await
 5155            })
 5156        } else if self.mode.is_local() {
 5157            let Some((_, lang_server)) = buffer_handle.update(cx, |buffer, cx| {
 5158                self.language_server_for_local_buffer(buffer, action.server_id, cx)
 5159                    .map(|(adapter, server)| (adapter.clone(), server.clone()))
 5160            }) else {
 5161                return Task::ready(Ok(ProjectTransaction::default()));
 5162            };
 5163            cx.spawn(async move |this,  cx| {
 5164                LocalLspStore::try_resolve_code_action(&lang_server, &mut action)
 5165                    .await
 5166                    .context("resolving a code action")?;
 5167                if let Some(edit) = action.lsp_action.edit()
 5168                    && (edit.changes.is_some() || edit.document_changes.is_some()) {
 5169                        return LocalLspStore::deserialize_workspace_edit(
 5170                            this.upgrade().context("no app present")?,
 5171                            edit.clone(),
 5172                            push_to_history,
 5173
 5174                            lang_server.clone(),
 5175                            cx,
 5176                        )
 5177                        .await;
 5178                    }
 5179
 5180                if let Some(command) = action.lsp_action.command() {
 5181                    let server_capabilities = lang_server.capabilities();
 5182                    let available_commands = server_capabilities
 5183                        .execute_command_provider
 5184                        .as_ref()
 5185                        .map(|options| options.commands.as_slice())
 5186                        .unwrap_or_default();
 5187                    if available_commands.contains(&command.command) {
 5188                        this.update(cx, |this, _| {
 5189                            this.as_local_mut()
 5190                                .unwrap()
 5191                                .last_workspace_edits_by_language_server
 5192                                .remove(&lang_server.server_id());
 5193                        })?;
 5194
 5195                        let _result = lang_server
 5196                            .request::<lsp::request::ExecuteCommand>(lsp::ExecuteCommandParams {
 5197                                command: command.command.clone(),
 5198                                arguments: command.arguments.clone().unwrap_or_default(),
 5199                                ..lsp::ExecuteCommandParams::default()
 5200                            })
 5201                            .await.into_response()
 5202                            .context("execute command")?;
 5203
 5204                        return this.update(cx, |this, _| {
 5205                            this.as_local_mut()
 5206                                .unwrap()
 5207                                .last_workspace_edits_by_language_server
 5208                                .remove(&lang_server.server_id())
 5209                                .unwrap_or_default()
 5210                        });
 5211                    } else {
 5212                        log::warn!("Cannot execute a command {} not listed in the language server capabilities", command.command);
 5213                    }
 5214                }
 5215
 5216                Ok(ProjectTransaction::default())
 5217            })
 5218        } else {
 5219            Task::ready(Err(anyhow!("no upstream client and not local")))
 5220        }
 5221    }
 5222
 5223    pub fn apply_code_action_kind(
 5224        &mut self,
 5225        buffers: HashSet<Entity<Buffer>>,
 5226        kind: CodeActionKind,
 5227        push_to_history: bool,
 5228        cx: &mut Context<Self>,
 5229    ) -> Task<anyhow::Result<ProjectTransaction>> {
 5230        if self.as_local().is_some() {
 5231            cx.spawn(async move |lsp_store, cx| {
 5232                let buffers = buffers.into_iter().collect::<Vec<_>>();
 5233                let result = LocalLspStore::execute_code_action_kind_locally(
 5234                    lsp_store.clone(),
 5235                    buffers,
 5236                    kind,
 5237                    push_to_history,
 5238                    cx,
 5239                )
 5240                .await;
 5241                lsp_store.update(cx, |lsp_store, _| {
 5242                    lsp_store.update_last_formatting_failure(&result);
 5243                })?;
 5244                result
 5245            })
 5246        } else if let Some((client, project_id)) = self.upstream_client() {
 5247            let buffer_store = self.buffer_store();
 5248            cx.spawn(async move |lsp_store, cx| {
 5249                let result = client
 5250                    .request(proto::ApplyCodeActionKind {
 5251                        project_id,
 5252                        kind: kind.as_str().to_owned(),
 5253                        buffer_ids: buffers
 5254                            .iter()
 5255                            .map(|buffer| {
 5256                                buffer.read_with(cx, |buffer, _| buffer.remote_id().into())
 5257                            })
 5258                            .collect(),
 5259                    })
 5260                    .await
 5261                    .and_then(|result| result.transaction.context("missing transaction"));
 5262                lsp_store.update(cx, |lsp_store, _| {
 5263                    lsp_store.update_last_formatting_failure(&result);
 5264                })?;
 5265
 5266                let transaction_response = result?;
 5267                buffer_store
 5268                    .update(cx, |buffer_store, cx| {
 5269                        buffer_store.deserialize_project_transaction(
 5270                            transaction_response,
 5271                            push_to_history,
 5272                            cx,
 5273                        )
 5274                    })
 5275                    .await
 5276            })
 5277        } else {
 5278            Task::ready(Ok(ProjectTransaction::default()))
 5279        }
 5280    }
 5281
 5282    pub fn resolved_hint(
 5283        &mut self,
 5284        buffer_id: BufferId,
 5285        id: InlayId,
 5286        cx: &mut Context<Self>,
 5287    ) -> Option<ResolvedHint> {
 5288        let buffer = self.buffer_store.read(cx).get(buffer_id)?;
 5289
 5290        let lsp_data = self.lsp_data.get_mut(&buffer_id)?;
 5291        let buffer_lsp_hints = &mut lsp_data.inlay_hints;
 5292        let hint = buffer_lsp_hints.hint_for_id(id)?.clone();
 5293        let (server_id, resolve_data) = match &hint.resolve_state {
 5294            ResolveState::Resolved => return Some(ResolvedHint::Resolved(hint)),
 5295            ResolveState::Resolving => {
 5296                return Some(ResolvedHint::Resolving(
 5297                    buffer_lsp_hints.hint_resolves.get(&id)?.clone(),
 5298                ));
 5299            }
 5300            ResolveState::CanResolve(server_id, resolve_data) => (*server_id, resolve_data.clone()),
 5301        };
 5302
 5303        let resolve_task = self.resolve_inlay_hint(hint, buffer, server_id, cx);
 5304        let buffer_lsp_hints = &mut self.lsp_data.get_mut(&buffer_id)?.inlay_hints;
 5305        let previous_task = buffer_lsp_hints.hint_resolves.insert(
 5306            id,
 5307            cx.spawn(async move |lsp_store, cx| {
 5308                let resolved_hint = resolve_task.await;
 5309                lsp_store
 5310                    .update(cx, |lsp_store, _| {
 5311                        if let Some(old_inlay_hint) = lsp_store
 5312                            .lsp_data
 5313                            .get_mut(&buffer_id)
 5314                            .and_then(|buffer_lsp_data| buffer_lsp_data.inlay_hints.hint_for_id(id))
 5315                        {
 5316                            match resolved_hint {
 5317                                Ok(resolved_hint) => {
 5318                                    *old_inlay_hint = resolved_hint;
 5319                                }
 5320                                Err(e) => {
 5321                                    old_inlay_hint.resolve_state =
 5322                                        ResolveState::CanResolve(server_id, resolve_data);
 5323                                    log::error!("Inlay hint resolve failed: {e:#}");
 5324                                }
 5325                            }
 5326                        }
 5327                    })
 5328                    .ok();
 5329            })
 5330            .shared(),
 5331        );
 5332        debug_assert!(
 5333            previous_task.is_none(),
 5334            "Did not change hint's resolve state after spawning its resolve"
 5335        );
 5336        buffer_lsp_hints.hint_for_id(id)?.resolve_state = ResolveState::Resolving;
 5337        None
 5338    }
 5339
 5340    fn resolve_inlay_hint(
 5341        &self,
 5342        mut hint: InlayHint,
 5343        buffer: Entity<Buffer>,
 5344        server_id: LanguageServerId,
 5345        cx: &mut Context<Self>,
 5346    ) -> Task<anyhow::Result<InlayHint>> {
 5347        if let Some((upstream_client, project_id)) = self.upstream_client() {
 5348            if !self.check_if_capable_for_proto_request(&buffer, InlayHints::can_resolve_inlays, cx)
 5349            {
 5350                hint.resolve_state = ResolveState::Resolved;
 5351                return Task::ready(Ok(hint));
 5352            }
 5353            let request = proto::ResolveInlayHint {
 5354                project_id,
 5355                buffer_id: buffer.read(cx).remote_id().into(),
 5356                language_server_id: server_id.0 as u64,
 5357                hint: Some(InlayHints::project_to_proto_hint(hint.clone())),
 5358            };
 5359            cx.background_spawn(async move {
 5360                let response = upstream_client
 5361                    .request(request)
 5362                    .await
 5363                    .context("inlay hints proto request")?;
 5364                match response.hint {
 5365                    Some(resolved_hint) => InlayHints::proto_to_project_hint(resolved_hint)
 5366                        .context("inlay hints proto resolve response conversion"),
 5367                    None => Ok(hint),
 5368                }
 5369            })
 5370        } else {
 5371            let Some(lang_server) = buffer.update(cx, |buffer, cx| {
 5372                self.language_server_for_local_buffer(buffer, server_id, cx)
 5373                    .map(|(_, server)| server.clone())
 5374            }) else {
 5375                return Task::ready(Ok(hint));
 5376            };
 5377            if !InlayHints::can_resolve_inlays(&lang_server.capabilities()) {
 5378                return Task::ready(Ok(hint));
 5379            }
 5380            let buffer_snapshot = buffer.read(cx).snapshot();
 5381            cx.spawn(async move |_, cx| {
 5382                let resolve_task = lang_server.request::<lsp::request::InlayHintResolveRequest>(
 5383                    InlayHints::project_to_lsp_hint(hint, &buffer_snapshot),
 5384                );
 5385                let resolved_hint = resolve_task
 5386                    .await
 5387                    .into_response()
 5388                    .context("inlay hint resolve LSP request")?;
 5389                let resolved_hint = InlayHints::lsp_to_project_hint(
 5390                    resolved_hint,
 5391                    &buffer,
 5392                    server_id,
 5393                    ResolveState::Resolved,
 5394                    false,
 5395                    cx,
 5396                )
 5397                .await?;
 5398                Ok(resolved_hint)
 5399            })
 5400        }
 5401    }
 5402
 5403    pub fn resolve_color_presentation(
 5404        &mut self,
 5405        mut color: DocumentColor,
 5406        buffer: Entity<Buffer>,
 5407        server_id: LanguageServerId,
 5408        cx: &mut Context<Self>,
 5409    ) -> Task<Result<DocumentColor>> {
 5410        if color.resolved {
 5411            return Task::ready(Ok(color));
 5412        }
 5413
 5414        if let Some((upstream_client, project_id)) = self.upstream_client() {
 5415            let start = color.lsp_range.start;
 5416            let end = color.lsp_range.end;
 5417            let request = proto::GetColorPresentation {
 5418                project_id,
 5419                server_id: server_id.to_proto(),
 5420                buffer_id: buffer.read(cx).remote_id().into(),
 5421                color: Some(proto::ColorInformation {
 5422                    red: color.color.red,
 5423                    green: color.color.green,
 5424                    blue: color.color.blue,
 5425                    alpha: color.color.alpha,
 5426                    lsp_range_start: Some(proto::PointUtf16 {
 5427                        row: start.line,
 5428                        column: start.character,
 5429                    }),
 5430                    lsp_range_end: Some(proto::PointUtf16 {
 5431                        row: end.line,
 5432                        column: end.character,
 5433                    }),
 5434                }),
 5435            };
 5436            cx.background_spawn(async move {
 5437                let response = upstream_client
 5438                    .request(request)
 5439                    .await
 5440                    .context("color presentation proto request")?;
 5441                color.resolved = true;
 5442                color.color_presentations = response
 5443                    .presentations
 5444                    .into_iter()
 5445                    .map(|presentation| ColorPresentation {
 5446                        label: SharedString::from(presentation.label),
 5447                        text_edit: presentation.text_edit.and_then(deserialize_lsp_edit),
 5448                        additional_text_edits: presentation
 5449                            .additional_text_edits
 5450                            .into_iter()
 5451                            .filter_map(deserialize_lsp_edit)
 5452                            .collect(),
 5453                    })
 5454                    .collect();
 5455                Ok(color)
 5456            })
 5457        } else {
 5458            let path = match buffer
 5459                .update(cx, |buffer, cx| {
 5460                    Some(File::from_dyn(buffer.file())?.abs_path(cx))
 5461                })
 5462                .context("buffer with the missing path")
 5463            {
 5464                Ok(path) => path,
 5465                Err(e) => return Task::ready(Err(e)),
 5466            };
 5467            let Some(lang_server) = buffer.update(cx, |buffer, cx| {
 5468                self.language_server_for_local_buffer(buffer, server_id, cx)
 5469                    .map(|(_, server)| server.clone())
 5470            }) else {
 5471                return Task::ready(Ok(color));
 5472            };
 5473            cx.background_spawn(async move {
 5474                let resolve_task = lang_server.request::<lsp::request::ColorPresentationRequest>(
 5475                    lsp::ColorPresentationParams {
 5476                        text_document: make_text_document_identifier(&path)?,
 5477                        color: color.color,
 5478                        range: color.lsp_range,
 5479                        work_done_progress_params: Default::default(),
 5480                        partial_result_params: Default::default(),
 5481                    },
 5482                );
 5483                color.color_presentations = resolve_task
 5484                    .await
 5485                    .into_response()
 5486                    .context("color presentation resolve LSP request")?
 5487                    .into_iter()
 5488                    .map(|presentation| ColorPresentation {
 5489                        label: SharedString::from(presentation.label),
 5490                        text_edit: presentation.text_edit,
 5491                        additional_text_edits: presentation
 5492                            .additional_text_edits
 5493                            .unwrap_or_default(),
 5494                    })
 5495                    .collect();
 5496                color.resolved = true;
 5497                Ok(color)
 5498            })
 5499        }
 5500    }
 5501
 5502    pub(crate) fn linked_edits(
 5503        &mut self,
 5504        buffer: &Entity<Buffer>,
 5505        position: Anchor,
 5506        cx: &mut Context<Self>,
 5507    ) -> Task<Result<Vec<Range<Anchor>>>> {
 5508        let snapshot = buffer.read(cx).snapshot();
 5509        let scope = snapshot.language_scope_at(position);
 5510        let Some(server_id) = self
 5511            .as_local()
 5512            .and_then(|local| {
 5513                buffer.update(cx, |buffer, cx| {
 5514                    local
 5515                        .language_servers_for_buffer(buffer, cx)
 5516                        .filter(|(_, server)| {
 5517                            LinkedEditingRange::check_server_capabilities(server.capabilities())
 5518                        })
 5519                        .filter(|(adapter, _)| {
 5520                            scope
 5521                                .as_ref()
 5522                                .map(|scope| scope.language_allowed(&adapter.name))
 5523                                .unwrap_or(true)
 5524                        })
 5525                        .map(|(_, server)| LanguageServerToQuery::Other(server.server_id()))
 5526                        .next()
 5527                })
 5528            })
 5529            .or_else(|| {
 5530                self.upstream_client()
 5531                    .is_some()
 5532                    .then_some(LanguageServerToQuery::FirstCapable)
 5533            })
 5534            .filter(|_| {
 5535                maybe!({
 5536                    let language = buffer.read(cx).language_at(position)?;
 5537                    Some(
 5538                        language_settings(Some(language.name()), buffer.read(cx).file(), cx)
 5539                            .linked_edits,
 5540                    )
 5541                }) == Some(true)
 5542            })
 5543        else {
 5544            return Task::ready(Ok(Vec::new()));
 5545        };
 5546
 5547        self.request_lsp(
 5548            buffer.clone(),
 5549            server_id,
 5550            LinkedEditingRange { position },
 5551            cx,
 5552        )
 5553    }
 5554
 5555    fn apply_on_type_formatting(
 5556        &mut self,
 5557        buffer: Entity<Buffer>,
 5558        position: Anchor,
 5559        trigger: String,
 5560        cx: &mut Context<Self>,
 5561    ) -> Task<Result<Option<Transaction>>> {
 5562        if let Some((client, project_id)) = self.upstream_client() {
 5563            if !self.check_if_capable_for_proto_request(
 5564                &buffer,
 5565                |capabilities| {
 5566                    OnTypeFormatting::supports_on_type_formatting(&trigger, capabilities)
 5567                },
 5568                cx,
 5569            ) {
 5570                return Task::ready(Ok(None));
 5571            }
 5572            let request = proto::OnTypeFormatting {
 5573                project_id,
 5574                buffer_id: buffer.read(cx).remote_id().into(),
 5575                position: Some(serialize_anchor(&position)),
 5576                trigger,
 5577                version: serialize_version(&buffer.read(cx).version()),
 5578            };
 5579            cx.background_spawn(async move {
 5580                client
 5581                    .request(request)
 5582                    .await?
 5583                    .transaction
 5584                    .map(language::proto::deserialize_transaction)
 5585                    .transpose()
 5586            })
 5587        } else if let Some(local) = self.as_local_mut() {
 5588            let buffer_id = buffer.read(cx).remote_id();
 5589            local.buffers_being_formatted.insert(buffer_id);
 5590            cx.spawn(async move |this, cx| {
 5591                let _cleanup = defer({
 5592                    let this = this.clone();
 5593                    let mut cx = cx.clone();
 5594                    move || {
 5595                        this.update(&mut cx, |this, _| {
 5596                            if let Some(local) = this.as_local_mut() {
 5597                                local.buffers_being_formatted.remove(&buffer_id);
 5598                            }
 5599                        })
 5600                        .ok();
 5601                    }
 5602                });
 5603
 5604                buffer
 5605                    .update(cx, |buffer, _| {
 5606                        buffer.wait_for_edits(Some(position.timestamp))
 5607                    })
 5608                    .await?;
 5609                this.update(cx, |this, cx| {
 5610                    let position = position.to_point_utf16(buffer.read(cx));
 5611                    this.on_type_format(buffer, position, trigger, false, cx)
 5612                })?
 5613                .await
 5614            })
 5615        } else {
 5616            Task::ready(Err(anyhow!("No upstream client or local language server")))
 5617        }
 5618    }
 5619
 5620    pub fn on_type_format<T: ToPointUtf16>(
 5621        &mut self,
 5622        buffer: Entity<Buffer>,
 5623        position: T,
 5624        trigger: String,
 5625        push_to_history: bool,
 5626        cx: &mut Context<Self>,
 5627    ) -> Task<Result<Option<Transaction>>> {
 5628        let position = position.to_point_utf16(buffer.read(cx));
 5629        self.on_type_format_impl(buffer, position, trigger, push_to_history, cx)
 5630    }
 5631
 5632    fn on_type_format_impl(
 5633        &mut self,
 5634        buffer: Entity<Buffer>,
 5635        position: PointUtf16,
 5636        trigger: String,
 5637        push_to_history: bool,
 5638        cx: &mut Context<Self>,
 5639    ) -> Task<Result<Option<Transaction>>> {
 5640        let options = buffer.update(cx, |buffer, cx| {
 5641            lsp_command::lsp_formatting_options(
 5642                language_settings(
 5643                    buffer.language_at(position).map(|l| l.name()),
 5644                    buffer.file(),
 5645                    cx,
 5646                )
 5647                .as_ref(),
 5648            )
 5649        });
 5650
 5651        cx.spawn(async move |this, cx| {
 5652            if let Some(waiter) =
 5653                buffer.update(cx, |buffer, _| buffer.wait_for_autoindent_applied())
 5654            {
 5655                waiter.await?;
 5656            }
 5657            cx.update(|cx| {
 5658                this.update(cx, |this, cx| {
 5659                    this.request_lsp(
 5660                        buffer.clone(),
 5661                        LanguageServerToQuery::FirstCapable,
 5662                        OnTypeFormatting {
 5663                            position,
 5664                            trigger,
 5665                            options,
 5666                            push_to_history,
 5667                        },
 5668                        cx,
 5669                    )
 5670                })
 5671            })?
 5672            .await
 5673        })
 5674    }
 5675
 5676    pub fn definitions(
 5677        &mut self,
 5678        buffer: &Entity<Buffer>,
 5679        position: PointUtf16,
 5680        cx: &mut Context<Self>,
 5681    ) -> Task<Result<Option<Vec<LocationLink>>>> {
 5682        if let Some((upstream_client, project_id)) = self.upstream_client() {
 5683            let request = GetDefinitions { position };
 5684            if !self.is_capable_for_proto_request(buffer, &request, cx) {
 5685                return Task::ready(Ok(None));
 5686            }
 5687            let request_task = upstream_client.request_lsp(
 5688                project_id,
 5689                None,
 5690                LSP_REQUEST_TIMEOUT,
 5691                cx.background_executor().clone(),
 5692                request.to_proto(project_id, buffer.read(cx)),
 5693            );
 5694            let buffer = buffer.clone();
 5695            cx.spawn(async move |weak_lsp_store, cx| {
 5696                let Some(lsp_store) = weak_lsp_store.upgrade() else {
 5697                    return Ok(None);
 5698                };
 5699                let Some(responses) = request_task.await? else {
 5700                    return Ok(None);
 5701                };
 5702                let actions = join_all(responses.payload.into_iter().map(|response| {
 5703                    GetDefinitions { position }.response_from_proto(
 5704                        response.response,
 5705                        lsp_store.clone(),
 5706                        buffer.clone(),
 5707                        cx.clone(),
 5708                    )
 5709                }))
 5710                .await;
 5711
 5712                Ok(Some(
 5713                    actions
 5714                        .into_iter()
 5715                        .collect::<Result<Vec<Vec<_>>>>()?
 5716                        .into_iter()
 5717                        .flatten()
 5718                        .dedup()
 5719                        .collect(),
 5720                ))
 5721            })
 5722        } else {
 5723            let definitions_task = self.request_multiple_lsp_locally(
 5724                buffer,
 5725                Some(position),
 5726                GetDefinitions { position },
 5727                cx,
 5728            );
 5729            cx.background_spawn(async move {
 5730                Ok(Some(
 5731                    definitions_task
 5732                        .await
 5733                        .into_iter()
 5734                        .flat_map(|(_, definitions)| definitions)
 5735                        .dedup()
 5736                        .collect(),
 5737                ))
 5738            })
 5739        }
 5740    }
 5741
 5742    pub fn declarations(
 5743        &mut self,
 5744        buffer: &Entity<Buffer>,
 5745        position: PointUtf16,
 5746        cx: &mut Context<Self>,
 5747    ) -> Task<Result<Option<Vec<LocationLink>>>> {
 5748        if let Some((upstream_client, project_id)) = self.upstream_client() {
 5749            let request = GetDeclarations { position };
 5750            if !self.is_capable_for_proto_request(buffer, &request, cx) {
 5751                return Task::ready(Ok(None));
 5752            }
 5753            let request_task = upstream_client.request_lsp(
 5754                project_id,
 5755                None,
 5756                LSP_REQUEST_TIMEOUT,
 5757                cx.background_executor().clone(),
 5758                request.to_proto(project_id, buffer.read(cx)),
 5759            );
 5760            let buffer = buffer.clone();
 5761            cx.spawn(async move |weak_lsp_store, cx| {
 5762                let Some(lsp_store) = weak_lsp_store.upgrade() else {
 5763                    return Ok(None);
 5764                };
 5765                let Some(responses) = request_task.await? else {
 5766                    return Ok(None);
 5767                };
 5768                let actions = join_all(responses.payload.into_iter().map(|response| {
 5769                    GetDeclarations { position }.response_from_proto(
 5770                        response.response,
 5771                        lsp_store.clone(),
 5772                        buffer.clone(),
 5773                        cx.clone(),
 5774                    )
 5775                }))
 5776                .await;
 5777
 5778                Ok(Some(
 5779                    actions
 5780                        .into_iter()
 5781                        .collect::<Result<Vec<Vec<_>>>>()?
 5782                        .into_iter()
 5783                        .flatten()
 5784                        .dedup()
 5785                        .collect(),
 5786                ))
 5787            })
 5788        } else {
 5789            let declarations_task = self.request_multiple_lsp_locally(
 5790                buffer,
 5791                Some(position),
 5792                GetDeclarations { position },
 5793                cx,
 5794            );
 5795            cx.background_spawn(async move {
 5796                Ok(Some(
 5797                    declarations_task
 5798                        .await
 5799                        .into_iter()
 5800                        .flat_map(|(_, declarations)| declarations)
 5801                        .dedup()
 5802                        .collect(),
 5803                ))
 5804            })
 5805        }
 5806    }
 5807
 5808    pub fn type_definitions(
 5809        &mut self,
 5810        buffer: &Entity<Buffer>,
 5811        position: PointUtf16,
 5812        cx: &mut Context<Self>,
 5813    ) -> Task<Result<Option<Vec<LocationLink>>>> {
 5814        if let Some((upstream_client, project_id)) = self.upstream_client() {
 5815            let request = GetTypeDefinitions { position };
 5816            if !self.is_capable_for_proto_request(buffer, &request, cx) {
 5817                return Task::ready(Ok(None));
 5818            }
 5819            let request_task = upstream_client.request_lsp(
 5820                project_id,
 5821                None,
 5822                LSP_REQUEST_TIMEOUT,
 5823                cx.background_executor().clone(),
 5824                request.to_proto(project_id, buffer.read(cx)),
 5825            );
 5826            let buffer = buffer.clone();
 5827            cx.spawn(async move |weak_lsp_store, cx| {
 5828                let Some(lsp_store) = weak_lsp_store.upgrade() else {
 5829                    return Ok(None);
 5830                };
 5831                let Some(responses) = request_task.await? else {
 5832                    return Ok(None);
 5833                };
 5834                let actions = join_all(responses.payload.into_iter().map(|response| {
 5835                    GetTypeDefinitions { position }.response_from_proto(
 5836                        response.response,
 5837                        lsp_store.clone(),
 5838                        buffer.clone(),
 5839                        cx.clone(),
 5840                    )
 5841                }))
 5842                .await;
 5843
 5844                Ok(Some(
 5845                    actions
 5846                        .into_iter()
 5847                        .collect::<Result<Vec<Vec<_>>>>()?
 5848                        .into_iter()
 5849                        .flatten()
 5850                        .dedup()
 5851                        .collect(),
 5852                ))
 5853            })
 5854        } else {
 5855            let type_definitions_task = self.request_multiple_lsp_locally(
 5856                buffer,
 5857                Some(position),
 5858                GetTypeDefinitions { position },
 5859                cx,
 5860            );
 5861            cx.background_spawn(async move {
 5862                Ok(Some(
 5863                    type_definitions_task
 5864                        .await
 5865                        .into_iter()
 5866                        .flat_map(|(_, type_definitions)| type_definitions)
 5867                        .dedup()
 5868                        .collect(),
 5869                ))
 5870            })
 5871        }
 5872    }
 5873
 5874    pub fn implementations(
 5875        &mut self,
 5876        buffer: &Entity<Buffer>,
 5877        position: PointUtf16,
 5878        cx: &mut Context<Self>,
 5879    ) -> Task<Result<Option<Vec<LocationLink>>>> {
 5880        if let Some((upstream_client, project_id)) = self.upstream_client() {
 5881            let request = GetImplementations { position };
 5882            if !self.is_capable_for_proto_request(buffer, &request, cx) {
 5883                return Task::ready(Ok(None));
 5884            }
 5885            let request_task = upstream_client.request_lsp(
 5886                project_id,
 5887                None,
 5888                LSP_REQUEST_TIMEOUT,
 5889                cx.background_executor().clone(),
 5890                request.to_proto(project_id, buffer.read(cx)),
 5891            );
 5892            let buffer = buffer.clone();
 5893            cx.spawn(async move |weak_lsp_store, cx| {
 5894                let Some(lsp_store) = weak_lsp_store.upgrade() else {
 5895                    return Ok(None);
 5896                };
 5897                let Some(responses) = request_task.await? else {
 5898                    return Ok(None);
 5899                };
 5900                let actions = join_all(responses.payload.into_iter().map(|response| {
 5901                    GetImplementations { position }.response_from_proto(
 5902                        response.response,
 5903                        lsp_store.clone(),
 5904                        buffer.clone(),
 5905                        cx.clone(),
 5906                    )
 5907                }))
 5908                .await;
 5909
 5910                Ok(Some(
 5911                    actions
 5912                        .into_iter()
 5913                        .collect::<Result<Vec<Vec<_>>>>()?
 5914                        .into_iter()
 5915                        .flatten()
 5916                        .dedup()
 5917                        .collect(),
 5918                ))
 5919            })
 5920        } else {
 5921            let implementations_task = self.request_multiple_lsp_locally(
 5922                buffer,
 5923                Some(position),
 5924                GetImplementations { position },
 5925                cx,
 5926            );
 5927            cx.background_spawn(async move {
 5928                Ok(Some(
 5929                    implementations_task
 5930                        .await
 5931                        .into_iter()
 5932                        .flat_map(|(_, implementations)| implementations)
 5933                        .dedup()
 5934                        .collect(),
 5935                ))
 5936            })
 5937        }
 5938    }
 5939
 5940    pub fn references(
 5941        &mut self,
 5942        buffer: &Entity<Buffer>,
 5943        position: PointUtf16,
 5944        cx: &mut Context<Self>,
 5945    ) -> Task<Result<Option<Vec<Location>>>> {
 5946        if let Some((upstream_client, project_id)) = self.upstream_client() {
 5947            let request = GetReferences { position };
 5948            if !self.is_capable_for_proto_request(buffer, &request, cx) {
 5949                return Task::ready(Ok(None));
 5950            }
 5951
 5952            let request_task = upstream_client.request_lsp(
 5953                project_id,
 5954                None,
 5955                LSP_REQUEST_TIMEOUT,
 5956                cx.background_executor().clone(),
 5957                request.to_proto(project_id, buffer.read(cx)),
 5958            );
 5959            let buffer = buffer.clone();
 5960            cx.spawn(async move |weak_lsp_store, cx| {
 5961                let Some(lsp_store) = weak_lsp_store.upgrade() else {
 5962                    return Ok(None);
 5963                };
 5964                let Some(responses) = request_task.await? else {
 5965                    return Ok(None);
 5966                };
 5967
 5968                let locations = join_all(responses.payload.into_iter().map(|lsp_response| {
 5969                    GetReferences { position }.response_from_proto(
 5970                        lsp_response.response,
 5971                        lsp_store.clone(),
 5972                        buffer.clone(),
 5973                        cx.clone(),
 5974                    )
 5975                }))
 5976                .await
 5977                .into_iter()
 5978                .collect::<Result<Vec<Vec<_>>>>()?
 5979                .into_iter()
 5980                .flatten()
 5981                .dedup()
 5982                .collect();
 5983                Ok(Some(locations))
 5984            })
 5985        } else {
 5986            let references_task = self.request_multiple_lsp_locally(
 5987                buffer,
 5988                Some(position),
 5989                GetReferences { position },
 5990                cx,
 5991            );
 5992            cx.background_spawn(async move {
 5993                Ok(Some(
 5994                    references_task
 5995                        .await
 5996                        .into_iter()
 5997                        .flat_map(|(_, references)| references)
 5998                        .dedup()
 5999                        .collect(),
 6000                ))
 6001            })
 6002        }
 6003    }
 6004
 6005    pub fn code_actions(
 6006        &mut self,
 6007        buffer: &Entity<Buffer>,
 6008        range: Range<Anchor>,
 6009        kinds: Option<Vec<CodeActionKind>>,
 6010        cx: &mut Context<Self>,
 6011    ) -> Task<Result<Option<Vec<CodeAction>>>> {
 6012        if let Some((upstream_client, project_id)) = self.upstream_client() {
 6013            let request = GetCodeActions {
 6014                range: range.clone(),
 6015                kinds: kinds.clone(),
 6016            };
 6017            if !self.is_capable_for_proto_request(buffer, &request, cx) {
 6018                return Task::ready(Ok(None));
 6019            }
 6020            let request_task = upstream_client.request_lsp(
 6021                project_id,
 6022                None,
 6023                LSP_REQUEST_TIMEOUT,
 6024                cx.background_executor().clone(),
 6025                request.to_proto(project_id, buffer.read(cx)),
 6026            );
 6027            let buffer = buffer.clone();
 6028            cx.spawn(async move |weak_lsp_store, cx| {
 6029                let Some(lsp_store) = weak_lsp_store.upgrade() else {
 6030                    return Ok(None);
 6031                };
 6032                let Some(responses) = request_task.await? else {
 6033                    return Ok(None);
 6034                };
 6035                let actions = join_all(responses.payload.into_iter().map(|response| {
 6036                    GetCodeActions {
 6037                        range: range.clone(),
 6038                        kinds: kinds.clone(),
 6039                    }
 6040                    .response_from_proto(
 6041                        response.response,
 6042                        lsp_store.clone(),
 6043                        buffer.clone(),
 6044                        cx.clone(),
 6045                    )
 6046                }))
 6047                .await;
 6048
 6049                Ok(Some(
 6050                    actions
 6051                        .into_iter()
 6052                        .collect::<Result<Vec<Vec<_>>>>()?
 6053                        .into_iter()
 6054                        .flatten()
 6055                        .collect(),
 6056                ))
 6057            })
 6058        } else {
 6059            let all_actions_task = self.request_multiple_lsp_locally(
 6060                buffer,
 6061                Some(range.start),
 6062                GetCodeActions { range, kinds },
 6063                cx,
 6064            );
 6065            cx.background_spawn(async move {
 6066                Ok(Some(
 6067                    all_actions_task
 6068                        .await
 6069                        .into_iter()
 6070                        .flat_map(|(_, actions)| actions)
 6071                        .collect(),
 6072                ))
 6073            })
 6074        }
 6075    }
 6076
 6077    pub fn code_lens_actions(
 6078        &mut self,
 6079        buffer: &Entity<Buffer>,
 6080        cx: &mut Context<Self>,
 6081    ) -> CodeLensTask {
 6082        let version_queried_for = buffer.read(cx).version();
 6083        let buffer_id = buffer.read(cx).remote_id();
 6084        let existing_servers = self.as_local().map(|local| {
 6085            local
 6086                .buffers_opened_in_servers
 6087                .get(&buffer_id)
 6088                .cloned()
 6089                .unwrap_or_default()
 6090        });
 6091
 6092        if let Some(lsp_data) = self.current_lsp_data(buffer_id) {
 6093            if let Some(cached_lens) = &lsp_data.code_lens {
 6094                if !version_queried_for.changed_since(&lsp_data.buffer_version) {
 6095                    let has_different_servers = existing_servers.is_some_and(|existing_servers| {
 6096                        existing_servers != cached_lens.lens.keys().copied().collect()
 6097                    });
 6098                    if !has_different_servers {
 6099                        return Task::ready(Ok(Some(
 6100                            cached_lens.lens.values().flatten().cloned().collect(),
 6101                        )))
 6102                        .shared();
 6103                    }
 6104                } else if let Some((updating_for, running_update)) = cached_lens.update.as_ref() {
 6105                    if !version_queried_for.changed_since(updating_for) {
 6106                        return running_update.clone();
 6107                    }
 6108                }
 6109            }
 6110        }
 6111
 6112        let lens_lsp_data = self
 6113            .latest_lsp_data(buffer, cx)
 6114            .code_lens
 6115            .get_or_insert_default();
 6116        let buffer = buffer.clone();
 6117        let query_version_queried_for = version_queried_for.clone();
 6118        let new_task = cx
 6119            .spawn(async move |lsp_store, cx| {
 6120                cx.background_executor()
 6121                    .timer(Duration::from_millis(30))
 6122                    .await;
 6123                let fetched_lens = lsp_store
 6124                    .update(cx, |lsp_store, cx| lsp_store.fetch_code_lens(&buffer, cx))
 6125                    .map_err(Arc::new)?
 6126                    .await
 6127                    .context("fetching code lens")
 6128                    .map_err(Arc::new);
 6129                let fetched_lens = match fetched_lens {
 6130                    Ok(fetched_lens) => fetched_lens,
 6131                    Err(e) => {
 6132                        lsp_store
 6133                            .update(cx, |lsp_store, _| {
 6134                                if let Some(lens_lsp_data) = lsp_store
 6135                                    .lsp_data
 6136                                    .get_mut(&buffer_id)
 6137                                    .and_then(|lsp_data| lsp_data.code_lens.as_mut())
 6138                                {
 6139                                    lens_lsp_data.update = None;
 6140                                }
 6141                            })
 6142                            .ok();
 6143                        return Err(e);
 6144                    }
 6145                };
 6146
 6147                lsp_store
 6148                    .update(cx, |lsp_store, _| {
 6149                        let lsp_data = lsp_store.current_lsp_data(buffer_id)?;
 6150                        let code_lens = lsp_data.code_lens.as_mut()?;
 6151                        if let Some(fetched_lens) = fetched_lens {
 6152                            if lsp_data.buffer_version == query_version_queried_for {
 6153                                code_lens.lens.extend(fetched_lens);
 6154                            } else if !lsp_data
 6155                                .buffer_version
 6156                                .changed_since(&query_version_queried_for)
 6157                            {
 6158                                lsp_data.buffer_version = query_version_queried_for;
 6159                                code_lens.lens = fetched_lens;
 6160                            }
 6161                        }
 6162                        code_lens.update = None;
 6163                        Some(code_lens.lens.values().flatten().cloned().collect())
 6164                    })
 6165                    .map_err(Arc::new)
 6166            })
 6167            .shared();
 6168        lens_lsp_data.update = Some((version_queried_for, new_task.clone()));
 6169        new_task
 6170    }
 6171
 6172    fn fetch_code_lens(
 6173        &mut self,
 6174        buffer: &Entity<Buffer>,
 6175        cx: &mut Context<Self>,
 6176    ) -> Task<Result<Option<HashMap<LanguageServerId, Vec<CodeAction>>>>> {
 6177        if let Some((upstream_client, project_id)) = self.upstream_client() {
 6178            let request = GetCodeLens;
 6179            if !self.is_capable_for_proto_request(buffer, &request, cx) {
 6180                return Task::ready(Ok(None));
 6181            }
 6182            let request_task = upstream_client.request_lsp(
 6183                project_id,
 6184                None,
 6185                LSP_REQUEST_TIMEOUT,
 6186                cx.background_executor().clone(),
 6187                request.to_proto(project_id, buffer.read(cx)),
 6188            );
 6189            let buffer = buffer.clone();
 6190            cx.spawn(async move |weak_lsp_store, cx| {
 6191                let Some(lsp_store) = weak_lsp_store.upgrade() else {
 6192                    return Ok(None);
 6193                };
 6194                let Some(responses) = request_task.await? else {
 6195                    return Ok(None);
 6196                };
 6197
 6198                let code_lens_actions = join_all(responses.payload.into_iter().map(|response| {
 6199                    let lsp_store = lsp_store.clone();
 6200                    let buffer = buffer.clone();
 6201                    let cx = cx.clone();
 6202                    async move {
 6203                        (
 6204                            LanguageServerId::from_proto(response.server_id),
 6205                            GetCodeLens
 6206                                .response_from_proto(response.response, lsp_store, buffer, cx)
 6207                                .await,
 6208                        )
 6209                    }
 6210                }))
 6211                .await;
 6212
 6213                let mut has_errors = false;
 6214                let code_lens_actions = code_lens_actions
 6215                    .into_iter()
 6216                    .filter_map(|(server_id, code_lens)| match code_lens {
 6217                        Ok(code_lens) => Some((server_id, code_lens)),
 6218                        Err(e) => {
 6219                            has_errors = true;
 6220                            log::error!("{e:#}");
 6221                            None
 6222                        }
 6223                    })
 6224                    .collect::<HashMap<_, _>>();
 6225                anyhow::ensure!(
 6226                    !has_errors || !code_lens_actions.is_empty(),
 6227                    "Failed to fetch code lens"
 6228                );
 6229                Ok(Some(code_lens_actions))
 6230            })
 6231        } else {
 6232            let code_lens_actions_task =
 6233                self.request_multiple_lsp_locally(buffer, None::<usize>, GetCodeLens, cx);
 6234            cx.background_spawn(async move {
 6235                Ok(Some(code_lens_actions_task.await.into_iter().collect()))
 6236            })
 6237        }
 6238    }
 6239
 6240    #[inline(never)]
 6241    pub fn completions(
 6242        &self,
 6243        buffer: &Entity<Buffer>,
 6244        position: PointUtf16,
 6245        context: CompletionContext,
 6246        cx: &mut Context<Self>,
 6247    ) -> Task<Result<Vec<CompletionResponse>>> {
 6248        let language_registry = self.languages.clone();
 6249
 6250        if let Some((upstream_client, project_id)) = self.upstream_client() {
 6251            let snapshot = buffer.read(cx).snapshot();
 6252            let offset = position.to_offset(&snapshot);
 6253            let scope = snapshot.language_scope_at(offset);
 6254            let capable_lsps = self.all_capable_for_proto_request(
 6255                buffer,
 6256                |server_name, capabilities| {
 6257                    capabilities.completion_provider.is_some()
 6258                        && scope
 6259                            .as_ref()
 6260                            .map(|scope| scope.language_allowed(server_name))
 6261                            .unwrap_or(true)
 6262                },
 6263                cx,
 6264            );
 6265            if capable_lsps.is_empty() {
 6266                return Task::ready(Ok(Vec::new()));
 6267            }
 6268
 6269            let language = buffer.read(cx).language().cloned();
 6270
 6271            // In the future, we should provide project guests with the names of LSP adapters,
 6272            // so that they can use the correct LSP adapter when computing labels. For now,
 6273            // guests just use the first LSP adapter associated with the buffer's language.
 6274            let lsp_adapter = language.as_ref().and_then(|language| {
 6275                language_registry
 6276                    .lsp_adapters(&language.name())
 6277                    .first()
 6278                    .cloned()
 6279            });
 6280
 6281            let buffer = buffer.clone();
 6282
 6283            cx.spawn(async move |this, cx| {
 6284                let requests = join_all(
 6285                    capable_lsps
 6286                        .into_iter()
 6287                        .map(|id| {
 6288                            let request = GetCompletions {
 6289                                position,
 6290                                context: context.clone(),
 6291                                server_id: Some(id),
 6292                            };
 6293                            let buffer = buffer.clone();
 6294                            let language = language.clone();
 6295                            let lsp_adapter = lsp_adapter.clone();
 6296                            let upstream_client = upstream_client.clone();
 6297                            let response = this
 6298                                .update(cx, |this, cx| {
 6299                                    this.send_lsp_proto_request(
 6300                                        buffer,
 6301                                        upstream_client,
 6302                                        project_id,
 6303                                        request,
 6304                                        cx,
 6305                                    )
 6306                                })
 6307                                .log_err();
 6308                            async move {
 6309                                let response = response?.await.log_err()?;
 6310
 6311                                let completions = populate_labels_for_completions(
 6312                                    response.completions,
 6313                                    language,
 6314                                    lsp_adapter,
 6315                                )
 6316                                .await;
 6317
 6318                                Some(CompletionResponse {
 6319                                    completions,
 6320                                    display_options: CompletionDisplayOptions::default(),
 6321                                    is_incomplete: response.is_incomplete,
 6322                                })
 6323                            }
 6324                        })
 6325                        .collect::<Vec<_>>(),
 6326                );
 6327                Ok(requests.await.into_iter().flatten().collect::<Vec<_>>())
 6328            })
 6329        } else if let Some(local) = self.as_local() {
 6330            let snapshot = buffer.read(cx).snapshot();
 6331            let offset = position.to_offset(&snapshot);
 6332            let scope = snapshot.language_scope_at(offset);
 6333            let language = snapshot.language().cloned();
 6334            let completion_settings = language_settings(
 6335                language.as_ref().map(|language| language.name()),
 6336                buffer.read(cx).file(),
 6337                cx,
 6338            )
 6339            .completions
 6340            .clone();
 6341            if !completion_settings.lsp {
 6342                return Task::ready(Ok(Vec::new()));
 6343            }
 6344
 6345            let server_ids: Vec<_> = buffer.update(cx, |buffer, cx| {
 6346                local
 6347                    .language_servers_for_buffer(buffer, cx)
 6348                    .filter(|(_, server)| server.capabilities().completion_provider.is_some())
 6349                    .filter(|(adapter, _)| {
 6350                        scope
 6351                            .as_ref()
 6352                            .map(|scope| scope.language_allowed(&adapter.name))
 6353                            .unwrap_or(true)
 6354                    })
 6355                    .map(|(_, server)| server.server_id())
 6356                    .collect()
 6357            });
 6358
 6359            let buffer = buffer.clone();
 6360            let lsp_timeout = completion_settings.lsp_fetch_timeout_ms;
 6361            let lsp_timeout = if lsp_timeout > 0 {
 6362                Some(Duration::from_millis(lsp_timeout))
 6363            } else {
 6364                None
 6365            };
 6366            cx.spawn(async move |this,  cx| {
 6367                let mut tasks = Vec::with_capacity(server_ids.len());
 6368                this.update(cx, |lsp_store, cx| {
 6369                    for server_id in server_ids {
 6370                        let lsp_adapter = lsp_store.language_server_adapter_for_id(server_id);
 6371                        let lsp_timeout = lsp_timeout
 6372                            .map(|lsp_timeout| cx.background_executor().timer(lsp_timeout));
 6373                        let mut timeout = cx.background_spawn(async move {
 6374                            match lsp_timeout {
 6375                                Some(lsp_timeout) => {
 6376                                    lsp_timeout.await;
 6377                                    true
 6378                                },
 6379                                None => false,
 6380                            }
 6381                        }).fuse();
 6382                        let mut lsp_request = lsp_store.request_lsp(
 6383                            buffer.clone(),
 6384                            LanguageServerToQuery::Other(server_id),
 6385                            GetCompletions {
 6386                                position,
 6387                                context: context.clone(),
 6388                                server_id: Some(server_id),
 6389                            },
 6390                            cx,
 6391                        ).fuse();
 6392                        let new_task = cx.background_spawn(async move {
 6393                            select_biased! {
 6394                                response = lsp_request => anyhow::Ok(Some(response?)),
 6395                                timeout_happened = timeout => {
 6396                                    if timeout_happened {
 6397                                        log::warn!("Fetching completions from server {server_id} timed out, timeout ms: {}", completion_settings.lsp_fetch_timeout_ms);
 6398                                        Ok(None)
 6399                                    } else {
 6400                                        let completions = lsp_request.await?;
 6401                                        Ok(Some(completions))
 6402                                    }
 6403                                },
 6404                            }
 6405                        });
 6406                        tasks.push((lsp_adapter, new_task));
 6407                    }
 6408                })?;
 6409
 6410                let futures = tasks.into_iter().map(async |(lsp_adapter, task)| {
 6411                    let completion_response = task.await.ok()??;
 6412                    let completions = populate_labels_for_completions(
 6413                            completion_response.completions,
 6414                            language.clone(),
 6415                            lsp_adapter,
 6416                        )
 6417                        .await;
 6418                    Some(CompletionResponse {
 6419                        completions,
 6420                        display_options: CompletionDisplayOptions::default(),
 6421                        is_incomplete: completion_response.is_incomplete,
 6422                    })
 6423                });
 6424
 6425                let responses: Vec<Option<CompletionResponse>> = join_all(futures).await;
 6426
 6427                Ok(responses.into_iter().flatten().collect())
 6428            })
 6429        } else {
 6430            Task::ready(Err(anyhow!("No upstream client or local language server")))
 6431        }
 6432    }
 6433
 6434    pub fn resolve_completions(
 6435        &self,
 6436        buffer: Entity<Buffer>,
 6437        completion_indices: Vec<usize>,
 6438        completions: Rc<RefCell<Box<[Completion]>>>,
 6439        cx: &mut Context<Self>,
 6440    ) -> Task<Result<bool>> {
 6441        let client = self.upstream_client();
 6442        let buffer_id = buffer.read(cx).remote_id();
 6443        let buffer_snapshot = buffer.read(cx).snapshot();
 6444
 6445        if !self.check_if_capable_for_proto_request(
 6446            &buffer,
 6447            GetCompletions::can_resolve_completions,
 6448            cx,
 6449        ) {
 6450            return Task::ready(Ok(false));
 6451        }
 6452        cx.spawn(async move |lsp_store, cx| {
 6453            let mut did_resolve = false;
 6454            if let Some((client, project_id)) = client {
 6455                for completion_index in completion_indices {
 6456                    let server_id = {
 6457                        let completion = &completions.borrow()[completion_index];
 6458                        completion.source.server_id()
 6459                    };
 6460                    if let Some(server_id) = server_id {
 6461                        if Self::resolve_completion_remote(
 6462                            project_id,
 6463                            server_id,
 6464                            buffer_id,
 6465                            completions.clone(),
 6466                            completion_index,
 6467                            client.clone(),
 6468                        )
 6469                        .await
 6470                        .log_err()
 6471                        .is_some()
 6472                        {
 6473                            did_resolve = true;
 6474                        }
 6475                    } else {
 6476                        resolve_word_completion(
 6477                            &buffer_snapshot,
 6478                            &mut completions.borrow_mut()[completion_index],
 6479                        );
 6480                    }
 6481                }
 6482            } else {
 6483                for completion_index in completion_indices {
 6484                    let server_id = {
 6485                        let completion = &completions.borrow()[completion_index];
 6486                        completion.source.server_id()
 6487                    };
 6488                    if let Some(server_id) = server_id {
 6489                        let server_and_adapter = lsp_store
 6490                            .read_with(cx, |lsp_store, _| {
 6491                                let server = lsp_store.language_server_for_id(server_id)?;
 6492                                let adapter =
 6493                                    lsp_store.language_server_adapter_for_id(server.server_id())?;
 6494                                Some((server, adapter))
 6495                            })
 6496                            .ok()
 6497                            .flatten();
 6498                        let Some((server, adapter)) = server_and_adapter else {
 6499                            continue;
 6500                        };
 6501
 6502                        let resolved = Self::resolve_completion_local(
 6503                            server,
 6504                            completions.clone(),
 6505                            completion_index,
 6506                        )
 6507                        .await
 6508                        .log_err()
 6509                        .is_some();
 6510                        if resolved {
 6511                            Self::regenerate_completion_labels(
 6512                                adapter,
 6513                                &buffer_snapshot,
 6514                                completions.clone(),
 6515                                completion_index,
 6516                            )
 6517                            .await
 6518                            .log_err();
 6519                            did_resolve = true;
 6520                        }
 6521                    } else {
 6522                        resolve_word_completion(
 6523                            &buffer_snapshot,
 6524                            &mut completions.borrow_mut()[completion_index],
 6525                        );
 6526                    }
 6527                }
 6528            }
 6529
 6530            Ok(did_resolve)
 6531        })
 6532    }
 6533
 6534    async fn resolve_completion_local(
 6535        server: Arc<lsp::LanguageServer>,
 6536        completions: Rc<RefCell<Box<[Completion]>>>,
 6537        completion_index: usize,
 6538    ) -> Result<()> {
 6539        let server_id = server.server_id();
 6540        if !GetCompletions::can_resolve_completions(&server.capabilities()) {
 6541            return Ok(());
 6542        }
 6543
 6544        let request = {
 6545            let completion = &completions.borrow()[completion_index];
 6546            match &completion.source {
 6547                CompletionSource::Lsp {
 6548                    lsp_completion,
 6549                    resolved,
 6550                    server_id: completion_server_id,
 6551                    ..
 6552                } => {
 6553                    if *resolved {
 6554                        return Ok(());
 6555                    }
 6556                    anyhow::ensure!(
 6557                        server_id == *completion_server_id,
 6558                        "server_id mismatch, querying completion resolve for {server_id} but completion server id is {completion_server_id}"
 6559                    );
 6560                    server.request::<lsp::request::ResolveCompletionItem>(*lsp_completion.clone())
 6561                }
 6562                CompletionSource::BufferWord { .. }
 6563                | CompletionSource::Dap { .. }
 6564                | CompletionSource::Custom => {
 6565                    return Ok(());
 6566                }
 6567            }
 6568        };
 6569        let resolved_completion = request
 6570            .await
 6571            .into_response()
 6572            .context("resolve completion")?;
 6573
 6574        // We must not use any data such as sortText, filterText, insertText and textEdit to edit `Completion` since they are not suppose change during resolve.
 6575        // Refer: https://microsoft.github.io/language-server-protocol/specifications/lsp/3.17/specification/#textDocument_completion
 6576
 6577        let mut completions = completions.borrow_mut();
 6578        let completion = &mut completions[completion_index];
 6579        if let CompletionSource::Lsp {
 6580            lsp_completion,
 6581            resolved,
 6582            server_id: completion_server_id,
 6583            ..
 6584        } = &mut completion.source
 6585        {
 6586            if *resolved {
 6587                return Ok(());
 6588            }
 6589            anyhow::ensure!(
 6590                server_id == *completion_server_id,
 6591                "server_id mismatch, applying completion resolve for {server_id} but completion server id is {completion_server_id}"
 6592            );
 6593            **lsp_completion = resolved_completion;
 6594            *resolved = true;
 6595        }
 6596        Ok(())
 6597    }
 6598
 6599    async fn regenerate_completion_labels(
 6600        adapter: Arc<CachedLspAdapter>,
 6601        snapshot: &BufferSnapshot,
 6602        completions: Rc<RefCell<Box<[Completion]>>>,
 6603        completion_index: usize,
 6604    ) -> Result<()> {
 6605        let completion_item = completions.borrow()[completion_index]
 6606            .source
 6607            .lsp_completion(true)
 6608            .map(Cow::into_owned);
 6609        if let Some(lsp_documentation) = completion_item
 6610            .as_ref()
 6611            .and_then(|completion_item| completion_item.documentation.clone())
 6612        {
 6613            let mut completions = completions.borrow_mut();
 6614            let completion = &mut completions[completion_index];
 6615            completion.documentation = Some(lsp_documentation.into());
 6616        } else {
 6617            let mut completions = completions.borrow_mut();
 6618            let completion = &mut completions[completion_index];
 6619            completion.documentation = Some(CompletionDocumentation::Undocumented);
 6620        }
 6621
 6622        let mut new_label = match completion_item {
 6623            Some(completion_item) => {
 6624                // Some language servers always return `detail` lazily via resolve, regardless of
 6625                // the resolvable properties Zed advertises. Regenerate labels here to handle this.
 6626                // See: https://github.com/yioneko/vtsls/issues/213
 6627                let language = snapshot.language();
 6628                match language {
 6629                    Some(language) => {
 6630                        adapter
 6631                            .labels_for_completions(
 6632                                std::slice::from_ref(&completion_item),
 6633                                language,
 6634                            )
 6635                            .await?
 6636                    }
 6637                    None => Vec::new(),
 6638                }
 6639                .pop()
 6640                .flatten()
 6641                .unwrap_or_else(|| {
 6642                    CodeLabel::fallback_for_completion(
 6643                        &completion_item,
 6644                        language.map(|language| language.as_ref()),
 6645                    )
 6646                })
 6647            }
 6648            None => CodeLabel::plain(
 6649                completions.borrow()[completion_index].new_text.clone(),
 6650                None,
 6651            ),
 6652        };
 6653        ensure_uniform_list_compatible_label(&mut new_label);
 6654
 6655        let mut completions = completions.borrow_mut();
 6656        let completion = &mut completions[completion_index];
 6657        if completion.label.filter_text() == new_label.filter_text() {
 6658            completion.label = new_label;
 6659        } else {
 6660            log::error!(
 6661                "Resolved completion changed display label from {} to {}. \
 6662                 Refusing to apply this because it changes the fuzzy match text from {} to {}",
 6663                completion.label.text(),
 6664                new_label.text(),
 6665                completion.label.filter_text(),
 6666                new_label.filter_text()
 6667            );
 6668        }
 6669
 6670        Ok(())
 6671    }
 6672
 6673    async fn resolve_completion_remote(
 6674        project_id: u64,
 6675        server_id: LanguageServerId,
 6676        buffer_id: BufferId,
 6677        completions: Rc<RefCell<Box<[Completion]>>>,
 6678        completion_index: usize,
 6679        client: AnyProtoClient,
 6680    ) -> Result<()> {
 6681        let lsp_completion = {
 6682            let completion = &completions.borrow()[completion_index];
 6683            match &completion.source {
 6684                CompletionSource::Lsp {
 6685                    lsp_completion,
 6686                    resolved,
 6687                    server_id: completion_server_id,
 6688                    ..
 6689                } => {
 6690                    anyhow::ensure!(
 6691                        server_id == *completion_server_id,
 6692                        "remote server_id mismatch, querying completion resolve for {server_id} but completion server id is {completion_server_id}"
 6693                    );
 6694                    if *resolved {
 6695                        return Ok(());
 6696                    }
 6697                    serde_json::to_string(lsp_completion).unwrap().into_bytes()
 6698                }
 6699                CompletionSource::Custom
 6700                | CompletionSource::Dap { .. }
 6701                | CompletionSource::BufferWord { .. } => {
 6702                    return Ok(());
 6703                }
 6704            }
 6705        };
 6706        let request = proto::ResolveCompletionDocumentation {
 6707            project_id,
 6708            language_server_id: server_id.0 as u64,
 6709            lsp_completion,
 6710            buffer_id: buffer_id.into(),
 6711        };
 6712
 6713        let response = client
 6714            .request(request)
 6715            .await
 6716            .context("completion documentation resolve proto request")?;
 6717        let resolved_lsp_completion = serde_json::from_slice(&response.lsp_completion)?;
 6718
 6719        let documentation = if response.documentation.is_empty() {
 6720            CompletionDocumentation::Undocumented
 6721        } else if response.documentation_is_markdown {
 6722            CompletionDocumentation::MultiLineMarkdown(response.documentation.into())
 6723        } else if response.documentation.lines().count() <= 1 {
 6724            CompletionDocumentation::SingleLine(response.documentation.into())
 6725        } else {
 6726            CompletionDocumentation::MultiLinePlainText(response.documentation.into())
 6727        };
 6728
 6729        let mut completions = completions.borrow_mut();
 6730        let completion = &mut completions[completion_index];
 6731        completion.documentation = Some(documentation);
 6732        if let CompletionSource::Lsp {
 6733            insert_range,
 6734            lsp_completion,
 6735            resolved,
 6736            server_id: completion_server_id,
 6737            lsp_defaults: _,
 6738        } = &mut completion.source
 6739        {
 6740            let completion_insert_range = response
 6741                .old_insert_start
 6742                .and_then(deserialize_anchor)
 6743                .zip(response.old_insert_end.and_then(deserialize_anchor));
 6744            *insert_range = completion_insert_range.map(|(start, end)| start..end);
 6745
 6746            if *resolved {
 6747                return Ok(());
 6748            }
 6749            anyhow::ensure!(
 6750                server_id == *completion_server_id,
 6751                "remote server_id mismatch, applying completion resolve for {server_id} but completion server id is {completion_server_id}"
 6752            );
 6753            **lsp_completion = resolved_lsp_completion;
 6754            *resolved = true;
 6755        }
 6756
 6757        let replace_range = response
 6758            .old_replace_start
 6759            .and_then(deserialize_anchor)
 6760            .zip(response.old_replace_end.and_then(deserialize_anchor));
 6761        if let Some((old_replace_start, old_replace_end)) = replace_range
 6762            && !response.new_text.is_empty()
 6763        {
 6764            completion.new_text = response.new_text;
 6765            completion.replace_range = old_replace_start..old_replace_end;
 6766        }
 6767
 6768        Ok(())
 6769    }
 6770
 6771    pub fn apply_additional_edits_for_completion(
 6772        &self,
 6773        buffer_handle: Entity<Buffer>,
 6774        completions: Rc<RefCell<Box<[Completion]>>>,
 6775        completion_index: usize,
 6776        push_to_history: bool,
 6777        cx: &mut Context<Self>,
 6778    ) -> Task<Result<Option<Transaction>>> {
 6779        if let Some((client, project_id)) = self.upstream_client() {
 6780            let buffer = buffer_handle.read(cx);
 6781            let buffer_id = buffer.remote_id();
 6782            cx.spawn(async move |_, cx| {
 6783                let request = {
 6784                    let completion = completions.borrow()[completion_index].clone();
 6785                    proto::ApplyCompletionAdditionalEdits {
 6786                        project_id,
 6787                        buffer_id: buffer_id.into(),
 6788                        completion: Some(Self::serialize_completion(&CoreCompletion {
 6789                            replace_range: completion.replace_range,
 6790                            new_text: completion.new_text,
 6791                            source: completion.source,
 6792                        })),
 6793                    }
 6794                };
 6795
 6796                if let Some(transaction) = client.request(request).await?.transaction {
 6797                    let transaction = language::proto::deserialize_transaction(transaction)?;
 6798                    buffer_handle
 6799                        .update(cx, |buffer, _| {
 6800                            buffer.wait_for_edits(transaction.edit_ids.iter().copied())
 6801                        })
 6802                        .await?;
 6803                    if push_to_history {
 6804                        buffer_handle.update(cx, |buffer, _| {
 6805                            buffer.push_transaction(transaction.clone(), Instant::now());
 6806                            buffer.finalize_last_transaction();
 6807                        });
 6808                    }
 6809                    Ok(Some(transaction))
 6810                } else {
 6811                    Ok(None)
 6812                }
 6813            })
 6814        } else {
 6815            let Some(server) = buffer_handle.update(cx, |buffer, cx| {
 6816                let completion = &completions.borrow()[completion_index];
 6817                let server_id = completion.source.server_id()?;
 6818                Some(
 6819                    self.language_server_for_local_buffer(buffer, server_id, cx)?
 6820                        .1
 6821                        .clone(),
 6822                )
 6823            }) else {
 6824                return Task::ready(Ok(None));
 6825            };
 6826
 6827            cx.spawn(async move |this, cx| {
 6828                Self::resolve_completion_local(
 6829                    server.clone(),
 6830                    completions.clone(),
 6831                    completion_index,
 6832                )
 6833                .await
 6834                .context("resolving completion")?;
 6835                let completion = completions.borrow()[completion_index].clone();
 6836                let additional_text_edits = completion
 6837                    .source
 6838                    .lsp_completion(true)
 6839                    .as_ref()
 6840                    .and_then(|lsp_completion| lsp_completion.additional_text_edits.clone());
 6841                if let Some(edits) = additional_text_edits {
 6842                    let edits = this
 6843                        .update(cx, |this, cx| {
 6844                            this.as_local_mut().unwrap().edits_from_lsp(
 6845                                &buffer_handle,
 6846                                edits,
 6847                                server.server_id(),
 6848                                None,
 6849                                cx,
 6850                            )
 6851                        })?
 6852                        .await?;
 6853
 6854                    buffer_handle.update(cx, |buffer, cx| {
 6855                        buffer.finalize_last_transaction();
 6856                        buffer.start_transaction();
 6857
 6858                        for (range, text) in edits {
 6859                            let primary = &completion.replace_range;
 6860
 6861                            // Special case: if both ranges start at the very beginning of the file (line 0, column 0),
 6862                            // and the primary completion is just an insertion (empty range), then this is likely
 6863                            // an auto-import scenario and should not be considered overlapping
 6864                            // https://github.com/zed-industries/zed/issues/26136
 6865                            let is_file_start_auto_import = {
 6866                                let snapshot = buffer.snapshot();
 6867                                let primary_start_point = primary.start.to_point(&snapshot);
 6868                                let range_start_point = range.start.to_point(&snapshot);
 6869
 6870                                let result = primary_start_point.row == 0
 6871                                    && primary_start_point.column == 0
 6872                                    && range_start_point.row == 0
 6873                                    && range_start_point.column == 0;
 6874
 6875                                result
 6876                            };
 6877
 6878                            let has_overlap = if is_file_start_auto_import {
 6879                                false
 6880                            } else {
 6881                                let start_within = primary.start.cmp(&range.start, buffer).is_le()
 6882                                    && primary.end.cmp(&range.start, buffer).is_ge();
 6883                                let end_within = range.start.cmp(&primary.end, buffer).is_le()
 6884                                    && range.end.cmp(&primary.end, buffer).is_ge();
 6885                                let result = start_within || end_within;
 6886                                result
 6887                            };
 6888
 6889                            //Skip additional edits which overlap with the primary completion edit
 6890                            //https://github.com/zed-industries/zed/pull/1871
 6891                            if !has_overlap {
 6892                                buffer.edit([(range, text)], None, cx);
 6893                            }
 6894                        }
 6895
 6896                        let transaction = if buffer.end_transaction(cx).is_some() {
 6897                            let transaction = buffer.finalize_last_transaction().unwrap().clone();
 6898                            if !push_to_history {
 6899                                buffer.forget_transaction(transaction.id);
 6900                            }
 6901                            Some(transaction)
 6902                        } else {
 6903                            None
 6904                        };
 6905                        Ok(transaction)
 6906                    })
 6907                } else {
 6908                    Ok(None)
 6909                }
 6910            })
 6911        }
 6912    }
 6913
 6914    pub fn pull_diagnostics(
 6915        &mut self,
 6916        buffer: Entity<Buffer>,
 6917        cx: &mut Context<Self>,
 6918    ) -> Task<Result<Option<Vec<LspPullDiagnostics>>>> {
 6919        let buffer_id = buffer.read(cx).remote_id();
 6920
 6921        if let Some((client, upstream_project_id)) = self.upstream_client() {
 6922            let mut suitable_capabilities = None;
 6923            // Are we capable for proto request?
 6924            let any_server_has_diagnostics_provider = self.check_if_capable_for_proto_request(
 6925                &buffer,
 6926                |capabilities| {
 6927                    if let Some(caps) = &capabilities.diagnostic_provider {
 6928                        suitable_capabilities = Some(caps.clone());
 6929                        true
 6930                    } else {
 6931                        false
 6932                    }
 6933                },
 6934                cx,
 6935            );
 6936            // We don't really care which caps are passed into the request, as they're ignored by RPC anyways.
 6937            let Some(dynamic_caps) = suitable_capabilities else {
 6938                return Task::ready(Ok(None));
 6939            };
 6940            assert!(any_server_has_diagnostics_provider);
 6941
 6942            let identifier = buffer_diagnostic_identifier(&dynamic_caps);
 6943            let request = GetDocumentDiagnostics {
 6944                previous_result_id: None,
 6945                identifier,
 6946                registration_id: None,
 6947            };
 6948            let request_task = client.request_lsp(
 6949                upstream_project_id,
 6950                None,
 6951                LSP_REQUEST_TIMEOUT,
 6952                cx.background_executor().clone(),
 6953                request.to_proto(upstream_project_id, buffer.read(cx)),
 6954            );
 6955            cx.background_spawn(async move {
 6956                // Proto requests cause the diagnostics to be pulled from language server(s) on the local side
 6957                // and then, buffer state updated with the diagnostics received, which will be later propagated to the client.
 6958                // Do not attempt to further process the dummy responses here.
 6959                let _response = request_task.await?;
 6960                Ok(None)
 6961            })
 6962        } else {
 6963            let servers = buffer.update(cx, |buffer, cx| {
 6964                self.running_language_servers_for_local_buffer(buffer, cx)
 6965                    .map(|(_, server)| server.clone())
 6966                    .collect::<Vec<_>>()
 6967            });
 6968
 6969            let pull_diagnostics = servers
 6970                .into_iter()
 6971                .flat_map(|server| {
 6972                    let result = maybe!({
 6973                        let local = self.as_local()?;
 6974                        let server_id = server.server_id();
 6975                        let providers_with_identifiers = local
 6976                            .language_server_dynamic_registrations
 6977                            .get(&server_id)
 6978                            .into_iter()
 6979                            .flat_map(|registrations| registrations.diagnostics.clone())
 6980                            .collect::<Vec<_>>();
 6981                        Some(
 6982                            providers_with_identifiers
 6983                                .into_iter()
 6984                                .map(|(registration_id, dynamic_caps)| {
 6985                                    let identifier = buffer_diagnostic_identifier(&dynamic_caps);
 6986                                    let registration_id = registration_id.map(SharedString::from);
 6987                                    let result_id = self.result_id_for_buffer_pull(
 6988                                        server_id,
 6989                                        buffer_id,
 6990                                        &registration_id,
 6991                                        cx,
 6992                                    );
 6993                                    self.request_lsp(
 6994                                        buffer.clone(),
 6995                                        LanguageServerToQuery::Other(server_id),
 6996                                        GetDocumentDiagnostics {
 6997                                            previous_result_id: result_id,
 6998                                            registration_id,
 6999                                            identifier,
 7000                                        },
 7001                                        cx,
 7002                                    )
 7003                                })
 7004                                .collect::<Vec<_>>(),
 7005                        )
 7006                    });
 7007
 7008                    result.unwrap_or_default()
 7009                })
 7010                .collect::<Vec<_>>();
 7011
 7012            cx.background_spawn(async move {
 7013                let mut responses = Vec::new();
 7014                for diagnostics in join_all(pull_diagnostics).await {
 7015                    responses.extend(diagnostics?);
 7016                }
 7017                Ok(Some(responses))
 7018            })
 7019        }
 7020    }
 7021
 7022    pub fn applicable_inlay_chunks(
 7023        &mut self,
 7024        buffer: &Entity<Buffer>,
 7025        ranges: &[Range<text::Anchor>],
 7026        cx: &mut Context<Self>,
 7027    ) -> Vec<Range<BufferRow>> {
 7028        let buffer_snapshot = buffer.read(cx).snapshot();
 7029        let ranges = ranges
 7030            .iter()
 7031            .map(|range| range.to_point(&buffer_snapshot))
 7032            .collect::<Vec<_>>();
 7033
 7034        self.latest_lsp_data(buffer, cx)
 7035            .inlay_hints
 7036            .applicable_chunks(ranges.as_slice())
 7037            .map(|chunk| chunk.row_range())
 7038            .collect()
 7039    }
 7040
 7041    pub fn invalidate_inlay_hints<'a>(
 7042        &'a mut self,
 7043        for_buffers: impl IntoIterator<Item = &'a BufferId> + 'a,
 7044    ) {
 7045        for buffer_id in for_buffers {
 7046            if let Some(lsp_data) = self.lsp_data.get_mut(buffer_id) {
 7047                lsp_data.inlay_hints.clear();
 7048            }
 7049        }
 7050    }
 7051
 7052    pub fn inlay_hints(
 7053        &mut self,
 7054        invalidate: InvalidationStrategy,
 7055        buffer: Entity<Buffer>,
 7056        ranges: Vec<Range<text::Anchor>>,
 7057        known_chunks: Option<(clock::Global, HashSet<Range<BufferRow>>)>,
 7058        cx: &mut Context<Self>,
 7059    ) -> HashMap<Range<BufferRow>, Task<Result<CacheInlayHints>>> {
 7060        let next_hint_id = self.next_hint_id.clone();
 7061        let lsp_data = self.latest_lsp_data(&buffer, cx);
 7062        let query_version = lsp_data.buffer_version.clone();
 7063        let mut lsp_refresh_requested = false;
 7064        let for_server = if let InvalidationStrategy::RefreshRequested {
 7065            server_id,
 7066            request_id,
 7067        } = invalidate
 7068        {
 7069            let invalidated = lsp_data
 7070                .inlay_hints
 7071                .invalidate_for_server_refresh(server_id, request_id);
 7072            lsp_refresh_requested = invalidated;
 7073            Some(server_id)
 7074        } else {
 7075            None
 7076        };
 7077        let existing_inlay_hints = &mut lsp_data.inlay_hints;
 7078        let known_chunks = known_chunks
 7079            .filter(|(known_version, _)| !lsp_data.buffer_version.changed_since(known_version))
 7080            .map(|(_, known_chunks)| known_chunks)
 7081            .unwrap_or_default();
 7082
 7083        let buffer_snapshot = buffer.read(cx).snapshot();
 7084        let ranges = ranges
 7085            .iter()
 7086            .map(|range| range.to_point(&buffer_snapshot))
 7087            .collect::<Vec<_>>();
 7088
 7089        let mut hint_fetch_tasks = Vec::new();
 7090        let mut cached_inlay_hints = None;
 7091        let mut ranges_to_query = None;
 7092        let applicable_chunks = existing_inlay_hints
 7093            .applicable_chunks(ranges.as_slice())
 7094            .filter(|chunk| !known_chunks.contains(&chunk.row_range()))
 7095            .collect::<Vec<_>>();
 7096        if applicable_chunks.is_empty() {
 7097            return HashMap::default();
 7098        }
 7099
 7100        for row_chunk in applicable_chunks {
 7101            match (
 7102                existing_inlay_hints
 7103                    .cached_hints(&row_chunk)
 7104                    .filter(|_| !lsp_refresh_requested)
 7105                    .cloned(),
 7106                existing_inlay_hints
 7107                    .fetched_hints(&row_chunk)
 7108                    .as_ref()
 7109                    .filter(|_| !lsp_refresh_requested)
 7110                    .cloned(),
 7111            ) {
 7112                (None, None) => {
 7113                    let chunk_range = row_chunk.anchor_range();
 7114                    ranges_to_query
 7115                        .get_or_insert_with(Vec::new)
 7116                        .push((row_chunk, chunk_range));
 7117                }
 7118                (None, Some(fetched_hints)) => hint_fetch_tasks.push((row_chunk, fetched_hints)),
 7119                (Some(cached_hints), None) => {
 7120                    for (server_id, cached_hints) in cached_hints {
 7121                        if for_server.is_none_or(|for_server| for_server == server_id) {
 7122                            cached_inlay_hints
 7123                                .get_or_insert_with(HashMap::default)
 7124                                .entry(row_chunk.row_range())
 7125                                .or_insert_with(HashMap::default)
 7126                                .entry(server_id)
 7127                                .or_insert_with(Vec::new)
 7128                                .extend(cached_hints);
 7129                        }
 7130                    }
 7131                }
 7132                (Some(cached_hints), Some(fetched_hints)) => {
 7133                    hint_fetch_tasks.push((row_chunk, fetched_hints));
 7134                    for (server_id, cached_hints) in cached_hints {
 7135                        if for_server.is_none_or(|for_server| for_server == server_id) {
 7136                            cached_inlay_hints
 7137                                .get_or_insert_with(HashMap::default)
 7138                                .entry(row_chunk.row_range())
 7139                                .or_insert_with(HashMap::default)
 7140                                .entry(server_id)
 7141                                .or_insert_with(Vec::new)
 7142                                .extend(cached_hints);
 7143                        }
 7144                    }
 7145                }
 7146            }
 7147        }
 7148
 7149        if hint_fetch_tasks.is_empty()
 7150            && ranges_to_query
 7151                .as_ref()
 7152                .is_none_or(|ranges| ranges.is_empty())
 7153            && let Some(cached_inlay_hints) = cached_inlay_hints
 7154        {
 7155            cached_inlay_hints
 7156                .into_iter()
 7157                .map(|(row_chunk, hints)| (row_chunk, Task::ready(Ok(hints))))
 7158                .collect()
 7159        } else {
 7160            for (chunk, range_to_query) in ranges_to_query.into_iter().flatten() {
 7161                let next_hint_id = next_hint_id.clone();
 7162                let buffer = buffer.clone();
 7163                let query_version = query_version.clone();
 7164                let new_inlay_hints = cx
 7165                    .spawn(async move |lsp_store, cx| {
 7166                        let new_fetch_task = lsp_store.update(cx, |lsp_store, cx| {
 7167                            lsp_store.fetch_inlay_hints(for_server, &buffer, range_to_query, cx)
 7168                        })?;
 7169                        new_fetch_task
 7170                            .await
 7171                            .and_then(|new_hints_by_server| {
 7172                                lsp_store.update(cx, |lsp_store, cx| {
 7173                                    let lsp_data = lsp_store.latest_lsp_data(&buffer, cx);
 7174                                    let update_cache = lsp_data.buffer_version == query_version;
 7175                                    if new_hints_by_server.is_empty() {
 7176                                        if update_cache {
 7177                                            lsp_data.inlay_hints.invalidate_for_chunk(chunk);
 7178                                        }
 7179                                        HashMap::default()
 7180                                    } else {
 7181                                        new_hints_by_server
 7182                                            .into_iter()
 7183                                            .map(|(server_id, new_hints)| {
 7184                                                let new_hints = new_hints
 7185                                                    .into_iter()
 7186                                                    .map(|new_hint| {
 7187                                                        (
 7188                                                            InlayId::Hint(next_hint_id.fetch_add(
 7189                                                                1,
 7190                                                                atomic::Ordering::AcqRel,
 7191                                                            )),
 7192                                                            new_hint,
 7193                                                        )
 7194                                                    })
 7195                                                    .collect::<Vec<_>>();
 7196                                                if update_cache {
 7197                                                    lsp_data.inlay_hints.insert_new_hints(
 7198                                                        chunk,
 7199                                                        server_id,
 7200                                                        new_hints.clone(),
 7201                                                    );
 7202                                                }
 7203                                                (server_id, new_hints)
 7204                                            })
 7205                                            .collect()
 7206                                    }
 7207                                })
 7208                            })
 7209                            .map_err(Arc::new)
 7210                    })
 7211                    .shared();
 7212
 7213                let fetch_task = lsp_data.inlay_hints.fetched_hints(&chunk);
 7214                *fetch_task = Some(new_inlay_hints.clone());
 7215                hint_fetch_tasks.push((chunk, new_inlay_hints));
 7216            }
 7217
 7218            cached_inlay_hints
 7219                .unwrap_or_default()
 7220                .into_iter()
 7221                .map(|(row_chunk, hints)| (row_chunk, Task::ready(Ok(hints))))
 7222                .chain(hint_fetch_tasks.into_iter().map(|(chunk, hints_fetch)| {
 7223                    (
 7224                        chunk.row_range(),
 7225                        cx.spawn(async move |_, _| {
 7226                            hints_fetch.await.map_err(|e| {
 7227                                if e.error_code() != ErrorCode::Internal {
 7228                                    anyhow!(e.error_code())
 7229                                } else {
 7230                                    anyhow!("{e:#}")
 7231                                }
 7232                            })
 7233                        }),
 7234                    )
 7235                }))
 7236                .collect()
 7237        }
 7238    }
 7239
 7240    fn fetch_inlay_hints(
 7241        &mut self,
 7242        for_server: Option<LanguageServerId>,
 7243        buffer: &Entity<Buffer>,
 7244        range: Range<Anchor>,
 7245        cx: &mut Context<Self>,
 7246    ) -> Task<Result<HashMap<LanguageServerId, Vec<InlayHint>>>> {
 7247        let request = InlayHints {
 7248            range: range.clone(),
 7249        };
 7250        if let Some((upstream_client, project_id)) = self.upstream_client() {
 7251            if !self.is_capable_for_proto_request(buffer, &request, cx) {
 7252                return Task::ready(Ok(HashMap::default()));
 7253            }
 7254            let request_task = upstream_client.request_lsp(
 7255                project_id,
 7256                for_server.map(|id| id.to_proto()),
 7257                LSP_REQUEST_TIMEOUT,
 7258                cx.background_executor().clone(),
 7259                request.to_proto(project_id, buffer.read(cx)),
 7260            );
 7261            let buffer = buffer.clone();
 7262            cx.spawn(async move |weak_lsp_store, cx| {
 7263                let Some(lsp_store) = weak_lsp_store.upgrade() else {
 7264                    return Ok(HashMap::default());
 7265                };
 7266                let Some(responses) = request_task.await? else {
 7267                    return Ok(HashMap::default());
 7268                };
 7269
 7270                let inlay_hints = join_all(responses.payload.into_iter().map(|response| {
 7271                    let lsp_store = lsp_store.clone();
 7272                    let buffer = buffer.clone();
 7273                    let cx = cx.clone();
 7274                    let request = request.clone();
 7275                    async move {
 7276                        (
 7277                            LanguageServerId::from_proto(response.server_id),
 7278                            request
 7279                                .response_from_proto(response.response, lsp_store, buffer, cx)
 7280                                .await,
 7281                        )
 7282                    }
 7283                }))
 7284                .await;
 7285
 7286                let buffer_snapshot = buffer.read_with(cx, |buffer, _| buffer.snapshot());
 7287                let mut has_errors = false;
 7288                let inlay_hints = inlay_hints
 7289                    .into_iter()
 7290                    .filter_map(|(server_id, inlay_hints)| match inlay_hints {
 7291                        Ok(inlay_hints) => Some((server_id, inlay_hints)),
 7292                        Err(e) => {
 7293                            has_errors = true;
 7294                            log::error!("{e:#}");
 7295                            None
 7296                        }
 7297                    })
 7298                    .map(|(server_id, mut new_hints)| {
 7299                        new_hints.retain(|hint| {
 7300                            hint.position.is_valid(&buffer_snapshot)
 7301                                && range.start.is_valid(&buffer_snapshot)
 7302                                && range.end.is_valid(&buffer_snapshot)
 7303                                && hint.position.cmp(&range.start, &buffer_snapshot).is_ge()
 7304                                && hint.position.cmp(&range.end, &buffer_snapshot).is_lt()
 7305                        });
 7306                        (server_id, new_hints)
 7307                    })
 7308                    .collect::<HashMap<_, _>>();
 7309                anyhow::ensure!(
 7310                    !has_errors || !inlay_hints.is_empty(),
 7311                    "Failed to fetch inlay hints"
 7312                );
 7313                Ok(inlay_hints)
 7314            })
 7315        } else {
 7316            let inlay_hints_task = match for_server {
 7317                Some(server_id) => {
 7318                    let server_task = self.request_lsp(
 7319                        buffer.clone(),
 7320                        LanguageServerToQuery::Other(server_id),
 7321                        request,
 7322                        cx,
 7323                    );
 7324                    cx.background_spawn(async move {
 7325                        let mut responses = Vec::new();
 7326                        match server_task.await {
 7327                            Ok(response) => responses.push((server_id, response)),
 7328                            // rust-analyzer likes to error with this when its still loading up
 7329                            Err(e) if format!("{e:#}").ends_with("content modified") => (),
 7330                            Err(e) => log::error!(
 7331                                "Error handling response for inlay hints request: {e:#}"
 7332                            ),
 7333                        }
 7334                        responses
 7335                    })
 7336                }
 7337                None => self.request_multiple_lsp_locally(buffer, None::<usize>, request, cx),
 7338            };
 7339            let buffer_snapshot = buffer.read_with(cx, |buffer, _| buffer.snapshot());
 7340            cx.background_spawn(async move {
 7341                Ok(inlay_hints_task
 7342                    .await
 7343                    .into_iter()
 7344                    .map(|(server_id, mut new_hints)| {
 7345                        new_hints.retain(|hint| {
 7346                            hint.position.is_valid(&buffer_snapshot)
 7347                                && range.start.is_valid(&buffer_snapshot)
 7348                                && range.end.is_valid(&buffer_snapshot)
 7349                                && hint.position.cmp(&range.start, &buffer_snapshot).is_ge()
 7350                                && hint.position.cmp(&range.end, &buffer_snapshot).is_lt()
 7351                        });
 7352                        (server_id, new_hints)
 7353                    })
 7354                    .collect())
 7355            })
 7356        }
 7357    }
 7358
 7359    fn diagnostic_registration_exists(
 7360        &self,
 7361        server_id: LanguageServerId,
 7362        registration_id: &Option<SharedString>,
 7363    ) -> bool {
 7364        let Some(local) = self.as_local() else {
 7365            return false;
 7366        };
 7367        let Some(registrations) = local.language_server_dynamic_registrations.get(&server_id)
 7368        else {
 7369            return false;
 7370        };
 7371        let registration_key = registration_id.as_ref().map(|s| s.to_string());
 7372        registrations.diagnostics.contains_key(&registration_key)
 7373    }
 7374
 7375    pub fn pull_diagnostics_for_buffer(
 7376        &mut self,
 7377        buffer: Entity<Buffer>,
 7378        cx: &mut Context<Self>,
 7379    ) -> Task<anyhow::Result<()>> {
 7380        let diagnostics = self.pull_diagnostics(buffer, cx);
 7381        cx.spawn(async move |lsp_store, cx| {
 7382            let Some(diagnostics) = diagnostics.await.context("pulling diagnostics")? else {
 7383                return Ok(());
 7384            };
 7385            lsp_store.update(cx, |lsp_store, cx| {
 7386                if lsp_store.as_local().is_none() {
 7387                    return;
 7388                }
 7389
 7390                let mut unchanged_buffers = HashMap::default();
 7391                let server_diagnostics_updates = diagnostics
 7392                    .into_iter()
 7393                    .filter_map(|diagnostics_set| match diagnostics_set {
 7394                        LspPullDiagnostics::Response {
 7395                            server_id,
 7396                            uri,
 7397                            diagnostics,
 7398                            registration_id,
 7399                        } => Some((server_id, uri, diagnostics, registration_id)),
 7400                        LspPullDiagnostics::Default => None,
 7401                    })
 7402                    .filter(|(server_id, _, _, registration_id)| {
 7403                        lsp_store.diagnostic_registration_exists(*server_id, registration_id)
 7404                    })
 7405                    .fold(
 7406                        HashMap::default(),
 7407                        |mut acc, (server_id, uri, diagnostics, new_registration_id)| {
 7408                            let (result_id, diagnostics) = match diagnostics {
 7409                                PulledDiagnostics::Unchanged { result_id } => {
 7410                                    unchanged_buffers
 7411                                        .entry(new_registration_id.clone())
 7412                                        .or_insert_with(HashSet::default)
 7413                                        .insert(uri.clone());
 7414                                    (Some(result_id), Vec::new())
 7415                                }
 7416                                PulledDiagnostics::Changed {
 7417                                    result_id,
 7418                                    diagnostics,
 7419                                } => (result_id, diagnostics),
 7420                            };
 7421                            let disk_based_sources = Cow::Owned(
 7422                                lsp_store
 7423                                    .language_server_adapter_for_id(server_id)
 7424                                    .as_ref()
 7425                                    .map(|adapter| adapter.disk_based_diagnostic_sources.as_slice())
 7426                                    .unwrap_or(&[])
 7427                                    .to_vec(),
 7428                            );
 7429                            acc.entry(server_id)
 7430                                .or_insert_with(HashMap::default)
 7431                                .entry(new_registration_id.clone())
 7432                                .or_insert_with(Vec::new)
 7433                                .push(DocumentDiagnosticsUpdate {
 7434                                    server_id,
 7435                                    diagnostics: lsp::PublishDiagnosticsParams {
 7436                                        uri,
 7437                                        diagnostics,
 7438                                        version: None,
 7439                                    },
 7440                                    result_id,
 7441                                    disk_based_sources,
 7442                                    registration_id: new_registration_id,
 7443                                });
 7444                            acc
 7445                        },
 7446                    );
 7447
 7448                for diagnostic_updates in server_diagnostics_updates.into_values() {
 7449                    for (registration_id, diagnostic_updates) in diagnostic_updates {
 7450                        lsp_store
 7451                            .merge_lsp_diagnostics(
 7452                                DiagnosticSourceKind::Pulled,
 7453                                diagnostic_updates,
 7454                                |document_uri, old_diagnostic, _| match old_diagnostic.source_kind {
 7455                                    DiagnosticSourceKind::Pulled => {
 7456                                        old_diagnostic.registration_id != registration_id
 7457                                            || unchanged_buffers
 7458                                                .get(&old_diagnostic.registration_id)
 7459                                                .is_some_and(|unchanged_buffers| {
 7460                                                    unchanged_buffers.contains(&document_uri)
 7461                                                })
 7462                                    }
 7463                                    DiagnosticSourceKind::Other | DiagnosticSourceKind::Pushed => {
 7464                                        true
 7465                                    }
 7466                                },
 7467                                cx,
 7468                            )
 7469                            .log_err();
 7470                    }
 7471                }
 7472            })
 7473        })
 7474    }
 7475
 7476    pub fn document_colors(
 7477        &mut self,
 7478        known_cache_version: Option<usize>,
 7479        buffer: Entity<Buffer>,
 7480        cx: &mut Context<Self>,
 7481    ) -> Option<DocumentColorTask> {
 7482        let version_queried_for = buffer.read(cx).version();
 7483        let buffer_id = buffer.read(cx).remote_id();
 7484
 7485        let current_language_servers = self.as_local().map(|local| {
 7486            local
 7487                .buffers_opened_in_servers
 7488                .get(&buffer_id)
 7489                .cloned()
 7490                .unwrap_or_default()
 7491        });
 7492
 7493        if let Some(lsp_data) = self.current_lsp_data(buffer_id) {
 7494            if let Some(cached_colors) = &lsp_data.document_colors {
 7495                if !version_queried_for.changed_since(&lsp_data.buffer_version) {
 7496                    let has_different_servers =
 7497                        current_language_servers.is_some_and(|current_language_servers| {
 7498                            current_language_servers
 7499                                != cached_colors.colors.keys().copied().collect()
 7500                        });
 7501                    if !has_different_servers {
 7502                        let cache_version = cached_colors.cache_version;
 7503                        if Some(cache_version) == known_cache_version {
 7504                            return None;
 7505                        } else {
 7506                            return Some(
 7507                                Task::ready(Ok(DocumentColors {
 7508                                    colors: cached_colors
 7509                                        .colors
 7510                                        .values()
 7511                                        .flatten()
 7512                                        .cloned()
 7513                                        .collect(),
 7514                                    cache_version: Some(cache_version),
 7515                                }))
 7516                                .shared(),
 7517                            );
 7518                        }
 7519                    }
 7520                }
 7521            }
 7522        }
 7523
 7524        let color_lsp_data = self
 7525            .latest_lsp_data(&buffer, cx)
 7526            .document_colors
 7527            .get_or_insert_default();
 7528        if let Some((updating_for, running_update)) = &color_lsp_data.colors_update
 7529            && !version_queried_for.changed_since(updating_for)
 7530        {
 7531            return Some(running_update.clone());
 7532        }
 7533        let buffer_version_queried_for = version_queried_for.clone();
 7534        let new_task = cx
 7535            .spawn(async move |lsp_store, cx| {
 7536                cx.background_executor()
 7537                    .timer(Duration::from_millis(30))
 7538                    .await;
 7539                let fetched_colors = lsp_store
 7540                    .update(cx, |lsp_store, cx| {
 7541                        lsp_store.fetch_document_colors_for_buffer(&buffer, cx)
 7542                    })?
 7543                    .await
 7544                    .context("fetching document colors")
 7545                    .map_err(Arc::new);
 7546                let fetched_colors = match fetched_colors {
 7547                    Ok(fetched_colors) => {
 7548                        if buffer.update(cx, |buffer, _| {
 7549                            buffer.version() != buffer_version_queried_for
 7550                        }) {
 7551                            return Ok(DocumentColors::default());
 7552                        }
 7553                        fetched_colors
 7554                    }
 7555                    Err(e) => {
 7556                        lsp_store
 7557                            .update(cx, |lsp_store, _| {
 7558                                if let Some(lsp_data) = lsp_store.lsp_data.get_mut(&buffer_id) {
 7559                                    if let Some(document_colors) = &mut lsp_data.document_colors {
 7560                                        document_colors.colors_update = None;
 7561                                    }
 7562                                }
 7563                            })
 7564                            .ok();
 7565                        return Err(e);
 7566                    }
 7567                };
 7568
 7569                lsp_store
 7570                    .update(cx, |lsp_store, cx| {
 7571                        let lsp_data = lsp_store.latest_lsp_data(&buffer, cx);
 7572                        let lsp_colors = lsp_data.document_colors.get_or_insert_default();
 7573
 7574                        if let Some(fetched_colors) = fetched_colors {
 7575                            if lsp_data.buffer_version == buffer_version_queried_for {
 7576                                lsp_colors.colors.extend(fetched_colors);
 7577                                lsp_colors.cache_version += 1;
 7578                            } else if !lsp_data
 7579                                .buffer_version
 7580                                .changed_since(&buffer_version_queried_for)
 7581                            {
 7582                                lsp_data.buffer_version = buffer_version_queried_for;
 7583                                lsp_colors.colors = fetched_colors;
 7584                                lsp_colors.cache_version += 1;
 7585                            }
 7586                        }
 7587                        lsp_colors.colors_update = None;
 7588                        let colors = lsp_colors
 7589                            .colors
 7590                            .values()
 7591                            .flatten()
 7592                            .cloned()
 7593                            .collect::<HashSet<_>>();
 7594                        DocumentColors {
 7595                            colors,
 7596                            cache_version: Some(lsp_colors.cache_version),
 7597                        }
 7598                    })
 7599                    .map_err(Arc::new)
 7600            })
 7601            .shared();
 7602        color_lsp_data.colors_update = Some((version_queried_for, new_task.clone()));
 7603        Some(new_task)
 7604    }
 7605
 7606    fn fetch_document_colors_for_buffer(
 7607        &mut self,
 7608        buffer: &Entity<Buffer>,
 7609        cx: &mut Context<Self>,
 7610    ) -> Task<anyhow::Result<Option<HashMap<LanguageServerId, HashSet<DocumentColor>>>>> {
 7611        if let Some((client, project_id)) = self.upstream_client() {
 7612            let request = GetDocumentColor {};
 7613            if !self.is_capable_for_proto_request(buffer, &request, cx) {
 7614                return Task::ready(Ok(None));
 7615            }
 7616
 7617            let request_task = client.request_lsp(
 7618                project_id,
 7619                None,
 7620                LSP_REQUEST_TIMEOUT,
 7621                cx.background_executor().clone(),
 7622                request.to_proto(project_id, buffer.read(cx)),
 7623            );
 7624            let buffer = buffer.clone();
 7625            cx.spawn(async move |lsp_store, cx| {
 7626                let Some(lsp_store) = lsp_store.upgrade() else {
 7627                    return Ok(None);
 7628                };
 7629                let colors = join_all(
 7630                    request_task
 7631                        .await
 7632                        .log_err()
 7633                        .flatten()
 7634                        .map(|response| response.payload)
 7635                        .unwrap_or_default()
 7636                        .into_iter()
 7637                        .map(|color_response| {
 7638                            let response = request.response_from_proto(
 7639                                color_response.response,
 7640                                lsp_store.clone(),
 7641                                buffer.clone(),
 7642                                cx.clone(),
 7643                            );
 7644                            async move {
 7645                                (
 7646                                    LanguageServerId::from_proto(color_response.server_id),
 7647                                    response.await.log_err().unwrap_or_default(),
 7648                                )
 7649                            }
 7650                        }),
 7651                )
 7652                .await
 7653                .into_iter()
 7654                .fold(HashMap::default(), |mut acc, (server_id, colors)| {
 7655                    acc.entry(server_id)
 7656                        .or_insert_with(HashSet::default)
 7657                        .extend(colors);
 7658                    acc
 7659                });
 7660                Ok(Some(colors))
 7661            })
 7662        } else {
 7663            let document_colors_task =
 7664                self.request_multiple_lsp_locally(buffer, None::<usize>, GetDocumentColor, cx);
 7665            cx.background_spawn(async move {
 7666                Ok(Some(
 7667                    document_colors_task
 7668                        .await
 7669                        .into_iter()
 7670                        .fold(HashMap::default(), |mut acc, (server_id, colors)| {
 7671                            acc.entry(server_id)
 7672                                .or_insert_with(HashSet::default)
 7673                                .extend(colors);
 7674                            acc
 7675                        })
 7676                        .into_iter()
 7677                        .collect(),
 7678                ))
 7679            })
 7680        }
 7681    }
 7682
 7683    pub fn signature_help<T: ToPointUtf16>(
 7684        &mut self,
 7685        buffer: &Entity<Buffer>,
 7686        position: T,
 7687        cx: &mut Context<Self>,
 7688    ) -> Task<Option<Vec<SignatureHelp>>> {
 7689        let position = position.to_point_utf16(buffer.read(cx));
 7690
 7691        if let Some((client, upstream_project_id)) = self.upstream_client() {
 7692            let request = GetSignatureHelp { position };
 7693            if !self.is_capable_for_proto_request(buffer, &request, cx) {
 7694                return Task::ready(None);
 7695            }
 7696            let request_task = client.request_lsp(
 7697                upstream_project_id,
 7698                None,
 7699                LSP_REQUEST_TIMEOUT,
 7700                cx.background_executor().clone(),
 7701                request.to_proto(upstream_project_id, buffer.read(cx)),
 7702            );
 7703            let buffer = buffer.clone();
 7704            cx.spawn(async move |weak_lsp_store, cx| {
 7705                let lsp_store = weak_lsp_store.upgrade()?;
 7706                let signatures = join_all(
 7707                    request_task
 7708                        .await
 7709                        .log_err()
 7710                        .flatten()
 7711                        .map(|response| response.payload)
 7712                        .unwrap_or_default()
 7713                        .into_iter()
 7714                        .map(|response| {
 7715                            let response = GetSignatureHelp { position }.response_from_proto(
 7716                                response.response,
 7717                                lsp_store.clone(),
 7718                                buffer.clone(),
 7719                                cx.clone(),
 7720                            );
 7721                            async move { response.await.log_err().flatten() }
 7722                        }),
 7723                )
 7724                .await
 7725                .into_iter()
 7726                .flatten()
 7727                .collect();
 7728                Some(signatures)
 7729            })
 7730        } else {
 7731            let all_actions_task = self.request_multiple_lsp_locally(
 7732                buffer,
 7733                Some(position),
 7734                GetSignatureHelp { position },
 7735                cx,
 7736            );
 7737            cx.background_spawn(async move {
 7738                Some(
 7739                    all_actions_task
 7740                        .await
 7741                        .into_iter()
 7742                        .flat_map(|(_, actions)| actions)
 7743                        .collect::<Vec<_>>(),
 7744                )
 7745            })
 7746        }
 7747    }
 7748
 7749    pub fn hover(
 7750        &mut self,
 7751        buffer: &Entity<Buffer>,
 7752        position: PointUtf16,
 7753        cx: &mut Context<Self>,
 7754    ) -> Task<Option<Vec<Hover>>> {
 7755        if let Some((client, upstream_project_id)) = self.upstream_client() {
 7756            let request = GetHover { position };
 7757            if !self.is_capable_for_proto_request(buffer, &request, cx) {
 7758                return Task::ready(None);
 7759            }
 7760            let request_task = client.request_lsp(
 7761                upstream_project_id,
 7762                None,
 7763                LSP_REQUEST_TIMEOUT,
 7764                cx.background_executor().clone(),
 7765                request.to_proto(upstream_project_id, buffer.read(cx)),
 7766            );
 7767            let buffer = buffer.clone();
 7768            cx.spawn(async move |weak_lsp_store, cx| {
 7769                let lsp_store = weak_lsp_store.upgrade()?;
 7770                let hovers = join_all(
 7771                    request_task
 7772                        .await
 7773                        .log_err()
 7774                        .flatten()
 7775                        .map(|response| response.payload)
 7776                        .unwrap_or_default()
 7777                        .into_iter()
 7778                        .map(|response| {
 7779                            let response = GetHover { position }.response_from_proto(
 7780                                response.response,
 7781                                lsp_store.clone(),
 7782                                buffer.clone(),
 7783                                cx.clone(),
 7784                            );
 7785                            async move {
 7786                                response
 7787                                    .await
 7788                                    .log_err()
 7789                                    .flatten()
 7790                                    .and_then(remove_empty_hover_blocks)
 7791                            }
 7792                        }),
 7793                )
 7794                .await
 7795                .into_iter()
 7796                .flatten()
 7797                .collect();
 7798                Some(hovers)
 7799            })
 7800        } else {
 7801            let all_actions_task = self.request_multiple_lsp_locally(
 7802                buffer,
 7803                Some(position),
 7804                GetHover { position },
 7805                cx,
 7806            );
 7807            cx.background_spawn(async move {
 7808                Some(
 7809                    all_actions_task
 7810                        .await
 7811                        .into_iter()
 7812                        .filter_map(|(_, hover)| remove_empty_hover_blocks(hover?))
 7813                        .collect::<Vec<Hover>>(),
 7814                )
 7815            })
 7816        }
 7817    }
 7818
 7819    pub fn symbols(&self, query: &str, cx: &mut Context<Self>) -> Task<Result<Vec<Symbol>>> {
 7820        let language_registry = self.languages.clone();
 7821
 7822        if let Some((upstream_client, project_id)) = self.upstream_client().as_ref() {
 7823            let request = upstream_client.request(proto::GetProjectSymbols {
 7824                project_id: *project_id,
 7825                query: query.to_string(),
 7826            });
 7827            cx.foreground_executor().spawn(async move {
 7828                let response = request.await?;
 7829                let mut symbols = Vec::new();
 7830                let core_symbols = response
 7831                    .symbols
 7832                    .into_iter()
 7833                    .filter_map(|symbol| Self::deserialize_symbol(symbol).log_err())
 7834                    .collect::<Vec<_>>();
 7835                populate_labels_for_symbols(core_symbols, &language_registry, None, &mut symbols)
 7836                    .await;
 7837                Ok(symbols)
 7838            })
 7839        } else if let Some(local) = self.as_local() {
 7840            struct WorkspaceSymbolsResult {
 7841                server_id: LanguageServerId,
 7842                lsp_adapter: Arc<CachedLspAdapter>,
 7843                worktree: WeakEntity<Worktree>,
 7844                lsp_symbols: Vec<(String, SymbolKind, lsp::Location)>,
 7845            }
 7846
 7847            let mut requests = Vec::new();
 7848            let mut requested_servers = BTreeSet::new();
 7849            for (seed, state) in local.language_server_ids.iter() {
 7850                let Some(worktree_handle) = self
 7851                    .worktree_store
 7852                    .read(cx)
 7853                    .worktree_for_id(seed.worktree_id, cx)
 7854                else {
 7855                    continue;
 7856                };
 7857                let worktree = worktree_handle.read(cx);
 7858                if !worktree.is_visible() {
 7859                    continue;
 7860                }
 7861
 7862                if !requested_servers.insert(state.id) {
 7863                    continue;
 7864                }
 7865
 7866                let (lsp_adapter, server) = match local.language_servers.get(&state.id) {
 7867                    Some(LanguageServerState::Running {
 7868                        adapter, server, ..
 7869                    }) => (adapter.clone(), server),
 7870
 7871                    _ => continue,
 7872                };
 7873                let supports_workspace_symbol_request =
 7874                    match server.capabilities().workspace_symbol_provider {
 7875                        Some(OneOf::Left(supported)) => supported,
 7876                        Some(OneOf::Right(_)) => true,
 7877                        None => false,
 7878                    };
 7879                if !supports_workspace_symbol_request {
 7880                    continue;
 7881                }
 7882                let worktree_handle = worktree_handle.clone();
 7883                let server_id = server.server_id();
 7884                requests.push(
 7885                    server
 7886                        .request::<lsp::request::WorkspaceSymbolRequest>(
 7887                            lsp::WorkspaceSymbolParams {
 7888                                query: query.to_string(),
 7889                                ..Default::default()
 7890                            },
 7891                        )
 7892                        .map(move |response| {
 7893                            let lsp_symbols = response
 7894                                .into_response()
 7895                                .context("workspace symbols request")
 7896                                .log_err()
 7897                                .flatten()
 7898                                .map(|symbol_response| match symbol_response {
 7899                                    lsp::WorkspaceSymbolResponse::Flat(flat_responses) => {
 7900                                        flat_responses
 7901                                            .into_iter()
 7902                                            .map(|lsp_symbol| {
 7903                                                (
 7904                                                    lsp_symbol.name,
 7905                                                    lsp_symbol.kind,
 7906                                                    lsp_symbol.location,
 7907                                                )
 7908                                            })
 7909                                            .collect::<Vec<_>>()
 7910                                    }
 7911                                    lsp::WorkspaceSymbolResponse::Nested(nested_responses) => {
 7912                                        nested_responses
 7913                                            .into_iter()
 7914                                            .filter_map(|lsp_symbol| {
 7915                                                let location = match lsp_symbol.location {
 7916                                                    OneOf::Left(location) => location,
 7917                                                    OneOf::Right(_) => {
 7918                                                        log::error!(
 7919                                                            "Unexpected: client capabilities \
 7920                                                            forbid symbol resolutions in \
 7921                                                            workspace.symbol.resolveSupport"
 7922                                                        );
 7923                                                        return None;
 7924                                                    }
 7925                                                };
 7926                                                Some((lsp_symbol.name, lsp_symbol.kind, location))
 7927                                            })
 7928                                            .collect::<Vec<_>>()
 7929                                    }
 7930                                })
 7931                                .unwrap_or_default();
 7932
 7933                            WorkspaceSymbolsResult {
 7934                                server_id,
 7935                                lsp_adapter,
 7936                                worktree: worktree_handle.downgrade(),
 7937                                lsp_symbols,
 7938                            }
 7939                        }),
 7940                );
 7941            }
 7942
 7943            cx.spawn(async move |this, cx| {
 7944                let responses = futures::future::join_all(requests).await;
 7945                let this = match this.upgrade() {
 7946                    Some(this) => this,
 7947                    None => return Ok(Vec::new()),
 7948                };
 7949
 7950                let mut symbols = Vec::new();
 7951                for result in responses {
 7952                    let core_symbols = this.update(cx, |this, cx| {
 7953                        result
 7954                            .lsp_symbols
 7955                            .into_iter()
 7956                            .filter_map(|(symbol_name, symbol_kind, symbol_location)| {
 7957                                let abs_path = symbol_location.uri.to_file_path().ok()?;
 7958                                let source_worktree = result.worktree.upgrade()?;
 7959                                let source_worktree_id = source_worktree.read(cx).id();
 7960
 7961                                let path = if let Some((tree, rel_path)) =
 7962                                    this.worktree_store.read(cx).find_worktree(&abs_path, cx)
 7963                                {
 7964                                    let worktree_id = tree.read(cx).id();
 7965                                    SymbolLocation::InProject(ProjectPath {
 7966                                        worktree_id,
 7967                                        path: rel_path,
 7968                                    })
 7969                                } else {
 7970                                    SymbolLocation::OutsideProject {
 7971                                        signature: this.symbol_signature(&abs_path),
 7972                                        abs_path: abs_path.into(),
 7973                                    }
 7974                                };
 7975
 7976                                Some(CoreSymbol {
 7977                                    source_language_server_id: result.server_id,
 7978                                    language_server_name: result.lsp_adapter.name.clone(),
 7979                                    source_worktree_id,
 7980                                    path,
 7981                                    kind: symbol_kind,
 7982                                    name: symbol_name,
 7983                                    range: range_from_lsp(symbol_location.range),
 7984                                })
 7985                            })
 7986                            .collect::<Vec<_>>()
 7987                    });
 7988
 7989                    populate_labels_for_symbols(
 7990                        core_symbols,
 7991                        &language_registry,
 7992                        Some(result.lsp_adapter),
 7993                        &mut symbols,
 7994                    )
 7995                    .await;
 7996                }
 7997
 7998                Ok(symbols)
 7999            })
 8000        } else {
 8001            Task::ready(Err(anyhow!("No upstream client or local language server")))
 8002        }
 8003    }
 8004
 8005    pub fn diagnostic_summary(&self, include_ignored: bool, cx: &App) -> DiagnosticSummary {
 8006        let mut summary = DiagnosticSummary::default();
 8007        for (_, _, path_summary) in self.diagnostic_summaries(include_ignored, cx) {
 8008            summary.error_count += path_summary.error_count;
 8009            summary.warning_count += path_summary.warning_count;
 8010        }
 8011        summary
 8012    }
 8013
 8014    /// Returns the diagnostic summary for a specific project path.
 8015    pub fn diagnostic_summary_for_path(
 8016        &self,
 8017        project_path: &ProjectPath,
 8018        _: &App,
 8019    ) -> DiagnosticSummary {
 8020        if let Some(summaries) = self
 8021            .diagnostic_summaries
 8022            .get(&project_path.worktree_id)
 8023            .and_then(|map| map.get(&project_path.path))
 8024        {
 8025            let (error_count, warning_count) = summaries.iter().fold(
 8026                (0, 0),
 8027                |(error_count, warning_count), (_language_server_id, summary)| {
 8028                    (
 8029                        error_count + summary.error_count,
 8030                        warning_count + summary.warning_count,
 8031                    )
 8032                },
 8033            );
 8034
 8035            DiagnosticSummary {
 8036                error_count,
 8037                warning_count,
 8038            }
 8039        } else {
 8040            DiagnosticSummary::default()
 8041        }
 8042    }
 8043
 8044    pub fn diagnostic_summaries<'a>(
 8045        &'a self,
 8046        include_ignored: bool,
 8047        cx: &'a App,
 8048    ) -> impl Iterator<Item = (ProjectPath, LanguageServerId, DiagnosticSummary)> + 'a {
 8049        self.worktree_store
 8050            .read(cx)
 8051            .visible_worktrees(cx)
 8052            .filter_map(|worktree| {
 8053                let worktree = worktree.read(cx);
 8054                Some((worktree, self.diagnostic_summaries.get(&worktree.id())?))
 8055            })
 8056            .flat_map(move |(worktree, summaries)| {
 8057                let worktree_id = worktree.id();
 8058                summaries
 8059                    .iter()
 8060                    .filter(move |(path, _)| {
 8061                        include_ignored
 8062                            || worktree
 8063                                .entry_for_path(path.as_ref())
 8064                                .is_some_and(|entry| !entry.is_ignored)
 8065                    })
 8066                    .flat_map(move |(path, summaries)| {
 8067                        summaries.iter().map(move |(server_id, summary)| {
 8068                            (
 8069                                ProjectPath {
 8070                                    worktree_id,
 8071                                    path: path.clone(),
 8072                                },
 8073                                *server_id,
 8074                                *summary,
 8075                            )
 8076                        })
 8077                    })
 8078            })
 8079    }
 8080
 8081    pub fn on_buffer_edited(
 8082        &mut self,
 8083        buffer: Entity<Buffer>,
 8084        cx: &mut Context<Self>,
 8085    ) -> Option<()> {
 8086        let language_servers: Vec<_> = buffer.update(cx, |buffer, cx| {
 8087            Some(
 8088                self.as_local()?
 8089                    .language_servers_for_buffer(buffer, cx)
 8090                    .map(|i| i.1.clone())
 8091                    .collect(),
 8092            )
 8093        })?;
 8094
 8095        let buffer = buffer.read(cx);
 8096        let file = File::from_dyn(buffer.file())?;
 8097        let abs_path = file.as_local()?.abs_path(cx);
 8098        let uri = lsp::Uri::from_file_path(&abs_path)
 8099            .ok()
 8100            .with_context(|| format!("Failed to convert path to URI: {}", abs_path.display()))
 8101            .log_err()?;
 8102        let next_snapshot = buffer.text_snapshot();
 8103        for language_server in language_servers {
 8104            let language_server = language_server.clone();
 8105
 8106            let buffer_snapshots = self
 8107                .as_local_mut()?
 8108                .buffer_snapshots
 8109                .get_mut(&buffer.remote_id())
 8110                .and_then(|m| m.get_mut(&language_server.server_id()))?;
 8111            let previous_snapshot = buffer_snapshots.last()?;
 8112
 8113            let build_incremental_change = || {
 8114                buffer
 8115                    .edits_since::<Dimensions<PointUtf16, usize>>(
 8116                        previous_snapshot.snapshot.version(),
 8117                    )
 8118                    .map(|edit| {
 8119                        let edit_start = edit.new.start.0;
 8120                        let edit_end = edit_start + (edit.old.end.0 - edit.old.start.0);
 8121                        let new_text = next_snapshot
 8122                            .text_for_range(edit.new.start.1..edit.new.end.1)
 8123                            .collect();
 8124                        lsp::TextDocumentContentChangeEvent {
 8125                            range: Some(lsp::Range::new(
 8126                                point_to_lsp(edit_start),
 8127                                point_to_lsp(edit_end),
 8128                            )),
 8129                            range_length: None,
 8130                            text: new_text,
 8131                        }
 8132                    })
 8133                    .collect()
 8134            };
 8135
 8136            let document_sync_kind = language_server
 8137                .capabilities()
 8138                .text_document_sync
 8139                .as_ref()
 8140                .and_then(|sync| match sync {
 8141                    lsp::TextDocumentSyncCapability::Kind(kind) => Some(*kind),
 8142                    lsp::TextDocumentSyncCapability::Options(options) => options.change,
 8143                });
 8144
 8145            let content_changes: Vec<_> = match document_sync_kind {
 8146                Some(lsp::TextDocumentSyncKind::FULL) => {
 8147                    vec![lsp::TextDocumentContentChangeEvent {
 8148                        range: None,
 8149                        range_length: None,
 8150                        text: next_snapshot.text(),
 8151                    }]
 8152                }
 8153                Some(lsp::TextDocumentSyncKind::INCREMENTAL) => build_incremental_change(),
 8154                _ => {
 8155                    #[cfg(any(test, feature = "test-support"))]
 8156                    {
 8157                        build_incremental_change()
 8158                    }
 8159
 8160                    #[cfg(not(any(test, feature = "test-support")))]
 8161                    {
 8162                        continue;
 8163                    }
 8164                }
 8165            };
 8166
 8167            let next_version = previous_snapshot.version + 1;
 8168            buffer_snapshots.push(LspBufferSnapshot {
 8169                version: next_version,
 8170                snapshot: next_snapshot.clone(),
 8171            });
 8172
 8173            language_server
 8174                .notify::<lsp::notification::DidChangeTextDocument>(
 8175                    lsp::DidChangeTextDocumentParams {
 8176                        text_document: lsp::VersionedTextDocumentIdentifier::new(
 8177                            uri.clone(),
 8178                            next_version,
 8179                        ),
 8180                        content_changes,
 8181                    },
 8182                )
 8183                .ok();
 8184            self.pull_workspace_diagnostics(language_server.server_id());
 8185        }
 8186
 8187        None
 8188    }
 8189
 8190    pub fn on_buffer_saved(
 8191        &mut self,
 8192        buffer: Entity<Buffer>,
 8193        cx: &mut Context<Self>,
 8194    ) -> Option<()> {
 8195        let file = File::from_dyn(buffer.read(cx).file())?;
 8196        let worktree_id = file.worktree_id(cx);
 8197        let abs_path = file.as_local()?.abs_path(cx);
 8198        let text_document = lsp::TextDocumentIdentifier {
 8199            uri: file_path_to_lsp_url(&abs_path).log_err()?,
 8200        };
 8201        let local = self.as_local()?;
 8202
 8203        for server in local.language_servers_for_worktree(worktree_id) {
 8204            if let Some(include_text) = include_text(server.as_ref()) {
 8205                let text = if include_text {
 8206                    Some(buffer.read(cx).text())
 8207                } else {
 8208                    None
 8209                };
 8210                server
 8211                    .notify::<lsp::notification::DidSaveTextDocument>(
 8212                        lsp::DidSaveTextDocumentParams {
 8213                            text_document: text_document.clone(),
 8214                            text,
 8215                        },
 8216                    )
 8217                    .ok();
 8218            }
 8219        }
 8220
 8221        let language_servers = buffer.update(cx, |buffer, cx| {
 8222            local.language_server_ids_for_buffer(buffer, cx)
 8223        });
 8224        for language_server_id in language_servers {
 8225            self.simulate_disk_based_diagnostics_events_if_needed(language_server_id, cx);
 8226        }
 8227
 8228        None
 8229    }
 8230
 8231    async fn refresh_workspace_configurations(lsp_store: &WeakEntity<Self>, cx: &mut AsyncApp) {
 8232        maybe!(async move {
 8233            let mut refreshed_servers = HashSet::default();
 8234            let servers = lsp_store
 8235                .update(cx, |lsp_store, cx| {
 8236                    let local = lsp_store.as_local()?;
 8237
 8238                    let servers = local
 8239                        .language_server_ids
 8240                        .iter()
 8241                        .filter_map(|(seed, state)| {
 8242                            let worktree = lsp_store
 8243                                .worktree_store
 8244                                .read(cx)
 8245                                .worktree_for_id(seed.worktree_id, cx);
 8246                            let delegate: Arc<dyn LspAdapterDelegate> =
 8247                                worktree.map(|worktree| {
 8248                                    LocalLspAdapterDelegate::new(
 8249                                        local.languages.clone(),
 8250                                        &local.environment,
 8251                                        cx.weak_entity(),
 8252                                        &worktree,
 8253                                        local.http_client.clone(),
 8254                                        local.fs.clone(),
 8255                                        cx,
 8256                                    )
 8257                                })?;
 8258                            let server_id = state.id;
 8259
 8260                            let states = local.language_servers.get(&server_id)?;
 8261
 8262                            match states {
 8263                                LanguageServerState::Starting { .. } => None,
 8264                                LanguageServerState::Running {
 8265                                    adapter, server, ..
 8266                                } => {
 8267                                    let adapter = adapter.clone();
 8268                                    let server = server.clone();
 8269                                    refreshed_servers.insert(server.name());
 8270                                    let toolchain = seed.toolchain.clone();
 8271                                    Some(cx.spawn(async move |_, cx| {
 8272                                        let settings =
 8273                                            LocalLspStore::workspace_configuration_for_adapter(
 8274                                                adapter.adapter.clone(),
 8275                                                &delegate,
 8276                                                toolchain,
 8277                                                None,
 8278                                                cx,
 8279                                            )
 8280                                            .await
 8281                                            .ok()?;
 8282                                        server
 8283                                            .notify::<lsp::notification::DidChangeConfiguration>(
 8284                                                lsp::DidChangeConfigurationParams { settings },
 8285                                            )
 8286                                            .ok()?;
 8287                                        Some(())
 8288                                    }))
 8289                                }
 8290                            }
 8291                        })
 8292                        .collect::<Vec<_>>();
 8293
 8294                    Some(servers)
 8295                })
 8296                .ok()
 8297                .flatten()?;
 8298
 8299            log::debug!("Refreshing workspace configurations for servers {refreshed_servers:?}");
 8300            // TODO this asynchronous job runs concurrently with extension (de)registration and may take enough time for a certain extension
 8301            // to stop and unregister its language server wrapper.
 8302            // This is racy : an extension might have already removed all `local.language_servers` state, but here we `.clone()` and hold onto it anyway.
 8303            // This now causes errors in the logs, we should find a way to remove such servers from the processing everywhere.
 8304            let _: Vec<Option<()>> = join_all(servers).await;
 8305
 8306            Some(())
 8307        })
 8308        .await;
 8309    }
 8310
 8311    fn maintain_workspace_config(
 8312        external_refresh_requests: watch::Receiver<()>,
 8313        cx: &mut Context<Self>,
 8314    ) -> Task<Result<()>> {
 8315        let (mut settings_changed_tx, mut settings_changed_rx) = watch::channel();
 8316        let _ = postage::stream::Stream::try_recv(&mut settings_changed_rx);
 8317
 8318        let settings_observation = cx.observe_global::<SettingsStore>(move |_, _| {
 8319            *settings_changed_tx.borrow_mut() = ();
 8320        });
 8321
 8322        let mut joint_future =
 8323            futures::stream::select(settings_changed_rx, external_refresh_requests);
 8324        // Multiple things can happen when a workspace environment (selected toolchain + settings) change:
 8325        // - 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).
 8326        // - 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.
 8327        // - In the same vein, we might also decide to start a new language server if the workspace configuration *diverges* from the other.
 8328        // - 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,
 8329        // but it is still different to what we had before, we're gonna send out a workspace configuration update.
 8330        cx.spawn(async move |this, cx| {
 8331            while let Some(()) = joint_future.next().await {
 8332                this.update(cx, |this, cx| {
 8333                    this.refresh_server_tree(cx);
 8334                })
 8335                .ok();
 8336
 8337                Self::refresh_workspace_configurations(&this, cx).await;
 8338            }
 8339
 8340            drop(settings_observation);
 8341            anyhow::Ok(())
 8342        })
 8343    }
 8344
 8345    pub fn running_language_servers_for_local_buffer<'a>(
 8346        &'a self,
 8347        buffer: &Buffer,
 8348        cx: &mut App,
 8349    ) -> impl Iterator<Item = (&'a Arc<CachedLspAdapter>, &'a Arc<LanguageServer>)> {
 8350        let local = self.as_local();
 8351        let language_server_ids = local
 8352            .map(|local| local.language_server_ids_for_buffer(buffer, cx))
 8353            .unwrap_or_default();
 8354
 8355        language_server_ids
 8356            .into_iter()
 8357            .filter_map(
 8358                move |server_id| match local?.language_servers.get(&server_id)? {
 8359                    LanguageServerState::Running {
 8360                        adapter, server, ..
 8361                    } => Some((adapter, server)),
 8362                    _ => None,
 8363                },
 8364            )
 8365    }
 8366
 8367    pub fn language_servers_for_local_buffer(
 8368        &self,
 8369        buffer: &Buffer,
 8370        cx: &mut App,
 8371    ) -> Vec<LanguageServerId> {
 8372        let local = self.as_local();
 8373        local
 8374            .map(|local| local.language_server_ids_for_buffer(buffer, cx))
 8375            .unwrap_or_default()
 8376    }
 8377
 8378    pub fn language_server_for_local_buffer<'a>(
 8379        &'a self,
 8380        buffer: &'a Buffer,
 8381        server_id: LanguageServerId,
 8382        cx: &'a mut App,
 8383    ) -> Option<(&'a Arc<CachedLspAdapter>, &'a Arc<LanguageServer>)> {
 8384        self.as_local()?
 8385            .language_servers_for_buffer(buffer, cx)
 8386            .find(|(_, s)| s.server_id() == server_id)
 8387    }
 8388
 8389    fn remove_worktree(&mut self, id_to_remove: WorktreeId, cx: &mut Context<Self>) {
 8390        self.diagnostic_summaries.remove(&id_to_remove);
 8391        if let Some(local) = self.as_local_mut() {
 8392            let to_remove = local.remove_worktree(id_to_remove, cx);
 8393            for server in to_remove {
 8394                self.language_server_statuses.remove(&server);
 8395            }
 8396        }
 8397    }
 8398
 8399    pub fn shared(
 8400        &mut self,
 8401        project_id: u64,
 8402        downstream_client: AnyProtoClient,
 8403        _: &mut Context<Self>,
 8404    ) {
 8405        self.downstream_client = Some((downstream_client.clone(), project_id));
 8406
 8407        for (server_id, status) in &self.language_server_statuses {
 8408            if let Some(server) = self.language_server_for_id(*server_id) {
 8409                downstream_client
 8410                    .send(proto::StartLanguageServer {
 8411                        project_id,
 8412                        server: Some(proto::LanguageServer {
 8413                            id: server_id.to_proto(),
 8414                            name: status.name.to_string(),
 8415                            worktree_id: status.worktree.map(|id| id.to_proto()),
 8416                        }),
 8417                        capabilities: serde_json::to_string(&server.capabilities())
 8418                            .expect("serializing server LSP capabilities"),
 8419                    })
 8420                    .log_err();
 8421            }
 8422        }
 8423    }
 8424
 8425    pub fn disconnected_from_host(&mut self) {
 8426        self.downstream_client.take();
 8427    }
 8428
 8429    pub fn disconnected_from_ssh_remote(&mut self) {
 8430        if let LspStoreMode::Remote(RemoteLspStore {
 8431            upstream_client, ..
 8432        }) = &mut self.mode
 8433        {
 8434            upstream_client.take();
 8435        }
 8436    }
 8437
 8438    pub(crate) fn set_language_server_statuses_from_proto(
 8439        &mut self,
 8440        project: WeakEntity<Project>,
 8441        language_servers: Vec<proto::LanguageServer>,
 8442        server_capabilities: Vec<String>,
 8443        cx: &mut Context<Self>,
 8444    ) {
 8445        let lsp_logs = cx
 8446            .try_global::<GlobalLogStore>()
 8447            .map(|lsp_store| lsp_store.0.clone());
 8448
 8449        self.language_server_statuses = language_servers
 8450            .into_iter()
 8451            .zip(server_capabilities)
 8452            .map(|(server, server_capabilities)| {
 8453                let server_id = LanguageServerId(server.id as usize);
 8454                if let Ok(server_capabilities) = serde_json::from_str(&server_capabilities) {
 8455                    self.lsp_server_capabilities
 8456                        .insert(server_id, server_capabilities);
 8457                }
 8458
 8459                let name = LanguageServerName::from_proto(server.name);
 8460                let worktree = server.worktree_id.map(WorktreeId::from_proto);
 8461
 8462                if let Some(lsp_logs) = &lsp_logs {
 8463                    lsp_logs.update(cx, |lsp_logs, cx| {
 8464                        lsp_logs.add_language_server(
 8465                            // Only remote clients get their language servers set from proto
 8466                            LanguageServerKind::Remote {
 8467                                project: project.clone(),
 8468                            },
 8469                            server_id,
 8470                            Some(name.clone()),
 8471                            worktree,
 8472                            None,
 8473                            cx,
 8474                        );
 8475                    });
 8476                }
 8477
 8478                (
 8479                    server_id,
 8480                    LanguageServerStatus {
 8481                        name,
 8482                        server_version: None,
 8483                        pending_work: Default::default(),
 8484                        has_pending_diagnostic_updates: false,
 8485                        progress_tokens: Default::default(),
 8486                        worktree,
 8487                        binary: None,
 8488                        configuration: None,
 8489                        workspace_folders: BTreeSet::new(),
 8490                    },
 8491                )
 8492            })
 8493            .collect();
 8494    }
 8495
 8496    #[cfg(feature = "test-support")]
 8497    pub fn update_diagnostic_entries(
 8498        &mut self,
 8499        server_id: LanguageServerId,
 8500        abs_path: PathBuf,
 8501        result_id: Option<SharedString>,
 8502        version: Option<i32>,
 8503        diagnostics: Vec<DiagnosticEntry<Unclipped<PointUtf16>>>,
 8504        cx: &mut Context<Self>,
 8505    ) -> anyhow::Result<()> {
 8506        self.merge_diagnostic_entries(
 8507            vec![DocumentDiagnosticsUpdate {
 8508                diagnostics: DocumentDiagnostics {
 8509                    diagnostics,
 8510                    document_abs_path: abs_path,
 8511                    version,
 8512                },
 8513                result_id,
 8514                server_id,
 8515                disk_based_sources: Cow::Borrowed(&[]),
 8516                registration_id: None,
 8517            }],
 8518            |_, _, _| false,
 8519            cx,
 8520        )?;
 8521        Ok(())
 8522    }
 8523
 8524    pub fn merge_diagnostic_entries<'a>(
 8525        &mut self,
 8526        diagnostic_updates: Vec<DocumentDiagnosticsUpdate<'a, DocumentDiagnostics>>,
 8527        merge: impl Fn(&lsp::Uri, &Diagnostic, &App) -> bool + Clone,
 8528        cx: &mut Context<Self>,
 8529    ) -> anyhow::Result<()> {
 8530        let mut diagnostics_summary = None::<proto::UpdateDiagnosticSummary>;
 8531        let mut updated_diagnostics_paths = HashMap::default();
 8532        for mut update in diagnostic_updates {
 8533            let abs_path = &update.diagnostics.document_abs_path;
 8534            let server_id = update.server_id;
 8535            let Some((worktree, relative_path)) =
 8536                self.worktree_store.read(cx).find_worktree(abs_path, cx)
 8537            else {
 8538                log::warn!("skipping diagnostics update, no worktree found for path {abs_path:?}");
 8539                return Ok(());
 8540            };
 8541
 8542            let worktree_id = worktree.read(cx).id();
 8543            let project_path = ProjectPath {
 8544                worktree_id,
 8545                path: relative_path,
 8546            };
 8547
 8548            let document_uri = lsp::Uri::from_file_path(abs_path)
 8549                .map_err(|()| anyhow!("Failed to convert buffer path {abs_path:?} to lsp Uri"))?;
 8550            if let Some(buffer_handle) = self.buffer_store.read(cx).get_by_path(&project_path) {
 8551                let snapshot = buffer_handle.read(cx).snapshot();
 8552                let buffer = buffer_handle.read(cx);
 8553                let reused_diagnostics = buffer
 8554                    .buffer_diagnostics(Some(server_id))
 8555                    .iter()
 8556                    .filter(|v| merge(&document_uri, &v.diagnostic, cx))
 8557                    .map(|v| {
 8558                        let start = Unclipped(v.range.start.to_point_utf16(&snapshot));
 8559                        let end = Unclipped(v.range.end.to_point_utf16(&snapshot));
 8560                        DiagnosticEntry {
 8561                            range: start..end,
 8562                            diagnostic: v.diagnostic.clone(),
 8563                        }
 8564                    })
 8565                    .collect::<Vec<_>>();
 8566
 8567                self.as_local_mut()
 8568                    .context("cannot merge diagnostics on a remote LspStore")?
 8569                    .update_buffer_diagnostics(
 8570                        &buffer_handle,
 8571                        server_id,
 8572                        Some(update.registration_id),
 8573                        update.result_id,
 8574                        update.diagnostics.version,
 8575                        update.diagnostics.diagnostics.clone(),
 8576                        reused_diagnostics.clone(),
 8577                        cx,
 8578                    )?;
 8579
 8580                update.diagnostics.diagnostics.extend(reused_diagnostics);
 8581            } else if let Some(local) = self.as_local() {
 8582                let reused_diagnostics = local
 8583                    .diagnostics
 8584                    .get(&worktree_id)
 8585                    .and_then(|diagnostics_for_tree| diagnostics_for_tree.get(&project_path.path))
 8586                    .and_then(|diagnostics_by_server_id| {
 8587                        diagnostics_by_server_id
 8588                            .binary_search_by_key(&server_id, |e| e.0)
 8589                            .ok()
 8590                            .map(|ix| &diagnostics_by_server_id[ix].1)
 8591                    })
 8592                    .into_iter()
 8593                    .flatten()
 8594                    .filter(|v| merge(&document_uri, &v.diagnostic, cx));
 8595
 8596                update
 8597                    .diagnostics
 8598                    .diagnostics
 8599                    .extend(reused_diagnostics.cloned());
 8600            }
 8601
 8602            let updated = worktree.update(cx, |worktree, cx| {
 8603                self.update_worktree_diagnostics(
 8604                    worktree.id(),
 8605                    server_id,
 8606                    project_path.path.clone(),
 8607                    update.diagnostics.diagnostics,
 8608                    cx,
 8609                )
 8610            })?;
 8611            match updated {
 8612                ControlFlow::Continue(new_summary) => {
 8613                    if let Some((project_id, new_summary)) = new_summary {
 8614                        match &mut diagnostics_summary {
 8615                            Some(diagnostics_summary) => {
 8616                                diagnostics_summary
 8617                                    .more_summaries
 8618                                    .push(proto::DiagnosticSummary {
 8619                                        path: project_path.path.as_ref().to_proto(),
 8620                                        language_server_id: server_id.0 as u64,
 8621                                        error_count: new_summary.error_count,
 8622                                        warning_count: new_summary.warning_count,
 8623                                    })
 8624                            }
 8625                            None => {
 8626                                diagnostics_summary = Some(proto::UpdateDiagnosticSummary {
 8627                                    project_id,
 8628                                    worktree_id: worktree_id.to_proto(),
 8629                                    summary: Some(proto::DiagnosticSummary {
 8630                                        path: project_path.path.as_ref().to_proto(),
 8631                                        language_server_id: server_id.0 as u64,
 8632                                        error_count: new_summary.error_count,
 8633                                        warning_count: new_summary.warning_count,
 8634                                    }),
 8635                                    more_summaries: Vec::new(),
 8636                                })
 8637                            }
 8638                        }
 8639                    }
 8640                    updated_diagnostics_paths
 8641                        .entry(server_id)
 8642                        .or_insert_with(Vec::new)
 8643                        .push(project_path);
 8644                }
 8645                ControlFlow::Break(()) => {}
 8646            }
 8647        }
 8648
 8649        if let Some((diagnostics_summary, (downstream_client, _))) =
 8650            diagnostics_summary.zip(self.downstream_client.as_ref())
 8651        {
 8652            downstream_client.send(diagnostics_summary).log_err();
 8653        }
 8654        for (server_id, paths) in updated_diagnostics_paths {
 8655            cx.emit(LspStoreEvent::DiagnosticsUpdated { server_id, paths });
 8656        }
 8657        Ok(())
 8658    }
 8659
 8660    fn update_worktree_diagnostics(
 8661        &mut self,
 8662        worktree_id: WorktreeId,
 8663        server_id: LanguageServerId,
 8664        path_in_worktree: Arc<RelPath>,
 8665        diagnostics: Vec<DiagnosticEntry<Unclipped<PointUtf16>>>,
 8666        _: &mut Context<Worktree>,
 8667    ) -> Result<ControlFlow<(), Option<(u64, proto::DiagnosticSummary)>>> {
 8668        let local = match &mut self.mode {
 8669            LspStoreMode::Local(local_lsp_store) => local_lsp_store,
 8670            _ => anyhow::bail!("update_worktree_diagnostics called on remote"),
 8671        };
 8672
 8673        let summaries_for_tree = self.diagnostic_summaries.entry(worktree_id).or_default();
 8674        let diagnostics_for_tree = local.diagnostics.entry(worktree_id).or_default();
 8675        let summaries_by_server_id = summaries_for_tree
 8676            .entry(path_in_worktree.clone())
 8677            .or_default();
 8678
 8679        let old_summary = summaries_by_server_id
 8680            .remove(&server_id)
 8681            .unwrap_or_default();
 8682
 8683        let new_summary = DiagnosticSummary::new(&diagnostics);
 8684        if diagnostics.is_empty() {
 8685            if let Some(diagnostics_by_server_id) = diagnostics_for_tree.get_mut(&path_in_worktree)
 8686            {
 8687                if let Ok(ix) = diagnostics_by_server_id.binary_search_by_key(&server_id, |e| e.0) {
 8688                    diagnostics_by_server_id.remove(ix);
 8689                }
 8690                if diagnostics_by_server_id.is_empty() {
 8691                    diagnostics_for_tree.remove(&path_in_worktree);
 8692                }
 8693            }
 8694        } else {
 8695            summaries_by_server_id.insert(server_id, new_summary);
 8696            let diagnostics_by_server_id = diagnostics_for_tree
 8697                .entry(path_in_worktree.clone())
 8698                .or_default();
 8699            match diagnostics_by_server_id.binary_search_by_key(&server_id, |e| e.0) {
 8700                Ok(ix) => {
 8701                    diagnostics_by_server_id[ix] = (server_id, diagnostics);
 8702                }
 8703                Err(ix) => {
 8704                    diagnostics_by_server_id.insert(ix, (server_id, diagnostics));
 8705                }
 8706            }
 8707        }
 8708
 8709        if !old_summary.is_empty() || !new_summary.is_empty() {
 8710            if let Some((_, project_id)) = &self.downstream_client {
 8711                Ok(ControlFlow::Continue(Some((
 8712                    *project_id,
 8713                    proto::DiagnosticSummary {
 8714                        path: path_in_worktree.to_proto(),
 8715                        language_server_id: server_id.0 as u64,
 8716                        error_count: new_summary.error_count as u32,
 8717                        warning_count: new_summary.warning_count as u32,
 8718                    },
 8719                ))))
 8720            } else {
 8721                Ok(ControlFlow::Continue(None))
 8722            }
 8723        } else {
 8724            Ok(ControlFlow::Break(()))
 8725        }
 8726    }
 8727
 8728    pub fn open_buffer_for_symbol(
 8729        &mut self,
 8730        symbol: &Symbol,
 8731        cx: &mut Context<Self>,
 8732    ) -> Task<Result<Entity<Buffer>>> {
 8733        if let Some((client, project_id)) = self.upstream_client() {
 8734            let request = client.request(proto::OpenBufferForSymbol {
 8735                project_id,
 8736                symbol: Some(Self::serialize_symbol(symbol)),
 8737            });
 8738            cx.spawn(async move |this, cx| {
 8739                let response = request.await?;
 8740                let buffer_id = BufferId::new(response.buffer_id)?;
 8741                this.update(cx, |this, cx| this.wait_for_remote_buffer(buffer_id, cx))?
 8742                    .await
 8743            })
 8744        } else if let Some(local) = self.as_local() {
 8745            let is_valid = local.language_server_ids.iter().any(|(seed, state)| {
 8746                seed.worktree_id == symbol.source_worktree_id
 8747                    && state.id == symbol.source_language_server_id
 8748                    && symbol.language_server_name == seed.name
 8749            });
 8750            if !is_valid {
 8751                return Task::ready(Err(anyhow!(
 8752                    "language server for worktree and language not found"
 8753                )));
 8754            };
 8755
 8756            let symbol_abs_path = match &symbol.path {
 8757                SymbolLocation::InProject(project_path) => self
 8758                    .worktree_store
 8759                    .read(cx)
 8760                    .absolutize(&project_path, cx)
 8761                    .context("no such worktree"),
 8762                SymbolLocation::OutsideProject {
 8763                    abs_path,
 8764                    signature: _,
 8765                } => Ok(abs_path.to_path_buf()),
 8766            };
 8767            let symbol_abs_path = match symbol_abs_path {
 8768                Ok(abs_path) => abs_path,
 8769                Err(err) => return Task::ready(Err(err)),
 8770            };
 8771            let symbol_uri = if let Ok(uri) = lsp::Uri::from_file_path(symbol_abs_path) {
 8772                uri
 8773            } else {
 8774                return Task::ready(Err(anyhow!("invalid symbol path")));
 8775            };
 8776
 8777            self.open_local_buffer_via_lsp(symbol_uri, symbol.source_language_server_id, cx)
 8778        } else {
 8779            Task::ready(Err(anyhow!("no upstream client or local store")))
 8780        }
 8781    }
 8782
 8783    pub(crate) fn open_local_buffer_via_lsp(
 8784        &mut self,
 8785        abs_path: lsp::Uri,
 8786        language_server_id: LanguageServerId,
 8787        cx: &mut Context<Self>,
 8788    ) -> Task<Result<Entity<Buffer>>> {
 8789        let path_style = self.worktree_store.read(cx).path_style();
 8790        cx.spawn(async move |lsp_store, cx| {
 8791            // Escape percent-encoded string.
 8792            let current_scheme = abs_path.scheme().to_owned();
 8793            // Uri is immutable, so we can't modify the scheme
 8794
 8795            let abs_path = abs_path
 8796                .to_file_path_ext(path_style)
 8797                .map_err(|()| anyhow!("can't convert URI to path"))?;
 8798            let p = abs_path.clone();
 8799            let yarn_worktree = lsp_store
 8800                .update(cx, move |lsp_store, cx| match lsp_store.as_local() {
 8801                    Some(local_lsp_store) => local_lsp_store.yarn.update(cx, |_, cx| {
 8802                        cx.spawn(async move |this, cx| {
 8803                            let t = this
 8804                                .update(cx, |this, cx| this.process_path(&p, &current_scheme, cx))
 8805                                .ok()?;
 8806                            t.await
 8807                        })
 8808                    }),
 8809                    None => Task::ready(None),
 8810                })?
 8811                .await;
 8812            let (worktree_root_target, known_relative_path) =
 8813                if let Some((zip_root, relative_path)) = yarn_worktree {
 8814                    (zip_root, Some(relative_path))
 8815                } else {
 8816                    (Arc::<Path>::from(abs_path.as_path()), None)
 8817                };
 8818            let worktree = lsp_store.update(cx, |lsp_store, cx| {
 8819                lsp_store.worktree_store.update(cx, |worktree_store, cx| {
 8820                    worktree_store.find_worktree(&worktree_root_target, cx)
 8821                })
 8822            })?;
 8823            let (worktree, relative_path, source_ws) = if let Some(result) = worktree {
 8824                let relative_path = known_relative_path.unwrap_or_else(|| result.1.clone());
 8825                (result.0, relative_path, None)
 8826            } else {
 8827                let worktree = lsp_store
 8828                    .update(cx, |lsp_store, cx| {
 8829                        lsp_store.worktree_store.update(cx, |worktree_store, cx| {
 8830                            worktree_store.create_worktree(&worktree_root_target, false, cx)
 8831                        })
 8832                    })?
 8833                    .await?;
 8834                let worktree_root = worktree.read_with(cx, |worktree, _| worktree.abs_path());
 8835                let source_ws = if worktree.read_with(cx, |worktree, _| worktree.is_local()) {
 8836                    lsp_store
 8837                        .update(cx, |lsp_store, cx| {
 8838                            if let Some(local) = lsp_store.as_local_mut() {
 8839                                local.register_language_server_for_invisible_worktree(
 8840                                    &worktree,
 8841                                    language_server_id,
 8842                                    cx,
 8843                                )
 8844                            }
 8845                            match lsp_store.language_server_statuses.get(&language_server_id) {
 8846                                Some(status) => status.worktree,
 8847                                None => None,
 8848                            }
 8849                        })
 8850                        .ok()
 8851                        .flatten()
 8852                        .zip(Some(worktree_root.clone()))
 8853                } else {
 8854                    None
 8855                };
 8856                let relative_path = if let Some(known_path) = known_relative_path {
 8857                    known_path
 8858                } else {
 8859                    RelPath::new(abs_path.strip_prefix(worktree_root)?, PathStyle::local())?
 8860                        .into_arc()
 8861                };
 8862                (worktree, relative_path, source_ws)
 8863            };
 8864            let project_path = ProjectPath {
 8865                worktree_id: worktree.read_with(cx, |worktree, _| worktree.id()),
 8866                path: relative_path,
 8867            };
 8868            let buffer = lsp_store
 8869                .update(cx, |lsp_store, cx| {
 8870                    lsp_store.buffer_store().update(cx, |buffer_store, cx| {
 8871                        buffer_store.open_buffer(project_path, cx)
 8872                    })
 8873                })?
 8874                .await?;
 8875            // we want to adhere to the read-only settings of the worktree we came from in case we opened an invisible one
 8876            if let Some((source_ws, worktree_root)) = source_ws {
 8877                buffer.update(cx, |buffer, cx| {
 8878                    let settings = WorktreeSettings::get(
 8879                        Some(
 8880                            (&ProjectPath {
 8881                                worktree_id: source_ws,
 8882                                path: Arc::from(RelPath::empty()),
 8883                            })
 8884                                .into(),
 8885                        ),
 8886                        cx,
 8887                    );
 8888                    let is_read_only = settings.is_std_path_read_only(&worktree_root);
 8889                    if is_read_only {
 8890                        buffer.set_capability(Capability::ReadOnly, cx);
 8891                    }
 8892                });
 8893            }
 8894            Ok(buffer)
 8895        })
 8896    }
 8897
 8898    fn request_multiple_lsp_locally<P, R>(
 8899        &mut self,
 8900        buffer: &Entity<Buffer>,
 8901        position: Option<P>,
 8902        request: R,
 8903        cx: &mut Context<Self>,
 8904    ) -> Task<Vec<(LanguageServerId, R::Response)>>
 8905    where
 8906        P: ToOffset,
 8907        R: LspCommand + Clone,
 8908        <R::LspRequest as lsp::request::Request>::Result: Send,
 8909        <R::LspRequest as lsp::request::Request>::Params: Send,
 8910    {
 8911        let Some(local) = self.as_local() else {
 8912            return Task::ready(Vec::new());
 8913        };
 8914
 8915        let snapshot = buffer.read(cx).snapshot();
 8916        let scope = position.and_then(|position| snapshot.language_scope_at(position));
 8917
 8918        let server_ids = buffer.update(cx, |buffer, cx| {
 8919            local
 8920                .language_servers_for_buffer(buffer, cx)
 8921                .filter(|(adapter, _)| {
 8922                    scope
 8923                        .as_ref()
 8924                        .map(|scope| scope.language_allowed(&adapter.name))
 8925                        .unwrap_or(true)
 8926                })
 8927                .map(|(_, server)| server.server_id())
 8928                .filter(|server_id| {
 8929                    self.as_local().is_none_or(|local| {
 8930                        local
 8931                            .buffers_opened_in_servers
 8932                            .get(&snapshot.remote_id())
 8933                            .is_some_and(|servers| servers.contains(server_id))
 8934                    })
 8935                })
 8936                .collect::<Vec<_>>()
 8937        });
 8938
 8939        let mut response_results = server_ids
 8940            .into_iter()
 8941            .map(|server_id| {
 8942                let task = self.request_lsp(
 8943                    buffer.clone(),
 8944                    LanguageServerToQuery::Other(server_id),
 8945                    request.clone(),
 8946                    cx,
 8947                );
 8948                async move { (server_id, task.await) }
 8949            })
 8950            .collect::<FuturesUnordered<_>>();
 8951
 8952        cx.background_spawn(async move {
 8953            let mut responses = Vec::with_capacity(response_results.len());
 8954            while let Some((server_id, response_result)) = response_results.next().await {
 8955                match response_result {
 8956                    Ok(response) => responses.push((server_id, response)),
 8957                    // rust-analyzer likes to error with this when its still loading up
 8958                    Err(e) if format!("{e:#}").ends_with("content modified") => (),
 8959                    Err(e) => log::error!("Error handling response for request {request:?}: {e:#}"),
 8960                }
 8961            }
 8962            responses
 8963        })
 8964    }
 8965
 8966    async fn handle_lsp_get_completions(
 8967        this: Entity<Self>,
 8968        envelope: TypedEnvelope<proto::GetCompletions>,
 8969        mut cx: AsyncApp,
 8970    ) -> Result<proto::GetCompletionsResponse> {
 8971        let sender_id = envelope.original_sender_id().unwrap_or_default();
 8972
 8973        let buffer_id = GetCompletions::buffer_id_from_proto(&envelope.payload)?;
 8974        let buffer_handle = this.update(&mut cx, |this, cx| {
 8975            this.buffer_store.read(cx).get_existing(buffer_id)
 8976        })?;
 8977        let request = GetCompletions::from_proto(
 8978            envelope.payload,
 8979            this.clone(),
 8980            buffer_handle.clone(),
 8981            cx.clone(),
 8982        )
 8983        .await?;
 8984
 8985        let server_to_query = match request.server_id {
 8986            Some(server_id) => LanguageServerToQuery::Other(server_id),
 8987            None => LanguageServerToQuery::FirstCapable,
 8988        };
 8989
 8990        let response = this
 8991            .update(&mut cx, |this, cx| {
 8992                this.request_lsp(buffer_handle.clone(), server_to_query, request, cx)
 8993            })
 8994            .await?;
 8995        this.update(&mut cx, |this, cx| {
 8996            Ok(GetCompletions::response_to_proto(
 8997                response,
 8998                this,
 8999                sender_id,
 9000                &buffer_handle.read(cx).version(),
 9001                cx,
 9002            ))
 9003        })
 9004    }
 9005
 9006    async fn handle_lsp_command<T: LspCommand>(
 9007        this: Entity<Self>,
 9008        envelope: TypedEnvelope<T::ProtoRequest>,
 9009        mut cx: AsyncApp,
 9010    ) -> Result<<T::ProtoRequest as proto::RequestMessage>::Response>
 9011    where
 9012        <T::LspRequest as lsp::request::Request>::Params: Send,
 9013        <T::LspRequest as lsp::request::Request>::Result: Send,
 9014    {
 9015        let sender_id = envelope.original_sender_id().unwrap_or_default();
 9016        let buffer_id = T::buffer_id_from_proto(&envelope.payload)?;
 9017        let buffer_handle = this.update(&mut cx, |this, cx| {
 9018            this.buffer_store.read(cx).get_existing(buffer_id)
 9019        })?;
 9020        let request = T::from_proto(
 9021            envelope.payload,
 9022            this.clone(),
 9023            buffer_handle.clone(),
 9024            cx.clone(),
 9025        )
 9026        .await?;
 9027        let response = this
 9028            .update(&mut cx, |this, cx| {
 9029                this.request_lsp(
 9030                    buffer_handle.clone(),
 9031                    LanguageServerToQuery::FirstCapable,
 9032                    request,
 9033                    cx,
 9034                )
 9035            })
 9036            .await?;
 9037        this.update(&mut cx, |this, cx| {
 9038            Ok(T::response_to_proto(
 9039                response,
 9040                this,
 9041                sender_id,
 9042                &buffer_handle.read(cx).version(),
 9043                cx,
 9044            ))
 9045        })
 9046    }
 9047
 9048    async fn handle_lsp_query(
 9049        lsp_store: Entity<Self>,
 9050        envelope: TypedEnvelope<proto::LspQuery>,
 9051        mut cx: AsyncApp,
 9052    ) -> Result<proto::Ack> {
 9053        use proto::lsp_query::Request;
 9054        let sender_id = envelope.original_sender_id().unwrap_or_default();
 9055        let lsp_query = envelope.payload;
 9056        let lsp_request_id = LspRequestId(lsp_query.lsp_request_id);
 9057        let server_id = lsp_query.server_id.map(LanguageServerId::from_proto);
 9058        match lsp_query.request.context("invalid LSP query request")? {
 9059            Request::GetReferences(get_references) => {
 9060                let position = get_references.position.clone().and_then(deserialize_anchor);
 9061                Self::query_lsp_locally::<GetReferences>(
 9062                    lsp_store,
 9063                    server_id,
 9064                    sender_id,
 9065                    lsp_request_id,
 9066                    get_references,
 9067                    position,
 9068                    &mut cx,
 9069                )
 9070                .await?;
 9071            }
 9072            Request::GetDocumentColor(get_document_color) => {
 9073                Self::query_lsp_locally::<GetDocumentColor>(
 9074                    lsp_store,
 9075                    server_id,
 9076                    sender_id,
 9077                    lsp_request_id,
 9078                    get_document_color,
 9079                    None,
 9080                    &mut cx,
 9081                )
 9082                .await?;
 9083            }
 9084            Request::GetHover(get_hover) => {
 9085                let position = get_hover.position.clone().and_then(deserialize_anchor);
 9086                Self::query_lsp_locally::<GetHover>(
 9087                    lsp_store,
 9088                    server_id,
 9089                    sender_id,
 9090                    lsp_request_id,
 9091                    get_hover,
 9092                    position,
 9093                    &mut cx,
 9094                )
 9095                .await?;
 9096            }
 9097            Request::GetCodeActions(get_code_actions) => {
 9098                Self::query_lsp_locally::<GetCodeActions>(
 9099                    lsp_store,
 9100                    server_id,
 9101                    sender_id,
 9102                    lsp_request_id,
 9103                    get_code_actions,
 9104                    None,
 9105                    &mut cx,
 9106                )
 9107                .await?;
 9108            }
 9109            Request::GetSignatureHelp(get_signature_help) => {
 9110                let position = get_signature_help
 9111                    .position
 9112                    .clone()
 9113                    .and_then(deserialize_anchor);
 9114                Self::query_lsp_locally::<GetSignatureHelp>(
 9115                    lsp_store,
 9116                    server_id,
 9117                    sender_id,
 9118                    lsp_request_id,
 9119                    get_signature_help,
 9120                    position,
 9121                    &mut cx,
 9122                )
 9123                .await?;
 9124            }
 9125            Request::GetCodeLens(get_code_lens) => {
 9126                Self::query_lsp_locally::<GetCodeLens>(
 9127                    lsp_store,
 9128                    server_id,
 9129                    sender_id,
 9130                    lsp_request_id,
 9131                    get_code_lens,
 9132                    None,
 9133                    &mut cx,
 9134                )
 9135                .await?;
 9136            }
 9137            Request::GetDefinition(get_definition) => {
 9138                let position = get_definition.position.clone().and_then(deserialize_anchor);
 9139                Self::query_lsp_locally::<GetDefinitions>(
 9140                    lsp_store,
 9141                    server_id,
 9142                    sender_id,
 9143                    lsp_request_id,
 9144                    get_definition,
 9145                    position,
 9146                    &mut cx,
 9147                )
 9148                .await?;
 9149            }
 9150            Request::GetDeclaration(get_declaration) => {
 9151                let position = get_declaration
 9152                    .position
 9153                    .clone()
 9154                    .and_then(deserialize_anchor);
 9155                Self::query_lsp_locally::<GetDeclarations>(
 9156                    lsp_store,
 9157                    server_id,
 9158                    sender_id,
 9159                    lsp_request_id,
 9160                    get_declaration,
 9161                    position,
 9162                    &mut cx,
 9163                )
 9164                .await?;
 9165            }
 9166            Request::GetTypeDefinition(get_type_definition) => {
 9167                let position = get_type_definition
 9168                    .position
 9169                    .clone()
 9170                    .and_then(deserialize_anchor);
 9171                Self::query_lsp_locally::<GetTypeDefinitions>(
 9172                    lsp_store,
 9173                    server_id,
 9174                    sender_id,
 9175                    lsp_request_id,
 9176                    get_type_definition,
 9177                    position,
 9178                    &mut cx,
 9179                )
 9180                .await?;
 9181            }
 9182            Request::GetImplementation(get_implementation) => {
 9183                let position = get_implementation
 9184                    .position
 9185                    .clone()
 9186                    .and_then(deserialize_anchor);
 9187                Self::query_lsp_locally::<GetImplementations>(
 9188                    lsp_store,
 9189                    server_id,
 9190                    sender_id,
 9191                    lsp_request_id,
 9192                    get_implementation,
 9193                    position,
 9194                    &mut cx,
 9195                )
 9196                .await?;
 9197            }
 9198            Request::GetDocumentDiagnostics(get_document_diagnostics) => {
 9199                let buffer_id = BufferId::new(get_document_diagnostics.buffer_id())?;
 9200                let version = deserialize_version(get_document_diagnostics.buffer_version());
 9201                let buffer = lsp_store.update(&mut cx, |this, cx| {
 9202                    this.buffer_store.read(cx).get_existing(buffer_id)
 9203                })?;
 9204                buffer
 9205                    .update(&mut cx, |buffer, _| {
 9206                        buffer.wait_for_version(version.clone())
 9207                    })
 9208                    .await?;
 9209                lsp_store.update(&mut cx, |lsp_store, cx| {
 9210                    let lsp_data = lsp_store.latest_lsp_data(&buffer, cx);
 9211                    let key = LspKey {
 9212                        request_type: TypeId::of::<GetDocumentDiagnostics>(),
 9213                        server_queried: server_id,
 9214                    };
 9215                    if <GetDocumentDiagnostics as LspCommand>::ProtoRequest::stop_previous_requests(
 9216                    ) {
 9217                        if let Some(lsp_requests) = lsp_data.lsp_requests.get_mut(&key) {
 9218                            lsp_requests.clear();
 9219                        };
 9220                    }
 9221
 9222                    let existing_queries = lsp_data.lsp_requests.entry(key).or_default();
 9223                    existing_queries.insert(
 9224                        lsp_request_id,
 9225                        cx.spawn(async move |lsp_store, cx| {
 9226                            let diagnostics_pull = lsp_store.update(cx, |lsp_store, cx| {
 9227                                lsp_store.pull_diagnostics_for_buffer(buffer, cx)
 9228                            });
 9229                            if let Ok(diagnostics_pull) = diagnostics_pull {
 9230                                match diagnostics_pull.await {
 9231                                    Ok(()) => {}
 9232                                    Err(e) => log::error!("Failed to pull diagnostics: {e:#}"),
 9233                                };
 9234                            }
 9235                        }),
 9236                    );
 9237                });
 9238            }
 9239            Request::InlayHints(inlay_hints) => {
 9240                let query_start = inlay_hints
 9241                    .start
 9242                    .clone()
 9243                    .and_then(deserialize_anchor)
 9244                    .context("invalid inlay hints range start")?;
 9245                let query_end = inlay_hints
 9246                    .end
 9247                    .clone()
 9248                    .and_then(deserialize_anchor)
 9249                    .context("invalid inlay hints range end")?;
 9250                Self::deduplicate_range_based_lsp_requests::<InlayHints>(
 9251                    &lsp_store,
 9252                    server_id,
 9253                    lsp_request_id,
 9254                    &inlay_hints,
 9255                    query_start..query_end,
 9256                    &mut cx,
 9257                )
 9258                .await
 9259                .context("preparing inlay hints request")?;
 9260                Self::query_lsp_locally::<InlayHints>(
 9261                    lsp_store,
 9262                    server_id,
 9263                    sender_id,
 9264                    lsp_request_id,
 9265                    inlay_hints,
 9266                    None,
 9267                    &mut cx,
 9268                )
 9269                .await
 9270                .context("querying for inlay hints")?
 9271            }
 9272        }
 9273        Ok(proto::Ack {})
 9274    }
 9275
 9276    async fn handle_lsp_query_response(
 9277        lsp_store: Entity<Self>,
 9278        envelope: TypedEnvelope<proto::LspQueryResponse>,
 9279        cx: AsyncApp,
 9280    ) -> Result<()> {
 9281        lsp_store.read_with(&cx, |lsp_store, _| {
 9282            if let Some((upstream_client, _)) = lsp_store.upstream_client() {
 9283                upstream_client.handle_lsp_response(envelope.clone());
 9284            }
 9285        });
 9286        Ok(())
 9287    }
 9288
 9289    async fn handle_apply_code_action(
 9290        this: Entity<Self>,
 9291        envelope: TypedEnvelope<proto::ApplyCodeAction>,
 9292        mut cx: AsyncApp,
 9293    ) -> Result<proto::ApplyCodeActionResponse> {
 9294        let sender_id = envelope.original_sender_id().unwrap_or_default();
 9295        let action =
 9296            Self::deserialize_code_action(envelope.payload.action.context("invalid action")?)?;
 9297        let apply_code_action = this.update(&mut cx, |this, cx| {
 9298            let buffer_id = BufferId::new(envelope.payload.buffer_id)?;
 9299            let buffer = this.buffer_store.read(cx).get_existing(buffer_id)?;
 9300            anyhow::Ok(this.apply_code_action(buffer, action, false, cx))
 9301        })?;
 9302
 9303        let project_transaction = apply_code_action.await?;
 9304        let project_transaction = this.update(&mut cx, |this, cx| {
 9305            this.buffer_store.update(cx, |buffer_store, cx| {
 9306                buffer_store.serialize_project_transaction_for_peer(
 9307                    project_transaction,
 9308                    sender_id,
 9309                    cx,
 9310                )
 9311            })
 9312        });
 9313        Ok(proto::ApplyCodeActionResponse {
 9314            transaction: Some(project_transaction),
 9315        })
 9316    }
 9317
 9318    async fn handle_register_buffer_with_language_servers(
 9319        this: Entity<Self>,
 9320        envelope: TypedEnvelope<proto::RegisterBufferWithLanguageServers>,
 9321        mut cx: AsyncApp,
 9322    ) -> Result<proto::Ack> {
 9323        let buffer_id = BufferId::new(envelope.payload.buffer_id)?;
 9324        let peer_id = envelope.original_sender_id.unwrap_or(envelope.sender_id);
 9325        this.update(&mut cx, |this, cx| {
 9326            if let Some((upstream_client, upstream_project_id)) = this.upstream_client() {
 9327                return upstream_client.send(proto::RegisterBufferWithLanguageServers {
 9328                    project_id: upstream_project_id,
 9329                    buffer_id: buffer_id.to_proto(),
 9330                    only_servers: envelope.payload.only_servers,
 9331                });
 9332            }
 9333
 9334            let Some(buffer) = this.buffer_store().read(cx).get(buffer_id) else {
 9335                anyhow::bail!("buffer is not open");
 9336            };
 9337
 9338            let handle = this.register_buffer_with_language_servers(
 9339                &buffer,
 9340                envelope
 9341                    .payload
 9342                    .only_servers
 9343                    .into_iter()
 9344                    .filter_map(|selector| {
 9345                        Some(match selector.selector? {
 9346                            proto::language_server_selector::Selector::ServerId(server_id) => {
 9347                                LanguageServerSelector::Id(LanguageServerId::from_proto(server_id))
 9348                            }
 9349                            proto::language_server_selector::Selector::Name(name) => {
 9350                                LanguageServerSelector::Name(LanguageServerName(
 9351                                    SharedString::from(name),
 9352                                ))
 9353                            }
 9354                        })
 9355                    })
 9356                    .collect(),
 9357                false,
 9358                cx,
 9359            );
 9360            // Pull diagnostics for the buffer even if it was already registered.
 9361            // This is needed to make test_streamed_lsp_pull_diagnostics pass,
 9362            // but it's unclear if we need it.
 9363            this.pull_diagnostics_for_buffer(buffer.clone(), cx)
 9364                .detach();
 9365            this.buffer_store().update(cx, |buffer_store, _| {
 9366                buffer_store.register_shared_lsp_handle(peer_id, buffer_id, handle);
 9367            });
 9368
 9369            Ok(())
 9370        })?;
 9371        Ok(proto::Ack {})
 9372    }
 9373
 9374    async fn handle_rename_project_entry(
 9375        this: Entity<Self>,
 9376        envelope: TypedEnvelope<proto::RenameProjectEntry>,
 9377        mut cx: AsyncApp,
 9378    ) -> Result<proto::ProjectEntryResponse> {
 9379        let entry_id = ProjectEntryId::from_proto(envelope.payload.entry_id);
 9380        let new_worktree_id = WorktreeId::from_proto(envelope.payload.new_worktree_id);
 9381        let new_path =
 9382            RelPath::from_proto(&envelope.payload.new_path).context("invalid relative path")?;
 9383
 9384        let (worktree_store, old_worktree, new_worktree, old_entry) = this
 9385            .update(&mut cx, |this, cx| {
 9386                let (worktree, entry) = this
 9387                    .worktree_store
 9388                    .read(cx)
 9389                    .worktree_and_entry_for_id(entry_id, cx)?;
 9390                let new_worktree = this
 9391                    .worktree_store
 9392                    .read(cx)
 9393                    .worktree_for_id(new_worktree_id, cx)?;
 9394                Some((
 9395                    this.worktree_store.clone(),
 9396                    worktree,
 9397                    new_worktree,
 9398                    entry.clone(),
 9399                ))
 9400            })
 9401            .context("worktree not found")?;
 9402        let (old_abs_path, old_worktree_id) = old_worktree.read_with(&cx, |worktree, _| {
 9403            (worktree.absolutize(&old_entry.path), worktree.id())
 9404        });
 9405        let new_abs_path =
 9406            new_worktree.read_with(&cx, |worktree, _| worktree.absolutize(&new_path));
 9407
 9408        let _transaction = Self::will_rename_entry(
 9409            this.downgrade(),
 9410            old_worktree_id,
 9411            &old_abs_path,
 9412            &new_abs_path,
 9413            old_entry.is_dir(),
 9414            cx.clone(),
 9415        )
 9416        .await;
 9417        let response = WorktreeStore::handle_rename_project_entry(
 9418            worktree_store,
 9419            envelope.payload,
 9420            cx.clone(),
 9421        )
 9422        .await;
 9423        this.read_with(&cx, |this, _| {
 9424            this.did_rename_entry(
 9425                old_worktree_id,
 9426                &old_abs_path,
 9427                &new_abs_path,
 9428                old_entry.is_dir(),
 9429            );
 9430        });
 9431        response
 9432    }
 9433
 9434    async fn handle_update_diagnostic_summary(
 9435        this: Entity<Self>,
 9436        envelope: TypedEnvelope<proto::UpdateDiagnosticSummary>,
 9437        mut cx: AsyncApp,
 9438    ) -> Result<()> {
 9439        this.update(&mut cx, |lsp_store, cx| {
 9440            let worktree_id = WorktreeId::from_proto(envelope.payload.worktree_id);
 9441            let mut updated_diagnostics_paths = HashMap::default();
 9442            let mut diagnostics_summary = None::<proto::UpdateDiagnosticSummary>;
 9443            for message_summary in envelope
 9444                .payload
 9445                .summary
 9446                .into_iter()
 9447                .chain(envelope.payload.more_summaries)
 9448            {
 9449                let project_path = ProjectPath {
 9450                    worktree_id,
 9451                    path: RelPath::from_proto(&message_summary.path).context("invalid path")?,
 9452                };
 9453                let path = project_path.path.clone();
 9454                let server_id = LanguageServerId(message_summary.language_server_id as usize);
 9455                let summary = DiagnosticSummary {
 9456                    error_count: message_summary.error_count as usize,
 9457                    warning_count: message_summary.warning_count as usize,
 9458                };
 9459
 9460                if summary.is_empty() {
 9461                    if let Some(worktree_summaries) =
 9462                        lsp_store.diagnostic_summaries.get_mut(&worktree_id)
 9463                        && let Some(summaries) = worktree_summaries.get_mut(&path)
 9464                    {
 9465                        summaries.remove(&server_id);
 9466                        if summaries.is_empty() {
 9467                            worktree_summaries.remove(&path);
 9468                        }
 9469                    }
 9470                } else {
 9471                    lsp_store
 9472                        .diagnostic_summaries
 9473                        .entry(worktree_id)
 9474                        .or_default()
 9475                        .entry(path)
 9476                        .or_default()
 9477                        .insert(server_id, summary);
 9478                }
 9479
 9480                if let Some((_, project_id)) = &lsp_store.downstream_client {
 9481                    match &mut diagnostics_summary {
 9482                        Some(diagnostics_summary) => {
 9483                            diagnostics_summary
 9484                                .more_summaries
 9485                                .push(proto::DiagnosticSummary {
 9486                                    path: project_path.path.as_ref().to_proto(),
 9487                                    language_server_id: server_id.0 as u64,
 9488                                    error_count: summary.error_count as u32,
 9489                                    warning_count: summary.warning_count as u32,
 9490                                })
 9491                        }
 9492                        None => {
 9493                            diagnostics_summary = Some(proto::UpdateDiagnosticSummary {
 9494                                project_id: *project_id,
 9495                                worktree_id: worktree_id.to_proto(),
 9496                                summary: Some(proto::DiagnosticSummary {
 9497                                    path: project_path.path.as_ref().to_proto(),
 9498                                    language_server_id: server_id.0 as u64,
 9499                                    error_count: summary.error_count as u32,
 9500                                    warning_count: summary.warning_count as u32,
 9501                                }),
 9502                                more_summaries: Vec::new(),
 9503                            })
 9504                        }
 9505                    }
 9506                }
 9507                updated_diagnostics_paths
 9508                    .entry(server_id)
 9509                    .or_insert_with(Vec::new)
 9510                    .push(project_path);
 9511            }
 9512
 9513            if let Some((diagnostics_summary, (downstream_client, _))) =
 9514                diagnostics_summary.zip(lsp_store.downstream_client.as_ref())
 9515            {
 9516                downstream_client.send(diagnostics_summary).log_err();
 9517            }
 9518            for (server_id, paths) in updated_diagnostics_paths {
 9519                cx.emit(LspStoreEvent::DiagnosticsUpdated { server_id, paths });
 9520            }
 9521            Ok(())
 9522        })
 9523    }
 9524
 9525    async fn handle_start_language_server(
 9526        lsp_store: Entity<Self>,
 9527        envelope: TypedEnvelope<proto::StartLanguageServer>,
 9528        mut cx: AsyncApp,
 9529    ) -> Result<()> {
 9530        let server = envelope.payload.server.context("invalid server")?;
 9531        let server_capabilities =
 9532            serde_json::from_str::<lsp::ServerCapabilities>(&envelope.payload.capabilities)
 9533                .with_context(|| {
 9534                    format!(
 9535                        "incorrect server capabilities {}",
 9536                        envelope.payload.capabilities
 9537                    )
 9538                })?;
 9539        lsp_store.update(&mut cx, |lsp_store, cx| {
 9540            let server_id = LanguageServerId(server.id as usize);
 9541            let server_name = LanguageServerName::from_proto(server.name.clone());
 9542            lsp_store
 9543                .lsp_server_capabilities
 9544                .insert(server_id, server_capabilities);
 9545            lsp_store.language_server_statuses.insert(
 9546                server_id,
 9547                LanguageServerStatus {
 9548                    name: server_name.clone(),
 9549                    server_version: None,
 9550                    pending_work: Default::default(),
 9551                    has_pending_diagnostic_updates: false,
 9552                    progress_tokens: Default::default(),
 9553                    worktree: server.worktree_id.map(WorktreeId::from_proto),
 9554                    binary: None,
 9555                    configuration: None,
 9556                    workspace_folders: BTreeSet::new(),
 9557                },
 9558            );
 9559            cx.emit(LspStoreEvent::LanguageServerAdded(
 9560                server_id,
 9561                server_name,
 9562                server.worktree_id.map(WorktreeId::from_proto),
 9563            ));
 9564            cx.notify();
 9565        });
 9566        Ok(())
 9567    }
 9568
 9569    async fn handle_update_language_server(
 9570        lsp_store: Entity<Self>,
 9571        envelope: TypedEnvelope<proto::UpdateLanguageServer>,
 9572        mut cx: AsyncApp,
 9573    ) -> Result<()> {
 9574        lsp_store.update(&mut cx, |lsp_store, cx| {
 9575            let language_server_id = LanguageServerId(envelope.payload.language_server_id as usize);
 9576
 9577            match envelope.payload.variant.context("invalid variant")? {
 9578                proto::update_language_server::Variant::WorkStart(payload) => {
 9579                    lsp_store.on_lsp_work_start(
 9580                        language_server_id,
 9581                        ProgressToken::from_proto(payload.token.context("missing progress token")?)
 9582                            .context("invalid progress token value")?,
 9583                        LanguageServerProgress {
 9584                            title: payload.title,
 9585                            is_disk_based_diagnostics_progress: false,
 9586                            is_cancellable: payload.is_cancellable.unwrap_or(false),
 9587                            message: payload.message,
 9588                            percentage: payload.percentage.map(|p| p as usize),
 9589                            last_update_at: cx.background_executor().now(),
 9590                        },
 9591                        cx,
 9592                    );
 9593                }
 9594                proto::update_language_server::Variant::WorkProgress(payload) => {
 9595                    lsp_store.on_lsp_work_progress(
 9596                        language_server_id,
 9597                        ProgressToken::from_proto(payload.token.context("missing progress token")?)
 9598                            .context("invalid progress token value")?,
 9599                        LanguageServerProgress {
 9600                            title: None,
 9601                            is_disk_based_diagnostics_progress: false,
 9602                            is_cancellable: payload.is_cancellable.unwrap_or(false),
 9603                            message: payload.message,
 9604                            percentage: payload.percentage.map(|p| p as usize),
 9605                            last_update_at: cx.background_executor().now(),
 9606                        },
 9607                        cx,
 9608                    );
 9609                }
 9610
 9611                proto::update_language_server::Variant::WorkEnd(payload) => {
 9612                    lsp_store.on_lsp_work_end(
 9613                        language_server_id,
 9614                        ProgressToken::from_proto(payload.token.context("missing progress token")?)
 9615                            .context("invalid progress token value")?,
 9616                        cx,
 9617                    );
 9618                }
 9619
 9620                proto::update_language_server::Variant::DiskBasedDiagnosticsUpdating(_) => {
 9621                    lsp_store.disk_based_diagnostics_started(language_server_id, cx);
 9622                }
 9623
 9624                proto::update_language_server::Variant::DiskBasedDiagnosticsUpdated(_) => {
 9625                    lsp_store.disk_based_diagnostics_finished(language_server_id, cx)
 9626                }
 9627
 9628                non_lsp @ proto::update_language_server::Variant::StatusUpdate(_)
 9629                | non_lsp @ proto::update_language_server::Variant::RegisteredForBuffer(_)
 9630                | non_lsp @ proto::update_language_server::Variant::MetadataUpdated(_) => {
 9631                    cx.emit(LspStoreEvent::LanguageServerUpdate {
 9632                        language_server_id,
 9633                        name: envelope
 9634                            .payload
 9635                            .server_name
 9636                            .map(SharedString::new)
 9637                            .map(LanguageServerName),
 9638                        message: non_lsp,
 9639                    });
 9640                }
 9641            }
 9642
 9643            Ok(())
 9644        })
 9645    }
 9646
 9647    async fn handle_language_server_log(
 9648        this: Entity<Self>,
 9649        envelope: TypedEnvelope<proto::LanguageServerLog>,
 9650        mut cx: AsyncApp,
 9651    ) -> Result<()> {
 9652        let language_server_id = LanguageServerId(envelope.payload.language_server_id as usize);
 9653        let log_type = envelope
 9654            .payload
 9655            .log_type
 9656            .map(LanguageServerLogType::from_proto)
 9657            .context("invalid language server log type")?;
 9658
 9659        let message = envelope.payload.message;
 9660
 9661        this.update(&mut cx, |_, cx| {
 9662            cx.emit(LspStoreEvent::LanguageServerLog(
 9663                language_server_id,
 9664                log_type,
 9665                message,
 9666            ));
 9667        });
 9668        Ok(())
 9669    }
 9670
 9671    async fn handle_lsp_ext_cancel_flycheck(
 9672        lsp_store: Entity<Self>,
 9673        envelope: TypedEnvelope<proto::LspExtCancelFlycheck>,
 9674        cx: AsyncApp,
 9675    ) -> Result<proto::Ack> {
 9676        let server_id = LanguageServerId(envelope.payload.language_server_id as usize);
 9677        let task = lsp_store.read_with(&cx, |lsp_store, _| {
 9678            if let Some(server) = lsp_store.language_server_for_id(server_id) {
 9679                Some(server.notify::<lsp_store::lsp_ext_command::LspExtCancelFlycheck>(()))
 9680            } else {
 9681                None
 9682            }
 9683        });
 9684        if let Some(task) = task {
 9685            task.context("handling lsp ext cancel flycheck")?;
 9686        }
 9687
 9688        Ok(proto::Ack {})
 9689    }
 9690
 9691    async fn handle_lsp_ext_run_flycheck(
 9692        lsp_store: Entity<Self>,
 9693        envelope: TypedEnvelope<proto::LspExtRunFlycheck>,
 9694        mut cx: AsyncApp,
 9695    ) -> Result<proto::Ack> {
 9696        let server_id = LanguageServerId(envelope.payload.language_server_id as usize);
 9697        lsp_store.update(&mut cx, |lsp_store, cx| {
 9698            if let Some(server) = lsp_store.language_server_for_id(server_id) {
 9699                let text_document = if envelope.payload.current_file_only {
 9700                    let buffer_id = envelope
 9701                        .payload
 9702                        .buffer_id
 9703                        .map(|id| BufferId::new(id))
 9704                        .transpose()?;
 9705                    buffer_id
 9706                        .and_then(|buffer_id| {
 9707                            lsp_store
 9708                                .buffer_store()
 9709                                .read(cx)
 9710                                .get(buffer_id)
 9711                                .and_then(|buffer| {
 9712                                    Some(buffer.read(cx).file()?.as_local()?.abs_path(cx))
 9713                                })
 9714                                .map(|path| make_text_document_identifier(&path))
 9715                        })
 9716                        .transpose()?
 9717                } else {
 9718                    None
 9719                };
 9720                server.notify::<lsp_store::lsp_ext_command::LspExtRunFlycheck>(
 9721                    lsp_store::lsp_ext_command::RunFlycheckParams { text_document },
 9722                )?;
 9723            }
 9724            anyhow::Ok(())
 9725        })?;
 9726
 9727        Ok(proto::Ack {})
 9728    }
 9729
 9730    async fn handle_lsp_ext_clear_flycheck(
 9731        lsp_store: Entity<Self>,
 9732        envelope: TypedEnvelope<proto::LspExtClearFlycheck>,
 9733        cx: AsyncApp,
 9734    ) -> Result<proto::Ack> {
 9735        let server_id = LanguageServerId(envelope.payload.language_server_id as usize);
 9736        lsp_store.read_with(&cx, |lsp_store, _| {
 9737            if let Some(server) = lsp_store.language_server_for_id(server_id) {
 9738                Some(server.notify::<lsp_store::lsp_ext_command::LspExtClearFlycheck>(()))
 9739            } else {
 9740                None
 9741            }
 9742        });
 9743
 9744        Ok(proto::Ack {})
 9745    }
 9746
 9747    pub fn disk_based_diagnostics_started(
 9748        &mut self,
 9749        language_server_id: LanguageServerId,
 9750        cx: &mut Context<Self>,
 9751    ) {
 9752        if let Some(language_server_status) =
 9753            self.language_server_statuses.get_mut(&language_server_id)
 9754        {
 9755            language_server_status.has_pending_diagnostic_updates = true;
 9756        }
 9757
 9758        cx.emit(LspStoreEvent::DiskBasedDiagnosticsStarted { language_server_id });
 9759        cx.emit(LspStoreEvent::LanguageServerUpdate {
 9760            language_server_id,
 9761            name: self
 9762                .language_server_adapter_for_id(language_server_id)
 9763                .map(|adapter| adapter.name()),
 9764            message: proto::update_language_server::Variant::DiskBasedDiagnosticsUpdating(
 9765                Default::default(),
 9766            ),
 9767        })
 9768    }
 9769
 9770    pub fn disk_based_diagnostics_finished(
 9771        &mut self,
 9772        language_server_id: LanguageServerId,
 9773        cx: &mut Context<Self>,
 9774    ) {
 9775        if let Some(language_server_status) =
 9776            self.language_server_statuses.get_mut(&language_server_id)
 9777        {
 9778            language_server_status.has_pending_diagnostic_updates = false;
 9779        }
 9780
 9781        cx.emit(LspStoreEvent::DiskBasedDiagnosticsFinished { language_server_id });
 9782        cx.emit(LspStoreEvent::LanguageServerUpdate {
 9783            language_server_id,
 9784            name: self
 9785                .language_server_adapter_for_id(language_server_id)
 9786                .map(|adapter| adapter.name()),
 9787            message: proto::update_language_server::Variant::DiskBasedDiagnosticsUpdated(
 9788                Default::default(),
 9789            ),
 9790        })
 9791    }
 9792
 9793    // After saving a buffer using a language server that doesn't provide a disk-based progress token,
 9794    // kick off a timer that will reset every time the buffer is saved. If the timer eventually fires,
 9795    // simulate disk-based diagnostics being finished so that other pieces of UI (e.g., project
 9796    // diagnostics view, diagnostic status bar) can update. We don't emit an event right away because
 9797    // the language server might take some time to publish diagnostics.
 9798    fn simulate_disk_based_diagnostics_events_if_needed(
 9799        &mut self,
 9800        language_server_id: LanguageServerId,
 9801        cx: &mut Context<Self>,
 9802    ) {
 9803        const DISK_BASED_DIAGNOSTICS_DEBOUNCE: Duration = Duration::from_secs(1);
 9804
 9805        let Some(LanguageServerState::Running {
 9806            simulate_disk_based_diagnostics_completion,
 9807            adapter,
 9808            ..
 9809        }) = self
 9810            .as_local_mut()
 9811            .and_then(|local_store| local_store.language_servers.get_mut(&language_server_id))
 9812        else {
 9813            return;
 9814        };
 9815
 9816        if adapter.disk_based_diagnostics_progress_token.is_some() {
 9817            return;
 9818        }
 9819
 9820        let prev_task =
 9821            simulate_disk_based_diagnostics_completion.replace(cx.spawn(async move |this, cx| {
 9822                cx.background_executor()
 9823                    .timer(DISK_BASED_DIAGNOSTICS_DEBOUNCE)
 9824                    .await;
 9825
 9826                this.update(cx, |this, cx| {
 9827                    this.disk_based_diagnostics_finished(language_server_id, cx);
 9828
 9829                    if let Some(LanguageServerState::Running {
 9830                        simulate_disk_based_diagnostics_completion,
 9831                        ..
 9832                    }) = this.as_local_mut().and_then(|local_store| {
 9833                        local_store.language_servers.get_mut(&language_server_id)
 9834                    }) {
 9835                        *simulate_disk_based_diagnostics_completion = None;
 9836                    }
 9837                })
 9838                .ok();
 9839            }));
 9840
 9841        if prev_task.is_none() {
 9842            self.disk_based_diagnostics_started(language_server_id, cx);
 9843        }
 9844    }
 9845
 9846    pub fn language_server_statuses(
 9847        &self,
 9848    ) -> impl DoubleEndedIterator<Item = (LanguageServerId, &LanguageServerStatus)> {
 9849        self.language_server_statuses
 9850            .iter()
 9851            .map(|(key, value)| (*key, value))
 9852    }
 9853
 9854    pub(super) fn did_rename_entry(
 9855        &self,
 9856        worktree_id: WorktreeId,
 9857        old_path: &Path,
 9858        new_path: &Path,
 9859        is_dir: bool,
 9860    ) {
 9861        maybe!({
 9862            let local_store = self.as_local()?;
 9863
 9864            let old_uri = lsp::Uri::from_file_path(old_path)
 9865                .ok()
 9866                .map(|uri| uri.to_string())?;
 9867            let new_uri = lsp::Uri::from_file_path(new_path)
 9868                .ok()
 9869                .map(|uri| uri.to_string())?;
 9870
 9871            for language_server in local_store.language_servers_for_worktree(worktree_id) {
 9872                let Some(filter) = local_store
 9873                    .language_server_paths_watched_for_rename
 9874                    .get(&language_server.server_id())
 9875                else {
 9876                    continue;
 9877                };
 9878
 9879                if filter.should_send_did_rename(&old_uri, is_dir) {
 9880                    language_server
 9881                        .notify::<DidRenameFiles>(RenameFilesParams {
 9882                            files: vec![FileRename {
 9883                                old_uri: old_uri.clone(),
 9884                                new_uri: new_uri.clone(),
 9885                            }],
 9886                        })
 9887                        .ok();
 9888                }
 9889            }
 9890            Some(())
 9891        });
 9892    }
 9893
 9894    pub(super) fn will_rename_entry(
 9895        this: WeakEntity<Self>,
 9896        worktree_id: WorktreeId,
 9897        old_path: &Path,
 9898        new_path: &Path,
 9899        is_dir: bool,
 9900        cx: AsyncApp,
 9901    ) -> Task<ProjectTransaction> {
 9902        let old_uri = lsp::Uri::from_file_path(old_path)
 9903            .ok()
 9904            .map(|uri| uri.to_string());
 9905        let new_uri = lsp::Uri::from_file_path(new_path)
 9906            .ok()
 9907            .map(|uri| uri.to_string());
 9908        cx.spawn(async move |cx| {
 9909            let mut tasks = vec![];
 9910            this.update(cx, |this, cx| {
 9911                let local_store = this.as_local()?;
 9912                let old_uri = old_uri?;
 9913                let new_uri = new_uri?;
 9914                for language_server in local_store.language_servers_for_worktree(worktree_id) {
 9915                    let Some(filter) = local_store
 9916                        .language_server_paths_watched_for_rename
 9917                        .get(&language_server.server_id())
 9918                    else {
 9919                        continue;
 9920                    };
 9921
 9922                    if filter.should_send_will_rename(&old_uri, is_dir) {
 9923                        let apply_edit = cx.spawn({
 9924                            let old_uri = old_uri.clone();
 9925                            let new_uri = new_uri.clone();
 9926                            let language_server = language_server.clone();
 9927                            async move |this, cx| {
 9928                                let edit = language_server
 9929                                    .request::<WillRenameFiles>(RenameFilesParams {
 9930                                        files: vec![FileRename { old_uri, new_uri }],
 9931                                    })
 9932                                    .await
 9933                                    .into_response()
 9934                                    .context("will rename files")
 9935                                    .log_err()
 9936                                    .flatten()?;
 9937
 9938                                let transaction = LocalLspStore::deserialize_workspace_edit(
 9939                                    this.upgrade()?,
 9940                                    edit,
 9941                                    false,
 9942                                    language_server.clone(),
 9943                                    cx,
 9944                                )
 9945                                .await
 9946                                .ok()?;
 9947                                Some(transaction)
 9948                            }
 9949                        });
 9950                        tasks.push(apply_edit);
 9951                    }
 9952                }
 9953                Some(())
 9954            })
 9955            .ok()
 9956            .flatten();
 9957            let mut merged_transaction = ProjectTransaction::default();
 9958            for task in tasks {
 9959                // Await on tasks sequentially so that the order of application of edits is deterministic
 9960                // (at least with regards to the order of registration of language servers)
 9961                if let Some(transaction) = task.await {
 9962                    for (buffer, buffer_transaction) in transaction.0 {
 9963                        merged_transaction.0.insert(buffer, buffer_transaction);
 9964                    }
 9965                }
 9966            }
 9967            merged_transaction
 9968        })
 9969    }
 9970
 9971    fn lsp_notify_abs_paths_changed(
 9972        &mut self,
 9973        server_id: LanguageServerId,
 9974        changes: Vec<PathEvent>,
 9975    ) {
 9976        maybe!({
 9977            let server = self.language_server_for_id(server_id)?;
 9978            let changes = changes
 9979                .into_iter()
 9980                .filter_map(|event| {
 9981                    let typ = match event.kind? {
 9982                        PathEventKind::Created => lsp::FileChangeType::CREATED,
 9983                        PathEventKind::Removed => lsp::FileChangeType::DELETED,
 9984                        PathEventKind::Changed => lsp::FileChangeType::CHANGED,
 9985                    };
 9986                    Some(lsp::FileEvent {
 9987                        uri: file_path_to_lsp_url(&event.path).log_err()?,
 9988                        typ,
 9989                    })
 9990                })
 9991                .collect::<Vec<_>>();
 9992            if !changes.is_empty() {
 9993                server
 9994                    .notify::<lsp::notification::DidChangeWatchedFiles>(
 9995                        lsp::DidChangeWatchedFilesParams { changes },
 9996                    )
 9997                    .ok();
 9998            }
 9999            Some(())
10000        });
10001    }
10002
10003    pub fn language_server_for_id(&self, id: LanguageServerId) -> Option<Arc<LanguageServer>> {
10004        self.as_local()?.language_server_for_id(id)
10005    }
10006
10007    fn on_lsp_progress(
10008        &mut self,
10009        progress_params: lsp::ProgressParams,
10010        language_server_id: LanguageServerId,
10011        disk_based_diagnostics_progress_token: Option<String>,
10012        cx: &mut Context<Self>,
10013    ) {
10014        match progress_params.value {
10015            lsp::ProgressParamsValue::WorkDone(progress) => {
10016                self.handle_work_done_progress(
10017                    progress,
10018                    language_server_id,
10019                    disk_based_diagnostics_progress_token,
10020                    ProgressToken::from_lsp(progress_params.token),
10021                    cx,
10022                );
10023            }
10024            lsp::ProgressParamsValue::WorkspaceDiagnostic(report) => {
10025                let registration_id = match progress_params.token {
10026                    lsp::NumberOrString::Number(_) => None,
10027                    lsp::NumberOrString::String(token) => token
10028                        .split_once(WORKSPACE_DIAGNOSTICS_TOKEN_START)
10029                        .map(|(_, id)| id.to_owned()),
10030                };
10031                if let Some(LanguageServerState::Running {
10032                    workspace_diagnostics_refresh_tasks,
10033                    ..
10034                }) = self
10035                    .as_local_mut()
10036                    .and_then(|local| local.language_servers.get_mut(&language_server_id))
10037                    && let Some(workspace_diagnostics) =
10038                        workspace_diagnostics_refresh_tasks.get_mut(&registration_id)
10039                {
10040                    workspace_diagnostics.progress_tx.try_send(()).ok();
10041                    self.apply_workspace_diagnostic_report(
10042                        language_server_id,
10043                        report,
10044                        registration_id.map(SharedString::from),
10045                        cx,
10046                    )
10047                }
10048            }
10049        }
10050    }
10051
10052    fn handle_work_done_progress(
10053        &mut self,
10054        progress: lsp::WorkDoneProgress,
10055        language_server_id: LanguageServerId,
10056        disk_based_diagnostics_progress_token: Option<String>,
10057        token: ProgressToken,
10058        cx: &mut Context<Self>,
10059    ) {
10060        let language_server_status =
10061            if let Some(status) = self.language_server_statuses.get_mut(&language_server_id) {
10062                status
10063            } else {
10064                return;
10065            };
10066
10067        if !language_server_status.progress_tokens.contains(&token) {
10068            return;
10069        }
10070
10071        let is_disk_based_diagnostics_progress =
10072            if let (Some(disk_based_token), ProgressToken::String(token)) =
10073                (&disk_based_diagnostics_progress_token, &token)
10074            {
10075                token.starts_with(disk_based_token)
10076            } else {
10077                false
10078            };
10079
10080        match progress {
10081            lsp::WorkDoneProgress::Begin(report) => {
10082                if is_disk_based_diagnostics_progress {
10083                    self.disk_based_diagnostics_started(language_server_id, cx);
10084                }
10085                self.on_lsp_work_start(
10086                    language_server_id,
10087                    token.clone(),
10088                    LanguageServerProgress {
10089                        title: Some(report.title),
10090                        is_disk_based_diagnostics_progress,
10091                        is_cancellable: report.cancellable.unwrap_or(false),
10092                        message: report.message.clone(),
10093                        percentage: report.percentage.map(|p| p as usize),
10094                        last_update_at: cx.background_executor().now(),
10095                    },
10096                    cx,
10097                );
10098            }
10099            lsp::WorkDoneProgress::Report(report) => self.on_lsp_work_progress(
10100                language_server_id,
10101                token,
10102                LanguageServerProgress {
10103                    title: None,
10104                    is_disk_based_diagnostics_progress,
10105                    is_cancellable: report.cancellable.unwrap_or(false),
10106                    message: report.message,
10107                    percentage: report.percentage.map(|p| p as usize),
10108                    last_update_at: cx.background_executor().now(),
10109                },
10110                cx,
10111            ),
10112            lsp::WorkDoneProgress::End(_) => {
10113                language_server_status.progress_tokens.remove(&token);
10114                self.on_lsp_work_end(language_server_id, token.clone(), cx);
10115                if is_disk_based_diagnostics_progress {
10116                    self.disk_based_diagnostics_finished(language_server_id, cx);
10117                }
10118            }
10119        }
10120    }
10121
10122    fn on_lsp_work_start(
10123        &mut self,
10124        language_server_id: LanguageServerId,
10125        token: ProgressToken,
10126        progress: LanguageServerProgress,
10127        cx: &mut Context<Self>,
10128    ) {
10129        if let Some(status) = self.language_server_statuses.get_mut(&language_server_id) {
10130            status.pending_work.insert(token.clone(), progress.clone());
10131            cx.notify();
10132        }
10133        cx.emit(LspStoreEvent::LanguageServerUpdate {
10134            language_server_id,
10135            name: self
10136                .language_server_adapter_for_id(language_server_id)
10137                .map(|adapter| adapter.name()),
10138            message: proto::update_language_server::Variant::WorkStart(proto::LspWorkStart {
10139                token: Some(token.to_proto()),
10140                title: progress.title,
10141                message: progress.message,
10142                percentage: progress.percentage.map(|p| p as u32),
10143                is_cancellable: Some(progress.is_cancellable),
10144            }),
10145        })
10146    }
10147
10148    fn on_lsp_work_progress(
10149        &mut self,
10150        language_server_id: LanguageServerId,
10151        token: ProgressToken,
10152        progress: LanguageServerProgress,
10153        cx: &mut Context<Self>,
10154    ) {
10155        let mut did_update = false;
10156        if let Some(status) = self.language_server_statuses.get_mut(&language_server_id) {
10157            match status.pending_work.entry(token.clone()) {
10158                btree_map::Entry::Vacant(entry) => {
10159                    entry.insert(progress.clone());
10160                    did_update = true;
10161                }
10162                btree_map::Entry::Occupied(mut entry) => {
10163                    let entry = entry.get_mut();
10164                    if (progress.last_update_at - entry.last_update_at)
10165                        >= SERVER_PROGRESS_THROTTLE_TIMEOUT
10166                    {
10167                        entry.last_update_at = progress.last_update_at;
10168                        if progress.message.is_some() {
10169                            entry.message = progress.message.clone();
10170                        }
10171                        if progress.percentage.is_some() {
10172                            entry.percentage = progress.percentage;
10173                        }
10174                        if progress.is_cancellable != entry.is_cancellable {
10175                            entry.is_cancellable = progress.is_cancellable;
10176                        }
10177                        did_update = true;
10178                    }
10179                }
10180            }
10181        }
10182
10183        if did_update {
10184            cx.emit(LspStoreEvent::LanguageServerUpdate {
10185                language_server_id,
10186                name: self
10187                    .language_server_adapter_for_id(language_server_id)
10188                    .map(|adapter| adapter.name()),
10189                message: proto::update_language_server::Variant::WorkProgress(
10190                    proto::LspWorkProgress {
10191                        token: Some(token.to_proto()),
10192                        message: progress.message,
10193                        percentage: progress.percentage.map(|p| p as u32),
10194                        is_cancellable: Some(progress.is_cancellable),
10195                    },
10196                ),
10197            })
10198        }
10199    }
10200
10201    fn on_lsp_work_end(
10202        &mut self,
10203        language_server_id: LanguageServerId,
10204        token: ProgressToken,
10205        cx: &mut Context<Self>,
10206    ) {
10207        if let Some(status) = self.language_server_statuses.get_mut(&language_server_id) {
10208            if let Some(work) = status.pending_work.remove(&token)
10209                && !work.is_disk_based_diagnostics_progress
10210            {
10211                cx.emit(LspStoreEvent::RefreshInlayHints {
10212                    server_id: language_server_id,
10213                    request_id: None,
10214                });
10215            }
10216            cx.notify();
10217        }
10218
10219        cx.emit(LspStoreEvent::LanguageServerUpdate {
10220            language_server_id,
10221            name: self
10222                .language_server_adapter_for_id(language_server_id)
10223                .map(|adapter| adapter.name()),
10224            message: proto::update_language_server::Variant::WorkEnd(proto::LspWorkEnd {
10225                token: Some(token.to_proto()),
10226            }),
10227        })
10228    }
10229
10230    pub async fn handle_resolve_completion_documentation(
10231        this: Entity<Self>,
10232        envelope: TypedEnvelope<proto::ResolveCompletionDocumentation>,
10233        mut cx: AsyncApp,
10234    ) -> Result<proto::ResolveCompletionDocumentationResponse> {
10235        let lsp_completion = serde_json::from_slice(&envelope.payload.lsp_completion)?;
10236
10237        let completion = this
10238            .read_with(&cx, |this, cx| {
10239                let id = LanguageServerId(envelope.payload.language_server_id as usize);
10240                let server = this
10241                    .language_server_for_id(id)
10242                    .with_context(|| format!("No language server {id}"))?;
10243
10244                anyhow::Ok(cx.background_spawn(async move {
10245                    let can_resolve = server
10246                        .capabilities()
10247                        .completion_provider
10248                        .as_ref()
10249                        .and_then(|options| options.resolve_provider)
10250                        .unwrap_or(false);
10251                    if can_resolve {
10252                        server
10253                            .request::<lsp::request::ResolveCompletionItem>(lsp_completion)
10254                            .await
10255                            .into_response()
10256                            .context("resolve completion item")
10257                    } else {
10258                        anyhow::Ok(lsp_completion)
10259                    }
10260                }))
10261            })?
10262            .await?;
10263
10264        let mut documentation_is_markdown = false;
10265        let lsp_completion = serde_json::to_string(&completion)?.into_bytes();
10266        let documentation = match completion.documentation {
10267            Some(lsp::Documentation::String(text)) => text,
10268
10269            Some(lsp::Documentation::MarkupContent(lsp::MarkupContent { kind, value })) => {
10270                documentation_is_markdown = kind == lsp::MarkupKind::Markdown;
10271                value
10272            }
10273
10274            _ => String::new(),
10275        };
10276
10277        // If we have a new buffer_id, that means we're talking to a new client
10278        // and want to check for new text_edits in the completion too.
10279        let mut old_replace_start = None;
10280        let mut old_replace_end = None;
10281        let mut old_insert_start = None;
10282        let mut old_insert_end = None;
10283        let mut new_text = String::default();
10284        if let Ok(buffer_id) = BufferId::new(envelope.payload.buffer_id) {
10285            let buffer_snapshot = this.update(&mut cx, |this, cx| {
10286                let buffer = this.buffer_store.read(cx).get_existing(buffer_id)?;
10287                anyhow::Ok(buffer.read(cx).snapshot())
10288            })?;
10289
10290            if let Some(text_edit) = completion.text_edit.as_ref() {
10291                let edit = parse_completion_text_edit(text_edit, &buffer_snapshot);
10292
10293                if let Some(mut edit) = edit {
10294                    LineEnding::normalize(&mut edit.new_text);
10295
10296                    new_text = edit.new_text;
10297                    old_replace_start = Some(serialize_anchor(&edit.replace_range.start));
10298                    old_replace_end = Some(serialize_anchor(&edit.replace_range.end));
10299                    if let Some(insert_range) = edit.insert_range {
10300                        old_insert_start = Some(serialize_anchor(&insert_range.start));
10301                        old_insert_end = Some(serialize_anchor(&insert_range.end));
10302                    }
10303                }
10304            }
10305        }
10306
10307        Ok(proto::ResolveCompletionDocumentationResponse {
10308            documentation,
10309            documentation_is_markdown,
10310            old_replace_start,
10311            old_replace_end,
10312            new_text,
10313            lsp_completion,
10314            old_insert_start,
10315            old_insert_end,
10316        })
10317    }
10318
10319    async fn handle_on_type_formatting(
10320        this: Entity<Self>,
10321        envelope: TypedEnvelope<proto::OnTypeFormatting>,
10322        mut cx: AsyncApp,
10323    ) -> Result<proto::OnTypeFormattingResponse> {
10324        let on_type_formatting = this.update(&mut cx, |this, cx| {
10325            let buffer_id = BufferId::new(envelope.payload.buffer_id)?;
10326            let buffer = this.buffer_store.read(cx).get_existing(buffer_id)?;
10327            let position = envelope
10328                .payload
10329                .position
10330                .and_then(deserialize_anchor)
10331                .context("invalid position")?;
10332            anyhow::Ok(this.apply_on_type_formatting(
10333                buffer,
10334                position,
10335                envelope.payload.trigger.clone(),
10336                cx,
10337            ))
10338        })?;
10339
10340        let transaction = on_type_formatting
10341            .await?
10342            .as_ref()
10343            .map(language::proto::serialize_transaction);
10344        Ok(proto::OnTypeFormattingResponse { transaction })
10345    }
10346
10347    async fn handle_refresh_inlay_hints(
10348        lsp_store: Entity<Self>,
10349        envelope: TypedEnvelope<proto::RefreshInlayHints>,
10350        mut cx: AsyncApp,
10351    ) -> Result<proto::Ack> {
10352        lsp_store.update(&mut cx, |_, cx| {
10353            cx.emit(LspStoreEvent::RefreshInlayHints {
10354                server_id: LanguageServerId::from_proto(envelope.payload.server_id),
10355                request_id: envelope.payload.request_id.map(|id| id as usize),
10356            });
10357        });
10358        Ok(proto::Ack {})
10359    }
10360
10361    async fn handle_pull_workspace_diagnostics(
10362        lsp_store: Entity<Self>,
10363        envelope: TypedEnvelope<proto::PullWorkspaceDiagnostics>,
10364        mut cx: AsyncApp,
10365    ) -> Result<proto::Ack> {
10366        let server_id = LanguageServerId::from_proto(envelope.payload.server_id);
10367        lsp_store.update(&mut cx, |lsp_store, _| {
10368            lsp_store.pull_workspace_diagnostics(server_id);
10369        });
10370        Ok(proto::Ack {})
10371    }
10372
10373    async fn handle_get_color_presentation(
10374        lsp_store: Entity<Self>,
10375        envelope: TypedEnvelope<proto::GetColorPresentation>,
10376        mut cx: AsyncApp,
10377    ) -> Result<proto::GetColorPresentationResponse> {
10378        let buffer_id = BufferId::new(envelope.payload.buffer_id)?;
10379        let buffer = lsp_store.update(&mut cx, |lsp_store, cx| {
10380            lsp_store.buffer_store.read(cx).get_existing(buffer_id)
10381        })?;
10382
10383        let color = envelope
10384            .payload
10385            .color
10386            .context("invalid color resolve request")?;
10387        let start = color
10388            .lsp_range_start
10389            .context("invalid color resolve request")?;
10390        let end = color
10391            .lsp_range_end
10392            .context("invalid color resolve request")?;
10393
10394        let color = DocumentColor {
10395            lsp_range: lsp::Range {
10396                start: point_to_lsp(PointUtf16::new(start.row, start.column)),
10397                end: point_to_lsp(PointUtf16::new(end.row, end.column)),
10398            },
10399            color: lsp::Color {
10400                red: color.red,
10401                green: color.green,
10402                blue: color.blue,
10403                alpha: color.alpha,
10404            },
10405            resolved: false,
10406            color_presentations: Vec::new(),
10407        };
10408        let resolved_color = lsp_store
10409            .update(&mut cx, |lsp_store, cx| {
10410                lsp_store.resolve_color_presentation(
10411                    color,
10412                    buffer.clone(),
10413                    LanguageServerId(envelope.payload.server_id as usize),
10414                    cx,
10415                )
10416            })
10417            .await
10418            .context("resolving color presentation")?;
10419
10420        Ok(proto::GetColorPresentationResponse {
10421            presentations: resolved_color
10422                .color_presentations
10423                .into_iter()
10424                .map(|presentation| proto::ColorPresentation {
10425                    label: presentation.label.to_string(),
10426                    text_edit: presentation.text_edit.map(serialize_lsp_edit),
10427                    additional_text_edits: presentation
10428                        .additional_text_edits
10429                        .into_iter()
10430                        .map(serialize_lsp_edit)
10431                        .collect(),
10432                })
10433                .collect(),
10434        })
10435    }
10436
10437    async fn handle_resolve_inlay_hint(
10438        lsp_store: Entity<Self>,
10439        envelope: TypedEnvelope<proto::ResolveInlayHint>,
10440        mut cx: AsyncApp,
10441    ) -> Result<proto::ResolveInlayHintResponse> {
10442        let proto_hint = envelope
10443            .payload
10444            .hint
10445            .expect("incorrect protobuf resolve inlay hint message: missing the inlay hint");
10446        let hint = InlayHints::proto_to_project_hint(proto_hint)
10447            .context("resolved proto inlay hint conversion")?;
10448        let buffer = lsp_store.update(&mut cx, |lsp_store, cx| {
10449            let buffer_id = BufferId::new(envelope.payload.buffer_id)?;
10450            lsp_store.buffer_store.read(cx).get_existing(buffer_id)
10451        })?;
10452        let response_hint = lsp_store
10453            .update(&mut cx, |lsp_store, cx| {
10454                lsp_store.resolve_inlay_hint(
10455                    hint,
10456                    buffer,
10457                    LanguageServerId(envelope.payload.language_server_id as usize),
10458                    cx,
10459                )
10460            })
10461            .await
10462            .context("inlay hints fetch")?;
10463        Ok(proto::ResolveInlayHintResponse {
10464            hint: Some(InlayHints::project_to_proto_hint(response_hint)),
10465        })
10466    }
10467
10468    async fn handle_refresh_code_lens(
10469        this: Entity<Self>,
10470        _: TypedEnvelope<proto::RefreshCodeLens>,
10471        mut cx: AsyncApp,
10472    ) -> Result<proto::Ack> {
10473        this.update(&mut cx, |_, cx| {
10474            cx.emit(LspStoreEvent::RefreshCodeLens);
10475        });
10476        Ok(proto::Ack {})
10477    }
10478
10479    async fn handle_open_buffer_for_symbol(
10480        this: Entity<Self>,
10481        envelope: TypedEnvelope<proto::OpenBufferForSymbol>,
10482        mut cx: AsyncApp,
10483    ) -> Result<proto::OpenBufferForSymbolResponse> {
10484        let peer_id = envelope.original_sender_id().unwrap_or_default();
10485        let symbol = envelope.payload.symbol.context("invalid symbol")?;
10486        let symbol = Self::deserialize_symbol(symbol)?;
10487        this.read_with(&cx, |this, _| {
10488            if let SymbolLocation::OutsideProject {
10489                abs_path,
10490                signature,
10491            } = &symbol.path
10492            {
10493                let new_signature = this.symbol_signature(&abs_path);
10494                anyhow::ensure!(&new_signature == signature, "invalid symbol signature");
10495            }
10496            Ok(())
10497        })?;
10498        let buffer = this
10499            .update(&mut cx, |this, cx| {
10500                this.open_buffer_for_symbol(
10501                    &Symbol {
10502                        language_server_name: symbol.language_server_name,
10503                        source_worktree_id: symbol.source_worktree_id,
10504                        source_language_server_id: symbol.source_language_server_id,
10505                        path: symbol.path,
10506                        name: symbol.name,
10507                        kind: symbol.kind,
10508                        range: symbol.range,
10509                        label: CodeLabel::default(),
10510                    },
10511                    cx,
10512                )
10513            })
10514            .await?;
10515
10516        this.update(&mut cx, |this, cx| {
10517            let is_private = buffer
10518                .read(cx)
10519                .file()
10520                .map(|f| f.is_private())
10521                .unwrap_or_default();
10522            if is_private {
10523                Err(anyhow!(rpc::ErrorCode::UnsharedItem))
10524            } else {
10525                this.buffer_store
10526                    .update(cx, |buffer_store, cx| {
10527                        buffer_store.create_buffer_for_peer(&buffer, peer_id, cx)
10528                    })
10529                    .detach_and_log_err(cx);
10530                let buffer_id = buffer.read(cx).remote_id().to_proto();
10531                Ok(proto::OpenBufferForSymbolResponse { buffer_id })
10532            }
10533        })
10534    }
10535
10536    fn symbol_signature(&self, abs_path: &Path) -> [u8; 32] {
10537        let mut hasher = Sha256::new();
10538        hasher.update(abs_path.to_string_lossy().as_bytes());
10539        hasher.update(self.nonce.to_be_bytes());
10540        hasher.finalize().as_slice().try_into().unwrap()
10541    }
10542
10543    pub async fn handle_get_project_symbols(
10544        this: Entity<Self>,
10545        envelope: TypedEnvelope<proto::GetProjectSymbols>,
10546        mut cx: AsyncApp,
10547    ) -> Result<proto::GetProjectSymbolsResponse> {
10548        let symbols = this
10549            .update(&mut cx, |this, cx| {
10550                this.symbols(&envelope.payload.query, cx)
10551            })
10552            .await?;
10553
10554        Ok(proto::GetProjectSymbolsResponse {
10555            symbols: symbols.iter().map(Self::serialize_symbol).collect(),
10556        })
10557    }
10558
10559    pub async fn handle_restart_language_servers(
10560        this: Entity<Self>,
10561        envelope: TypedEnvelope<proto::RestartLanguageServers>,
10562        mut cx: AsyncApp,
10563    ) -> Result<proto::Ack> {
10564        this.update(&mut cx, |lsp_store, cx| {
10565            let buffers =
10566                lsp_store.buffer_ids_to_buffers(envelope.payload.buffer_ids.into_iter(), cx);
10567            lsp_store.restart_language_servers_for_buffers(
10568                buffers,
10569                envelope
10570                    .payload
10571                    .only_servers
10572                    .into_iter()
10573                    .filter_map(|selector| {
10574                        Some(match selector.selector? {
10575                            proto::language_server_selector::Selector::ServerId(server_id) => {
10576                                LanguageServerSelector::Id(LanguageServerId::from_proto(server_id))
10577                            }
10578                            proto::language_server_selector::Selector::Name(name) => {
10579                                LanguageServerSelector::Name(LanguageServerName(
10580                                    SharedString::from(name),
10581                                ))
10582                            }
10583                        })
10584                    })
10585                    .collect(),
10586                cx,
10587            );
10588        });
10589
10590        Ok(proto::Ack {})
10591    }
10592
10593    pub async fn handle_stop_language_servers(
10594        lsp_store: Entity<Self>,
10595        envelope: TypedEnvelope<proto::StopLanguageServers>,
10596        mut cx: AsyncApp,
10597    ) -> Result<proto::Ack> {
10598        lsp_store.update(&mut cx, |lsp_store, cx| {
10599            if envelope.payload.all
10600                && envelope.payload.also_servers.is_empty()
10601                && envelope.payload.buffer_ids.is_empty()
10602            {
10603                lsp_store.stop_all_language_servers(cx);
10604            } else {
10605                let buffers =
10606                    lsp_store.buffer_ids_to_buffers(envelope.payload.buffer_ids.into_iter(), cx);
10607                lsp_store
10608                    .stop_language_servers_for_buffers(
10609                        buffers,
10610                        envelope
10611                            .payload
10612                            .also_servers
10613                            .into_iter()
10614                            .filter_map(|selector| {
10615                                Some(match selector.selector? {
10616                                    proto::language_server_selector::Selector::ServerId(
10617                                        server_id,
10618                                    ) => LanguageServerSelector::Id(LanguageServerId::from_proto(
10619                                        server_id,
10620                                    )),
10621                                    proto::language_server_selector::Selector::Name(name) => {
10622                                        LanguageServerSelector::Name(LanguageServerName(
10623                                            SharedString::from(name),
10624                                        ))
10625                                    }
10626                                })
10627                            })
10628                            .collect(),
10629                        cx,
10630                    )
10631                    .detach_and_log_err(cx);
10632            }
10633        });
10634
10635        Ok(proto::Ack {})
10636    }
10637
10638    pub async fn handle_cancel_language_server_work(
10639        lsp_store: Entity<Self>,
10640        envelope: TypedEnvelope<proto::CancelLanguageServerWork>,
10641        mut cx: AsyncApp,
10642    ) -> Result<proto::Ack> {
10643        lsp_store.update(&mut cx, |lsp_store, cx| {
10644            if let Some(work) = envelope.payload.work {
10645                match work {
10646                    proto::cancel_language_server_work::Work::Buffers(buffers) => {
10647                        let buffers =
10648                            lsp_store.buffer_ids_to_buffers(buffers.buffer_ids.into_iter(), cx);
10649                        lsp_store.cancel_language_server_work_for_buffers(buffers, cx);
10650                    }
10651                    proto::cancel_language_server_work::Work::LanguageServerWork(work) => {
10652                        let server_id = LanguageServerId::from_proto(work.language_server_id);
10653                        let token = work
10654                            .token
10655                            .map(|token| {
10656                                ProgressToken::from_proto(token)
10657                                    .context("invalid work progress token")
10658                            })
10659                            .transpose()?;
10660                        lsp_store.cancel_language_server_work(server_id, token, cx);
10661                    }
10662                }
10663            }
10664            anyhow::Ok(())
10665        })?;
10666
10667        Ok(proto::Ack {})
10668    }
10669
10670    fn buffer_ids_to_buffers(
10671        &mut self,
10672        buffer_ids: impl Iterator<Item = u64>,
10673        cx: &mut Context<Self>,
10674    ) -> Vec<Entity<Buffer>> {
10675        buffer_ids
10676            .into_iter()
10677            .flat_map(|buffer_id| {
10678                self.buffer_store
10679                    .read(cx)
10680                    .get(BufferId::new(buffer_id).log_err()?)
10681            })
10682            .collect::<Vec<_>>()
10683    }
10684
10685    async fn handle_apply_additional_edits_for_completion(
10686        this: Entity<Self>,
10687        envelope: TypedEnvelope<proto::ApplyCompletionAdditionalEdits>,
10688        mut cx: AsyncApp,
10689    ) -> Result<proto::ApplyCompletionAdditionalEditsResponse> {
10690        let (buffer, completion) = this.update(&mut cx, |this, cx| {
10691            let buffer_id = BufferId::new(envelope.payload.buffer_id)?;
10692            let buffer = this.buffer_store.read(cx).get_existing(buffer_id)?;
10693            let completion = Self::deserialize_completion(
10694                envelope.payload.completion.context("invalid completion")?,
10695            )?;
10696            anyhow::Ok((buffer, completion))
10697        })?;
10698
10699        let apply_additional_edits = this.update(&mut cx, |this, cx| {
10700            this.apply_additional_edits_for_completion(
10701                buffer,
10702                Rc::new(RefCell::new(Box::new([Completion {
10703                    replace_range: completion.replace_range,
10704                    new_text: completion.new_text,
10705                    source: completion.source,
10706                    documentation: None,
10707                    label: CodeLabel::default(),
10708                    match_start: None,
10709                    snippet_deduplication_key: None,
10710                    insert_text_mode: None,
10711                    icon_path: None,
10712                    confirm: None,
10713                }]))),
10714                0,
10715                false,
10716                cx,
10717            )
10718        });
10719
10720        Ok(proto::ApplyCompletionAdditionalEditsResponse {
10721            transaction: apply_additional_edits
10722                .await?
10723                .as_ref()
10724                .map(language::proto::serialize_transaction),
10725        })
10726    }
10727
10728    pub fn last_formatting_failure(&self) -> Option<&str> {
10729        self.last_formatting_failure.as_deref()
10730    }
10731
10732    pub fn reset_last_formatting_failure(&mut self) {
10733        self.last_formatting_failure = None;
10734    }
10735
10736    pub fn environment_for_buffer(
10737        &self,
10738        buffer: &Entity<Buffer>,
10739        cx: &mut Context<Self>,
10740    ) -> Shared<Task<Option<HashMap<String, String>>>> {
10741        if let Some(environment) = &self.as_local().map(|local| local.environment.clone()) {
10742            environment.update(cx, |env, cx| {
10743                env.buffer_environment(buffer, &self.worktree_store, cx)
10744            })
10745        } else {
10746            Task::ready(None).shared()
10747        }
10748    }
10749
10750    pub fn format(
10751        &mut self,
10752        buffers: HashSet<Entity<Buffer>>,
10753        target: LspFormatTarget,
10754        push_to_history: bool,
10755        trigger: FormatTrigger,
10756        cx: &mut Context<Self>,
10757    ) -> Task<anyhow::Result<ProjectTransaction>> {
10758        let logger = zlog::scoped!("format");
10759        if self.as_local().is_some() {
10760            zlog::trace!(logger => "Formatting locally");
10761            let logger = zlog::scoped!(logger => "local");
10762            let buffers = buffers
10763                .into_iter()
10764                .map(|buffer_handle| {
10765                    let buffer = buffer_handle.read(cx);
10766                    let buffer_abs_path = File::from_dyn(buffer.file())
10767                        .and_then(|file| file.as_local().map(|f| f.abs_path(cx)));
10768
10769                    (buffer_handle, buffer_abs_path, buffer.remote_id())
10770                })
10771                .collect::<Vec<_>>();
10772
10773            cx.spawn(async move |lsp_store, cx| {
10774                let mut formattable_buffers = Vec::with_capacity(buffers.len());
10775
10776                for (handle, abs_path, id) in buffers {
10777                    let env = lsp_store
10778                        .update(cx, |lsp_store, cx| {
10779                            lsp_store.environment_for_buffer(&handle, cx)
10780                        })?
10781                        .await;
10782
10783                    let ranges = match &target {
10784                        LspFormatTarget::Buffers => None,
10785                        LspFormatTarget::Ranges(ranges) => {
10786                            Some(ranges.get(&id).context("No format ranges provided for buffer")?.clone())
10787                        }
10788                    };
10789
10790                    formattable_buffers.push(FormattableBuffer {
10791                        handle,
10792                        abs_path,
10793                        env,
10794                        ranges,
10795                    });
10796                }
10797                zlog::trace!(logger => "Formatting {:?} buffers", formattable_buffers.len());
10798
10799                let format_timer = zlog::time!(logger => "Formatting buffers");
10800                let result = LocalLspStore::format_locally(
10801                    lsp_store.clone(),
10802                    formattable_buffers,
10803                    push_to_history,
10804                    trigger,
10805                    logger,
10806                    cx,
10807                )
10808                .await;
10809                format_timer.end();
10810
10811                zlog::trace!(logger => "Formatting completed with result {:?}", result.as_ref().map(|_| "<project-transaction>"));
10812
10813                lsp_store.update(cx, |lsp_store, _| {
10814                    lsp_store.update_last_formatting_failure(&result);
10815                })?;
10816
10817                result
10818            })
10819        } else if let Some((client, project_id)) = self.upstream_client() {
10820            zlog::trace!(logger => "Formatting remotely");
10821            let logger = zlog::scoped!(logger => "remote");
10822
10823            let buffer_ranges = match &target {
10824                LspFormatTarget::Buffers => Vec::new(),
10825                LspFormatTarget::Ranges(ranges) => ranges
10826                    .iter()
10827                    .map(|(buffer_id, ranges)| proto::BufferFormatRanges {
10828                        buffer_id: buffer_id.to_proto(),
10829                        ranges: ranges.iter().cloned().map(serialize_anchor_range).collect(),
10830                    })
10831                    .collect(),
10832            };
10833
10834            let buffer_store = self.buffer_store();
10835            cx.spawn(async move |lsp_store, cx| {
10836                zlog::trace!(logger => "Sending remote format request");
10837                let request_timer = zlog::time!(logger => "remote format request");
10838                let result = client
10839                    .request(proto::FormatBuffers {
10840                        project_id,
10841                        trigger: trigger as i32,
10842                        buffer_ids: buffers
10843                            .iter()
10844                            .map(|buffer| buffer.read_with(cx, |buffer, _| buffer.remote_id().to_proto()))
10845                            .collect(),
10846                        buffer_ranges,
10847                    })
10848                    .await
10849                    .and_then(|result| result.transaction.context("missing transaction"));
10850                request_timer.end();
10851
10852                zlog::trace!(logger => "Remote format request resolved to {:?}", result.as_ref().map(|_| "<project_transaction>"));
10853
10854                lsp_store.update(cx, |lsp_store, _| {
10855                    lsp_store.update_last_formatting_failure(&result);
10856                })?;
10857
10858                let transaction_response = result?;
10859                let _timer = zlog::time!(logger => "deserializing project transaction");
10860                buffer_store
10861                    .update(cx, |buffer_store, cx| {
10862                        buffer_store.deserialize_project_transaction(
10863                            transaction_response,
10864                            push_to_history,
10865                            cx,
10866                        )
10867                    })
10868                    .await
10869            })
10870        } else {
10871            zlog::trace!(logger => "Not formatting");
10872            Task::ready(Ok(ProjectTransaction::default()))
10873        }
10874    }
10875
10876    async fn handle_format_buffers(
10877        this: Entity<Self>,
10878        envelope: TypedEnvelope<proto::FormatBuffers>,
10879        mut cx: AsyncApp,
10880    ) -> Result<proto::FormatBuffersResponse> {
10881        let sender_id = envelope.original_sender_id().unwrap_or_default();
10882        let format = this.update(&mut cx, |this, cx| {
10883            let mut buffers = HashSet::default();
10884            for buffer_id in &envelope.payload.buffer_ids {
10885                let buffer_id = BufferId::new(*buffer_id)?;
10886                buffers.insert(this.buffer_store.read(cx).get_existing(buffer_id)?);
10887            }
10888
10889            let target = if envelope.payload.buffer_ranges.is_empty() {
10890                LspFormatTarget::Buffers
10891            } else {
10892                let mut ranges_map = BTreeMap::new();
10893                for buffer_range in &envelope.payload.buffer_ranges {
10894                    let buffer_id = BufferId::new(buffer_range.buffer_id)?;
10895                    let ranges: Result<Vec<_>> = buffer_range
10896                        .ranges
10897                        .iter()
10898                        .map(|range| {
10899                            deserialize_anchor_range(range.clone()).context("invalid anchor range")
10900                        })
10901                        .collect();
10902                    ranges_map.insert(buffer_id, ranges?);
10903                }
10904                LspFormatTarget::Ranges(ranges_map)
10905            };
10906
10907            let trigger = FormatTrigger::from_proto(envelope.payload.trigger);
10908            anyhow::Ok(this.format(buffers, target, false, trigger, cx))
10909        })?;
10910
10911        let project_transaction = format.await?;
10912        let project_transaction = this.update(&mut cx, |this, cx| {
10913            this.buffer_store.update(cx, |buffer_store, cx| {
10914                buffer_store.serialize_project_transaction_for_peer(
10915                    project_transaction,
10916                    sender_id,
10917                    cx,
10918                )
10919            })
10920        });
10921        Ok(proto::FormatBuffersResponse {
10922            transaction: Some(project_transaction),
10923        })
10924    }
10925
10926    async fn handle_apply_code_action_kind(
10927        this: Entity<Self>,
10928        envelope: TypedEnvelope<proto::ApplyCodeActionKind>,
10929        mut cx: AsyncApp,
10930    ) -> Result<proto::ApplyCodeActionKindResponse> {
10931        let sender_id = envelope.original_sender_id().unwrap_or_default();
10932        let format = this.update(&mut cx, |this, cx| {
10933            let mut buffers = HashSet::default();
10934            for buffer_id in &envelope.payload.buffer_ids {
10935                let buffer_id = BufferId::new(*buffer_id)?;
10936                buffers.insert(this.buffer_store.read(cx).get_existing(buffer_id)?);
10937            }
10938            let kind = match envelope.payload.kind.as_str() {
10939                "" => CodeActionKind::EMPTY,
10940                "quickfix" => CodeActionKind::QUICKFIX,
10941                "refactor" => CodeActionKind::REFACTOR,
10942                "refactor.extract" => CodeActionKind::REFACTOR_EXTRACT,
10943                "refactor.inline" => CodeActionKind::REFACTOR_INLINE,
10944                "refactor.rewrite" => CodeActionKind::REFACTOR_REWRITE,
10945                "source" => CodeActionKind::SOURCE,
10946                "source.organizeImports" => CodeActionKind::SOURCE_ORGANIZE_IMPORTS,
10947                "source.fixAll" => CodeActionKind::SOURCE_FIX_ALL,
10948                _ => anyhow::bail!(
10949                    "Invalid code action kind {}",
10950                    envelope.payload.kind.as_str()
10951                ),
10952            };
10953            anyhow::Ok(this.apply_code_action_kind(buffers, kind, false, cx))
10954        })?;
10955
10956        let project_transaction = format.await?;
10957        let project_transaction = this.update(&mut cx, |this, cx| {
10958            this.buffer_store.update(cx, |buffer_store, cx| {
10959                buffer_store.serialize_project_transaction_for_peer(
10960                    project_transaction,
10961                    sender_id,
10962                    cx,
10963                )
10964            })
10965        });
10966        Ok(proto::ApplyCodeActionKindResponse {
10967            transaction: Some(project_transaction),
10968        })
10969    }
10970
10971    async fn shutdown_language_server(
10972        server_state: Option<LanguageServerState>,
10973        name: LanguageServerName,
10974        cx: &mut AsyncApp,
10975    ) {
10976        let server = match server_state {
10977            Some(LanguageServerState::Starting { startup, .. }) => {
10978                let mut timer = cx
10979                    .background_executor()
10980                    .timer(SERVER_LAUNCHING_BEFORE_SHUTDOWN_TIMEOUT)
10981                    .fuse();
10982
10983                select! {
10984                    server = startup.fuse() => server,
10985                    () = timer => {
10986                        log::info!("timeout waiting for language server {name} to finish launching before stopping");
10987                        None
10988                    },
10989                }
10990            }
10991
10992            Some(LanguageServerState::Running { server, .. }) => Some(server),
10993
10994            None => None,
10995        };
10996
10997        if let Some(server) = server
10998            && let Some(shutdown) = server.shutdown()
10999        {
11000            shutdown.await;
11001        }
11002    }
11003
11004    // Returns a list of all of the worktrees which no longer have a language server and the root path
11005    // for the stopped server
11006    fn stop_local_language_server(
11007        &mut self,
11008        server_id: LanguageServerId,
11009        cx: &mut Context<Self>,
11010    ) -> Task<()> {
11011        let local = match &mut self.mode {
11012            LspStoreMode::Local(local) => local,
11013            _ => {
11014                return Task::ready(());
11015            }
11016        };
11017
11018        // Remove this server ID from all entries in the given worktree.
11019        local
11020            .language_server_ids
11021            .retain(|_, state| state.id != server_id);
11022        self.buffer_store.update(cx, |buffer_store, cx| {
11023            for buffer in buffer_store.buffers() {
11024                buffer.update(cx, |buffer, cx| {
11025                    buffer.update_diagnostics(server_id, DiagnosticSet::new([], buffer), cx);
11026                    buffer.set_completion_triggers(server_id, Default::default(), cx);
11027                });
11028            }
11029        });
11030
11031        for (worktree_id, summaries) in self.diagnostic_summaries.iter_mut() {
11032            summaries.retain(|path, summaries_by_server_id| {
11033                if summaries_by_server_id.remove(&server_id).is_some() {
11034                    if let Some((client, project_id)) = self.downstream_client.clone() {
11035                        client
11036                            .send(proto::UpdateDiagnosticSummary {
11037                                project_id,
11038                                worktree_id: worktree_id.to_proto(),
11039                                summary: Some(proto::DiagnosticSummary {
11040                                    path: path.as_ref().to_proto(),
11041                                    language_server_id: server_id.0 as u64,
11042                                    error_count: 0,
11043                                    warning_count: 0,
11044                                }),
11045                                more_summaries: Vec::new(),
11046                            })
11047                            .log_err();
11048                    }
11049                    !summaries_by_server_id.is_empty()
11050                } else {
11051                    true
11052                }
11053            });
11054        }
11055
11056        let local = self.as_local_mut().unwrap();
11057        for diagnostics in local.diagnostics.values_mut() {
11058            diagnostics.retain(|_, diagnostics_by_server_id| {
11059                if let Ok(ix) = diagnostics_by_server_id.binary_search_by_key(&server_id, |e| e.0) {
11060                    diagnostics_by_server_id.remove(ix);
11061                    !diagnostics_by_server_id.is_empty()
11062                } else {
11063                    true
11064                }
11065            });
11066        }
11067        local.language_server_watched_paths.remove(&server_id);
11068
11069        let server_state = local.language_servers.remove(&server_id);
11070        self.cleanup_lsp_data(server_id);
11071        let name = self
11072            .language_server_statuses
11073            .remove(&server_id)
11074            .map(|status| status.name)
11075            .or_else(|| {
11076                if let Some(LanguageServerState::Running { adapter, .. }) = server_state.as_ref() {
11077                    Some(adapter.name())
11078                } else {
11079                    None
11080                }
11081            });
11082
11083        if let Some(name) = name {
11084            log::info!("stopping language server {name}");
11085            self.languages
11086                .update_lsp_binary_status(name.clone(), BinaryStatus::Stopping);
11087            cx.notify();
11088
11089            return cx.spawn(async move |lsp_store, cx| {
11090                Self::shutdown_language_server(server_state, name.clone(), cx).await;
11091                lsp_store
11092                    .update(cx, |lsp_store, cx| {
11093                        lsp_store
11094                            .languages
11095                            .update_lsp_binary_status(name, BinaryStatus::Stopped);
11096                        cx.emit(LspStoreEvent::LanguageServerRemoved(server_id));
11097                        cx.notify();
11098                    })
11099                    .ok();
11100            });
11101        }
11102
11103        if server_state.is_some() {
11104            cx.emit(LspStoreEvent::LanguageServerRemoved(server_id));
11105        }
11106        Task::ready(())
11107    }
11108
11109    pub fn stop_all_language_servers(&mut self, cx: &mut Context<Self>) {
11110        self.shutdown_all_language_servers(cx).detach();
11111    }
11112
11113    pub fn shutdown_all_language_servers(&mut self, cx: &mut Context<Self>) -> Task<()> {
11114        if let Some((client, project_id)) = self.upstream_client() {
11115            let request = client.request(proto::StopLanguageServers {
11116                project_id,
11117                buffer_ids: Vec::new(),
11118                also_servers: Vec::new(),
11119                all: true,
11120            });
11121            cx.background_spawn(async move {
11122                request.await.ok();
11123            })
11124        } else {
11125            let Some(local) = self.as_local_mut() else {
11126                return Task::ready(());
11127            };
11128            let language_servers_to_stop = local
11129                .language_server_ids
11130                .values()
11131                .map(|state| state.id)
11132                .collect();
11133            local.lsp_tree.remove_nodes(&language_servers_to_stop);
11134            let tasks = language_servers_to_stop
11135                .into_iter()
11136                .map(|server| self.stop_local_language_server(server, cx))
11137                .collect::<Vec<_>>();
11138            cx.background_spawn(async move {
11139                futures::future::join_all(tasks).await;
11140            })
11141        }
11142    }
11143
11144    pub fn restart_language_servers_for_buffers(
11145        &mut self,
11146        buffers: Vec<Entity<Buffer>>,
11147        only_restart_servers: HashSet<LanguageServerSelector>,
11148        cx: &mut Context<Self>,
11149    ) {
11150        if let Some((client, project_id)) = self.upstream_client() {
11151            let request = client.request(proto::RestartLanguageServers {
11152                project_id,
11153                buffer_ids: buffers
11154                    .into_iter()
11155                    .map(|b| b.read(cx).remote_id().to_proto())
11156                    .collect(),
11157                only_servers: only_restart_servers
11158                    .into_iter()
11159                    .map(|selector| {
11160                        let selector = match selector {
11161                            LanguageServerSelector::Id(language_server_id) => {
11162                                proto::language_server_selector::Selector::ServerId(
11163                                    language_server_id.to_proto(),
11164                                )
11165                            }
11166                            LanguageServerSelector::Name(language_server_name) => {
11167                                proto::language_server_selector::Selector::Name(
11168                                    language_server_name.to_string(),
11169                                )
11170                            }
11171                        };
11172                        proto::LanguageServerSelector {
11173                            selector: Some(selector),
11174                        }
11175                    })
11176                    .collect(),
11177                all: false,
11178            });
11179            cx.background_spawn(request).detach_and_log_err(cx);
11180        } else {
11181            let stop_task = if only_restart_servers.is_empty() {
11182                self.stop_local_language_servers_for_buffers(&buffers, HashSet::default(), cx)
11183            } else {
11184                self.stop_local_language_servers_for_buffers(&[], only_restart_servers.clone(), cx)
11185            };
11186            cx.spawn(async move |lsp_store, cx| {
11187                stop_task.await;
11188                lsp_store.update(cx, |lsp_store, cx| {
11189                    for buffer in buffers {
11190                        lsp_store.register_buffer_with_language_servers(
11191                            &buffer,
11192                            only_restart_servers.clone(),
11193                            true,
11194                            cx,
11195                        );
11196                    }
11197                })
11198            })
11199            .detach();
11200        }
11201    }
11202
11203    pub fn stop_language_servers_for_buffers(
11204        &mut self,
11205        buffers: Vec<Entity<Buffer>>,
11206        also_stop_servers: HashSet<LanguageServerSelector>,
11207        cx: &mut Context<Self>,
11208    ) -> Task<Result<()>> {
11209        if let Some((client, project_id)) = self.upstream_client() {
11210            let request = client.request(proto::StopLanguageServers {
11211                project_id,
11212                buffer_ids: buffers
11213                    .into_iter()
11214                    .map(|b| b.read(cx).remote_id().to_proto())
11215                    .collect(),
11216                also_servers: also_stop_servers
11217                    .into_iter()
11218                    .map(|selector| {
11219                        let selector = match selector {
11220                            LanguageServerSelector::Id(language_server_id) => {
11221                                proto::language_server_selector::Selector::ServerId(
11222                                    language_server_id.to_proto(),
11223                                )
11224                            }
11225                            LanguageServerSelector::Name(language_server_name) => {
11226                                proto::language_server_selector::Selector::Name(
11227                                    language_server_name.to_string(),
11228                                )
11229                            }
11230                        };
11231                        proto::LanguageServerSelector {
11232                            selector: Some(selector),
11233                        }
11234                    })
11235                    .collect(),
11236                all: false,
11237            });
11238            cx.background_spawn(async move {
11239                let _ = request.await?;
11240                Ok(())
11241            })
11242        } else {
11243            let task =
11244                self.stop_local_language_servers_for_buffers(&buffers, also_stop_servers, cx);
11245            cx.background_spawn(async move {
11246                task.await;
11247                Ok(())
11248            })
11249        }
11250    }
11251
11252    fn stop_local_language_servers_for_buffers(
11253        &mut self,
11254        buffers: &[Entity<Buffer>],
11255        also_stop_servers: HashSet<LanguageServerSelector>,
11256        cx: &mut Context<Self>,
11257    ) -> Task<()> {
11258        let Some(local) = self.as_local_mut() else {
11259            return Task::ready(());
11260        };
11261        let mut language_server_names_to_stop = BTreeSet::default();
11262        let mut language_servers_to_stop = also_stop_servers
11263            .into_iter()
11264            .flat_map(|selector| match selector {
11265                LanguageServerSelector::Id(id) => Some(id),
11266                LanguageServerSelector::Name(name) => {
11267                    language_server_names_to_stop.insert(name);
11268                    None
11269                }
11270            })
11271            .collect::<BTreeSet<_>>();
11272
11273        let mut covered_worktrees = HashSet::default();
11274        for buffer in buffers {
11275            buffer.update(cx, |buffer, cx| {
11276                language_servers_to_stop.extend(local.language_server_ids_for_buffer(buffer, cx));
11277                if let Some(worktree_id) = buffer.file().map(|f| f.worktree_id(cx))
11278                    && covered_worktrees.insert(worktree_id)
11279                {
11280                    language_server_names_to_stop.retain(|name| {
11281                        let old_ids_count = language_servers_to_stop.len();
11282                        let all_language_servers_with_this_name = local
11283                            .language_server_ids
11284                            .iter()
11285                            .filter_map(|(seed, state)| seed.name.eq(name).then(|| state.id));
11286                        language_servers_to_stop.extend(all_language_servers_with_this_name);
11287                        old_ids_count == language_servers_to_stop.len()
11288                    });
11289                }
11290            });
11291        }
11292        for name in language_server_names_to_stop {
11293            language_servers_to_stop.extend(
11294                local
11295                    .language_server_ids
11296                    .iter()
11297                    .filter_map(|(seed, v)| seed.name.eq(&name).then(|| v.id)),
11298            );
11299        }
11300
11301        local.lsp_tree.remove_nodes(&language_servers_to_stop);
11302        let tasks = language_servers_to_stop
11303            .into_iter()
11304            .map(|server| self.stop_local_language_server(server, cx))
11305            .collect::<Vec<_>>();
11306
11307        cx.background_spawn(futures::future::join_all(tasks).map(|_| ()))
11308    }
11309
11310    fn get_buffer<'a>(&self, abs_path: &Path, cx: &'a App) -> Option<&'a Buffer> {
11311        let (worktree, relative_path) =
11312            self.worktree_store.read(cx).find_worktree(&abs_path, cx)?;
11313
11314        let project_path = ProjectPath {
11315            worktree_id: worktree.read(cx).id(),
11316            path: relative_path,
11317        };
11318
11319        Some(
11320            self.buffer_store()
11321                .read(cx)
11322                .get_by_path(&project_path)?
11323                .read(cx),
11324        )
11325    }
11326
11327    #[cfg(any(test, feature = "test-support"))]
11328    pub fn update_diagnostics(
11329        &mut self,
11330        server_id: LanguageServerId,
11331        diagnostics: lsp::PublishDiagnosticsParams,
11332        result_id: Option<SharedString>,
11333        source_kind: DiagnosticSourceKind,
11334        disk_based_sources: &[String],
11335        cx: &mut Context<Self>,
11336    ) -> Result<()> {
11337        self.merge_lsp_diagnostics(
11338            source_kind,
11339            vec![DocumentDiagnosticsUpdate {
11340                diagnostics,
11341                result_id,
11342                server_id,
11343                disk_based_sources: Cow::Borrowed(disk_based_sources),
11344                registration_id: None,
11345            }],
11346            |_, _, _| false,
11347            cx,
11348        )
11349    }
11350
11351    pub fn merge_lsp_diagnostics(
11352        &mut self,
11353        source_kind: DiagnosticSourceKind,
11354        lsp_diagnostics: Vec<DocumentDiagnosticsUpdate<lsp::PublishDiagnosticsParams>>,
11355        merge: impl Fn(&lsp::Uri, &Diagnostic, &App) -> bool + Clone,
11356        cx: &mut Context<Self>,
11357    ) -> Result<()> {
11358        anyhow::ensure!(self.mode.is_local(), "called update_diagnostics on remote");
11359        let updates = lsp_diagnostics
11360            .into_iter()
11361            .filter_map(|update| {
11362                let abs_path = update.diagnostics.uri.to_file_path().ok()?;
11363                Some(DocumentDiagnosticsUpdate {
11364                    diagnostics: self.lsp_to_document_diagnostics(
11365                        abs_path,
11366                        source_kind,
11367                        update.server_id,
11368                        update.diagnostics,
11369                        &update.disk_based_sources,
11370                        update.registration_id.clone(),
11371                    ),
11372                    result_id: update.result_id,
11373                    server_id: update.server_id,
11374                    disk_based_sources: update.disk_based_sources,
11375                    registration_id: update.registration_id,
11376                })
11377            })
11378            .collect();
11379        self.merge_diagnostic_entries(updates, merge, cx)?;
11380        Ok(())
11381    }
11382
11383    fn lsp_to_document_diagnostics(
11384        &mut self,
11385        document_abs_path: PathBuf,
11386        source_kind: DiagnosticSourceKind,
11387        server_id: LanguageServerId,
11388        mut lsp_diagnostics: lsp::PublishDiagnosticsParams,
11389        disk_based_sources: &[String],
11390        registration_id: Option<SharedString>,
11391    ) -> DocumentDiagnostics {
11392        let mut diagnostics = Vec::default();
11393        let mut primary_diagnostic_group_ids = HashMap::default();
11394        let mut sources_by_group_id = HashMap::default();
11395        let mut supporting_diagnostics = HashMap::default();
11396
11397        let adapter = self.language_server_adapter_for_id(server_id);
11398
11399        // Ensure that primary diagnostics are always the most severe
11400        lsp_diagnostics
11401            .diagnostics
11402            .sort_by_key(|item| item.severity);
11403
11404        for diagnostic in &lsp_diagnostics.diagnostics {
11405            let source = diagnostic.source.as_ref();
11406            let range = range_from_lsp(diagnostic.range);
11407            let is_supporting = diagnostic
11408                .related_information
11409                .as_ref()
11410                .is_some_and(|infos| {
11411                    infos.iter().any(|info| {
11412                        primary_diagnostic_group_ids.contains_key(&(
11413                            source,
11414                            diagnostic.code.clone(),
11415                            range_from_lsp(info.location.range),
11416                        ))
11417                    })
11418                });
11419
11420            let is_unnecessary = diagnostic
11421                .tags
11422                .as_ref()
11423                .is_some_and(|tags| tags.contains(&DiagnosticTag::UNNECESSARY));
11424
11425            let underline = self
11426                .language_server_adapter_for_id(server_id)
11427                .is_none_or(|adapter| adapter.underline_diagnostic(diagnostic));
11428
11429            if is_supporting {
11430                supporting_diagnostics.insert(
11431                    (source, diagnostic.code.clone(), range),
11432                    (diagnostic.severity, is_unnecessary),
11433                );
11434            } else {
11435                let group_id = post_inc(&mut self.as_local_mut().unwrap().next_diagnostic_group_id);
11436                let is_disk_based =
11437                    source.is_some_and(|source| disk_based_sources.contains(source));
11438
11439                sources_by_group_id.insert(group_id, source);
11440                primary_diagnostic_group_ids
11441                    .insert((source, diagnostic.code.clone(), range.clone()), group_id);
11442
11443                diagnostics.push(DiagnosticEntry {
11444                    range,
11445                    diagnostic: Diagnostic {
11446                        source: diagnostic.source.clone(),
11447                        source_kind,
11448                        code: diagnostic.code.clone(),
11449                        code_description: diagnostic
11450                            .code_description
11451                            .as_ref()
11452                            .and_then(|d| d.href.clone()),
11453                        severity: diagnostic.severity.unwrap_or(DiagnosticSeverity::ERROR),
11454                        markdown: adapter.as_ref().and_then(|adapter| {
11455                            adapter.diagnostic_message_to_markdown(&diagnostic.message)
11456                        }),
11457                        message: diagnostic.message.trim().to_string(),
11458                        group_id,
11459                        is_primary: true,
11460                        is_disk_based,
11461                        is_unnecessary,
11462                        underline,
11463                        data: diagnostic.data.clone(),
11464                        registration_id: registration_id.clone(),
11465                    },
11466                });
11467                if let Some(infos) = &diagnostic.related_information {
11468                    for info in infos {
11469                        if info.location.uri == lsp_diagnostics.uri && !info.message.is_empty() {
11470                            let range = range_from_lsp(info.location.range);
11471                            diagnostics.push(DiagnosticEntry {
11472                                range,
11473                                diagnostic: Diagnostic {
11474                                    source: diagnostic.source.clone(),
11475                                    source_kind,
11476                                    code: diagnostic.code.clone(),
11477                                    code_description: diagnostic
11478                                        .code_description
11479                                        .as_ref()
11480                                        .and_then(|d| d.href.clone()),
11481                                    severity: DiagnosticSeverity::INFORMATION,
11482                                    markdown: adapter.as_ref().and_then(|adapter| {
11483                                        adapter.diagnostic_message_to_markdown(&info.message)
11484                                    }),
11485                                    message: info.message.trim().to_string(),
11486                                    group_id,
11487                                    is_primary: false,
11488                                    is_disk_based,
11489                                    is_unnecessary: false,
11490                                    underline,
11491                                    data: diagnostic.data.clone(),
11492                                    registration_id: registration_id.clone(),
11493                                },
11494                            });
11495                        }
11496                    }
11497                }
11498            }
11499        }
11500
11501        for entry in &mut diagnostics {
11502            let diagnostic = &mut entry.diagnostic;
11503            if !diagnostic.is_primary {
11504                let source = *sources_by_group_id.get(&diagnostic.group_id).unwrap();
11505                if let Some(&(severity, is_unnecessary)) = supporting_diagnostics.get(&(
11506                    source,
11507                    diagnostic.code.clone(),
11508                    entry.range.clone(),
11509                )) {
11510                    if let Some(severity) = severity {
11511                        diagnostic.severity = severity;
11512                    }
11513                    diagnostic.is_unnecessary = is_unnecessary;
11514                }
11515            }
11516        }
11517
11518        DocumentDiagnostics {
11519            diagnostics,
11520            document_abs_path,
11521            version: lsp_diagnostics.version,
11522        }
11523    }
11524
11525    fn insert_newly_running_language_server(
11526        &mut self,
11527        adapter: Arc<CachedLspAdapter>,
11528        language_server: Arc<LanguageServer>,
11529        server_id: LanguageServerId,
11530        key: LanguageServerSeed,
11531        workspace_folders: Arc<Mutex<BTreeSet<Uri>>>,
11532        cx: &mut Context<Self>,
11533    ) {
11534        let Some(local) = self.as_local_mut() else {
11535            return;
11536        };
11537        // If the language server for this key doesn't match the server id, don't store the
11538        // server. Which will cause it to be dropped, killing the process
11539        if local
11540            .language_server_ids
11541            .get(&key)
11542            .map(|state| state.id != server_id)
11543            .unwrap_or(false)
11544        {
11545            return;
11546        }
11547
11548        // Update language_servers collection with Running variant of LanguageServerState
11549        // indicating that the server is up and running and ready
11550        let workspace_folders = workspace_folders.lock().clone();
11551        language_server.set_workspace_folders(workspace_folders);
11552
11553        let workspace_diagnostics_refresh_tasks = language_server
11554            .capabilities()
11555            .diagnostic_provider
11556            .and_then(|provider| {
11557                local
11558                    .language_server_dynamic_registrations
11559                    .entry(server_id)
11560                    .or_default()
11561                    .diagnostics
11562                    .entry(None)
11563                    .or_insert(provider.clone());
11564                let workspace_refresher =
11565                    lsp_workspace_diagnostics_refresh(None, provider, language_server.clone(), cx)?;
11566
11567                Some((None, workspace_refresher))
11568            })
11569            .into_iter()
11570            .collect();
11571        local.language_servers.insert(
11572            server_id,
11573            LanguageServerState::Running {
11574                workspace_diagnostics_refresh_tasks,
11575                adapter: adapter.clone(),
11576                server: language_server.clone(),
11577                simulate_disk_based_diagnostics_completion: None,
11578            },
11579        );
11580        local
11581            .languages
11582            .update_lsp_binary_status(adapter.name(), BinaryStatus::None);
11583        if let Some(file_ops_caps) = language_server
11584            .capabilities()
11585            .workspace
11586            .as_ref()
11587            .and_then(|ws| ws.file_operations.as_ref())
11588        {
11589            let did_rename_caps = file_ops_caps.did_rename.as_ref();
11590            let will_rename_caps = file_ops_caps.will_rename.as_ref();
11591            if did_rename_caps.or(will_rename_caps).is_some() {
11592                let watcher = RenamePathsWatchedForServer::default()
11593                    .with_did_rename_patterns(did_rename_caps)
11594                    .with_will_rename_patterns(will_rename_caps);
11595                local
11596                    .language_server_paths_watched_for_rename
11597                    .insert(server_id, watcher);
11598            }
11599        }
11600
11601        self.language_server_statuses.insert(
11602            server_id,
11603            LanguageServerStatus {
11604                name: language_server.name(),
11605                server_version: language_server.version(),
11606                pending_work: Default::default(),
11607                has_pending_diagnostic_updates: false,
11608                progress_tokens: Default::default(),
11609                worktree: Some(key.worktree_id),
11610                binary: Some(language_server.binary().clone()),
11611                configuration: Some(language_server.configuration().clone()),
11612                workspace_folders: language_server.workspace_folders(),
11613            },
11614        );
11615
11616        cx.emit(LspStoreEvent::LanguageServerAdded(
11617            server_id,
11618            language_server.name(),
11619            Some(key.worktree_id),
11620        ));
11621
11622        let server_capabilities = language_server.capabilities();
11623        if let Some((downstream_client, project_id)) = self.downstream_client.as_ref() {
11624            downstream_client
11625                .send(proto::StartLanguageServer {
11626                    project_id: *project_id,
11627                    server: Some(proto::LanguageServer {
11628                        id: server_id.to_proto(),
11629                        name: language_server.name().to_string(),
11630                        worktree_id: Some(key.worktree_id.to_proto()),
11631                    }),
11632                    capabilities: serde_json::to_string(&server_capabilities)
11633                        .expect("serializing server LSP capabilities"),
11634                })
11635                .log_err();
11636        }
11637        self.lsp_server_capabilities
11638            .insert(server_id, server_capabilities);
11639
11640        // Tell the language server about every open buffer in the worktree that matches the language.
11641        // Also check for buffers in worktrees that reused this server
11642        let mut worktrees_using_server = vec![key.worktree_id];
11643        if let Some(local) = self.as_local() {
11644            // Find all worktrees that have this server in their language server tree
11645            for (worktree_id, servers) in &local.lsp_tree.instances {
11646                if *worktree_id != key.worktree_id {
11647                    for server_map in servers.roots.values() {
11648                        if server_map
11649                            .values()
11650                            .any(|(node, _)| node.id() == Some(server_id))
11651                        {
11652                            worktrees_using_server.push(*worktree_id);
11653                        }
11654                    }
11655                }
11656            }
11657        }
11658
11659        let mut buffer_paths_registered = Vec::new();
11660        self.buffer_store.clone().update(cx, |buffer_store, cx| {
11661            let mut lsp_adapters = HashMap::default();
11662            for buffer_handle in buffer_store.buffers() {
11663                let buffer = buffer_handle.read(cx);
11664                let file = match File::from_dyn(buffer.file()) {
11665                    Some(file) => file,
11666                    None => continue,
11667                };
11668                let language = match buffer.language() {
11669                    Some(language) => language,
11670                    None => continue,
11671                };
11672
11673                if !worktrees_using_server.contains(&file.worktree.read(cx).id())
11674                    || !lsp_adapters
11675                        .entry(language.name())
11676                        .or_insert_with(|| self.languages.lsp_adapters(&language.name()))
11677                        .iter()
11678                        .any(|a| a.name == key.name)
11679                {
11680                    continue;
11681                }
11682                // didOpen
11683                let file = match file.as_local() {
11684                    Some(file) => file,
11685                    None => continue,
11686                };
11687
11688                let local = self.as_local_mut().unwrap();
11689
11690                let buffer_id = buffer.remote_id();
11691                if local.registered_buffers.contains_key(&buffer_id) {
11692                    let versions = local
11693                        .buffer_snapshots
11694                        .entry(buffer_id)
11695                        .or_default()
11696                        .entry(server_id)
11697                        .and_modify(|_| {
11698                            assert!(
11699                            false,
11700                            "There should not be an existing snapshot for a newly inserted buffer"
11701                        )
11702                        })
11703                        .or_insert_with(|| {
11704                            vec![LspBufferSnapshot {
11705                                version: 0,
11706                                snapshot: buffer.text_snapshot(),
11707                            }]
11708                        });
11709
11710                    let snapshot = versions.last().unwrap();
11711                    let version = snapshot.version;
11712                    let initial_snapshot = &snapshot.snapshot;
11713                    let uri = lsp::Uri::from_file_path(file.abs_path(cx)).unwrap();
11714                    language_server.register_buffer(
11715                        uri,
11716                        adapter.language_id(&language.name()),
11717                        version,
11718                        initial_snapshot.text(),
11719                    );
11720                    buffer_paths_registered.push((buffer_id, file.abs_path(cx)));
11721                    local
11722                        .buffers_opened_in_servers
11723                        .entry(buffer_id)
11724                        .or_default()
11725                        .insert(server_id);
11726                }
11727                buffer_handle.update(cx, |buffer, cx| {
11728                    buffer.set_completion_triggers(
11729                        server_id,
11730                        language_server
11731                            .capabilities()
11732                            .completion_provider
11733                            .as_ref()
11734                            .and_then(|provider| {
11735                                provider
11736                                    .trigger_characters
11737                                    .as_ref()
11738                                    .map(|characters| characters.iter().cloned().collect())
11739                            })
11740                            .unwrap_or_default(),
11741                        cx,
11742                    )
11743                });
11744            }
11745        });
11746
11747        for (buffer_id, abs_path) in buffer_paths_registered {
11748            cx.emit(LspStoreEvent::LanguageServerUpdate {
11749                language_server_id: server_id,
11750                name: Some(adapter.name()),
11751                message: proto::update_language_server::Variant::RegisteredForBuffer(
11752                    proto::RegisteredForBuffer {
11753                        buffer_abs_path: abs_path.to_string_lossy().into_owned(),
11754                        buffer_id: buffer_id.to_proto(),
11755                    },
11756                ),
11757            });
11758        }
11759
11760        cx.notify();
11761    }
11762
11763    pub fn language_servers_running_disk_based_diagnostics(
11764        &self,
11765    ) -> impl Iterator<Item = LanguageServerId> + '_ {
11766        self.language_server_statuses
11767            .iter()
11768            .filter_map(|(id, status)| {
11769                if status.has_pending_diagnostic_updates {
11770                    Some(*id)
11771                } else {
11772                    None
11773                }
11774            })
11775    }
11776
11777    pub(crate) fn cancel_language_server_work_for_buffers(
11778        &mut self,
11779        buffers: impl IntoIterator<Item = Entity<Buffer>>,
11780        cx: &mut Context<Self>,
11781    ) {
11782        if let Some((client, project_id)) = self.upstream_client() {
11783            let request = client.request(proto::CancelLanguageServerWork {
11784                project_id,
11785                work: Some(proto::cancel_language_server_work::Work::Buffers(
11786                    proto::cancel_language_server_work::Buffers {
11787                        buffer_ids: buffers
11788                            .into_iter()
11789                            .map(|b| b.read(cx).remote_id().to_proto())
11790                            .collect(),
11791                    },
11792                )),
11793            });
11794            cx.background_spawn(request).detach_and_log_err(cx);
11795        } else if let Some(local) = self.as_local() {
11796            let servers = buffers
11797                .into_iter()
11798                .flat_map(|buffer| {
11799                    buffer.update(cx, |buffer, cx| {
11800                        local.language_server_ids_for_buffer(buffer, cx).into_iter()
11801                    })
11802                })
11803                .collect::<HashSet<_>>();
11804            for server_id in servers {
11805                self.cancel_language_server_work(server_id, None, cx);
11806            }
11807        }
11808    }
11809
11810    pub(crate) fn cancel_language_server_work(
11811        &mut self,
11812        server_id: LanguageServerId,
11813        token_to_cancel: Option<ProgressToken>,
11814        cx: &mut Context<Self>,
11815    ) {
11816        if let Some(local) = self.as_local() {
11817            let status = self.language_server_statuses.get(&server_id);
11818            let server = local.language_servers.get(&server_id);
11819            if let Some((LanguageServerState::Running { server, .. }, status)) = server.zip(status)
11820            {
11821                for (token, progress) in &status.pending_work {
11822                    if let Some(token_to_cancel) = token_to_cancel.as_ref()
11823                        && token != token_to_cancel
11824                    {
11825                        continue;
11826                    }
11827                    if progress.is_cancellable {
11828                        server
11829                            .notify::<lsp::notification::WorkDoneProgressCancel>(
11830                                WorkDoneProgressCancelParams {
11831                                    token: token.to_lsp(),
11832                                },
11833                            )
11834                            .ok();
11835                    }
11836                }
11837            }
11838        } else if let Some((client, project_id)) = self.upstream_client() {
11839            let request = client.request(proto::CancelLanguageServerWork {
11840                project_id,
11841                work: Some(
11842                    proto::cancel_language_server_work::Work::LanguageServerWork(
11843                        proto::cancel_language_server_work::LanguageServerWork {
11844                            language_server_id: server_id.to_proto(),
11845                            token: token_to_cancel.map(|token| token.to_proto()),
11846                        },
11847                    ),
11848                ),
11849            });
11850            cx.background_spawn(request).detach_and_log_err(cx);
11851        }
11852    }
11853
11854    fn register_supplementary_language_server(
11855        &mut self,
11856        id: LanguageServerId,
11857        name: LanguageServerName,
11858        server: Arc<LanguageServer>,
11859        cx: &mut Context<Self>,
11860    ) {
11861        if let Some(local) = self.as_local_mut() {
11862            local
11863                .supplementary_language_servers
11864                .insert(id, (name.clone(), server));
11865            cx.emit(LspStoreEvent::LanguageServerAdded(id, name, None));
11866        }
11867    }
11868
11869    fn unregister_supplementary_language_server(
11870        &mut self,
11871        id: LanguageServerId,
11872        cx: &mut Context<Self>,
11873    ) {
11874        if let Some(local) = self.as_local_mut() {
11875            local.supplementary_language_servers.remove(&id);
11876            cx.emit(LspStoreEvent::LanguageServerRemoved(id));
11877        }
11878    }
11879
11880    pub(crate) fn supplementary_language_servers(
11881        &self,
11882    ) -> impl '_ + Iterator<Item = (LanguageServerId, LanguageServerName)> {
11883        self.as_local().into_iter().flat_map(|local| {
11884            local
11885                .supplementary_language_servers
11886                .iter()
11887                .map(|(id, (name, _))| (*id, name.clone()))
11888        })
11889    }
11890
11891    pub fn language_server_adapter_for_id(
11892        &self,
11893        id: LanguageServerId,
11894    ) -> Option<Arc<CachedLspAdapter>> {
11895        self.as_local()
11896            .and_then(|local| local.language_servers.get(&id))
11897            .and_then(|language_server_state| match language_server_state {
11898                LanguageServerState::Running { adapter, .. } => Some(adapter.clone()),
11899                _ => None,
11900            })
11901    }
11902
11903    pub(super) fn update_local_worktree_language_servers(
11904        &mut self,
11905        worktree_handle: &Entity<Worktree>,
11906        changes: &[(Arc<RelPath>, ProjectEntryId, PathChange)],
11907        cx: &mut Context<Self>,
11908    ) {
11909        if changes.is_empty() {
11910            return;
11911        }
11912
11913        let Some(local) = self.as_local() else { return };
11914
11915        local.prettier_store.update(cx, |prettier_store, cx| {
11916            prettier_store.update_prettier_settings(worktree_handle, changes, cx)
11917        });
11918
11919        let worktree_id = worktree_handle.read(cx).id();
11920        let mut language_server_ids = local
11921            .language_server_ids
11922            .iter()
11923            .filter_map(|(seed, v)| seed.worktree_id.eq(&worktree_id).then(|| v.id))
11924            .collect::<Vec<_>>();
11925        language_server_ids.sort();
11926        language_server_ids.dedup();
11927
11928        // let abs_path = worktree_handle.read(cx).abs_path();
11929        for server_id in &language_server_ids {
11930            if let Some(LanguageServerState::Running { server, .. }) =
11931                local.language_servers.get(server_id)
11932                && let Some(watched_paths) = local
11933                    .language_server_watched_paths
11934                    .get(server_id)
11935                    .and_then(|paths| paths.worktree_paths.get(&worktree_id))
11936            {
11937                let params = lsp::DidChangeWatchedFilesParams {
11938                    changes: changes
11939                        .iter()
11940                        .filter_map(|(path, _, change)| {
11941                            if !watched_paths.is_match(path.as_std_path()) {
11942                                return None;
11943                            }
11944                            let typ = match change {
11945                                PathChange::Loaded => return None,
11946                                PathChange::Added => lsp::FileChangeType::CREATED,
11947                                PathChange::Removed => lsp::FileChangeType::DELETED,
11948                                PathChange::Updated => lsp::FileChangeType::CHANGED,
11949                                PathChange::AddedOrUpdated => lsp::FileChangeType::CHANGED,
11950                            };
11951                            let uri = lsp::Uri::from_file_path(
11952                                worktree_handle.read(cx).absolutize(&path),
11953                            )
11954                            .ok()?;
11955                            Some(lsp::FileEvent { uri, typ })
11956                        })
11957                        .collect(),
11958                };
11959                if !params.changes.is_empty() {
11960                    server
11961                        .notify::<lsp::notification::DidChangeWatchedFiles>(params)
11962                        .ok();
11963                }
11964            }
11965        }
11966        for (path, _, _) in changes {
11967            if let Some(file_name) = path.file_name()
11968                && local.watched_manifest_filenames.contains(file_name)
11969            {
11970                self.request_workspace_config_refresh();
11971                break;
11972            }
11973        }
11974    }
11975
11976    pub fn wait_for_remote_buffer(
11977        &mut self,
11978        id: BufferId,
11979        cx: &mut Context<Self>,
11980    ) -> Task<Result<Entity<Buffer>>> {
11981        self.buffer_store.update(cx, |buffer_store, cx| {
11982            buffer_store.wait_for_remote_buffer(id, cx)
11983        })
11984    }
11985
11986    fn serialize_symbol(symbol: &Symbol) -> proto::Symbol {
11987        let mut result = proto::Symbol {
11988            language_server_name: symbol.language_server_name.0.to_string(),
11989            source_worktree_id: symbol.source_worktree_id.to_proto(),
11990            language_server_id: symbol.source_language_server_id.to_proto(),
11991            name: symbol.name.clone(),
11992            kind: unsafe { mem::transmute::<lsp::SymbolKind, i32>(symbol.kind) },
11993            start: Some(proto::PointUtf16 {
11994                row: symbol.range.start.0.row,
11995                column: symbol.range.start.0.column,
11996            }),
11997            end: Some(proto::PointUtf16 {
11998                row: symbol.range.end.0.row,
11999                column: symbol.range.end.0.column,
12000            }),
12001            worktree_id: Default::default(),
12002            path: Default::default(),
12003            signature: Default::default(),
12004        };
12005        match &symbol.path {
12006            SymbolLocation::InProject(path) => {
12007                result.worktree_id = path.worktree_id.to_proto();
12008                result.path = path.path.to_proto();
12009            }
12010            SymbolLocation::OutsideProject {
12011                abs_path,
12012                signature,
12013            } => {
12014                result.path = abs_path.to_string_lossy().into_owned();
12015                result.signature = signature.to_vec();
12016            }
12017        }
12018        result
12019    }
12020
12021    fn deserialize_symbol(serialized_symbol: proto::Symbol) -> Result<CoreSymbol> {
12022        let source_worktree_id = WorktreeId::from_proto(serialized_symbol.source_worktree_id);
12023        let worktree_id = WorktreeId::from_proto(serialized_symbol.worktree_id);
12024        let kind = unsafe { mem::transmute::<i32, lsp::SymbolKind>(serialized_symbol.kind) };
12025
12026        let path = if serialized_symbol.signature.is_empty() {
12027            SymbolLocation::InProject(ProjectPath {
12028                worktree_id,
12029                path: RelPath::from_proto(&serialized_symbol.path)
12030                    .context("invalid symbol path")?,
12031            })
12032        } else {
12033            SymbolLocation::OutsideProject {
12034                abs_path: Path::new(&serialized_symbol.path).into(),
12035                signature: serialized_symbol
12036                    .signature
12037                    .try_into()
12038                    .map_err(|_| anyhow!("invalid signature"))?,
12039            }
12040        };
12041
12042        let start = serialized_symbol.start.context("invalid start")?;
12043        let end = serialized_symbol.end.context("invalid end")?;
12044        Ok(CoreSymbol {
12045            language_server_name: LanguageServerName(serialized_symbol.language_server_name.into()),
12046            source_worktree_id,
12047            source_language_server_id: LanguageServerId::from_proto(
12048                serialized_symbol.language_server_id,
12049            ),
12050            path,
12051            name: serialized_symbol.name,
12052            range: Unclipped(PointUtf16::new(start.row, start.column))
12053                ..Unclipped(PointUtf16::new(end.row, end.column)),
12054            kind,
12055        })
12056    }
12057
12058    pub(crate) fn serialize_completion(completion: &CoreCompletion) -> proto::Completion {
12059        let mut serialized_completion = proto::Completion {
12060            old_replace_start: Some(serialize_anchor(&completion.replace_range.start)),
12061            old_replace_end: Some(serialize_anchor(&completion.replace_range.end)),
12062            new_text: completion.new_text.clone(),
12063            ..proto::Completion::default()
12064        };
12065        match &completion.source {
12066            CompletionSource::Lsp {
12067                insert_range,
12068                server_id,
12069                lsp_completion,
12070                lsp_defaults,
12071                resolved,
12072            } => {
12073                let (old_insert_start, old_insert_end) = insert_range
12074                    .as_ref()
12075                    .map(|range| (serialize_anchor(&range.start), serialize_anchor(&range.end)))
12076                    .unzip();
12077
12078                serialized_completion.old_insert_start = old_insert_start;
12079                serialized_completion.old_insert_end = old_insert_end;
12080                serialized_completion.source = proto::completion::Source::Lsp as i32;
12081                serialized_completion.server_id = server_id.0 as u64;
12082                serialized_completion.lsp_completion = serde_json::to_vec(lsp_completion).unwrap();
12083                serialized_completion.lsp_defaults = lsp_defaults
12084                    .as_deref()
12085                    .map(|lsp_defaults| serde_json::to_vec(lsp_defaults).unwrap());
12086                serialized_completion.resolved = *resolved;
12087            }
12088            CompletionSource::BufferWord {
12089                word_range,
12090                resolved,
12091            } => {
12092                serialized_completion.source = proto::completion::Source::BufferWord as i32;
12093                serialized_completion.buffer_word_start = Some(serialize_anchor(&word_range.start));
12094                serialized_completion.buffer_word_end = Some(serialize_anchor(&word_range.end));
12095                serialized_completion.resolved = *resolved;
12096            }
12097            CompletionSource::Custom => {
12098                serialized_completion.source = proto::completion::Source::Custom as i32;
12099                serialized_completion.resolved = true;
12100            }
12101            CompletionSource::Dap { sort_text } => {
12102                serialized_completion.source = proto::completion::Source::Dap as i32;
12103                serialized_completion.sort_text = Some(sort_text.clone());
12104            }
12105        }
12106
12107        serialized_completion
12108    }
12109
12110    pub(crate) fn deserialize_completion(completion: proto::Completion) -> Result<CoreCompletion> {
12111        let old_replace_start = completion
12112            .old_replace_start
12113            .and_then(deserialize_anchor)
12114            .context("invalid old start")?;
12115        let old_replace_end = completion
12116            .old_replace_end
12117            .and_then(deserialize_anchor)
12118            .context("invalid old end")?;
12119        let insert_range = {
12120            match completion.old_insert_start.zip(completion.old_insert_end) {
12121                Some((start, end)) => {
12122                    let start = deserialize_anchor(start).context("invalid insert old start")?;
12123                    let end = deserialize_anchor(end).context("invalid insert old end")?;
12124                    Some(start..end)
12125                }
12126                None => None,
12127            }
12128        };
12129        Ok(CoreCompletion {
12130            replace_range: old_replace_start..old_replace_end,
12131            new_text: completion.new_text,
12132            source: match proto::completion::Source::from_i32(completion.source) {
12133                Some(proto::completion::Source::Custom) => CompletionSource::Custom,
12134                Some(proto::completion::Source::Lsp) => CompletionSource::Lsp {
12135                    insert_range,
12136                    server_id: LanguageServerId::from_proto(completion.server_id),
12137                    lsp_completion: serde_json::from_slice(&completion.lsp_completion)?,
12138                    lsp_defaults: completion
12139                        .lsp_defaults
12140                        .as_deref()
12141                        .map(serde_json::from_slice)
12142                        .transpose()?,
12143                    resolved: completion.resolved,
12144                },
12145                Some(proto::completion::Source::BufferWord) => {
12146                    let word_range = completion
12147                        .buffer_word_start
12148                        .and_then(deserialize_anchor)
12149                        .context("invalid buffer word start")?
12150                        ..completion
12151                            .buffer_word_end
12152                            .and_then(deserialize_anchor)
12153                            .context("invalid buffer word end")?;
12154                    CompletionSource::BufferWord {
12155                        word_range,
12156                        resolved: completion.resolved,
12157                    }
12158                }
12159                Some(proto::completion::Source::Dap) => CompletionSource::Dap {
12160                    sort_text: completion
12161                        .sort_text
12162                        .context("expected sort text to exist")?,
12163                },
12164                _ => anyhow::bail!("Unexpected completion source {}", completion.source),
12165            },
12166        })
12167    }
12168
12169    pub(crate) fn serialize_code_action(action: &CodeAction) -> proto::CodeAction {
12170        let (kind, lsp_action) = match &action.lsp_action {
12171            LspAction::Action(code_action) => (
12172                proto::code_action::Kind::Action as i32,
12173                serde_json::to_vec(code_action).unwrap(),
12174            ),
12175            LspAction::Command(command) => (
12176                proto::code_action::Kind::Command as i32,
12177                serde_json::to_vec(command).unwrap(),
12178            ),
12179            LspAction::CodeLens(code_lens) => (
12180                proto::code_action::Kind::CodeLens as i32,
12181                serde_json::to_vec(code_lens).unwrap(),
12182            ),
12183        };
12184
12185        proto::CodeAction {
12186            server_id: action.server_id.0 as u64,
12187            start: Some(serialize_anchor(&action.range.start)),
12188            end: Some(serialize_anchor(&action.range.end)),
12189            lsp_action,
12190            kind,
12191            resolved: action.resolved,
12192        }
12193    }
12194
12195    pub(crate) fn deserialize_code_action(action: proto::CodeAction) -> Result<CodeAction> {
12196        let start = action
12197            .start
12198            .and_then(deserialize_anchor)
12199            .context("invalid start")?;
12200        let end = action
12201            .end
12202            .and_then(deserialize_anchor)
12203            .context("invalid end")?;
12204        let lsp_action = match proto::code_action::Kind::from_i32(action.kind) {
12205            Some(proto::code_action::Kind::Action) => {
12206                LspAction::Action(serde_json::from_slice(&action.lsp_action)?)
12207            }
12208            Some(proto::code_action::Kind::Command) => {
12209                LspAction::Command(serde_json::from_slice(&action.lsp_action)?)
12210            }
12211            Some(proto::code_action::Kind::CodeLens) => {
12212                LspAction::CodeLens(serde_json::from_slice(&action.lsp_action)?)
12213            }
12214            None => anyhow::bail!("Unknown action kind {}", action.kind),
12215        };
12216        Ok(CodeAction {
12217            server_id: LanguageServerId(action.server_id as usize),
12218            range: start..end,
12219            resolved: action.resolved,
12220            lsp_action,
12221        })
12222    }
12223
12224    fn update_last_formatting_failure<T>(&mut self, formatting_result: &anyhow::Result<T>) {
12225        match &formatting_result {
12226            Ok(_) => self.last_formatting_failure = None,
12227            Err(error) => {
12228                let error_string = format!("{error:#}");
12229                log::error!("Formatting failed: {error_string}");
12230                self.last_formatting_failure
12231                    .replace(error_string.lines().join(" "));
12232            }
12233        }
12234    }
12235
12236    fn cleanup_lsp_data(&mut self, for_server: LanguageServerId) {
12237        self.lsp_server_capabilities.remove(&for_server);
12238        for lsp_data in self.lsp_data.values_mut() {
12239            lsp_data.remove_server_data(for_server);
12240        }
12241        if let Some(local) = self.as_local_mut() {
12242            local.buffer_pull_diagnostics_result_ids.remove(&for_server);
12243            local
12244                .workspace_pull_diagnostics_result_ids
12245                .remove(&for_server);
12246            for buffer_servers in local.buffers_opened_in_servers.values_mut() {
12247                buffer_servers.remove(&for_server);
12248            }
12249        }
12250    }
12251
12252    pub fn result_id_for_buffer_pull(
12253        &self,
12254        server_id: LanguageServerId,
12255        buffer_id: BufferId,
12256        registration_id: &Option<SharedString>,
12257        cx: &App,
12258    ) -> Option<SharedString> {
12259        let abs_path = self
12260            .buffer_store
12261            .read(cx)
12262            .get(buffer_id)
12263            .and_then(|b| File::from_dyn(b.read(cx).file()))
12264            .map(|f| f.abs_path(cx))?;
12265        self.as_local()?
12266            .buffer_pull_diagnostics_result_ids
12267            .get(&server_id)?
12268            .get(registration_id)?
12269            .get(&abs_path)?
12270            .clone()
12271    }
12272
12273    /// Gets all result_ids for a workspace diagnostics pull request.
12274    /// 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.
12275    /// The latter is supposed to be of lower priority as we keep on pulling diagnostics for open buffers eagerly.
12276    pub fn result_ids_for_workspace_refresh(
12277        &self,
12278        server_id: LanguageServerId,
12279        registration_id: &Option<SharedString>,
12280    ) -> HashMap<PathBuf, SharedString> {
12281        let Some(local) = self.as_local() else {
12282            return HashMap::default();
12283        };
12284        local
12285            .workspace_pull_diagnostics_result_ids
12286            .get(&server_id)
12287            .into_iter()
12288            .filter_map(|diagnostics| diagnostics.get(registration_id))
12289            .flatten()
12290            .filter_map(|(abs_path, result_id)| {
12291                let result_id = local
12292                    .buffer_pull_diagnostics_result_ids
12293                    .get(&server_id)
12294                    .and_then(|buffer_ids_result_ids| {
12295                        buffer_ids_result_ids.get(registration_id)?.get(abs_path)
12296                    })
12297                    .cloned()
12298                    .flatten()
12299                    .or_else(|| result_id.clone())?;
12300                Some((abs_path.clone(), result_id))
12301            })
12302            .collect()
12303    }
12304
12305    pub fn pull_workspace_diagnostics(&mut self, server_id: LanguageServerId) {
12306        if let Some(LanguageServerState::Running {
12307            workspace_diagnostics_refresh_tasks,
12308            ..
12309        }) = self
12310            .as_local_mut()
12311            .and_then(|local| local.language_servers.get_mut(&server_id))
12312        {
12313            for diagnostics in workspace_diagnostics_refresh_tasks.values_mut() {
12314                diagnostics.refresh_tx.try_send(()).ok();
12315            }
12316        }
12317    }
12318
12319    /// Refreshes `textDocument/diagnostic` for all open buffers associated with the given server.
12320    /// This is called in response to `workspace/diagnostic/refresh` to comply with the LSP spec,
12321    /// which requires refreshing both workspace and document diagnostics.
12322    pub fn pull_document_diagnostics_for_server(
12323        &mut self,
12324        server_id: LanguageServerId,
12325        source_buffer_id: Option<BufferId>,
12326        cx: &mut Context<Self>,
12327    ) -> Shared<Task<()>> {
12328        let Some(local) = self.as_local_mut() else {
12329            return Task::ready(()).shared();
12330        };
12331        let mut buffers_to_refresh = HashSet::default();
12332        for (buffer_id, server_ids) in &local.buffers_opened_in_servers {
12333            if server_ids.contains(&server_id) && Some(buffer_id) != source_buffer_id.as_ref() {
12334                buffers_to_refresh.insert(*buffer_id);
12335            }
12336        }
12337
12338        self.refresh_background_diagnostics_for_buffers(buffers_to_refresh, cx)
12339    }
12340
12341    pub fn pull_document_diagnostics_for_buffer_edit(
12342        &mut self,
12343        buffer_id: BufferId,
12344        cx: &mut Context<Self>,
12345    ) {
12346        let Some(local) = self.as_local_mut() else {
12347            return;
12348        };
12349        let Some(languages_servers) = local.buffers_opened_in_servers.get(&buffer_id).cloned()
12350        else {
12351            return;
12352        };
12353        for server_id in languages_servers {
12354            let _ = self.pull_document_diagnostics_for_server(server_id, Some(buffer_id), cx);
12355        }
12356    }
12357
12358    fn apply_workspace_diagnostic_report(
12359        &mut self,
12360        server_id: LanguageServerId,
12361        report: lsp::WorkspaceDiagnosticReportResult,
12362        registration_id: Option<SharedString>,
12363        cx: &mut Context<Self>,
12364    ) {
12365        let mut workspace_diagnostics =
12366            GetDocumentDiagnostics::deserialize_workspace_diagnostics_report(
12367                report,
12368                server_id,
12369                registration_id,
12370            );
12371        workspace_diagnostics.retain(|d| match &d.diagnostics {
12372            LspPullDiagnostics::Response {
12373                server_id,
12374                registration_id,
12375                ..
12376            } => self.diagnostic_registration_exists(*server_id, registration_id),
12377            LspPullDiagnostics::Default => false,
12378        });
12379        let mut unchanged_buffers = HashMap::default();
12380        let workspace_diagnostics_updates = workspace_diagnostics
12381            .into_iter()
12382            .filter_map(
12383                |workspace_diagnostics| match workspace_diagnostics.diagnostics {
12384                    LspPullDiagnostics::Response {
12385                        server_id,
12386                        uri,
12387                        diagnostics,
12388                        registration_id,
12389                    } => Some((
12390                        server_id,
12391                        uri,
12392                        diagnostics,
12393                        workspace_diagnostics.version,
12394                        registration_id,
12395                    )),
12396                    LspPullDiagnostics::Default => None,
12397                },
12398            )
12399            .fold(
12400                HashMap::default(),
12401                |mut acc, (server_id, uri, diagnostics, version, new_registration_id)| {
12402                    let (result_id, diagnostics) = match diagnostics {
12403                        PulledDiagnostics::Unchanged { result_id } => {
12404                            unchanged_buffers
12405                                .entry(new_registration_id.clone())
12406                                .or_insert_with(HashSet::default)
12407                                .insert(uri.clone());
12408                            (Some(result_id), Vec::new())
12409                        }
12410                        PulledDiagnostics::Changed {
12411                            result_id,
12412                            diagnostics,
12413                        } => (result_id, diagnostics),
12414                    };
12415                    let disk_based_sources = Cow::Owned(
12416                        self.language_server_adapter_for_id(server_id)
12417                            .as_ref()
12418                            .map(|adapter| adapter.disk_based_diagnostic_sources.as_slice())
12419                            .unwrap_or(&[])
12420                            .to_vec(),
12421                    );
12422
12423                    let Some(abs_path) = uri.to_file_path().ok() else {
12424                        return acc;
12425                    };
12426                    let Some((worktree, relative_path)) =
12427                        self.worktree_store.read(cx).find_worktree(abs_path.clone(), cx)
12428                    else {
12429                        log::warn!("skipping workspace diagnostics update, no worktree found for path {abs_path:?}");
12430                        return acc;
12431                    };
12432                    let worktree_id = worktree.read(cx).id();
12433                    let project_path = ProjectPath {
12434                        worktree_id,
12435                        path: relative_path,
12436                    };
12437                    if let Some(local_lsp_store) = self.as_local_mut() {
12438                        local_lsp_store.workspace_pull_diagnostics_result_ids.entry(server_id)
12439                            .or_default().entry(new_registration_id.clone()).or_default().insert(abs_path, result_id.clone());
12440                    }
12441                    // The LSP spec recommends that "diagnostics from a document pull should win over diagnostics from a workspace pull."
12442                    // Since we actively pull diagnostics for documents with open buffers, we ignore contents of workspace pulls for these documents.
12443                    if self.buffer_store.read(cx).get_by_path(&project_path).is_none() {
12444                        acc.entry(server_id)
12445                            .or_insert_with(HashMap::default)
12446                            .entry(new_registration_id.clone())
12447                            .or_insert_with(Vec::new)
12448                            .push(DocumentDiagnosticsUpdate {
12449                                server_id,
12450                                diagnostics: lsp::PublishDiagnosticsParams {
12451                                    uri,
12452                                    diagnostics,
12453                                    version,
12454                                },
12455                                result_id,
12456                                disk_based_sources,
12457                                registration_id: new_registration_id,
12458                            });
12459                    }
12460                    acc
12461                },
12462            );
12463
12464        for diagnostic_updates in workspace_diagnostics_updates.into_values() {
12465            for (registration_id, diagnostic_updates) in diagnostic_updates {
12466                self.merge_lsp_diagnostics(
12467                    DiagnosticSourceKind::Pulled,
12468                    diagnostic_updates,
12469                    |document_uri, old_diagnostic, _| match old_diagnostic.source_kind {
12470                        DiagnosticSourceKind::Pulled => {
12471                            old_diagnostic.registration_id != registration_id
12472                                || unchanged_buffers
12473                                    .get(&old_diagnostic.registration_id)
12474                                    .is_some_and(|unchanged_buffers| {
12475                                        unchanged_buffers.contains(&document_uri)
12476                                    })
12477                        }
12478                        DiagnosticSourceKind::Other | DiagnosticSourceKind::Pushed => true,
12479                    },
12480                    cx,
12481                )
12482                .log_err();
12483            }
12484        }
12485    }
12486
12487    fn register_server_capabilities(
12488        &mut self,
12489        server_id: LanguageServerId,
12490        params: lsp::RegistrationParams,
12491        cx: &mut Context<Self>,
12492    ) -> anyhow::Result<()> {
12493        let server = self
12494            .language_server_for_id(server_id)
12495            .with_context(|| format!("no server {server_id} found"))?;
12496        for reg in params.registrations {
12497            match reg.method.as_str() {
12498                "workspace/didChangeWatchedFiles" => {
12499                    if let Some(options) = reg.register_options {
12500                        let notify = if let Some(local_lsp_store) = self.as_local_mut() {
12501                            let caps = serde_json::from_value(options)?;
12502                            local_lsp_store
12503                                .on_lsp_did_change_watched_files(server_id, &reg.id, caps, cx);
12504                            true
12505                        } else {
12506                            false
12507                        };
12508                        if notify {
12509                            notify_server_capabilities_updated(&server, cx);
12510                        }
12511                    }
12512                }
12513                "workspace/didChangeConfiguration" => {
12514                    // Ignore payload since we notify clients of setting changes unconditionally, relying on them pulling the latest settings.
12515                }
12516                "workspace/didChangeWorkspaceFolders" => {
12517                    // In this case register options is an empty object, we can ignore it
12518                    let caps = lsp::WorkspaceFoldersServerCapabilities {
12519                        supported: Some(true),
12520                        change_notifications: Some(OneOf::Right(reg.id)),
12521                    };
12522                    server.update_capabilities(|capabilities| {
12523                        capabilities
12524                            .workspace
12525                            .get_or_insert_default()
12526                            .workspace_folders = Some(caps);
12527                    });
12528                    notify_server_capabilities_updated(&server, cx);
12529                }
12530                "workspace/symbol" => {
12531                    let options = parse_register_capabilities(reg)?;
12532                    server.update_capabilities(|capabilities| {
12533                        capabilities.workspace_symbol_provider = Some(options);
12534                    });
12535                    notify_server_capabilities_updated(&server, cx);
12536                }
12537                "workspace/fileOperations" => {
12538                    if let Some(options) = reg.register_options {
12539                        let caps = serde_json::from_value(options)?;
12540                        server.update_capabilities(|capabilities| {
12541                            capabilities
12542                                .workspace
12543                                .get_or_insert_default()
12544                                .file_operations = Some(caps);
12545                        });
12546                        notify_server_capabilities_updated(&server, cx);
12547                    }
12548                }
12549                "workspace/executeCommand" => {
12550                    if let Some(options) = reg.register_options {
12551                        let options = serde_json::from_value(options)?;
12552                        server.update_capabilities(|capabilities| {
12553                            capabilities.execute_command_provider = Some(options);
12554                        });
12555                        notify_server_capabilities_updated(&server, cx);
12556                    }
12557                }
12558                "textDocument/rangeFormatting" => {
12559                    let options = parse_register_capabilities(reg)?;
12560                    server.update_capabilities(|capabilities| {
12561                        capabilities.document_range_formatting_provider = Some(options);
12562                    });
12563                    notify_server_capabilities_updated(&server, cx);
12564                }
12565                "textDocument/onTypeFormatting" => {
12566                    if let Some(options) = reg
12567                        .register_options
12568                        .map(serde_json::from_value)
12569                        .transpose()?
12570                    {
12571                        server.update_capabilities(|capabilities| {
12572                            capabilities.document_on_type_formatting_provider = Some(options);
12573                        });
12574                        notify_server_capabilities_updated(&server, cx);
12575                    }
12576                }
12577                "textDocument/formatting" => {
12578                    let options = parse_register_capabilities(reg)?;
12579                    server.update_capabilities(|capabilities| {
12580                        capabilities.document_formatting_provider = Some(options);
12581                    });
12582                    notify_server_capabilities_updated(&server, cx);
12583                }
12584                "textDocument/rename" => {
12585                    let options = parse_register_capabilities(reg)?;
12586                    server.update_capabilities(|capabilities| {
12587                        capabilities.rename_provider = Some(options);
12588                    });
12589                    notify_server_capabilities_updated(&server, cx);
12590                }
12591                "textDocument/inlayHint" => {
12592                    let options = parse_register_capabilities(reg)?;
12593                    server.update_capabilities(|capabilities| {
12594                        capabilities.inlay_hint_provider = Some(options);
12595                    });
12596                    notify_server_capabilities_updated(&server, cx);
12597                }
12598                "textDocument/documentSymbol" => {
12599                    let options = parse_register_capabilities(reg)?;
12600                    server.update_capabilities(|capabilities| {
12601                        capabilities.document_symbol_provider = Some(options);
12602                    });
12603                    notify_server_capabilities_updated(&server, cx);
12604                }
12605                "textDocument/codeAction" => {
12606                    let options = parse_register_capabilities(reg)?;
12607                    let provider = match options {
12608                        OneOf::Left(value) => lsp::CodeActionProviderCapability::Simple(value),
12609                        OneOf::Right(caps) => caps,
12610                    };
12611                    server.update_capabilities(|capabilities| {
12612                        capabilities.code_action_provider = Some(provider);
12613                    });
12614                    notify_server_capabilities_updated(&server, cx);
12615                }
12616                "textDocument/definition" => {
12617                    let options = parse_register_capabilities(reg)?;
12618                    server.update_capabilities(|capabilities| {
12619                        capabilities.definition_provider = Some(options);
12620                    });
12621                    notify_server_capabilities_updated(&server, cx);
12622                }
12623                "textDocument/completion" => {
12624                    if let Some(caps) = reg
12625                        .register_options
12626                        .map(serde_json::from_value::<CompletionOptions>)
12627                        .transpose()?
12628                    {
12629                        server.update_capabilities(|capabilities| {
12630                            capabilities.completion_provider = Some(caps.clone());
12631                        });
12632
12633                        if let Some(local) = self.as_local() {
12634                            let mut buffers_with_language_server = Vec::new();
12635                            for handle in self.buffer_store.read(cx).buffers() {
12636                                let buffer_id = handle.read(cx).remote_id();
12637                                if local
12638                                    .buffers_opened_in_servers
12639                                    .get(&buffer_id)
12640                                    .filter(|s| s.contains(&server_id))
12641                                    .is_some()
12642                                {
12643                                    buffers_with_language_server.push(handle);
12644                                }
12645                            }
12646                            let triggers = caps
12647                                .trigger_characters
12648                                .unwrap_or_default()
12649                                .into_iter()
12650                                .collect::<BTreeSet<_>>();
12651                            for handle in buffers_with_language_server {
12652                                let triggers = triggers.clone();
12653                                let _ = handle.update(cx, move |buffer, cx| {
12654                                    buffer.set_completion_triggers(server_id, triggers, cx);
12655                                });
12656                            }
12657                        }
12658                        notify_server_capabilities_updated(&server, cx);
12659                    }
12660                }
12661                "textDocument/hover" => {
12662                    let options = parse_register_capabilities(reg)?;
12663                    let provider = match options {
12664                        OneOf::Left(value) => lsp::HoverProviderCapability::Simple(value),
12665                        OneOf::Right(caps) => caps,
12666                    };
12667                    server.update_capabilities(|capabilities| {
12668                        capabilities.hover_provider = Some(provider);
12669                    });
12670                    notify_server_capabilities_updated(&server, cx);
12671                }
12672                "textDocument/signatureHelp" => {
12673                    if let Some(caps) = reg
12674                        .register_options
12675                        .map(serde_json::from_value)
12676                        .transpose()?
12677                    {
12678                        server.update_capabilities(|capabilities| {
12679                            capabilities.signature_help_provider = Some(caps);
12680                        });
12681                        notify_server_capabilities_updated(&server, cx);
12682                    }
12683                }
12684                "textDocument/didChange" => {
12685                    if let Some(sync_kind) = reg
12686                        .register_options
12687                        .and_then(|opts| opts.get("syncKind").cloned())
12688                        .map(serde_json::from_value::<lsp::TextDocumentSyncKind>)
12689                        .transpose()?
12690                    {
12691                        server.update_capabilities(|capabilities| {
12692                            let mut sync_options =
12693                                Self::take_text_document_sync_options(capabilities);
12694                            sync_options.change = Some(sync_kind);
12695                            capabilities.text_document_sync =
12696                                Some(lsp::TextDocumentSyncCapability::Options(sync_options));
12697                        });
12698                        notify_server_capabilities_updated(&server, cx);
12699                    }
12700                }
12701                "textDocument/didSave" => {
12702                    if let Some(include_text) = reg
12703                        .register_options
12704                        .map(|opts| {
12705                            let transpose = opts
12706                                .get("includeText")
12707                                .cloned()
12708                                .map(serde_json::from_value::<Option<bool>>)
12709                                .transpose();
12710                            match transpose {
12711                                Ok(value) => Ok(value.flatten()),
12712                                Err(e) => Err(e),
12713                            }
12714                        })
12715                        .transpose()?
12716                    {
12717                        server.update_capabilities(|capabilities| {
12718                            let mut sync_options =
12719                                Self::take_text_document_sync_options(capabilities);
12720                            sync_options.save =
12721                                Some(TextDocumentSyncSaveOptions::SaveOptions(lsp::SaveOptions {
12722                                    include_text,
12723                                }));
12724                            capabilities.text_document_sync =
12725                                Some(lsp::TextDocumentSyncCapability::Options(sync_options));
12726                        });
12727                        notify_server_capabilities_updated(&server, cx);
12728                    }
12729                }
12730                "textDocument/codeLens" => {
12731                    if let Some(caps) = reg
12732                        .register_options
12733                        .map(serde_json::from_value)
12734                        .transpose()?
12735                    {
12736                        server.update_capabilities(|capabilities| {
12737                            capabilities.code_lens_provider = Some(caps);
12738                        });
12739                        notify_server_capabilities_updated(&server, cx);
12740                    }
12741                }
12742                "textDocument/diagnostic" => {
12743                    if let Some(caps) = reg
12744                        .register_options
12745                        .map(serde_json::from_value::<DiagnosticServerCapabilities>)
12746                        .transpose()?
12747                    {
12748                        let local = self
12749                            .as_local_mut()
12750                            .context("Expected LSP Store to be local")?;
12751                        let state = local
12752                            .language_servers
12753                            .get_mut(&server_id)
12754                            .context("Could not obtain Language Servers state")?;
12755                        local
12756                            .language_server_dynamic_registrations
12757                            .entry(server_id)
12758                            .or_default()
12759                            .diagnostics
12760                            .insert(Some(reg.id.clone()), caps.clone());
12761
12762                        let supports_workspace_diagnostics =
12763                            |capabilities: &DiagnosticServerCapabilities| match capabilities {
12764                                DiagnosticServerCapabilities::Options(diagnostic_options) => {
12765                                    diagnostic_options.workspace_diagnostics
12766                                }
12767                                DiagnosticServerCapabilities::RegistrationOptions(
12768                                    diagnostic_registration_options,
12769                                ) => {
12770                                    diagnostic_registration_options
12771                                        .diagnostic_options
12772                                        .workspace_diagnostics
12773                                }
12774                            };
12775
12776                        if supports_workspace_diagnostics(&caps) {
12777                            if let LanguageServerState::Running {
12778                                workspace_diagnostics_refresh_tasks,
12779                                ..
12780                            } = state
12781                                && let Some(task) = lsp_workspace_diagnostics_refresh(
12782                                    Some(reg.id.clone()),
12783                                    caps.clone(),
12784                                    server.clone(),
12785                                    cx,
12786                                )
12787                            {
12788                                workspace_diagnostics_refresh_tasks.insert(Some(reg.id), task);
12789                            }
12790                        }
12791
12792                        server.update_capabilities(|capabilities| {
12793                            capabilities.diagnostic_provider = Some(caps);
12794                        });
12795
12796                        notify_server_capabilities_updated(&server, cx);
12797
12798                        let _ = self.pull_document_diagnostics_for_server(server_id, None, cx);
12799                    }
12800                }
12801                "textDocument/documentColor" => {
12802                    let options = parse_register_capabilities(reg)?;
12803                    let provider = match options {
12804                        OneOf::Left(value) => lsp::ColorProviderCapability::Simple(value),
12805                        OneOf::Right(caps) => caps,
12806                    };
12807                    server.update_capabilities(|capabilities| {
12808                        capabilities.color_provider = Some(provider);
12809                    });
12810                    notify_server_capabilities_updated(&server, cx);
12811                }
12812                _ => log::warn!("unhandled capability registration: {reg:?}"),
12813            }
12814        }
12815
12816        Ok(())
12817    }
12818
12819    fn unregister_server_capabilities(
12820        &mut self,
12821        server_id: LanguageServerId,
12822        params: lsp::UnregistrationParams,
12823        cx: &mut Context<Self>,
12824    ) -> anyhow::Result<()> {
12825        let server = self
12826            .language_server_for_id(server_id)
12827            .with_context(|| format!("no server {server_id} found"))?;
12828        for unreg in params.unregisterations.iter() {
12829            match unreg.method.as_str() {
12830                "workspace/didChangeWatchedFiles" => {
12831                    let notify = if let Some(local_lsp_store) = self.as_local_mut() {
12832                        local_lsp_store
12833                            .on_lsp_unregister_did_change_watched_files(server_id, &unreg.id, cx);
12834                        true
12835                    } else {
12836                        false
12837                    };
12838                    if notify {
12839                        notify_server_capabilities_updated(&server, cx);
12840                    }
12841                }
12842                "workspace/didChangeConfiguration" => {
12843                    // Ignore payload since we notify clients of setting changes unconditionally, relying on them pulling the latest settings.
12844                }
12845                "workspace/didChangeWorkspaceFolders" => {
12846                    server.update_capabilities(|capabilities| {
12847                        capabilities
12848                            .workspace
12849                            .get_or_insert_with(|| lsp::WorkspaceServerCapabilities {
12850                                workspace_folders: None,
12851                                file_operations: None,
12852                            })
12853                            .workspace_folders = None;
12854                    });
12855                    notify_server_capabilities_updated(&server, cx);
12856                }
12857                "workspace/symbol" => {
12858                    server.update_capabilities(|capabilities| {
12859                        capabilities.workspace_symbol_provider = None
12860                    });
12861                    notify_server_capabilities_updated(&server, cx);
12862                }
12863                "workspace/fileOperations" => {
12864                    server.update_capabilities(|capabilities| {
12865                        capabilities
12866                            .workspace
12867                            .get_or_insert_with(|| lsp::WorkspaceServerCapabilities {
12868                                workspace_folders: None,
12869                                file_operations: None,
12870                            })
12871                            .file_operations = None;
12872                    });
12873                    notify_server_capabilities_updated(&server, cx);
12874                }
12875                "workspace/executeCommand" => {
12876                    server.update_capabilities(|capabilities| {
12877                        capabilities.execute_command_provider = None;
12878                    });
12879                    notify_server_capabilities_updated(&server, cx);
12880                }
12881                "textDocument/rangeFormatting" => {
12882                    server.update_capabilities(|capabilities| {
12883                        capabilities.document_range_formatting_provider = None
12884                    });
12885                    notify_server_capabilities_updated(&server, cx);
12886                }
12887                "textDocument/onTypeFormatting" => {
12888                    server.update_capabilities(|capabilities| {
12889                        capabilities.document_on_type_formatting_provider = None;
12890                    });
12891                    notify_server_capabilities_updated(&server, cx);
12892                }
12893                "textDocument/formatting" => {
12894                    server.update_capabilities(|capabilities| {
12895                        capabilities.document_formatting_provider = None;
12896                    });
12897                    notify_server_capabilities_updated(&server, cx);
12898                }
12899                "textDocument/rename" => {
12900                    server.update_capabilities(|capabilities| capabilities.rename_provider = None);
12901                    notify_server_capabilities_updated(&server, cx);
12902                }
12903                "textDocument/codeAction" => {
12904                    server.update_capabilities(|capabilities| {
12905                        capabilities.code_action_provider = None;
12906                    });
12907                    notify_server_capabilities_updated(&server, cx);
12908                }
12909                "textDocument/definition" => {
12910                    server.update_capabilities(|capabilities| {
12911                        capabilities.definition_provider = None;
12912                    });
12913                    notify_server_capabilities_updated(&server, cx);
12914                }
12915                "textDocument/completion" => {
12916                    server.update_capabilities(|capabilities| {
12917                        capabilities.completion_provider = None;
12918                    });
12919                    notify_server_capabilities_updated(&server, cx);
12920                }
12921                "textDocument/hover" => {
12922                    server.update_capabilities(|capabilities| {
12923                        capabilities.hover_provider = None;
12924                    });
12925                    notify_server_capabilities_updated(&server, cx);
12926                }
12927                "textDocument/signatureHelp" => {
12928                    server.update_capabilities(|capabilities| {
12929                        capabilities.signature_help_provider = None;
12930                    });
12931                    notify_server_capabilities_updated(&server, cx);
12932                }
12933                "textDocument/didChange" => {
12934                    server.update_capabilities(|capabilities| {
12935                        let mut sync_options = Self::take_text_document_sync_options(capabilities);
12936                        sync_options.change = None;
12937                        capabilities.text_document_sync =
12938                            Some(lsp::TextDocumentSyncCapability::Options(sync_options));
12939                    });
12940                    notify_server_capabilities_updated(&server, cx);
12941                }
12942                "textDocument/didSave" => {
12943                    server.update_capabilities(|capabilities| {
12944                        let mut sync_options = Self::take_text_document_sync_options(capabilities);
12945                        sync_options.save = None;
12946                        capabilities.text_document_sync =
12947                            Some(lsp::TextDocumentSyncCapability::Options(sync_options));
12948                    });
12949                    notify_server_capabilities_updated(&server, cx);
12950                }
12951                "textDocument/codeLens" => {
12952                    server.update_capabilities(|capabilities| {
12953                        capabilities.code_lens_provider = None;
12954                    });
12955                    notify_server_capabilities_updated(&server, cx);
12956                }
12957                "textDocument/diagnostic" => {
12958                    let local = self
12959                        .as_local_mut()
12960                        .context("Expected LSP Store to be local")?;
12961
12962                    let state = local
12963                        .language_servers
12964                        .get_mut(&server_id)
12965                        .context("Could not obtain Language Servers state")?;
12966                    let registrations = local
12967                        .language_server_dynamic_registrations
12968                        .get_mut(&server_id)
12969                        .with_context(|| {
12970                            format!("Expected dynamic registration to exist for server {server_id}")
12971                        })?;
12972                    registrations.diagnostics
12973                        .remove(&Some(unreg.id.clone()))
12974                        .with_context(|| format!(
12975                            "Attempted to unregister non-existent diagnostic registration with ID {}",
12976                            unreg.id)
12977                        )?;
12978                    let removed_last_diagnostic_provider = registrations.diagnostics.is_empty();
12979
12980                    if let LanguageServerState::Running {
12981                        workspace_diagnostics_refresh_tasks,
12982                        ..
12983                    } = state
12984                    {
12985                        workspace_diagnostics_refresh_tasks.remove(&Some(unreg.id.clone()));
12986                    }
12987
12988                    self.clear_unregistered_diagnostics(
12989                        server_id,
12990                        SharedString::from(unreg.id.clone()),
12991                        cx,
12992                    )?;
12993
12994                    if removed_last_diagnostic_provider {
12995                        server.update_capabilities(|capabilities| {
12996                            debug_assert!(capabilities.diagnostic_provider.is_some());
12997                            capabilities.diagnostic_provider = None;
12998                        });
12999                    }
13000
13001                    notify_server_capabilities_updated(&server, cx);
13002                }
13003                "textDocument/documentColor" => {
13004                    server.update_capabilities(|capabilities| {
13005                        capabilities.color_provider = None;
13006                    });
13007                    notify_server_capabilities_updated(&server, cx);
13008                }
13009                _ => log::warn!("unhandled capability unregistration: {unreg:?}"),
13010            }
13011        }
13012
13013        Ok(())
13014    }
13015
13016    fn clear_unregistered_diagnostics(
13017        &mut self,
13018        server_id: LanguageServerId,
13019        cleared_registration_id: SharedString,
13020        cx: &mut Context<Self>,
13021    ) -> anyhow::Result<()> {
13022        let mut affected_abs_paths: HashSet<PathBuf> = HashSet::default();
13023
13024        self.buffer_store.update(cx, |buffer_store, cx| {
13025            for buffer_handle in buffer_store.buffers() {
13026                let buffer = buffer_handle.read(cx);
13027                let abs_path = File::from_dyn(buffer.file()).map(|f| f.abs_path(cx));
13028                let Some(abs_path) = abs_path else {
13029                    continue;
13030                };
13031                affected_abs_paths.insert(abs_path);
13032            }
13033        });
13034
13035        let local = self.as_local().context("Expected LSP Store to be local")?;
13036        for (worktree_id, diagnostics_for_tree) in local.diagnostics.iter() {
13037            let Some(worktree) = self
13038                .worktree_store
13039                .read(cx)
13040                .worktree_for_id(*worktree_id, cx)
13041            else {
13042                continue;
13043            };
13044
13045            for (rel_path, diagnostics_by_server_id) in diagnostics_for_tree.iter() {
13046                if let Ok(ix) = diagnostics_by_server_id.binary_search_by_key(&server_id, |e| e.0) {
13047                    let has_matching_registration =
13048                        diagnostics_by_server_id[ix].1.iter().any(|entry| {
13049                            entry.diagnostic.registration_id.as_ref()
13050                                == Some(&cleared_registration_id)
13051                        });
13052                    if has_matching_registration {
13053                        let abs_path = worktree.read(cx).absolutize(rel_path);
13054                        affected_abs_paths.insert(abs_path);
13055                    }
13056                }
13057            }
13058        }
13059
13060        if affected_abs_paths.is_empty() {
13061            return Ok(());
13062        }
13063
13064        // Send a fake diagnostic update which clears the state for the registration ID
13065        let clears: Vec<DocumentDiagnosticsUpdate<'static, DocumentDiagnostics>> =
13066            affected_abs_paths
13067                .into_iter()
13068                .map(|abs_path| DocumentDiagnosticsUpdate {
13069                    diagnostics: DocumentDiagnostics {
13070                        diagnostics: Vec::new(),
13071                        document_abs_path: abs_path,
13072                        version: None,
13073                    },
13074                    result_id: None,
13075                    registration_id: Some(cleared_registration_id.clone()),
13076                    server_id,
13077                    disk_based_sources: Cow::Borrowed(&[]),
13078                })
13079                .collect();
13080
13081        let merge_registration_id = cleared_registration_id.clone();
13082        self.merge_diagnostic_entries(
13083            clears,
13084            move |_, diagnostic, _| {
13085                if diagnostic.source_kind == DiagnosticSourceKind::Pulled {
13086                    diagnostic.registration_id != Some(merge_registration_id.clone())
13087                } else {
13088                    true
13089                }
13090            },
13091            cx,
13092        )?;
13093
13094        Ok(())
13095    }
13096
13097    async fn deduplicate_range_based_lsp_requests<T>(
13098        lsp_store: &Entity<Self>,
13099        server_id: Option<LanguageServerId>,
13100        lsp_request_id: LspRequestId,
13101        proto_request: &T::ProtoRequest,
13102        range: Range<Anchor>,
13103        cx: &mut AsyncApp,
13104    ) -> Result<()>
13105    where
13106        T: LspCommand,
13107        T::ProtoRequest: proto::LspRequestMessage,
13108    {
13109        let buffer_id = BufferId::new(proto_request.buffer_id())?;
13110        let version = deserialize_version(proto_request.buffer_version());
13111        let buffer = lsp_store.update(cx, |this, cx| {
13112            this.buffer_store.read(cx).get_existing(buffer_id)
13113        })?;
13114        buffer
13115            .update(cx, |buffer, _| buffer.wait_for_version(version))
13116            .await?;
13117        lsp_store.update(cx, |lsp_store, cx| {
13118            let buffer_snapshot = buffer.read(cx).snapshot();
13119            let lsp_data = lsp_store.latest_lsp_data(&buffer, cx);
13120            let chunks_queried_for = lsp_data
13121                .inlay_hints
13122                .applicable_chunks(&[range.to_point(&buffer_snapshot)])
13123                .collect::<Vec<_>>();
13124            match chunks_queried_for.as_slice() {
13125                &[chunk] => {
13126                    let key = LspKey {
13127                        request_type: TypeId::of::<T>(),
13128                        server_queried: server_id,
13129                    };
13130                    let previous_request = lsp_data
13131                        .chunk_lsp_requests
13132                        .entry(key)
13133                        .or_default()
13134                        .insert(chunk, lsp_request_id);
13135                    if let Some((previous_request, running_requests)) =
13136                        previous_request.zip(lsp_data.lsp_requests.get_mut(&key))
13137                    {
13138                        running_requests.remove(&previous_request);
13139                    }
13140                }
13141                _ambiguous_chunks => {
13142                    // Have not found a unique chunk for the query range — be lenient and let the query to be spawned,
13143                    // there, a buffer version-based check will be performed and outdated requests discarded.
13144                }
13145            }
13146            anyhow::Ok(())
13147        })?;
13148
13149        Ok(())
13150    }
13151
13152    async fn query_lsp_locally<T>(
13153        lsp_store: Entity<Self>,
13154        for_server_id: Option<LanguageServerId>,
13155        sender_id: proto::PeerId,
13156        lsp_request_id: LspRequestId,
13157        proto_request: T::ProtoRequest,
13158        position: Option<Anchor>,
13159        cx: &mut AsyncApp,
13160    ) -> Result<()>
13161    where
13162        T: LspCommand + Clone,
13163        T::ProtoRequest: proto::LspRequestMessage,
13164        <T::ProtoRequest as proto::RequestMessage>::Response:
13165            Into<<T::ProtoRequest as proto::LspRequestMessage>::Response>,
13166    {
13167        let buffer_id = BufferId::new(proto_request.buffer_id())?;
13168        let version = deserialize_version(proto_request.buffer_version());
13169        let buffer = lsp_store.update(cx, |this, cx| {
13170            this.buffer_store.read(cx).get_existing(buffer_id)
13171        })?;
13172        buffer
13173            .update(cx, |buffer, _| buffer.wait_for_version(version.clone()))
13174            .await?;
13175        let buffer_version = buffer.read_with(cx, |buffer, _| buffer.version());
13176        let request =
13177            T::from_proto(proto_request, lsp_store.clone(), buffer.clone(), cx.clone()).await?;
13178        let key = LspKey {
13179            request_type: TypeId::of::<T>(),
13180            server_queried: for_server_id,
13181        };
13182        lsp_store.update(cx, |lsp_store, cx| {
13183            let request_task = match for_server_id {
13184                Some(server_id) => {
13185                    let server_task = lsp_store.request_lsp(
13186                        buffer.clone(),
13187                        LanguageServerToQuery::Other(server_id),
13188                        request.clone(),
13189                        cx,
13190                    );
13191                    cx.background_spawn(async move {
13192                        let mut responses = Vec::new();
13193                        match server_task.await {
13194                            Ok(response) => responses.push((server_id, response)),
13195                            // rust-analyzer likes to error with this when its still loading up
13196                            Err(e) if format!("{e:#}").ends_with("content modified") => (),
13197                            Err(e) => log::error!(
13198                                "Error handling response for request {request:?}: {e:#}"
13199                            ),
13200                        }
13201                        responses
13202                    })
13203                }
13204                None => lsp_store.request_multiple_lsp_locally(&buffer, position, request, cx),
13205            };
13206            let lsp_data = lsp_store.latest_lsp_data(&buffer, cx);
13207            if T::ProtoRequest::stop_previous_requests() {
13208                if let Some(lsp_requests) = lsp_data.lsp_requests.get_mut(&key) {
13209                    lsp_requests.clear();
13210                }
13211            }
13212            lsp_data.lsp_requests.entry(key).or_default().insert(
13213                lsp_request_id,
13214                cx.spawn(async move |lsp_store, cx| {
13215                    let response = request_task.await;
13216                    lsp_store
13217                        .update(cx, |lsp_store, cx| {
13218                            if let Some((client, project_id)) = lsp_store.downstream_client.clone()
13219                            {
13220                                let response = response
13221                                    .into_iter()
13222                                    .map(|(server_id, response)| {
13223                                        (
13224                                            server_id.to_proto(),
13225                                            T::response_to_proto(
13226                                                response,
13227                                                lsp_store,
13228                                                sender_id,
13229                                                &buffer_version,
13230                                                cx,
13231                                            )
13232                                            .into(),
13233                                        )
13234                                    })
13235                                    .collect::<HashMap<_, _>>();
13236                                match client.send_lsp_response::<T::ProtoRequest>(
13237                                    project_id,
13238                                    lsp_request_id,
13239                                    response,
13240                                ) {
13241                                    Ok(()) => {}
13242                                    Err(e) => {
13243                                        log::error!("Failed to send LSP response: {e:#}",)
13244                                    }
13245                                }
13246                            }
13247                        })
13248                        .ok();
13249                }),
13250            );
13251        });
13252        Ok(())
13253    }
13254
13255    fn take_text_document_sync_options(
13256        capabilities: &mut lsp::ServerCapabilities,
13257    ) -> lsp::TextDocumentSyncOptions {
13258        match capabilities.text_document_sync.take() {
13259            Some(lsp::TextDocumentSyncCapability::Options(sync_options)) => sync_options,
13260            Some(lsp::TextDocumentSyncCapability::Kind(sync_kind)) => {
13261                let mut sync_options = lsp::TextDocumentSyncOptions::default();
13262                sync_options.change = Some(sync_kind);
13263                sync_options
13264            }
13265            None => lsp::TextDocumentSyncOptions::default(),
13266        }
13267    }
13268
13269    #[cfg(any(test, feature = "test-support"))]
13270    pub fn forget_code_lens_task(&mut self, buffer_id: BufferId) -> Option<CodeLensTask> {
13271        Some(
13272            self.lsp_data
13273                .get_mut(&buffer_id)?
13274                .code_lens
13275                .take()?
13276                .update
13277                .take()?
13278                .1,
13279        )
13280    }
13281
13282    pub fn downstream_client(&self) -> Option<(AnyProtoClient, u64)> {
13283        self.downstream_client.clone()
13284    }
13285
13286    pub fn worktree_store(&self) -> Entity<WorktreeStore> {
13287        self.worktree_store.clone()
13288    }
13289
13290    /// Gets what's stored in the LSP data for the given buffer.
13291    pub fn current_lsp_data(&mut self, buffer_id: BufferId) -> Option<&mut BufferLspData> {
13292        self.lsp_data.get_mut(&buffer_id)
13293    }
13294
13295    /// Gets the most recent LSP data for the given buffer: if the data is absent or out of date,
13296    /// new [`BufferLspData`] will be created to replace the previous state.
13297    pub fn latest_lsp_data(&mut self, buffer: &Entity<Buffer>, cx: &mut App) -> &mut BufferLspData {
13298        let (buffer_id, buffer_version) =
13299            buffer.read_with(cx, |buffer, _| (buffer.remote_id(), buffer.version()));
13300        let lsp_data = self
13301            .lsp_data
13302            .entry(buffer_id)
13303            .or_insert_with(|| BufferLspData::new(buffer, cx));
13304        if buffer_version.changed_since(&lsp_data.buffer_version) {
13305            *lsp_data = BufferLspData::new(buffer, cx);
13306        }
13307        lsp_data
13308    }
13309}
13310
13311// Registration with registerOptions as null, should fallback to true.
13312// https://github.com/microsoft/vscode-languageserver-node/blob/d90a87f9557a0df9142cfb33e251cfa6fe27d970/client/src/common/client.ts#L2133
13313fn parse_register_capabilities<T: serde::de::DeserializeOwned>(
13314    reg: lsp::Registration,
13315) -> Result<OneOf<bool, T>> {
13316    Ok(match reg.register_options {
13317        Some(options) => OneOf::Right(serde_json::from_value::<T>(options)?),
13318        None => OneOf::Left(true),
13319    })
13320}
13321
13322fn subscribe_to_binary_statuses(
13323    languages: &Arc<LanguageRegistry>,
13324    cx: &mut Context<'_, LspStore>,
13325) -> Task<()> {
13326    let mut server_statuses = languages.language_server_binary_statuses();
13327    cx.spawn(async move |lsp_store, cx| {
13328        while let Some((server_name, binary_status)) = server_statuses.next().await {
13329            if lsp_store
13330                .update(cx, |_, cx| {
13331                    let mut message = None;
13332                    let binary_status = match binary_status {
13333                        BinaryStatus::None => proto::ServerBinaryStatus::None,
13334                        BinaryStatus::CheckingForUpdate => {
13335                            proto::ServerBinaryStatus::CheckingForUpdate
13336                        }
13337                        BinaryStatus::Downloading => proto::ServerBinaryStatus::Downloading,
13338                        BinaryStatus::Starting => proto::ServerBinaryStatus::Starting,
13339                        BinaryStatus::Stopping => proto::ServerBinaryStatus::Stopping,
13340                        BinaryStatus::Stopped => proto::ServerBinaryStatus::Stopped,
13341                        BinaryStatus::Failed { error } => {
13342                            message = Some(error);
13343                            proto::ServerBinaryStatus::Failed
13344                        }
13345                    };
13346                    cx.emit(LspStoreEvent::LanguageServerUpdate {
13347                        // Binary updates are about the binary that might not have any language server id at that point.
13348                        // Reuse `LanguageServerUpdate` for them and provide a fake id that won't be used on the receiver side.
13349                        language_server_id: LanguageServerId(0),
13350                        name: Some(server_name),
13351                        message: proto::update_language_server::Variant::StatusUpdate(
13352                            proto::StatusUpdate {
13353                                message,
13354                                status: Some(proto::status_update::Status::Binary(
13355                                    binary_status as i32,
13356                                )),
13357                            },
13358                        ),
13359                    });
13360                })
13361                .is_err()
13362            {
13363                break;
13364            }
13365        }
13366    })
13367}
13368
13369fn lsp_workspace_diagnostics_refresh(
13370    registration_id: Option<String>,
13371    options: DiagnosticServerCapabilities,
13372    server: Arc<LanguageServer>,
13373    cx: &mut Context<'_, LspStore>,
13374) -> Option<WorkspaceRefreshTask> {
13375    let identifier = workspace_diagnostic_identifier(&options)?;
13376    let registration_id_shared = registration_id.as_ref().map(SharedString::from);
13377
13378    let (progress_tx, mut progress_rx) = mpsc::channel(1);
13379    let (mut refresh_tx, mut refresh_rx) = mpsc::channel(1);
13380    refresh_tx.try_send(()).ok();
13381
13382    let workspace_query_language_server = cx.spawn(async move |lsp_store, cx| {
13383        let mut attempts = 0;
13384        let max_attempts = 50;
13385        let mut requests = 0;
13386
13387        loop {
13388            let Some(()) = refresh_rx.recv().await else {
13389                return;
13390            };
13391
13392            'request: loop {
13393                requests += 1;
13394                if attempts > max_attempts {
13395                    log::error!(
13396                        "Failed to pull workspace diagnostics {max_attempts} times, aborting"
13397                    );
13398                    return;
13399                }
13400                let backoff_millis = (50 * (1 << attempts)).clamp(30, 1000);
13401                cx.background_executor()
13402                    .timer(Duration::from_millis(backoff_millis))
13403                    .await;
13404                attempts += 1;
13405
13406                let Ok(previous_result_ids) = lsp_store.update(cx, |lsp_store, _| {
13407                    lsp_store
13408                        .result_ids_for_workspace_refresh(server.server_id(), &registration_id_shared)
13409                        .into_iter()
13410                        .filter_map(|(abs_path, result_id)| {
13411                            let uri = file_path_to_lsp_url(&abs_path).ok()?;
13412                            Some(lsp::PreviousResultId {
13413                                uri,
13414                                value: result_id.to_string(),
13415                            })
13416                        })
13417                        .collect()
13418                }) else {
13419                    return;
13420                };
13421
13422                let token = if let Some(registration_id) = &registration_id {
13423                    format!(
13424                        "workspace/diagnostic/{}/{requests}/{WORKSPACE_DIAGNOSTICS_TOKEN_START}{registration_id}",
13425                        server.server_id(),
13426                    )
13427                } else {
13428                    format!("workspace/diagnostic/{}/{requests}", server.server_id())
13429                };
13430
13431                progress_rx.try_recv().ok();
13432                let timer =
13433                    LanguageServer::default_request_timer(cx.background_executor().clone()).fuse();
13434                let progress = pin!(progress_rx.recv().fuse());
13435                let response_result = server
13436                    .request_with_timer::<lsp::WorkspaceDiagnosticRequest, _>(
13437                        lsp::WorkspaceDiagnosticParams {
13438                            previous_result_ids,
13439                            identifier: identifier.clone(),
13440                            work_done_progress_params: Default::default(),
13441                            partial_result_params: lsp::PartialResultParams {
13442                                partial_result_token: Some(lsp::ProgressToken::String(token)),
13443                            },
13444                        },
13445                        select(timer, progress).then(|either| match either {
13446                            Either::Left((message, ..)) => ready(message).left_future(),
13447                            Either::Right(..) => pending::<String>().right_future(),
13448                        }),
13449                    )
13450                    .await;
13451
13452                // https://microsoft.github.io/language-server-protocol/specifications/lsp/3.17/specification/#diagnostic_refresh
13453                // >  If a server closes a workspace diagnostic pull request the client should re-trigger the request.
13454                match response_result {
13455                    ConnectionResult::Timeout => {
13456                        log::error!("Timeout during workspace diagnostics pull");
13457                        continue 'request;
13458                    }
13459                    ConnectionResult::ConnectionReset => {
13460                        log::error!("Server closed a workspace diagnostics pull request");
13461                        continue 'request;
13462                    }
13463                    ConnectionResult::Result(Err(e)) => {
13464                        log::error!("Error during workspace diagnostics pull: {e:#}");
13465                        break 'request;
13466                    }
13467                    ConnectionResult::Result(Ok(pulled_diagnostics)) => {
13468                        attempts = 0;
13469                        if lsp_store
13470                            .update(cx, |lsp_store, cx| {
13471                                lsp_store.apply_workspace_diagnostic_report(
13472                                    server.server_id(),
13473                                    pulled_diagnostics,
13474                                    registration_id_shared.clone(),
13475                                    cx,
13476                                )
13477                            })
13478                            .is_err()
13479                        {
13480                            return;
13481                        }
13482                        break 'request;
13483                    }
13484                }
13485            }
13486        }
13487    });
13488
13489    Some(WorkspaceRefreshTask {
13490        refresh_tx,
13491        progress_tx,
13492        task: workspace_query_language_server,
13493    })
13494}
13495
13496fn buffer_diagnostic_identifier(options: &DiagnosticServerCapabilities) -> Option<String> {
13497    match &options {
13498        lsp::DiagnosticServerCapabilities::Options(diagnostic_options) => {
13499            diagnostic_options.identifier.clone()
13500        }
13501        lsp::DiagnosticServerCapabilities::RegistrationOptions(registration_options) => {
13502            let diagnostic_options = &registration_options.diagnostic_options;
13503            diagnostic_options.identifier.clone()
13504        }
13505    }
13506}
13507
13508fn workspace_diagnostic_identifier(
13509    options: &DiagnosticServerCapabilities,
13510) -> Option<Option<String>> {
13511    match &options {
13512        lsp::DiagnosticServerCapabilities::Options(diagnostic_options) => {
13513            if !diagnostic_options.workspace_diagnostics {
13514                return None;
13515            }
13516            Some(diagnostic_options.identifier.clone())
13517        }
13518        lsp::DiagnosticServerCapabilities::RegistrationOptions(registration_options) => {
13519            let diagnostic_options = &registration_options.diagnostic_options;
13520            if !diagnostic_options.workspace_diagnostics {
13521                return None;
13522            }
13523            Some(diagnostic_options.identifier.clone())
13524        }
13525    }
13526}
13527
13528fn resolve_word_completion(snapshot: &BufferSnapshot, completion: &mut Completion) {
13529    let CompletionSource::BufferWord {
13530        word_range,
13531        resolved,
13532    } = &mut completion.source
13533    else {
13534        return;
13535    };
13536    if *resolved {
13537        return;
13538    }
13539
13540    if completion.new_text
13541        != snapshot
13542            .text_for_range(word_range.clone())
13543            .collect::<String>()
13544    {
13545        return;
13546    }
13547
13548    let mut offset = 0;
13549    for chunk in snapshot.chunks(word_range.clone(), true) {
13550        let end_offset = offset + chunk.text.len();
13551        if let Some(highlight_id) = chunk.syntax_highlight_id {
13552            completion
13553                .label
13554                .runs
13555                .push((offset..end_offset, highlight_id));
13556        }
13557        offset = end_offset;
13558    }
13559    *resolved = true;
13560}
13561
13562impl EventEmitter<LspStoreEvent> for LspStore {}
13563
13564fn remove_empty_hover_blocks(mut hover: Hover) -> Option<Hover> {
13565    hover
13566        .contents
13567        .retain(|hover_block| !hover_block.text.trim().is_empty());
13568    if hover.contents.is_empty() {
13569        None
13570    } else {
13571        Some(hover)
13572    }
13573}
13574
13575async fn populate_labels_for_completions(
13576    new_completions: Vec<CoreCompletion>,
13577    language: Option<Arc<Language>>,
13578    lsp_adapter: Option<Arc<CachedLspAdapter>>,
13579) -> Vec<Completion> {
13580    let lsp_completions = new_completions
13581        .iter()
13582        .filter_map(|new_completion| {
13583            new_completion
13584                .source
13585                .lsp_completion(true)
13586                .map(|lsp_completion| lsp_completion.into_owned())
13587        })
13588        .collect::<Vec<_>>();
13589
13590    let mut labels = if let Some((language, lsp_adapter)) = language.as_ref().zip(lsp_adapter) {
13591        lsp_adapter
13592            .labels_for_completions(&lsp_completions, language)
13593            .await
13594            .log_err()
13595            .unwrap_or_default()
13596    } else {
13597        Vec::new()
13598    }
13599    .into_iter()
13600    .fuse();
13601
13602    let mut completions = Vec::new();
13603    for completion in new_completions {
13604        match completion.source.lsp_completion(true) {
13605            Some(lsp_completion) => {
13606                let documentation = lsp_completion.documentation.clone().map(|docs| docs.into());
13607
13608                let mut label = labels.next().flatten().unwrap_or_else(|| {
13609                    CodeLabel::fallback_for_completion(&lsp_completion, language.as_deref())
13610                });
13611                ensure_uniform_list_compatible_label(&mut label);
13612                completions.push(Completion {
13613                    label,
13614                    documentation,
13615                    replace_range: completion.replace_range,
13616                    new_text: completion.new_text,
13617                    insert_text_mode: lsp_completion.insert_text_mode,
13618                    source: completion.source,
13619                    icon_path: None,
13620                    confirm: None,
13621                    match_start: None,
13622                    snippet_deduplication_key: None,
13623                });
13624            }
13625            None => {
13626                let mut label = CodeLabel::plain(completion.new_text.clone(), None);
13627                ensure_uniform_list_compatible_label(&mut label);
13628                completions.push(Completion {
13629                    label,
13630                    documentation: None,
13631                    replace_range: completion.replace_range,
13632                    new_text: completion.new_text,
13633                    source: completion.source,
13634                    insert_text_mode: None,
13635                    icon_path: None,
13636                    confirm: None,
13637                    match_start: None,
13638                    snippet_deduplication_key: None,
13639                });
13640            }
13641        }
13642    }
13643    completions
13644}
13645
13646#[derive(Debug)]
13647pub enum LanguageServerToQuery {
13648    /// Query language servers in order of users preference, up until one capable of handling the request is found.
13649    FirstCapable,
13650    /// Query a specific language server.
13651    Other(LanguageServerId),
13652}
13653
13654#[derive(Default)]
13655struct RenamePathsWatchedForServer {
13656    did_rename: Vec<RenameActionPredicate>,
13657    will_rename: Vec<RenameActionPredicate>,
13658}
13659
13660impl RenamePathsWatchedForServer {
13661    fn with_did_rename_patterns(
13662        mut self,
13663        did_rename: Option<&FileOperationRegistrationOptions>,
13664    ) -> Self {
13665        if let Some(did_rename) = did_rename {
13666            self.did_rename = did_rename
13667                .filters
13668                .iter()
13669                .filter_map(|filter| filter.try_into().log_err())
13670                .collect();
13671        }
13672        self
13673    }
13674    fn with_will_rename_patterns(
13675        mut self,
13676        will_rename: Option<&FileOperationRegistrationOptions>,
13677    ) -> Self {
13678        if let Some(will_rename) = will_rename {
13679            self.will_rename = will_rename
13680                .filters
13681                .iter()
13682                .filter_map(|filter| filter.try_into().log_err())
13683                .collect();
13684        }
13685        self
13686    }
13687
13688    fn should_send_did_rename(&self, path: &str, is_dir: bool) -> bool {
13689        self.did_rename.iter().any(|pred| pred.eval(path, is_dir))
13690    }
13691    fn should_send_will_rename(&self, path: &str, is_dir: bool) -> bool {
13692        self.will_rename.iter().any(|pred| pred.eval(path, is_dir))
13693    }
13694}
13695
13696impl TryFrom<&FileOperationFilter> for RenameActionPredicate {
13697    type Error = globset::Error;
13698    fn try_from(ops: &FileOperationFilter) -> Result<Self, globset::Error> {
13699        Ok(Self {
13700            kind: ops.pattern.matches.clone(),
13701            glob: GlobBuilder::new(&ops.pattern.glob)
13702                .case_insensitive(
13703                    ops.pattern
13704                        .options
13705                        .as_ref()
13706                        .is_some_and(|ops| ops.ignore_case.unwrap_or(false)),
13707                )
13708                .build()?
13709                .compile_matcher(),
13710        })
13711    }
13712}
13713struct RenameActionPredicate {
13714    glob: GlobMatcher,
13715    kind: Option<FileOperationPatternKind>,
13716}
13717
13718impl RenameActionPredicate {
13719    // Returns true if language server should be notified
13720    fn eval(&self, path: &str, is_dir: bool) -> bool {
13721        self.kind.as_ref().is_none_or(|kind| {
13722            let expected_kind = if is_dir {
13723                FileOperationPatternKind::Folder
13724            } else {
13725                FileOperationPatternKind::File
13726            };
13727            kind == &expected_kind
13728        }) && self.glob.is_match(path)
13729    }
13730}
13731
13732#[derive(Default)]
13733struct LanguageServerWatchedPaths {
13734    worktree_paths: HashMap<WorktreeId, GlobSet>,
13735    abs_paths: HashMap<Arc<Path>, (GlobSet, Task<()>)>,
13736}
13737
13738#[derive(Default)]
13739struct LanguageServerWatchedPathsBuilder {
13740    worktree_paths: HashMap<WorktreeId, GlobSet>,
13741    abs_paths: HashMap<Arc<Path>, GlobSet>,
13742}
13743
13744impl LanguageServerWatchedPathsBuilder {
13745    fn watch_worktree(&mut self, worktree_id: WorktreeId, glob_set: GlobSet) {
13746        self.worktree_paths.insert(worktree_id, glob_set);
13747    }
13748    fn watch_abs_path(&mut self, path: Arc<Path>, glob_set: GlobSet) {
13749        self.abs_paths.insert(path, glob_set);
13750    }
13751    fn build(
13752        self,
13753        fs: Arc<dyn Fs>,
13754        language_server_id: LanguageServerId,
13755        cx: &mut Context<LspStore>,
13756    ) -> LanguageServerWatchedPaths {
13757        let lsp_store = cx.weak_entity();
13758
13759        const LSP_ABS_PATH_OBSERVE: Duration = Duration::from_millis(100);
13760        let abs_paths = self
13761            .abs_paths
13762            .into_iter()
13763            .map(|(abs_path, globset)| {
13764                let task = cx.spawn({
13765                    let abs_path = abs_path.clone();
13766                    let fs = fs.clone();
13767
13768                    let lsp_store = lsp_store.clone();
13769                    async move |_, cx| {
13770                        maybe!(async move {
13771                            let mut push_updates = fs.watch(&abs_path, LSP_ABS_PATH_OBSERVE).await;
13772                            while let Some(update) = push_updates.0.next().await {
13773                                let action = lsp_store
13774                                    .update(cx, |this, _| {
13775                                        let Some(local) = this.as_local() else {
13776                                            return ControlFlow::Break(());
13777                                        };
13778                                        let Some(watcher) = local
13779                                            .language_server_watched_paths
13780                                            .get(&language_server_id)
13781                                        else {
13782                                            return ControlFlow::Break(());
13783                                        };
13784                                        let (globs, _) = watcher.abs_paths.get(&abs_path).expect(
13785                                            "Watched abs path is not registered with a watcher",
13786                                        );
13787                                        let matching_entries = update
13788                                            .into_iter()
13789                                            .filter(|event| globs.is_match(&event.path))
13790                                            .collect::<Vec<_>>();
13791                                        this.lsp_notify_abs_paths_changed(
13792                                            language_server_id,
13793                                            matching_entries,
13794                                        );
13795                                        ControlFlow::Continue(())
13796                                    })
13797                                    .ok()?;
13798
13799                                if action.is_break() {
13800                                    break;
13801                                }
13802                            }
13803                            Some(())
13804                        })
13805                        .await;
13806                    }
13807                });
13808                (abs_path, (globset, task))
13809            })
13810            .collect();
13811        LanguageServerWatchedPaths {
13812            worktree_paths: self.worktree_paths,
13813            abs_paths,
13814        }
13815    }
13816}
13817
13818struct LspBufferSnapshot {
13819    version: i32,
13820    snapshot: TextBufferSnapshot,
13821}
13822
13823/// A prompt requested by LSP server.
13824#[derive(Clone, Debug)]
13825pub struct LanguageServerPromptRequest {
13826    pub id: usize,
13827    pub level: PromptLevel,
13828    pub message: String,
13829    pub actions: Vec<MessageActionItem>,
13830    pub lsp_name: String,
13831    pub(crate) response_channel: smol::channel::Sender<MessageActionItem>,
13832}
13833
13834impl LanguageServerPromptRequest {
13835    pub fn new(
13836        level: PromptLevel,
13837        message: String,
13838        actions: Vec<MessageActionItem>,
13839        lsp_name: String,
13840        response_channel: smol::channel::Sender<MessageActionItem>,
13841    ) -> Self {
13842        let id = NEXT_PROMPT_REQUEST_ID.fetch_add(1, atomic::Ordering::AcqRel);
13843        LanguageServerPromptRequest {
13844            id,
13845            level,
13846            message,
13847            actions,
13848            lsp_name,
13849            response_channel,
13850        }
13851    }
13852    pub async fn respond(self, index: usize) -> Option<()> {
13853        if let Some(response) = self.actions.into_iter().nth(index) {
13854            self.response_channel.send(response).await.ok()
13855        } else {
13856            None
13857        }
13858    }
13859
13860    #[cfg(any(test, feature = "test-support"))]
13861    pub fn test(
13862        level: PromptLevel,
13863        message: String,
13864        actions: Vec<MessageActionItem>,
13865        lsp_name: String,
13866    ) -> Self {
13867        let (tx, _rx) = smol::channel::unbounded();
13868        LanguageServerPromptRequest::new(level, message, actions, lsp_name, tx)
13869    }
13870}
13871impl PartialEq for LanguageServerPromptRequest {
13872    fn eq(&self, other: &Self) -> bool {
13873        self.message == other.message && self.actions == other.actions
13874    }
13875}
13876
13877#[derive(Clone, Debug, PartialEq)]
13878pub enum LanguageServerLogType {
13879    Log(MessageType),
13880    Trace { verbose_info: Option<String> },
13881    Rpc { received: bool },
13882}
13883
13884impl LanguageServerLogType {
13885    pub fn to_proto(&self) -> proto::language_server_log::LogType {
13886        match self {
13887            Self::Log(log_type) => {
13888                use proto::log_message::LogLevel;
13889                let level = match *log_type {
13890                    MessageType::ERROR => LogLevel::Error,
13891                    MessageType::WARNING => LogLevel::Warning,
13892                    MessageType::INFO => LogLevel::Info,
13893                    MessageType::LOG => LogLevel::Log,
13894                    other => {
13895                        log::warn!("Unknown lsp log message type: {other:?}");
13896                        LogLevel::Log
13897                    }
13898                };
13899                proto::language_server_log::LogType::Log(proto::LogMessage {
13900                    level: level as i32,
13901                })
13902            }
13903            Self::Trace { verbose_info } => {
13904                proto::language_server_log::LogType::Trace(proto::TraceMessage {
13905                    verbose_info: verbose_info.to_owned(),
13906                })
13907            }
13908            Self::Rpc { received } => {
13909                let kind = if *received {
13910                    proto::rpc_message::Kind::Received
13911                } else {
13912                    proto::rpc_message::Kind::Sent
13913                };
13914                let kind = kind as i32;
13915                proto::language_server_log::LogType::Rpc(proto::RpcMessage { kind })
13916            }
13917        }
13918    }
13919
13920    pub fn from_proto(log_type: proto::language_server_log::LogType) -> Self {
13921        use proto::log_message::LogLevel;
13922        use proto::rpc_message;
13923        match log_type {
13924            proto::language_server_log::LogType::Log(message_type) => Self::Log(
13925                match LogLevel::from_i32(message_type.level).unwrap_or(LogLevel::Log) {
13926                    LogLevel::Error => MessageType::ERROR,
13927                    LogLevel::Warning => MessageType::WARNING,
13928                    LogLevel::Info => MessageType::INFO,
13929                    LogLevel::Log => MessageType::LOG,
13930                },
13931            ),
13932            proto::language_server_log::LogType::Trace(trace_message) => Self::Trace {
13933                verbose_info: trace_message.verbose_info,
13934            },
13935            proto::language_server_log::LogType::Rpc(message) => Self::Rpc {
13936                received: match rpc_message::Kind::from_i32(message.kind)
13937                    .unwrap_or(rpc_message::Kind::Received)
13938                {
13939                    rpc_message::Kind::Received => true,
13940                    rpc_message::Kind::Sent => false,
13941                },
13942            },
13943        }
13944    }
13945}
13946
13947pub struct WorkspaceRefreshTask {
13948    refresh_tx: mpsc::Sender<()>,
13949    progress_tx: mpsc::Sender<()>,
13950    #[allow(dead_code)]
13951    task: Task<()>,
13952}
13953
13954pub enum LanguageServerState {
13955    Starting {
13956        startup: Task<Option<Arc<LanguageServer>>>,
13957        /// List of language servers that will be added to the workspace once it's initialization completes.
13958        pending_workspace_folders: Arc<Mutex<BTreeSet<Uri>>>,
13959    },
13960
13961    Running {
13962        adapter: Arc<CachedLspAdapter>,
13963        server: Arc<LanguageServer>,
13964        simulate_disk_based_diagnostics_completion: Option<Task<()>>,
13965        workspace_diagnostics_refresh_tasks: HashMap<Option<String>, WorkspaceRefreshTask>,
13966    },
13967}
13968
13969impl LanguageServerState {
13970    fn add_workspace_folder(&self, uri: Uri) {
13971        match self {
13972            LanguageServerState::Starting {
13973                pending_workspace_folders,
13974                ..
13975            } => {
13976                pending_workspace_folders.lock().insert(uri);
13977            }
13978            LanguageServerState::Running { server, .. } => {
13979                server.add_workspace_folder(uri);
13980            }
13981        }
13982    }
13983    fn _remove_workspace_folder(&self, uri: Uri) {
13984        match self {
13985            LanguageServerState::Starting {
13986                pending_workspace_folders,
13987                ..
13988            } => {
13989                pending_workspace_folders.lock().remove(&uri);
13990            }
13991            LanguageServerState::Running { server, .. } => server.remove_workspace_folder(uri),
13992        }
13993    }
13994}
13995
13996impl std::fmt::Debug for LanguageServerState {
13997    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
13998        match self {
13999            LanguageServerState::Starting { .. } => {
14000                f.debug_struct("LanguageServerState::Starting").finish()
14001            }
14002            LanguageServerState::Running { .. } => {
14003                f.debug_struct("LanguageServerState::Running").finish()
14004            }
14005        }
14006    }
14007}
14008
14009#[derive(Clone, Debug, Serialize)]
14010pub struct LanguageServerProgress {
14011    pub is_disk_based_diagnostics_progress: bool,
14012    pub is_cancellable: bool,
14013    pub title: Option<String>,
14014    pub message: Option<String>,
14015    pub percentage: Option<usize>,
14016    #[serde(skip_serializing)]
14017    pub last_update_at: Instant,
14018}
14019
14020#[derive(Copy, Clone, Debug, Default, PartialEq, Serialize)]
14021pub struct DiagnosticSummary {
14022    pub error_count: usize,
14023    pub warning_count: usize,
14024}
14025
14026impl DiagnosticSummary {
14027    pub fn new<'a, T: 'a>(diagnostics: impl IntoIterator<Item = &'a DiagnosticEntry<T>>) -> Self {
14028        let mut this = Self {
14029            error_count: 0,
14030            warning_count: 0,
14031        };
14032
14033        for entry in diagnostics {
14034            if entry.diagnostic.is_primary {
14035                match entry.diagnostic.severity {
14036                    DiagnosticSeverity::ERROR => this.error_count += 1,
14037                    DiagnosticSeverity::WARNING => this.warning_count += 1,
14038                    _ => {}
14039                }
14040            }
14041        }
14042
14043        this
14044    }
14045
14046    pub fn is_empty(&self) -> bool {
14047        self.error_count == 0 && self.warning_count == 0
14048    }
14049
14050    pub fn to_proto(
14051        self,
14052        language_server_id: LanguageServerId,
14053        path: &RelPath,
14054    ) -> proto::DiagnosticSummary {
14055        proto::DiagnosticSummary {
14056            path: path.to_proto(),
14057            language_server_id: language_server_id.0 as u64,
14058            error_count: self.error_count as u32,
14059            warning_count: self.warning_count as u32,
14060        }
14061    }
14062}
14063
14064#[derive(Clone, Debug)]
14065pub enum CompletionDocumentation {
14066    /// There is no documentation for this completion.
14067    Undocumented,
14068    /// A single line of documentation.
14069    SingleLine(SharedString),
14070    /// Multiple lines of plain text documentation.
14071    MultiLinePlainText(SharedString),
14072    /// Markdown documentation.
14073    MultiLineMarkdown(SharedString),
14074    /// Both single line and multiple lines of plain text documentation.
14075    SingleLineAndMultiLinePlainText {
14076        single_line: SharedString,
14077        plain_text: Option<SharedString>,
14078    },
14079}
14080
14081impl CompletionDocumentation {
14082    #[cfg(any(test, feature = "test-support"))]
14083    pub fn text(&self) -> SharedString {
14084        match self {
14085            CompletionDocumentation::Undocumented => "".into(),
14086            CompletionDocumentation::SingleLine(s) => s.clone(),
14087            CompletionDocumentation::MultiLinePlainText(s) => s.clone(),
14088            CompletionDocumentation::MultiLineMarkdown(s) => s.clone(),
14089            CompletionDocumentation::SingleLineAndMultiLinePlainText { single_line, .. } => {
14090                single_line.clone()
14091            }
14092        }
14093    }
14094}
14095
14096impl From<lsp::Documentation> for CompletionDocumentation {
14097    fn from(docs: lsp::Documentation) -> Self {
14098        match docs {
14099            lsp::Documentation::String(text) => {
14100                if text.lines().count() <= 1 {
14101                    CompletionDocumentation::SingleLine(text.trim().to_string().into())
14102                } else {
14103                    CompletionDocumentation::MultiLinePlainText(text.into())
14104                }
14105            }
14106
14107            lsp::Documentation::MarkupContent(lsp::MarkupContent { kind, value }) => match kind {
14108                lsp::MarkupKind::PlainText => {
14109                    if value.lines().count() <= 1 {
14110                        CompletionDocumentation::SingleLine(value.into())
14111                    } else {
14112                        CompletionDocumentation::MultiLinePlainText(value.into())
14113                    }
14114                }
14115
14116                lsp::MarkupKind::Markdown => {
14117                    CompletionDocumentation::MultiLineMarkdown(value.into())
14118                }
14119            },
14120        }
14121    }
14122}
14123
14124pub enum ResolvedHint {
14125    Resolved(InlayHint),
14126    Resolving(Shared<Task<()>>),
14127}
14128
14129pub fn glob_literal_prefix(glob: &Path) -> PathBuf {
14130    glob.components()
14131        .take_while(|component| match component {
14132            path::Component::Normal(part) => !part.to_string_lossy().contains(['*', '?', '{', '}']),
14133            _ => true,
14134        })
14135        .collect()
14136}
14137
14138pub struct SshLspAdapter {
14139    name: LanguageServerName,
14140    binary: LanguageServerBinary,
14141    initialization_options: Option<String>,
14142    code_action_kinds: Option<Vec<CodeActionKind>>,
14143}
14144
14145impl SshLspAdapter {
14146    pub fn new(
14147        name: LanguageServerName,
14148        binary: LanguageServerBinary,
14149        initialization_options: Option<String>,
14150        code_action_kinds: Option<String>,
14151    ) -> Self {
14152        Self {
14153            name,
14154            binary,
14155            initialization_options,
14156            code_action_kinds: code_action_kinds
14157                .as_ref()
14158                .and_then(|c| serde_json::from_str(c).ok()),
14159        }
14160    }
14161}
14162
14163impl LspInstaller for SshLspAdapter {
14164    type BinaryVersion = ();
14165    async fn check_if_user_installed(
14166        &self,
14167        _: &dyn LspAdapterDelegate,
14168        _: Option<Toolchain>,
14169        _: &AsyncApp,
14170    ) -> Option<LanguageServerBinary> {
14171        Some(self.binary.clone())
14172    }
14173
14174    async fn cached_server_binary(
14175        &self,
14176        _: PathBuf,
14177        _: &dyn LspAdapterDelegate,
14178    ) -> Option<LanguageServerBinary> {
14179        None
14180    }
14181
14182    async fn fetch_latest_server_version(
14183        &self,
14184        _: &dyn LspAdapterDelegate,
14185        _: bool,
14186        _: &mut AsyncApp,
14187    ) -> Result<()> {
14188        anyhow::bail!("SshLspAdapter does not support fetch_latest_server_version")
14189    }
14190
14191    async fn fetch_server_binary(
14192        &self,
14193        _: (),
14194        _: PathBuf,
14195        _: &dyn LspAdapterDelegate,
14196    ) -> Result<LanguageServerBinary> {
14197        anyhow::bail!("SshLspAdapter does not support fetch_server_binary")
14198    }
14199}
14200
14201#[async_trait(?Send)]
14202impl LspAdapter for SshLspAdapter {
14203    fn name(&self) -> LanguageServerName {
14204        self.name.clone()
14205    }
14206
14207    async fn initialization_options(
14208        self: Arc<Self>,
14209        _: &Arc<dyn LspAdapterDelegate>,
14210    ) -> Result<Option<serde_json::Value>> {
14211        let Some(options) = &self.initialization_options else {
14212            return Ok(None);
14213        };
14214        let result = serde_json::from_str(options)?;
14215        Ok(result)
14216    }
14217
14218    fn code_action_kinds(&self) -> Option<Vec<CodeActionKind>> {
14219        self.code_action_kinds.clone()
14220    }
14221}
14222
14223pub fn language_server_settings<'a>(
14224    delegate: &'a dyn LspAdapterDelegate,
14225    language: &LanguageServerName,
14226    cx: &'a App,
14227) -> Option<&'a LspSettings> {
14228    language_server_settings_for(
14229        SettingsLocation {
14230            worktree_id: delegate.worktree_id(),
14231            path: RelPath::empty(),
14232        },
14233        language,
14234        cx,
14235    )
14236}
14237
14238pub fn language_server_settings_for<'a>(
14239    location: SettingsLocation<'a>,
14240    language: &LanguageServerName,
14241    cx: &'a App,
14242) -> Option<&'a LspSettings> {
14243    ProjectSettings::get(Some(location), cx).lsp.get(language)
14244}
14245
14246pub struct LocalLspAdapterDelegate {
14247    lsp_store: WeakEntity<LspStore>,
14248    worktree: worktree::Snapshot,
14249    fs: Arc<dyn Fs>,
14250    http_client: Arc<dyn HttpClient>,
14251    language_registry: Arc<LanguageRegistry>,
14252    load_shell_env_task: Shared<Task<Option<HashMap<String, String>>>>,
14253}
14254
14255impl LocalLspAdapterDelegate {
14256    pub fn new(
14257        language_registry: Arc<LanguageRegistry>,
14258        environment: &Entity<ProjectEnvironment>,
14259        lsp_store: WeakEntity<LspStore>,
14260        worktree: &Entity<Worktree>,
14261        http_client: Arc<dyn HttpClient>,
14262        fs: Arc<dyn Fs>,
14263        cx: &mut App,
14264    ) -> Arc<Self> {
14265        let load_shell_env_task =
14266            environment.update(cx, |env, cx| env.worktree_environment(worktree.clone(), cx));
14267
14268        Arc::new(Self {
14269            lsp_store,
14270            worktree: worktree.read(cx).snapshot(),
14271            fs,
14272            http_client,
14273            language_registry,
14274            load_shell_env_task,
14275        })
14276    }
14277
14278    pub fn from_local_lsp(
14279        local: &LocalLspStore,
14280        worktree: &Entity<Worktree>,
14281        cx: &mut App,
14282    ) -> Arc<Self> {
14283        Self::new(
14284            local.languages.clone(),
14285            &local.environment,
14286            local.weak.clone(),
14287            worktree,
14288            local.http_client.clone(),
14289            local.fs.clone(),
14290            cx,
14291        )
14292    }
14293}
14294
14295#[async_trait]
14296impl LspAdapterDelegate for LocalLspAdapterDelegate {
14297    fn show_notification(&self, message: &str, cx: &mut App) {
14298        self.lsp_store
14299            .update(cx, |_, cx| {
14300                cx.emit(LspStoreEvent::Notification(message.to_owned()))
14301            })
14302            .ok();
14303    }
14304
14305    fn http_client(&self) -> Arc<dyn HttpClient> {
14306        self.http_client.clone()
14307    }
14308
14309    fn worktree_id(&self) -> WorktreeId {
14310        self.worktree.id()
14311    }
14312
14313    fn worktree_root_path(&self) -> &Path {
14314        self.worktree.abs_path().as_ref()
14315    }
14316
14317    fn resolve_executable_path(&self, path: PathBuf) -> PathBuf {
14318        self.worktree.resolve_executable_path(path)
14319    }
14320
14321    async fn shell_env(&self) -> HashMap<String, String> {
14322        let task = self.load_shell_env_task.clone();
14323        task.await.unwrap_or_default()
14324    }
14325
14326    async fn npm_package_installed_version(
14327        &self,
14328        package_name: &str,
14329    ) -> Result<Option<(PathBuf, Version)>> {
14330        let local_package_directory = self.worktree_root_path();
14331        let node_modules_directory = local_package_directory.join("node_modules");
14332
14333        if let Some(version) =
14334            read_package_installed_version(node_modules_directory.clone(), package_name).await?
14335        {
14336            return Ok(Some((node_modules_directory, version)));
14337        }
14338        let Some(npm) = self.which("npm".as_ref()).await else {
14339            log::warn!(
14340                "Failed to find npm executable for {:?}",
14341                local_package_directory
14342            );
14343            return Ok(None);
14344        };
14345
14346        let env = self.shell_env().await;
14347        let output = util::command::new_smol_command(&npm)
14348            .args(["root", "-g"])
14349            .envs(env)
14350            .current_dir(local_package_directory)
14351            .output()
14352            .await?;
14353        let global_node_modules =
14354            PathBuf::from(String::from_utf8_lossy(&output.stdout).to_string());
14355
14356        if let Some(version) =
14357            read_package_installed_version(global_node_modules.clone(), package_name).await?
14358        {
14359            return Ok(Some((global_node_modules, version)));
14360        }
14361        return Ok(None);
14362    }
14363
14364    async fn which(&self, command: &OsStr) -> Option<PathBuf> {
14365        let mut worktree_abs_path = self.worktree_root_path().to_path_buf();
14366        if self.fs.is_file(&worktree_abs_path).await {
14367            worktree_abs_path.pop();
14368        }
14369
14370        let env = self.shell_env().await;
14371
14372        let shell_path = env.get("PATH").cloned();
14373
14374        which::which_in(command, shell_path.as_ref(), worktree_abs_path).ok()
14375    }
14376
14377    async fn try_exec(&self, command: LanguageServerBinary) -> Result<()> {
14378        let mut working_dir = self.worktree_root_path().to_path_buf();
14379        if self.fs.is_file(&working_dir).await {
14380            working_dir.pop();
14381        }
14382        let output = util::command::new_smol_command(&command.path)
14383            .args(command.arguments)
14384            .envs(command.env.clone().unwrap_or_default())
14385            .current_dir(working_dir)
14386            .output()
14387            .await?;
14388
14389        anyhow::ensure!(
14390            output.status.success(),
14391            "{}, stdout: {:?}, stderr: {:?}",
14392            output.status,
14393            String::from_utf8_lossy(&output.stdout),
14394            String::from_utf8_lossy(&output.stderr)
14395        );
14396        Ok(())
14397    }
14398
14399    fn update_status(&self, server_name: LanguageServerName, status: language::BinaryStatus) {
14400        self.language_registry
14401            .update_lsp_binary_status(server_name, status);
14402    }
14403
14404    fn registered_lsp_adapters(&self) -> Vec<Arc<dyn LspAdapter>> {
14405        self.language_registry
14406            .all_lsp_adapters()
14407            .into_iter()
14408            .map(|adapter| adapter.adapter.clone() as Arc<dyn LspAdapter>)
14409            .collect()
14410    }
14411
14412    async fn language_server_download_dir(&self, name: &LanguageServerName) -> Option<Arc<Path>> {
14413        let dir = self.language_registry.language_server_download_dir(name)?;
14414
14415        if !dir.exists() {
14416            smol::fs::create_dir_all(&dir)
14417                .await
14418                .context("failed to create container directory")
14419                .log_err()?;
14420        }
14421
14422        Some(dir)
14423    }
14424
14425    async fn read_text_file(&self, path: &RelPath) -> Result<String> {
14426        let entry = self
14427            .worktree
14428            .entry_for_path(path)
14429            .with_context(|| format!("no worktree entry for path {path:?}"))?;
14430        let abs_path = self.worktree.absolutize(&entry.path);
14431        self.fs.load(&abs_path).await
14432    }
14433}
14434
14435async fn populate_labels_for_symbols(
14436    symbols: Vec<CoreSymbol>,
14437    language_registry: &Arc<LanguageRegistry>,
14438    lsp_adapter: Option<Arc<CachedLspAdapter>>,
14439    output: &mut Vec<Symbol>,
14440) {
14441    #[allow(clippy::mutable_key_type)]
14442    let mut symbols_by_language = HashMap::<Option<Arc<Language>>, Vec<CoreSymbol>>::default();
14443
14444    let mut unknown_paths = BTreeSet::<Arc<str>>::new();
14445    for symbol in symbols {
14446        let Some(file_name) = symbol.path.file_name() else {
14447            continue;
14448        };
14449        let language = language_registry
14450            .load_language_for_file_path(Path::new(file_name))
14451            .await
14452            .ok()
14453            .or_else(|| {
14454                unknown_paths.insert(file_name.into());
14455                None
14456            });
14457        symbols_by_language
14458            .entry(language)
14459            .or_default()
14460            .push(symbol);
14461    }
14462
14463    for unknown_path in unknown_paths {
14464        log::info!("no language found for symbol in file {unknown_path:?}");
14465    }
14466
14467    let mut label_params = Vec::new();
14468    for (language, mut symbols) in symbols_by_language {
14469        label_params.clear();
14470        label_params.extend(
14471            symbols
14472                .iter_mut()
14473                .map(|symbol| (mem::take(&mut symbol.name), symbol.kind)),
14474        );
14475
14476        let mut labels = Vec::new();
14477        if let Some(language) = language {
14478            let lsp_adapter = lsp_adapter.clone().or_else(|| {
14479                language_registry
14480                    .lsp_adapters(&language.name())
14481                    .first()
14482                    .cloned()
14483            });
14484            if let Some(lsp_adapter) = lsp_adapter {
14485                labels = lsp_adapter
14486                    .labels_for_symbols(&label_params, &language)
14487                    .await
14488                    .log_err()
14489                    .unwrap_or_default();
14490            }
14491        }
14492
14493        for ((symbol, (name, _)), label) in symbols
14494            .into_iter()
14495            .zip(label_params.drain(..))
14496            .zip(labels.into_iter().chain(iter::repeat(None)))
14497        {
14498            output.push(Symbol {
14499                language_server_name: symbol.language_server_name,
14500                source_worktree_id: symbol.source_worktree_id,
14501                source_language_server_id: symbol.source_language_server_id,
14502                path: symbol.path,
14503                label: label.unwrap_or_else(|| CodeLabel::plain(name.clone(), None)),
14504                name,
14505                kind: symbol.kind,
14506                range: symbol.range,
14507            });
14508        }
14509    }
14510}
14511
14512fn include_text(server: &lsp::LanguageServer) -> Option<bool> {
14513    match server.capabilities().text_document_sync.as_ref()? {
14514        lsp::TextDocumentSyncCapability::Options(opts) => match opts.save.as_ref()? {
14515            // Server wants didSave but didn't specify includeText.
14516            lsp::TextDocumentSyncSaveOptions::Supported(true) => Some(false),
14517            // Server doesn't want didSave at all.
14518            lsp::TextDocumentSyncSaveOptions::Supported(false) => None,
14519            // Server provided SaveOptions.
14520            lsp::TextDocumentSyncSaveOptions::SaveOptions(save_options) => {
14521                Some(save_options.include_text.unwrap_or(false))
14522            }
14523        },
14524        // We do not have any save info. Kind affects didChange only.
14525        lsp::TextDocumentSyncCapability::Kind(_) => None,
14526    }
14527}
14528
14529/// Completion items are displayed in a `UniformList`.
14530/// Usually, those items are single-line strings, but in LSP responses,
14531/// completion items `label`, `detail` and `label_details.description` may contain newlines or long spaces.
14532/// Many language plugins construct these items by joining these parts together, and we may use `CodeLabel::fallback_for_completion` that uses `label` at least.
14533/// 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,
14534/// breaking the completions menu presentation.
14535///
14536/// 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.
14537pub fn ensure_uniform_list_compatible_label(label: &mut CodeLabel) {
14538    let mut new_text = String::with_capacity(label.text.len());
14539    let mut offset_map = vec![0; label.text.len() + 1];
14540    let mut last_char_was_space = false;
14541    let mut new_idx = 0;
14542    let chars = label.text.char_indices().fuse();
14543    let mut newlines_removed = false;
14544
14545    for (idx, c) in chars {
14546        offset_map[idx] = new_idx;
14547
14548        match c {
14549            '\n' if last_char_was_space => {
14550                newlines_removed = true;
14551            }
14552            '\t' | ' ' if last_char_was_space => {}
14553            '\n' if !last_char_was_space => {
14554                new_text.push(' ');
14555                new_idx += 1;
14556                last_char_was_space = true;
14557                newlines_removed = true;
14558            }
14559            ' ' | '\t' => {
14560                new_text.push(' ');
14561                new_idx += 1;
14562                last_char_was_space = true;
14563            }
14564            _ => {
14565                new_text.push(c);
14566                new_idx += c.len_utf8();
14567                last_char_was_space = false;
14568            }
14569        }
14570    }
14571    offset_map[label.text.len()] = new_idx;
14572
14573    // Only modify the label if newlines were removed.
14574    if !newlines_removed {
14575        return;
14576    }
14577
14578    let last_index = new_idx;
14579    let mut run_ranges_errors = Vec::new();
14580    label.runs.retain_mut(|(range, _)| {
14581        match offset_map.get(range.start) {
14582            Some(&start) => range.start = start,
14583            None => {
14584                run_ranges_errors.push(range.clone());
14585                return false;
14586            }
14587        }
14588
14589        match offset_map.get(range.end) {
14590            Some(&end) => range.end = end,
14591            None => {
14592                run_ranges_errors.push(range.clone());
14593                range.end = last_index;
14594            }
14595        }
14596        true
14597    });
14598    if !run_ranges_errors.is_empty() {
14599        log::error!(
14600            "Completion label has errors in its run ranges: {run_ranges_errors:?}, label text: {}",
14601            label.text
14602        );
14603    }
14604
14605    let mut wrong_filter_range = None;
14606    if label.filter_range == (0..label.text.len()) {
14607        label.filter_range = 0..new_text.len();
14608    } else {
14609        let mut original_filter_range = Some(label.filter_range.clone());
14610        match offset_map.get(label.filter_range.start) {
14611            Some(&start) => label.filter_range.start = start,
14612            None => {
14613                wrong_filter_range = original_filter_range.take();
14614                label.filter_range.start = last_index;
14615            }
14616        }
14617
14618        match offset_map.get(label.filter_range.end) {
14619            Some(&end) => label.filter_range.end = end,
14620            None => {
14621                wrong_filter_range = original_filter_range.take();
14622                label.filter_range.end = last_index;
14623            }
14624        }
14625    }
14626    if let Some(wrong_filter_range) = wrong_filter_range {
14627        log::error!(
14628            "Completion label has an invalid filter range: {wrong_filter_range:?}, label text: {}",
14629            label.text
14630        );
14631    }
14632
14633    label.text = new_text;
14634}