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    pub process_id: Option<u32>,
 3912}
 3913
 3914#[derive(Clone, Debug)]
 3915struct CoreSymbol {
 3916    pub language_server_name: LanguageServerName,
 3917    pub source_worktree_id: WorktreeId,
 3918    pub source_language_server_id: LanguageServerId,
 3919    pub path: SymbolLocation,
 3920    pub name: String,
 3921    pub kind: lsp::SymbolKind,
 3922    pub range: Range<Unclipped<PointUtf16>>,
 3923}
 3924
 3925#[derive(Clone, Debug, PartialEq, Eq)]
 3926pub enum SymbolLocation {
 3927    InProject(ProjectPath),
 3928    OutsideProject {
 3929        abs_path: Arc<Path>,
 3930        signature: [u8; 32],
 3931    },
 3932}
 3933
 3934impl SymbolLocation {
 3935    fn file_name(&self) -> Option<&str> {
 3936        match self {
 3937            Self::InProject(path) => path.path.file_name(),
 3938            Self::OutsideProject { abs_path, .. } => abs_path.file_name()?.to_str(),
 3939        }
 3940    }
 3941}
 3942
 3943impl LspStore {
 3944    pub fn init(client: &AnyProtoClient) {
 3945        client.add_entity_request_handler(Self::handle_lsp_query);
 3946        client.add_entity_message_handler(Self::handle_lsp_query_response);
 3947        client.add_entity_request_handler(Self::handle_restart_language_servers);
 3948        client.add_entity_request_handler(Self::handle_stop_language_servers);
 3949        client.add_entity_request_handler(Self::handle_cancel_language_server_work);
 3950        client.add_entity_message_handler(Self::handle_start_language_server);
 3951        client.add_entity_message_handler(Self::handle_update_language_server);
 3952        client.add_entity_message_handler(Self::handle_language_server_log);
 3953        client.add_entity_message_handler(Self::handle_update_diagnostic_summary);
 3954        client.add_entity_request_handler(Self::handle_format_buffers);
 3955        client.add_entity_request_handler(Self::handle_apply_code_action_kind);
 3956        client.add_entity_request_handler(Self::handle_resolve_completion_documentation);
 3957        client.add_entity_request_handler(Self::handle_apply_code_action);
 3958        client.add_entity_request_handler(Self::handle_get_project_symbols);
 3959        client.add_entity_request_handler(Self::handle_resolve_inlay_hint);
 3960        client.add_entity_request_handler(Self::handle_get_color_presentation);
 3961        client.add_entity_request_handler(Self::handle_open_buffer_for_symbol);
 3962        client.add_entity_request_handler(Self::handle_refresh_inlay_hints);
 3963        client.add_entity_request_handler(Self::handle_refresh_code_lens);
 3964        client.add_entity_request_handler(Self::handle_on_type_formatting);
 3965        client.add_entity_request_handler(Self::handle_apply_additional_edits_for_completion);
 3966        client.add_entity_request_handler(Self::handle_register_buffer_with_language_servers);
 3967        client.add_entity_request_handler(Self::handle_rename_project_entry);
 3968        client.add_entity_request_handler(Self::handle_pull_workspace_diagnostics);
 3969        client.add_entity_request_handler(Self::handle_lsp_get_completions);
 3970        client.add_entity_request_handler(Self::handle_lsp_command::<GetDocumentHighlights>);
 3971        client.add_entity_request_handler(Self::handle_lsp_command::<GetDocumentSymbols>);
 3972        client.add_entity_request_handler(Self::handle_lsp_command::<PrepareRename>);
 3973        client.add_entity_request_handler(Self::handle_lsp_command::<PerformRename>);
 3974        client.add_entity_request_handler(Self::handle_lsp_command::<LinkedEditingRange>);
 3975
 3976        client.add_entity_request_handler(Self::handle_lsp_ext_cancel_flycheck);
 3977        client.add_entity_request_handler(Self::handle_lsp_ext_run_flycheck);
 3978        client.add_entity_request_handler(Self::handle_lsp_ext_clear_flycheck);
 3979        client.add_entity_request_handler(Self::handle_lsp_command::<lsp_ext_command::ExpandMacro>);
 3980        client.add_entity_request_handler(Self::handle_lsp_command::<lsp_ext_command::OpenDocs>);
 3981        client.add_entity_request_handler(
 3982            Self::handle_lsp_command::<lsp_ext_command::GoToParentModule>,
 3983        );
 3984        client.add_entity_request_handler(
 3985            Self::handle_lsp_command::<lsp_ext_command::GetLspRunnables>,
 3986        );
 3987        client.add_entity_request_handler(
 3988            Self::handle_lsp_command::<lsp_ext_command::SwitchSourceHeader>,
 3989        );
 3990    }
 3991
 3992    pub fn as_remote(&self) -> Option<&RemoteLspStore> {
 3993        match &self.mode {
 3994            LspStoreMode::Remote(remote_lsp_store) => Some(remote_lsp_store),
 3995            _ => None,
 3996        }
 3997    }
 3998
 3999    pub fn as_local(&self) -> Option<&LocalLspStore> {
 4000        match &self.mode {
 4001            LspStoreMode::Local(local_lsp_store) => Some(local_lsp_store),
 4002            _ => None,
 4003        }
 4004    }
 4005
 4006    pub fn as_local_mut(&mut self) -> Option<&mut LocalLspStore> {
 4007        match &mut self.mode {
 4008            LspStoreMode::Local(local_lsp_store) => Some(local_lsp_store),
 4009            _ => None,
 4010        }
 4011    }
 4012
 4013    pub fn upstream_client(&self) -> Option<(AnyProtoClient, u64)> {
 4014        match &self.mode {
 4015            LspStoreMode::Remote(RemoteLspStore {
 4016                upstream_client: Some(upstream_client),
 4017                upstream_project_id,
 4018                ..
 4019            }) => Some((upstream_client.clone(), *upstream_project_id)),
 4020
 4021            LspStoreMode::Remote(RemoteLspStore {
 4022                upstream_client: None,
 4023                ..
 4024            }) => None,
 4025            LspStoreMode::Local(_) => None,
 4026        }
 4027    }
 4028
 4029    pub fn new_local(
 4030        buffer_store: Entity<BufferStore>,
 4031        worktree_store: Entity<WorktreeStore>,
 4032        prettier_store: Entity<PrettierStore>,
 4033        toolchain_store: Entity<LocalToolchainStore>,
 4034        environment: Entity<ProjectEnvironment>,
 4035        manifest_tree: Entity<ManifestTree>,
 4036        languages: Arc<LanguageRegistry>,
 4037        http_client: Arc<dyn HttpClient>,
 4038        fs: Arc<dyn Fs>,
 4039        cx: &mut Context<Self>,
 4040    ) -> Self {
 4041        let yarn = YarnPathStore::new(fs.clone(), cx);
 4042        cx.subscribe(&buffer_store, Self::on_buffer_store_event)
 4043            .detach();
 4044        cx.subscribe(&worktree_store, Self::on_worktree_store_event)
 4045            .detach();
 4046        cx.subscribe(&prettier_store, Self::on_prettier_store_event)
 4047            .detach();
 4048        cx.subscribe(&toolchain_store, Self::on_toolchain_store_event)
 4049            .detach();
 4050        cx.observe_global::<SettingsStore>(Self::on_settings_changed)
 4051            .detach();
 4052        subscribe_to_binary_statuses(&languages, cx).detach();
 4053
 4054        let _maintain_workspace_config = {
 4055            let (sender, receiver) = watch::channel();
 4056            (Self::maintain_workspace_config(receiver, cx), sender)
 4057        };
 4058
 4059        Self {
 4060            mode: LspStoreMode::Local(LocalLspStore {
 4061                weak: cx.weak_entity(),
 4062                worktree_store: worktree_store.clone(),
 4063
 4064                supplementary_language_servers: Default::default(),
 4065                languages: languages.clone(),
 4066                language_server_ids: Default::default(),
 4067                language_servers: Default::default(),
 4068                last_workspace_edits_by_language_server: Default::default(),
 4069                language_server_watched_paths: Default::default(),
 4070                language_server_paths_watched_for_rename: Default::default(),
 4071                language_server_dynamic_registrations: Default::default(),
 4072                buffers_being_formatted: Default::default(),
 4073                buffers_to_refresh_hash_set: HashSet::default(),
 4074                buffers_to_refresh_queue: VecDeque::new(),
 4075                _background_diagnostics_worker: Task::ready(()).shared(),
 4076                buffer_snapshots: Default::default(),
 4077                prettier_store,
 4078                environment,
 4079                http_client,
 4080                fs,
 4081                yarn,
 4082                next_diagnostic_group_id: Default::default(),
 4083                diagnostics: Default::default(),
 4084                _subscription: cx.on_app_quit(|this, cx| {
 4085                    this.as_local_mut()
 4086                        .unwrap()
 4087                        .shutdown_language_servers_on_quit(cx)
 4088                }),
 4089                lsp_tree: LanguageServerTree::new(
 4090                    manifest_tree,
 4091                    languages.clone(),
 4092                    toolchain_store.clone(),
 4093                ),
 4094                toolchain_store,
 4095                registered_buffers: HashMap::default(),
 4096                buffers_opened_in_servers: HashMap::default(),
 4097                buffer_pull_diagnostics_result_ids: HashMap::default(),
 4098                workspace_pull_diagnostics_result_ids: HashMap::default(),
 4099                restricted_worktrees_tasks: HashMap::default(),
 4100                watched_manifest_filenames: ManifestProvidersStore::global(cx)
 4101                    .manifest_file_names(),
 4102            }),
 4103            last_formatting_failure: None,
 4104            downstream_client: None,
 4105            buffer_store,
 4106            worktree_store,
 4107            languages: languages.clone(),
 4108            language_server_statuses: Default::default(),
 4109            nonce: StdRng::from_os_rng().random(),
 4110            diagnostic_summaries: HashMap::default(),
 4111            lsp_server_capabilities: HashMap::default(),
 4112            lsp_data: HashMap::default(),
 4113            next_hint_id: Arc::default(),
 4114            active_entry: None,
 4115            _maintain_workspace_config,
 4116            _maintain_buffer_languages: Self::maintain_buffer_languages(languages, cx),
 4117        }
 4118    }
 4119
 4120    fn send_lsp_proto_request<R: LspCommand>(
 4121        &self,
 4122        buffer: Entity<Buffer>,
 4123        client: AnyProtoClient,
 4124        upstream_project_id: u64,
 4125        request: R,
 4126        cx: &mut Context<LspStore>,
 4127    ) -> Task<anyhow::Result<<R as LspCommand>::Response>> {
 4128        if !self.is_capable_for_proto_request(&buffer, &request, cx) {
 4129            return Task::ready(Ok(R::Response::default()));
 4130        }
 4131        let message = request.to_proto(upstream_project_id, buffer.read(cx));
 4132        cx.spawn(async move |this, cx| {
 4133            let response = client.request(message).await?;
 4134            let this = this.upgrade().context("project dropped")?;
 4135            request
 4136                .response_from_proto(response, this, buffer, cx.clone())
 4137                .await
 4138        })
 4139    }
 4140
 4141    pub(super) fn new_remote(
 4142        buffer_store: Entity<BufferStore>,
 4143        worktree_store: Entity<WorktreeStore>,
 4144        languages: Arc<LanguageRegistry>,
 4145        upstream_client: AnyProtoClient,
 4146        project_id: u64,
 4147        cx: &mut Context<Self>,
 4148    ) -> Self {
 4149        cx.subscribe(&buffer_store, Self::on_buffer_store_event)
 4150            .detach();
 4151        cx.subscribe(&worktree_store, Self::on_worktree_store_event)
 4152            .detach();
 4153        subscribe_to_binary_statuses(&languages, cx).detach();
 4154        let _maintain_workspace_config = {
 4155            let (sender, receiver) = watch::channel();
 4156            (Self::maintain_workspace_config(receiver, cx), sender)
 4157        };
 4158        Self {
 4159            mode: LspStoreMode::Remote(RemoteLspStore {
 4160                upstream_client: Some(upstream_client),
 4161                upstream_project_id: project_id,
 4162            }),
 4163            downstream_client: None,
 4164            last_formatting_failure: None,
 4165            buffer_store,
 4166            worktree_store,
 4167            languages: languages.clone(),
 4168            language_server_statuses: Default::default(),
 4169            nonce: StdRng::from_os_rng().random(),
 4170            diagnostic_summaries: HashMap::default(),
 4171            lsp_server_capabilities: HashMap::default(),
 4172            next_hint_id: Arc::default(),
 4173            lsp_data: HashMap::default(),
 4174            active_entry: None,
 4175
 4176            _maintain_workspace_config,
 4177            _maintain_buffer_languages: Self::maintain_buffer_languages(languages.clone(), cx),
 4178        }
 4179    }
 4180
 4181    fn on_buffer_store_event(
 4182        &mut self,
 4183        _: Entity<BufferStore>,
 4184        event: &BufferStoreEvent,
 4185        cx: &mut Context<Self>,
 4186    ) {
 4187        match event {
 4188            BufferStoreEvent::BufferAdded(buffer) => {
 4189                self.on_buffer_added(buffer, cx).log_err();
 4190            }
 4191            BufferStoreEvent::BufferChangedFilePath { buffer, old_file } => {
 4192                let buffer_id = buffer.read(cx).remote_id();
 4193                if let Some(local) = self.as_local_mut()
 4194                    && let Some(old_file) = File::from_dyn(old_file.as_ref())
 4195                {
 4196                    local.reset_buffer(buffer, old_file, cx);
 4197
 4198                    if local.registered_buffers.contains_key(&buffer_id) {
 4199                        local.unregister_old_buffer_from_language_servers(buffer, old_file, cx);
 4200                    }
 4201                }
 4202
 4203                self.detect_language_for_buffer(buffer, cx);
 4204                if let Some(local) = self.as_local_mut() {
 4205                    local.initialize_buffer(buffer, cx);
 4206                    if local.registered_buffers.contains_key(&buffer_id) {
 4207                        local.register_buffer_with_language_servers(buffer, HashSet::default(), cx);
 4208                    }
 4209                }
 4210            }
 4211            _ => {}
 4212        }
 4213    }
 4214
 4215    fn on_worktree_store_event(
 4216        &mut self,
 4217        _: Entity<WorktreeStore>,
 4218        event: &WorktreeStoreEvent,
 4219        cx: &mut Context<Self>,
 4220    ) {
 4221        match event {
 4222            WorktreeStoreEvent::WorktreeAdded(worktree) => {
 4223                if !worktree.read(cx).is_local() {
 4224                    return;
 4225                }
 4226                cx.subscribe(worktree, |this, worktree, event, cx| match event {
 4227                    worktree::Event::UpdatedEntries(changes) => {
 4228                        this.update_local_worktree_language_servers(&worktree, changes, cx);
 4229                    }
 4230                    worktree::Event::UpdatedGitRepositories(_)
 4231                    | worktree::Event::DeletedEntry(_) => {}
 4232                })
 4233                .detach()
 4234            }
 4235            WorktreeStoreEvent::WorktreeRemoved(_, id) => self.remove_worktree(*id, cx),
 4236            WorktreeStoreEvent::WorktreeUpdateSent(worktree) => {
 4237                worktree.update(cx, |worktree, _cx| self.send_diagnostic_summaries(worktree));
 4238            }
 4239            WorktreeStoreEvent::WorktreeReleased(..)
 4240            | WorktreeStoreEvent::WorktreeOrderChanged
 4241            | WorktreeStoreEvent::WorktreeUpdatedEntries(..)
 4242            | WorktreeStoreEvent::WorktreeUpdatedGitRepositories(..)
 4243            | WorktreeStoreEvent::WorktreeDeletedEntry(..) => {}
 4244        }
 4245    }
 4246
 4247    fn on_prettier_store_event(
 4248        &mut self,
 4249        _: Entity<PrettierStore>,
 4250        event: &PrettierStoreEvent,
 4251        cx: &mut Context<Self>,
 4252    ) {
 4253        match event {
 4254            PrettierStoreEvent::LanguageServerRemoved(prettier_server_id) => {
 4255                self.unregister_supplementary_language_server(*prettier_server_id, cx);
 4256            }
 4257            PrettierStoreEvent::LanguageServerAdded {
 4258                new_server_id,
 4259                name,
 4260                prettier_server,
 4261            } => {
 4262                self.register_supplementary_language_server(
 4263                    *new_server_id,
 4264                    name.clone(),
 4265                    prettier_server.clone(),
 4266                    cx,
 4267                );
 4268            }
 4269        }
 4270    }
 4271
 4272    fn on_toolchain_store_event(
 4273        &mut self,
 4274        _: Entity<LocalToolchainStore>,
 4275        event: &ToolchainStoreEvent,
 4276        _: &mut Context<Self>,
 4277    ) {
 4278        if let ToolchainStoreEvent::ToolchainActivated = event {
 4279            self.request_workspace_config_refresh()
 4280        }
 4281    }
 4282
 4283    fn request_workspace_config_refresh(&mut self) {
 4284        *self._maintain_workspace_config.1.borrow_mut() = ();
 4285    }
 4286
 4287    pub fn prettier_store(&self) -> Option<Entity<PrettierStore>> {
 4288        self.as_local().map(|local| local.prettier_store.clone())
 4289    }
 4290
 4291    fn on_buffer_event(
 4292        &mut self,
 4293        buffer: Entity<Buffer>,
 4294        event: &language::BufferEvent,
 4295        cx: &mut Context<Self>,
 4296    ) {
 4297        match event {
 4298            language::BufferEvent::Edited => {
 4299                self.on_buffer_edited(buffer, cx);
 4300            }
 4301
 4302            language::BufferEvent::Saved => {
 4303                self.on_buffer_saved(buffer, cx);
 4304            }
 4305
 4306            _ => {}
 4307        }
 4308    }
 4309
 4310    fn on_buffer_added(&mut self, buffer: &Entity<Buffer>, cx: &mut Context<Self>) -> Result<()> {
 4311        buffer
 4312            .read(cx)
 4313            .set_language_registry(self.languages.clone());
 4314
 4315        cx.subscribe(buffer, |this, buffer, event, cx| {
 4316            this.on_buffer_event(buffer, event, cx);
 4317        })
 4318        .detach();
 4319
 4320        self.detect_language_for_buffer(buffer, cx);
 4321        if let Some(local) = self.as_local_mut() {
 4322            local.initialize_buffer(buffer, cx);
 4323        }
 4324
 4325        Ok(())
 4326    }
 4327
 4328    pub fn refresh_background_diagnostics_for_buffers(
 4329        &mut self,
 4330        buffers: HashSet<BufferId>,
 4331        cx: &mut Context<Self>,
 4332    ) -> Shared<Task<()>> {
 4333        let Some(local) = self.as_local_mut() else {
 4334            return Task::ready(()).shared();
 4335        };
 4336        for buffer in buffers {
 4337            if local.buffers_to_refresh_hash_set.insert(buffer) {
 4338                local.buffers_to_refresh_queue.push_back(buffer);
 4339                if local.buffers_to_refresh_queue.len() == 1 {
 4340                    local._background_diagnostics_worker =
 4341                        Self::background_diagnostics_worker(cx).shared();
 4342                }
 4343            }
 4344        }
 4345
 4346        local._background_diagnostics_worker.clone()
 4347    }
 4348
 4349    fn refresh_next_buffer(&mut self, cx: &mut Context<Self>) -> Option<Task<Result<()>>> {
 4350        let buffer_store = self.buffer_store.clone();
 4351        let local = self.as_local_mut()?;
 4352        while let Some(buffer_id) = local.buffers_to_refresh_queue.pop_front() {
 4353            local.buffers_to_refresh_hash_set.remove(&buffer_id);
 4354            if let Some(buffer) = buffer_store.read(cx).get(buffer_id) {
 4355                return Some(self.pull_diagnostics_for_buffer(buffer, cx));
 4356            }
 4357        }
 4358        None
 4359    }
 4360
 4361    fn background_diagnostics_worker(cx: &mut Context<Self>) -> Task<()> {
 4362        cx.spawn(async move |this, cx| {
 4363            while let Ok(Some(task)) = this.update(cx, |this, cx| this.refresh_next_buffer(cx)) {
 4364                task.await.log_err();
 4365            }
 4366        })
 4367    }
 4368
 4369    pub(crate) fn register_buffer_with_language_servers(
 4370        &mut self,
 4371        buffer: &Entity<Buffer>,
 4372        only_register_servers: HashSet<LanguageServerSelector>,
 4373        ignore_refcounts: bool,
 4374        cx: &mut Context<Self>,
 4375    ) -> OpenLspBufferHandle {
 4376        let buffer_id = buffer.read(cx).remote_id();
 4377        let handle = OpenLspBufferHandle(cx.new(|_| OpenLspBuffer(buffer.clone())));
 4378        if let Some(local) = self.as_local_mut() {
 4379            let refcount = local.registered_buffers.entry(buffer_id).or_insert(0);
 4380            if !ignore_refcounts {
 4381                *refcount += 1;
 4382            }
 4383
 4384            // We run early exits on non-existing buffers AFTER we mark the buffer as registered in order to handle buffer saving.
 4385            // 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
 4386            // 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
 4387            // servers in practice (we don't support non-file URI schemes in our LSP impl).
 4388            let Some(file) = File::from_dyn(buffer.read(cx).file()) else {
 4389                return handle;
 4390            };
 4391            if !file.is_local() {
 4392                return handle;
 4393            }
 4394
 4395            if ignore_refcounts || *refcount == 1 {
 4396                local.register_buffer_with_language_servers(buffer, only_register_servers, cx);
 4397            }
 4398            if !ignore_refcounts {
 4399                cx.observe_release(&handle.0, move |lsp_store, buffer, cx| {
 4400                    let refcount = {
 4401                        let local = lsp_store.as_local_mut().unwrap();
 4402                        let Some(refcount) = local.registered_buffers.get_mut(&buffer_id) else {
 4403                            debug_panic!("bad refcounting");
 4404                            return;
 4405                        };
 4406
 4407                        *refcount -= 1;
 4408                        *refcount
 4409                    };
 4410                    if refcount == 0 {
 4411                        lsp_store.lsp_data.remove(&buffer_id);
 4412                        let local = lsp_store.as_local_mut().unwrap();
 4413                        local.registered_buffers.remove(&buffer_id);
 4414
 4415                        local.buffers_opened_in_servers.remove(&buffer_id);
 4416                        if let Some(file) = File::from_dyn(buffer.0.read(cx).file()).cloned() {
 4417                            local.unregister_old_buffer_from_language_servers(&buffer.0, &file, cx);
 4418
 4419                            let buffer_abs_path = file.abs_path(cx);
 4420                            for (_, buffer_pull_diagnostics_result_ids) in
 4421                                &mut local.buffer_pull_diagnostics_result_ids
 4422                            {
 4423                                buffer_pull_diagnostics_result_ids.retain(
 4424                                    |_, buffer_result_ids| {
 4425                                        buffer_result_ids.remove(&buffer_abs_path);
 4426                                        !buffer_result_ids.is_empty()
 4427                                    },
 4428                                );
 4429                            }
 4430
 4431                            let diagnostic_updates = local
 4432                                .language_servers
 4433                                .keys()
 4434                                .cloned()
 4435                                .map(|server_id| DocumentDiagnosticsUpdate {
 4436                                    diagnostics: DocumentDiagnostics {
 4437                                        document_abs_path: buffer_abs_path.clone(),
 4438                                        version: None,
 4439                                        diagnostics: Vec::new(),
 4440                                    },
 4441                                    result_id: None,
 4442                                    registration_id: None,
 4443                                    server_id: server_id,
 4444                                    disk_based_sources: Cow::Borrowed(&[]),
 4445                                })
 4446                                .collect::<Vec<_>>();
 4447
 4448                            lsp_store
 4449                                .merge_diagnostic_entries(
 4450                                    diagnostic_updates,
 4451                                    |_, diagnostic, _| {
 4452                                        diagnostic.source_kind != DiagnosticSourceKind::Pulled
 4453                                    },
 4454                                    cx,
 4455                                )
 4456                                .context("Clearing diagnostics for the closed buffer")
 4457                                .log_err();
 4458                        }
 4459                    }
 4460                })
 4461                .detach();
 4462            }
 4463        } else if let Some((upstream_client, upstream_project_id)) = self.upstream_client() {
 4464            let buffer_id = buffer.read(cx).remote_id().to_proto();
 4465            cx.background_spawn(async move {
 4466                upstream_client
 4467                    .request(proto::RegisterBufferWithLanguageServers {
 4468                        project_id: upstream_project_id,
 4469                        buffer_id,
 4470                        only_servers: only_register_servers
 4471                            .into_iter()
 4472                            .map(|selector| {
 4473                                let selector = match selector {
 4474                                    LanguageServerSelector::Id(language_server_id) => {
 4475                                        proto::language_server_selector::Selector::ServerId(
 4476                                            language_server_id.to_proto(),
 4477                                        )
 4478                                    }
 4479                                    LanguageServerSelector::Name(language_server_name) => {
 4480                                        proto::language_server_selector::Selector::Name(
 4481                                            language_server_name.to_string(),
 4482                                        )
 4483                                    }
 4484                                };
 4485                                proto::LanguageServerSelector {
 4486                                    selector: Some(selector),
 4487                                }
 4488                            })
 4489                            .collect(),
 4490                    })
 4491                    .await
 4492            })
 4493            .detach();
 4494        } else {
 4495            // Our remote connection got closed
 4496        }
 4497        handle
 4498    }
 4499
 4500    fn maintain_buffer_languages(
 4501        languages: Arc<LanguageRegistry>,
 4502        cx: &mut Context<Self>,
 4503    ) -> Task<()> {
 4504        let mut subscription = languages.subscribe();
 4505        let mut prev_reload_count = languages.reload_count();
 4506        cx.spawn(async move |this, cx| {
 4507            while let Some(()) = subscription.next().await {
 4508                if let Some(this) = this.upgrade() {
 4509                    // If the language registry has been reloaded, then remove and
 4510                    // re-assign the languages on all open buffers.
 4511                    let reload_count = languages.reload_count();
 4512                    if reload_count > prev_reload_count {
 4513                        prev_reload_count = reload_count;
 4514                        this.update(cx, |this, cx| {
 4515                            this.buffer_store.clone().update(cx, |buffer_store, cx| {
 4516                                for buffer in buffer_store.buffers() {
 4517                                    if let Some(f) = File::from_dyn(buffer.read(cx).file()).cloned()
 4518                                    {
 4519                                        buffer.update(cx, |buffer, cx| {
 4520                                            buffer.set_language_async(None, cx)
 4521                                        });
 4522                                        if let Some(local) = this.as_local_mut() {
 4523                                            local.reset_buffer(&buffer, &f, cx);
 4524
 4525                                            if local
 4526                                                .registered_buffers
 4527                                                .contains_key(&buffer.read(cx).remote_id())
 4528                                                && let Some(file_url) =
 4529                                                    file_path_to_lsp_url(&f.abs_path(cx)).log_err()
 4530                                            {
 4531                                                local.unregister_buffer_from_language_servers(
 4532                                                    &buffer, &file_url, cx,
 4533                                                );
 4534                                            }
 4535                                        }
 4536                                    }
 4537                                }
 4538                            });
 4539                        });
 4540                    }
 4541
 4542                    this.update(cx, |this, cx| {
 4543                        let mut plain_text_buffers = Vec::new();
 4544                        let mut buffers_with_unknown_injections = Vec::new();
 4545                        for handle in this.buffer_store.read(cx).buffers() {
 4546                            let buffer = handle.read(cx);
 4547                            if buffer.language().is_none()
 4548                                || buffer.language() == Some(&*language::PLAIN_TEXT)
 4549                            {
 4550                                plain_text_buffers.push(handle);
 4551                            } else if buffer.contains_unknown_injections() {
 4552                                buffers_with_unknown_injections.push(handle);
 4553                            }
 4554                        }
 4555
 4556                        // Deprioritize the invisible worktrees so main worktrees' language servers can be started first,
 4557                        // and reused later in the invisible worktrees.
 4558                        plain_text_buffers.sort_by_key(|buffer| {
 4559                            Reverse(
 4560                                File::from_dyn(buffer.read(cx).file())
 4561                                    .map(|file| file.worktree.read(cx).is_visible()),
 4562                            )
 4563                        });
 4564
 4565                        for buffer in plain_text_buffers {
 4566                            this.detect_language_for_buffer(&buffer, cx);
 4567                            if let Some(local) = this.as_local_mut() {
 4568                                local.initialize_buffer(&buffer, cx);
 4569                                if local
 4570                                    .registered_buffers
 4571                                    .contains_key(&buffer.read(cx).remote_id())
 4572                                {
 4573                                    local.register_buffer_with_language_servers(
 4574                                        &buffer,
 4575                                        HashSet::default(),
 4576                                        cx,
 4577                                    );
 4578                                }
 4579                            }
 4580                        }
 4581
 4582                        for buffer in buffers_with_unknown_injections {
 4583                            buffer.update(cx, |buffer, cx| buffer.reparse(cx, false));
 4584                        }
 4585                    });
 4586                }
 4587            }
 4588        })
 4589    }
 4590
 4591    fn detect_language_for_buffer(
 4592        &mut self,
 4593        buffer_handle: &Entity<Buffer>,
 4594        cx: &mut Context<Self>,
 4595    ) -> Option<language::AvailableLanguage> {
 4596        // If the buffer has a language, set it and start the language server if we haven't already.
 4597        let buffer = buffer_handle.read(cx);
 4598        let file = buffer.file()?;
 4599
 4600        let content = buffer.as_rope();
 4601        let available_language = self.languages.language_for_file(file, Some(content), cx);
 4602        if let Some(available_language) = &available_language {
 4603            if let Some(Ok(Ok(new_language))) = self
 4604                .languages
 4605                .load_language(available_language)
 4606                .now_or_never()
 4607            {
 4608                self.set_language_for_buffer(buffer_handle, new_language, cx);
 4609            }
 4610        } else {
 4611            cx.emit(LspStoreEvent::LanguageDetected {
 4612                buffer: buffer_handle.clone(),
 4613                new_language: None,
 4614            });
 4615        }
 4616
 4617        available_language
 4618    }
 4619
 4620    pub(crate) fn set_language_for_buffer(
 4621        &mut self,
 4622        buffer_entity: &Entity<Buffer>,
 4623        new_language: Arc<Language>,
 4624        cx: &mut Context<Self>,
 4625    ) {
 4626        let buffer = buffer_entity.read(cx);
 4627        let buffer_file = buffer.file().cloned();
 4628        let buffer_id = buffer.remote_id();
 4629        if let Some(local_store) = self.as_local_mut()
 4630            && local_store.registered_buffers.contains_key(&buffer_id)
 4631            && let Some(abs_path) =
 4632                File::from_dyn(buffer_file.as_ref()).map(|file| file.abs_path(cx))
 4633            && let Some(file_url) = file_path_to_lsp_url(&abs_path).log_err()
 4634        {
 4635            local_store.unregister_buffer_from_language_servers(buffer_entity, &file_url, cx);
 4636        }
 4637        buffer_entity.update(cx, |buffer, cx| {
 4638            if buffer
 4639                .language()
 4640                .is_none_or(|old_language| !Arc::ptr_eq(old_language, &new_language))
 4641            {
 4642                buffer.set_language_async(Some(new_language.clone()), cx);
 4643            }
 4644        });
 4645
 4646        let settings =
 4647            language_settings(Some(new_language.name()), buffer_file.as_ref(), cx).into_owned();
 4648        let buffer_file = File::from_dyn(buffer_file.as_ref());
 4649
 4650        let worktree_id = if let Some(file) = buffer_file {
 4651            let worktree = file.worktree.clone();
 4652
 4653            if let Some(local) = self.as_local_mut()
 4654                && local.registered_buffers.contains_key(&buffer_id)
 4655            {
 4656                local.register_buffer_with_language_servers(buffer_entity, HashSet::default(), cx);
 4657            }
 4658            Some(worktree.read(cx).id())
 4659        } else {
 4660            None
 4661        };
 4662
 4663        if settings.prettier.allowed
 4664            && let Some(prettier_plugins) = prettier_store::prettier_plugins_for_language(&settings)
 4665        {
 4666            let prettier_store = self.as_local().map(|s| s.prettier_store.clone());
 4667            if let Some(prettier_store) = prettier_store {
 4668                prettier_store.update(cx, |prettier_store, cx| {
 4669                    prettier_store.install_default_prettier(
 4670                        worktree_id,
 4671                        prettier_plugins.iter().map(|s| Arc::from(s.as_str())),
 4672                        cx,
 4673                    )
 4674                })
 4675            }
 4676        }
 4677
 4678        cx.emit(LspStoreEvent::LanguageDetected {
 4679            buffer: buffer_entity.clone(),
 4680            new_language: Some(new_language),
 4681        })
 4682    }
 4683
 4684    pub fn buffer_store(&self) -> Entity<BufferStore> {
 4685        self.buffer_store.clone()
 4686    }
 4687
 4688    pub fn set_active_entry(&mut self, active_entry: Option<ProjectEntryId>) {
 4689        self.active_entry = active_entry;
 4690    }
 4691
 4692    pub(crate) fn send_diagnostic_summaries(&self, worktree: &mut Worktree) {
 4693        if let Some((client, downstream_project_id)) = self.downstream_client.clone()
 4694            && let Some(diangostic_summaries) = self.diagnostic_summaries.get(&worktree.id())
 4695        {
 4696            let mut summaries = diangostic_summaries.iter().flat_map(|(path, summaries)| {
 4697                summaries
 4698                    .iter()
 4699                    .map(|(server_id, summary)| summary.to_proto(*server_id, path.as_ref()))
 4700            });
 4701            if let Some(summary) = summaries.next() {
 4702                client
 4703                    .send(proto::UpdateDiagnosticSummary {
 4704                        project_id: downstream_project_id,
 4705                        worktree_id: worktree.id().to_proto(),
 4706                        summary: Some(summary),
 4707                        more_summaries: summaries.collect(),
 4708                    })
 4709                    .log_err();
 4710            }
 4711        }
 4712    }
 4713
 4714    fn is_capable_for_proto_request<R>(
 4715        &self,
 4716        buffer: &Entity<Buffer>,
 4717        request: &R,
 4718        cx: &App,
 4719    ) -> bool
 4720    where
 4721        R: LspCommand,
 4722    {
 4723        self.check_if_capable_for_proto_request(
 4724            buffer,
 4725            |capabilities| {
 4726                request.check_capabilities(AdapterServerCapabilities {
 4727                    server_capabilities: capabilities.clone(),
 4728                    code_action_kinds: None,
 4729                })
 4730            },
 4731            cx,
 4732        )
 4733    }
 4734
 4735    fn check_if_capable_for_proto_request<F>(
 4736        &self,
 4737        buffer: &Entity<Buffer>,
 4738        check: F,
 4739        cx: &App,
 4740    ) -> bool
 4741    where
 4742        F: FnMut(&lsp::ServerCapabilities) -> bool,
 4743    {
 4744        let Some(language) = buffer.read(cx).language().cloned() else {
 4745            return false;
 4746        };
 4747        let registered_language_servers = self
 4748            .languages
 4749            .lsp_adapters(&language.name())
 4750            .into_iter()
 4751            .map(|lsp_adapter| lsp_adapter.name())
 4752            .collect::<HashSet<_>>();
 4753        self.language_server_statuses
 4754            .iter()
 4755            .filter_map(|(server_id, server_status)| {
 4756                // Include servers that are either registered for this language OR
 4757                // available to be loaded (for SSH remote mode where adapters like
 4758                // ty/pylsp/pyright are registered via register_available_lsp_adapter
 4759                // but only loaded on the server side)
 4760                let is_relevant = registered_language_servers.contains(&server_status.name)
 4761                    || self.languages.is_lsp_adapter_available(&server_status.name);
 4762                is_relevant.then_some(server_id)
 4763            })
 4764            .filter_map(|server_id| self.lsp_server_capabilities.get(server_id))
 4765            .any(check)
 4766    }
 4767
 4768    fn all_capable_for_proto_request<F>(
 4769        &self,
 4770        buffer: &Entity<Buffer>,
 4771        mut check: F,
 4772        cx: &App,
 4773    ) -> Vec<lsp::LanguageServerId>
 4774    where
 4775        F: FnMut(&lsp::LanguageServerName, &lsp::ServerCapabilities) -> bool,
 4776    {
 4777        let Some(language) = buffer.read(cx).language().cloned() else {
 4778            return Vec::default();
 4779        };
 4780        let registered_language_servers = self
 4781            .languages
 4782            .lsp_adapters(&language.name())
 4783            .into_iter()
 4784            .map(|lsp_adapter| lsp_adapter.name())
 4785            .collect::<HashSet<_>>();
 4786        self.language_server_statuses
 4787            .iter()
 4788            .filter_map(|(server_id, server_status)| {
 4789                // Include servers that are either registered for this language OR
 4790                // available to be loaded (for SSH remote mode where adapters like
 4791                // ty/pylsp/pyright are registered via register_available_lsp_adapter
 4792                // but only loaded on the server side)
 4793                let is_relevant = registered_language_servers.contains(&server_status.name)
 4794                    || self.languages.is_lsp_adapter_available(&server_status.name);
 4795                is_relevant.then_some((server_id, &server_status.name))
 4796            })
 4797            .filter_map(|(server_id, server_name)| {
 4798                self.lsp_server_capabilities
 4799                    .get(server_id)
 4800                    .map(|c| (server_id, server_name, c))
 4801            })
 4802            .filter(|(_, server_name, capabilities)| check(server_name, capabilities))
 4803            .map(|(server_id, _, _)| *server_id)
 4804            .collect()
 4805    }
 4806
 4807    pub fn request_lsp<R>(
 4808        &mut self,
 4809        buffer: Entity<Buffer>,
 4810        server: LanguageServerToQuery,
 4811        request: R,
 4812        cx: &mut Context<Self>,
 4813    ) -> Task<Result<R::Response>>
 4814    where
 4815        R: LspCommand,
 4816        <R::LspRequest as lsp::request::Request>::Result: Send,
 4817        <R::LspRequest as lsp::request::Request>::Params: Send,
 4818    {
 4819        if let Some((upstream_client, upstream_project_id)) = self.upstream_client() {
 4820            return self.send_lsp_proto_request(
 4821                buffer,
 4822                upstream_client,
 4823                upstream_project_id,
 4824                request,
 4825                cx,
 4826            );
 4827        }
 4828
 4829        let Some(language_server) = buffer.update(cx, |buffer, cx| match server {
 4830            LanguageServerToQuery::FirstCapable => self.as_local().and_then(|local| {
 4831                local
 4832                    .language_servers_for_buffer(buffer, cx)
 4833                    .find(|(_, server)| {
 4834                        request.check_capabilities(server.adapter_server_capabilities())
 4835                    })
 4836                    .map(|(_, server)| server.clone())
 4837            }),
 4838            LanguageServerToQuery::Other(id) => self
 4839                .language_server_for_local_buffer(buffer, id, cx)
 4840                .and_then(|(_, server)| {
 4841                    request
 4842                        .check_capabilities(server.adapter_server_capabilities())
 4843                        .then(|| Arc::clone(server))
 4844                }),
 4845        }) else {
 4846            return Task::ready(Ok(Default::default()));
 4847        };
 4848
 4849        let file = File::from_dyn(buffer.read(cx).file()).and_then(File::as_local);
 4850
 4851        let Some(file) = file else {
 4852            return Task::ready(Ok(Default::default()));
 4853        };
 4854
 4855        let lsp_params = match request.to_lsp_params_or_response(
 4856            &file.abs_path(cx),
 4857            buffer.read(cx),
 4858            &language_server,
 4859            cx,
 4860        ) {
 4861            Ok(LspParamsOrResponse::Params(lsp_params)) => lsp_params,
 4862            Ok(LspParamsOrResponse::Response(response)) => return Task::ready(Ok(response)),
 4863            Err(err) => {
 4864                let message = format!(
 4865                    "{} via {} failed: {}",
 4866                    request.display_name(),
 4867                    language_server.name(),
 4868                    err
 4869                );
 4870                // rust-analyzer likes to error with this when its still loading up
 4871                if !message.ends_with("content modified") {
 4872                    log::warn!("{message}");
 4873                }
 4874                return Task::ready(Err(anyhow!(message)));
 4875            }
 4876        };
 4877
 4878        let status = request.status();
 4879        if !request.check_capabilities(language_server.adapter_server_capabilities()) {
 4880            return Task::ready(Ok(Default::default()));
 4881        }
 4882        cx.spawn(async move |this, cx| {
 4883            let lsp_request = language_server.request::<R::LspRequest>(lsp_params);
 4884
 4885            let id = lsp_request.id();
 4886            let _cleanup = if status.is_some() {
 4887                cx.update(|cx| {
 4888                    this.update(cx, |this, cx| {
 4889                        this.on_lsp_work_start(
 4890                            language_server.server_id(),
 4891                            ProgressToken::Number(id),
 4892                            LanguageServerProgress {
 4893                                is_disk_based_diagnostics_progress: false,
 4894                                is_cancellable: false,
 4895                                title: None,
 4896                                message: status.clone(),
 4897                                percentage: None,
 4898                                last_update_at: cx.background_executor().now(),
 4899                            },
 4900                            cx,
 4901                        );
 4902                    })
 4903                })
 4904                .log_err();
 4905
 4906                Some(defer(|| {
 4907                    cx.update(|cx| {
 4908                        this.update(cx, |this, cx| {
 4909                            this.on_lsp_work_end(
 4910                                language_server.server_id(),
 4911                                ProgressToken::Number(id),
 4912                                cx,
 4913                            );
 4914                        })
 4915                    })
 4916                    .log_err();
 4917                }))
 4918            } else {
 4919                None
 4920            };
 4921
 4922            let result = lsp_request.await.into_response();
 4923
 4924            let response = result.map_err(|err| {
 4925                let message = format!(
 4926                    "{} via {} failed: {}",
 4927                    request.display_name(),
 4928                    language_server.name(),
 4929                    err
 4930                );
 4931                // rust-analyzer likes to error with this when its still loading up
 4932                if !message.ends_with("content modified") {
 4933                    log::warn!("{message}");
 4934                }
 4935                anyhow::anyhow!(message)
 4936            })?;
 4937
 4938            request
 4939                .response_from_lsp(
 4940                    response,
 4941                    this.upgrade().context("no app context")?,
 4942                    buffer,
 4943                    language_server.server_id(),
 4944                    cx.clone(),
 4945                )
 4946                .await
 4947        })
 4948    }
 4949
 4950    fn on_settings_changed(&mut self, cx: &mut Context<Self>) {
 4951        let mut language_formatters_to_check = Vec::new();
 4952        for buffer in self.buffer_store.read(cx).buffers() {
 4953            let buffer = buffer.read(cx);
 4954            let buffer_file = File::from_dyn(buffer.file());
 4955            let buffer_language = buffer.language();
 4956            let settings = language_settings(buffer_language.map(|l| l.name()), buffer.file(), cx);
 4957            if buffer_language.is_some() {
 4958                language_formatters_to_check.push((
 4959                    buffer_file.map(|f| f.worktree_id(cx)),
 4960                    settings.into_owned(),
 4961                ));
 4962            }
 4963        }
 4964
 4965        self.request_workspace_config_refresh();
 4966
 4967        if let Some(prettier_store) = self.as_local().map(|s| s.prettier_store.clone()) {
 4968            prettier_store.update(cx, |prettier_store, cx| {
 4969                prettier_store.on_settings_changed(language_formatters_to_check, cx)
 4970            })
 4971        }
 4972
 4973        cx.notify();
 4974    }
 4975
 4976    fn refresh_server_tree(&mut self, cx: &mut Context<Self>) {
 4977        let buffer_store = self.buffer_store.clone();
 4978        let Some(local) = self.as_local_mut() else {
 4979            return;
 4980        };
 4981        let mut adapters = BTreeMap::default();
 4982        let get_adapter = {
 4983            let languages = local.languages.clone();
 4984            let environment = local.environment.clone();
 4985            let weak = local.weak.clone();
 4986            let worktree_store = local.worktree_store.clone();
 4987            let http_client = local.http_client.clone();
 4988            let fs = local.fs.clone();
 4989            move |worktree_id, cx: &mut App| {
 4990                let worktree = worktree_store.read(cx).worktree_for_id(worktree_id, cx)?;
 4991                Some(LocalLspAdapterDelegate::new(
 4992                    languages.clone(),
 4993                    &environment,
 4994                    weak.clone(),
 4995                    &worktree,
 4996                    http_client.clone(),
 4997                    fs.clone(),
 4998                    cx,
 4999                ))
 5000            }
 5001        };
 5002
 5003        let mut messages_to_report = Vec::new();
 5004        let (new_tree, to_stop) = {
 5005            let mut rebase = local.lsp_tree.rebase();
 5006            let buffers = buffer_store
 5007                .read(cx)
 5008                .buffers()
 5009                .filter_map(|buffer| {
 5010                    let raw_buffer = buffer.read(cx);
 5011                    if !local
 5012                        .registered_buffers
 5013                        .contains_key(&raw_buffer.remote_id())
 5014                    {
 5015                        return None;
 5016                    }
 5017                    let file = File::from_dyn(raw_buffer.file()).cloned()?;
 5018                    let language = raw_buffer.language().cloned()?;
 5019                    Some((file, language, raw_buffer.remote_id()))
 5020                })
 5021                .sorted_by_key(|(file, _, _)| Reverse(file.worktree.read(cx).is_visible()));
 5022            for (file, language, buffer_id) in buffers {
 5023                let worktree_id = file.worktree_id(cx);
 5024                let Some(worktree) = local
 5025                    .worktree_store
 5026                    .read(cx)
 5027                    .worktree_for_id(worktree_id, cx)
 5028                else {
 5029                    continue;
 5030                };
 5031
 5032                if let Some((_, apply)) = local.reuse_existing_language_server(
 5033                    rebase.server_tree(),
 5034                    &worktree,
 5035                    &language.name(),
 5036                    cx,
 5037                ) {
 5038                    (apply)(rebase.server_tree());
 5039                } else if let Some(lsp_delegate) = adapters
 5040                    .entry(worktree_id)
 5041                    .or_insert_with(|| get_adapter(worktree_id, cx))
 5042                    .clone()
 5043                {
 5044                    let delegate =
 5045                        Arc::new(ManifestQueryDelegate::new(worktree.read(cx).snapshot()));
 5046                    let path = file
 5047                        .path()
 5048                        .parent()
 5049                        .map(Arc::from)
 5050                        .unwrap_or_else(|| file.path().clone());
 5051                    let worktree_path = ProjectPath { worktree_id, path };
 5052                    let abs_path = file.abs_path(cx);
 5053                    let nodes = rebase
 5054                        .walk(
 5055                            worktree_path,
 5056                            language.name(),
 5057                            language.manifest(),
 5058                            delegate.clone(),
 5059                            cx,
 5060                        )
 5061                        .collect::<Vec<_>>();
 5062                    for node in nodes {
 5063                        let server_id = node.server_id_or_init(|disposition| {
 5064                            let path = &disposition.path;
 5065                            let uri = Uri::from_file_path(worktree.read(cx).absolutize(&path.path));
 5066                            let key = LanguageServerSeed {
 5067                                worktree_id,
 5068                                name: disposition.server_name.clone(),
 5069                                settings: LanguageServerSeedSettings {
 5070                                    binary: disposition.settings.binary.clone(),
 5071                                    initialization_options: disposition
 5072                                        .settings
 5073                                        .initialization_options
 5074                                        .clone(),
 5075                                },
 5076                                toolchain: local.toolchain_store.read(cx).active_toolchain(
 5077                                    path.worktree_id,
 5078                                    &path.path,
 5079                                    language.name(),
 5080                                ),
 5081                            };
 5082                            local.language_server_ids.remove(&key);
 5083
 5084                            let server_id = local.get_or_insert_language_server(
 5085                                &worktree,
 5086                                lsp_delegate.clone(),
 5087                                disposition,
 5088                                &language.name(),
 5089                                cx,
 5090                            );
 5091                            if let Some(state) = local.language_servers.get(&server_id)
 5092                                && let Ok(uri) = uri
 5093                            {
 5094                                state.add_workspace_folder(uri);
 5095                            };
 5096                            server_id
 5097                        });
 5098
 5099                        if let Some(language_server_id) = server_id {
 5100                            messages_to_report.push(LspStoreEvent::LanguageServerUpdate {
 5101                                language_server_id,
 5102                                name: node.name(),
 5103                                message:
 5104                                    proto::update_language_server::Variant::RegisteredForBuffer(
 5105                                        proto::RegisteredForBuffer {
 5106                                            buffer_abs_path: abs_path
 5107                                                .to_string_lossy()
 5108                                                .into_owned(),
 5109                                            buffer_id: buffer_id.to_proto(),
 5110                                        },
 5111                                    ),
 5112                            });
 5113                        }
 5114                    }
 5115                } else {
 5116                    continue;
 5117                }
 5118            }
 5119            rebase.finish()
 5120        };
 5121        for message in messages_to_report {
 5122            cx.emit(message);
 5123        }
 5124        local.lsp_tree = new_tree;
 5125        for (id, _) in to_stop {
 5126            self.stop_local_language_server(id, cx).detach();
 5127        }
 5128    }
 5129
 5130    pub fn apply_code_action(
 5131        &self,
 5132        buffer_handle: Entity<Buffer>,
 5133        mut action: CodeAction,
 5134        push_to_history: bool,
 5135        cx: &mut Context<Self>,
 5136    ) -> Task<Result<ProjectTransaction>> {
 5137        if let Some((upstream_client, project_id)) = self.upstream_client() {
 5138            let request = proto::ApplyCodeAction {
 5139                project_id,
 5140                buffer_id: buffer_handle.read(cx).remote_id().into(),
 5141                action: Some(Self::serialize_code_action(&action)),
 5142            };
 5143            let buffer_store = self.buffer_store();
 5144            cx.spawn(async move |_, cx| {
 5145                let response = upstream_client
 5146                    .request(request)
 5147                    .await?
 5148                    .transaction
 5149                    .context("missing transaction")?;
 5150
 5151                buffer_store
 5152                    .update(cx, |buffer_store, cx| {
 5153                        buffer_store.deserialize_project_transaction(response, push_to_history, cx)
 5154                    })
 5155                    .await
 5156            })
 5157        } else if self.mode.is_local() {
 5158            let Some((_, lang_server)) = buffer_handle.update(cx, |buffer, cx| {
 5159                self.language_server_for_local_buffer(buffer, action.server_id, cx)
 5160                    .map(|(adapter, server)| (adapter.clone(), server.clone()))
 5161            }) else {
 5162                return Task::ready(Ok(ProjectTransaction::default()));
 5163            };
 5164            cx.spawn(async move |this,  cx| {
 5165                LocalLspStore::try_resolve_code_action(&lang_server, &mut action)
 5166                    .await
 5167                    .context("resolving a code action")?;
 5168                if let Some(edit) = action.lsp_action.edit()
 5169                    && (edit.changes.is_some() || edit.document_changes.is_some()) {
 5170                        return LocalLspStore::deserialize_workspace_edit(
 5171                            this.upgrade().context("no app present")?,
 5172                            edit.clone(),
 5173                            push_to_history,
 5174
 5175                            lang_server.clone(),
 5176                            cx,
 5177                        )
 5178                        .await;
 5179                    }
 5180
 5181                if let Some(command) = action.lsp_action.command() {
 5182                    let server_capabilities = lang_server.capabilities();
 5183                    let available_commands = server_capabilities
 5184                        .execute_command_provider
 5185                        .as_ref()
 5186                        .map(|options| options.commands.as_slice())
 5187                        .unwrap_or_default();
 5188                    if available_commands.contains(&command.command) {
 5189                        this.update(cx, |this, _| {
 5190                            this.as_local_mut()
 5191                                .unwrap()
 5192                                .last_workspace_edits_by_language_server
 5193                                .remove(&lang_server.server_id());
 5194                        })?;
 5195
 5196                        let _result = lang_server
 5197                            .request::<lsp::request::ExecuteCommand>(lsp::ExecuteCommandParams {
 5198                                command: command.command.clone(),
 5199                                arguments: command.arguments.clone().unwrap_or_default(),
 5200                                ..lsp::ExecuteCommandParams::default()
 5201                            })
 5202                            .await.into_response()
 5203                            .context("execute command")?;
 5204
 5205                        return this.update(cx, |this, _| {
 5206                            this.as_local_mut()
 5207                                .unwrap()
 5208                                .last_workspace_edits_by_language_server
 5209                                .remove(&lang_server.server_id())
 5210                                .unwrap_or_default()
 5211                        });
 5212                    } else {
 5213                        log::warn!("Cannot execute a command {} not listed in the language server capabilities", command.command);
 5214                    }
 5215                }
 5216
 5217                Ok(ProjectTransaction::default())
 5218            })
 5219        } else {
 5220            Task::ready(Err(anyhow!("no upstream client and not local")))
 5221        }
 5222    }
 5223
 5224    pub fn apply_code_action_kind(
 5225        &mut self,
 5226        buffers: HashSet<Entity<Buffer>>,
 5227        kind: CodeActionKind,
 5228        push_to_history: bool,
 5229        cx: &mut Context<Self>,
 5230    ) -> Task<anyhow::Result<ProjectTransaction>> {
 5231        if self.as_local().is_some() {
 5232            cx.spawn(async move |lsp_store, cx| {
 5233                let buffers = buffers.into_iter().collect::<Vec<_>>();
 5234                let result = LocalLspStore::execute_code_action_kind_locally(
 5235                    lsp_store.clone(),
 5236                    buffers,
 5237                    kind,
 5238                    push_to_history,
 5239                    cx,
 5240                )
 5241                .await;
 5242                lsp_store.update(cx, |lsp_store, _| {
 5243                    lsp_store.update_last_formatting_failure(&result);
 5244                })?;
 5245                result
 5246            })
 5247        } else if let Some((client, project_id)) = self.upstream_client() {
 5248            let buffer_store = self.buffer_store();
 5249            cx.spawn(async move |lsp_store, cx| {
 5250                let result = client
 5251                    .request(proto::ApplyCodeActionKind {
 5252                        project_id,
 5253                        kind: kind.as_str().to_owned(),
 5254                        buffer_ids: buffers
 5255                            .iter()
 5256                            .map(|buffer| {
 5257                                buffer.read_with(cx, |buffer, _| buffer.remote_id().into())
 5258                            })
 5259                            .collect(),
 5260                    })
 5261                    .await
 5262                    .and_then(|result| result.transaction.context("missing transaction"));
 5263                lsp_store.update(cx, |lsp_store, _| {
 5264                    lsp_store.update_last_formatting_failure(&result);
 5265                })?;
 5266
 5267                let transaction_response = result?;
 5268                buffer_store
 5269                    .update(cx, |buffer_store, cx| {
 5270                        buffer_store.deserialize_project_transaction(
 5271                            transaction_response,
 5272                            push_to_history,
 5273                            cx,
 5274                        )
 5275                    })
 5276                    .await
 5277            })
 5278        } else {
 5279            Task::ready(Ok(ProjectTransaction::default()))
 5280        }
 5281    }
 5282
 5283    pub fn resolved_hint(
 5284        &mut self,
 5285        buffer_id: BufferId,
 5286        id: InlayId,
 5287        cx: &mut Context<Self>,
 5288    ) -> Option<ResolvedHint> {
 5289        let buffer = self.buffer_store.read(cx).get(buffer_id)?;
 5290
 5291        let lsp_data = self.lsp_data.get_mut(&buffer_id)?;
 5292        let buffer_lsp_hints = &mut lsp_data.inlay_hints;
 5293        let hint = buffer_lsp_hints.hint_for_id(id)?.clone();
 5294        let (server_id, resolve_data) = match &hint.resolve_state {
 5295            ResolveState::Resolved => return Some(ResolvedHint::Resolved(hint)),
 5296            ResolveState::Resolving => {
 5297                return Some(ResolvedHint::Resolving(
 5298                    buffer_lsp_hints.hint_resolves.get(&id)?.clone(),
 5299                ));
 5300            }
 5301            ResolveState::CanResolve(server_id, resolve_data) => (*server_id, resolve_data.clone()),
 5302        };
 5303
 5304        let resolve_task = self.resolve_inlay_hint(hint, buffer, server_id, cx);
 5305        let buffer_lsp_hints = &mut self.lsp_data.get_mut(&buffer_id)?.inlay_hints;
 5306        let previous_task = buffer_lsp_hints.hint_resolves.insert(
 5307            id,
 5308            cx.spawn(async move |lsp_store, cx| {
 5309                let resolved_hint = resolve_task.await;
 5310                lsp_store
 5311                    .update(cx, |lsp_store, _| {
 5312                        if let Some(old_inlay_hint) = lsp_store
 5313                            .lsp_data
 5314                            .get_mut(&buffer_id)
 5315                            .and_then(|buffer_lsp_data| buffer_lsp_data.inlay_hints.hint_for_id(id))
 5316                        {
 5317                            match resolved_hint {
 5318                                Ok(resolved_hint) => {
 5319                                    *old_inlay_hint = resolved_hint;
 5320                                }
 5321                                Err(e) => {
 5322                                    old_inlay_hint.resolve_state =
 5323                                        ResolveState::CanResolve(server_id, resolve_data);
 5324                                    log::error!("Inlay hint resolve failed: {e:#}");
 5325                                }
 5326                            }
 5327                        }
 5328                    })
 5329                    .ok();
 5330            })
 5331            .shared(),
 5332        );
 5333        debug_assert!(
 5334            previous_task.is_none(),
 5335            "Did not change hint's resolve state after spawning its resolve"
 5336        );
 5337        buffer_lsp_hints.hint_for_id(id)?.resolve_state = ResolveState::Resolving;
 5338        None
 5339    }
 5340
 5341    fn resolve_inlay_hint(
 5342        &self,
 5343        mut hint: InlayHint,
 5344        buffer: Entity<Buffer>,
 5345        server_id: LanguageServerId,
 5346        cx: &mut Context<Self>,
 5347    ) -> Task<anyhow::Result<InlayHint>> {
 5348        if let Some((upstream_client, project_id)) = self.upstream_client() {
 5349            if !self.check_if_capable_for_proto_request(&buffer, InlayHints::can_resolve_inlays, cx)
 5350            {
 5351                hint.resolve_state = ResolveState::Resolved;
 5352                return Task::ready(Ok(hint));
 5353            }
 5354            let request = proto::ResolveInlayHint {
 5355                project_id,
 5356                buffer_id: buffer.read(cx).remote_id().into(),
 5357                language_server_id: server_id.0 as u64,
 5358                hint: Some(InlayHints::project_to_proto_hint(hint.clone())),
 5359            };
 5360            cx.background_spawn(async move {
 5361                let response = upstream_client
 5362                    .request(request)
 5363                    .await
 5364                    .context("inlay hints proto request")?;
 5365                match response.hint {
 5366                    Some(resolved_hint) => InlayHints::proto_to_project_hint(resolved_hint)
 5367                        .context("inlay hints proto resolve response conversion"),
 5368                    None => Ok(hint),
 5369                }
 5370            })
 5371        } else {
 5372            let Some(lang_server) = buffer.update(cx, |buffer, cx| {
 5373                self.language_server_for_local_buffer(buffer, server_id, cx)
 5374                    .map(|(_, server)| server.clone())
 5375            }) else {
 5376                return Task::ready(Ok(hint));
 5377            };
 5378            if !InlayHints::can_resolve_inlays(&lang_server.capabilities()) {
 5379                return Task::ready(Ok(hint));
 5380            }
 5381            let buffer_snapshot = buffer.read(cx).snapshot();
 5382            cx.spawn(async move |_, cx| {
 5383                let resolve_task = lang_server.request::<lsp::request::InlayHintResolveRequest>(
 5384                    InlayHints::project_to_lsp_hint(hint, &buffer_snapshot),
 5385                );
 5386                let resolved_hint = resolve_task
 5387                    .await
 5388                    .into_response()
 5389                    .context("inlay hint resolve LSP request")?;
 5390                let resolved_hint = InlayHints::lsp_to_project_hint(
 5391                    resolved_hint,
 5392                    &buffer,
 5393                    server_id,
 5394                    ResolveState::Resolved,
 5395                    false,
 5396                    cx,
 5397                )
 5398                .await?;
 5399                Ok(resolved_hint)
 5400            })
 5401        }
 5402    }
 5403
 5404    pub fn resolve_color_presentation(
 5405        &mut self,
 5406        mut color: DocumentColor,
 5407        buffer: Entity<Buffer>,
 5408        server_id: LanguageServerId,
 5409        cx: &mut Context<Self>,
 5410    ) -> Task<Result<DocumentColor>> {
 5411        if color.resolved {
 5412            return Task::ready(Ok(color));
 5413        }
 5414
 5415        if let Some((upstream_client, project_id)) = self.upstream_client() {
 5416            let start = color.lsp_range.start;
 5417            let end = color.lsp_range.end;
 5418            let request = proto::GetColorPresentation {
 5419                project_id,
 5420                server_id: server_id.to_proto(),
 5421                buffer_id: buffer.read(cx).remote_id().into(),
 5422                color: Some(proto::ColorInformation {
 5423                    red: color.color.red,
 5424                    green: color.color.green,
 5425                    blue: color.color.blue,
 5426                    alpha: color.color.alpha,
 5427                    lsp_range_start: Some(proto::PointUtf16 {
 5428                        row: start.line,
 5429                        column: start.character,
 5430                    }),
 5431                    lsp_range_end: Some(proto::PointUtf16 {
 5432                        row: end.line,
 5433                        column: end.character,
 5434                    }),
 5435                }),
 5436            };
 5437            cx.background_spawn(async move {
 5438                let response = upstream_client
 5439                    .request(request)
 5440                    .await
 5441                    .context("color presentation proto request")?;
 5442                color.resolved = true;
 5443                color.color_presentations = response
 5444                    .presentations
 5445                    .into_iter()
 5446                    .map(|presentation| ColorPresentation {
 5447                        label: SharedString::from(presentation.label),
 5448                        text_edit: presentation.text_edit.and_then(deserialize_lsp_edit),
 5449                        additional_text_edits: presentation
 5450                            .additional_text_edits
 5451                            .into_iter()
 5452                            .filter_map(deserialize_lsp_edit)
 5453                            .collect(),
 5454                    })
 5455                    .collect();
 5456                Ok(color)
 5457            })
 5458        } else {
 5459            let path = match buffer
 5460                .update(cx, |buffer, cx| {
 5461                    Some(File::from_dyn(buffer.file())?.abs_path(cx))
 5462                })
 5463                .context("buffer with the missing path")
 5464            {
 5465                Ok(path) => path,
 5466                Err(e) => return Task::ready(Err(e)),
 5467            };
 5468            let Some(lang_server) = buffer.update(cx, |buffer, cx| {
 5469                self.language_server_for_local_buffer(buffer, server_id, cx)
 5470                    .map(|(_, server)| server.clone())
 5471            }) else {
 5472                return Task::ready(Ok(color));
 5473            };
 5474            cx.background_spawn(async move {
 5475                let resolve_task = lang_server.request::<lsp::request::ColorPresentationRequest>(
 5476                    lsp::ColorPresentationParams {
 5477                        text_document: make_text_document_identifier(&path)?,
 5478                        color: color.color,
 5479                        range: color.lsp_range,
 5480                        work_done_progress_params: Default::default(),
 5481                        partial_result_params: Default::default(),
 5482                    },
 5483                );
 5484                color.color_presentations = resolve_task
 5485                    .await
 5486                    .into_response()
 5487                    .context("color presentation resolve LSP request")?
 5488                    .into_iter()
 5489                    .map(|presentation| ColorPresentation {
 5490                        label: SharedString::from(presentation.label),
 5491                        text_edit: presentation.text_edit,
 5492                        additional_text_edits: presentation
 5493                            .additional_text_edits
 5494                            .unwrap_or_default(),
 5495                    })
 5496                    .collect();
 5497                color.resolved = true;
 5498                Ok(color)
 5499            })
 5500        }
 5501    }
 5502
 5503    pub(crate) fn linked_edits(
 5504        &mut self,
 5505        buffer: &Entity<Buffer>,
 5506        position: Anchor,
 5507        cx: &mut Context<Self>,
 5508    ) -> Task<Result<Vec<Range<Anchor>>>> {
 5509        let snapshot = buffer.read(cx).snapshot();
 5510        let scope = snapshot.language_scope_at(position);
 5511        let Some(server_id) = self
 5512            .as_local()
 5513            .and_then(|local| {
 5514                buffer.update(cx, |buffer, cx| {
 5515                    local
 5516                        .language_servers_for_buffer(buffer, cx)
 5517                        .filter(|(_, server)| {
 5518                            LinkedEditingRange::check_server_capabilities(server.capabilities())
 5519                        })
 5520                        .filter(|(adapter, _)| {
 5521                            scope
 5522                                .as_ref()
 5523                                .map(|scope| scope.language_allowed(&adapter.name))
 5524                                .unwrap_or(true)
 5525                        })
 5526                        .map(|(_, server)| LanguageServerToQuery::Other(server.server_id()))
 5527                        .next()
 5528                })
 5529            })
 5530            .or_else(|| {
 5531                self.upstream_client()
 5532                    .is_some()
 5533                    .then_some(LanguageServerToQuery::FirstCapable)
 5534            })
 5535            .filter(|_| {
 5536                maybe!({
 5537                    let language = buffer.read(cx).language_at(position)?;
 5538                    Some(
 5539                        language_settings(Some(language.name()), buffer.read(cx).file(), cx)
 5540                            .linked_edits,
 5541                    )
 5542                }) == Some(true)
 5543            })
 5544        else {
 5545            return Task::ready(Ok(Vec::new()));
 5546        };
 5547
 5548        self.request_lsp(
 5549            buffer.clone(),
 5550            server_id,
 5551            LinkedEditingRange { position },
 5552            cx,
 5553        )
 5554    }
 5555
 5556    fn apply_on_type_formatting(
 5557        &mut self,
 5558        buffer: Entity<Buffer>,
 5559        position: Anchor,
 5560        trigger: String,
 5561        cx: &mut Context<Self>,
 5562    ) -> Task<Result<Option<Transaction>>> {
 5563        if let Some((client, project_id)) = self.upstream_client() {
 5564            if !self.check_if_capable_for_proto_request(
 5565                &buffer,
 5566                |capabilities| {
 5567                    OnTypeFormatting::supports_on_type_formatting(&trigger, capabilities)
 5568                },
 5569                cx,
 5570            ) {
 5571                return Task::ready(Ok(None));
 5572            }
 5573            let request = proto::OnTypeFormatting {
 5574                project_id,
 5575                buffer_id: buffer.read(cx).remote_id().into(),
 5576                position: Some(serialize_anchor(&position)),
 5577                trigger,
 5578                version: serialize_version(&buffer.read(cx).version()),
 5579            };
 5580            cx.background_spawn(async move {
 5581                client
 5582                    .request(request)
 5583                    .await?
 5584                    .transaction
 5585                    .map(language::proto::deserialize_transaction)
 5586                    .transpose()
 5587            })
 5588        } else if let Some(local) = self.as_local_mut() {
 5589            let buffer_id = buffer.read(cx).remote_id();
 5590            local.buffers_being_formatted.insert(buffer_id);
 5591            cx.spawn(async move |this, cx| {
 5592                let _cleanup = defer({
 5593                    let this = this.clone();
 5594                    let mut cx = cx.clone();
 5595                    move || {
 5596                        this.update(&mut cx, |this, _| {
 5597                            if let Some(local) = this.as_local_mut() {
 5598                                local.buffers_being_formatted.remove(&buffer_id);
 5599                            }
 5600                        })
 5601                        .ok();
 5602                    }
 5603                });
 5604
 5605                buffer
 5606                    .update(cx, |buffer, _| {
 5607                        buffer.wait_for_edits(Some(position.timestamp))
 5608                    })
 5609                    .await?;
 5610                this.update(cx, |this, cx| {
 5611                    let position = position.to_point_utf16(buffer.read(cx));
 5612                    this.on_type_format(buffer, position, trigger, false, cx)
 5613                })?
 5614                .await
 5615            })
 5616        } else {
 5617            Task::ready(Err(anyhow!("No upstream client or local language server")))
 5618        }
 5619    }
 5620
 5621    pub fn on_type_format<T: ToPointUtf16>(
 5622        &mut self,
 5623        buffer: Entity<Buffer>,
 5624        position: T,
 5625        trigger: String,
 5626        push_to_history: bool,
 5627        cx: &mut Context<Self>,
 5628    ) -> Task<Result<Option<Transaction>>> {
 5629        let position = position.to_point_utf16(buffer.read(cx));
 5630        self.on_type_format_impl(buffer, position, trigger, push_to_history, cx)
 5631    }
 5632
 5633    fn on_type_format_impl(
 5634        &mut self,
 5635        buffer: Entity<Buffer>,
 5636        position: PointUtf16,
 5637        trigger: String,
 5638        push_to_history: bool,
 5639        cx: &mut Context<Self>,
 5640    ) -> Task<Result<Option<Transaction>>> {
 5641        let options = buffer.update(cx, |buffer, cx| {
 5642            lsp_command::lsp_formatting_options(
 5643                language_settings(
 5644                    buffer.language_at(position).map(|l| l.name()),
 5645                    buffer.file(),
 5646                    cx,
 5647                )
 5648                .as_ref(),
 5649            )
 5650        });
 5651
 5652        cx.spawn(async move |this, cx| {
 5653            if let Some(waiter) =
 5654                buffer.update(cx, |buffer, _| buffer.wait_for_autoindent_applied())
 5655            {
 5656                waiter.await?;
 5657            }
 5658            cx.update(|cx| {
 5659                this.update(cx, |this, cx| {
 5660                    this.request_lsp(
 5661                        buffer.clone(),
 5662                        LanguageServerToQuery::FirstCapable,
 5663                        OnTypeFormatting {
 5664                            position,
 5665                            trigger,
 5666                            options,
 5667                            push_to_history,
 5668                        },
 5669                        cx,
 5670                    )
 5671                })
 5672            })?
 5673            .await
 5674        })
 5675    }
 5676
 5677    pub fn definitions(
 5678        &mut self,
 5679        buffer: &Entity<Buffer>,
 5680        position: PointUtf16,
 5681        cx: &mut Context<Self>,
 5682    ) -> Task<Result<Option<Vec<LocationLink>>>> {
 5683        if let Some((upstream_client, project_id)) = self.upstream_client() {
 5684            let request = GetDefinitions { position };
 5685            if !self.is_capable_for_proto_request(buffer, &request, cx) {
 5686                return Task::ready(Ok(None));
 5687            }
 5688            let request_task = upstream_client.request_lsp(
 5689                project_id,
 5690                None,
 5691                LSP_REQUEST_TIMEOUT,
 5692                cx.background_executor().clone(),
 5693                request.to_proto(project_id, buffer.read(cx)),
 5694            );
 5695            let buffer = buffer.clone();
 5696            cx.spawn(async move |weak_lsp_store, cx| {
 5697                let Some(lsp_store) = weak_lsp_store.upgrade() else {
 5698                    return Ok(None);
 5699                };
 5700                let Some(responses) = request_task.await? else {
 5701                    return Ok(None);
 5702                };
 5703                let actions = join_all(responses.payload.into_iter().map(|response| {
 5704                    GetDefinitions { position }.response_from_proto(
 5705                        response.response,
 5706                        lsp_store.clone(),
 5707                        buffer.clone(),
 5708                        cx.clone(),
 5709                    )
 5710                }))
 5711                .await;
 5712
 5713                Ok(Some(
 5714                    actions
 5715                        .into_iter()
 5716                        .collect::<Result<Vec<Vec<_>>>>()?
 5717                        .into_iter()
 5718                        .flatten()
 5719                        .dedup()
 5720                        .collect(),
 5721                ))
 5722            })
 5723        } else {
 5724            let definitions_task = self.request_multiple_lsp_locally(
 5725                buffer,
 5726                Some(position),
 5727                GetDefinitions { position },
 5728                cx,
 5729            );
 5730            cx.background_spawn(async move {
 5731                Ok(Some(
 5732                    definitions_task
 5733                        .await
 5734                        .into_iter()
 5735                        .flat_map(|(_, definitions)| definitions)
 5736                        .dedup()
 5737                        .collect(),
 5738                ))
 5739            })
 5740        }
 5741    }
 5742
 5743    pub fn declarations(
 5744        &mut self,
 5745        buffer: &Entity<Buffer>,
 5746        position: PointUtf16,
 5747        cx: &mut Context<Self>,
 5748    ) -> Task<Result<Option<Vec<LocationLink>>>> {
 5749        if let Some((upstream_client, project_id)) = self.upstream_client() {
 5750            let request = GetDeclarations { position };
 5751            if !self.is_capable_for_proto_request(buffer, &request, cx) {
 5752                return Task::ready(Ok(None));
 5753            }
 5754            let request_task = upstream_client.request_lsp(
 5755                project_id,
 5756                None,
 5757                LSP_REQUEST_TIMEOUT,
 5758                cx.background_executor().clone(),
 5759                request.to_proto(project_id, buffer.read(cx)),
 5760            );
 5761            let buffer = buffer.clone();
 5762            cx.spawn(async move |weak_lsp_store, cx| {
 5763                let Some(lsp_store) = weak_lsp_store.upgrade() else {
 5764                    return Ok(None);
 5765                };
 5766                let Some(responses) = request_task.await? else {
 5767                    return Ok(None);
 5768                };
 5769                let actions = join_all(responses.payload.into_iter().map(|response| {
 5770                    GetDeclarations { position }.response_from_proto(
 5771                        response.response,
 5772                        lsp_store.clone(),
 5773                        buffer.clone(),
 5774                        cx.clone(),
 5775                    )
 5776                }))
 5777                .await;
 5778
 5779                Ok(Some(
 5780                    actions
 5781                        .into_iter()
 5782                        .collect::<Result<Vec<Vec<_>>>>()?
 5783                        .into_iter()
 5784                        .flatten()
 5785                        .dedup()
 5786                        .collect(),
 5787                ))
 5788            })
 5789        } else {
 5790            let declarations_task = self.request_multiple_lsp_locally(
 5791                buffer,
 5792                Some(position),
 5793                GetDeclarations { position },
 5794                cx,
 5795            );
 5796            cx.background_spawn(async move {
 5797                Ok(Some(
 5798                    declarations_task
 5799                        .await
 5800                        .into_iter()
 5801                        .flat_map(|(_, declarations)| declarations)
 5802                        .dedup()
 5803                        .collect(),
 5804                ))
 5805            })
 5806        }
 5807    }
 5808
 5809    pub fn type_definitions(
 5810        &mut self,
 5811        buffer: &Entity<Buffer>,
 5812        position: PointUtf16,
 5813        cx: &mut Context<Self>,
 5814    ) -> Task<Result<Option<Vec<LocationLink>>>> {
 5815        if let Some((upstream_client, project_id)) = self.upstream_client() {
 5816            let request = GetTypeDefinitions { position };
 5817            if !self.is_capable_for_proto_request(buffer, &request, cx) {
 5818                return Task::ready(Ok(None));
 5819            }
 5820            let request_task = upstream_client.request_lsp(
 5821                project_id,
 5822                None,
 5823                LSP_REQUEST_TIMEOUT,
 5824                cx.background_executor().clone(),
 5825                request.to_proto(project_id, buffer.read(cx)),
 5826            );
 5827            let buffer = buffer.clone();
 5828            cx.spawn(async move |weak_lsp_store, cx| {
 5829                let Some(lsp_store) = weak_lsp_store.upgrade() else {
 5830                    return Ok(None);
 5831                };
 5832                let Some(responses) = request_task.await? else {
 5833                    return Ok(None);
 5834                };
 5835                let actions = join_all(responses.payload.into_iter().map(|response| {
 5836                    GetTypeDefinitions { position }.response_from_proto(
 5837                        response.response,
 5838                        lsp_store.clone(),
 5839                        buffer.clone(),
 5840                        cx.clone(),
 5841                    )
 5842                }))
 5843                .await;
 5844
 5845                Ok(Some(
 5846                    actions
 5847                        .into_iter()
 5848                        .collect::<Result<Vec<Vec<_>>>>()?
 5849                        .into_iter()
 5850                        .flatten()
 5851                        .dedup()
 5852                        .collect(),
 5853                ))
 5854            })
 5855        } else {
 5856            let type_definitions_task = self.request_multiple_lsp_locally(
 5857                buffer,
 5858                Some(position),
 5859                GetTypeDefinitions { position },
 5860                cx,
 5861            );
 5862            cx.background_spawn(async move {
 5863                Ok(Some(
 5864                    type_definitions_task
 5865                        .await
 5866                        .into_iter()
 5867                        .flat_map(|(_, type_definitions)| type_definitions)
 5868                        .dedup()
 5869                        .collect(),
 5870                ))
 5871            })
 5872        }
 5873    }
 5874
 5875    pub fn implementations(
 5876        &mut self,
 5877        buffer: &Entity<Buffer>,
 5878        position: PointUtf16,
 5879        cx: &mut Context<Self>,
 5880    ) -> Task<Result<Option<Vec<LocationLink>>>> {
 5881        if let Some((upstream_client, project_id)) = self.upstream_client() {
 5882            let request = GetImplementations { position };
 5883            if !self.is_capable_for_proto_request(buffer, &request, cx) {
 5884                return Task::ready(Ok(None));
 5885            }
 5886            let request_task = upstream_client.request_lsp(
 5887                project_id,
 5888                None,
 5889                LSP_REQUEST_TIMEOUT,
 5890                cx.background_executor().clone(),
 5891                request.to_proto(project_id, buffer.read(cx)),
 5892            );
 5893            let buffer = buffer.clone();
 5894            cx.spawn(async move |weak_lsp_store, cx| {
 5895                let Some(lsp_store) = weak_lsp_store.upgrade() else {
 5896                    return Ok(None);
 5897                };
 5898                let Some(responses) = request_task.await? else {
 5899                    return Ok(None);
 5900                };
 5901                let actions = join_all(responses.payload.into_iter().map(|response| {
 5902                    GetImplementations { position }.response_from_proto(
 5903                        response.response,
 5904                        lsp_store.clone(),
 5905                        buffer.clone(),
 5906                        cx.clone(),
 5907                    )
 5908                }))
 5909                .await;
 5910
 5911                Ok(Some(
 5912                    actions
 5913                        .into_iter()
 5914                        .collect::<Result<Vec<Vec<_>>>>()?
 5915                        .into_iter()
 5916                        .flatten()
 5917                        .dedup()
 5918                        .collect(),
 5919                ))
 5920            })
 5921        } else {
 5922            let implementations_task = self.request_multiple_lsp_locally(
 5923                buffer,
 5924                Some(position),
 5925                GetImplementations { position },
 5926                cx,
 5927            );
 5928            cx.background_spawn(async move {
 5929                Ok(Some(
 5930                    implementations_task
 5931                        .await
 5932                        .into_iter()
 5933                        .flat_map(|(_, implementations)| implementations)
 5934                        .dedup()
 5935                        .collect(),
 5936                ))
 5937            })
 5938        }
 5939    }
 5940
 5941    pub fn references(
 5942        &mut self,
 5943        buffer: &Entity<Buffer>,
 5944        position: PointUtf16,
 5945        cx: &mut Context<Self>,
 5946    ) -> Task<Result<Option<Vec<Location>>>> {
 5947        if let Some((upstream_client, project_id)) = self.upstream_client() {
 5948            let request = GetReferences { position };
 5949            if !self.is_capable_for_proto_request(buffer, &request, cx) {
 5950                return Task::ready(Ok(None));
 5951            }
 5952
 5953            let request_task = upstream_client.request_lsp(
 5954                project_id,
 5955                None,
 5956                LSP_REQUEST_TIMEOUT,
 5957                cx.background_executor().clone(),
 5958                request.to_proto(project_id, buffer.read(cx)),
 5959            );
 5960            let buffer = buffer.clone();
 5961            cx.spawn(async move |weak_lsp_store, cx| {
 5962                let Some(lsp_store) = weak_lsp_store.upgrade() else {
 5963                    return Ok(None);
 5964                };
 5965                let Some(responses) = request_task.await? else {
 5966                    return Ok(None);
 5967                };
 5968
 5969                let locations = join_all(responses.payload.into_iter().map(|lsp_response| {
 5970                    GetReferences { position }.response_from_proto(
 5971                        lsp_response.response,
 5972                        lsp_store.clone(),
 5973                        buffer.clone(),
 5974                        cx.clone(),
 5975                    )
 5976                }))
 5977                .await
 5978                .into_iter()
 5979                .collect::<Result<Vec<Vec<_>>>>()?
 5980                .into_iter()
 5981                .flatten()
 5982                .dedup()
 5983                .collect();
 5984                Ok(Some(locations))
 5985            })
 5986        } else {
 5987            let references_task = self.request_multiple_lsp_locally(
 5988                buffer,
 5989                Some(position),
 5990                GetReferences { position },
 5991                cx,
 5992            );
 5993            cx.background_spawn(async move {
 5994                Ok(Some(
 5995                    references_task
 5996                        .await
 5997                        .into_iter()
 5998                        .flat_map(|(_, references)| references)
 5999                        .dedup()
 6000                        .collect(),
 6001                ))
 6002            })
 6003        }
 6004    }
 6005
 6006    pub fn code_actions(
 6007        &mut self,
 6008        buffer: &Entity<Buffer>,
 6009        range: Range<Anchor>,
 6010        kinds: Option<Vec<CodeActionKind>>,
 6011        cx: &mut Context<Self>,
 6012    ) -> Task<Result<Option<Vec<CodeAction>>>> {
 6013        if let Some((upstream_client, project_id)) = self.upstream_client() {
 6014            let request = GetCodeActions {
 6015                range: range.clone(),
 6016                kinds: kinds.clone(),
 6017            };
 6018            if !self.is_capable_for_proto_request(buffer, &request, cx) {
 6019                return Task::ready(Ok(None));
 6020            }
 6021            let request_task = upstream_client.request_lsp(
 6022                project_id,
 6023                None,
 6024                LSP_REQUEST_TIMEOUT,
 6025                cx.background_executor().clone(),
 6026                request.to_proto(project_id, buffer.read(cx)),
 6027            );
 6028            let buffer = buffer.clone();
 6029            cx.spawn(async move |weak_lsp_store, cx| {
 6030                let Some(lsp_store) = weak_lsp_store.upgrade() else {
 6031                    return Ok(None);
 6032                };
 6033                let Some(responses) = request_task.await? else {
 6034                    return Ok(None);
 6035                };
 6036                let actions = join_all(responses.payload.into_iter().map(|response| {
 6037                    GetCodeActions {
 6038                        range: range.clone(),
 6039                        kinds: kinds.clone(),
 6040                    }
 6041                    .response_from_proto(
 6042                        response.response,
 6043                        lsp_store.clone(),
 6044                        buffer.clone(),
 6045                        cx.clone(),
 6046                    )
 6047                }))
 6048                .await;
 6049
 6050                Ok(Some(
 6051                    actions
 6052                        .into_iter()
 6053                        .collect::<Result<Vec<Vec<_>>>>()?
 6054                        .into_iter()
 6055                        .flatten()
 6056                        .collect(),
 6057                ))
 6058            })
 6059        } else {
 6060            let all_actions_task = self.request_multiple_lsp_locally(
 6061                buffer,
 6062                Some(range.start),
 6063                GetCodeActions { range, kinds },
 6064                cx,
 6065            );
 6066            cx.background_spawn(async move {
 6067                Ok(Some(
 6068                    all_actions_task
 6069                        .await
 6070                        .into_iter()
 6071                        .flat_map(|(_, actions)| actions)
 6072                        .collect(),
 6073                ))
 6074            })
 6075        }
 6076    }
 6077
 6078    pub fn code_lens_actions(
 6079        &mut self,
 6080        buffer: &Entity<Buffer>,
 6081        cx: &mut Context<Self>,
 6082    ) -> CodeLensTask {
 6083        let version_queried_for = buffer.read(cx).version();
 6084        let buffer_id = buffer.read(cx).remote_id();
 6085        let existing_servers = self.as_local().map(|local| {
 6086            local
 6087                .buffers_opened_in_servers
 6088                .get(&buffer_id)
 6089                .cloned()
 6090                .unwrap_or_default()
 6091        });
 6092
 6093        if let Some(lsp_data) = self.current_lsp_data(buffer_id) {
 6094            if let Some(cached_lens) = &lsp_data.code_lens {
 6095                if !version_queried_for.changed_since(&lsp_data.buffer_version) {
 6096                    let has_different_servers = existing_servers.is_some_and(|existing_servers| {
 6097                        existing_servers != cached_lens.lens.keys().copied().collect()
 6098                    });
 6099                    if !has_different_servers {
 6100                        return Task::ready(Ok(Some(
 6101                            cached_lens.lens.values().flatten().cloned().collect(),
 6102                        )))
 6103                        .shared();
 6104                    }
 6105                } else if let Some((updating_for, running_update)) = cached_lens.update.as_ref() {
 6106                    if !version_queried_for.changed_since(updating_for) {
 6107                        return running_update.clone();
 6108                    }
 6109                }
 6110            }
 6111        }
 6112
 6113        let lens_lsp_data = self
 6114            .latest_lsp_data(buffer, cx)
 6115            .code_lens
 6116            .get_or_insert_default();
 6117        let buffer = buffer.clone();
 6118        let query_version_queried_for = version_queried_for.clone();
 6119        let new_task = cx
 6120            .spawn(async move |lsp_store, cx| {
 6121                cx.background_executor()
 6122                    .timer(Duration::from_millis(30))
 6123                    .await;
 6124                let fetched_lens = lsp_store
 6125                    .update(cx, |lsp_store, cx| lsp_store.fetch_code_lens(&buffer, cx))
 6126                    .map_err(Arc::new)?
 6127                    .await
 6128                    .context("fetching code lens")
 6129                    .map_err(Arc::new);
 6130                let fetched_lens = match fetched_lens {
 6131                    Ok(fetched_lens) => fetched_lens,
 6132                    Err(e) => {
 6133                        lsp_store
 6134                            .update(cx, |lsp_store, _| {
 6135                                if let Some(lens_lsp_data) = lsp_store
 6136                                    .lsp_data
 6137                                    .get_mut(&buffer_id)
 6138                                    .and_then(|lsp_data| lsp_data.code_lens.as_mut())
 6139                                {
 6140                                    lens_lsp_data.update = None;
 6141                                }
 6142                            })
 6143                            .ok();
 6144                        return Err(e);
 6145                    }
 6146                };
 6147
 6148                lsp_store
 6149                    .update(cx, |lsp_store, _| {
 6150                        let lsp_data = lsp_store.current_lsp_data(buffer_id)?;
 6151                        let code_lens = lsp_data.code_lens.as_mut()?;
 6152                        if let Some(fetched_lens) = fetched_lens {
 6153                            if lsp_data.buffer_version == query_version_queried_for {
 6154                                code_lens.lens.extend(fetched_lens);
 6155                            } else if !lsp_data
 6156                                .buffer_version
 6157                                .changed_since(&query_version_queried_for)
 6158                            {
 6159                                lsp_data.buffer_version = query_version_queried_for;
 6160                                code_lens.lens = fetched_lens;
 6161                            }
 6162                        }
 6163                        code_lens.update = None;
 6164                        Some(code_lens.lens.values().flatten().cloned().collect())
 6165                    })
 6166                    .map_err(Arc::new)
 6167            })
 6168            .shared();
 6169        lens_lsp_data.update = Some((version_queried_for, new_task.clone()));
 6170        new_task
 6171    }
 6172
 6173    fn fetch_code_lens(
 6174        &mut self,
 6175        buffer: &Entity<Buffer>,
 6176        cx: &mut Context<Self>,
 6177    ) -> Task<Result<Option<HashMap<LanguageServerId, Vec<CodeAction>>>>> {
 6178        if let Some((upstream_client, project_id)) = self.upstream_client() {
 6179            let request = GetCodeLens;
 6180            if !self.is_capable_for_proto_request(buffer, &request, cx) {
 6181                return Task::ready(Ok(None));
 6182            }
 6183            let request_task = upstream_client.request_lsp(
 6184                project_id,
 6185                None,
 6186                LSP_REQUEST_TIMEOUT,
 6187                cx.background_executor().clone(),
 6188                request.to_proto(project_id, buffer.read(cx)),
 6189            );
 6190            let buffer = buffer.clone();
 6191            cx.spawn(async move |weak_lsp_store, cx| {
 6192                let Some(lsp_store) = weak_lsp_store.upgrade() else {
 6193                    return Ok(None);
 6194                };
 6195                let Some(responses) = request_task.await? else {
 6196                    return Ok(None);
 6197                };
 6198
 6199                let code_lens_actions = join_all(responses.payload.into_iter().map(|response| {
 6200                    let lsp_store = lsp_store.clone();
 6201                    let buffer = buffer.clone();
 6202                    let cx = cx.clone();
 6203                    async move {
 6204                        (
 6205                            LanguageServerId::from_proto(response.server_id),
 6206                            GetCodeLens
 6207                                .response_from_proto(response.response, lsp_store, buffer, cx)
 6208                                .await,
 6209                        )
 6210                    }
 6211                }))
 6212                .await;
 6213
 6214                let mut has_errors = false;
 6215                let code_lens_actions = code_lens_actions
 6216                    .into_iter()
 6217                    .filter_map(|(server_id, code_lens)| match code_lens {
 6218                        Ok(code_lens) => Some((server_id, code_lens)),
 6219                        Err(e) => {
 6220                            has_errors = true;
 6221                            log::error!("{e:#}");
 6222                            None
 6223                        }
 6224                    })
 6225                    .collect::<HashMap<_, _>>();
 6226                anyhow::ensure!(
 6227                    !has_errors || !code_lens_actions.is_empty(),
 6228                    "Failed to fetch code lens"
 6229                );
 6230                Ok(Some(code_lens_actions))
 6231            })
 6232        } else {
 6233            let code_lens_actions_task =
 6234                self.request_multiple_lsp_locally(buffer, None::<usize>, GetCodeLens, cx);
 6235            cx.background_spawn(async move {
 6236                Ok(Some(code_lens_actions_task.await.into_iter().collect()))
 6237            })
 6238        }
 6239    }
 6240
 6241    #[inline(never)]
 6242    pub fn completions(
 6243        &self,
 6244        buffer: &Entity<Buffer>,
 6245        position: PointUtf16,
 6246        context: CompletionContext,
 6247        cx: &mut Context<Self>,
 6248    ) -> Task<Result<Vec<CompletionResponse>>> {
 6249        let language_registry = self.languages.clone();
 6250
 6251        if let Some((upstream_client, project_id)) = self.upstream_client() {
 6252            let snapshot = buffer.read(cx).snapshot();
 6253            let offset = position.to_offset(&snapshot);
 6254            let scope = snapshot.language_scope_at(offset);
 6255            let capable_lsps = self.all_capable_for_proto_request(
 6256                buffer,
 6257                |server_name, capabilities| {
 6258                    capabilities.completion_provider.is_some()
 6259                        && scope
 6260                            .as_ref()
 6261                            .map(|scope| scope.language_allowed(server_name))
 6262                            .unwrap_or(true)
 6263                },
 6264                cx,
 6265            );
 6266            if capable_lsps.is_empty() {
 6267                return Task::ready(Ok(Vec::new()));
 6268            }
 6269
 6270            let language = buffer.read(cx).language().cloned();
 6271
 6272            // In the future, we should provide project guests with the names of LSP adapters,
 6273            // so that they can use the correct LSP adapter when computing labels. For now,
 6274            // guests just use the first LSP adapter associated with the buffer's language.
 6275            let lsp_adapter = language.as_ref().and_then(|language| {
 6276                language_registry
 6277                    .lsp_adapters(&language.name())
 6278                    .first()
 6279                    .cloned()
 6280            });
 6281
 6282            let buffer = buffer.clone();
 6283
 6284            cx.spawn(async move |this, cx| {
 6285                let requests = join_all(
 6286                    capable_lsps
 6287                        .into_iter()
 6288                        .map(|id| {
 6289                            let request = GetCompletions {
 6290                                position,
 6291                                context: context.clone(),
 6292                                server_id: Some(id),
 6293                            };
 6294                            let buffer = buffer.clone();
 6295                            let language = language.clone();
 6296                            let lsp_adapter = lsp_adapter.clone();
 6297                            let upstream_client = upstream_client.clone();
 6298                            let response = this
 6299                                .update(cx, |this, cx| {
 6300                                    this.send_lsp_proto_request(
 6301                                        buffer,
 6302                                        upstream_client,
 6303                                        project_id,
 6304                                        request,
 6305                                        cx,
 6306                                    )
 6307                                })
 6308                                .log_err();
 6309                            async move {
 6310                                let response = response?.await.log_err()?;
 6311
 6312                                let completions = populate_labels_for_completions(
 6313                                    response.completions,
 6314                                    language,
 6315                                    lsp_adapter,
 6316                                )
 6317                                .await;
 6318
 6319                                Some(CompletionResponse {
 6320                                    completions,
 6321                                    display_options: CompletionDisplayOptions::default(),
 6322                                    is_incomplete: response.is_incomplete,
 6323                                })
 6324                            }
 6325                        })
 6326                        .collect::<Vec<_>>(),
 6327                );
 6328                Ok(requests.await.into_iter().flatten().collect::<Vec<_>>())
 6329            })
 6330        } else if let Some(local) = self.as_local() {
 6331            let snapshot = buffer.read(cx).snapshot();
 6332            let offset = position.to_offset(&snapshot);
 6333            let scope = snapshot.language_scope_at(offset);
 6334            let language = snapshot.language().cloned();
 6335            let completion_settings = language_settings(
 6336                language.as_ref().map(|language| language.name()),
 6337                buffer.read(cx).file(),
 6338                cx,
 6339            )
 6340            .completions
 6341            .clone();
 6342            if !completion_settings.lsp {
 6343                return Task::ready(Ok(Vec::new()));
 6344            }
 6345
 6346            let server_ids: Vec<_> = buffer.update(cx, |buffer, cx| {
 6347                local
 6348                    .language_servers_for_buffer(buffer, cx)
 6349                    .filter(|(_, server)| server.capabilities().completion_provider.is_some())
 6350                    .filter(|(adapter, _)| {
 6351                        scope
 6352                            .as_ref()
 6353                            .map(|scope| scope.language_allowed(&adapter.name))
 6354                            .unwrap_or(true)
 6355                    })
 6356                    .map(|(_, server)| server.server_id())
 6357                    .collect()
 6358            });
 6359
 6360            let buffer = buffer.clone();
 6361            let lsp_timeout = completion_settings.lsp_fetch_timeout_ms;
 6362            let lsp_timeout = if lsp_timeout > 0 {
 6363                Some(Duration::from_millis(lsp_timeout))
 6364            } else {
 6365                None
 6366            };
 6367            cx.spawn(async move |this,  cx| {
 6368                let mut tasks = Vec::with_capacity(server_ids.len());
 6369                this.update(cx, |lsp_store, cx| {
 6370                    for server_id in server_ids {
 6371                        let lsp_adapter = lsp_store.language_server_adapter_for_id(server_id);
 6372                        let lsp_timeout = lsp_timeout
 6373                            .map(|lsp_timeout| cx.background_executor().timer(lsp_timeout));
 6374                        let mut timeout = cx.background_spawn(async move {
 6375                            match lsp_timeout {
 6376                                Some(lsp_timeout) => {
 6377                                    lsp_timeout.await;
 6378                                    true
 6379                                },
 6380                                None => false,
 6381                            }
 6382                        }).fuse();
 6383                        let mut lsp_request = lsp_store.request_lsp(
 6384                            buffer.clone(),
 6385                            LanguageServerToQuery::Other(server_id),
 6386                            GetCompletions {
 6387                                position,
 6388                                context: context.clone(),
 6389                                server_id: Some(server_id),
 6390                            },
 6391                            cx,
 6392                        ).fuse();
 6393                        let new_task = cx.background_spawn(async move {
 6394                            select_biased! {
 6395                                response = lsp_request => anyhow::Ok(Some(response?)),
 6396                                timeout_happened = timeout => {
 6397                                    if timeout_happened {
 6398                                        log::warn!("Fetching completions from server {server_id} timed out, timeout ms: {}", completion_settings.lsp_fetch_timeout_ms);
 6399                                        Ok(None)
 6400                                    } else {
 6401                                        let completions = lsp_request.await?;
 6402                                        Ok(Some(completions))
 6403                                    }
 6404                                },
 6405                            }
 6406                        });
 6407                        tasks.push((lsp_adapter, new_task));
 6408                    }
 6409                })?;
 6410
 6411                let futures = tasks.into_iter().map(async |(lsp_adapter, task)| {
 6412                    let completion_response = task.await.ok()??;
 6413                    let completions = populate_labels_for_completions(
 6414                            completion_response.completions,
 6415                            language.clone(),
 6416                            lsp_adapter,
 6417                        )
 6418                        .await;
 6419                    Some(CompletionResponse {
 6420                        completions,
 6421                        display_options: CompletionDisplayOptions::default(),
 6422                        is_incomplete: completion_response.is_incomplete,
 6423                    })
 6424                });
 6425
 6426                let responses: Vec<Option<CompletionResponse>> = join_all(futures).await;
 6427
 6428                Ok(responses.into_iter().flatten().collect())
 6429            })
 6430        } else {
 6431            Task::ready(Err(anyhow!("No upstream client or local language server")))
 6432        }
 6433    }
 6434
 6435    pub fn resolve_completions(
 6436        &self,
 6437        buffer: Entity<Buffer>,
 6438        completion_indices: Vec<usize>,
 6439        completions: Rc<RefCell<Box<[Completion]>>>,
 6440        cx: &mut Context<Self>,
 6441    ) -> Task<Result<bool>> {
 6442        let client = self.upstream_client();
 6443        let buffer_id = buffer.read(cx).remote_id();
 6444        let buffer_snapshot = buffer.read(cx).snapshot();
 6445
 6446        if !self.check_if_capable_for_proto_request(
 6447            &buffer,
 6448            GetCompletions::can_resolve_completions,
 6449            cx,
 6450        ) {
 6451            return Task::ready(Ok(false));
 6452        }
 6453        cx.spawn(async move |lsp_store, cx| {
 6454            let mut did_resolve = false;
 6455            if let Some((client, project_id)) = client {
 6456                for completion_index in completion_indices {
 6457                    let server_id = {
 6458                        let completion = &completions.borrow()[completion_index];
 6459                        completion.source.server_id()
 6460                    };
 6461                    if let Some(server_id) = server_id {
 6462                        if Self::resolve_completion_remote(
 6463                            project_id,
 6464                            server_id,
 6465                            buffer_id,
 6466                            completions.clone(),
 6467                            completion_index,
 6468                            client.clone(),
 6469                        )
 6470                        .await
 6471                        .log_err()
 6472                        .is_some()
 6473                        {
 6474                            did_resolve = true;
 6475                        }
 6476                    } else {
 6477                        resolve_word_completion(
 6478                            &buffer_snapshot,
 6479                            &mut completions.borrow_mut()[completion_index],
 6480                        );
 6481                    }
 6482                }
 6483            } else {
 6484                for completion_index in completion_indices {
 6485                    let server_id = {
 6486                        let completion = &completions.borrow()[completion_index];
 6487                        completion.source.server_id()
 6488                    };
 6489                    if let Some(server_id) = server_id {
 6490                        let server_and_adapter = lsp_store
 6491                            .read_with(cx, |lsp_store, _| {
 6492                                let server = lsp_store.language_server_for_id(server_id)?;
 6493                                let adapter =
 6494                                    lsp_store.language_server_adapter_for_id(server.server_id())?;
 6495                                Some((server, adapter))
 6496                            })
 6497                            .ok()
 6498                            .flatten();
 6499                        let Some((server, adapter)) = server_and_adapter else {
 6500                            continue;
 6501                        };
 6502
 6503                        let resolved = Self::resolve_completion_local(
 6504                            server,
 6505                            completions.clone(),
 6506                            completion_index,
 6507                        )
 6508                        .await
 6509                        .log_err()
 6510                        .is_some();
 6511                        if resolved {
 6512                            Self::regenerate_completion_labels(
 6513                                adapter,
 6514                                &buffer_snapshot,
 6515                                completions.clone(),
 6516                                completion_index,
 6517                            )
 6518                            .await
 6519                            .log_err();
 6520                            did_resolve = true;
 6521                        }
 6522                    } else {
 6523                        resolve_word_completion(
 6524                            &buffer_snapshot,
 6525                            &mut completions.borrow_mut()[completion_index],
 6526                        );
 6527                    }
 6528                }
 6529            }
 6530
 6531            Ok(did_resolve)
 6532        })
 6533    }
 6534
 6535    async fn resolve_completion_local(
 6536        server: Arc<lsp::LanguageServer>,
 6537        completions: Rc<RefCell<Box<[Completion]>>>,
 6538        completion_index: usize,
 6539    ) -> Result<()> {
 6540        let server_id = server.server_id();
 6541        if !GetCompletions::can_resolve_completions(&server.capabilities()) {
 6542            return Ok(());
 6543        }
 6544
 6545        let request = {
 6546            let completion = &completions.borrow()[completion_index];
 6547            match &completion.source {
 6548                CompletionSource::Lsp {
 6549                    lsp_completion,
 6550                    resolved,
 6551                    server_id: completion_server_id,
 6552                    ..
 6553                } => {
 6554                    if *resolved {
 6555                        return Ok(());
 6556                    }
 6557                    anyhow::ensure!(
 6558                        server_id == *completion_server_id,
 6559                        "server_id mismatch, querying completion resolve for {server_id} but completion server id is {completion_server_id}"
 6560                    );
 6561                    server.request::<lsp::request::ResolveCompletionItem>(*lsp_completion.clone())
 6562                }
 6563                CompletionSource::BufferWord { .. }
 6564                | CompletionSource::Dap { .. }
 6565                | CompletionSource::Custom => {
 6566                    return Ok(());
 6567                }
 6568            }
 6569        };
 6570        let resolved_completion = request
 6571            .await
 6572            .into_response()
 6573            .context("resolve completion")?;
 6574
 6575        // We must not use any data such as sortText, filterText, insertText and textEdit to edit `Completion` since they are not suppose change during resolve.
 6576        // Refer: https://microsoft.github.io/language-server-protocol/specifications/lsp/3.17/specification/#textDocument_completion
 6577
 6578        let mut completions = completions.borrow_mut();
 6579        let completion = &mut completions[completion_index];
 6580        if let CompletionSource::Lsp {
 6581            lsp_completion,
 6582            resolved,
 6583            server_id: completion_server_id,
 6584            ..
 6585        } = &mut completion.source
 6586        {
 6587            if *resolved {
 6588                return Ok(());
 6589            }
 6590            anyhow::ensure!(
 6591                server_id == *completion_server_id,
 6592                "server_id mismatch, applying completion resolve for {server_id} but completion server id is {completion_server_id}"
 6593            );
 6594            **lsp_completion = resolved_completion;
 6595            *resolved = true;
 6596        }
 6597        Ok(())
 6598    }
 6599
 6600    async fn regenerate_completion_labels(
 6601        adapter: Arc<CachedLspAdapter>,
 6602        snapshot: &BufferSnapshot,
 6603        completions: Rc<RefCell<Box<[Completion]>>>,
 6604        completion_index: usize,
 6605    ) -> Result<()> {
 6606        let completion_item = completions.borrow()[completion_index]
 6607            .source
 6608            .lsp_completion(true)
 6609            .map(Cow::into_owned);
 6610        if let Some(lsp_documentation) = completion_item
 6611            .as_ref()
 6612            .and_then(|completion_item| completion_item.documentation.clone())
 6613        {
 6614            let mut completions = completions.borrow_mut();
 6615            let completion = &mut completions[completion_index];
 6616            completion.documentation = Some(lsp_documentation.into());
 6617        } else {
 6618            let mut completions = completions.borrow_mut();
 6619            let completion = &mut completions[completion_index];
 6620            completion.documentation = Some(CompletionDocumentation::Undocumented);
 6621        }
 6622
 6623        let mut new_label = match completion_item {
 6624            Some(completion_item) => {
 6625                // Some language servers always return `detail` lazily via resolve, regardless of
 6626                // the resolvable properties Zed advertises. Regenerate labels here to handle this.
 6627                // See: https://github.com/yioneko/vtsls/issues/213
 6628                let language = snapshot.language();
 6629                match language {
 6630                    Some(language) => {
 6631                        adapter
 6632                            .labels_for_completions(
 6633                                std::slice::from_ref(&completion_item),
 6634                                language,
 6635                            )
 6636                            .await?
 6637                    }
 6638                    None => Vec::new(),
 6639                }
 6640                .pop()
 6641                .flatten()
 6642                .unwrap_or_else(|| {
 6643                    CodeLabel::fallback_for_completion(
 6644                        &completion_item,
 6645                        language.map(|language| language.as_ref()),
 6646                    )
 6647                })
 6648            }
 6649            None => CodeLabel::plain(
 6650                completions.borrow()[completion_index].new_text.clone(),
 6651                None,
 6652            ),
 6653        };
 6654        ensure_uniform_list_compatible_label(&mut new_label);
 6655
 6656        let mut completions = completions.borrow_mut();
 6657        let completion = &mut completions[completion_index];
 6658        if completion.label.filter_text() == new_label.filter_text() {
 6659            completion.label = new_label;
 6660        } else {
 6661            log::error!(
 6662                "Resolved completion changed display label from {} to {}. \
 6663                 Refusing to apply this because it changes the fuzzy match text from {} to {}",
 6664                completion.label.text(),
 6665                new_label.text(),
 6666                completion.label.filter_text(),
 6667                new_label.filter_text()
 6668            );
 6669        }
 6670
 6671        Ok(())
 6672    }
 6673
 6674    async fn resolve_completion_remote(
 6675        project_id: u64,
 6676        server_id: LanguageServerId,
 6677        buffer_id: BufferId,
 6678        completions: Rc<RefCell<Box<[Completion]>>>,
 6679        completion_index: usize,
 6680        client: AnyProtoClient,
 6681    ) -> Result<()> {
 6682        let lsp_completion = {
 6683            let completion = &completions.borrow()[completion_index];
 6684            match &completion.source {
 6685                CompletionSource::Lsp {
 6686                    lsp_completion,
 6687                    resolved,
 6688                    server_id: completion_server_id,
 6689                    ..
 6690                } => {
 6691                    anyhow::ensure!(
 6692                        server_id == *completion_server_id,
 6693                        "remote server_id mismatch, querying completion resolve for {server_id} but completion server id is {completion_server_id}"
 6694                    );
 6695                    if *resolved {
 6696                        return Ok(());
 6697                    }
 6698                    serde_json::to_string(lsp_completion).unwrap().into_bytes()
 6699                }
 6700                CompletionSource::Custom
 6701                | CompletionSource::Dap { .. }
 6702                | CompletionSource::BufferWord { .. } => {
 6703                    return Ok(());
 6704                }
 6705            }
 6706        };
 6707        let request = proto::ResolveCompletionDocumentation {
 6708            project_id,
 6709            language_server_id: server_id.0 as u64,
 6710            lsp_completion,
 6711            buffer_id: buffer_id.into(),
 6712        };
 6713
 6714        let response = client
 6715            .request(request)
 6716            .await
 6717            .context("completion documentation resolve proto request")?;
 6718        let resolved_lsp_completion = serde_json::from_slice(&response.lsp_completion)?;
 6719
 6720        let documentation = if response.documentation.is_empty() {
 6721            CompletionDocumentation::Undocumented
 6722        } else if response.documentation_is_markdown {
 6723            CompletionDocumentation::MultiLineMarkdown(response.documentation.into())
 6724        } else if response.documentation.lines().count() <= 1 {
 6725            CompletionDocumentation::SingleLine(response.documentation.into())
 6726        } else {
 6727            CompletionDocumentation::MultiLinePlainText(response.documentation.into())
 6728        };
 6729
 6730        let mut completions = completions.borrow_mut();
 6731        let completion = &mut completions[completion_index];
 6732        completion.documentation = Some(documentation);
 6733        if let CompletionSource::Lsp {
 6734            insert_range,
 6735            lsp_completion,
 6736            resolved,
 6737            server_id: completion_server_id,
 6738            lsp_defaults: _,
 6739        } = &mut completion.source
 6740        {
 6741            let completion_insert_range = response
 6742                .old_insert_start
 6743                .and_then(deserialize_anchor)
 6744                .zip(response.old_insert_end.and_then(deserialize_anchor));
 6745            *insert_range = completion_insert_range.map(|(start, end)| start..end);
 6746
 6747            if *resolved {
 6748                return Ok(());
 6749            }
 6750            anyhow::ensure!(
 6751                server_id == *completion_server_id,
 6752                "remote server_id mismatch, applying completion resolve for {server_id} but completion server id is {completion_server_id}"
 6753            );
 6754            **lsp_completion = resolved_lsp_completion;
 6755            *resolved = true;
 6756        }
 6757
 6758        let replace_range = response
 6759            .old_replace_start
 6760            .and_then(deserialize_anchor)
 6761            .zip(response.old_replace_end.and_then(deserialize_anchor));
 6762        if let Some((old_replace_start, old_replace_end)) = replace_range
 6763            && !response.new_text.is_empty()
 6764        {
 6765            completion.new_text = response.new_text;
 6766            completion.replace_range = old_replace_start..old_replace_end;
 6767        }
 6768
 6769        Ok(())
 6770    }
 6771
 6772    pub fn apply_additional_edits_for_completion(
 6773        &self,
 6774        buffer_handle: Entity<Buffer>,
 6775        completions: Rc<RefCell<Box<[Completion]>>>,
 6776        completion_index: usize,
 6777        push_to_history: bool,
 6778        cx: &mut Context<Self>,
 6779    ) -> Task<Result<Option<Transaction>>> {
 6780        if let Some((client, project_id)) = self.upstream_client() {
 6781            let buffer = buffer_handle.read(cx);
 6782            let buffer_id = buffer.remote_id();
 6783            cx.spawn(async move |_, cx| {
 6784                let request = {
 6785                    let completion = completions.borrow()[completion_index].clone();
 6786                    proto::ApplyCompletionAdditionalEdits {
 6787                        project_id,
 6788                        buffer_id: buffer_id.into(),
 6789                        completion: Some(Self::serialize_completion(&CoreCompletion {
 6790                            replace_range: completion.replace_range,
 6791                            new_text: completion.new_text,
 6792                            source: completion.source,
 6793                        })),
 6794                    }
 6795                };
 6796
 6797                if let Some(transaction) = client.request(request).await?.transaction {
 6798                    let transaction = language::proto::deserialize_transaction(transaction)?;
 6799                    buffer_handle
 6800                        .update(cx, |buffer, _| {
 6801                            buffer.wait_for_edits(transaction.edit_ids.iter().copied())
 6802                        })
 6803                        .await?;
 6804                    if push_to_history {
 6805                        buffer_handle.update(cx, |buffer, _| {
 6806                            buffer.push_transaction(transaction.clone(), Instant::now());
 6807                            buffer.finalize_last_transaction();
 6808                        });
 6809                    }
 6810                    Ok(Some(transaction))
 6811                } else {
 6812                    Ok(None)
 6813                }
 6814            })
 6815        } else {
 6816            let Some(server) = buffer_handle.update(cx, |buffer, cx| {
 6817                let completion = &completions.borrow()[completion_index];
 6818                let server_id = completion.source.server_id()?;
 6819                Some(
 6820                    self.language_server_for_local_buffer(buffer, server_id, cx)?
 6821                        .1
 6822                        .clone(),
 6823                )
 6824            }) else {
 6825                return Task::ready(Ok(None));
 6826            };
 6827
 6828            cx.spawn(async move |this, cx| {
 6829                Self::resolve_completion_local(
 6830                    server.clone(),
 6831                    completions.clone(),
 6832                    completion_index,
 6833                )
 6834                .await
 6835                .context("resolving completion")?;
 6836                let completion = completions.borrow()[completion_index].clone();
 6837                let additional_text_edits = completion
 6838                    .source
 6839                    .lsp_completion(true)
 6840                    .as_ref()
 6841                    .and_then(|lsp_completion| lsp_completion.additional_text_edits.clone());
 6842                if let Some(edits) = additional_text_edits {
 6843                    let edits = this
 6844                        .update(cx, |this, cx| {
 6845                            this.as_local_mut().unwrap().edits_from_lsp(
 6846                                &buffer_handle,
 6847                                edits,
 6848                                server.server_id(),
 6849                                None,
 6850                                cx,
 6851                            )
 6852                        })?
 6853                        .await?;
 6854
 6855                    buffer_handle.update(cx, |buffer, cx| {
 6856                        buffer.finalize_last_transaction();
 6857                        buffer.start_transaction();
 6858
 6859                        for (range, text) in edits {
 6860                            let primary = &completion.replace_range;
 6861
 6862                            // Special case: if both ranges start at the very beginning of the file (line 0, column 0),
 6863                            // and the primary completion is just an insertion (empty range), then this is likely
 6864                            // an auto-import scenario and should not be considered overlapping
 6865                            // https://github.com/zed-industries/zed/issues/26136
 6866                            let is_file_start_auto_import = {
 6867                                let snapshot = buffer.snapshot();
 6868                                let primary_start_point = primary.start.to_point(&snapshot);
 6869                                let range_start_point = range.start.to_point(&snapshot);
 6870
 6871                                let result = primary_start_point.row == 0
 6872                                    && primary_start_point.column == 0
 6873                                    && range_start_point.row == 0
 6874                                    && range_start_point.column == 0;
 6875
 6876                                result
 6877                            };
 6878
 6879                            let has_overlap = if is_file_start_auto_import {
 6880                                false
 6881                            } else {
 6882                                let start_within = primary.start.cmp(&range.start, buffer).is_le()
 6883                                    && primary.end.cmp(&range.start, buffer).is_ge();
 6884                                let end_within = range.start.cmp(&primary.end, buffer).is_le()
 6885                                    && range.end.cmp(&primary.end, buffer).is_ge();
 6886                                let result = start_within || end_within;
 6887                                result
 6888                            };
 6889
 6890                            //Skip additional edits which overlap with the primary completion edit
 6891                            //https://github.com/zed-industries/zed/pull/1871
 6892                            if !has_overlap {
 6893                                buffer.edit([(range, text)], None, cx);
 6894                            }
 6895                        }
 6896
 6897                        let transaction = if buffer.end_transaction(cx).is_some() {
 6898                            let transaction = buffer.finalize_last_transaction().unwrap().clone();
 6899                            if !push_to_history {
 6900                                buffer.forget_transaction(transaction.id);
 6901                            }
 6902                            Some(transaction)
 6903                        } else {
 6904                            None
 6905                        };
 6906                        Ok(transaction)
 6907                    })
 6908                } else {
 6909                    Ok(None)
 6910                }
 6911            })
 6912        }
 6913    }
 6914
 6915    pub fn pull_diagnostics(
 6916        &mut self,
 6917        buffer: Entity<Buffer>,
 6918        cx: &mut Context<Self>,
 6919    ) -> Task<Result<Option<Vec<LspPullDiagnostics>>>> {
 6920        let buffer_id = buffer.read(cx).remote_id();
 6921
 6922        if let Some((client, upstream_project_id)) = self.upstream_client() {
 6923            let mut suitable_capabilities = None;
 6924            // Are we capable for proto request?
 6925            let any_server_has_diagnostics_provider = self.check_if_capable_for_proto_request(
 6926                &buffer,
 6927                |capabilities| {
 6928                    if let Some(caps) = &capabilities.diagnostic_provider {
 6929                        suitable_capabilities = Some(caps.clone());
 6930                        true
 6931                    } else {
 6932                        false
 6933                    }
 6934                },
 6935                cx,
 6936            );
 6937            // We don't really care which caps are passed into the request, as they're ignored by RPC anyways.
 6938            let Some(dynamic_caps) = suitable_capabilities else {
 6939                return Task::ready(Ok(None));
 6940            };
 6941            assert!(any_server_has_diagnostics_provider);
 6942
 6943            let identifier = buffer_diagnostic_identifier(&dynamic_caps);
 6944            let request = GetDocumentDiagnostics {
 6945                previous_result_id: None,
 6946                identifier,
 6947                registration_id: None,
 6948            };
 6949            let request_task = client.request_lsp(
 6950                upstream_project_id,
 6951                None,
 6952                LSP_REQUEST_TIMEOUT,
 6953                cx.background_executor().clone(),
 6954                request.to_proto(upstream_project_id, buffer.read(cx)),
 6955            );
 6956            cx.background_spawn(async move {
 6957                // Proto requests cause the diagnostics to be pulled from language server(s) on the local side
 6958                // and then, buffer state updated with the diagnostics received, which will be later propagated to the client.
 6959                // Do not attempt to further process the dummy responses here.
 6960                let _response = request_task.await?;
 6961                Ok(None)
 6962            })
 6963        } else {
 6964            let servers = buffer.update(cx, |buffer, cx| {
 6965                self.running_language_servers_for_local_buffer(buffer, cx)
 6966                    .map(|(_, server)| server.clone())
 6967                    .collect::<Vec<_>>()
 6968            });
 6969
 6970            let pull_diagnostics = servers
 6971                .into_iter()
 6972                .flat_map(|server| {
 6973                    let result = maybe!({
 6974                        let local = self.as_local()?;
 6975                        let server_id = server.server_id();
 6976                        let providers_with_identifiers = local
 6977                            .language_server_dynamic_registrations
 6978                            .get(&server_id)
 6979                            .into_iter()
 6980                            .flat_map(|registrations| registrations.diagnostics.clone())
 6981                            .collect::<Vec<_>>();
 6982                        Some(
 6983                            providers_with_identifiers
 6984                                .into_iter()
 6985                                .map(|(registration_id, dynamic_caps)| {
 6986                                    let identifier = buffer_diagnostic_identifier(&dynamic_caps);
 6987                                    let registration_id = registration_id.map(SharedString::from);
 6988                                    let result_id = self.result_id_for_buffer_pull(
 6989                                        server_id,
 6990                                        buffer_id,
 6991                                        &registration_id,
 6992                                        cx,
 6993                                    );
 6994                                    self.request_lsp(
 6995                                        buffer.clone(),
 6996                                        LanguageServerToQuery::Other(server_id),
 6997                                        GetDocumentDiagnostics {
 6998                                            previous_result_id: result_id,
 6999                                            registration_id,
 7000                                            identifier,
 7001                                        },
 7002                                        cx,
 7003                                    )
 7004                                })
 7005                                .collect::<Vec<_>>(),
 7006                        )
 7007                    });
 7008
 7009                    result.unwrap_or_default()
 7010                })
 7011                .collect::<Vec<_>>();
 7012
 7013            cx.background_spawn(async move {
 7014                let mut responses = Vec::new();
 7015                for diagnostics in join_all(pull_diagnostics).await {
 7016                    responses.extend(diagnostics?);
 7017                }
 7018                Ok(Some(responses))
 7019            })
 7020        }
 7021    }
 7022
 7023    pub fn applicable_inlay_chunks(
 7024        &mut self,
 7025        buffer: &Entity<Buffer>,
 7026        ranges: &[Range<text::Anchor>],
 7027        cx: &mut Context<Self>,
 7028    ) -> Vec<Range<BufferRow>> {
 7029        let buffer_snapshot = buffer.read(cx).snapshot();
 7030        let ranges = ranges
 7031            .iter()
 7032            .map(|range| range.to_point(&buffer_snapshot))
 7033            .collect::<Vec<_>>();
 7034
 7035        self.latest_lsp_data(buffer, cx)
 7036            .inlay_hints
 7037            .applicable_chunks(ranges.as_slice())
 7038            .map(|chunk| chunk.row_range())
 7039            .collect()
 7040    }
 7041
 7042    pub fn invalidate_inlay_hints<'a>(
 7043        &'a mut self,
 7044        for_buffers: impl IntoIterator<Item = &'a BufferId> + 'a,
 7045    ) {
 7046        for buffer_id in for_buffers {
 7047            if let Some(lsp_data) = self.lsp_data.get_mut(buffer_id) {
 7048                lsp_data.inlay_hints.clear();
 7049            }
 7050        }
 7051    }
 7052
 7053    pub fn inlay_hints(
 7054        &mut self,
 7055        invalidate: InvalidationStrategy,
 7056        buffer: Entity<Buffer>,
 7057        ranges: Vec<Range<text::Anchor>>,
 7058        known_chunks: Option<(clock::Global, HashSet<Range<BufferRow>>)>,
 7059        cx: &mut Context<Self>,
 7060    ) -> HashMap<Range<BufferRow>, Task<Result<CacheInlayHints>>> {
 7061        let next_hint_id = self.next_hint_id.clone();
 7062        let lsp_data = self.latest_lsp_data(&buffer, cx);
 7063        let query_version = lsp_data.buffer_version.clone();
 7064        let mut lsp_refresh_requested = false;
 7065        let for_server = if let InvalidationStrategy::RefreshRequested {
 7066            server_id,
 7067            request_id,
 7068        } = invalidate
 7069        {
 7070            let invalidated = lsp_data
 7071                .inlay_hints
 7072                .invalidate_for_server_refresh(server_id, request_id);
 7073            lsp_refresh_requested = invalidated;
 7074            Some(server_id)
 7075        } else {
 7076            None
 7077        };
 7078        let existing_inlay_hints = &mut lsp_data.inlay_hints;
 7079        let known_chunks = known_chunks
 7080            .filter(|(known_version, _)| !lsp_data.buffer_version.changed_since(known_version))
 7081            .map(|(_, known_chunks)| known_chunks)
 7082            .unwrap_or_default();
 7083
 7084        let buffer_snapshot = buffer.read(cx).snapshot();
 7085        let ranges = ranges
 7086            .iter()
 7087            .map(|range| range.to_point(&buffer_snapshot))
 7088            .collect::<Vec<_>>();
 7089
 7090        let mut hint_fetch_tasks = Vec::new();
 7091        let mut cached_inlay_hints = None;
 7092        let mut ranges_to_query = None;
 7093        let applicable_chunks = existing_inlay_hints
 7094            .applicable_chunks(ranges.as_slice())
 7095            .filter(|chunk| !known_chunks.contains(&chunk.row_range()))
 7096            .collect::<Vec<_>>();
 7097        if applicable_chunks.is_empty() {
 7098            return HashMap::default();
 7099        }
 7100
 7101        for row_chunk in applicable_chunks {
 7102            match (
 7103                existing_inlay_hints
 7104                    .cached_hints(&row_chunk)
 7105                    .filter(|_| !lsp_refresh_requested)
 7106                    .cloned(),
 7107                existing_inlay_hints
 7108                    .fetched_hints(&row_chunk)
 7109                    .as_ref()
 7110                    .filter(|_| !lsp_refresh_requested)
 7111                    .cloned(),
 7112            ) {
 7113                (None, None) => {
 7114                    let chunk_range = row_chunk.anchor_range();
 7115                    ranges_to_query
 7116                        .get_or_insert_with(Vec::new)
 7117                        .push((row_chunk, chunk_range));
 7118                }
 7119                (None, Some(fetched_hints)) => hint_fetch_tasks.push((row_chunk, fetched_hints)),
 7120                (Some(cached_hints), None) => {
 7121                    for (server_id, cached_hints) in cached_hints {
 7122                        if for_server.is_none_or(|for_server| for_server == server_id) {
 7123                            cached_inlay_hints
 7124                                .get_or_insert_with(HashMap::default)
 7125                                .entry(row_chunk.row_range())
 7126                                .or_insert_with(HashMap::default)
 7127                                .entry(server_id)
 7128                                .or_insert_with(Vec::new)
 7129                                .extend(cached_hints);
 7130                        }
 7131                    }
 7132                }
 7133                (Some(cached_hints), Some(fetched_hints)) => {
 7134                    hint_fetch_tasks.push((row_chunk, fetched_hints));
 7135                    for (server_id, cached_hints) in cached_hints {
 7136                        if for_server.is_none_or(|for_server| for_server == server_id) {
 7137                            cached_inlay_hints
 7138                                .get_or_insert_with(HashMap::default)
 7139                                .entry(row_chunk.row_range())
 7140                                .or_insert_with(HashMap::default)
 7141                                .entry(server_id)
 7142                                .or_insert_with(Vec::new)
 7143                                .extend(cached_hints);
 7144                        }
 7145                    }
 7146                }
 7147            }
 7148        }
 7149
 7150        if hint_fetch_tasks.is_empty()
 7151            && ranges_to_query
 7152                .as_ref()
 7153                .is_none_or(|ranges| ranges.is_empty())
 7154            && let Some(cached_inlay_hints) = cached_inlay_hints
 7155        {
 7156            cached_inlay_hints
 7157                .into_iter()
 7158                .map(|(row_chunk, hints)| (row_chunk, Task::ready(Ok(hints))))
 7159                .collect()
 7160        } else {
 7161            for (chunk, range_to_query) in ranges_to_query.into_iter().flatten() {
 7162                let next_hint_id = next_hint_id.clone();
 7163                let buffer = buffer.clone();
 7164                let query_version = query_version.clone();
 7165                let new_inlay_hints = cx
 7166                    .spawn(async move |lsp_store, cx| {
 7167                        let new_fetch_task = lsp_store.update(cx, |lsp_store, cx| {
 7168                            lsp_store.fetch_inlay_hints(for_server, &buffer, range_to_query, cx)
 7169                        })?;
 7170                        new_fetch_task
 7171                            .await
 7172                            .and_then(|new_hints_by_server| {
 7173                                lsp_store.update(cx, |lsp_store, cx| {
 7174                                    let lsp_data = lsp_store.latest_lsp_data(&buffer, cx);
 7175                                    let update_cache = lsp_data.buffer_version == query_version;
 7176                                    if new_hints_by_server.is_empty() {
 7177                                        if update_cache {
 7178                                            lsp_data.inlay_hints.invalidate_for_chunk(chunk);
 7179                                        }
 7180                                        HashMap::default()
 7181                                    } else {
 7182                                        new_hints_by_server
 7183                                            .into_iter()
 7184                                            .map(|(server_id, new_hints)| {
 7185                                                let new_hints = new_hints
 7186                                                    .into_iter()
 7187                                                    .map(|new_hint| {
 7188                                                        (
 7189                                                            InlayId::Hint(next_hint_id.fetch_add(
 7190                                                                1,
 7191                                                                atomic::Ordering::AcqRel,
 7192                                                            )),
 7193                                                            new_hint,
 7194                                                        )
 7195                                                    })
 7196                                                    .collect::<Vec<_>>();
 7197                                                if update_cache {
 7198                                                    lsp_data.inlay_hints.insert_new_hints(
 7199                                                        chunk,
 7200                                                        server_id,
 7201                                                        new_hints.clone(),
 7202                                                    );
 7203                                                }
 7204                                                (server_id, new_hints)
 7205                                            })
 7206                                            .collect()
 7207                                    }
 7208                                })
 7209                            })
 7210                            .map_err(Arc::new)
 7211                    })
 7212                    .shared();
 7213
 7214                let fetch_task = lsp_data.inlay_hints.fetched_hints(&chunk);
 7215                *fetch_task = Some(new_inlay_hints.clone());
 7216                hint_fetch_tasks.push((chunk, new_inlay_hints));
 7217            }
 7218
 7219            cached_inlay_hints
 7220                .unwrap_or_default()
 7221                .into_iter()
 7222                .map(|(row_chunk, hints)| (row_chunk, Task::ready(Ok(hints))))
 7223                .chain(hint_fetch_tasks.into_iter().map(|(chunk, hints_fetch)| {
 7224                    (
 7225                        chunk.row_range(),
 7226                        cx.spawn(async move |_, _| {
 7227                            hints_fetch.await.map_err(|e| {
 7228                                if e.error_code() != ErrorCode::Internal {
 7229                                    anyhow!(e.error_code())
 7230                                } else {
 7231                                    anyhow!("{e:#}")
 7232                                }
 7233                            })
 7234                        }),
 7235                    )
 7236                }))
 7237                .collect()
 7238        }
 7239    }
 7240
 7241    fn fetch_inlay_hints(
 7242        &mut self,
 7243        for_server: Option<LanguageServerId>,
 7244        buffer: &Entity<Buffer>,
 7245        range: Range<Anchor>,
 7246        cx: &mut Context<Self>,
 7247    ) -> Task<Result<HashMap<LanguageServerId, Vec<InlayHint>>>> {
 7248        let request = InlayHints {
 7249            range: range.clone(),
 7250        };
 7251        if let Some((upstream_client, project_id)) = self.upstream_client() {
 7252            if !self.is_capable_for_proto_request(buffer, &request, cx) {
 7253                return Task::ready(Ok(HashMap::default()));
 7254            }
 7255            let request_task = upstream_client.request_lsp(
 7256                project_id,
 7257                for_server.map(|id| id.to_proto()),
 7258                LSP_REQUEST_TIMEOUT,
 7259                cx.background_executor().clone(),
 7260                request.to_proto(project_id, buffer.read(cx)),
 7261            );
 7262            let buffer = buffer.clone();
 7263            cx.spawn(async move |weak_lsp_store, cx| {
 7264                let Some(lsp_store) = weak_lsp_store.upgrade() else {
 7265                    return Ok(HashMap::default());
 7266                };
 7267                let Some(responses) = request_task.await? else {
 7268                    return Ok(HashMap::default());
 7269                };
 7270
 7271                let inlay_hints = join_all(responses.payload.into_iter().map(|response| {
 7272                    let lsp_store = lsp_store.clone();
 7273                    let buffer = buffer.clone();
 7274                    let cx = cx.clone();
 7275                    let request = request.clone();
 7276                    async move {
 7277                        (
 7278                            LanguageServerId::from_proto(response.server_id),
 7279                            request
 7280                                .response_from_proto(response.response, lsp_store, buffer, cx)
 7281                                .await,
 7282                        )
 7283                    }
 7284                }))
 7285                .await;
 7286
 7287                let buffer_snapshot = buffer.read_with(cx, |buffer, _| buffer.snapshot());
 7288                let mut has_errors = false;
 7289                let inlay_hints = inlay_hints
 7290                    .into_iter()
 7291                    .filter_map(|(server_id, inlay_hints)| match inlay_hints {
 7292                        Ok(inlay_hints) => Some((server_id, inlay_hints)),
 7293                        Err(e) => {
 7294                            has_errors = true;
 7295                            log::error!("{e:#}");
 7296                            None
 7297                        }
 7298                    })
 7299                    .map(|(server_id, mut new_hints)| {
 7300                        new_hints.retain(|hint| {
 7301                            hint.position.is_valid(&buffer_snapshot)
 7302                                && range.start.is_valid(&buffer_snapshot)
 7303                                && range.end.is_valid(&buffer_snapshot)
 7304                                && hint.position.cmp(&range.start, &buffer_snapshot).is_ge()
 7305                                && hint.position.cmp(&range.end, &buffer_snapshot).is_lt()
 7306                        });
 7307                        (server_id, new_hints)
 7308                    })
 7309                    .collect::<HashMap<_, _>>();
 7310                anyhow::ensure!(
 7311                    !has_errors || !inlay_hints.is_empty(),
 7312                    "Failed to fetch inlay hints"
 7313                );
 7314                Ok(inlay_hints)
 7315            })
 7316        } else {
 7317            let inlay_hints_task = match for_server {
 7318                Some(server_id) => {
 7319                    let server_task = self.request_lsp(
 7320                        buffer.clone(),
 7321                        LanguageServerToQuery::Other(server_id),
 7322                        request,
 7323                        cx,
 7324                    );
 7325                    cx.background_spawn(async move {
 7326                        let mut responses = Vec::new();
 7327                        match server_task.await {
 7328                            Ok(response) => responses.push((server_id, response)),
 7329                            // rust-analyzer likes to error with this when its still loading up
 7330                            Err(e) if format!("{e:#}").ends_with("content modified") => (),
 7331                            Err(e) => log::error!(
 7332                                "Error handling response for inlay hints request: {e:#}"
 7333                            ),
 7334                        }
 7335                        responses
 7336                    })
 7337                }
 7338                None => self.request_multiple_lsp_locally(buffer, None::<usize>, request, cx),
 7339            };
 7340            let buffer_snapshot = buffer.read_with(cx, |buffer, _| buffer.snapshot());
 7341            cx.background_spawn(async move {
 7342                Ok(inlay_hints_task
 7343                    .await
 7344                    .into_iter()
 7345                    .map(|(server_id, mut new_hints)| {
 7346                        new_hints.retain(|hint| {
 7347                            hint.position.is_valid(&buffer_snapshot)
 7348                                && range.start.is_valid(&buffer_snapshot)
 7349                                && range.end.is_valid(&buffer_snapshot)
 7350                                && hint.position.cmp(&range.start, &buffer_snapshot).is_ge()
 7351                                && hint.position.cmp(&range.end, &buffer_snapshot).is_lt()
 7352                        });
 7353                        (server_id, new_hints)
 7354                    })
 7355                    .collect())
 7356            })
 7357        }
 7358    }
 7359
 7360    fn diagnostic_registration_exists(
 7361        &self,
 7362        server_id: LanguageServerId,
 7363        registration_id: &Option<SharedString>,
 7364    ) -> bool {
 7365        let Some(local) = self.as_local() else {
 7366            return false;
 7367        };
 7368        let Some(registrations) = local.language_server_dynamic_registrations.get(&server_id)
 7369        else {
 7370            return false;
 7371        };
 7372        let registration_key = registration_id.as_ref().map(|s| s.to_string());
 7373        registrations.diagnostics.contains_key(&registration_key)
 7374    }
 7375
 7376    pub fn pull_diagnostics_for_buffer(
 7377        &mut self,
 7378        buffer: Entity<Buffer>,
 7379        cx: &mut Context<Self>,
 7380    ) -> Task<anyhow::Result<()>> {
 7381        let diagnostics = self.pull_diagnostics(buffer, cx);
 7382        cx.spawn(async move |lsp_store, cx| {
 7383            let Some(diagnostics) = diagnostics.await.context("pulling diagnostics")? else {
 7384                return Ok(());
 7385            };
 7386            lsp_store.update(cx, |lsp_store, cx| {
 7387                if lsp_store.as_local().is_none() {
 7388                    return;
 7389                }
 7390
 7391                let mut unchanged_buffers = HashMap::default();
 7392                let server_diagnostics_updates = diagnostics
 7393                    .into_iter()
 7394                    .filter_map(|diagnostics_set| match diagnostics_set {
 7395                        LspPullDiagnostics::Response {
 7396                            server_id,
 7397                            uri,
 7398                            diagnostics,
 7399                            registration_id,
 7400                        } => Some((server_id, uri, diagnostics, registration_id)),
 7401                        LspPullDiagnostics::Default => None,
 7402                    })
 7403                    .filter(|(server_id, _, _, registration_id)| {
 7404                        lsp_store.diagnostic_registration_exists(*server_id, registration_id)
 7405                    })
 7406                    .fold(
 7407                        HashMap::default(),
 7408                        |mut acc, (server_id, uri, diagnostics, new_registration_id)| {
 7409                            let (result_id, diagnostics) = match diagnostics {
 7410                                PulledDiagnostics::Unchanged { result_id } => {
 7411                                    unchanged_buffers
 7412                                        .entry(new_registration_id.clone())
 7413                                        .or_insert_with(HashSet::default)
 7414                                        .insert(uri.clone());
 7415                                    (Some(result_id), Vec::new())
 7416                                }
 7417                                PulledDiagnostics::Changed {
 7418                                    result_id,
 7419                                    diagnostics,
 7420                                } => (result_id, diagnostics),
 7421                            };
 7422                            let disk_based_sources = Cow::Owned(
 7423                                lsp_store
 7424                                    .language_server_adapter_for_id(server_id)
 7425                                    .as_ref()
 7426                                    .map(|adapter| adapter.disk_based_diagnostic_sources.as_slice())
 7427                                    .unwrap_or(&[])
 7428                                    .to_vec(),
 7429                            );
 7430                            acc.entry(server_id)
 7431                                .or_insert_with(HashMap::default)
 7432                                .entry(new_registration_id.clone())
 7433                                .or_insert_with(Vec::new)
 7434                                .push(DocumentDiagnosticsUpdate {
 7435                                    server_id,
 7436                                    diagnostics: lsp::PublishDiagnosticsParams {
 7437                                        uri,
 7438                                        diagnostics,
 7439                                        version: None,
 7440                                    },
 7441                                    result_id,
 7442                                    disk_based_sources,
 7443                                    registration_id: new_registration_id,
 7444                                });
 7445                            acc
 7446                        },
 7447                    );
 7448
 7449                for diagnostic_updates in server_diagnostics_updates.into_values() {
 7450                    for (registration_id, diagnostic_updates) in diagnostic_updates {
 7451                        lsp_store
 7452                            .merge_lsp_diagnostics(
 7453                                DiagnosticSourceKind::Pulled,
 7454                                diagnostic_updates,
 7455                                |document_uri, old_diagnostic, _| match old_diagnostic.source_kind {
 7456                                    DiagnosticSourceKind::Pulled => {
 7457                                        old_diagnostic.registration_id != registration_id
 7458                                            || unchanged_buffers
 7459                                                .get(&old_diagnostic.registration_id)
 7460                                                .is_some_and(|unchanged_buffers| {
 7461                                                    unchanged_buffers.contains(&document_uri)
 7462                                                })
 7463                                    }
 7464                                    DiagnosticSourceKind::Other | DiagnosticSourceKind::Pushed => {
 7465                                        true
 7466                                    }
 7467                                },
 7468                                cx,
 7469                            )
 7470                            .log_err();
 7471                    }
 7472                }
 7473            })
 7474        })
 7475    }
 7476
 7477    pub fn document_colors(
 7478        &mut self,
 7479        known_cache_version: Option<usize>,
 7480        buffer: Entity<Buffer>,
 7481        cx: &mut Context<Self>,
 7482    ) -> Option<DocumentColorTask> {
 7483        let version_queried_for = buffer.read(cx).version();
 7484        let buffer_id = buffer.read(cx).remote_id();
 7485
 7486        let current_language_servers = self.as_local().map(|local| {
 7487            local
 7488                .buffers_opened_in_servers
 7489                .get(&buffer_id)
 7490                .cloned()
 7491                .unwrap_or_default()
 7492        });
 7493
 7494        if let Some(lsp_data) = self.current_lsp_data(buffer_id) {
 7495            if let Some(cached_colors) = &lsp_data.document_colors {
 7496                if !version_queried_for.changed_since(&lsp_data.buffer_version) {
 7497                    let has_different_servers =
 7498                        current_language_servers.is_some_and(|current_language_servers| {
 7499                            current_language_servers
 7500                                != cached_colors.colors.keys().copied().collect()
 7501                        });
 7502                    if !has_different_servers {
 7503                        let cache_version = cached_colors.cache_version;
 7504                        if Some(cache_version) == known_cache_version {
 7505                            return None;
 7506                        } else {
 7507                            return Some(
 7508                                Task::ready(Ok(DocumentColors {
 7509                                    colors: cached_colors
 7510                                        .colors
 7511                                        .values()
 7512                                        .flatten()
 7513                                        .cloned()
 7514                                        .collect(),
 7515                                    cache_version: Some(cache_version),
 7516                                }))
 7517                                .shared(),
 7518                            );
 7519                        }
 7520                    }
 7521                }
 7522            }
 7523        }
 7524
 7525        let color_lsp_data = self
 7526            .latest_lsp_data(&buffer, cx)
 7527            .document_colors
 7528            .get_or_insert_default();
 7529        if let Some((updating_for, running_update)) = &color_lsp_data.colors_update
 7530            && !version_queried_for.changed_since(updating_for)
 7531        {
 7532            return Some(running_update.clone());
 7533        }
 7534        let buffer_version_queried_for = version_queried_for.clone();
 7535        let new_task = cx
 7536            .spawn(async move |lsp_store, cx| {
 7537                cx.background_executor()
 7538                    .timer(Duration::from_millis(30))
 7539                    .await;
 7540                let fetched_colors = lsp_store
 7541                    .update(cx, |lsp_store, cx| {
 7542                        lsp_store.fetch_document_colors_for_buffer(&buffer, cx)
 7543                    })?
 7544                    .await
 7545                    .context("fetching document colors")
 7546                    .map_err(Arc::new);
 7547                let fetched_colors = match fetched_colors {
 7548                    Ok(fetched_colors) => {
 7549                        if buffer.update(cx, |buffer, _| {
 7550                            buffer.version() != buffer_version_queried_for
 7551                        }) {
 7552                            return Ok(DocumentColors::default());
 7553                        }
 7554                        fetched_colors
 7555                    }
 7556                    Err(e) => {
 7557                        lsp_store
 7558                            .update(cx, |lsp_store, _| {
 7559                                if let Some(lsp_data) = lsp_store.lsp_data.get_mut(&buffer_id) {
 7560                                    if let Some(document_colors) = &mut lsp_data.document_colors {
 7561                                        document_colors.colors_update = None;
 7562                                    }
 7563                                }
 7564                            })
 7565                            .ok();
 7566                        return Err(e);
 7567                    }
 7568                };
 7569
 7570                lsp_store
 7571                    .update(cx, |lsp_store, cx| {
 7572                        let lsp_data = lsp_store.latest_lsp_data(&buffer, cx);
 7573                        let lsp_colors = lsp_data.document_colors.get_or_insert_default();
 7574
 7575                        if let Some(fetched_colors) = fetched_colors {
 7576                            if lsp_data.buffer_version == buffer_version_queried_for {
 7577                                lsp_colors.colors.extend(fetched_colors);
 7578                                lsp_colors.cache_version += 1;
 7579                            } else if !lsp_data
 7580                                .buffer_version
 7581                                .changed_since(&buffer_version_queried_for)
 7582                            {
 7583                                lsp_data.buffer_version = buffer_version_queried_for;
 7584                                lsp_colors.colors = fetched_colors;
 7585                                lsp_colors.cache_version += 1;
 7586                            }
 7587                        }
 7588                        lsp_colors.colors_update = None;
 7589                        let colors = lsp_colors
 7590                            .colors
 7591                            .values()
 7592                            .flatten()
 7593                            .cloned()
 7594                            .collect::<HashSet<_>>();
 7595                        DocumentColors {
 7596                            colors,
 7597                            cache_version: Some(lsp_colors.cache_version),
 7598                        }
 7599                    })
 7600                    .map_err(Arc::new)
 7601            })
 7602            .shared();
 7603        color_lsp_data.colors_update = Some((version_queried_for, new_task.clone()));
 7604        Some(new_task)
 7605    }
 7606
 7607    fn fetch_document_colors_for_buffer(
 7608        &mut self,
 7609        buffer: &Entity<Buffer>,
 7610        cx: &mut Context<Self>,
 7611    ) -> Task<anyhow::Result<Option<HashMap<LanguageServerId, HashSet<DocumentColor>>>>> {
 7612        if let Some((client, project_id)) = self.upstream_client() {
 7613            let request = GetDocumentColor {};
 7614            if !self.is_capable_for_proto_request(buffer, &request, cx) {
 7615                return Task::ready(Ok(None));
 7616            }
 7617
 7618            let request_task = client.request_lsp(
 7619                project_id,
 7620                None,
 7621                LSP_REQUEST_TIMEOUT,
 7622                cx.background_executor().clone(),
 7623                request.to_proto(project_id, buffer.read(cx)),
 7624            );
 7625            let buffer = buffer.clone();
 7626            cx.spawn(async move |lsp_store, cx| {
 7627                let Some(lsp_store) = lsp_store.upgrade() else {
 7628                    return Ok(None);
 7629                };
 7630                let colors = join_all(
 7631                    request_task
 7632                        .await
 7633                        .log_err()
 7634                        .flatten()
 7635                        .map(|response| response.payload)
 7636                        .unwrap_or_default()
 7637                        .into_iter()
 7638                        .map(|color_response| {
 7639                            let response = request.response_from_proto(
 7640                                color_response.response,
 7641                                lsp_store.clone(),
 7642                                buffer.clone(),
 7643                                cx.clone(),
 7644                            );
 7645                            async move {
 7646                                (
 7647                                    LanguageServerId::from_proto(color_response.server_id),
 7648                                    response.await.log_err().unwrap_or_default(),
 7649                                )
 7650                            }
 7651                        }),
 7652                )
 7653                .await
 7654                .into_iter()
 7655                .fold(HashMap::default(), |mut acc, (server_id, colors)| {
 7656                    acc.entry(server_id)
 7657                        .or_insert_with(HashSet::default)
 7658                        .extend(colors);
 7659                    acc
 7660                });
 7661                Ok(Some(colors))
 7662            })
 7663        } else {
 7664            let document_colors_task =
 7665                self.request_multiple_lsp_locally(buffer, None::<usize>, GetDocumentColor, cx);
 7666            cx.background_spawn(async move {
 7667                Ok(Some(
 7668                    document_colors_task
 7669                        .await
 7670                        .into_iter()
 7671                        .fold(HashMap::default(), |mut acc, (server_id, colors)| {
 7672                            acc.entry(server_id)
 7673                                .or_insert_with(HashSet::default)
 7674                                .extend(colors);
 7675                            acc
 7676                        })
 7677                        .into_iter()
 7678                        .collect(),
 7679                ))
 7680            })
 7681        }
 7682    }
 7683
 7684    pub fn signature_help<T: ToPointUtf16>(
 7685        &mut self,
 7686        buffer: &Entity<Buffer>,
 7687        position: T,
 7688        cx: &mut Context<Self>,
 7689    ) -> Task<Option<Vec<SignatureHelp>>> {
 7690        let position = position.to_point_utf16(buffer.read(cx));
 7691
 7692        if let Some((client, upstream_project_id)) = self.upstream_client() {
 7693            let request = GetSignatureHelp { position };
 7694            if !self.is_capable_for_proto_request(buffer, &request, cx) {
 7695                return Task::ready(None);
 7696            }
 7697            let request_task = client.request_lsp(
 7698                upstream_project_id,
 7699                None,
 7700                LSP_REQUEST_TIMEOUT,
 7701                cx.background_executor().clone(),
 7702                request.to_proto(upstream_project_id, buffer.read(cx)),
 7703            );
 7704            let buffer = buffer.clone();
 7705            cx.spawn(async move |weak_lsp_store, cx| {
 7706                let lsp_store = weak_lsp_store.upgrade()?;
 7707                let signatures = join_all(
 7708                    request_task
 7709                        .await
 7710                        .log_err()
 7711                        .flatten()
 7712                        .map(|response| response.payload)
 7713                        .unwrap_or_default()
 7714                        .into_iter()
 7715                        .map(|response| {
 7716                            let response = GetSignatureHelp { position }.response_from_proto(
 7717                                response.response,
 7718                                lsp_store.clone(),
 7719                                buffer.clone(),
 7720                                cx.clone(),
 7721                            );
 7722                            async move { response.await.log_err().flatten() }
 7723                        }),
 7724                )
 7725                .await
 7726                .into_iter()
 7727                .flatten()
 7728                .collect();
 7729                Some(signatures)
 7730            })
 7731        } else {
 7732            let all_actions_task = self.request_multiple_lsp_locally(
 7733                buffer,
 7734                Some(position),
 7735                GetSignatureHelp { position },
 7736                cx,
 7737            );
 7738            cx.background_spawn(async move {
 7739                Some(
 7740                    all_actions_task
 7741                        .await
 7742                        .into_iter()
 7743                        .flat_map(|(_, actions)| actions)
 7744                        .collect::<Vec<_>>(),
 7745                )
 7746            })
 7747        }
 7748    }
 7749
 7750    pub fn hover(
 7751        &mut self,
 7752        buffer: &Entity<Buffer>,
 7753        position: PointUtf16,
 7754        cx: &mut Context<Self>,
 7755    ) -> Task<Option<Vec<Hover>>> {
 7756        if let Some((client, upstream_project_id)) = self.upstream_client() {
 7757            let request = GetHover { position };
 7758            if !self.is_capable_for_proto_request(buffer, &request, cx) {
 7759                return Task::ready(None);
 7760            }
 7761            let request_task = client.request_lsp(
 7762                upstream_project_id,
 7763                None,
 7764                LSP_REQUEST_TIMEOUT,
 7765                cx.background_executor().clone(),
 7766                request.to_proto(upstream_project_id, buffer.read(cx)),
 7767            );
 7768            let buffer = buffer.clone();
 7769            cx.spawn(async move |weak_lsp_store, cx| {
 7770                let lsp_store = weak_lsp_store.upgrade()?;
 7771                let hovers = join_all(
 7772                    request_task
 7773                        .await
 7774                        .log_err()
 7775                        .flatten()
 7776                        .map(|response| response.payload)
 7777                        .unwrap_or_default()
 7778                        .into_iter()
 7779                        .map(|response| {
 7780                            let response = GetHover { position }.response_from_proto(
 7781                                response.response,
 7782                                lsp_store.clone(),
 7783                                buffer.clone(),
 7784                                cx.clone(),
 7785                            );
 7786                            async move {
 7787                                response
 7788                                    .await
 7789                                    .log_err()
 7790                                    .flatten()
 7791                                    .and_then(remove_empty_hover_blocks)
 7792                            }
 7793                        }),
 7794                )
 7795                .await
 7796                .into_iter()
 7797                .flatten()
 7798                .collect();
 7799                Some(hovers)
 7800            })
 7801        } else {
 7802            let all_actions_task = self.request_multiple_lsp_locally(
 7803                buffer,
 7804                Some(position),
 7805                GetHover { position },
 7806                cx,
 7807            );
 7808            cx.background_spawn(async move {
 7809                Some(
 7810                    all_actions_task
 7811                        .await
 7812                        .into_iter()
 7813                        .filter_map(|(_, hover)| remove_empty_hover_blocks(hover?))
 7814                        .collect::<Vec<Hover>>(),
 7815                )
 7816            })
 7817        }
 7818    }
 7819
 7820    pub fn symbols(&self, query: &str, cx: &mut Context<Self>) -> Task<Result<Vec<Symbol>>> {
 7821        let language_registry = self.languages.clone();
 7822
 7823        if let Some((upstream_client, project_id)) = self.upstream_client().as_ref() {
 7824            let request = upstream_client.request(proto::GetProjectSymbols {
 7825                project_id: *project_id,
 7826                query: query.to_string(),
 7827            });
 7828            cx.foreground_executor().spawn(async move {
 7829                let response = request.await?;
 7830                let mut symbols = Vec::new();
 7831                let core_symbols = response
 7832                    .symbols
 7833                    .into_iter()
 7834                    .filter_map(|symbol| Self::deserialize_symbol(symbol).log_err())
 7835                    .collect::<Vec<_>>();
 7836                populate_labels_for_symbols(core_symbols, &language_registry, None, &mut symbols)
 7837                    .await;
 7838                Ok(symbols)
 7839            })
 7840        } else if let Some(local) = self.as_local() {
 7841            struct WorkspaceSymbolsResult {
 7842                server_id: LanguageServerId,
 7843                lsp_adapter: Arc<CachedLspAdapter>,
 7844                worktree: WeakEntity<Worktree>,
 7845                lsp_symbols: Vec<(String, SymbolKind, lsp::Location)>,
 7846            }
 7847
 7848            let mut requests = Vec::new();
 7849            let mut requested_servers = BTreeSet::new();
 7850            for (seed, state) in local.language_server_ids.iter() {
 7851                let Some(worktree_handle) = self
 7852                    .worktree_store
 7853                    .read(cx)
 7854                    .worktree_for_id(seed.worktree_id, cx)
 7855                else {
 7856                    continue;
 7857                };
 7858                let worktree = worktree_handle.read(cx);
 7859                if !worktree.is_visible() {
 7860                    continue;
 7861                }
 7862
 7863                if !requested_servers.insert(state.id) {
 7864                    continue;
 7865                }
 7866
 7867                let (lsp_adapter, server) = match local.language_servers.get(&state.id) {
 7868                    Some(LanguageServerState::Running {
 7869                        adapter, server, ..
 7870                    }) => (adapter.clone(), server),
 7871
 7872                    _ => continue,
 7873                };
 7874                let supports_workspace_symbol_request =
 7875                    match server.capabilities().workspace_symbol_provider {
 7876                        Some(OneOf::Left(supported)) => supported,
 7877                        Some(OneOf::Right(_)) => true,
 7878                        None => false,
 7879                    };
 7880                if !supports_workspace_symbol_request {
 7881                    continue;
 7882                }
 7883                let worktree_handle = worktree_handle.clone();
 7884                let server_id = server.server_id();
 7885                requests.push(
 7886                    server
 7887                        .request::<lsp::request::WorkspaceSymbolRequest>(
 7888                            lsp::WorkspaceSymbolParams {
 7889                                query: query.to_string(),
 7890                                ..Default::default()
 7891                            },
 7892                        )
 7893                        .map(move |response| {
 7894                            let lsp_symbols = response
 7895                                .into_response()
 7896                                .context("workspace symbols request")
 7897                                .log_err()
 7898                                .flatten()
 7899                                .map(|symbol_response| match symbol_response {
 7900                                    lsp::WorkspaceSymbolResponse::Flat(flat_responses) => {
 7901                                        flat_responses
 7902                                            .into_iter()
 7903                                            .map(|lsp_symbol| {
 7904                                                (
 7905                                                    lsp_symbol.name,
 7906                                                    lsp_symbol.kind,
 7907                                                    lsp_symbol.location,
 7908                                                )
 7909                                            })
 7910                                            .collect::<Vec<_>>()
 7911                                    }
 7912                                    lsp::WorkspaceSymbolResponse::Nested(nested_responses) => {
 7913                                        nested_responses
 7914                                            .into_iter()
 7915                                            .filter_map(|lsp_symbol| {
 7916                                                let location = match lsp_symbol.location {
 7917                                                    OneOf::Left(location) => location,
 7918                                                    OneOf::Right(_) => {
 7919                                                        log::error!(
 7920                                                            "Unexpected: client capabilities \
 7921                                                            forbid symbol resolutions in \
 7922                                                            workspace.symbol.resolveSupport"
 7923                                                        );
 7924                                                        return None;
 7925                                                    }
 7926                                                };
 7927                                                Some((lsp_symbol.name, lsp_symbol.kind, location))
 7928                                            })
 7929                                            .collect::<Vec<_>>()
 7930                                    }
 7931                                })
 7932                                .unwrap_or_default();
 7933
 7934                            WorkspaceSymbolsResult {
 7935                                server_id,
 7936                                lsp_adapter,
 7937                                worktree: worktree_handle.downgrade(),
 7938                                lsp_symbols,
 7939                            }
 7940                        }),
 7941                );
 7942            }
 7943
 7944            cx.spawn(async move |this, cx| {
 7945                let responses = futures::future::join_all(requests).await;
 7946                let this = match this.upgrade() {
 7947                    Some(this) => this,
 7948                    None => return Ok(Vec::new()),
 7949                };
 7950
 7951                let mut symbols = Vec::new();
 7952                for result in responses {
 7953                    let core_symbols = this.update(cx, |this, cx| {
 7954                        result
 7955                            .lsp_symbols
 7956                            .into_iter()
 7957                            .filter_map(|(symbol_name, symbol_kind, symbol_location)| {
 7958                                let abs_path = symbol_location.uri.to_file_path().ok()?;
 7959                                let source_worktree = result.worktree.upgrade()?;
 7960                                let source_worktree_id = source_worktree.read(cx).id();
 7961
 7962                                let path = if let Some((tree, rel_path)) =
 7963                                    this.worktree_store.read(cx).find_worktree(&abs_path, cx)
 7964                                {
 7965                                    let worktree_id = tree.read(cx).id();
 7966                                    SymbolLocation::InProject(ProjectPath {
 7967                                        worktree_id,
 7968                                        path: rel_path,
 7969                                    })
 7970                                } else {
 7971                                    SymbolLocation::OutsideProject {
 7972                                        signature: this.symbol_signature(&abs_path),
 7973                                        abs_path: abs_path.into(),
 7974                                    }
 7975                                };
 7976
 7977                                Some(CoreSymbol {
 7978                                    source_language_server_id: result.server_id,
 7979                                    language_server_name: result.lsp_adapter.name.clone(),
 7980                                    source_worktree_id,
 7981                                    path,
 7982                                    kind: symbol_kind,
 7983                                    name: symbol_name,
 7984                                    range: range_from_lsp(symbol_location.range),
 7985                                })
 7986                            })
 7987                            .collect::<Vec<_>>()
 7988                    });
 7989
 7990                    populate_labels_for_symbols(
 7991                        core_symbols,
 7992                        &language_registry,
 7993                        Some(result.lsp_adapter),
 7994                        &mut symbols,
 7995                    )
 7996                    .await;
 7997                }
 7998
 7999                Ok(symbols)
 8000            })
 8001        } else {
 8002            Task::ready(Err(anyhow!("No upstream client or local language server")))
 8003        }
 8004    }
 8005
 8006    pub fn diagnostic_summary(&self, include_ignored: bool, cx: &App) -> DiagnosticSummary {
 8007        let mut summary = DiagnosticSummary::default();
 8008        for (_, _, path_summary) in self.diagnostic_summaries(include_ignored, cx) {
 8009            summary.error_count += path_summary.error_count;
 8010            summary.warning_count += path_summary.warning_count;
 8011        }
 8012        summary
 8013    }
 8014
 8015    /// Returns the diagnostic summary for a specific project path.
 8016    pub fn diagnostic_summary_for_path(
 8017        &self,
 8018        project_path: &ProjectPath,
 8019        _: &App,
 8020    ) -> DiagnosticSummary {
 8021        if let Some(summaries) = self
 8022            .diagnostic_summaries
 8023            .get(&project_path.worktree_id)
 8024            .and_then(|map| map.get(&project_path.path))
 8025        {
 8026            let (error_count, warning_count) = summaries.iter().fold(
 8027                (0, 0),
 8028                |(error_count, warning_count), (_language_server_id, summary)| {
 8029                    (
 8030                        error_count + summary.error_count,
 8031                        warning_count + summary.warning_count,
 8032                    )
 8033                },
 8034            );
 8035
 8036            DiagnosticSummary {
 8037                error_count,
 8038                warning_count,
 8039            }
 8040        } else {
 8041            DiagnosticSummary::default()
 8042        }
 8043    }
 8044
 8045    pub fn diagnostic_summaries<'a>(
 8046        &'a self,
 8047        include_ignored: bool,
 8048        cx: &'a App,
 8049    ) -> impl Iterator<Item = (ProjectPath, LanguageServerId, DiagnosticSummary)> + 'a {
 8050        self.worktree_store
 8051            .read(cx)
 8052            .visible_worktrees(cx)
 8053            .filter_map(|worktree| {
 8054                let worktree = worktree.read(cx);
 8055                Some((worktree, self.diagnostic_summaries.get(&worktree.id())?))
 8056            })
 8057            .flat_map(move |(worktree, summaries)| {
 8058                let worktree_id = worktree.id();
 8059                summaries
 8060                    .iter()
 8061                    .filter(move |(path, _)| {
 8062                        include_ignored
 8063                            || worktree
 8064                                .entry_for_path(path.as_ref())
 8065                                .is_some_and(|entry| !entry.is_ignored)
 8066                    })
 8067                    .flat_map(move |(path, summaries)| {
 8068                        summaries.iter().map(move |(server_id, summary)| {
 8069                            (
 8070                                ProjectPath {
 8071                                    worktree_id,
 8072                                    path: path.clone(),
 8073                                },
 8074                                *server_id,
 8075                                *summary,
 8076                            )
 8077                        })
 8078                    })
 8079            })
 8080    }
 8081
 8082    pub fn on_buffer_edited(
 8083        &mut self,
 8084        buffer: Entity<Buffer>,
 8085        cx: &mut Context<Self>,
 8086    ) -> Option<()> {
 8087        let language_servers: Vec<_> = buffer.update(cx, |buffer, cx| {
 8088            Some(
 8089                self.as_local()?
 8090                    .language_servers_for_buffer(buffer, cx)
 8091                    .map(|i| i.1.clone())
 8092                    .collect(),
 8093            )
 8094        })?;
 8095
 8096        let buffer = buffer.read(cx);
 8097        let file = File::from_dyn(buffer.file())?;
 8098        let abs_path = file.as_local()?.abs_path(cx);
 8099        let uri = lsp::Uri::from_file_path(&abs_path)
 8100            .ok()
 8101            .with_context(|| format!("Failed to convert path to URI: {}", abs_path.display()))
 8102            .log_err()?;
 8103        let next_snapshot = buffer.text_snapshot();
 8104        for language_server in language_servers {
 8105            let language_server = language_server.clone();
 8106
 8107            let buffer_snapshots = self
 8108                .as_local_mut()?
 8109                .buffer_snapshots
 8110                .get_mut(&buffer.remote_id())
 8111                .and_then(|m| m.get_mut(&language_server.server_id()))?;
 8112            let previous_snapshot = buffer_snapshots.last()?;
 8113
 8114            let build_incremental_change = || {
 8115                buffer
 8116                    .edits_since::<Dimensions<PointUtf16, usize>>(
 8117                        previous_snapshot.snapshot.version(),
 8118                    )
 8119                    .map(|edit| {
 8120                        let edit_start = edit.new.start.0;
 8121                        let edit_end = edit_start + (edit.old.end.0 - edit.old.start.0);
 8122                        let new_text = next_snapshot
 8123                            .text_for_range(edit.new.start.1..edit.new.end.1)
 8124                            .collect();
 8125                        lsp::TextDocumentContentChangeEvent {
 8126                            range: Some(lsp::Range::new(
 8127                                point_to_lsp(edit_start),
 8128                                point_to_lsp(edit_end),
 8129                            )),
 8130                            range_length: None,
 8131                            text: new_text,
 8132                        }
 8133                    })
 8134                    .collect()
 8135            };
 8136
 8137            let document_sync_kind = language_server
 8138                .capabilities()
 8139                .text_document_sync
 8140                .as_ref()
 8141                .and_then(|sync| match sync {
 8142                    lsp::TextDocumentSyncCapability::Kind(kind) => Some(*kind),
 8143                    lsp::TextDocumentSyncCapability::Options(options) => options.change,
 8144                });
 8145
 8146            let content_changes: Vec<_> = match document_sync_kind {
 8147                Some(lsp::TextDocumentSyncKind::FULL) => {
 8148                    vec![lsp::TextDocumentContentChangeEvent {
 8149                        range: None,
 8150                        range_length: None,
 8151                        text: next_snapshot.text(),
 8152                    }]
 8153                }
 8154                Some(lsp::TextDocumentSyncKind::INCREMENTAL) => build_incremental_change(),
 8155                _ => {
 8156                    #[cfg(any(test, feature = "test-support"))]
 8157                    {
 8158                        build_incremental_change()
 8159                    }
 8160
 8161                    #[cfg(not(any(test, feature = "test-support")))]
 8162                    {
 8163                        continue;
 8164                    }
 8165                }
 8166            };
 8167
 8168            let next_version = previous_snapshot.version + 1;
 8169            buffer_snapshots.push(LspBufferSnapshot {
 8170                version: next_version,
 8171                snapshot: next_snapshot.clone(),
 8172            });
 8173
 8174            language_server
 8175                .notify::<lsp::notification::DidChangeTextDocument>(
 8176                    lsp::DidChangeTextDocumentParams {
 8177                        text_document: lsp::VersionedTextDocumentIdentifier::new(
 8178                            uri.clone(),
 8179                            next_version,
 8180                        ),
 8181                        content_changes,
 8182                    },
 8183                )
 8184                .ok();
 8185            self.pull_workspace_diagnostics(language_server.server_id());
 8186        }
 8187
 8188        None
 8189    }
 8190
 8191    pub fn on_buffer_saved(
 8192        &mut self,
 8193        buffer: Entity<Buffer>,
 8194        cx: &mut Context<Self>,
 8195    ) -> Option<()> {
 8196        let file = File::from_dyn(buffer.read(cx).file())?;
 8197        let worktree_id = file.worktree_id(cx);
 8198        let abs_path = file.as_local()?.abs_path(cx);
 8199        let text_document = lsp::TextDocumentIdentifier {
 8200            uri: file_path_to_lsp_url(&abs_path).log_err()?,
 8201        };
 8202        let local = self.as_local()?;
 8203
 8204        for server in local.language_servers_for_worktree(worktree_id) {
 8205            if let Some(include_text) = include_text(server.as_ref()) {
 8206                let text = if include_text {
 8207                    Some(buffer.read(cx).text())
 8208                } else {
 8209                    None
 8210                };
 8211                server
 8212                    .notify::<lsp::notification::DidSaveTextDocument>(
 8213                        lsp::DidSaveTextDocumentParams {
 8214                            text_document: text_document.clone(),
 8215                            text,
 8216                        },
 8217                    )
 8218                    .ok();
 8219            }
 8220        }
 8221
 8222        let language_servers = buffer.update(cx, |buffer, cx| {
 8223            local.language_server_ids_for_buffer(buffer, cx)
 8224        });
 8225        for language_server_id in language_servers {
 8226            self.simulate_disk_based_diagnostics_events_if_needed(language_server_id, cx);
 8227        }
 8228
 8229        None
 8230    }
 8231
 8232    async fn refresh_workspace_configurations(lsp_store: &WeakEntity<Self>, cx: &mut AsyncApp) {
 8233        maybe!(async move {
 8234            let mut refreshed_servers = HashSet::default();
 8235            let servers = lsp_store
 8236                .update(cx, |lsp_store, cx| {
 8237                    let local = lsp_store.as_local()?;
 8238
 8239                    let servers = local
 8240                        .language_server_ids
 8241                        .iter()
 8242                        .filter_map(|(seed, state)| {
 8243                            let worktree = lsp_store
 8244                                .worktree_store
 8245                                .read(cx)
 8246                                .worktree_for_id(seed.worktree_id, cx);
 8247                            let delegate: Arc<dyn LspAdapterDelegate> =
 8248                                worktree.map(|worktree| {
 8249                                    LocalLspAdapterDelegate::new(
 8250                                        local.languages.clone(),
 8251                                        &local.environment,
 8252                                        cx.weak_entity(),
 8253                                        &worktree,
 8254                                        local.http_client.clone(),
 8255                                        local.fs.clone(),
 8256                                        cx,
 8257                                    )
 8258                                })?;
 8259                            let server_id = state.id;
 8260
 8261                            let states = local.language_servers.get(&server_id)?;
 8262
 8263                            match states {
 8264                                LanguageServerState::Starting { .. } => None,
 8265                                LanguageServerState::Running {
 8266                                    adapter, server, ..
 8267                                } => {
 8268                                    let adapter = adapter.clone();
 8269                                    let server = server.clone();
 8270                                    refreshed_servers.insert(server.name());
 8271                                    let toolchain = seed.toolchain.clone();
 8272                                    Some(cx.spawn(async move |_, cx| {
 8273                                        let settings =
 8274                                            LocalLspStore::workspace_configuration_for_adapter(
 8275                                                adapter.adapter.clone(),
 8276                                                &delegate,
 8277                                                toolchain,
 8278                                                None,
 8279                                                cx,
 8280                                            )
 8281                                            .await
 8282                                            .ok()?;
 8283                                        server
 8284                                            .notify::<lsp::notification::DidChangeConfiguration>(
 8285                                                lsp::DidChangeConfigurationParams { settings },
 8286                                            )
 8287                                            .ok()?;
 8288                                        Some(())
 8289                                    }))
 8290                                }
 8291                            }
 8292                        })
 8293                        .collect::<Vec<_>>();
 8294
 8295                    Some(servers)
 8296                })
 8297                .ok()
 8298                .flatten()?;
 8299
 8300            log::debug!("Refreshing workspace configurations for servers {refreshed_servers:?}");
 8301            // TODO this asynchronous job runs concurrently with extension (de)registration and may take enough time for a certain extension
 8302            // to stop and unregister its language server wrapper.
 8303            // This is racy : an extension might have already removed all `local.language_servers` state, but here we `.clone()` and hold onto it anyway.
 8304            // This now causes errors in the logs, we should find a way to remove such servers from the processing everywhere.
 8305            let _: Vec<Option<()>> = join_all(servers).await;
 8306
 8307            Some(())
 8308        })
 8309        .await;
 8310    }
 8311
 8312    fn maintain_workspace_config(
 8313        external_refresh_requests: watch::Receiver<()>,
 8314        cx: &mut Context<Self>,
 8315    ) -> Task<Result<()>> {
 8316        let (mut settings_changed_tx, mut settings_changed_rx) = watch::channel();
 8317        let _ = postage::stream::Stream::try_recv(&mut settings_changed_rx);
 8318
 8319        let settings_observation = cx.observe_global::<SettingsStore>(move |_, _| {
 8320            *settings_changed_tx.borrow_mut() = ();
 8321        });
 8322
 8323        let mut joint_future =
 8324            futures::stream::select(settings_changed_rx, external_refresh_requests);
 8325        // Multiple things can happen when a workspace environment (selected toolchain + settings) change:
 8326        // - 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).
 8327        // - 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.
 8328        // - In the same vein, we might also decide to start a new language server if the workspace configuration *diverges* from the other.
 8329        // - 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,
 8330        // but it is still different to what we had before, we're gonna send out a workspace configuration update.
 8331        cx.spawn(async move |this, cx| {
 8332            while let Some(()) = joint_future.next().await {
 8333                this.update(cx, |this, cx| {
 8334                    this.refresh_server_tree(cx);
 8335                })
 8336                .ok();
 8337
 8338                Self::refresh_workspace_configurations(&this, cx).await;
 8339            }
 8340
 8341            drop(settings_observation);
 8342            anyhow::Ok(())
 8343        })
 8344    }
 8345
 8346    pub fn running_language_servers_for_local_buffer<'a>(
 8347        &'a self,
 8348        buffer: &Buffer,
 8349        cx: &mut App,
 8350    ) -> impl Iterator<Item = (&'a Arc<CachedLspAdapter>, &'a Arc<LanguageServer>)> {
 8351        let local = self.as_local();
 8352        let language_server_ids = local
 8353            .map(|local| local.language_server_ids_for_buffer(buffer, cx))
 8354            .unwrap_or_default();
 8355
 8356        language_server_ids
 8357            .into_iter()
 8358            .filter_map(
 8359                move |server_id| match local?.language_servers.get(&server_id)? {
 8360                    LanguageServerState::Running {
 8361                        adapter, server, ..
 8362                    } => Some((adapter, server)),
 8363                    _ => None,
 8364                },
 8365            )
 8366    }
 8367
 8368    pub fn language_servers_for_local_buffer(
 8369        &self,
 8370        buffer: &Buffer,
 8371        cx: &mut App,
 8372    ) -> Vec<LanguageServerId> {
 8373        let local = self.as_local();
 8374        local
 8375            .map(|local| local.language_server_ids_for_buffer(buffer, cx))
 8376            .unwrap_or_default()
 8377    }
 8378
 8379    pub fn language_server_for_local_buffer<'a>(
 8380        &'a self,
 8381        buffer: &'a Buffer,
 8382        server_id: LanguageServerId,
 8383        cx: &'a mut App,
 8384    ) -> Option<(&'a Arc<CachedLspAdapter>, &'a Arc<LanguageServer>)> {
 8385        self.as_local()?
 8386            .language_servers_for_buffer(buffer, cx)
 8387            .find(|(_, s)| s.server_id() == server_id)
 8388    }
 8389
 8390    fn remove_worktree(&mut self, id_to_remove: WorktreeId, cx: &mut Context<Self>) {
 8391        self.diagnostic_summaries.remove(&id_to_remove);
 8392        if let Some(local) = self.as_local_mut() {
 8393            let to_remove = local.remove_worktree(id_to_remove, cx);
 8394            for server in to_remove {
 8395                self.language_server_statuses.remove(&server);
 8396            }
 8397        }
 8398    }
 8399
 8400    pub fn shared(
 8401        &mut self,
 8402        project_id: u64,
 8403        downstream_client: AnyProtoClient,
 8404        _: &mut Context<Self>,
 8405    ) {
 8406        self.downstream_client = Some((downstream_client.clone(), project_id));
 8407
 8408        for (server_id, status) in &self.language_server_statuses {
 8409            if let Some(server) = self.language_server_for_id(*server_id) {
 8410                downstream_client
 8411                    .send(proto::StartLanguageServer {
 8412                        project_id,
 8413                        server: Some(proto::LanguageServer {
 8414                            id: server_id.to_proto(),
 8415                            name: status.name.to_string(),
 8416                            worktree_id: status.worktree.map(|id| id.to_proto()),
 8417                        }),
 8418                        capabilities: serde_json::to_string(&server.capabilities())
 8419                            .expect("serializing server LSP capabilities"),
 8420                    })
 8421                    .log_err();
 8422            }
 8423        }
 8424    }
 8425
 8426    pub fn disconnected_from_host(&mut self) {
 8427        self.downstream_client.take();
 8428    }
 8429
 8430    pub fn disconnected_from_ssh_remote(&mut self) {
 8431        if let LspStoreMode::Remote(RemoteLspStore {
 8432            upstream_client, ..
 8433        }) = &mut self.mode
 8434        {
 8435            upstream_client.take();
 8436        }
 8437    }
 8438
 8439    pub(crate) fn set_language_server_statuses_from_proto(
 8440        &mut self,
 8441        project: WeakEntity<Project>,
 8442        language_servers: Vec<proto::LanguageServer>,
 8443        server_capabilities: Vec<String>,
 8444        cx: &mut Context<Self>,
 8445    ) {
 8446        let lsp_logs = cx
 8447            .try_global::<GlobalLogStore>()
 8448            .map(|lsp_store| lsp_store.0.clone());
 8449
 8450        self.language_server_statuses = language_servers
 8451            .into_iter()
 8452            .zip(server_capabilities)
 8453            .map(|(server, server_capabilities)| {
 8454                let server_id = LanguageServerId(server.id as usize);
 8455                if let Ok(server_capabilities) = serde_json::from_str(&server_capabilities) {
 8456                    self.lsp_server_capabilities
 8457                        .insert(server_id, server_capabilities);
 8458                }
 8459
 8460                let name = LanguageServerName::from_proto(server.name);
 8461                let worktree = server.worktree_id.map(WorktreeId::from_proto);
 8462
 8463                if let Some(lsp_logs) = &lsp_logs {
 8464                    lsp_logs.update(cx, |lsp_logs, cx| {
 8465                        lsp_logs.add_language_server(
 8466                            // Only remote clients get their language servers set from proto
 8467                            LanguageServerKind::Remote {
 8468                                project: project.clone(),
 8469                            },
 8470                            server_id,
 8471                            Some(name.clone()),
 8472                            worktree,
 8473                            None,
 8474                            cx,
 8475                        );
 8476                    });
 8477                }
 8478
 8479                (
 8480                    server_id,
 8481                    LanguageServerStatus {
 8482                        name,
 8483                        server_version: None,
 8484                        pending_work: Default::default(),
 8485                        has_pending_diagnostic_updates: false,
 8486                        progress_tokens: Default::default(),
 8487                        worktree,
 8488                        binary: None,
 8489                        configuration: None,
 8490                        workspace_folders: BTreeSet::new(),
 8491                        process_id: None,
 8492                    },
 8493                )
 8494            })
 8495            .collect();
 8496    }
 8497
 8498    #[cfg(feature = "test-support")]
 8499    pub fn update_diagnostic_entries(
 8500        &mut self,
 8501        server_id: LanguageServerId,
 8502        abs_path: PathBuf,
 8503        result_id: Option<SharedString>,
 8504        version: Option<i32>,
 8505        diagnostics: Vec<DiagnosticEntry<Unclipped<PointUtf16>>>,
 8506        cx: &mut Context<Self>,
 8507    ) -> anyhow::Result<()> {
 8508        self.merge_diagnostic_entries(
 8509            vec![DocumentDiagnosticsUpdate {
 8510                diagnostics: DocumentDiagnostics {
 8511                    diagnostics,
 8512                    document_abs_path: abs_path,
 8513                    version,
 8514                },
 8515                result_id,
 8516                server_id,
 8517                disk_based_sources: Cow::Borrowed(&[]),
 8518                registration_id: None,
 8519            }],
 8520            |_, _, _| false,
 8521            cx,
 8522        )?;
 8523        Ok(())
 8524    }
 8525
 8526    pub fn merge_diagnostic_entries<'a>(
 8527        &mut self,
 8528        diagnostic_updates: Vec<DocumentDiagnosticsUpdate<'a, DocumentDiagnostics>>,
 8529        merge: impl Fn(&lsp::Uri, &Diagnostic, &App) -> bool + Clone,
 8530        cx: &mut Context<Self>,
 8531    ) -> anyhow::Result<()> {
 8532        let mut diagnostics_summary = None::<proto::UpdateDiagnosticSummary>;
 8533        let mut updated_diagnostics_paths = HashMap::default();
 8534        for mut update in diagnostic_updates {
 8535            let abs_path = &update.diagnostics.document_abs_path;
 8536            let server_id = update.server_id;
 8537            let Some((worktree, relative_path)) =
 8538                self.worktree_store.read(cx).find_worktree(abs_path, cx)
 8539            else {
 8540                log::warn!("skipping diagnostics update, no worktree found for path {abs_path:?}");
 8541                return Ok(());
 8542            };
 8543
 8544            let worktree_id = worktree.read(cx).id();
 8545            let project_path = ProjectPath {
 8546                worktree_id,
 8547                path: relative_path,
 8548            };
 8549
 8550            let document_uri = lsp::Uri::from_file_path(abs_path)
 8551                .map_err(|()| anyhow!("Failed to convert buffer path {abs_path:?} to lsp Uri"))?;
 8552            if let Some(buffer_handle) = self.buffer_store.read(cx).get_by_path(&project_path) {
 8553                let snapshot = buffer_handle.read(cx).snapshot();
 8554                let buffer = buffer_handle.read(cx);
 8555                let reused_diagnostics = buffer
 8556                    .buffer_diagnostics(Some(server_id))
 8557                    .iter()
 8558                    .filter(|v| merge(&document_uri, &v.diagnostic, cx))
 8559                    .map(|v| {
 8560                        let start = Unclipped(v.range.start.to_point_utf16(&snapshot));
 8561                        let end = Unclipped(v.range.end.to_point_utf16(&snapshot));
 8562                        DiagnosticEntry {
 8563                            range: start..end,
 8564                            diagnostic: v.diagnostic.clone(),
 8565                        }
 8566                    })
 8567                    .collect::<Vec<_>>();
 8568
 8569                self.as_local_mut()
 8570                    .context("cannot merge diagnostics on a remote LspStore")?
 8571                    .update_buffer_diagnostics(
 8572                        &buffer_handle,
 8573                        server_id,
 8574                        Some(update.registration_id),
 8575                        update.result_id,
 8576                        update.diagnostics.version,
 8577                        update.diagnostics.diagnostics.clone(),
 8578                        reused_diagnostics.clone(),
 8579                        cx,
 8580                    )?;
 8581
 8582                update.diagnostics.diagnostics.extend(reused_diagnostics);
 8583            } else if let Some(local) = self.as_local() {
 8584                let reused_diagnostics = local
 8585                    .diagnostics
 8586                    .get(&worktree_id)
 8587                    .and_then(|diagnostics_for_tree| diagnostics_for_tree.get(&project_path.path))
 8588                    .and_then(|diagnostics_by_server_id| {
 8589                        diagnostics_by_server_id
 8590                            .binary_search_by_key(&server_id, |e| e.0)
 8591                            .ok()
 8592                            .map(|ix| &diagnostics_by_server_id[ix].1)
 8593                    })
 8594                    .into_iter()
 8595                    .flatten()
 8596                    .filter(|v| merge(&document_uri, &v.diagnostic, cx));
 8597
 8598                update
 8599                    .diagnostics
 8600                    .diagnostics
 8601                    .extend(reused_diagnostics.cloned());
 8602            }
 8603
 8604            let updated = worktree.update(cx, |worktree, cx| {
 8605                self.update_worktree_diagnostics(
 8606                    worktree.id(),
 8607                    server_id,
 8608                    project_path.path.clone(),
 8609                    update.diagnostics.diagnostics,
 8610                    cx,
 8611                )
 8612            })?;
 8613            match updated {
 8614                ControlFlow::Continue(new_summary) => {
 8615                    if let Some((project_id, new_summary)) = new_summary {
 8616                        match &mut diagnostics_summary {
 8617                            Some(diagnostics_summary) => {
 8618                                diagnostics_summary
 8619                                    .more_summaries
 8620                                    .push(proto::DiagnosticSummary {
 8621                                        path: project_path.path.as_ref().to_proto(),
 8622                                        language_server_id: server_id.0 as u64,
 8623                                        error_count: new_summary.error_count,
 8624                                        warning_count: new_summary.warning_count,
 8625                                    })
 8626                            }
 8627                            None => {
 8628                                diagnostics_summary = Some(proto::UpdateDiagnosticSummary {
 8629                                    project_id,
 8630                                    worktree_id: worktree_id.to_proto(),
 8631                                    summary: Some(proto::DiagnosticSummary {
 8632                                        path: project_path.path.as_ref().to_proto(),
 8633                                        language_server_id: server_id.0 as u64,
 8634                                        error_count: new_summary.error_count,
 8635                                        warning_count: new_summary.warning_count,
 8636                                    }),
 8637                                    more_summaries: Vec::new(),
 8638                                })
 8639                            }
 8640                        }
 8641                    }
 8642                    updated_diagnostics_paths
 8643                        .entry(server_id)
 8644                        .or_insert_with(Vec::new)
 8645                        .push(project_path);
 8646                }
 8647                ControlFlow::Break(()) => {}
 8648            }
 8649        }
 8650
 8651        if let Some((diagnostics_summary, (downstream_client, _))) =
 8652            diagnostics_summary.zip(self.downstream_client.as_ref())
 8653        {
 8654            downstream_client.send(diagnostics_summary).log_err();
 8655        }
 8656        for (server_id, paths) in updated_diagnostics_paths {
 8657            cx.emit(LspStoreEvent::DiagnosticsUpdated { server_id, paths });
 8658        }
 8659        Ok(())
 8660    }
 8661
 8662    fn update_worktree_diagnostics(
 8663        &mut self,
 8664        worktree_id: WorktreeId,
 8665        server_id: LanguageServerId,
 8666        path_in_worktree: Arc<RelPath>,
 8667        diagnostics: Vec<DiagnosticEntry<Unclipped<PointUtf16>>>,
 8668        _: &mut Context<Worktree>,
 8669    ) -> Result<ControlFlow<(), Option<(u64, proto::DiagnosticSummary)>>> {
 8670        let local = match &mut self.mode {
 8671            LspStoreMode::Local(local_lsp_store) => local_lsp_store,
 8672            _ => anyhow::bail!("update_worktree_diagnostics called on remote"),
 8673        };
 8674
 8675        let summaries_for_tree = self.diagnostic_summaries.entry(worktree_id).or_default();
 8676        let diagnostics_for_tree = local.diagnostics.entry(worktree_id).or_default();
 8677        let summaries_by_server_id = summaries_for_tree
 8678            .entry(path_in_worktree.clone())
 8679            .or_default();
 8680
 8681        let old_summary = summaries_by_server_id
 8682            .remove(&server_id)
 8683            .unwrap_or_default();
 8684
 8685        let new_summary = DiagnosticSummary::new(&diagnostics);
 8686        if diagnostics.is_empty() {
 8687            if let Some(diagnostics_by_server_id) = diagnostics_for_tree.get_mut(&path_in_worktree)
 8688            {
 8689                if let Ok(ix) = diagnostics_by_server_id.binary_search_by_key(&server_id, |e| e.0) {
 8690                    diagnostics_by_server_id.remove(ix);
 8691                }
 8692                if diagnostics_by_server_id.is_empty() {
 8693                    diagnostics_for_tree.remove(&path_in_worktree);
 8694                }
 8695            }
 8696        } else {
 8697            summaries_by_server_id.insert(server_id, new_summary);
 8698            let diagnostics_by_server_id = diagnostics_for_tree
 8699                .entry(path_in_worktree.clone())
 8700                .or_default();
 8701            match diagnostics_by_server_id.binary_search_by_key(&server_id, |e| e.0) {
 8702                Ok(ix) => {
 8703                    diagnostics_by_server_id[ix] = (server_id, diagnostics);
 8704                }
 8705                Err(ix) => {
 8706                    diagnostics_by_server_id.insert(ix, (server_id, diagnostics));
 8707                }
 8708            }
 8709        }
 8710
 8711        if !old_summary.is_empty() || !new_summary.is_empty() {
 8712            if let Some((_, project_id)) = &self.downstream_client {
 8713                Ok(ControlFlow::Continue(Some((
 8714                    *project_id,
 8715                    proto::DiagnosticSummary {
 8716                        path: path_in_worktree.to_proto(),
 8717                        language_server_id: server_id.0 as u64,
 8718                        error_count: new_summary.error_count as u32,
 8719                        warning_count: new_summary.warning_count as u32,
 8720                    },
 8721                ))))
 8722            } else {
 8723                Ok(ControlFlow::Continue(None))
 8724            }
 8725        } else {
 8726            Ok(ControlFlow::Break(()))
 8727        }
 8728    }
 8729
 8730    pub fn open_buffer_for_symbol(
 8731        &mut self,
 8732        symbol: &Symbol,
 8733        cx: &mut Context<Self>,
 8734    ) -> Task<Result<Entity<Buffer>>> {
 8735        if let Some((client, project_id)) = self.upstream_client() {
 8736            let request = client.request(proto::OpenBufferForSymbol {
 8737                project_id,
 8738                symbol: Some(Self::serialize_symbol(symbol)),
 8739            });
 8740            cx.spawn(async move |this, cx| {
 8741                let response = request.await?;
 8742                let buffer_id = BufferId::new(response.buffer_id)?;
 8743                this.update(cx, |this, cx| this.wait_for_remote_buffer(buffer_id, cx))?
 8744                    .await
 8745            })
 8746        } else if let Some(local) = self.as_local() {
 8747            let is_valid = local.language_server_ids.iter().any(|(seed, state)| {
 8748                seed.worktree_id == symbol.source_worktree_id
 8749                    && state.id == symbol.source_language_server_id
 8750                    && symbol.language_server_name == seed.name
 8751            });
 8752            if !is_valid {
 8753                return Task::ready(Err(anyhow!(
 8754                    "language server for worktree and language not found"
 8755                )));
 8756            };
 8757
 8758            let symbol_abs_path = match &symbol.path {
 8759                SymbolLocation::InProject(project_path) => self
 8760                    .worktree_store
 8761                    .read(cx)
 8762                    .absolutize(&project_path, cx)
 8763                    .context("no such worktree"),
 8764                SymbolLocation::OutsideProject {
 8765                    abs_path,
 8766                    signature: _,
 8767                } => Ok(abs_path.to_path_buf()),
 8768            };
 8769            let symbol_abs_path = match symbol_abs_path {
 8770                Ok(abs_path) => abs_path,
 8771                Err(err) => return Task::ready(Err(err)),
 8772            };
 8773            let symbol_uri = if let Ok(uri) = lsp::Uri::from_file_path(symbol_abs_path) {
 8774                uri
 8775            } else {
 8776                return Task::ready(Err(anyhow!("invalid symbol path")));
 8777            };
 8778
 8779            self.open_local_buffer_via_lsp(symbol_uri, symbol.source_language_server_id, cx)
 8780        } else {
 8781            Task::ready(Err(anyhow!("no upstream client or local store")))
 8782        }
 8783    }
 8784
 8785    pub(crate) fn open_local_buffer_via_lsp(
 8786        &mut self,
 8787        abs_path: lsp::Uri,
 8788        language_server_id: LanguageServerId,
 8789        cx: &mut Context<Self>,
 8790    ) -> Task<Result<Entity<Buffer>>> {
 8791        let path_style = self.worktree_store.read(cx).path_style();
 8792        cx.spawn(async move |lsp_store, cx| {
 8793            // Escape percent-encoded string.
 8794            let current_scheme = abs_path.scheme().to_owned();
 8795            // Uri is immutable, so we can't modify the scheme
 8796
 8797            let abs_path = abs_path
 8798                .to_file_path_ext(path_style)
 8799                .map_err(|()| anyhow!("can't convert URI to path"))?;
 8800            let p = abs_path.clone();
 8801            let yarn_worktree = lsp_store
 8802                .update(cx, move |lsp_store, cx| match lsp_store.as_local() {
 8803                    Some(local_lsp_store) => local_lsp_store.yarn.update(cx, |_, cx| {
 8804                        cx.spawn(async move |this, cx| {
 8805                            let t = this
 8806                                .update(cx, |this, cx| this.process_path(&p, &current_scheme, cx))
 8807                                .ok()?;
 8808                            t.await
 8809                        })
 8810                    }),
 8811                    None => Task::ready(None),
 8812                })?
 8813                .await;
 8814            let (worktree_root_target, known_relative_path) =
 8815                if let Some((zip_root, relative_path)) = yarn_worktree {
 8816                    (zip_root, Some(relative_path))
 8817                } else {
 8818                    (Arc::<Path>::from(abs_path.as_path()), None)
 8819                };
 8820            let worktree = lsp_store.update(cx, |lsp_store, cx| {
 8821                lsp_store.worktree_store.update(cx, |worktree_store, cx| {
 8822                    worktree_store.find_worktree(&worktree_root_target, cx)
 8823                })
 8824            })?;
 8825            let (worktree, relative_path, source_ws) = if let Some(result) = worktree {
 8826                let relative_path = known_relative_path.unwrap_or_else(|| result.1.clone());
 8827                (result.0, relative_path, None)
 8828            } else {
 8829                let worktree = lsp_store
 8830                    .update(cx, |lsp_store, cx| {
 8831                        lsp_store.worktree_store.update(cx, |worktree_store, cx| {
 8832                            worktree_store.create_worktree(&worktree_root_target, false, cx)
 8833                        })
 8834                    })?
 8835                    .await?;
 8836                let worktree_root = worktree.read_with(cx, |worktree, _| worktree.abs_path());
 8837                let source_ws = if worktree.read_with(cx, |worktree, _| worktree.is_local()) {
 8838                    lsp_store
 8839                        .update(cx, |lsp_store, cx| {
 8840                            if let Some(local) = lsp_store.as_local_mut() {
 8841                                local.register_language_server_for_invisible_worktree(
 8842                                    &worktree,
 8843                                    language_server_id,
 8844                                    cx,
 8845                                )
 8846                            }
 8847                            match lsp_store.language_server_statuses.get(&language_server_id) {
 8848                                Some(status) => status.worktree,
 8849                                None => None,
 8850                            }
 8851                        })
 8852                        .ok()
 8853                        .flatten()
 8854                        .zip(Some(worktree_root.clone()))
 8855                } else {
 8856                    None
 8857                };
 8858                let relative_path = if let Some(known_path) = known_relative_path {
 8859                    known_path
 8860                } else {
 8861                    RelPath::new(abs_path.strip_prefix(worktree_root)?, PathStyle::local())?
 8862                        .into_arc()
 8863                };
 8864                (worktree, relative_path, source_ws)
 8865            };
 8866            let project_path = ProjectPath {
 8867                worktree_id: worktree.read_with(cx, |worktree, _| worktree.id()),
 8868                path: relative_path,
 8869            };
 8870            let buffer = lsp_store
 8871                .update(cx, |lsp_store, cx| {
 8872                    lsp_store.buffer_store().update(cx, |buffer_store, cx| {
 8873                        buffer_store.open_buffer(project_path, cx)
 8874                    })
 8875                })?
 8876                .await?;
 8877            // we want to adhere to the read-only settings of the worktree we came from in case we opened an invisible one
 8878            if let Some((source_ws, worktree_root)) = source_ws {
 8879                buffer.update(cx, |buffer, cx| {
 8880                    let settings = WorktreeSettings::get(
 8881                        Some(
 8882                            (&ProjectPath {
 8883                                worktree_id: source_ws,
 8884                                path: Arc::from(RelPath::empty()),
 8885                            })
 8886                                .into(),
 8887                        ),
 8888                        cx,
 8889                    );
 8890                    let is_read_only = settings.is_std_path_read_only(&worktree_root);
 8891                    if is_read_only {
 8892                        buffer.set_capability(Capability::ReadOnly, cx);
 8893                    }
 8894                });
 8895            }
 8896            Ok(buffer)
 8897        })
 8898    }
 8899
 8900    fn request_multiple_lsp_locally<P, R>(
 8901        &mut self,
 8902        buffer: &Entity<Buffer>,
 8903        position: Option<P>,
 8904        request: R,
 8905        cx: &mut Context<Self>,
 8906    ) -> Task<Vec<(LanguageServerId, R::Response)>>
 8907    where
 8908        P: ToOffset,
 8909        R: LspCommand + Clone,
 8910        <R::LspRequest as lsp::request::Request>::Result: Send,
 8911        <R::LspRequest as lsp::request::Request>::Params: Send,
 8912    {
 8913        let Some(local) = self.as_local() else {
 8914            return Task::ready(Vec::new());
 8915        };
 8916
 8917        let snapshot = buffer.read(cx).snapshot();
 8918        let scope = position.and_then(|position| snapshot.language_scope_at(position));
 8919
 8920        let server_ids = buffer.update(cx, |buffer, cx| {
 8921            local
 8922                .language_servers_for_buffer(buffer, cx)
 8923                .filter(|(adapter, _)| {
 8924                    scope
 8925                        .as_ref()
 8926                        .map(|scope| scope.language_allowed(&adapter.name))
 8927                        .unwrap_or(true)
 8928                })
 8929                .map(|(_, server)| server.server_id())
 8930                .filter(|server_id| {
 8931                    self.as_local().is_none_or(|local| {
 8932                        local
 8933                            .buffers_opened_in_servers
 8934                            .get(&snapshot.remote_id())
 8935                            .is_some_and(|servers| servers.contains(server_id))
 8936                    })
 8937                })
 8938                .collect::<Vec<_>>()
 8939        });
 8940
 8941        let mut response_results = server_ids
 8942            .into_iter()
 8943            .map(|server_id| {
 8944                let task = self.request_lsp(
 8945                    buffer.clone(),
 8946                    LanguageServerToQuery::Other(server_id),
 8947                    request.clone(),
 8948                    cx,
 8949                );
 8950                async move { (server_id, task.await) }
 8951            })
 8952            .collect::<FuturesUnordered<_>>();
 8953
 8954        cx.background_spawn(async move {
 8955            let mut responses = Vec::with_capacity(response_results.len());
 8956            while let Some((server_id, response_result)) = response_results.next().await {
 8957                match response_result {
 8958                    Ok(response) => responses.push((server_id, response)),
 8959                    // rust-analyzer likes to error with this when its still loading up
 8960                    Err(e) if format!("{e:#}").ends_with("content modified") => (),
 8961                    Err(e) => log::error!("Error handling response for request {request:?}: {e:#}"),
 8962                }
 8963            }
 8964            responses
 8965        })
 8966    }
 8967
 8968    async fn handle_lsp_get_completions(
 8969        this: Entity<Self>,
 8970        envelope: TypedEnvelope<proto::GetCompletions>,
 8971        mut cx: AsyncApp,
 8972    ) -> Result<proto::GetCompletionsResponse> {
 8973        let sender_id = envelope.original_sender_id().unwrap_or_default();
 8974
 8975        let buffer_id = GetCompletions::buffer_id_from_proto(&envelope.payload)?;
 8976        let buffer_handle = this.update(&mut cx, |this, cx| {
 8977            this.buffer_store.read(cx).get_existing(buffer_id)
 8978        })?;
 8979        let request = GetCompletions::from_proto(
 8980            envelope.payload,
 8981            this.clone(),
 8982            buffer_handle.clone(),
 8983            cx.clone(),
 8984        )
 8985        .await?;
 8986
 8987        let server_to_query = match request.server_id {
 8988            Some(server_id) => LanguageServerToQuery::Other(server_id),
 8989            None => LanguageServerToQuery::FirstCapable,
 8990        };
 8991
 8992        let response = this
 8993            .update(&mut cx, |this, cx| {
 8994                this.request_lsp(buffer_handle.clone(), server_to_query, request, cx)
 8995            })
 8996            .await?;
 8997        this.update(&mut cx, |this, cx| {
 8998            Ok(GetCompletions::response_to_proto(
 8999                response,
 9000                this,
 9001                sender_id,
 9002                &buffer_handle.read(cx).version(),
 9003                cx,
 9004            ))
 9005        })
 9006    }
 9007
 9008    async fn handle_lsp_command<T: LspCommand>(
 9009        this: Entity<Self>,
 9010        envelope: TypedEnvelope<T::ProtoRequest>,
 9011        mut cx: AsyncApp,
 9012    ) -> Result<<T::ProtoRequest as proto::RequestMessage>::Response>
 9013    where
 9014        <T::LspRequest as lsp::request::Request>::Params: Send,
 9015        <T::LspRequest as lsp::request::Request>::Result: Send,
 9016    {
 9017        let sender_id = envelope.original_sender_id().unwrap_or_default();
 9018        let buffer_id = T::buffer_id_from_proto(&envelope.payload)?;
 9019        let buffer_handle = this.update(&mut cx, |this, cx| {
 9020            this.buffer_store.read(cx).get_existing(buffer_id)
 9021        })?;
 9022        let request = T::from_proto(
 9023            envelope.payload,
 9024            this.clone(),
 9025            buffer_handle.clone(),
 9026            cx.clone(),
 9027        )
 9028        .await?;
 9029        let response = this
 9030            .update(&mut cx, |this, cx| {
 9031                this.request_lsp(
 9032                    buffer_handle.clone(),
 9033                    LanguageServerToQuery::FirstCapable,
 9034                    request,
 9035                    cx,
 9036                )
 9037            })
 9038            .await?;
 9039        this.update(&mut cx, |this, cx| {
 9040            Ok(T::response_to_proto(
 9041                response,
 9042                this,
 9043                sender_id,
 9044                &buffer_handle.read(cx).version(),
 9045                cx,
 9046            ))
 9047        })
 9048    }
 9049
 9050    async fn handle_lsp_query(
 9051        lsp_store: Entity<Self>,
 9052        envelope: TypedEnvelope<proto::LspQuery>,
 9053        mut cx: AsyncApp,
 9054    ) -> Result<proto::Ack> {
 9055        use proto::lsp_query::Request;
 9056        let sender_id = envelope.original_sender_id().unwrap_or_default();
 9057        let lsp_query = envelope.payload;
 9058        let lsp_request_id = LspRequestId(lsp_query.lsp_request_id);
 9059        let server_id = lsp_query.server_id.map(LanguageServerId::from_proto);
 9060        match lsp_query.request.context("invalid LSP query request")? {
 9061            Request::GetReferences(get_references) => {
 9062                let position = get_references.position.clone().and_then(deserialize_anchor);
 9063                Self::query_lsp_locally::<GetReferences>(
 9064                    lsp_store,
 9065                    server_id,
 9066                    sender_id,
 9067                    lsp_request_id,
 9068                    get_references,
 9069                    position,
 9070                    &mut cx,
 9071                )
 9072                .await?;
 9073            }
 9074            Request::GetDocumentColor(get_document_color) => {
 9075                Self::query_lsp_locally::<GetDocumentColor>(
 9076                    lsp_store,
 9077                    server_id,
 9078                    sender_id,
 9079                    lsp_request_id,
 9080                    get_document_color,
 9081                    None,
 9082                    &mut cx,
 9083                )
 9084                .await?;
 9085            }
 9086            Request::GetHover(get_hover) => {
 9087                let position = get_hover.position.clone().and_then(deserialize_anchor);
 9088                Self::query_lsp_locally::<GetHover>(
 9089                    lsp_store,
 9090                    server_id,
 9091                    sender_id,
 9092                    lsp_request_id,
 9093                    get_hover,
 9094                    position,
 9095                    &mut cx,
 9096                )
 9097                .await?;
 9098            }
 9099            Request::GetCodeActions(get_code_actions) => {
 9100                Self::query_lsp_locally::<GetCodeActions>(
 9101                    lsp_store,
 9102                    server_id,
 9103                    sender_id,
 9104                    lsp_request_id,
 9105                    get_code_actions,
 9106                    None,
 9107                    &mut cx,
 9108                )
 9109                .await?;
 9110            }
 9111            Request::GetSignatureHelp(get_signature_help) => {
 9112                let position = get_signature_help
 9113                    .position
 9114                    .clone()
 9115                    .and_then(deserialize_anchor);
 9116                Self::query_lsp_locally::<GetSignatureHelp>(
 9117                    lsp_store,
 9118                    server_id,
 9119                    sender_id,
 9120                    lsp_request_id,
 9121                    get_signature_help,
 9122                    position,
 9123                    &mut cx,
 9124                )
 9125                .await?;
 9126            }
 9127            Request::GetCodeLens(get_code_lens) => {
 9128                Self::query_lsp_locally::<GetCodeLens>(
 9129                    lsp_store,
 9130                    server_id,
 9131                    sender_id,
 9132                    lsp_request_id,
 9133                    get_code_lens,
 9134                    None,
 9135                    &mut cx,
 9136                )
 9137                .await?;
 9138            }
 9139            Request::GetDefinition(get_definition) => {
 9140                let position = get_definition.position.clone().and_then(deserialize_anchor);
 9141                Self::query_lsp_locally::<GetDefinitions>(
 9142                    lsp_store,
 9143                    server_id,
 9144                    sender_id,
 9145                    lsp_request_id,
 9146                    get_definition,
 9147                    position,
 9148                    &mut cx,
 9149                )
 9150                .await?;
 9151            }
 9152            Request::GetDeclaration(get_declaration) => {
 9153                let position = get_declaration
 9154                    .position
 9155                    .clone()
 9156                    .and_then(deserialize_anchor);
 9157                Self::query_lsp_locally::<GetDeclarations>(
 9158                    lsp_store,
 9159                    server_id,
 9160                    sender_id,
 9161                    lsp_request_id,
 9162                    get_declaration,
 9163                    position,
 9164                    &mut cx,
 9165                )
 9166                .await?;
 9167            }
 9168            Request::GetTypeDefinition(get_type_definition) => {
 9169                let position = get_type_definition
 9170                    .position
 9171                    .clone()
 9172                    .and_then(deserialize_anchor);
 9173                Self::query_lsp_locally::<GetTypeDefinitions>(
 9174                    lsp_store,
 9175                    server_id,
 9176                    sender_id,
 9177                    lsp_request_id,
 9178                    get_type_definition,
 9179                    position,
 9180                    &mut cx,
 9181                )
 9182                .await?;
 9183            }
 9184            Request::GetImplementation(get_implementation) => {
 9185                let position = get_implementation
 9186                    .position
 9187                    .clone()
 9188                    .and_then(deserialize_anchor);
 9189                Self::query_lsp_locally::<GetImplementations>(
 9190                    lsp_store,
 9191                    server_id,
 9192                    sender_id,
 9193                    lsp_request_id,
 9194                    get_implementation,
 9195                    position,
 9196                    &mut cx,
 9197                )
 9198                .await?;
 9199            }
 9200            Request::GetDocumentDiagnostics(get_document_diagnostics) => {
 9201                let buffer_id = BufferId::new(get_document_diagnostics.buffer_id())?;
 9202                let version = deserialize_version(get_document_diagnostics.buffer_version());
 9203                let buffer = lsp_store.update(&mut cx, |this, cx| {
 9204                    this.buffer_store.read(cx).get_existing(buffer_id)
 9205                })?;
 9206                buffer
 9207                    .update(&mut cx, |buffer, _| {
 9208                        buffer.wait_for_version(version.clone())
 9209                    })
 9210                    .await?;
 9211                lsp_store.update(&mut cx, |lsp_store, cx| {
 9212                    let lsp_data = lsp_store.latest_lsp_data(&buffer, cx);
 9213                    let key = LspKey {
 9214                        request_type: TypeId::of::<GetDocumentDiagnostics>(),
 9215                        server_queried: server_id,
 9216                    };
 9217                    if <GetDocumentDiagnostics as LspCommand>::ProtoRequest::stop_previous_requests(
 9218                    ) {
 9219                        if let Some(lsp_requests) = lsp_data.lsp_requests.get_mut(&key) {
 9220                            lsp_requests.clear();
 9221                        };
 9222                    }
 9223
 9224                    let existing_queries = lsp_data.lsp_requests.entry(key).or_default();
 9225                    existing_queries.insert(
 9226                        lsp_request_id,
 9227                        cx.spawn(async move |lsp_store, cx| {
 9228                            let diagnostics_pull = lsp_store.update(cx, |lsp_store, cx| {
 9229                                lsp_store.pull_diagnostics_for_buffer(buffer, cx)
 9230                            });
 9231                            if let Ok(diagnostics_pull) = diagnostics_pull {
 9232                                match diagnostics_pull.await {
 9233                                    Ok(()) => {}
 9234                                    Err(e) => log::error!("Failed to pull diagnostics: {e:#}"),
 9235                                };
 9236                            }
 9237                        }),
 9238                    );
 9239                });
 9240            }
 9241            Request::InlayHints(inlay_hints) => {
 9242                let query_start = inlay_hints
 9243                    .start
 9244                    .clone()
 9245                    .and_then(deserialize_anchor)
 9246                    .context("invalid inlay hints range start")?;
 9247                let query_end = inlay_hints
 9248                    .end
 9249                    .clone()
 9250                    .and_then(deserialize_anchor)
 9251                    .context("invalid inlay hints range end")?;
 9252                Self::deduplicate_range_based_lsp_requests::<InlayHints>(
 9253                    &lsp_store,
 9254                    server_id,
 9255                    lsp_request_id,
 9256                    &inlay_hints,
 9257                    query_start..query_end,
 9258                    &mut cx,
 9259                )
 9260                .await
 9261                .context("preparing inlay hints request")?;
 9262                Self::query_lsp_locally::<InlayHints>(
 9263                    lsp_store,
 9264                    server_id,
 9265                    sender_id,
 9266                    lsp_request_id,
 9267                    inlay_hints,
 9268                    None,
 9269                    &mut cx,
 9270                )
 9271                .await
 9272                .context("querying for inlay hints")?
 9273            }
 9274        }
 9275        Ok(proto::Ack {})
 9276    }
 9277
 9278    async fn handle_lsp_query_response(
 9279        lsp_store: Entity<Self>,
 9280        envelope: TypedEnvelope<proto::LspQueryResponse>,
 9281        cx: AsyncApp,
 9282    ) -> Result<()> {
 9283        lsp_store.read_with(&cx, |lsp_store, _| {
 9284            if let Some((upstream_client, _)) = lsp_store.upstream_client() {
 9285                upstream_client.handle_lsp_response(envelope.clone());
 9286            }
 9287        });
 9288        Ok(())
 9289    }
 9290
 9291    async fn handle_apply_code_action(
 9292        this: Entity<Self>,
 9293        envelope: TypedEnvelope<proto::ApplyCodeAction>,
 9294        mut cx: AsyncApp,
 9295    ) -> Result<proto::ApplyCodeActionResponse> {
 9296        let sender_id = envelope.original_sender_id().unwrap_or_default();
 9297        let action =
 9298            Self::deserialize_code_action(envelope.payload.action.context("invalid action")?)?;
 9299        let apply_code_action = this.update(&mut cx, |this, cx| {
 9300            let buffer_id = BufferId::new(envelope.payload.buffer_id)?;
 9301            let buffer = this.buffer_store.read(cx).get_existing(buffer_id)?;
 9302            anyhow::Ok(this.apply_code_action(buffer, action, false, cx))
 9303        })?;
 9304
 9305        let project_transaction = apply_code_action.await?;
 9306        let project_transaction = this.update(&mut cx, |this, cx| {
 9307            this.buffer_store.update(cx, |buffer_store, cx| {
 9308                buffer_store.serialize_project_transaction_for_peer(
 9309                    project_transaction,
 9310                    sender_id,
 9311                    cx,
 9312                )
 9313            })
 9314        });
 9315        Ok(proto::ApplyCodeActionResponse {
 9316            transaction: Some(project_transaction),
 9317        })
 9318    }
 9319
 9320    async fn handle_register_buffer_with_language_servers(
 9321        this: Entity<Self>,
 9322        envelope: TypedEnvelope<proto::RegisterBufferWithLanguageServers>,
 9323        mut cx: AsyncApp,
 9324    ) -> Result<proto::Ack> {
 9325        let buffer_id = BufferId::new(envelope.payload.buffer_id)?;
 9326        let peer_id = envelope.original_sender_id.unwrap_or(envelope.sender_id);
 9327        this.update(&mut cx, |this, cx| {
 9328            if let Some((upstream_client, upstream_project_id)) = this.upstream_client() {
 9329                return upstream_client.send(proto::RegisterBufferWithLanguageServers {
 9330                    project_id: upstream_project_id,
 9331                    buffer_id: buffer_id.to_proto(),
 9332                    only_servers: envelope.payload.only_servers,
 9333                });
 9334            }
 9335
 9336            let Some(buffer) = this.buffer_store().read(cx).get(buffer_id) else {
 9337                anyhow::bail!("buffer is not open");
 9338            };
 9339
 9340            let handle = this.register_buffer_with_language_servers(
 9341                &buffer,
 9342                envelope
 9343                    .payload
 9344                    .only_servers
 9345                    .into_iter()
 9346                    .filter_map(|selector| {
 9347                        Some(match selector.selector? {
 9348                            proto::language_server_selector::Selector::ServerId(server_id) => {
 9349                                LanguageServerSelector::Id(LanguageServerId::from_proto(server_id))
 9350                            }
 9351                            proto::language_server_selector::Selector::Name(name) => {
 9352                                LanguageServerSelector::Name(LanguageServerName(
 9353                                    SharedString::from(name),
 9354                                ))
 9355                            }
 9356                        })
 9357                    })
 9358                    .collect(),
 9359                false,
 9360                cx,
 9361            );
 9362            // Pull diagnostics for the buffer even if it was already registered.
 9363            // This is needed to make test_streamed_lsp_pull_diagnostics pass,
 9364            // but it's unclear if we need it.
 9365            this.pull_diagnostics_for_buffer(buffer.clone(), cx)
 9366                .detach();
 9367            this.buffer_store().update(cx, |buffer_store, _| {
 9368                buffer_store.register_shared_lsp_handle(peer_id, buffer_id, handle);
 9369            });
 9370
 9371            Ok(())
 9372        })?;
 9373        Ok(proto::Ack {})
 9374    }
 9375
 9376    async fn handle_rename_project_entry(
 9377        this: Entity<Self>,
 9378        envelope: TypedEnvelope<proto::RenameProjectEntry>,
 9379        mut cx: AsyncApp,
 9380    ) -> Result<proto::ProjectEntryResponse> {
 9381        let entry_id = ProjectEntryId::from_proto(envelope.payload.entry_id);
 9382        let new_worktree_id = WorktreeId::from_proto(envelope.payload.new_worktree_id);
 9383        let new_path =
 9384            RelPath::from_proto(&envelope.payload.new_path).context("invalid relative path")?;
 9385
 9386        let (worktree_store, old_worktree, new_worktree, old_entry) = this
 9387            .update(&mut cx, |this, cx| {
 9388                let (worktree, entry) = this
 9389                    .worktree_store
 9390                    .read(cx)
 9391                    .worktree_and_entry_for_id(entry_id, cx)?;
 9392                let new_worktree = this
 9393                    .worktree_store
 9394                    .read(cx)
 9395                    .worktree_for_id(new_worktree_id, cx)?;
 9396                Some((
 9397                    this.worktree_store.clone(),
 9398                    worktree,
 9399                    new_worktree,
 9400                    entry.clone(),
 9401                ))
 9402            })
 9403            .context("worktree not found")?;
 9404        let (old_abs_path, old_worktree_id) = old_worktree.read_with(&cx, |worktree, _| {
 9405            (worktree.absolutize(&old_entry.path), worktree.id())
 9406        });
 9407        let new_abs_path =
 9408            new_worktree.read_with(&cx, |worktree, _| worktree.absolutize(&new_path));
 9409
 9410        let _transaction = Self::will_rename_entry(
 9411            this.downgrade(),
 9412            old_worktree_id,
 9413            &old_abs_path,
 9414            &new_abs_path,
 9415            old_entry.is_dir(),
 9416            cx.clone(),
 9417        )
 9418        .await;
 9419        let response = WorktreeStore::handle_rename_project_entry(
 9420            worktree_store,
 9421            envelope.payload,
 9422            cx.clone(),
 9423        )
 9424        .await;
 9425        this.read_with(&cx, |this, _| {
 9426            this.did_rename_entry(
 9427                old_worktree_id,
 9428                &old_abs_path,
 9429                &new_abs_path,
 9430                old_entry.is_dir(),
 9431            );
 9432        });
 9433        response
 9434    }
 9435
 9436    async fn handle_update_diagnostic_summary(
 9437        this: Entity<Self>,
 9438        envelope: TypedEnvelope<proto::UpdateDiagnosticSummary>,
 9439        mut cx: AsyncApp,
 9440    ) -> Result<()> {
 9441        this.update(&mut cx, |lsp_store, cx| {
 9442            let worktree_id = WorktreeId::from_proto(envelope.payload.worktree_id);
 9443            let mut updated_diagnostics_paths = HashMap::default();
 9444            let mut diagnostics_summary = None::<proto::UpdateDiagnosticSummary>;
 9445            for message_summary in envelope
 9446                .payload
 9447                .summary
 9448                .into_iter()
 9449                .chain(envelope.payload.more_summaries)
 9450            {
 9451                let project_path = ProjectPath {
 9452                    worktree_id,
 9453                    path: RelPath::from_proto(&message_summary.path).context("invalid path")?,
 9454                };
 9455                let path = project_path.path.clone();
 9456                let server_id = LanguageServerId(message_summary.language_server_id as usize);
 9457                let summary = DiagnosticSummary {
 9458                    error_count: message_summary.error_count as usize,
 9459                    warning_count: message_summary.warning_count as usize,
 9460                };
 9461
 9462                if summary.is_empty() {
 9463                    if let Some(worktree_summaries) =
 9464                        lsp_store.diagnostic_summaries.get_mut(&worktree_id)
 9465                        && let Some(summaries) = worktree_summaries.get_mut(&path)
 9466                    {
 9467                        summaries.remove(&server_id);
 9468                        if summaries.is_empty() {
 9469                            worktree_summaries.remove(&path);
 9470                        }
 9471                    }
 9472                } else {
 9473                    lsp_store
 9474                        .diagnostic_summaries
 9475                        .entry(worktree_id)
 9476                        .or_default()
 9477                        .entry(path)
 9478                        .or_default()
 9479                        .insert(server_id, summary);
 9480                }
 9481
 9482                if let Some((_, project_id)) = &lsp_store.downstream_client {
 9483                    match &mut diagnostics_summary {
 9484                        Some(diagnostics_summary) => {
 9485                            diagnostics_summary
 9486                                .more_summaries
 9487                                .push(proto::DiagnosticSummary {
 9488                                    path: project_path.path.as_ref().to_proto(),
 9489                                    language_server_id: server_id.0 as u64,
 9490                                    error_count: summary.error_count as u32,
 9491                                    warning_count: summary.warning_count as u32,
 9492                                })
 9493                        }
 9494                        None => {
 9495                            diagnostics_summary = Some(proto::UpdateDiagnosticSummary {
 9496                                project_id: *project_id,
 9497                                worktree_id: worktree_id.to_proto(),
 9498                                summary: Some(proto::DiagnosticSummary {
 9499                                    path: project_path.path.as_ref().to_proto(),
 9500                                    language_server_id: server_id.0 as u64,
 9501                                    error_count: summary.error_count as u32,
 9502                                    warning_count: summary.warning_count as u32,
 9503                                }),
 9504                                more_summaries: Vec::new(),
 9505                            })
 9506                        }
 9507                    }
 9508                }
 9509                updated_diagnostics_paths
 9510                    .entry(server_id)
 9511                    .or_insert_with(Vec::new)
 9512                    .push(project_path);
 9513            }
 9514
 9515            if let Some((diagnostics_summary, (downstream_client, _))) =
 9516                diagnostics_summary.zip(lsp_store.downstream_client.as_ref())
 9517            {
 9518                downstream_client.send(diagnostics_summary).log_err();
 9519            }
 9520            for (server_id, paths) in updated_diagnostics_paths {
 9521                cx.emit(LspStoreEvent::DiagnosticsUpdated { server_id, paths });
 9522            }
 9523            Ok(())
 9524        })
 9525    }
 9526
 9527    async fn handle_start_language_server(
 9528        lsp_store: Entity<Self>,
 9529        envelope: TypedEnvelope<proto::StartLanguageServer>,
 9530        mut cx: AsyncApp,
 9531    ) -> Result<()> {
 9532        let server = envelope.payload.server.context("invalid server")?;
 9533        let server_capabilities =
 9534            serde_json::from_str::<lsp::ServerCapabilities>(&envelope.payload.capabilities)
 9535                .with_context(|| {
 9536                    format!(
 9537                        "incorrect server capabilities {}",
 9538                        envelope.payload.capabilities
 9539                    )
 9540                })?;
 9541        lsp_store.update(&mut cx, |lsp_store, cx| {
 9542            let server_id = LanguageServerId(server.id as usize);
 9543            let server_name = LanguageServerName::from_proto(server.name.clone());
 9544            lsp_store
 9545                .lsp_server_capabilities
 9546                .insert(server_id, server_capabilities);
 9547            lsp_store.language_server_statuses.insert(
 9548                server_id,
 9549                LanguageServerStatus {
 9550                    name: server_name.clone(),
 9551                    server_version: None,
 9552                    pending_work: Default::default(),
 9553                    has_pending_diagnostic_updates: false,
 9554                    progress_tokens: Default::default(),
 9555                    worktree: server.worktree_id.map(WorktreeId::from_proto),
 9556                    binary: None,
 9557                    configuration: None,
 9558                    workspace_folders: BTreeSet::new(),
 9559                    process_id: None,
 9560                },
 9561            );
 9562            cx.emit(LspStoreEvent::LanguageServerAdded(
 9563                server_id,
 9564                server_name,
 9565                server.worktree_id.map(WorktreeId::from_proto),
 9566            ));
 9567            cx.notify();
 9568        });
 9569        Ok(())
 9570    }
 9571
 9572    async fn handle_update_language_server(
 9573        lsp_store: Entity<Self>,
 9574        envelope: TypedEnvelope<proto::UpdateLanguageServer>,
 9575        mut cx: AsyncApp,
 9576    ) -> Result<()> {
 9577        lsp_store.update(&mut cx, |lsp_store, cx| {
 9578            let language_server_id = LanguageServerId(envelope.payload.language_server_id as usize);
 9579
 9580            match envelope.payload.variant.context("invalid variant")? {
 9581                proto::update_language_server::Variant::WorkStart(payload) => {
 9582                    lsp_store.on_lsp_work_start(
 9583                        language_server_id,
 9584                        ProgressToken::from_proto(payload.token.context("missing progress token")?)
 9585                            .context("invalid progress token value")?,
 9586                        LanguageServerProgress {
 9587                            title: payload.title,
 9588                            is_disk_based_diagnostics_progress: false,
 9589                            is_cancellable: payload.is_cancellable.unwrap_or(false),
 9590                            message: payload.message,
 9591                            percentage: payload.percentage.map(|p| p as usize),
 9592                            last_update_at: cx.background_executor().now(),
 9593                        },
 9594                        cx,
 9595                    );
 9596                }
 9597                proto::update_language_server::Variant::WorkProgress(payload) => {
 9598                    lsp_store.on_lsp_work_progress(
 9599                        language_server_id,
 9600                        ProgressToken::from_proto(payload.token.context("missing progress token")?)
 9601                            .context("invalid progress token value")?,
 9602                        LanguageServerProgress {
 9603                            title: None,
 9604                            is_disk_based_diagnostics_progress: false,
 9605                            is_cancellable: payload.is_cancellable.unwrap_or(false),
 9606                            message: payload.message,
 9607                            percentage: payload.percentage.map(|p| p as usize),
 9608                            last_update_at: cx.background_executor().now(),
 9609                        },
 9610                        cx,
 9611                    );
 9612                }
 9613
 9614                proto::update_language_server::Variant::WorkEnd(payload) => {
 9615                    lsp_store.on_lsp_work_end(
 9616                        language_server_id,
 9617                        ProgressToken::from_proto(payload.token.context("missing progress token")?)
 9618                            .context("invalid progress token value")?,
 9619                        cx,
 9620                    );
 9621                }
 9622
 9623                proto::update_language_server::Variant::DiskBasedDiagnosticsUpdating(_) => {
 9624                    lsp_store.disk_based_diagnostics_started(language_server_id, cx);
 9625                }
 9626
 9627                proto::update_language_server::Variant::DiskBasedDiagnosticsUpdated(_) => {
 9628                    lsp_store.disk_based_diagnostics_finished(language_server_id, cx)
 9629                }
 9630
 9631                non_lsp @ proto::update_language_server::Variant::StatusUpdate(_)
 9632                | non_lsp @ proto::update_language_server::Variant::RegisteredForBuffer(_)
 9633                | non_lsp @ proto::update_language_server::Variant::MetadataUpdated(_) => {
 9634                    cx.emit(LspStoreEvent::LanguageServerUpdate {
 9635                        language_server_id,
 9636                        name: envelope
 9637                            .payload
 9638                            .server_name
 9639                            .map(SharedString::new)
 9640                            .map(LanguageServerName),
 9641                        message: non_lsp,
 9642                    });
 9643                }
 9644            }
 9645
 9646            Ok(())
 9647        })
 9648    }
 9649
 9650    async fn handle_language_server_log(
 9651        this: Entity<Self>,
 9652        envelope: TypedEnvelope<proto::LanguageServerLog>,
 9653        mut cx: AsyncApp,
 9654    ) -> Result<()> {
 9655        let language_server_id = LanguageServerId(envelope.payload.language_server_id as usize);
 9656        let log_type = envelope
 9657            .payload
 9658            .log_type
 9659            .map(LanguageServerLogType::from_proto)
 9660            .context("invalid language server log type")?;
 9661
 9662        let message = envelope.payload.message;
 9663
 9664        this.update(&mut cx, |_, cx| {
 9665            cx.emit(LspStoreEvent::LanguageServerLog(
 9666                language_server_id,
 9667                log_type,
 9668                message,
 9669            ));
 9670        });
 9671        Ok(())
 9672    }
 9673
 9674    async fn handle_lsp_ext_cancel_flycheck(
 9675        lsp_store: Entity<Self>,
 9676        envelope: TypedEnvelope<proto::LspExtCancelFlycheck>,
 9677        cx: AsyncApp,
 9678    ) -> Result<proto::Ack> {
 9679        let server_id = LanguageServerId(envelope.payload.language_server_id as usize);
 9680        let task = lsp_store.read_with(&cx, |lsp_store, _| {
 9681            if let Some(server) = lsp_store.language_server_for_id(server_id) {
 9682                Some(server.notify::<lsp_store::lsp_ext_command::LspExtCancelFlycheck>(()))
 9683            } else {
 9684                None
 9685            }
 9686        });
 9687        if let Some(task) = task {
 9688            task.context("handling lsp ext cancel flycheck")?;
 9689        }
 9690
 9691        Ok(proto::Ack {})
 9692    }
 9693
 9694    async fn handle_lsp_ext_run_flycheck(
 9695        lsp_store: Entity<Self>,
 9696        envelope: TypedEnvelope<proto::LspExtRunFlycheck>,
 9697        mut cx: AsyncApp,
 9698    ) -> Result<proto::Ack> {
 9699        let server_id = LanguageServerId(envelope.payload.language_server_id as usize);
 9700        lsp_store.update(&mut cx, |lsp_store, cx| {
 9701            if let Some(server) = lsp_store.language_server_for_id(server_id) {
 9702                let text_document = if envelope.payload.current_file_only {
 9703                    let buffer_id = envelope
 9704                        .payload
 9705                        .buffer_id
 9706                        .map(|id| BufferId::new(id))
 9707                        .transpose()?;
 9708                    buffer_id
 9709                        .and_then(|buffer_id| {
 9710                            lsp_store
 9711                                .buffer_store()
 9712                                .read(cx)
 9713                                .get(buffer_id)
 9714                                .and_then(|buffer| {
 9715                                    Some(buffer.read(cx).file()?.as_local()?.abs_path(cx))
 9716                                })
 9717                                .map(|path| make_text_document_identifier(&path))
 9718                        })
 9719                        .transpose()?
 9720                } else {
 9721                    None
 9722                };
 9723                server.notify::<lsp_store::lsp_ext_command::LspExtRunFlycheck>(
 9724                    lsp_store::lsp_ext_command::RunFlycheckParams { text_document },
 9725                )?;
 9726            }
 9727            anyhow::Ok(())
 9728        })?;
 9729
 9730        Ok(proto::Ack {})
 9731    }
 9732
 9733    async fn handle_lsp_ext_clear_flycheck(
 9734        lsp_store: Entity<Self>,
 9735        envelope: TypedEnvelope<proto::LspExtClearFlycheck>,
 9736        cx: AsyncApp,
 9737    ) -> Result<proto::Ack> {
 9738        let server_id = LanguageServerId(envelope.payload.language_server_id as usize);
 9739        lsp_store.read_with(&cx, |lsp_store, _| {
 9740            if let Some(server) = lsp_store.language_server_for_id(server_id) {
 9741                Some(server.notify::<lsp_store::lsp_ext_command::LspExtClearFlycheck>(()))
 9742            } else {
 9743                None
 9744            }
 9745        });
 9746
 9747        Ok(proto::Ack {})
 9748    }
 9749
 9750    pub fn disk_based_diagnostics_started(
 9751        &mut self,
 9752        language_server_id: LanguageServerId,
 9753        cx: &mut Context<Self>,
 9754    ) {
 9755        if let Some(language_server_status) =
 9756            self.language_server_statuses.get_mut(&language_server_id)
 9757        {
 9758            language_server_status.has_pending_diagnostic_updates = true;
 9759        }
 9760
 9761        cx.emit(LspStoreEvent::DiskBasedDiagnosticsStarted { language_server_id });
 9762        cx.emit(LspStoreEvent::LanguageServerUpdate {
 9763            language_server_id,
 9764            name: self
 9765                .language_server_adapter_for_id(language_server_id)
 9766                .map(|adapter| adapter.name()),
 9767            message: proto::update_language_server::Variant::DiskBasedDiagnosticsUpdating(
 9768                Default::default(),
 9769            ),
 9770        })
 9771    }
 9772
 9773    pub fn disk_based_diagnostics_finished(
 9774        &mut self,
 9775        language_server_id: LanguageServerId,
 9776        cx: &mut Context<Self>,
 9777    ) {
 9778        if let Some(language_server_status) =
 9779            self.language_server_statuses.get_mut(&language_server_id)
 9780        {
 9781            language_server_status.has_pending_diagnostic_updates = false;
 9782        }
 9783
 9784        cx.emit(LspStoreEvent::DiskBasedDiagnosticsFinished { language_server_id });
 9785        cx.emit(LspStoreEvent::LanguageServerUpdate {
 9786            language_server_id,
 9787            name: self
 9788                .language_server_adapter_for_id(language_server_id)
 9789                .map(|adapter| adapter.name()),
 9790            message: proto::update_language_server::Variant::DiskBasedDiagnosticsUpdated(
 9791                Default::default(),
 9792            ),
 9793        })
 9794    }
 9795
 9796    // After saving a buffer using a language server that doesn't provide a disk-based progress token,
 9797    // kick off a timer that will reset every time the buffer is saved. If the timer eventually fires,
 9798    // simulate disk-based diagnostics being finished so that other pieces of UI (e.g., project
 9799    // diagnostics view, diagnostic status bar) can update. We don't emit an event right away because
 9800    // the language server might take some time to publish diagnostics.
 9801    fn simulate_disk_based_diagnostics_events_if_needed(
 9802        &mut self,
 9803        language_server_id: LanguageServerId,
 9804        cx: &mut Context<Self>,
 9805    ) {
 9806        const DISK_BASED_DIAGNOSTICS_DEBOUNCE: Duration = Duration::from_secs(1);
 9807
 9808        let Some(LanguageServerState::Running {
 9809            simulate_disk_based_diagnostics_completion,
 9810            adapter,
 9811            ..
 9812        }) = self
 9813            .as_local_mut()
 9814            .and_then(|local_store| local_store.language_servers.get_mut(&language_server_id))
 9815        else {
 9816            return;
 9817        };
 9818
 9819        if adapter.disk_based_diagnostics_progress_token.is_some() {
 9820            return;
 9821        }
 9822
 9823        let prev_task =
 9824            simulate_disk_based_diagnostics_completion.replace(cx.spawn(async move |this, cx| {
 9825                cx.background_executor()
 9826                    .timer(DISK_BASED_DIAGNOSTICS_DEBOUNCE)
 9827                    .await;
 9828
 9829                this.update(cx, |this, cx| {
 9830                    this.disk_based_diagnostics_finished(language_server_id, cx);
 9831
 9832                    if let Some(LanguageServerState::Running {
 9833                        simulate_disk_based_diagnostics_completion,
 9834                        ..
 9835                    }) = this.as_local_mut().and_then(|local_store| {
 9836                        local_store.language_servers.get_mut(&language_server_id)
 9837                    }) {
 9838                        *simulate_disk_based_diagnostics_completion = None;
 9839                    }
 9840                })
 9841                .ok();
 9842            }));
 9843
 9844        if prev_task.is_none() {
 9845            self.disk_based_diagnostics_started(language_server_id, cx);
 9846        }
 9847    }
 9848
 9849    pub fn language_server_statuses(
 9850        &self,
 9851    ) -> impl DoubleEndedIterator<Item = (LanguageServerId, &LanguageServerStatus)> {
 9852        self.language_server_statuses
 9853            .iter()
 9854            .map(|(key, value)| (*key, value))
 9855    }
 9856
 9857    pub(super) fn did_rename_entry(
 9858        &self,
 9859        worktree_id: WorktreeId,
 9860        old_path: &Path,
 9861        new_path: &Path,
 9862        is_dir: bool,
 9863    ) {
 9864        maybe!({
 9865            let local_store = self.as_local()?;
 9866
 9867            let old_uri = lsp::Uri::from_file_path(old_path)
 9868                .ok()
 9869                .map(|uri| uri.to_string())?;
 9870            let new_uri = lsp::Uri::from_file_path(new_path)
 9871                .ok()
 9872                .map(|uri| uri.to_string())?;
 9873
 9874            for language_server in local_store.language_servers_for_worktree(worktree_id) {
 9875                let Some(filter) = local_store
 9876                    .language_server_paths_watched_for_rename
 9877                    .get(&language_server.server_id())
 9878                else {
 9879                    continue;
 9880                };
 9881
 9882                if filter.should_send_did_rename(&old_uri, is_dir) {
 9883                    language_server
 9884                        .notify::<DidRenameFiles>(RenameFilesParams {
 9885                            files: vec![FileRename {
 9886                                old_uri: old_uri.clone(),
 9887                                new_uri: new_uri.clone(),
 9888                            }],
 9889                        })
 9890                        .ok();
 9891                }
 9892            }
 9893            Some(())
 9894        });
 9895    }
 9896
 9897    pub(super) fn will_rename_entry(
 9898        this: WeakEntity<Self>,
 9899        worktree_id: WorktreeId,
 9900        old_path: &Path,
 9901        new_path: &Path,
 9902        is_dir: bool,
 9903        cx: AsyncApp,
 9904    ) -> Task<ProjectTransaction> {
 9905        let old_uri = lsp::Uri::from_file_path(old_path)
 9906            .ok()
 9907            .map(|uri| uri.to_string());
 9908        let new_uri = lsp::Uri::from_file_path(new_path)
 9909            .ok()
 9910            .map(|uri| uri.to_string());
 9911        cx.spawn(async move |cx| {
 9912            let mut tasks = vec![];
 9913            this.update(cx, |this, cx| {
 9914                let local_store = this.as_local()?;
 9915                let old_uri = old_uri?;
 9916                let new_uri = new_uri?;
 9917                for language_server in local_store.language_servers_for_worktree(worktree_id) {
 9918                    let Some(filter) = local_store
 9919                        .language_server_paths_watched_for_rename
 9920                        .get(&language_server.server_id())
 9921                    else {
 9922                        continue;
 9923                    };
 9924
 9925                    if filter.should_send_will_rename(&old_uri, is_dir) {
 9926                        let apply_edit = cx.spawn({
 9927                            let old_uri = old_uri.clone();
 9928                            let new_uri = new_uri.clone();
 9929                            let language_server = language_server.clone();
 9930                            async move |this, cx| {
 9931                                let edit = language_server
 9932                                    .request::<WillRenameFiles>(RenameFilesParams {
 9933                                        files: vec![FileRename { old_uri, new_uri }],
 9934                                    })
 9935                                    .await
 9936                                    .into_response()
 9937                                    .context("will rename files")
 9938                                    .log_err()
 9939                                    .flatten()?;
 9940
 9941                                let transaction = LocalLspStore::deserialize_workspace_edit(
 9942                                    this.upgrade()?,
 9943                                    edit,
 9944                                    false,
 9945                                    language_server.clone(),
 9946                                    cx,
 9947                                )
 9948                                .await
 9949                                .ok()?;
 9950                                Some(transaction)
 9951                            }
 9952                        });
 9953                        tasks.push(apply_edit);
 9954                    }
 9955                }
 9956                Some(())
 9957            })
 9958            .ok()
 9959            .flatten();
 9960            let mut merged_transaction = ProjectTransaction::default();
 9961            for task in tasks {
 9962                // Await on tasks sequentially so that the order of application of edits is deterministic
 9963                // (at least with regards to the order of registration of language servers)
 9964                if let Some(transaction) = task.await {
 9965                    for (buffer, buffer_transaction) in transaction.0 {
 9966                        merged_transaction.0.insert(buffer, buffer_transaction);
 9967                    }
 9968                }
 9969            }
 9970            merged_transaction
 9971        })
 9972    }
 9973
 9974    fn lsp_notify_abs_paths_changed(
 9975        &mut self,
 9976        server_id: LanguageServerId,
 9977        changes: Vec<PathEvent>,
 9978    ) {
 9979        maybe!({
 9980            let server = self.language_server_for_id(server_id)?;
 9981            let changes = changes
 9982                .into_iter()
 9983                .filter_map(|event| {
 9984                    let typ = match event.kind? {
 9985                        PathEventKind::Created => lsp::FileChangeType::CREATED,
 9986                        PathEventKind::Removed => lsp::FileChangeType::DELETED,
 9987                        PathEventKind::Changed => lsp::FileChangeType::CHANGED,
 9988                    };
 9989                    Some(lsp::FileEvent {
 9990                        uri: file_path_to_lsp_url(&event.path).log_err()?,
 9991                        typ,
 9992                    })
 9993                })
 9994                .collect::<Vec<_>>();
 9995            if !changes.is_empty() {
 9996                server
 9997                    .notify::<lsp::notification::DidChangeWatchedFiles>(
 9998                        lsp::DidChangeWatchedFilesParams { changes },
 9999                    )
10000                    .ok();
10001            }
10002            Some(())
10003        });
10004    }
10005
10006    pub fn language_server_for_id(&self, id: LanguageServerId) -> Option<Arc<LanguageServer>> {
10007        self.as_local()?.language_server_for_id(id)
10008    }
10009
10010    fn on_lsp_progress(
10011        &mut self,
10012        progress_params: lsp::ProgressParams,
10013        language_server_id: LanguageServerId,
10014        disk_based_diagnostics_progress_token: Option<String>,
10015        cx: &mut Context<Self>,
10016    ) {
10017        match progress_params.value {
10018            lsp::ProgressParamsValue::WorkDone(progress) => {
10019                self.handle_work_done_progress(
10020                    progress,
10021                    language_server_id,
10022                    disk_based_diagnostics_progress_token,
10023                    ProgressToken::from_lsp(progress_params.token),
10024                    cx,
10025                );
10026            }
10027            lsp::ProgressParamsValue::WorkspaceDiagnostic(report) => {
10028                let registration_id = match progress_params.token {
10029                    lsp::NumberOrString::Number(_) => None,
10030                    lsp::NumberOrString::String(token) => token
10031                        .split_once(WORKSPACE_DIAGNOSTICS_TOKEN_START)
10032                        .map(|(_, id)| id.to_owned()),
10033                };
10034                if let Some(LanguageServerState::Running {
10035                    workspace_diagnostics_refresh_tasks,
10036                    ..
10037                }) = self
10038                    .as_local_mut()
10039                    .and_then(|local| local.language_servers.get_mut(&language_server_id))
10040                    && let Some(workspace_diagnostics) =
10041                        workspace_diagnostics_refresh_tasks.get_mut(&registration_id)
10042                {
10043                    workspace_diagnostics.progress_tx.try_send(()).ok();
10044                    self.apply_workspace_diagnostic_report(
10045                        language_server_id,
10046                        report,
10047                        registration_id.map(SharedString::from),
10048                        cx,
10049                    )
10050                }
10051            }
10052        }
10053    }
10054
10055    fn handle_work_done_progress(
10056        &mut self,
10057        progress: lsp::WorkDoneProgress,
10058        language_server_id: LanguageServerId,
10059        disk_based_diagnostics_progress_token: Option<String>,
10060        token: ProgressToken,
10061        cx: &mut Context<Self>,
10062    ) {
10063        let language_server_status =
10064            if let Some(status) = self.language_server_statuses.get_mut(&language_server_id) {
10065                status
10066            } else {
10067                return;
10068            };
10069
10070        if !language_server_status.progress_tokens.contains(&token) {
10071            return;
10072        }
10073
10074        let is_disk_based_diagnostics_progress =
10075            if let (Some(disk_based_token), ProgressToken::String(token)) =
10076                (&disk_based_diagnostics_progress_token, &token)
10077            {
10078                token.starts_with(disk_based_token)
10079            } else {
10080                false
10081            };
10082
10083        match progress {
10084            lsp::WorkDoneProgress::Begin(report) => {
10085                if is_disk_based_diagnostics_progress {
10086                    self.disk_based_diagnostics_started(language_server_id, cx);
10087                }
10088                self.on_lsp_work_start(
10089                    language_server_id,
10090                    token.clone(),
10091                    LanguageServerProgress {
10092                        title: Some(report.title),
10093                        is_disk_based_diagnostics_progress,
10094                        is_cancellable: report.cancellable.unwrap_or(false),
10095                        message: report.message.clone(),
10096                        percentage: report.percentage.map(|p| p as usize),
10097                        last_update_at: cx.background_executor().now(),
10098                    },
10099                    cx,
10100                );
10101            }
10102            lsp::WorkDoneProgress::Report(report) => self.on_lsp_work_progress(
10103                language_server_id,
10104                token,
10105                LanguageServerProgress {
10106                    title: None,
10107                    is_disk_based_diagnostics_progress,
10108                    is_cancellable: report.cancellable.unwrap_or(false),
10109                    message: report.message,
10110                    percentage: report.percentage.map(|p| p as usize),
10111                    last_update_at: cx.background_executor().now(),
10112                },
10113                cx,
10114            ),
10115            lsp::WorkDoneProgress::End(_) => {
10116                language_server_status.progress_tokens.remove(&token);
10117                self.on_lsp_work_end(language_server_id, token.clone(), cx);
10118                if is_disk_based_diagnostics_progress {
10119                    self.disk_based_diagnostics_finished(language_server_id, cx);
10120                }
10121            }
10122        }
10123    }
10124
10125    fn on_lsp_work_start(
10126        &mut self,
10127        language_server_id: LanguageServerId,
10128        token: ProgressToken,
10129        progress: LanguageServerProgress,
10130        cx: &mut Context<Self>,
10131    ) {
10132        if let Some(status) = self.language_server_statuses.get_mut(&language_server_id) {
10133            status.pending_work.insert(token.clone(), progress.clone());
10134            cx.notify();
10135        }
10136        cx.emit(LspStoreEvent::LanguageServerUpdate {
10137            language_server_id,
10138            name: self
10139                .language_server_adapter_for_id(language_server_id)
10140                .map(|adapter| adapter.name()),
10141            message: proto::update_language_server::Variant::WorkStart(proto::LspWorkStart {
10142                token: Some(token.to_proto()),
10143                title: progress.title,
10144                message: progress.message,
10145                percentage: progress.percentage.map(|p| p as u32),
10146                is_cancellable: Some(progress.is_cancellable),
10147            }),
10148        })
10149    }
10150
10151    fn on_lsp_work_progress(
10152        &mut self,
10153        language_server_id: LanguageServerId,
10154        token: ProgressToken,
10155        progress: LanguageServerProgress,
10156        cx: &mut Context<Self>,
10157    ) {
10158        let mut did_update = false;
10159        if let Some(status) = self.language_server_statuses.get_mut(&language_server_id) {
10160            match status.pending_work.entry(token.clone()) {
10161                btree_map::Entry::Vacant(entry) => {
10162                    entry.insert(progress.clone());
10163                    did_update = true;
10164                }
10165                btree_map::Entry::Occupied(mut entry) => {
10166                    let entry = entry.get_mut();
10167                    if (progress.last_update_at - entry.last_update_at)
10168                        >= SERVER_PROGRESS_THROTTLE_TIMEOUT
10169                    {
10170                        entry.last_update_at = progress.last_update_at;
10171                        if progress.message.is_some() {
10172                            entry.message = progress.message.clone();
10173                        }
10174                        if progress.percentage.is_some() {
10175                            entry.percentage = progress.percentage;
10176                        }
10177                        if progress.is_cancellable != entry.is_cancellable {
10178                            entry.is_cancellable = progress.is_cancellable;
10179                        }
10180                        did_update = true;
10181                    }
10182                }
10183            }
10184        }
10185
10186        if did_update {
10187            cx.emit(LspStoreEvent::LanguageServerUpdate {
10188                language_server_id,
10189                name: self
10190                    .language_server_adapter_for_id(language_server_id)
10191                    .map(|adapter| adapter.name()),
10192                message: proto::update_language_server::Variant::WorkProgress(
10193                    proto::LspWorkProgress {
10194                        token: Some(token.to_proto()),
10195                        message: progress.message,
10196                        percentage: progress.percentage.map(|p| p as u32),
10197                        is_cancellable: Some(progress.is_cancellable),
10198                    },
10199                ),
10200            })
10201        }
10202    }
10203
10204    fn on_lsp_work_end(
10205        &mut self,
10206        language_server_id: LanguageServerId,
10207        token: ProgressToken,
10208        cx: &mut Context<Self>,
10209    ) {
10210        if let Some(status) = self.language_server_statuses.get_mut(&language_server_id) {
10211            if let Some(work) = status.pending_work.remove(&token)
10212                && !work.is_disk_based_diagnostics_progress
10213            {
10214                cx.emit(LspStoreEvent::RefreshInlayHints {
10215                    server_id: language_server_id,
10216                    request_id: None,
10217                });
10218            }
10219            cx.notify();
10220        }
10221
10222        cx.emit(LspStoreEvent::LanguageServerUpdate {
10223            language_server_id,
10224            name: self
10225                .language_server_adapter_for_id(language_server_id)
10226                .map(|adapter| adapter.name()),
10227            message: proto::update_language_server::Variant::WorkEnd(proto::LspWorkEnd {
10228                token: Some(token.to_proto()),
10229            }),
10230        })
10231    }
10232
10233    pub async fn handle_resolve_completion_documentation(
10234        this: Entity<Self>,
10235        envelope: TypedEnvelope<proto::ResolveCompletionDocumentation>,
10236        mut cx: AsyncApp,
10237    ) -> Result<proto::ResolveCompletionDocumentationResponse> {
10238        let lsp_completion = serde_json::from_slice(&envelope.payload.lsp_completion)?;
10239
10240        let completion = this
10241            .read_with(&cx, |this, cx| {
10242                let id = LanguageServerId(envelope.payload.language_server_id as usize);
10243                let server = this
10244                    .language_server_for_id(id)
10245                    .with_context(|| format!("No language server {id}"))?;
10246
10247                anyhow::Ok(cx.background_spawn(async move {
10248                    let can_resolve = server
10249                        .capabilities()
10250                        .completion_provider
10251                        .as_ref()
10252                        .and_then(|options| options.resolve_provider)
10253                        .unwrap_or(false);
10254                    if can_resolve {
10255                        server
10256                            .request::<lsp::request::ResolveCompletionItem>(lsp_completion)
10257                            .await
10258                            .into_response()
10259                            .context("resolve completion item")
10260                    } else {
10261                        anyhow::Ok(lsp_completion)
10262                    }
10263                }))
10264            })?
10265            .await?;
10266
10267        let mut documentation_is_markdown = false;
10268        let lsp_completion = serde_json::to_string(&completion)?.into_bytes();
10269        let documentation = match completion.documentation {
10270            Some(lsp::Documentation::String(text)) => text,
10271
10272            Some(lsp::Documentation::MarkupContent(lsp::MarkupContent { kind, value })) => {
10273                documentation_is_markdown = kind == lsp::MarkupKind::Markdown;
10274                value
10275            }
10276
10277            _ => String::new(),
10278        };
10279
10280        // If we have a new buffer_id, that means we're talking to a new client
10281        // and want to check for new text_edits in the completion too.
10282        let mut old_replace_start = None;
10283        let mut old_replace_end = None;
10284        let mut old_insert_start = None;
10285        let mut old_insert_end = None;
10286        let mut new_text = String::default();
10287        if let Ok(buffer_id) = BufferId::new(envelope.payload.buffer_id) {
10288            let buffer_snapshot = this.update(&mut cx, |this, cx| {
10289                let buffer = this.buffer_store.read(cx).get_existing(buffer_id)?;
10290                anyhow::Ok(buffer.read(cx).snapshot())
10291            })?;
10292
10293            if let Some(text_edit) = completion.text_edit.as_ref() {
10294                let edit = parse_completion_text_edit(text_edit, &buffer_snapshot);
10295
10296                if let Some(mut edit) = edit {
10297                    LineEnding::normalize(&mut edit.new_text);
10298
10299                    new_text = edit.new_text;
10300                    old_replace_start = Some(serialize_anchor(&edit.replace_range.start));
10301                    old_replace_end = Some(serialize_anchor(&edit.replace_range.end));
10302                    if let Some(insert_range) = edit.insert_range {
10303                        old_insert_start = Some(serialize_anchor(&insert_range.start));
10304                        old_insert_end = Some(serialize_anchor(&insert_range.end));
10305                    }
10306                }
10307            }
10308        }
10309
10310        Ok(proto::ResolveCompletionDocumentationResponse {
10311            documentation,
10312            documentation_is_markdown,
10313            old_replace_start,
10314            old_replace_end,
10315            new_text,
10316            lsp_completion,
10317            old_insert_start,
10318            old_insert_end,
10319        })
10320    }
10321
10322    async fn handle_on_type_formatting(
10323        this: Entity<Self>,
10324        envelope: TypedEnvelope<proto::OnTypeFormatting>,
10325        mut cx: AsyncApp,
10326    ) -> Result<proto::OnTypeFormattingResponse> {
10327        let on_type_formatting = this.update(&mut cx, |this, cx| {
10328            let buffer_id = BufferId::new(envelope.payload.buffer_id)?;
10329            let buffer = this.buffer_store.read(cx).get_existing(buffer_id)?;
10330            let position = envelope
10331                .payload
10332                .position
10333                .and_then(deserialize_anchor)
10334                .context("invalid position")?;
10335            anyhow::Ok(this.apply_on_type_formatting(
10336                buffer,
10337                position,
10338                envelope.payload.trigger.clone(),
10339                cx,
10340            ))
10341        })?;
10342
10343        let transaction = on_type_formatting
10344            .await?
10345            .as_ref()
10346            .map(language::proto::serialize_transaction);
10347        Ok(proto::OnTypeFormattingResponse { transaction })
10348    }
10349
10350    async fn handle_refresh_inlay_hints(
10351        lsp_store: Entity<Self>,
10352        envelope: TypedEnvelope<proto::RefreshInlayHints>,
10353        mut cx: AsyncApp,
10354    ) -> Result<proto::Ack> {
10355        lsp_store.update(&mut cx, |_, cx| {
10356            cx.emit(LspStoreEvent::RefreshInlayHints {
10357                server_id: LanguageServerId::from_proto(envelope.payload.server_id),
10358                request_id: envelope.payload.request_id.map(|id| id as usize),
10359            });
10360        });
10361        Ok(proto::Ack {})
10362    }
10363
10364    async fn handle_pull_workspace_diagnostics(
10365        lsp_store: Entity<Self>,
10366        envelope: TypedEnvelope<proto::PullWorkspaceDiagnostics>,
10367        mut cx: AsyncApp,
10368    ) -> Result<proto::Ack> {
10369        let server_id = LanguageServerId::from_proto(envelope.payload.server_id);
10370        lsp_store.update(&mut cx, |lsp_store, _| {
10371            lsp_store.pull_workspace_diagnostics(server_id);
10372        });
10373        Ok(proto::Ack {})
10374    }
10375
10376    async fn handle_get_color_presentation(
10377        lsp_store: Entity<Self>,
10378        envelope: TypedEnvelope<proto::GetColorPresentation>,
10379        mut cx: AsyncApp,
10380    ) -> Result<proto::GetColorPresentationResponse> {
10381        let buffer_id = BufferId::new(envelope.payload.buffer_id)?;
10382        let buffer = lsp_store.update(&mut cx, |lsp_store, cx| {
10383            lsp_store.buffer_store.read(cx).get_existing(buffer_id)
10384        })?;
10385
10386        let color = envelope
10387            .payload
10388            .color
10389            .context("invalid color resolve request")?;
10390        let start = color
10391            .lsp_range_start
10392            .context("invalid color resolve request")?;
10393        let end = color
10394            .lsp_range_end
10395            .context("invalid color resolve request")?;
10396
10397        let color = DocumentColor {
10398            lsp_range: lsp::Range {
10399                start: point_to_lsp(PointUtf16::new(start.row, start.column)),
10400                end: point_to_lsp(PointUtf16::new(end.row, end.column)),
10401            },
10402            color: lsp::Color {
10403                red: color.red,
10404                green: color.green,
10405                blue: color.blue,
10406                alpha: color.alpha,
10407            },
10408            resolved: false,
10409            color_presentations: Vec::new(),
10410        };
10411        let resolved_color = lsp_store
10412            .update(&mut cx, |lsp_store, cx| {
10413                lsp_store.resolve_color_presentation(
10414                    color,
10415                    buffer.clone(),
10416                    LanguageServerId(envelope.payload.server_id as usize),
10417                    cx,
10418                )
10419            })
10420            .await
10421            .context("resolving color presentation")?;
10422
10423        Ok(proto::GetColorPresentationResponse {
10424            presentations: resolved_color
10425                .color_presentations
10426                .into_iter()
10427                .map(|presentation| proto::ColorPresentation {
10428                    label: presentation.label.to_string(),
10429                    text_edit: presentation.text_edit.map(serialize_lsp_edit),
10430                    additional_text_edits: presentation
10431                        .additional_text_edits
10432                        .into_iter()
10433                        .map(serialize_lsp_edit)
10434                        .collect(),
10435                })
10436                .collect(),
10437        })
10438    }
10439
10440    async fn handle_resolve_inlay_hint(
10441        lsp_store: Entity<Self>,
10442        envelope: TypedEnvelope<proto::ResolveInlayHint>,
10443        mut cx: AsyncApp,
10444    ) -> Result<proto::ResolveInlayHintResponse> {
10445        let proto_hint = envelope
10446            .payload
10447            .hint
10448            .expect("incorrect protobuf resolve inlay hint message: missing the inlay hint");
10449        let hint = InlayHints::proto_to_project_hint(proto_hint)
10450            .context("resolved proto inlay hint conversion")?;
10451        let buffer = lsp_store.update(&mut cx, |lsp_store, cx| {
10452            let buffer_id = BufferId::new(envelope.payload.buffer_id)?;
10453            lsp_store.buffer_store.read(cx).get_existing(buffer_id)
10454        })?;
10455        let response_hint = lsp_store
10456            .update(&mut cx, |lsp_store, cx| {
10457                lsp_store.resolve_inlay_hint(
10458                    hint,
10459                    buffer,
10460                    LanguageServerId(envelope.payload.language_server_id as usize),
10461                    cx,
10462                )
10463            })
10464            .await
10465            .context("inlay hints fetch")?;
10466        Ok(proto::ResolveInlayHintResponse {
10467            hint: Some(InlayHints::project_to_proto_hint(response_hint)),
10468        })
10469    }
10470
10471    async fn handle_refresh_code_lens(
10472        this: Entity<Self>,
10473        _: TypedEnvelope<proto::RefreshCodeLens>,
10474        mut cx: AsyncApp,
10475    ) -> Result<proto::Ack> {
10476        this.update(&mut cx, |_, cx| {
10477            cx.emit(LspStoreEvent::RefreshCodeLens);
10478        });
10479        Ok(proto::Ack {})
10480    }
10481
10482    async fn handle_open_buffer_for_symbol(
10483        this: Entity<Self>,
10484        envelope: TypedEnvelope<proto::OpenBufferForSymbol>,
10485        mut cx: AsyncApp,
10486    ) -> Result<proto::OpenBufferForSymbolResponse> {
10487        let peer_id = envelope.original_sender_id().unwrap_or_default();
10488        let symbol = envelope.payload.symbol.context("invalid symbol")?;
10489        let symbol = Self::deserialize_symbol(symbol)?;
10490        this.read_with(&cx, |this, _| {
10491            if let SymbolLocation::OutsideProject {
10492                abs_path,
10493                signature,
10494            } = &symbol.path
10495            {
10496                let new_signature = this.symbol_signature(&abs_path);
10497                anyhow::ensure!(&new_signature == signature, "invalid symbol signature");
10498            }
10499            Ok(())
10500        })?;
10501        let buffer = this
10502            .update(&mut cx, |this, cx| {
10503                this.open_buffer_for_symbol(
10504                    &Symbol {
10505                        language_server_name: symbol.language_server_name,
10506                        source_worktree_id: symbol.source_worktree_id,
10507                        source_language_server_id: symbol.source_language_server_id,
10508                        path: symbol.path,
10509                        name: symbol.name,
10510                        kind: symbol.kind,
10511                        range: symbol.range,
10512                        label: CodeLabel::default(),
10513                    },
10514                    cx,
10515                )
10516            })
10517            .await?;
10518
10519        this.update(&mut cx, |this, cx| {
10520            let is_private = buffer
10521                .read(cx)
10522                .file()
10523                .map(|f| f.is_private())
10524                .unwrap_or_default();
10525            if is_private {
10526                Err(anyhow!(rpc::ErrorCode::UnsharedItem))
10527            } else {
10528                this.buffer_store
10529                    .update(cx, |buffer_store, cx| {
10530                        buffer_store.create_buffer_for_peer(&buffer, peer_id, cx)
10531                    })
10532                    .detach_and_log_err(cx);
10533                let buffer_id = buffer.read(cx).remote_id().to_proto();
10534                Ok(proto::OpenBufferForSymbolResponse { buffer_id })
10535            }
10536        })
10537    }
10538
10539    fn symbol_signature(&self, abs_path: &Path) -> [u8; 32] {
10540        let mut hasher = Sha256::new();
10541        hasher.update(abs_path.to_string_lossy().as_bytes());
10542        hasher.update(self.nonce.to_be_bytes());
10543        hasher.finalize().as_slice().try_into().unwrap()
10544    }
10545
10546    pub async fn handle_get_project_symbols(
10547        this: Entity<Self>,
10548        envelope: TypedEnvelope<proto::GetProjectSymbols>,
10549        mut cx: AsyncApp,
10550    ) -> Result<proto::GetProjectSymbolsResponse> {
10551        let symbols = this
10552            .update(&mut cx, |this, cx| {
10553                this.symbols(&envelope.payload.query, cx)
10554            })
10555            .await?;
10556
10557        Ok(proto::GetProjectSymbolsResponse {
10558            symbols: symbols.iter().map(Self::serialize_symbol).collect(),
10559        })
10560    }
10561
10562    pub async fn handle_restart_language_servers(
10563        this: Entity<Self>,
10564        envelope: TypedEnvelope<proto::RestartLanguageServers>,
10565        mut cx: AsyncApp,
10566    ) -> Result<proto::Ack> {
10567        this.update(&mut cx, |lsp_store, cx| {
10568            let buffers =
10569                lsp_store.buffer_ids_to_buffers(envelope.payload.buffer_ids.into_iter(), cx);
10570            lsp_store.restart_language_servers_for_buffers(
10571                buffers,
10572                envelope
10573                    .payload
10574                    .only_servers
10575                    .into_iter()
10576                    .filter_map(|selector| {
10577                        Some(match selector.selector? {
10578                            proto::language_server_selector::Selector::ServerId(server_id) => {
10579                                LanguageServerSelector::Id(LanguageServerId::from_proto(server_id))
10580                            }
10581                            proto::language_server_selector::Selector::Name(name) => {
10582                                LanguageServerSelector::Name(LanguageServerName(
10583                                    SharedString::from(name),
10584                                ))
10585                            }
10586                        })
10587                    })
10588                    .collect(),
10589                cx,
10590            );
10591        });
10592
10593        Ok(proto::Ack {})
10594    }
10595
10596    pub async fn handle_stop_language_servers(
10597        lsp_store: Entity<Self>,
10598        envelope: TypedEnvelope<proto::StopLanguageServers>,
10599        mut cx: AsyncApp,
10600    ) -> Result<proto::Ack> {
10601        lsp_store.update(&mut cx, |lsp_store, cx| {
10602            if envelope.payload.all
10603                && envelope.payload.also_servers.is_empty()
10604                && envelope.payload.buffer_ids.is_empty()
10605            {
10606                lsp_store.stop_all_language_servers(cx);
10607            } else {
10608                let buffers =
10609                    lsp_store.buffer_ids_to_buffers(envelope.payload.buffer_ids.into_iter(), cx);
10610                lsp_store
10611                    .stop_language_servers_for_buffers(
10612                        buffers,
10613                        envelope
10614                            .payload
10615                            .also_servers
10616                            .into_iter()
10617                            .filter_map(|selector| {
10618                                Some(match selector.selector? {
10619                                    proto::language_server_selector::Selector::ServerId(
10620                                        server_id,
10621                                    ) => LanguageServerSelector::Id(LanguageServerId::from_proto(
10622                                        server_id,
10623                                    )),
10624                                    proto::language_server_selector::Selector::Name(name) => {
10625                                        LanguageServerSelector::Name(LanguageServerName(
10626                                            SharedString::from(name),
10627                                        ))
10628                                    }
10629                                })
10630                            })
10631                            .collect(),
10632                        cx,
10633                    )
10634                    .detach_and_log_err(cx);
10635            }
10636        });
10637
10638        Ok(proto::Ack {})
10639    }
10640
10641    pub async fn handle_cancel_language_server_work(
10642        lsp_store: Entity<Self>,
10643        envelope: TypedEnvelope<proto::CancelLanguageServerWork>,
10644        mut cx: AsyncApp,
10645    ) -> Result<proto::Ack> {
10646        lsp_store.update(&mut cx, |lsp_store, cx| {
10647            if let Some(work) = envelope.payload.work {
10648                match work {
10649                    proto::cancel_language_server_work::Work::Buffers(buffers) => {
10650                        let buffers =
10651                            lsp_store.buffer_ids_to_buffers(buffers.buffer_ids.into_iter(), cx);
10652                        lsp_store.cancel_language_server_work_for_buffers(buffers, cx);
10653                    }
10654                    proto::cancel_language_server_work::Work::LanguageServerWork(work) => {
10655                        let server_id = LanguageServerId::from_proto(work.language_server_id);
10656                        let token = work
10657                            .token
10658                            .map(|token| {
10659                                ProgressToken::from_proto(token)
10660                                    .context("invalid work progress token")
10661                            })
10662                            .transpose()?;
10663                        lsp_store.cancel_language_server_work(server_id, token, cx);
10664                    }
10665                }
10666            }
10667            anyhow::Ok(())
10668        })?;
10669
10670        Ok(proto::Ack {})
10671    }
10672
10673    fn buffer_ids_to_buffers(
10674        &mut self,
10675        buffer_ids: impl Iterator<Item = u64>,
10676        cx: &mut Context<Self>,
10677    ) -> Vec<Entity<Buffer>> {
10678        buffer_ids
10679            .into_iter()
10680            .flat_map(|buffer_id| {
10681                self.buffer_store
10682                    .read(cx)
10683                    .get(BufferId::new(buffer_id).log_err()?)
10684            })
10685            .collect::<Vec<_>>()
10686    }
10687
10688    async fn handle_apply_additional_edits_for_completion(
10689        this: Entity<Self>,
10690        envelope: TypedEnvelope<proto::ApplyCompletionAdditionalEdits>,
10691        mut cx: AsyncApp,
10692    ) -> Result<proto::ApplyCompletionAdditionalEditsResponse> {
10693        let (buffer, completion) = this.update(&mut cx, |this, cx| {
10694            let buffer_id = BufferId::new(envelope.payload.buffer_id)?;
10695            let buffer = this.buffer_store.read(cx).get_existing(buffer_id)?;
10696            let completion = Self::deserialize_completion(
10697                envelope.payload.completion.context("invalid completion")?,
10698            )?;
10699            anyhow::Ok((buffer, completion))
10700        })?;
10701
10702        let apply_additional_edits = this.update(&mut cx, |this, cx| {
10703            this.apply_additional_edits_for_completion(
10704                buffer,
10705                Rc::new(RefCell::new(Box::new([Completion {
10706                    replace_range: completion.replace_range,
10707                    new_text: completion.new_text,
10708                    source: completion.source,
10709                    documentation: None,
10710                    label: CodeLabel::default(),
10711                    match_start: None,
10712                    snippet_deduplication_key: None,
10713                    insert_text_mode: None,
10714                    icon_path: None,
10715                    confirm: None,
10716                }]))),
10717                0,
10718                false,
10719                cx,
10720            )
10721        });
10722
10723        Ok(proto::ApplyCompletionAdditionalEditsResponse {
10724            transaction: apply_additional_edits
10725                .await?
10726                .as_ref()
10727                .map(language::proto::serialize_transaction),
10728        })
10729    }
10730
10731    pub fn last_formatting_failure(&self) -> Option<&str> {
10732        self.last_formatting_failure.as_deref()
10733    }
10734
10735    pub fn reset_last_formatting_failure(&mut self) {
10736        self.last_formatting_failure = None;
10737    }
10738
10739    pub fn environment_for_buffer(
10740        &self,
10741        buffer: &Entity<Buffer>,
10742        cx: &mut Context<Self>,
10743    ) -> Shared<Task<Option<HashMap<String, String>>>> {
10744        if let Some(environment) = &self.as_local().map(|local| local.environment.clone()) {
10745            environment.update(cx, |env, cx| {
10746                env.buffer_environment(buffer, &self.worktree_store, cx)
10747            })
10748        } else {
10749            Task::ready(None).shared()
10750        }
10751    }
10752
10753    pub fn format(
10754        &mut self,
10755        buffers: HashSet<Entity<Buffer>>,
10756        target: LspFormatTarget,
10757        push_to_history: bool,
10758        trigger: FormatTrigger,
10759        cx: &mut Context<Self>,
10760    ) -> Task<anyhow::Result<ProjectTransaction>> {
10761        let logger = zlog::scoped!("format");
10762        if self.as_local().is_some() {
10763            zlog::trace!(logger => "Formatting locally");
10764            let logger = zlog::scoped!(logger => "local");
10765            let buffers = buffers
10766                .into_iter()
10767                .map(|buffer_handle| {
10768                    let buffer = buffer_handle.read(cx);
10769                    let buffer_abs_path = File::from_dyn(buffer.file())
10770                        .and_then(|file| file.as_local().map(|f| f.abs_path(cx)));
10771
10772                    (buffer_handle, buffer_abs_path, buffer.remote_id())
10773                })
10774                .collect::<Vec<_>>();
10775
10776            cx.spawn(async move |lsp_store, cx| {
10777                let mut formattable_buffers = Vec::with_capacity(buffers.len());
10778
10779                for (handle, abs_path, id) in buffers {
10780                    let env = lsp_store
10781                        .update(cx, |lsp_store, cx| {
10782                            lsp_store.environment_for_buffer(&handle, cx)
10783                        })?
10784                        .await;
10785
10786                    let ranges = match &target {
10787                        LspFormatTarget::Buffers => None,
10788                        LspFormatTarget::Ranges(ranges) => {
10789                            Some(ranges.get(&id).context("No format ranges provided for buffer")?.clone())
10790                        }
10791                    };
10792
10793                    formattable_buffers.push(FormattableBuffer {
10794                        handle,
10795                        abs_path,
10796                        env,
10797                        ranges,
10798                    });
10799                }
10800                zlog::trace!(logger => "Formatting {:?} buffers", formattable_buffers.len());
10801
10802                let format_timer = zlog::time!(logger => "Formatting buffers");
10803                let result = LocalLspStore::format_locally(
10804                    lsp_store.clone(),
10805                    formattable_buffers,
10806                    push_to_history,
10807                    trigger,
10808                    logger,
10809                    cx,
10810                )
10811                .await;
10812                format_timer.end();
10813
10814                zlog::trace!(logger => "Formatting completed with result {:?}", result.as_ref().map(|_| "<project-transaction>"));
10815
10816                lsp_store.update(cx, |lsp_store, _| {
10817                    lsp_store.update_last_formatting_failure(&result);
10818                })?;
10819
10820                result
10821            })
10822        } else if let Some((client, project_id)) = self.upstream_client() {
10823            zlog::trace!(logger => "Formatting remotely");
10824            let logger = zlog::scoped!(logger => "remote");
10825
10826            let buffer_ranges = match &target {
10827                LspFormatTarget::Buffers => Vec::new(),
10828                LspFormatTarget::Ranges(ranges) => ranges
10829                    .iter()
10830                    .map(|(buffer_id, ranges)| proto::BufferFormatRanges {
10831                        buffer_id: buffer_id.to_proto(),
10832                        ranges: ranges.iter().cloned().map(serialize_anchor_range).collect(),
10833                    })
10834                    .collect(),
10835            };
10836
10837            let buffer_store = self.buffer_store();
10838            cx.spawn(async move |lsp_store, cx| {
10839                zlog::trace!(logger => "Sending remote format request");
10840                let request_timer = zlog::time!(logger => "remote format request");
10841                let result = client
10842                    .request(proto::FormatBuffers {
10843                        project_id,
10844                        trigger: trigger as i32,
10845                        buffer_ids: buffers
10846                            .iter()
10847                            .map(|buffer| buffer.read_with(cx, |buffer, _| buffer.remote_id().to_proto()))
10848                            .collect(),
10849                        buffer_ranges,
10850                    })
10851                    .await
10852                    .and_then(|result| result.transaction.context("missing transaction"));
10853                request_timer.end();
10854
10855                zlog::trace!(logger => "Remote format request resolved to {:?}", result.as_ref().map(|_| "<project_transaction>"));
10856
10857                lsp_store.update(cx, |lsp_store, _| {
10858                    lsp_store.update_last_formatting_failure(&result);
10859                })?;
10860
10861                let transaction_response = result?;
10862                let _timer = zlog::time!(logger => "deserializing project transaction");
10863                buffer_store
10864                    .update(cx, |buffer_store, cx| {
10865                        buffer_store.deserialize_project_transaction(
10866                            transaction_response,
10867                            push_to_history,
10868                            cx,
10869                        )
10870                    })
10871                    .await
10872            })
10873        } else {
10874            zlog::trace!(logger => "Not formatting");
10875            Task::ready(Ok(ProjectTransaction::default()))
10876        }
10877    }
10878
10879    async fn handle_format_buffers(
10880        this: Entity<Self>,
10881        envelope: TypedEnvelope<proto::FormatBuffers>,
10882        mut cx: AsyncApp,
10883    ) -> Result<proto::FormatBuffersResponse> {
10884        let sender_id = envelope.original_sender_id().unwrap_or_default();
10885        let format = this.update(&mut cx, |this, cx| {
10886            let mut buffers = HashSet::default();
10887            for buffer_id in &envelope.payload.buffer_ids {
10888                let buffer_id = BufferId::new(*buffer_id)?;
10889                buffers.insert(this.buffer_store.read(cx).get_existing(buffer_id)?);
10890            }
10891
10892            let target = if envelope.payload.buffer_ranges.is_empty() {
10893                LspFormatTarget::Buffers
10894            } else {
10895                let mut ranges_map = BTreeMap::new();
10896                for buffer_range in &envelope.payload.buffer_ranges {
10897                    let buffer_id = BufferId::new(buffer_range.buffer_id)?;
10898                    let ranges: Result<Vec<_>> = buffer_range
10899                        .ranges
10900                        .iter()
10901                        .map(|range| {
10902                            deserialize_anchor_range(range.clone()).context("invalid anchor range")
10903                        })
10904                        .collect();
10905                    ranges_map.insert(buffer_id, ranges?);
10906                }
10907                LspFormatTarget::Ranges(ranges_map)
10908            };
10909
10910            let trigger = FormatTrigger::from_proto(envelope.payload.trigger);
10911            anyhow::Ok(this.format(buffers, target, false, trigger, cx))
10912        })?;
10913
10914        let project_transaction = format.await?;
10915        let project_transaction = this.update(&mut cx, |this, cx| {
10916            this.buffer_store.update(cx, |buffer_store, cx| {
10917                buffer_store.serialize_project_transaction_for_peer(
10918                    project_transaction,
10919                    sender_id,
10920                    cx,
10921                )
10922            })
10923        });
10924        Ok(proto::FormatBuffersResponse {
10925            transaction: Some(project_transaction),
10926        })
10927    }
10928
10929    async fn handle_apply_code_action_kind(
10930        this: Entity<Self>,
10931        envelope: TypedEnvelope<proto::ApplyCodeActionKind>,
10932        mut cx: AsyncApp,
10933    ) -> Result<proto::ApplyCodeActionKindResponse> {
10934        let sender_id = envelope.original_sender_id().unwrap_or_default();
10935        let format = this.update(&mut cx, |this, cx| {
10936            let mut buffers = HashSet::default();
10937            for buffer_id in &envelope.payload.buffer_ids {
10938                let buffer_id = BufferId::new(*buffer_id)?;
10939                buffers.insert(this.buffer_store.read(cx).get_existing(buffer_id)?);
10940            }
10941            let kind = match envelope.payload.kind.as_str() {
10942                "" => CodeActionKind::EMPTY,
10943                "quickfix" => CodeActionKind::QUICKFIX,
10944                "refactor" => CodeActionKind::REFACTOR,
10945                "refactor.extract" => CodeActionKind::REFACTOR_EXTRACT,
10946                "refactor.inline" => CodeActionKind::REFACTOR_INLINE,
10947                "refactor.rewrite" => CodeActionKind::REFACTOR_REWRITE,
10948                "source" => CodeActionKind::SOURCE,
10949                "source.organizeImports" => CodeActionKind::SOURCE_ORGANIZE_IMPORTS,
10950                "source.fixAll" => CodeActionKind::SOURCE_FIX_ALL,
10951                _ => anyhow::bail!(
10952                    "Invalid code action kind {}",
10953                    envelope.payload.kind.as_str()
10954                ),
10955            };
10956            anyhow::Ok(this.apply_code_action_kind(buffers, kind, false, cx))
10957        })?;
10958
10959        let project_transaction = format.await?;
10960        let project_transaction = this.update(&mut cx, |this, cx| {
10961            this.buffer_store.update(cx, |buffer_store, cx| {
10962                buffer_store.serialize_project_transaction_for_peer(
10963                    project_transaction,
10964                    sender_id,
10965                    cx,
10966                )
10967            })
10968        });
10969        Ok(proto::ApplyCodeActionKindResponse {
10970            transaction: Some(project_transaction),
10971        })
10972    }
10973
10974    async fn shutdown_language_server(
10975        server_state: Option<LanguageServerState>,
10976        name: LanguageServerName,
10977        cx: &mut AsyncApp,
10978    ) {
10979        let server = match server_state {
10980            Some(LanguageServerState::Starting { startup, .. }) => {
10981                let mut timer = cx
10982                    .background_executor()
10983                    .timer(SERVER_LAUNCHING_BEFORE_SHUTDOWN_TIMEOUT)
10984                    .fuse();
10985
10986                select! {
10987                    server = startup.fuse() => server,
10988                    () = timer => {
10989                        log::info!("timeout waiting for language server {name} to finish launching before stopping");
10990                        None
10991                    },
10992                }
10993            }
10994
10995            Some(LanguageServerState::Running { server, .. }) => Some(server),
10996
10997            None => None,
10998        };
10999
11000        if let Some(server) = server
11001            && let Some(shutdown) = server.shutdown()
11002        {
11003            shutdown.await;
11004        }
11005    }
11006
11007    // Returns a list of all of the worktrees which no longer have a language server and the root path
11008    // for the stopped server
11009    fn stop_local_language_server(
11010        &mut self,
11011        server_id: LanguageServerId,
11012        cx: &mut Context<Self>,
11013    ) -> Task<()> {
11014        let local = match &mut self.mode {
11015            LspStoreMode::Local(local) => local,
11016            _ => {
11017                return Task::ready(());
11018            }
11019        };
11020
11021        // Remove this server ID from all entries in the given worktree.
11022        local
11023            .language_server_ids
11024            .retain(|_, state| state.id != server_id);
11025        self.buffer_store.update(cx, |buffer_store, cx| {
11026            for buffer in buffer_store.buffers() {
11027                buffer.update(cx, |buffer, cx| {
11028                    buffer.update_diagnostics(server_id, DiagnosticSet::new([], buffer), cx);
11029                    buffer.set_completion_triggers(server_id, Default::default(), cx);
11030                });
11031            }
11032        });
11033
11034        for (worktree_id, summaries) in self.diagnostic_summaries.iter_mut() {
11035            summaries.retain(|path, summaries_by_server_id| {
11036                if summaries_by_server_id.remove(&server_id).is_some() {
11037                    if let Some((client, project_id)) = self.downstream_client.clone() {
11038                        client
11039                            .send(proto::UpdateDiagnosticSummary {
11040                                project_id,
11041                                worktree_id: worktree_id.to_proto(),
11042                                summary: Some(proto::DiagnosticSummary {
11043                                    path: path.as_ref().to_proto(),
11044                                    language_server_id: server_id.0 as u64,
11045                                    error_count: 0,
11046                                    warning_count: 0,
11047                                }),
11048                                more_summaries: Vec::new(),
11049                            })
11050                            .log_err();
11051                    }
11052                    !summaries_by_server_id.is_empty()
11053                } else {
11054                    true
11055                }
11056            });
11057        }
11058
11059        let local = self.as_local_mut().unwrap();
11060        for diagnostics in local.diagnostics.values_mut() {
11061            diagnostics.retain(|_, diagnostics_by_server_id| {
11062                if let Ok(ix) = diagnostics_by_server_id.binary_search_by_key(&server_id, |e| e.0) {
11063                    diagnostics_by_server_id.remove(ix);
11064                    !diagnostics_by_server_id.is_empty()
11065                } else {
11066                    true
11067                }
11068            });
11069        }
11070        local.language_server_watched_paths.remove(&server_id);
11071
11072        let server_state = local.language_servers.remove(&server_id);
11073        self.cleanup_lsp_data(server_id);
11074        let name = self
11075            .language_server_statuses
11076            .remove(&server_id)
11077            .map(|status| status.name)
11078            .or_else(|| {
11079                if let Some(LanguageServerState::Running { adapter, .. }) = server_state.as_ref() {
11080                    Some(adapter.name())
11081                } else {
11082                    None
11083                }
11084            });
11085
11086        if let Some(name) = name {
11087            log::info!("stopping language server {name}");
11088            self.languages
11089                .update_lsp_binary_status(name.clone(), BinaryStatus::Stopping);
11090            cx.notify();
11091
11092            return cx.spawn(async move |lsp_store, cx| {
11093                Self::shutdown_language_server(server_state, name.clone(), cx).await;
11094                lsp_store
11095                    .update(cx, |lsp_store, cx| {
11096                        lsp_store
11097                            .languages
11098                            .update_lsp_binary_status(name, BinaryStatus::Stopped);
11099                        cx.emit(LspStoreEvent::LanguageServerRemoved(server_id));
11100                        cx.notify();
11101                    })
11102                    .ok();
11103            });
11104        }
11105
11106        if server_state.is_some() {
11107            cx.emit(LspStoreEvent::LanguageServerRemoved(server_id));
11108        }
11109        Task::ready(())
11110    }
11111
11112    pub fn stop_all_language_servers(&mut self, cx: &mut Context<Self>) {
11113        self.shutdown_all_language_servers(cx).detach();
11114    }
11115
11116    pub fn shutdown_all_language_servers(&mut self, cx: &mut Context<Self>) -> Task<()> {
11117        if let Some((client, project_id)) = self.upstream_client() {
11118            let request = client.request(proto::StopLanguageServers {
11119                project_id,
11120                buffer_ids: Vec::new(),
11121                also_servers: Vec::new(),
11122                all: true,
11123            });
11124            cx.background_spawn(async move {
11125                request.await.ok();
11126            })
11127        } else {
11128            let Some(local) = self.as_local_mut() else {
11129                return Task::ready(());
11130            };
11131            let language_servers_to_stop = local
11132                .language_server_ids
11133                .values()
11134                .map(|state| state.id)
11135                .collect();
11136            local.lsp_tree.remove_nodes(&language_servers_to_stop);
11137            let tasks = language_servers_to_stop
11138                .into_iter()
11139                .map(|server| self.stop_local_language_server(server, cx))
11140                .collect::<Vec<_>>();
11141            cx.background_spawn(async move {
11142                futures::future::join_all(tasks).await;
11143            })
11144        }
11145    }
11146
11147    pub fn restart_language_servers_for_buffers(
11148        &mut self,
11149        buffers: Vec<Entity<Buffer>>,
11150        only_restart_servers: HashSet<LanguageServerSelector>,
11151        cx: &mut Context<Self>,
11152    ) {
11153        if let Some((client, project_id)) = self.upstream_client() {
11154            let request = client.request(proto::RestartLanguageServers {
11155                project_id,
11156                buffer_ids: buffers
11157                    .into_iter()
11158                    .map(|b| b.read(cx).remote_id().to_proto())
11159                    .collect(),
11160                only_servers: only_restart_servers
11161                    .into_iter()
11162                    .map(|selector| {
11163                        let selector = match selector {
11164                            LanguageServerSelector::Id(language_server_id) => {
11165                                proto::language_server_selector::Selector::ServerId(
11166                                    language_server_id.to_proto(),
11167                                )
11168                            }
11169                            LanguageServerSelector::Name(language_server_name) => {
11170                                proto::language_server_selector::Selector::Name(
11171                                    language_server_name.to_string(),
11172                                )
11173                            }
11174                        };
11175                        proto::LanguageServerSelector {
11176                            selector: Some(selector),
11177                        }
11178                    })
11179                    .collect(),
11180                all: false,
11181            });
11182            cx.background_spawn(request).detach_and_log_err(cx);
11183        } else {
11184            let stop_task = if only_restart_servers.is_empty() {
11185                self.stop_local_language_servers_for_buffers(&buffers, HashSet::default(), cx)
11186            } else {
11187                self.stop_local_language_servers_for_buffers(&[], only_restart_servers.clone(), cx)
11188            };
11189            cx.spawn(async move |lsp_store, cx| {
11190                stop_task.await;
11191                lsp_store.update(cx, |lsp_store, cx| {
11192                    for buffer in buffers {
11193                        lsp_store.register_buffer_with_language_servers(
11194                            &buffer,
11195                            only_restart_servers.clone(),
11196                            true,
11197                            cx,
11198                        );
11199                    }
11200                })
11201            })
11202            .detach();
11203        }
11204    }
11205
11206    pub fn stop_language_servers_for_buffers(
11207        &mut self,
11208        buffers: Vec<Entity<Buffer>>,
11209        also_stop_servers: HashSet<LanguageServerSelector>,
11210        cx: &mut Context<Self>,
11211    ) -> Task<Result<()>> {
11212        if let Some((client, project_id)) = self.upstream_client() {
11213            let request = client.request(proto::StopLanguageServers {
11214                project_id,
11215                buffer_ids: buffers
11216                    .into_iter()
11217                    .map(|b| b.read(cx).remote_id().to_proto())
11218                    .collect(),
11219                also_servers: also_stop_servers
11220                    .into_iter()
11221                    .map(|selector| {
11222                        let selector = match selector {
11223                            LanguageServerSelector::Id(language_server_id) => {
11224                                proto::language_server_selector::Selector::ServerId(
11225                                    language_server_id.to_proto(),
11226                                )
11227                            }
11228                            LanguageServerSelector::Name(language_server_name) => {
11229                                proto::language_server_selector::Selector::Name(
11230                                    language_server_name.to_string(),
11231                                )
11232                            }
11233                        };
11234                        proto::LanguageServerSelector {
11235                            selector: Some(selector),
11236                        }
11237                    })
11238                    .collect(),
11239                all: false,
11240            });
11241            cx.background_spawn(async move {
11242                let _ = request.await?;
11243                Ok(())
11244            })
11245        } else {
11246            let task =
11247                self.stop_local_language_servers_for_buffers(&buffers, also_stop_servers, cx);
11248            cx.background_spawn(async move {
11249                task.await;
11250                Ok(())
11251            })
11252        }
11253    }
11254
11255    fn stop_local_language_servers_for_buffers(
11256        &mut self,
11257        buffers: &[Entity<Buffer>],
11258        also_stop_servers: HashSet<LanguageServerSelector>,
11259        cx: &mut Context<Self>,
11260    ) -> Task<()> {
11261        let Some(local) = self.as_local_mut() else {
11262            return Task::ready(());
11263        };
11264        let mut language_server_names_to_stop = BTreeSet::default();
11265        let mut language_servers_to_stop = also_stop_servers
11266            .into_iter()
11267            .flat_map(|selector| match selector {
11268                LanguageServerSelector::Id(id) => Some(id),
11269                LanguageServerSelector::Name(name) => {
11270                    language_server_names_to_stop.insert(name);
11271                    None
11272                }
11273            })
11274            .collect::<BTreeSet<_>>();
11275
11276        let mut covered_worktrees = HashSet::default();
11277        for buffer in buffers {
11278            buffer.update(cx, |buffer, cx| {
11279                language_servers_to_stop.extend(local.language_server_ids_for_buffer(buffer, cx));
11280                if let Some(worktree_id) = buffer.file().map(|f| f.worktree_id(cx))
11281                    && covered_worktrees.insert(worktree_id)
11282                {
11283                    language_server_names_to_stop.retain(|name| {
11284                        let old_ids_count = language_servers_to_stop.len();
11285                        let all_language_servers_with_this_name = local
11286                            .language_server_ids
11287                            .iter()
11288                            .filter_map(|(seed, state)| seed.name.eq(name).then(|| state.id));
11289                        language_servers_to_stop.extend(all_language_servers_with_this_name);
11290                        old_ids_count == language_servers_to_stop.len()
11291                    });
11292                }
11293            });
11294        }
11295        for name in language_server_names_to_stop {
11296            language_servers_to_stop.extend(
11297                local
11298                    .language_server_ids
11299                    .iter()
11300                    .filter_map(|(seed, v)| seed.name.eq(&name).then(|| v.id)),
11301            );
11302        }
11303
11304        local.lsp_tree.remove_nodes(&language_servers_to_stop);
11305        let tasks = language_servers_to_stop
11306            .into_iter()
11307            .map(|server| self.stop_local_language_server(server, cx))
11308            .collect::<Vec<_>>();
11309
11310        cx.background_spawn(futures::future::join_all(tasks).map(|_| ()))
11311    }
11312
11313    fn get_buffer<'a>(&self, abs_path: &Path, cx: &'a App) -> Option<&'a Buffer> {
11314        let (worktree, relative_path) =
11315            self.worktree_store.read(cx).find_worktree(&abs_path, cx)?;
11316
11317        let project_path = ProjectPath {
11318            worktree_id: worktree.read(cx).id(),
11319            path: relative_path,
11320        };
11321
11322        Some(
11323            self.buffer_store()
11324                .read(cx)
11325                .get_by_path(&project_path)?
11326                .read(cx),
11327        )
11328    }
11329
11330    #[cfg(any(test, feature = "test-support"))]
11331    pub fn update_diagnostics(
11332        &mut self,
11333        server_id: LanguageServerId,
11334        diagnostics: lsp::PublishDiagnosticsParams,
11335        result_id: Option<SharedString>,
11336        source_kind: DiagnosticSourceKind,
11337        disk_based_sources: &[String],
11338        cx: &mut Context<Self>,
11339    ) -> Result<()> {
11340        self.merge_lsp_diagnostics(
11341            source_kind,
11342            vec![DocumentDiagnosticsUpdate {
11343                diagnostics,
11344                result_id,
11345                server_id,
11346                disk_based_sources: Cow::Borrowed(disk_based_sources),
11347                registration_id: None,
11348            }],
11349            |_, _, _| false,
11350            cx,
11351        )
11352    }
11353
11354    pub fn merge_lsp_diagnostics(
11355        &mut self,
11356        source_kind: DiagnosticSourceKind,
11357        lsp_diagnostics: Vec<DocumentDiagnosticsUpdate<lsp::PublishDiagnosticsParams>>,
11358        merge: impl Fn(&lsp::Uri, &Diagnostic, &App) -> bool + Clone,
11359        cx: &mut Context<Self>,
11360    ) -> Result<()> {
11361        anyhow::ensure!(self.mode.is_local(), "called update_diagnostics on remote");
11362        let updates = lsp_diagnostics
11363            .into_iter()
11364            .filter_map(|update| {
11365                let abs_path = update.diagnostics.uri.to_file_path().ok()?;
11366                Some(DocumentDiagnosticsUpdate {
11367                    diagnostics: self.lsp_to_document_diagnostics(
11368                        abs_path,
11369                        source_kind,
11370                        update.server_id,
11371                        update.diagnostics,
11372                        &update.disk_based_sources,
11373                        update.registration_id.clone(),
11374                    ),
11375                    result_id: update.result_id,
11376                    server_id: update.server_id,
11377                    disk_based_sources: update.disk_based_sources,
11378                    registration_id: update.registration_id,
11379                })
11380            })
11381            .collect();
11382        self.merge_diagnostic_entries(updates, merge, cx)?;
11383        Ok(())
11384    }
11385
11386    fn lsp_to_document_diagnostics(
11387        &mut self,
11388        document_abs_path: PathBuf,
11389        source_kind: DiagnosticSourceKind,
11390        server_id: LanguageServerId,
11391        mut lsp_diagnostics: lsp::PublishDiagnosticsParams,
11392        disk_based_sources: &[String],
11393        registration_id: Option<SharedString>,
11394    ) -> DocumentDiagnostics {
11395        let mut diagnostics = Vec::default();
11396        let mut primary_diagnostic_group_ids = HashMap::default();
11397        let mut sources_by_group_id = HashMap::default();
11398        let mut supporting_diagnostics = HashMap::default();
11399
11400        let adapter = self.language_server_adapter_for_id(server_id);
11401
11402        // Ensure that primary diagnostics are always the most severe
11403        lsp_diagnostics
11404            .diagnostics
11405            .sort_by_key(|item| item.severity);
11406
11407        for diagnostic in &lsp_diagnostics.diagnostics {
11408            let source = diagnostic.source.as_ref();
11409            let range = range_from_lsp(diagnostic.range);
11410            let is_supporting = diagnostic
11411                .related_information
11412                .as_ref()
11413                .is_some_and(|infos| {
11414                    infos.iter().any(|info| {
11415                        primary_diagnostic_group_ids.contains_key(&(
11416                            source,
11417                            diagnostic.code.clone(),
11418                            range_from_lsp(info.location.range),
11419                        ))
11420                    })
11421                });
11422
11423            let is_unnecessary = diagnostic
11424                .tags
11425                .as_ref()
11426                .is_some_and(|tags| tags.contains(&DiagnosticTag::UNNECESSARY));
11427
11428            let underline = self
11429                .language_server_adapter_for_id(server_id)
11430                .is_none_or(|adapter| adapter.underline_diagnostic(diagnostic));
11431
11432            if is_supporting {
11433                supporting_diagnostics.insert(
11434                    (source, diagnostic.code.clone(), range),
11435                    (diagnostic.severity, is_unnecessary),
11436                );
11437            } else {
11438                let group_id = post_inc(&mut self.as_local_mut().unwrap().next_diagnostic_group_id);
11439                let is_disk_based =
11440                    source.is_some_and(|source| disk_based_sources.contains(source));
11441
11442                sources_by_group_id.insert(group_id, source);
11443                primary_diagnostic_group_ids
11444                    .insert((source, diagnostic.code.clone(), range.clone()), group_id);
11445
11446                diagnostics.push(DiagnosticEntry {
11447                    range,
11448                    diagnostic: Diagnostic {
11449                        source: diagnostic.source.clone(),
11450                        source_kind,
11451                        code: diagnostic.code.clone(),
11452                        code_description: diagnostic
11453                            .code_description
11454                            .as_ref()
11455                            .and_then(|d| d.href.clone()),
11456                        severity: diagnostic.severity.unwrap_or(DiagnosticSeverity::ERROR),
11457                        markdown: adapter.as_ref().and_then(|adapter| {
11458                            adapter.diagnostic_message_to_markdown(&diagnostic.message)
11459                        }),
11460                        message: diagnostic.message.trim().to_string(),
11461                        group_id,
11462                        is_primary: true,
11463                        is_disk_based,
11464                        is_unnecessary,
11465                        underline,
11466                        data: diagnostic.data.clone(),
11467                        registration_id: registration_id.clone(),
11468                    },
11469                });
11470                if let Some(infos) = &diagnostic.related_information {
11471                    for info in infos {
11472                        if info.location.uri == lsp_diagnostics.uri && !info.message.is_empty() {
11473                            let range = range_from_lsp(info.location.range);
11474                            diagnostics.push(DiagnosticEntry {
11475                                range,
11476                                diagnostic: Diagnostic {
11477                                    source: diagnostic.source.clone(),
11478                                    source_kind,
11479                                    code: diagnostic.code.clone(),
11480                                    code_description: diagnostic
11481                                        .code_description
11482                                        .as_ref()
11483                                        .and_then(|d| d.href.clone()),
11484                                    severity: DiagnosticSeverity::INFORMATION,
11485                                    markdown: adapter.as_ref().and_then(|adapter| {
11486                                        adapter.diagnostic_message_to_markdown(&info.message)
11487                                    }),
11488                                    message: info.message.trim().to_string(),
11489                                    group_id,
11490                                    is_primary: false,
11491                                    is_disk_based,
11492                                    is_unnecessary: false,
11493                                    underline,
11494                                    data: diagnostic.data.clone(),
11495                                    registration_id: registration_id.clone(),
11496                                },
11497                            });
11498                        }
11499                    }
11500                }
11501            }
11502        }
11503
11504        for entry in &mut diagnostics {
11505            let diagnostic = &mut entry.diagnostic;
11506            if !diagnostic.is_primary {
11507                let source = *sources_by_group_id.get(&diagnostic.group_id).unwrap();
11508                if let Some(&(severity, is_unnecessary)) = supporting_diagnostics.get(&(
11509                    source,
11510                    diagnostic.code.clone(),
11511                    entry.range.clone(),
11512                )) {
11513                    if let Some(severity) = severity {
11514                        diagnostic.severity = severity;
11515                    }
11516                    diagnostic.is_unnecessary = is_unnecessary;
11517                }
11518            }
11519        }
11520
11521        DocumentDiagnostics {
11522            diagnostics,
11523            document_abs_path,
11524            version: lsp_diagnostics.version,
11525        }
11526    }
11527
11528    fn insert_newly_running_language_server(
11529        &mut self,
11530        adapter: Arc<CachedLspAdapter>,
11531        language_server: Arc<LanguageServer>,
11532        server_id: LanguageServerId,
11533        key: LanguageServerSeed,
11534        workspace_folders: Arc<Mutex<BTreeSet<Uri>>>,
11535        cx: &mut Context<Self>,
11536    ) {
11537        let Some(local) = self.as_local_mut() else {
11538            return;
11539        };
11540        // If the language server for this key doesn't match the server id, don't store the
11541        // server. Which will cause it to be dropped, killing the process
11542        if local
11543            .language_server_ids
11544            .get(&key)
11545            .map(|state| state.id != server_id)
11546            .unwrap_or(false)
11547        {
11548            return;
11549        }
11550
11551        // Update language_servers collection with Running variant of LanguageServerState
11552        // indicating that the server is up and running and ready
11553        let workspace_folders = workspace_folders.lock().clone();
11554        language_server.set_workspace_folders(workspace_folders);
11555
11556        let workspace_diagnostics_refresh_tasks = language_server
11557            .capabilities()
11558            .diagnostic_provider
11559            .and_then(|provider| {
11560                local
11561                    .language_server_dynamic_registrations
11562                    .entry(server_id)
11563                    .or_default()
11564                    .diagnostics
11565                    .entry(None)
11566                    .or_insert(provider.clone());
11567                let workspace_refresher =
11568                    lsp_workspace_diagnostics_refresh(None, provider, language_server.clone(), cx)?;
11569
11570                Some((None, workspace_refresher))
11571            })
11572            .into_iter()
11573            .collect();
11574        local.language_servers.insert(
11575            server_id,
11576            LanguageServerState::Running {
11577                workspace_diagnostics_refresh_tasks,
11578                adapter: adapter.clone(),
11579                server: language_server.clone(),
11580                simulate_disk_based_diagnostics_completion: None,
11581            },
11582        );
11583        local
11584            .languages
11585            .update_lsp_binary_status(adapter.name(), BinaryStatus::None);
11586        if let Some(file_ops_caps) = language_server
11587            .capabilities()
11588            .workspace
11589            .as_ref()
11590            .and_then(|ws| ws.file_operations.as_ref())
11591        {
11592            let did_rename_caps = file_ops_caps.did_rename.as_ref();
11593            let will_rename_caps = file_ops_caps.will_rename.as_ref();
11594            if did_rename_caps.or(will_rename_caps).is_some() {
11595                let watcher = RenamePathsWatchedForServer::default()
11596                    .with_did_rename_patterns(did_rename_caps)
11597                    .with_will_rename_patterns(will_rename_caps);
11598                local
11599                    .language_server_paths_watched_for_rename
11600                    .insert(server_id, watcher);
11601            }
11602        }
11603
11604        self.language_server_statuses.insert(
11605            server_id,
11606            LanguageServerStatus {
11607                name: language_server.name(),
11608                server_version: language_server.version(),
11609                pending_work: Default::default(),
11610                has_pending_diagnostic_updates: false,
11611                progress_tokens: Default::default(),
11612                worktree: Some(key.worktree_id),
11613                binary: Some(language_server.binary().clone()),
11614                configuration: Some(language_server.configuration().clone()),
11615                workspace_folders: language_server.workspace_folders(),
11616                process_id: language_server.process_id(),
11617            },
11618        );
11619
11620        cx.emit(LspStoreEvent::LanguageServerAdded(
11621            server_id,
11622            language_server.name(),
11623            Some(key.worktree_id),
11624        ));
11625
11626        let server_capabilities = language_server.capabilities();
11627        if let Some((downstream_client, project_id)) = self.downstream_client.as_ref() {
11628            downstream_client
11629                .send(proto::StartLanguageServer {
11630                    project_id: *project_id,
11631                    server: Some(proto::LanguageServer {
11632                        id: server_id.to_proto(),
11633                        name: language_server.name().to_string(),
11634                        worktree_id: Some(key.worktree_id.to_proto()),
11635                    }),
11636                    capabilities: serde_json::to_string(&server_capabilities)
11637                        .expect("serializing server LSP capabilities"),
11638                })
11639                .log_err();
11640        }
11641        self.lsp_server_capabilities
11642            .insert(server_id, server_capabilities);
11643
11644        // Tell the language server about every open buffer in the worktree that matches the language.
11645        // Also check for buffers in worktrees that reused this server
11646        let mut worktrees_using_server = vec![key.worktree_id];
11647        if let Some(local) = self.as_local() {
11648            // Find all worktrees that have this server in their language server tree
11649            for (worktree_id, servers) in &local.lsp_tree.instances {
11650                if *worktree_id != key.worktree_id {
11651                    for server_map in servers.roots.values() {
11652                        if server_map
11653                            .values()
11654                            .any(|(node, _)| node.id() == Some(server_id))
11655                        {
11656                            worktrees_using_server.push(*worktree_id);
11657                        }
11658                    }
11659                }
11660            }
11661        }
11662
11663        let mut buffer_paths_registered = Vec::new();
11664        self.buffer_store.clone().update(cx, |buffer_store, cx| {
11665            let mut lsp_adapters = HashMap::default();
11666            for buffer_handle in buffer_store.buffers() {
11667                let buffer = buffer_handle.read(cx);
11668                let file = match File::from_dyn(buffer.file()) {
11669                    Some(file) => file,
11670                    None => continue,
11671                };
11672                let language = match buffer.language() {
11673                    Some(language) => language,
11674                    None => continue,
11675                };
11676
11677                if !worktrees_using_server.contains(&file.worktree.read(cx).id())
11678                    || !lsp_adapters
11679                        .entry(language.name())
11680                        .or_insert_with(|| self.languages.lsp_adapters(&language.name()))
11681                        .iter()
11682                        .any(|a| a.name == key.name)
11683                {
11684                    continue;
11685                }
11686                // didOpen
11687                let file = match file.as_local() {
11688                    Some(file) => file,
11689                    None => continue,
11690                };
11691
11692                let local = self.as_local_mut().unwrap();
11693
11694                let buffer_id = buffer.remote_id();
11695                if local.registered_buffers.contains_key(&buffer_id) {
11696                    let versions = local
11697                        .buffer_snapshots
11698                        .entry(buffer_id)
11699                        .or_default()
11700                        .entry(server_id)
11701                        .and_modify(|_| {
11702                            assert!(
11703                            false,
11704                            "There should not be an existing snapshot for a newly inserted buffer"
11705                        )
11706                        })
11707                        .or_insert_with(|| {
11708                            vec![LspBufferSnapshot {
11709                                version: 0,
11710                                snapshot: buffer.text_snapshot(),
11711                            }]
11712                        });
11713
11714                    let snapshot = versions.last().unwrap();
11715                    let version = snapshot.version;
11716                    let initial_snapshot = &snapshot.snapshot;
11717                    let uri = lsp::Uri::from_file_path(file.abs_path(cx)).unwrap();
11718                    language_server.register_buffer(
11719                        uri,
11720                        adapter.language_id(&language.name()),
11721                        version,
11722                        initial_snapshot.text(),
11723                    );
11724                    buffer_paths_registered.push((buffer_id, file.abs_path(cx)));
11725                    local
11726                        .buffers_opened_in_servers
11727                        .entry(buffer_id)
11728                        .or_default()
11729                        .insert(server_id);
11730                }
11731                buffer_handle.update(cx, |buffer, cx| {
11732                    buffer.set_completion_triggers(
11733                        server_id,
11734                        language_server
11735                            .capabilities()
11736                            .completion_provider
11737                            .as_ref()
11738                            .and_then(|provider| {
11739                                provider
11740                                    .trigger_characters
11741                                    .as_ref()
11742                                    .map(|characters| characters.iter().cloned().collect())
11743                            })
11744                            .unwrap_or_default(),
11745                        cx,
11746                    )
11747                });
11748            }
11749        });
11750
11751        for (buffer_id, abs_path) in buffer_paths_registered {
11752            cx.emit(LspStoreEvent::LanguageServerUpdate {
11753                language_server_id: server_id,
11754                name: Some(adapter.name()),
11755                message: proto::update_language_server::Variant::RegisteredForBuffer(
11756                    proto::RegisteredForBuffer {
11757                        buffer_abs_path: abs_path.to_string_lossy().into_owned(),
11758                        buffer_id: buffer_id.to_proto(),
11759                    },
11760                ),
11761            });
11762        }
11763
11764        cx.notify();
11765    }
11766
11767    pub fn language_servers_running_disk_based_diagnostics(
11768        &self,
11769    ) -> impl Iterator<Item = LanguageServerId> + '_ {
11770        self.language_server_statuses
11771            .iter()
11772            .filter_map(|(id, status)| {
11773                if status.has_pending_diagnostic_updates {
11774                    Some(*id)
11775                } else {
11776                    None
11777                }
11778            })
11779    }
11780
11781    pub(crate) fn cancel_language_server_work_for_buffers(
11782        &mut self,
11783        buffers: impl IntoIterator<Item = Entity<Buffer>>,
11784        cx: &mut Context<Self>,
11785    ) {
11786        if let Some((client, project_id)) = self.upstream_client() {
11787            let request = client.request(proto::CancelLanguageServerWork {
11788                project_id,
11789                work: Some(proto::cancel_language_server_work::Work::Buffers(
11790                    proto::cancel_language_server_work::Buffers {
11791                        buffer_ids: buffers
11792                            .into_iter()
11793                            .map(|b| b.read(cx).remote_id().to_proto())
11794                            .collect(),
11795                    },
11796                )),
11797            });
11798            cx.background_spawn(request).detach_and_log_err(cx);
11799        } else if let Some(local) = self.as_local() {
11800            let servers = buffers
11801                .into_iter()
11802                .flat_map(|buffer| {
11803                    buffer.update(cx, |buffer, cx| {
11804                        local.language_server_ids_for_buffer(buffer, cx).into_iter()
11805                    })
11806                })
11807                .collect::<HashSet<_>>();
11808            for server_id in servers {
11809                self.cancel_language_server_work(server_id, None, cx);
11810            }
11811        }
11812    }
11813
11814    pub(crate) fn cancel_language_server_work(
11815        &mut self,
11816        server_id: LanguageServerId,
11817        token_to_cancel: Option<ProgressToken>,
11818        cx: &mut Context<Self>,
11819    ) {
11820        if let Some(local) = self.as_local() {
11821            let status = self.language_server_statuses.get(&server_id);
11822            let server = local.language_servers.get(&server_id);
11823            if let Some((LanguageServerState::Running { server, .. }, status)) = server.zip(status)
11824            {
11825                for (token, progress) in &status.pending_work {
11826                    if let Some(token_to_cancel) = token_to_cancel.as_ref()
11827                        && token != token_to_cancel
11828                    {
11829                        continue;
11830                    }
11831                    if progress.is_cancellable {
11832                        server
11833                            .notify::<lsp::notification::WorkDoneProgressCancel>(
11834                                WorkDoneProgressCancelParams {
11835                                    token: token.to_lsp(),
11836                                },
11837                            )
11838                            .ok();
11839                    }
11840                }
11841            }
11842        } else if let Some((client, project_id)) = self.upstream_client() {
11843            let request = client.request(proto::CancelLanguageServerWork {
11844                project_id,
11845                work: Some(
11846                    proto::cancel_language_server_work::Work::LanguageServerWork(
11847                        proto::cancel_language_server_work::LanguageServerWork {
11848                            language_server_id: server_id.to_proto(),
11849                            token: token_to_cancel.map(|token| token.to_proto()),
11850                        },
11851                    ),
11852                ),
11853            });
11854            cx.background_spawn(request).detach_and_log_err(cx);
11855        }
11856    }
11857
11858    fn register_supplementary_language_server(
11859        &mut self,
11860        id: LanguageServerId,
11861        name: LanguageServerName,
11862        server: Arc<LanguageServer>,
11863        cx: &mut Context<Self>,
11864    ) {
11865        if let Some(local) = self.as_local_mut() {
11866            local
11867                .supplementary_language_servers
11868                .insert(id, (name.clone(), server));
11869            cx.emit(LspStoreEvent::LanguageServerAdded(id, name, None));
11870        }
11871    }
11872
11873    fn unregister_supplementary_language_server(
11874        &mut self,
11875        id: LanguageServerId,
11876        cx: &mut Context<Self>,
11877    ) {
11878        if let Some(local) = self.as_local_mut() {
11879            local.supplementary_language_servers.remove(&id);
11880            cx.emit(LspStoreEvent::LanguageServerRemoved(id));
11881        }
11882    }
11883
11884    pub(crate) fn supplementary_language_servers(
11885        &self,
11886    ) -> impl '_ + Iterator<Item = (LanguageServerId, LanguageServerName)> {
11887        self.as_local().into_iter().flat_map(|local| {
11888            local
11889                .supplementary_language_servers
11890                .iter()
11891                .map(|(id, (name, _))| (*id, name.clone()))
11892        })
11893    }
11894
11895    pub fn language_server_adapter_for_id(
11896        &self,
11897        id: LanguageServerId,
11898    ) -> Option<Arc<CachedLspAdapter>> {
11899        self.as_local()
11900            .and_then(|local| local.language_servers.get(&id))
11901            .and_then(|language_server_state| match language_server_state {
11902                LanguageServerState::Running { adapter, .. } => Some(adapter.clone()),
11903                _ => None,
11904            })
11905    }
11906
11907    pub(super) fn update_local_worktree_language_servers(
11908        &mut self,
11909        worktree_handle: &Entity<Worktree>,
11910        changes: &[(Arc<RelPath>, ProjectEntryId, PathChange)],
11911        cx: &mut Context<Self>,
11912    ) {
11913        if changes.is_empty() {
11914            return;
11915        }
11916
11917        let Some(local) = self.as_local() else { return };
11918
11919        local.prettier_store.update(cx, |prettier_store, cx| {
11920            prettier_store.update_prettier_settings(worktree_handle, changes, cx)
11921        });
11922
11923        let worktree_id = worktree_handle.read(cx).id();
11924        let mut language_server_ids = local
11925            .language_server_ids
11926            .iter()
11927            .filter_map(|(seed, v)| seed.worktree_id.eq(&worktree_id).then(|| v.id))
11928            .collect::<Vec<_>>();
11929        language_server_ids.sort();
11930        language_server_ids.dedup();
11931
11932        // let abs_path = worktree_handle.read(cx).abs_path();
11933        for server_id in &language_server_ids {
11934            if let Some(LanguageServerState::Running { server, .. }) =
11935                local.language_servers.get(server_id)
11936                && let Some(watched_paths) = local
11937                    .language_server_watched_paths
11938                    .get(server_id)
11939                    .and_then(|paths| paths.worktree_paths.get(&worktree_id))
11940            {
11941                let params = lsp::DidChangeWatchedFilesParams {
11942                    changes: changes
11943                        .iter()
11944                        .filter_map(|(path, _, change)| {
11945                            if !watched_paths.is_match(path.as_std_path()) {
11946                                return None;
11947                            }
11948                            let typ = match change {
11949                                PathChange::Loaded => return None,
11950                                PathChange::Added => lsp::FileChangeType::CREATED,
11951                                PathChange::Removed => lsp::FileChangeType::DELETED,
11952                                PathChange::Updated => lsp::FileChangeType::CHANGED,
11953                                PathChange::AddedOrUpdated => lsp::FileChangeType::CHANGED,
11954                            };
11955                            let uri = lsp::Uri::from_file_path(
11956                                worktree_handle.read(cx).absolutize(&path),
11957                            )
11958                            .ok()?;
11959                            Some(lsp::FileEvent { uri, typ })
11960                        })
11961                        .collect(),
11962                };
11963                if !params.changes.is_empty() {
11964                    server
11965                        .notify::<lsp::notification::DidChangeWatchedFiles>(params)
11966                        .ok();
11967                }
11968            }
11969        }
11970        for (path, _, _) in changes {
11971            if let Some(file_name) = path.file_name()
11972                && local.watched_manifest_filenames.contains(file_name)
11973            {
11974                self.request_workspace_config_refresh();
11975                break;
11976            }
11977        }
11978    }
11979
11980    pub fn wait_for_remote_buffer(
11981        &mut self,
11982        id: BufferId,
11983        cx: &mut Context<Self>,
11984    ) -> Task<Result<Entity<Buffer>>> {
11985        self.buffer_store.update(cx, |buffer_store, cx| {
11986            buffer_store.wait_for_remote_buffer(id, cx)
11987        })
11988    }
11989
11990    fn serialize_symbol(symbol: &Symbol) -> proto::Symbol {
11991        let mut result = proto::Symbol {
11992            language_server_name: symbol.language_server_name.0.to_string(),
11993            source_worktree_id: symbol.source_worktree_id.to_proto(),
11994            language_server_id: symbol.source_language_server_id.to_proto(),
11995            name: symbol.name.clone(),
11996            kind: unsafe { mem::transmute::<lsp::SymbolKind, i32>(symbol.kind) },
11997            start: Some(proto::PointUtf16 {
11998                row: symbol.range.start.0.row,
11999                column: symbol.range.start.0.column,
12000            }),
12001            end: Some(proto::PointUtf16 {
12002                row: symbol.range.end.0.row,
12003                column: symbol.range.end.0.column,
12004            }),
12005            worktree_id: Default::default(),
12006            path: Default::default(),
12007            signature: Default::default(),
12008        };
12009        match &symbol.path {
12010            SymbolLocation::InProject(path) => {
12011                result.worktree_id = path.worktree_id.to_proto();
12012                result.path = path.path.to_proto();
12013            }
12014            SymbolLocation::OutsideProject {
12015                abs_path,
12016                signature,
12017            } => {
12018                result.path = abs_path.to_string_lossy().into_owned();
12019                result.signature = signature.to_vec();
12020            }
12021        }
12022        result
12023    }
12024
12025    fn deserialize_symbol(serialized_symbol: proto::Symbol) -> Result<CoreSymbol> {
12026        let source_worktree_id = WorktreeId::from_proto(serialized_symbol.source_worktree_id);
12027        let worktree_id = WorktreeId::from_proto(serialized_symbol.worktree_id);
12028        let kind = unsafe { mem::transmute::<i32, lsp::SymbolKind>(serialized_symbol.kind) };
12029
12030        let path = if serialized_symbol.signature.is_empty() {
12031            SymbolLocation::InProject(ProjectPath {
12032                worktree_id,
12033                path: RelPath::from_proto(&serialized_symbol.path)
12034                    .context("invalid symbol path")?,
12035            })
12036        } else {
12037            SymbolLocation::OutsideProject {
12038                abs_path: Path::new(&serialized_symbol.path).into(),
12039                signature: serialized_symbol
12040                    .signature
12041                    .try_into()
12042                    .map_err(|_| anyhow!("invalid signature"))?,
12043            }
12044        };
12045
12046        let start = serialized_symbol.start.context("invalid start")?;
12047        let end = serialized_symbol.end.context("invalid end")?;
12048        Ok(CoreSymbol {
12049            language_server_name: LanguageServerName(serialized_symbol.language_server_name.into()),
12050            source_worktree_id,
12051            source_language_server_id: LanguageServerId::from_proto(
12052                serialized_symbol.language_server_id,
12053            ),
12054            path,
12055            name: serialized_symbol.name,
12056            range: Unclipped(PointUtf16::new(start.row, start.column))
12057                ..Unclipped(PointUtf16::new(end.row, end.column)),
12058            kind,
12059        })
12060    }
12061
12062    pub(crate) fn serialize_completion(completion: &CoreCompletion) -> proto::Completion {
12063        let mut serialized_completion = proto::Completion {
12064            old_replace_start: Some(serialize_anchor(&completion.replace_range.start)),
12065            old_replace_end: Some(serialize_anchor(&completion.replace_range.end)),
12066            new_text: completion.new_text.clone(),
12067            ..proto::Completion::default()
12068        };
12069        match &completion.source {
12070            CompletionSource::Lsp {
12071                insert_range,
12072                server_id,
12073                lsp_completion,
12074                lsp_defaults,
12075                resolved,
12076            } => {
12077                let (old_insert_start, old_insert_end) = insert_range
12078                    .as_ref()
12079                    .map(|range| (serialize_anchor(&range.start), serialize_anchor(&range.end)))
12080                    .unzip();
12081
12082                serialized_completion.old_insert_start = old_insert_start;
12083                serialized_completion.old_insert_end = old_insert_end;
12084                serialized_completion.source = proto::completion::Source::Lsp as i32;
12085                serialized_completion.server_id = server_id.0 as u64;
12086                serialized_completion.lsp_completion = serde_json::to_vec(lsp_completion).unwrap();
12087                serialized_completion.lsp_defaults = lsp_defaults
12088                    .as_deref()
12089                    .map(|lsp_defaults| serde_json::to_vec(lsp_defaults).unwrap());
12090                serialized_completion.resolved = *resolved;
12091            }
12092            CompletionSource::BufferWord {
12093                word_range,
12094                resolved,
12095            } => {
12096                serialized_completion.source = proto::completion::Source::BufferWord as i32;
12097                serialized_completion.buffer_word_start = Some(serialize_anchor(&word_range.start));
12098                serialized_completion.buffer_word_end = Some(serialize_anchor(&word_range.end));
12099                serialized_completion.resolved = *resolved;
12100            }
12101            CompletionSource::Custom => {
12102                serialized_completion.source = proto::completion::Source::Custom as i32;
12103                serialized_completion.resolved = true;
12104            }
12105            CompletionSource::Dap { sort_text } => {
12106                serialized_completion.source = proto::completion::Source::Dap as i32;
12107                serialized_completion.sort_text = Some(sort_text.clone());
12108            }
12109        }
12110
12111        serialized_completion
12112    }
12113
12114    pub(crate) fn deserialize_completion(completion: proto::Completion) -> Result<CoreCompletion> {
12115        let old_replace_start = completion
12116            .old_replace_start
12117            .and_then(deserialize_anchor)
12118            .context("invalid old start")?;
12119        let old_replace_end = completion
12120            .old_replace_end
12121            .and_then(deserialize_anchor)
12122            .context("invalid old end")?;
12123        let insert_range = {
12124            match completion.old_insert_start.zip(completion.old_insert_end) {
12125                Some((start, end)) => {
12126                    let start = deserialize_anchor(start).context("invalid insert old start")?;
12127                    let end = deserialize_anchor(end).context("invalid insert old end")?;
12128                    Some(start..end)
12129                }
12130                None => None,
12131            }
12132        };
12133        Ok(CoreCompletion {
12134            replace_range: old_replace_start..old_replace_end,
12135            new_text: completion.new_text,
12136            source: match proto::completion::Source::from_i32(completion.source) {
12137                Some(proto::completion::Source::Custom) => CompletionSource::Custom,
12138                Some(proto::completion::Source::Lsp) => CompletionSource::Lsp {
12139                    insert_range,
12140                    server_id: LanguageServerId::from_proto(completion.server_id),
12141                    lsp_completion: serde_json::from_slice(&completion.lsp_completion)?,
12142                    lsp_defaults: completion
12143                        .lsp_defaults
12144                        .as_deref()
12145                        .map(serde_json::from_slice)
12146                        .transpose()?,
12147                    resolved: completion.resolved,
12148                },
12149                Some(proto::completion::Source::BufferWord) => {
12150                    let word_range = completion
12151                        .buffer_word_start
12152                        .and_then(deserialize_anchor)
12153                        .context("invalid buffer word start")?
12154                        ..completion
12155                            .buffer_word_end
12156                            .and_then(deserialize_anchor)
12157                            .context("invalid buffer word end")?;
12158                    CompletionSource::BufferWord {
12159                        word_range,
12160                        resolved: completion.resolved,
12161                    }
12162                }
12163                Some(proto::completion::Source::Dap) => CompletionSource::Dap {
12164                    sort_text: completion
12165                        .sort_text
12166                        .context("expected sort text to exist")?,
12167                },
12168                _ => anyhow::bail!("Unexpected completion source {}", completion.source),
12169            },
12170        })
12171    }
12172
12173    pub(crate) fn serialize_code_action(action: &CodeAction) -> proto::CodeAction {
12174        let (kind, lsp_action) = match &action.lsp_action {
12175            LspAction::Action(code_action) => (
12176                proto::code_action::Kind::Action as i32,
12177                serde_json::to_vec(code_action).unwrap(),
12178            ),
12179            LspAction::Command(command) => (
12180                proto::code_action::Kind::Command as i32,
12181                serde_json::to_vec(command).unwrap(),
12182            ),
12183            LspAction::CodeLens(code_lens) => (
12184                proto::code_action::Kind::CodeLens as i32,
12185                serde_json::to_vec(code_lens).unwrap(),
12186            ),
12187        };
12188
12189        proto::CodeAction {
12190            server_id: action.server_id.0 as u64,
12191            start: Some(serialize_anchor(&action.range.start)),
12192            end: Some(serialize_anchor(&action.range.end)),
12193            lsp_action,
12194            kind,
12195            resolved: action.resolved,
12196        }
12197    }
12198
12199    pub(crate) fn deserialize_code_action(action: proto::CodeAction) -> Result<CodeAction> {
12200        let start = action
12201            .start
12202            .and_then(deserialize_anchor)
12203            .context("invalid start")?;
12204        let end = action
12205            .end
12206            .and_then(deserialize_anchor)
12207            .context("invalid end")?;
12208        let lsp_action = match proto::code_action::Kind::from_i32(action.kind) {
12209            Some(proto::code_action::Kind::Action) => {
12210                LspAction::Action(serde_json::from_slice(&action.lsp_action)?)
12211            }
12212            Some(proto::code_action::Kind::Command) => {
12213                LspAction::Command(serde_json::from_slice(&action.lsp_action)?)
12214            }
12215            Some(proto::code_action::Kind::CodeLens) => {
12216                LspAction::CodeLens(serde_json::from_slice(&action.lsp_action)?)
12217            }
12218            None => anyhow::bail!("Unknown action kind {}", action.kind),
12219        };
12220        Ok(CodeAction {
12221            server_id: LanguageServerId(action.server_id as usize),
12222            range: start..end,
12223            resolved: action.resolved,
12224            lsp_action,
12225        })
12226    }
12227
12228    fn update_last_formatting_failure<T>(&mut self, formatting_result: &anyhow::Result<T>) {
12229        match &formatting_result {
12230            Ok(_) => self.last_formatting_failure = None,
12231            Err(error) => {
12232                let error_string = format!("{error:#}");
12233                log::error!("Formatting failed: {error_string}");
12234                self.last_formatting_failure
12235                    .replace(error_string.lines().join(" "));
12236            }
12237        }
12238    }
12239
12240    fn cleanup_lsp_data(&mut self, for_server: LanguageServerId) {
12241        self.lsp_server_capabilities.remove(&for_server);
12242        for lsp_data in self.lsp_data.values_mut() {
12243            lsp_data.remove_server_data(for_server);
12244        }
12245        if let Some(local) = self.as_local_mut() {
12246            local.buffer_pull_diagnostics_result_ids.remove(&for_server);
12247            local
12248                .workspace_pull_diagnostics_result_ids
12249                .remove(&for_server);
12250            for buffer_servers in local.buffers_opened_in_servers.values_mut() {
12251                buffer_servers.remove(&for_server);
12252            }
12253        }
12254    }
12255
12256    pub fn result_id_for_buffer_pull(
12257        &self,
12258        server_id: LanguageServerId,
12259        buffer_id: BufferId,
12260        registration_id: &Option<SharedString>,
12261        cx: &App,
12262    ) -> Option<SharedString> {
12263        let abs_path = self
12264            .buffer_store
12265            .read(cx)
12266            .get(buffer_id)
12267            .and_then(|b| File::from_dyn(b.read(cx).file()))
12268            .map(|f| f.abs_path(cx))?;
12269        self.as_local()?
12270            .buffer_pull_diagnostics_result_ids
12271            .get(&server_id)?
12272            .get(registration_id)?
12273            .get(&abs_path)?
12274            .clone()
12275    }
12276
12277    /// Gets all result_ids for a workspace diagnostics pull request.
12278    /// 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.
12279    /// The latter is supposed to be of lower priority as we keep on pulling diagnostics for open buffers eagerly.
12280    pub fn result_ids_for_workspace_refresh(
12281        &self,
12282        server_id: LanguageServerId,
12283        registration_id: &Option<SharedString>,
12284    ) -> HashMap<PathBuf, SharedString> {
12285        let Some(local) = self.as_local() else {
12286            return HashMap::default();
12287        };
12288        local
12289            .workspace_pull_diagnostics_result_ids
12290            .get(&server_id)
12291            .into_iter()
12292            .filter_map(|diagnostics| diagnostics.get(registration_id))
12293            .flatten()
12294            .filter_map(|(abs_path, result_id)| {
12295                let result_id = local
12296                    .buffer_pull_diagnostics_result_ids
12297                    .get(&server_id)
12298                    .and_then(|buffer_ids_result_ids| {
12299                        buffer_ids_result_ids.get(registration_id)?.get(abs_path)
12300                    })
12301                    .cloned()
12302                    .flatten()
12303                    .or_else(|| result_id.clone())?;
12304                Some((abs_path.clone(), result_id))
12305            })
12306            .collect()
12307    }
12308
12309    pub fn pull_workspace_diagnostics(&mut self, server_id: LanguageServerId) {
12310        if let Some(LanguageServerState::Running {
12311            workspace_diagnostics_refresh_tasks,
12312            ..
12313        }) = self
12314            .as_local_mut()
12315            .and_then(|local| local.language_servers.get_mut(&server_id))
12316        {
12317            for diagnostics in workspace_diagnostics_refresh_tasks.values_mut() {
12318                diagnostics.refresh_tx.try_send(()).ok();
12319            }
12320        }
12321    }
12322
12323    /// Refreshes `textDocument/diagnostic` for all open buffers associated with the given server.
12324    /// This is called in response to `workspace/diagnostic/refresh` to comply with the LSP spec,
12325    /// which requires refreshing both workspace and document diagnostics.
12326    pub fn pull_document_diagnostics_for_server(
12327        &mut self,
12328        server_id: LanguageServerId,
12329        source_buffer_id: Option<BufferId>,
12330        cx: &mut Context<Self>,
12331    ) -> Shared<Task<()>> {
12332        let Some(local) = self.as_local_mut() else {
12333            return Task::ready(()).shared();
12334        };
12335        let mut buffers_to_refresh = HashSet::default();
12336        for (buffer_id, server_ids) in &local.buffers_opened_in_servers {
12337            if server_ids.contains(&server_id) && Some(buffer_id) != source_buffer_id.as_ref() {
12338                buffers_to_refresh.insert(*buffer_id);
12339            }
12340        }
12341
12342        self.refresh_background_diagnostics_for_buffers(buffers_to_refresh, cx)
12343    }
12344
12345    pub fn pull_document_diagnostics_for_buffer_edit(
12346        &mut self,
12347        buffer_id: BufferId,
12348        cx: &mut Context<Self>,
12349    ) {
12350        let Some(local) = self.as_local_mut() else {
12351            return;
12352        };
12353        let Some(languages_servers) = local.buffers_opened_in_servers.get(&buffer_id).cloned()
12354        else {
12355            return;
12356        };
12357        for server_id in languages_servers {
12358            let _ = self.pull_document_diagnostics_for_server(server_id, Some(buffer_id), cx);
12359        }
12360    }
12361
12362    fn apply_workspace_diagnostic_report(
12363        &mut self,
12364        server_id: LanguageServerId,
12365        report: lsp::WorkspaceDiagnosticReportResult,
12366        registration_id: Option<SharedString>,
12367        cx: &mut Context<Self>,
12368    ) {
12369        let mut workspace_diagnostics =
12370            GetDocumentDiagnostics::deserialize_workspace_diagnostics_report(
12371                report,
12372                server_id,
12373                registration_id,
12374            );
12375        workspace_diagnostics.retain(|d| match &d.diagnostics {
12376            LspPullDiagnostics::Response {
12377                server_id,
12378                registration_id,
12379                ..
12380            } => self.diagnostic_registration_exists(*server_id, registration_id),
12381            LspPullDiagnostics::Default => false,
12382        });
12383        let mut unchanged_buffers = HashMap::default();
12384        let workspace_diagnostics_updates = workspace_diagnostics
12385            .into_iter()
12386            .filter_map(
12387                |workspace_diagnostics| match workspace_diagnostics.diagnostics {
12388                    LspPullDiagnostics::Response {
12389                        server_id,
12390                        uri,
12391                        diagnostics,
12392                        registration_id,
12393                    } => Some((
12394                        server_id,
12395                        uri,
12396                        diagnostics,
12397                        workspace_diagnostics.version,
12398                        registration_id,
12399                    )),
12400                    LspPullDiagnostics::Default => None,
12401                },
12402            )
12403            .fold(
12404                HashMap::default(),
12405                |mut acc, (server_id, uri, diagnostics, version, new_registration_id)| {
12406                    let (result_id, diagnostics) = match diagnostics {
12407                        PulledDiagnostics::Unchanged { result_id } => {
12408                            unchanged_buffers
12409                                .entry(new_registration_id.clone())
12410                                .or_insert_with(HashSet::default)
12411                                .insert(uri.clone());
12412                            (Some(result_id), Vec::new())
12413                        }
12414                        PulledDiagnostics::Changed {
12415                            result_id,
12416                            diagnostics,
12417                        } => (result_id, diagnostics),
12418                    };
12419                    let disk_based_sources = Cow::Owned(
12420                        self.language_server_adapter_for_id(server_id)
12421                            .as_ref()
12422                            .map(|adapter| adapter.disk_based_diagnostic_sources.as_slice())
12423                            .unwrap_or(&[])
12424                            .to_vec(),
12425                    );
12426
12427                    let Some(abs_path) = uri.to_file_path().ok() else {
12428                        return acc;
12429                    };
12430                    let Some((worktree, relative_path)) =
12431                        self.worktree_store.read(cx).find_worktree(abs_path.clone(), cx)
12432                    else {
12433                        log::warn!("skipping workspace diagnostics update, no worktree found for path {abs_path:?}");
12434                        return acc;
12435                    };
12436                    let worktree_id = worktree.read(cx).id();
12437                    let project_path = ProjectPath {
12438                        worktree_id,
12439                        path: relative_path,
12440                    };
12441                    if let Some(local_lsp_store) = self.as_local_mut() {
12442                        local_lsp_store.workspace_pull_diagnostics_result_ids.entry(server_id)
12443                            .or_default().entry(new_registration_id.clone()).or_default().insert(abs_path, result_id.clone());
12444                    }
12445                    // The LSP spec recommends that "diagnostics from a document pull should win over diagnostics from a workspace pull."
12446                    // Since we actively pull diagnostics for documents with open buffers, we ignore contents of workspace pulls for these documents.
12447                    if self.buffer_store.read(cx).get_by_path(&project_path).is_none() {
12448                        acc.entry(server_id)
12449                            .or_insert_with(HashMap::default)
12450                            .entry(new_registration_id.clone())
12451                            .or_insert_with(Vec::new)
12452                            .push(DocumentDiagnosticsUpdate {
12453                                server_id,
12454                                diagnostics: lsp::PublishDiagnosticsParams {
12455                                    uri,
12456                                    diagnostics,
12457                                    version,
12458                                },
12459                                result_id,
12460                                disk_based_sources,
12461                                registration_id: new_registration_id,
12462                            });
12463                    }
12464                    acc
12465                },
12466            );
12467
12468        for diagnostic_updates in workspace_diagnostics_updates.into_values() {
12469            for (registration_id, diagnostic_updates) in diagnostic_updates {
12470                self.merge_lsp_diagnostics(
12471                    DiagnosticSourceKind::Pulled,
12472                    diagnostic_updates,
12473                    |document_uri, old_diagnostic, _| match old_diagnostic.source_kind {
12474                        DiagnosticSourceKind::Pulled => {
12475                            old_diagnostic.registration_id != registration_id
12476                                || unchanged_buffers
12477                                    .get(&old_diagnostic.registration_id)
12478                                    .is_some_and(|unchanged_buffers| {
12479                                        unchanged_buffers.contains(&document_uri)
12480                                    })
12481                        }
12482                        DiagnosticSourceKind::Other | DiagnosticSourceKind::Pushed => true,
12483                    },
12484                    cx,
12485                )
12486                .log_err();
12487            }
12488        }
12489    }
12490
12491    fn register_server_capabilities(
12492        &mut self,
12493        server_id: LanguageServerId,
12494        params: lsp::RegistrationParams,
12495        cx: &mut Context<Self>,
12496    ) -> anyhow::Result<()> {
12497        let server = self
12498            .language_server_for_id(server_id)
12499            .with_context(|| format!("no server {server_id} found"))?;
12500        for reg in params.registrations {
12501            match reg.method.as_str() {
12502                "workspace/didChangeWatchedFiles" => {
12503                    if let Some(options) = reg.register_options {
12504                        let notify = if let Some(local_lsp_store) = self.as_local_mut() {
12505                            let caps = serde_json::from_value(options)?;
12506                            local_lsp_store
12507                                .on_lsp_did_change_watched_files(server_id, &reg.id, caps, cx);
12508                            true
12509                        } else {
12510                            false
12511                        };
12512                        if notify {
12513                            notify_server_capabilities_updated(&server, cx);
12514                        }
12515                    }
12516                }
12517                "workspace/didChangeConfiguration" => {
12518                    // Ignore payload since we notify clients of setting changes unconditionally, relying on them pulling the latest settings.
12519                }
12520                "workspace/didChangeWorkspaceFolders" => {
12521                    // In this case register options is an empty object, we can ignore it
12522                    let caps = lsp::WorkspaceFoldersServerCapabilities {
12523                        supported: Some(true),
12524                        change_notifications: Some(OneOf::Right(reg.id)),
12525                    };
12526                    server.update_capabilities(|capabilities| {
12527                        capabilities
12528                            .workspace
12529                            .get_or_insert_default()
12530                            .workspace_folders = Some(caps);
12531                    });
12532                    notify_server_capabilities_updated(&server, cx);
12533                }
12534                "workspace/symbol" => {
12535                    let options = parse_register_capabilities(reg)?;
12536                    server.update_capabilities(|capabilities| {
12537                        capabilities.workspace_symbol_provider = Some(options);
12538                    });
12539                    notify_server_capabilities_updated(&server, cx);
12540                }
12541                "workspace/fileOperations" => {
12542                    if let Some(options) = reg.register_options {
12543                        let caps = serde_json::from_value(options)?;
12544                        server.update_capabilities(|capabilities| {
12545                            capabilities
12546                                .workspace
12547                                .get_or_insert_default()
12548                                .file_operations = Some(caps);
12549                        });
12550                        notify_server_capabilities_updated(&server, cx);
12551                    }
12552                }
12553                "workspace/executeCommand" => {
12554                    if let Some(options) = reg.register_options {
12555                        let options = serde_json::from_value(options)?;
12556                        server.update_capabilities(|capabilities| {
12557                            capabilities.execute_command_provider = Some(options);
12558                        });
12559                        notify_server_capabilities_updated(&server, cx);
12560                    }
12561                }
12562                "textDocument/rangeFormatting" => {
12563                    let options = parse_register_capabilities(reg)?;
12564                    server.update_capabilities(|capabilities| {
12565                        capabilities.document_range_formatting_provider = Some(options);
12566                    });
12567                    notify_server_capabilities_updated(&server, cx);
12568                }
12569                "textDocument/onTypeFormatting" => {
12570                    if let Some(options) = reg
12571                        .register_options
12572                        .map(serde_json::from_value)
12573                        .transpose()?
12574                    {
12575                        server.update_capabilities(|capabilities| {
12576                            capabilities.document_on_type_formatting_provider = Some(options);
12577                        });
12578                        notify_server_capabilities_updated(&server, cx);
12579                    }
12580                }
12581                "textDocument/formatting" => {
12582                    let options = parse_register_capabilities(reg)?;
12583                    server.update_capabilities(|capabilities| {
12584                        capabilities.document_formatting_provider = Some(options);
12585                    });
12586                    notify_server_capabilities_updated(&server, cx);
12587                }
12588                "textDocument/rename" => {
12589                    let options = parse_register_capabilities(reg)?;
12590                    server.update_capabilities(|capabilities| {
12591                        capabilities.rename_provider = Some(options);
12592                    });
12593                    notify_server_capabilities_updated(&server, cx);
12594                }
12595                "textDocument/inlayHint" => {
12596                    let options = parse_register_capabilities(reg)?;
12597                    server.update_capabilities(|capabilities| {
12598                        capabilities.inlay_hint_provider = Some(options);
12599                    });
12600                    notify_server_capabilities_updated(&server, cx);
12601                }
12602                "textDocument/documentSymbol" => {
12603                    let options = parse_register_capabilities(reg)?;
12604                    server.update_capabilities(|capabilities| {
12605                        capabilities.document_symbol_provider = Some(options);
12606                    });
12607                    notify_server_capabilities_updated(&server, cx);
12608                }
12609                "textDocument/codeAction" => {
12610                    let options = parse_register_capabilities(reg)?;
12611                    let provider = match options {
12612                        OneOf::Left(value) => lsp::CodeActionProviderCapability::Simple(value),
12613                        OneOf::Right(caps) => caps,
12614                    };
12615                    server.update_capabilities(|capabilities| {
12616                        capabilities.code_action_provider = Some(provider);
12617                    });
12618                    notify_server_capabilities_updated(&server, cx);
12619                }
12620                "textDocument/definition" => {
12621                    let options = parse_register_capabilities(reg)?;
12622                    server.update_capabilities(|capabilities| {
12623                        capabilities.definition_provider = Some(options);
12624                    });
12625                    notify_server_capabilities_updated(&server, cx);
12626                }
12627                "textDocument/completion" => {
12628                    if let Some(caps) = reg
12629                        .register_options
12630                        .map(serde_json::from_value::<CompletionOptions>)
12631                        .transpose()?
12632                    {
12633                        server.update_capabilities(|capabilities| {
12634                            capabilities.completion_provider = Some(caps.clone());
12635                        });
12636
12637                        if let Some(local) = self.as_local() {
12638                            let mut buffers_with_language_server = Vec::new();
12639                            for handle in self.buffer_store.read(cx).buffers() {
12640                                let buffer_id = handle.read(cx).remote_id();
12641                                if local
12642                                    .buffers_opened_in_servers
12643                                    .get(&buffer_id)
12644                                    .filter(|s| s.contains(&server_id))
12645                                    .is_some()
12646                                {
12647                                    buffers_with_language_server.push(handle);
12648                                }
12649                            }
12650                            let triggers = caps
12651                                .trigger_characters
12652                                .unwrap_or_default()
12653                                .into_iter()
12654                                .collect::<BTreeSet<_>>();
12655                            for handle in buffers_with_language_server {
12656                                let triggers = triggers.clone();
12657                                let _ = handle.update(cx, move |buffer, cx| {
12658                                    buffer.set_completion_triggers(server_id, triggers, cx);
12659                                });
12660                            }
12661                        }
12662                        notify_server_capabilities_updated(&server, cx);
12663                    }
12664                }
12665                "textDocument/hover" => {
12666                    let options = parse_register_capabilities(reg)?;
12667                    let provider = match options {
12668                        OneOf::Left(value) => lsp::HoverProviderCapability::Simple(value),
12669                        OneOf::Right(caps) => caps,
12670                    };
12671                    server.update_capabilities(|capabilities| {
12672                        capabilities.hover_provider = Some(provider);
12673                    });
12674                    notify_server_capabilities_updated(&server, cx);
12675                }
12676                "textDocument/signatureHelp" => {
12677                    if let Some(caps) = reg
12678                        .register_options
12679                        .map(serde_json::from_value)
12680                        .transpose()?
12681                    {
12682                        server.update_capabilities(|capabilities| {
12683                            capabilities.signature_help_provider = Some(caps);
12684                        });
12685                        notify_server_capabilities_updated(&server, cx);
12686                    }
12687                }
12688                "textDocument/didChange" => {
12689                    if let Some(sync_kind) = reg
12690                        .register_options
12691                        .and_then(|opts| opts.get("syncKind").cloned())
12692                        .map(serde_json::from_value::<lsp::TextDocumentSyncKind>)
12693                        .transpose()?
12694                    {
12695                        server.update_capabilities(|capabilities| {
12696                            let mut sync_options =
12697                                Self::take_text_document_sync_options(capabilities);
12698                            sync_options.change = Some(sync_kind);
12699                            capabilities.text_document_sync =
12700                                Some(lsp::TextDocumentSyncCapability::Options(sync_options));
12701                        });
12702                        notify_server_capabilities_updated(&server, cx);
12703                    }
12704                }
12705                "textDocument/didSave" => {
12706                    if let Some(include_text) = reg
12707                        .register_options
12708                        .map(|opts| {
12709                            let transpose = opts
12710                                .get("includeText")
12711                                .cloned()
12712                                .map(serde_json::from_value::<Option<bool>>)
12713                                .transpose();
12714                            match transpose {
12715                                Ok(value) => Ok(value.flatten()),
12716                                Err(e) => Err(e),
12717                            }
12718                        })
12719                        .transpose()?
12720                    {
12721                        server.update_capabilities(|capabilities| {
12722                            let mut sync_options =
12723                                Self::take_text_document_sync_options(capabilities);
12724                            sync_options.save =
12725                                Some(TextDocumentSyncSaveOptions::SaveOptions(lsp::SaveOptions {
12726                                    include_text,
12727                                }));
12728                            capabilities.text_document_sync =
12729                                Some(lsp::TextDocumentSyncCapability::Options(sync_options));
12730                        });
12731                        notify_server_capabilities_updated(&server, cx);
12732                    }
12733                }
12734                "textDocument/codeLens" => {
12735                    if let Some(caps) = reg
12736                        .register_options
12737                        .map(serde_json::from_value)
12738                        .transpose()?
12739                    {
12740                        server.update_capabilities(|capabilities| {
12741                            capabilities.code_lens_provider = Some(caps);
12742                        });
12743                        notify_server_capabilities_updated(&server, cx);
12744                    }
12745                }
12746                "textDocument/diagnostic" => {
12747                    if let Some(caps) = reg
12748                        .register_options
12749                        .map(serde_json::from_value::<DiagnosticServerCapabilities>)
12750                        .transpose()?
12751                    {
12752                        let local = self
12753                            .as_local_mut()
12754                            .context("Expected LSP Store to be local")?;
12755                        let state = local
12756                            .language_servers
12757                            .get_mut(&server_id)
12758                            .context("Could not obtain Language Servers state")?;
12759                        local
12760                            .language_server_dynamic_registrations
12761                            .entry(server_id)
12762                            .or_default()
12763                            .diagnostics
12764                            .insert(Some(reg.id.clone()), caps.clone());
12765
12766                        let supports_workspace_diagnostics =
12767                            |capabilities: &DiagnosticServerCapabilities| match capabilities {
12768                                DiagnosticServerCapabilities::Options(diagnostic_options) => {
12769                                    diagnostic_options.workspace_diagnostics
12770                                }
12771                                DiagnosticServerCapabilities::RegistrationOptions(
12772                                    diagnostic_registration_options,
12773                                ) => {
12774                                    diagnostic_registration_options
12775                                        .diagnostic_options
12776                                        .workspace_diagnostics
12777                                }
12778                            };
12779
12780                        if supports_workspace_diagnostics(&caps) {
12781                            if let LanguageServerState::Running {
12782                                workspace_diagnostics_refresh_tasks,
12783                                ..
12784                            } = state
12785                                && let Some(task) = lsp_workspace_diagnostics_refresh(
12786                                    Some(reg.id.clone()),
12787                                    caps.clone(),
12788                                    server.clone(),
12789                                    cx,
12790                                )
12791                            {
12792                                workspace_diagnostics_refresh_tasks.insert(Some(reg.id), task);
12793                            }
12794                        }
12795
12796                        server.update_capabilities(|capabilities| {
12797                            capabilities.diagnostic_provider = Some(caps);
12798                        });
12799
12800                        notify_server_capabilities_updated(&server, cx);
12801
12802                        let _ = self.pull_document_diagnostics_for_server(server_id, None, cx);
12803                    }
12804                }
12805                "textDocument/documentColor" => {
12806                    let options = parse_register_capabilities(reg)?;
12807                    let provider = match options {
12808                        OneOf::Left(value) => lsp::ColorProviderCapability::Simple(value),
12809                        OneOf::Right(caps) => caps,
12810                    };
12811                    server.update_capabilities(|capabilities| {
12812                        capabilities.color_provider = Some(provider);
12813                    });
12814                    notify_server_capabilities_updated(&server, cx);
12815                }
12816                _ => log::warn!("unhandled capability registration: {reg:?}"),
12817            }
12818        }
12819
12820        Ok(())
12821    }
12822
12823    fn unregister_server_capabilities(
12824        &mut self,
12825        server_id: LanguageServerId,
12826        params: lsp::UnregistrationParams,
12827        cx: &mut Context<Self>,
12828    ) -> anyhow::Result<()> {
12829        let server = self
12830            .language_server_for_id(server_id)
12831            .with_context(|| format!("no server {server_id} found"))?;
12832        for unreg in params.unregisterations.iter() {
12833            match unreg.method.as_str() {
12834                "workspace/didChangeWatchedFiles" => {
12835                    let notify = if let Some(local_lsp_store) = self.as_local_mut() {
12836                        local_lsp_store
12837                            .on_lsp_unregister_did_change_watched_files(server_id, &unreg.id, cx);
12838                        true
12839                    } else {
12840                        false
12841                    };
12842                    if notify {
12843                        notify_server_capabilities_updated(&server, cx);
12844                    }
12845                }
12846                "workspace/didChangeConfiguration" => {
12847                    // Ignore payload since we notify clients of setting changes unconditionally, relying on them pulling the latest settings.
12848                }
12849                "workspace/didChangeWorkspaceFolders" => {
12850                    server.update_capabilities(|capabilities| {
12851                        capabilities
12852                            .workspace
12853                            .get_or_insert_with(|| lsp::WorkspaceServerCapabilities {
12854                                workspace_folders: None,
12855                                file_operations: None,
12856                            })
12857                            .workspace_folders = None;
12858                    });
12859                    notify_server_capabilities_updated(&server, cx);
12860                }
12861                "workspace/symbol" => {
12862                    server.update_capabilities(|capabilities| {
12863                        capabilities.workspace_symbol_provider = None
12864                    });
12865                    notify_server_capabilities_updated(&server, cx);
12866                }
12867                "workspace/fileOperations" => {
12868                    server.update_capabilities(|capabilities| {
12869                        capabilities
12870                            .workspace
12871                            .get_or_insert_with(|| lsp::WorkspaceServerCapabilities {
12872                                workspace_folders: None,
12873                                file_operations: None,
12874                            })
12875                            .file_operations = None;
12876                    });
12877                    notify_server_capabilities_updated(&server, cx);
12878                }
12879                "workspace/executeCommand" => {
12880                    server.update_capabilities(|capabilities| {
12881                        capabilities.execute_command_provider = None;
12882                    });
12883                    notify_server_capabilities_updated(&server, cx);
12884                }
12885                "textDocument/rangeFormatting" => {
12886                    server.update_capabilities(|capabilities| {
12887                        capabilities.document_range_formatting_provider = None
12888                    });
12889                    notify_server_capabilities_updated(&server, cx);
12890                }
12891                "textDocument/onTypeFormatting" => {
12892                    server.update_capabilities(|capabilities| {
12893                        capabilities.document_on_type_formatting_provider = None;
12894                    });
12895                    notify_server_capabilities_updated(&server, cx);
12896                }
12897                "textDocument/formatting" => {
12898                    server.update_capabilities(|capabilities| {
12899                        capabilities.document_formatting_provider = None;
12900                    });
12901                    notify_server_capabilities_updated(&server, cx);
12902                }
12903                "textDocument/rename" => {
12904                    server.update_capabilities(|capabilities| capabilities.rename_provider = None);
12905                    notify_server_capabilities_updated(&server, cx);
12906                }
12907                "textDocument/codeAction" => {
12908                    server.update_capabilities(|capabilities| {
12909                        capabilities.code_action_provider = None;
12910                    });
12911                    notify_server_capabilities_updated(&server, cx);
12912                }
12913                "textDocument/definition" => {
12914                    server.update_capabilities(|capabilities| {
12915                        capabilities.definition_provider = None;
12916                    });
12917                    notify_server_capabilities_updated(&server, cx);
12918                }
12919                "textDocument/completion" => {
12920                    server.update_capabilities(|capabilities| {
12921                        capabilities.completion_provider = None;
12922                    });
12923                    notify_server_capabilities_updated(&server, cx);
12924                }
12925                "textDocument/hover" => {
12926                    server.update_capabilities(|capabilities| {
12927                        capabilities.hover_provider = None;
12928                    });
12929                    notify_server_capabilities_updated(&server, cx);
12930                }
12931                "textDocument/signatureHelp" => {
12932                    server.update_capabilities(|capabilities| {
12933                        capabilities.signature_help_provider = None;
12934                    });
12935                    notify_server_capabilities_updated(&server, cx);
12936                }
12937                "textDocument/didChange" => {
12938                    server.update_capabilities(|capabilities| {
12939                        let mut sync_options = Self::take_text_document_sync_options(capabilities);
12940                        sync_options.change = None;
12941                        capabilities.text_document_sync =
12942                            Some(lsp::TextDocumentSyncCapability::Options(sync_options));
12943                    });
12944                    notify_server_capabilities_updated(&server, cx);
12945                }
12946                "textDocument/didSave" => {
12947                    server.update_capabilities(|capabilities| {
12948                        let mut sync_options = Self::take_text_document_sync_options(capabilities);
12949                        sync_options.save = None;
12950                        capabilities.text_document_sync =
12951                            Some(lsp::TextDocumentSyncCapability::Options(sync_options));
12952                    });
12953                    notify_server_capabilities_updated(&server, cx);
12954                }
12955                "textDocument/codeLens" => {
12956                    server.update_capabilities(|capabilities| {
12957                        capabilities.code_lens_provider = None;
12958                    });
12959                    notify_server_capabilities_updated(&server, cx);
12960                }
12961                "textDocument/diagnostic" => {
12962                    let local = self
12963                        .as_local_mut()
12964                        .context("Expected LSP Store to be local")?;
12965
12966                    let state = local
12967                        .language_servers
12968                        .get_mut(&server_id)
12969                        .context("Could not obtain Language Servers state")?;
12970                    let registrations = local
12971                        .language_server_dynamic_registrations
12972                        .get_mut(&server_id)
12973                        .with_context(|| {
12974                            format!("Expected dynamic registration to exist for server {server_id}")
12975                        })?;
12976                    registrations.diagnostics
12977                        .remove(&Some(unreg.id.clone()))
12978                        .with_context(|| format!(
12979                            "Attempted to unregister non-existent diagnostic registration with ID {}",
12980                            unreg.id)
12981                        )?;
12982                    let removed_last_diagnostic_provider = registrations.diagnostics.is_empty();
12983
12984                    if let LanguageServerState::Running {
12985                        workspace_diagnostics_refresh_tasks,
12986                        ..
12987                    } = state
12988                    {
12989                        workspace_diagnostics_refresh_tasks.remove(&Some(unreg.id.clone()));
12990                    }
12991
12992                    self.clear_unregistered_diagnostics(
12993                        server_id,
12994                        SharedString::from(unreg.id.clone()),
12995                        cx,
12996                    )?;
12997
12998                    if removed_last_diagnostic_provider {
12999                        server.update_capabilities(|capabilities| {
13000                            debug_assert!(capabilities.diagnostic_provider.is_some());
13001                            capabilities.diagnostic_provider = None;
13002                        });
13003                    }
13004
13005                    notify_server_capabilities_updated(&server, cx);
13006                }
13007                "textDocument/documentColor" => {
13008                    server.update_capabilities(|capabilities| {
13009                        capabilities.color_provider = None;
13010                    });
13011                    notify_server_capabilities_updated(&server, cx);
13012                }
13013                _ => log::warn!("unhandled capability unregistration: {unreg:?}"),
13014            }
13015        }
13016
13017        Ok(())
13018    }
13019
13020    fn clear_unregistered_diagnostics(
13021        &mut self,
13022        server_id: LanguageServerId,
13023        cleared_registration_id: SharedString,
13024        cx: &mut Context<Self>,
13025    ) -> anyhow::Result<()> {
13026        let mut affected_abs_paths: HashSet<PathBuf> = HashSet::default();
13027
13028        self.buffer_store.update(cx, |buffer_store, cx| {
13029            for buffer_handle in buffer_store.buffers() {
13030                let buffer = buffer_handle.read(cx);
13031                let abs_path = File::from_dyn(buffer.file()).map(|f| f.abs_path(cx));
13032                let Some(abs_path) = abs_path else {
13033                    continue;
13034                };
13035                affected_abs_paths.insert(abs_path);
13036            }
13037        });
13038
13039        let local = self.as_local().context("Expected LSP Store to be local")?;
13040        for (worktree_id, diagnostics_for_tree) in local.diagnostics.iter() {
13041            let Some(worktree) = self
13042                .worktree_store
13043                .read(cx)
13044                .worktree_for_id(*worktree_id, cx)
13045            else {
13046                continue;
13047            };
13048
13049            for (rel_path, diagnostics_by_server_id) in diagnostics_for_tree.iter() {
13050                if let Ok(ix) = diagnostics_by_server_id.binary_search_by_key(&server_id, |e| e.0) {
13051                    let has_matching_registration =
13052                        diagnostics_by_server_id[ix].1.iter().any(|entry| {
13053                            entry.diagnostic.registration_id.as_ref()
13054                                == Some(&cleared_registration_id)
13055                        });
13056                    if has_matching_registration {
13057                        let abs_path = worktree.read(cx).absolutize(rel_path);
13058                        affected_abs_paths.insert(abs_path);
13059                    }
13060                }
13061            }
13062        }
13063
13064        if affected_abs_paths.is_empty() {
13065            return Ok(());
13066        }
13067
13068        // Send a fake diagnostic update which clears the state for the registration ID
13069        let clears: Vec<DocumentDiagnosticsUpdate<'static, DocumentDiagnostics>> =
13070            affected_abs_paths
13071                .into_iter()
13072                .map(|abs_path| DocumentDiagnosticsUpdate {
13073                    diagnostics: DocumentDiagnostics {
13074                        diagnostics: Vec::new(),
13075                        document_abs_path: abs_path,
13076                        version: None,
13077                    },
13078                    result_id: None,
13079                    registration_id: Some(cleared_registration_id.clone()),
13080                    server_id,
13081                    disk_based_sources: Cow::Borrowed(&[]),
13082                })
13083                .collect();
13084
13085        let merge_registration_id = cleared_registration_id.clone();
13086        self.merge_diagnostic_entries(
13087            clears,
13088            move |_, diagnostic, _| {
13089                if diagnostic.source_kind == DiagnosticSourceKind::Pulled {
13090                    diagnostic.registration_id != Some(merge_registration_id.clone())
13091                } else {
13092                    true
13093                }
13094            },
13095            cx,
13096        )?;
13097
13098        Ok(())
13099    }
13100
13101    async fn deduplicate_range_based_lsp_requests<T>(
13102        lsp_store: &Entity<Self>,
13103        server_id: Option<LanguageServerId>,
13104        lsp_request_id: LspRequestId,
13105        proto_request: &T::ProtoRequest,
13106        range: Range<Anchor>,
13107        cx: &mut AsyncApp,
13108    ) -> Result<()>
13109    where
13110        T: LspCommand,
13111        T::ProtoRequest: proto::LspRequestMessage,
13112    {
13113        let buffer_id = BufferId::new(proto_request.buffer_id())?;
13114        let version = deserialize_version(proto_request.buffer_version());
13115        let buffer = lsp_store.update(cx, |this, cx| {
13116            this.buffer_store.read(cx).get_existing(buffer_id)
13117        })?;
13118        buffer
13119            .update(cx, |buffer, _| buffer.wait_for_version(version))
13120            .await?;
13121        lsp_store.update(cx, |lsp_store, cx| {
13122            let buffer_snapshot = buffer.read(cx).snapshot();
13123            let lsp_data = lsp_store.latest_lsp_data(&buffer, cx);
13124            let chunks_queried_for = lsp_data
13125                .inlay_hints
13126                .applicable_chunks(&[range.to_point(&buffer_snapshot)])
13127                .collect::<Vec<_>>();
13128            match chunks_queried_for.as_slice() {
13129                &[chunk] => {
13130                    let key = LspKey {
13131                        request_type: TypeId::of::<T>(),
13132                        server_queried: server_id,
13133                    };
13134                    let previous_request = lsp_data
13135                        .chunk_lsp_requests
13136                        .entry(key)
13137                        .or_default()
13138                        .insert(chunk, lsp_request_id);
13139                    if let Some((previous_request, running_requests)) =
13140                        previous_request.zip(lsp_data.lsp_requests.get_mut(&key))
13141                    {
13142                        running_requests.remove(&previous_request);
13143                    }
13144                }
13145                _ambiguous_chunks => {
13146                    // Have not found a unique chunk for the query range — be lenient and let the query to be spawned,
13147                    // there, a buffer version-based check will be performed and outdated requests discarded.
13148                }
13149            }
13150            anyhow::Ok(())
13151        })?;
13152
13153        Ok(())
13154    }
13155
13156    async fn query_lsp_locally<T>(
13157        lsp_store: Entity<Self>,
13158        for_server_id: Option<LanguageServerId>,
13159        sender_id: proto::PeerId,
13160        lsp_request_id: LspRequestId,
13161        proto_request: T::ProtoRequest,
13162        position: Option<Anchor>,
13163        cx: &mut AsyncApp,
13164    ) -> Result<()>
13165    where
13166        T: LspCommand + Clone,
13167        T::ProtoRequest: proto::LspRequestMessage,
13168        <T::ProtoRequest as proto::RequestMessage>::Response:
13169            Into<<T::ProtoRequest as proto::LspRequestMessage>::Response>,
13170    {
13171        let buffer_id = BufferId::new(proto_request.buffer_id())?;
13172        let version = deserialize_version(proto_request.buffer_version());
13173        let buffer = lsp_store.update(cx, |this, cx| {
13174            this.buffer_store.read(cx).get_existing(buffer_id)
13175        })?;
13176        buffer
13177            .update(cx, |buffer, _| buffer.wait_for_version(version.clone()))
13178            .await?;
13179        let buffer_version = buffer.read_with(cx, |buffer, _| buffer.version());
13180        let request =
13181            T::from_proto(proto_request, lsp_store.clone(), buffer.clone(), cx.clone()).await?;
13182        let key = LspKey {
13183            request_type: TypeId::of::<T>(),
13184            server_queried: for_server_id,
13185        };
13186        lsp_store.update(cx, |lsp_store, cx| {
13187            let request_task = match for_server_id {
13188                Some(server_id) => {
13189                    let server_task = lsp_store.request_lsp(
13190                        buffer.clone(),
13191                        LanguageServerToQuery::Other(server_id),
13192                        request.clone(),
13193                        cx,
13194                    );
13195                    cx.background_spawn(async move {
13196                        let mut responses = Vec::new();
13197                        match server_task.await {
13198                            Ok(response) => responses.push((server_id, response)),
13199                            // rust-analyzer likes to error with this when its still loading up
13200                            Err(e) if format!("{e:#}").ends_with("content modified") => (),
13201                            Err(e) => log::error!(
13202                                "Error handling response for request {request:?}: {e:#}"
13203                            ),
13204                        }
13205                        responses
13206                    })
13207                }
13208                None => lsp_store.request_multiple_lsp_locally(&buffer, position, request, cx),
13209            };
13210            let lsp_data = lsp_store.latest_lsp_data(&buffer, cx);
13211            if T::ProtoRequest::stop_previous_requests() {
13212                if let Some(lsp_requests) = lsp_data.lsp_requests.get_mut(&key) {
13213                    lsp_requests.clear();
13214                }
13215            }
13216            lsp_data.lsp_requests.entry(key).or_default().insert(
13217                lsp_request_id,
13218                cx.spawn(async move |lsp_store, cx| {
13219                    let response = request_task.await;
13220                    lsp_store
13221                        .update(cx, |lsp_store, cx| {
13222                            if let Some((client, project_id)) = lsp_store.downstream_client.clone()
13223                            {
13224                                let response = response
13225                                    .into_iter()
13226                                    .map(|(server_id, response)| {
13227                                        (
13228                                            server_id.to_proto(),
13229                                            T::response_to_proto(
13230                                                response,
13231                                                lsp_store,
13232                                                sender_id,
13233                                                &buffer_version,
13234                                                cx,
13235                                            )
13236                                            .into(),
13237                                        )
13238                                    })
13239                                    .collect::<HashMap<_, _>>();
13240                                match client.send_lsp_response::<T::ProtoRequest>(
13241                                    project_id,
13242                                    lsp_request_id,
13243                                    response,
13244                                ) {
13245                                    Ok(()) => {}
13246                                    Err(e) => {
13247                                        log::error!("Failed to send LSP response: {e:#}",)
13248                                    }
13249                                }
13250                            }
13251                        })
13252                        .ok();
13253                }),
13254            );
13255        });
13256        Ok(())
13257    }
13258
13259    fn take_text_document_sync_options(
13260        capabilities: &mut lsp::ServerCapabilities,
13261    ) -> lsp::TextDocumentSyncOptions {
13262        match capabilities.text_document_sync.take() {
13263            Some(lsp::TextDocumentSyncCapability::Options(sync_options)) => sync_options,
13264            Some(lsp::TextDocumentSyncCapability::Kind(sync_kind)) => {
13265                let mut sync_options = lsp::TextDocumentSyncOptions::default();
13266                sync_options.change = Some(sync_kind);
13267                sync_options
13268            }
13269            None => lsp::TextDocumentSyncOptions::default(),
13270        }
13271    }
13272
13273    #[cfg(any(test, feature = "test-support"))]
13274    pub fn forget_code_lens_task(&mut self, buffer_id: BufferId) -> Option<CodeLensTask> {
13275        Some(
13276            self.lsp_data
13277                .get_mut(&buffer_id)?
13278                .code_lens
13279                .take()?
13280                .update
13281                .take()?
13282                .1,
13283        )
13284    }
13285
13286    pub fn downstream_client(&self) -> Option<(AnyProtoClient, u64)> {
13287        self.downstream_client.clone()
13288    }
13289
13290    pub fn worktree_store(&self) -> Entity<WorktreeStore> {
13291        self.worktree_store.clone()
13292    }
13293
13294    /// Gets what's stored in the LSP data for the given buffer.
13295    pub fn current_lsp_data(&mut self, buffer_id: BufferId) -> Option<&mut BufferLspData> {
13296        self.lsp_data.get_mut(&buffer_id)
13297    }
13298
13299    /// Gets the most recent LSP data for the given buffer: if the data is absent or out of date,
13300    /// new [`BufferLspData`] will be created to replace the previous state.
13301    pub fn latest_lsp_data(&mut self, buffer: &Entity<Buffer>, cx: &mut App) -> &mut BufferLspData {
13302        let (buffer_id, buffer_version) =
13303            buffer.read_with(cx, |buffer, _| (buffer.remote_id(), buffer.version()));
13304        let lsp_data = self
13305            .lsp_data
13306            .entry(buffer_id)
13307            .or_insert_with(|| BufferLspData::new(buffer, cx));
13308        if buffer_version.changed_since(&lsp_data.buffer_version) {
13309            *lsp_data = BufferLspData::new(buffer, cx);
13310        }
13311        lsp_data
13312    }
13313}
13314
13315// Registration with registerOptions as null, should fallback to true.
13316// https://github.com/microsoft/vscode-languageserver-node/blob/d90a87f9557a0df9142cfb33e251cfa6fe27d970/client/src/common/client.ts#L2133
13317fn parse_register_capabilities<T: serde::de::DeserializeOwned>(
13318    reg: lsp::Registration,
13319) -> Result<OneOf<bool, T>> {
13320    Ok(match reg.register_options {
13321        Some(options) => OneOf::Right(serde_json::from_value::<T>(options)?),
13322        None => OneOf::Left(true),
13323    })
13324}
13325
13326fn subscribe_to_binary_statuses(
13327    languages: &Arc<LanguageRegistry>,
13328    cx: &mut Context<'_, LspStore>,
13329) -> Task<()> {
13330    let mut server_statuses = languages.language_server_binary_statuses();
13331    cx.spawn(async move |lsp_store, cx| {
13332        while let Some((server_name, binary_status)) = server_statuses.next().await {
13333            if lsp_store
13334                .update(cx, |_, cx| {
13335                    let mut message = None;
13336                    let binary_status = match binary_status {
13337                        BinaryStatus::None => proto::ServerBinaryStatus::None,
13338                        BinaryStatus::CheckingForUpdate => {
13339                            proto::ServerBinaryStatus::CheckingForUpdate
13340                        }
13341                        BinaryStatus::Downloading => proto::ServerBinaryStatus::Downloading,
13342                        BinaryStatus::Starting => proto::ServerBinaryStatus::Starting,
13343                        BinaryStatus::Stopping => proto::ServerBinaryStatus::Stopping,
13344                        BinaryStatus::Stopped => proto::ServerBinaryStatus::Stopped,
13345                        BinaryStatus::Failed { error } => {
13346                            message = Some(error);
13347                            proto::ServerBinaryStatus::Failed
13348                        }
13349                    };
13350                    cx.emit(LspStoreEvent::LanguageServerUpdate {
13351                        // Binary updates are about the binary that might not have any language server id at that point.
13352                        // Reuse `LanguageServerUpdate` for them and provide a fake id that won't be used on the receiver side.
13353                        language_server_id: LanguageServerId(0),
13354                        name: Some(server_name),
13355                        message: proto::update_language_server::Variant::StatusUpdate(
13356                            proto::StatusUpdate {
13357                                message,
13358                                status: Some(proto::status_update::Status::Binary(
13359                                    binary_status as i32,
13360                                )),
13361                            },
13362                        ),
13363                    });
13364                })
13365                .is_err()
13366            {
13367                break;
13368            }
13369        }
13370    })
13371}
13372
13373fn lsp_workspace_diagnostics_refresh(
13374    registration_id: Option<String>,
13375    options: DiagnosticServerCapabilities,
13376    server: Arc<LanguageServer>,
13377    cx: &mut Context<'_, LspStore>,
13378) -> Option<WorkspaceRefreshTask> {
13379    let identifier = workspace_diagnostic_identifier(&options)?;
13380    let registration_id_shared = registration_id.as_ref().map(SharedString::from);
13381
13382    let (progress_tx, mut progress_rx) = mpsc::channel(1);
13383    let (mut refresh_tx, mut refresh_rx) = mpsc::channel(1);
13384    refresh_tx.try_send(()).ok();
13385
13386    let workspace_query_language_server = cx.spawn(async move |lsp_store, cx| {
13387        let mut attempts = 0;
13388        let max_attempts = 50;
13389        let mut requests = 0;
13390
13391        loop {
13392            let Some(()) = refresh_rx.recv().await else {
13393                return;
13394            };
13395
13396            'request: loop {
13397                requests += 1;
13398                if attempts > max_attempts {
13399                    log::error!(
13400                        "Failed to pull workspace diagnostics {max_attempts} times, aborting"
13401                    );
13402                    return;
13403                }
13404                let backoff_millis = (50 * (1 << attempts)).clamp(30, 1000);
13405                cx.background_executor()
13406                    .timer(Duration::from_millis(backoff_millis))
13407                    .await;
13408                attempts += 1;
13409
13410                let Ok(previous_result_ids) = lsp_store.update(cx, |lsp_store, _| {
13411                    lsp_store
13412                        .result_ids_for_workspace_refresh(server.server_id(), &registration_id_shared)
13413                        .into_iter()
13414                        .filter_map(|(abs_path, result_id)| {
13415                            let uri = file_path_to_lsp_url(&abs_path).ok()?;
13416                            Some(lsp::PreviousResultId {
13417                                uri,
13418                                value: result_id.to_string(),
13419                            })
13420                        })
13421                        .collect()
13422                }) else {
13423                    return;
13424                };
13425
13426                let token = if let Some(registration_id) = &registration_id {
13427                    format!(
13428                        "workspace/diagnostic/{}/{requests}/{WORKSPACE_DIAGNOSTICS_TOKEN_START}{registration_id}",
13429                        server.server_id(),
13430                    )
13431                } else {
13432                    format!("workspace/diagnostic/{}/{requests}", server.server_id())
13433                };
13434
13435                progress_rx.try_recv().ok();
13436                let timer =
13437                    LanguageServer::default_request_timer(cx.background_executor().clone()).fuse();
13438                let progress = pin!(progress_rx.recv().fuse());
13439                let response_result = server
13440                    .request_with_timer::<lsp::WorkspaceDiagnosticRequest, _>(
13441                        lsp::WorkspaceDiagnosticParams {
13442                            previous_result_ids,
13443                            identifier: identifier.clone(),
13444                            work_done_progress_params: Default::default(),
13445                            partial_result_params: lsp::PartialResultParams {
13446                                partial_result_token: Some(lsp::ProgressToken::String(token)),
13447                            },
13448                        },
13449                        select(timer, progress).then(|either| match either {
13450                            Either::Left((message, ..)) => ready(message).left_future(),
13451                            Either::Right(..) => pending::<String>().right_future(),
13452                        }),
13453                    )
13454                    .await;
13455
13456                // https://microsoft.github.io/language-server-protocol/specifications/lsp/3.17/specification/#diagnostic_refresh
13457                // >  If a server closes a workspace diagnostic pull request the client should re-trigger the request.
13458                match response_result {
13459                    ConnectionResult::Timeout => {
13460                        log::error!("Timeout during workspace diagnostics pull");
13461                        continue 'request;
13462                    }
13463                    ConnectionResult::ConnectionReset => {
13464                        log::error!("Server closed a workspace diagnostics pull request");
13465                        continue 'request;
13466                    }
13467                    ConnectionResult::Result(Err(e)) => {
13468                        log::error!("Error during workspace diagnostics pull: {e:#}");
13469                        break 'request;
13470                    }
13471                    ConnectionResult::Result(Ok(pulled_diagnostics)) => {
13472                        attempts = 0;
13473                        if lsp_store
13474                            .update(cx, |lsp_store, cx| {
13475                                lsp_store.apply_workspace_diagnostic_report(
13476                                    server.server_id(),
13477                                    pulled_diagnostics,
13478                                    registration_id_shared.clone(),
13479                                    cx,
13480                                )
13481                            })
13482                            .is_err()
13483                        {
13484                            return;
13485                        }
13486                        break 'request;
13487                    }
13488                }
13489            }
13490        }
13491    });
13492
13493    Some(WorkspaceRefreshTask {
13494        refresh_tx,
13495        progress_tx,
13496        task: workspace_query_language_server,
13497    })
13498}
13499
13500fn buffer_diagnostic_identifier(options: &DiagnosticServerCapabilities) -> Option<String> {
13501    match &options {
13502        lsp::DiagnosticServerCapabilities::Options(diagnostic_options) => {
13503            diagnostic_options.identifier.clone()
13504        }
13505        lsp::DiagnosticServerCapabilities::RegistrationOptions(registration_options) => {
13506            let diagnostic_options = &registration_options.diagnostic_options;
13507            diagnostic_options.identifier.clone()
13508        }
13509    }
13510}
13511
13512fn workspace_diagnostic_identifier(
13513    options: &DiagnosticServerCapabilities,
13514) -> Option<Option<String>> {
13515    match &options {
13516        lsp::DiagnosticServerCapabilities::Options(diagnostic_options) => {
13517            if !diagnostic_options.workspace_diagnostics {
13518                return None;
13519            }
13520            Some(diagnostic_options.identifier.clone())
13521        }
13522        lsp::DiagnosticServerCapabilities::RegistrationOptions(registration_options) => {
13523            let diagnostic_options = &registration_options.diagnostic_options;
13524            if !diagnostic_options.workspace_diagnostics {
13525                return None;
13526            }
13527            Some(diagnostic_options.identifier.clone())
13528        }
13529    }
13530}
13531
13532fn resolve_word_completion(snapshot: &BufferSnapshot, completion: &mut Completion) {
13533    let CompletionSource::BufferWord {
13534        word_range,
13535        resolved,
13536    } = &mut completion.source
13537    else {
13538        return;
13539    };
13540    if *resolved {
13541        return;
13542    }
13543
13544    if completion.new_text
13545        != snapshot
13546            .text_for_range(word_range.clone())
13547            .collect::<String>()
13548    {
13549        return;
13550    }
13551
13552    let mut offset = 0;
13553    for chunk in snapshot.chunks(word_range.clone(), true) {
13554        let end_offset = offset + chunk.text.len();
13555        if let Some(highlight_id) = chunk.syntax_highlight_id {
13556            completion
13557                .label
13558                .runs
13559                .push((offset..end_offset, highlight_id));
13560        }
13561        offset = end_offset;
13562    }
13563    *resolved = true;
13564}
13565
13566impl EventEmitter<LspStoreEvent> for LspStore {}
13567
13568fn remove_empty_hover_blocks(mut hover: Hover) -> Option<Hover> {
13569    hover
13570        .contents
13571        .retain(|hover_block| !hover_block.text.trim().is_empty());
13572    if hover.contents.is_empty() {
13573        None
13574    } else {
13575        Some(hover)
13576    }
13577}
13578
13579async fn populate_labels_for_completions(
13580    new_completions: Vec<CoreCompletion>,
13581    language: Option<Arc<Language>>,
13582    lsp_adapter: Option<Arc<CachedLspAdapter>>,
13583) -> Vec<Completion> {
13584    let lsp_completions = new_completions
13585        .iter()
13586        .filter_map(|new_completion| {
13587            new_completion
13588                .source
13589                .lsp_completion(true)
13590                .map(|lsp_completion| lsp_completion.into_owned())
13591        })
13592        .collect::<Vec<_>>();
13593
13594    let mut labels = if let Some((language, lsp_adapter)) = language.as_ref().zip(lsp_adapter) {
13595        lsp_adapter
13596            .labels_for_completions(&lsp_completions, language)
13597            .await
13598            .log_err()
13599            .unwrap_or_default()
13600    } else {
13601        Vec::new()
13602    }
13603    .into_iter()
13604    .fuse();
13605
13606    let mut completions = Vec::new();
13607    for completion in new_completions {
13608        match completion.source.lsp_completion(true) {
13609            Some(lsp_completion) => {
13610                let documentation = lsp_completion.documentation.clone().map(|docs| docs.into());
13611
13612                let mut label = labels.next().flatten().unwrap_or_else(|| {
13613                    CodeLabel::fallback_for_completion(&lsp_completion, language.as_deref())
13614                });
13615                ensure_uniform_list_compatible_label(&mut label);
13616                completions.push(Completion {
13617                    label,
13618                    documentation,
13619                    replace_range: completion.replace_range,
13620                    new_text: completion.new_text,
13621                    insert_text_mode: lsp_completion.insert_text_mode,
13622                    source: completion.source,
13623                    icon_path: None,
13624                    confirm: None,
13625                    match_start: None,
13626                    snippet_deduplication_key: None,
13627                });
13628            }
13629            None => {
13630                let mut label = CodeLabel::plain(completion.new_text.clone(), None);
13631                ensure_uniform_list_compatible_label(&mut label);
13632                completions.push(Completion {
13633                    label,
13634                    documentation: None,
13635                    replace_range: completion.replace_range,
13636                    new_text: completion.new_text,
13637                    source: completion.source,
13638                    insert_text_mode: None,
13639                    icon_path: None,
13640                    confirm: None,
13641                    match_start: None,
13642                    snippet_deduplication_key: None,
13643                });
13644            }
13645        }
13646    }
13647    completions
13648}
13649
13650#[derive(Debug)]
13651pub enum LanguageServerToQuery {
13652    /// Query language servers in order of users preference, up until one capable of handling the request is found.
13653    FirstCapable,
13654    /// Query a specific language server.
13655    Other(LanguageServerId),
13656}
13657
13658#[derive(Default)]
13659struct RenamePathsWatchedForServer {
13660    did_rename: Vec<RenameActionPredicate>,
13661    will_rename: Vec<RenameActionPredicate>,
13662}
13663
13664impl RenamePathsWatchedForServer {
13665    fn with_did_rename_patterns(
13666        mut self,
13667        did_rename: Option<&FileOperationRegistrationOptions>,
13668    ) -> Self {
13669        if let Some(did_rename) = did_rename {
13670            self.did_rename = did_rename
13671                .filters
13672                .iter()
13673                .filter_map(|filter| filter.try_into().log_err())
13674                .collect();
13675        }
13676        self
13677    }
13678    fn with_will_rename_patterns(
13679        mut self,
13680        will_rename: Option<&FileOperationRegistrationOptions>,
13681    ) -> Self {
13682        if let Some(will_rename) = will_rename {
13683            self.will_rename = will_rename
13684                .filters
13685                .iter()
13686                .filter_map(|filter| filter.try_into().log_err())
13687                .collect();
13688        }
13689        self
13690    }
13691
13692    fn should_send_did_rename(&self, path: &str, is_dir: bool) -> bool {
13693        self.did_rename.iter().any(|pred| pred.eval(path, is_dir))
13694    }
13695    fn should_send_will_rename(&self, path: &str, is_dir: bool) -> bool {
13696        self.will_rename.iter().any(|pred| pred.eval(path, is_dir))
13697    }
13698}
13699
13700impl TryFrom<&FileOperationFilter> for RenameActionPredicate {
13701    type Error = globset::Error;
13702    fn try_from(ops: &FileOperationFilter) -> Result<Self, globset::Error> {
13703        Ok(Self {
13704            kind: ops.pattern.matches.clone(),
13705            glob: GlobBuilder::new(&ops.pattern.glob)
13706                .case_insensitive(
13707                    ops.pattern
13708                        .options
13709                        .as_ref()
13710                        .is_some_and(|ops| ops.ignore_case.unwrap_or(false)),
13711                )
13712                .build()?
13713                .compile_matcher(),
13714        })
13715    }
13716}
13717struct RenameActionPredicate {
13718    glob: GlobMatcher,
13719    kind: Option<FileOperationPatternKind>,
13720}
13721
13722impl RenameActionPredicate {
13723    // Returns true if language server should be notified
13724    fn eval(&self, path: &str, is_dir: bool) -> bool {
13725        self.kind.as_ref().is_none_or(|kind| {
13726            let expected_kind = if is_dir {
13727                FileOperationPatternKind::Folder
13728            } else {
13729                FileOperationPatternKind::File
13730            };
13731            kind == &expected_kind
13732        }) && self.glob.is_match(path)
13733    }
13734}
13735
13736#[derive(Default)]
13737struct LanguageServerWatchedPaths {
13738    worktree_paths: HashMap<WorktreeId, GlobSet>,
13739    abs_paths: HashMap<Arc<Path>, (GlobSet, Task<()>)>,
13740}
13741
13742#[derive(Default)]
13743struct LanguageServerWatchedPathsBuilder {
13744    worktree_paths: HashMap<WorktreeId, GlobSet>,
13745    abs_paths: HashMap<Arc<Path>, GlobSet>,
13746}
13747
13748impl LanguageServerWatchedPathsBuilder {
13749    fn watch_worktree(&mut self, worktree_id: WorktreeId, glob_set: GlobSet) {
13750        self.worktree_paths.insert(worktree_id, glob_set);
13751    }
13752    fn watch_abs_path(&mut self, path: Arc<Path>, glob_set: GlobSet) {
13753        self.abs_paths.insert(path, glob_set);
13754    }
13755    fn build(
13756        self,
13757        fs: Arc<dyn Fs>,
13758        language_server_id: LanguageServerId,
13759        cx: &mut Context<LspStore>,
13760    ) -> LanguageServerWatchedPaths {
13761        let lsp_store = cx.weak_entity();
13762
13763        const LSP_ABS_PATH_OBSERVE: Duration = Duration::from_millis(100);
13764        let abs_paths = self
13765            .abs_paths
13766            .into_iter()
13767            .map(|(abs_path, globset)| {
13768                let task = cx.spawn({
13769                    let abs_path = abs_path.clone();
13770                    let fs = fs.clone();
13771
13772                    let lsp_store = lsp_store.clone();
13773                    async move |_, cx| {
13774                        maybe!(async move {
13775                            let mut push_updates = fs.watch(&abs_path, LSP_ABS_PATH_OBSERVE).await;
13776                            while let Some(update) = push_updates.0.next().await {
13777                                let action = lsp_store
13778                                    .update(cx, |this, _| {
13779                                        let Some(local) = this.as_local() else {
13780                                            return ControlFlow::Break(());
13781                                        };
13782                                        let Some(watcher) = local
13783                                            .language_server_watched_paths
13784                                            .get(&language_server_id)
13785                                        else {
13786                                            return ControlFlow::Break(());
13787                                        };
13788                                        let (globs, _) = watcher.abs_paths.get(&abs_path).expect(
13789                                            "Watched abs path is not registered with a watcher",
13790                                        );
13791                                        let matching_entries = update
13792                                            .into_iter()
13793                                            .filter(|event| globs.is_match(&event.path))
13794                                            .collect::<Vec<_>>();
13795                                        this.lsp_notify_abs_paths_changed(
13796                                            language_server_id,
13797                                            matching_entries,
13798                                        );
13799                                        ControlFlow::Continue(())
13800                                    })
13801                                    .ok()?;
13802
13803                                if action.is_break() {
13804                                    break;
13805                                }
13806                            }
13807                            Some(())
13808                        })
13809                        .await;
13810                    }
13811                });
13812                (abs_path, (globset, task))
13813            })
13814            .collect();
13815        LanguageServerWatchedPaths {
13816            worktree_paths: self.worktree_paths,
13817            abs_paths,
13818        }
13819    }
13820}
13821
13822struct LspBufferSnapshot {
13823    version: i32,
13824    snapshot: TextBufferSnapshot,
13825}
13826
13827/// A prompt requested by LSP server.
13828#[derive(Clone, Debug)]
13829pub struct LanguageServerPromptRequest {
13830    pub id: usize,
13831    pub level: PromptLevel,
13832    pub message: String,
13833    pub actions: Vec<MessageActionItem>,
13834    pub lsp_name: String,
13835    pub(crate) response_channel: smol::channel::Sender<MessageActionItem>,
13836}
13837
13838impl LanguageServerPromptRequest {
13839    pub fn new(
13840        level: PromptLevel,
13841        message: String,
13842        actions: Vec<MessageActionItem>,
13843        lsp_name: String,
13844        response_channel: smol::channel::Sender<MessageActionItem>,
13845    ) -> Self {
13846        let id = NEXT_PROMPT_REQUEST_ID.fetch_add(1, atomic::Ordering::AcqRel);
13847        LanguageServerPromptRequest {
13848            id,
13849            level,
13850            message,
13851            actions,
13852            lsp_name,
13853            response_channel,
13854        }
13855    }
13856    pub async fn respond(self, index: usize) -> Option<()> {
13857        if let Some(response) = self.actions.into_iter().nth(index) {
13858            self.response_channel.send(response).await.ok()
13859        } else {
13860            None
13861        }
13862    }
13863
13864    #[cfg(any(test, feature = "test-support"))]
13865    pub fn test(
13866        level: PromptLevel,
13867        message: String,
13868        actions: Vec<MessageActionItem>,
13869        lsp_name: String,
13870    ) -> Self {
13871        let (tx, _rx) = smol::channel::unbounded();
13872        LanguageServerPromptRequest::new(level, message, actions, lsp_name, tx)
13873    }
13874}
13875impl PartialEq for LanguageServerPromptRequest {
13876    fn eq(&self, other: &Self) -> bool {
13877        self.message == other.message && self.actions == other.actions
13878    }
13879}
13880
13881#[derive(Clone, Debug, PartialEq)]
13882pub enum LanguageServerLogType {
13883    Log(MessageType),
13884    Trace { verbose_info: Option<String> },
13885    Rpc { received: bool },
13886}
13887
13888impl LanguageServerLogType {
13889    pub fn to_proto(&self) -> proto::language_server_log::LogType {
13890        match self {
13891            Self::Log(log_type) => {
13892                use proto::log_message::LogLevel;
13893                let level = match *log_type {
13894                    MessageType::ERROR => LogLevel::Error,
13895                    MessageType::WARNING => LogLevel::Warning,
13896                    MessageType::INFO => LogLevel::Info,
13897                    MessageType::LOG => LogLevel::Log,
13898                    other => {
13899                        log::warn!("Unknown lsp log message type: {other:?}");
13900                        LogLevel::Log
13901                    }
13902                };
13903                proto::language_server_log::LogType::Log(proto::LogMessage {
13904                    level: level as i32,
13905                })
13906            }
13907            Self::Trace { verbose_info } => {
13908                proto::language_server_log::LogType::Trace(proto::TraceMessage {
13909                    verbose_info: verbose_info.to_owned(),
13910                })
13911            }
13912            Self::Rpc { received } => {
13913                let kind = if *received {
13914                    proto::rpc_message::Kind::Received
13915                } else {
13916                    proto::rpc_message::Kind::Sent
13917                };
13918                let kind = kind as i32;
13919                proto::language_server_log::LogType::Rpc(proto::RpcMessage { kind })
13920            }
13921        }
13922    }
13923
13924    pub fn from_proto(log_type: proto::language_server_log::LogType) -> Self {
13925        use proto::log_message::LogLevel;
13926        use proto::rpc_message;
13927        match log_type {
13928            proto::language_server_log::LogType::Log(message_type) => Self::Log(
13929                match LogLevel::from_i32(message_type.level).unwrap_or(LogLevel::Log) {
13930                    LogLevel::Error => MessageType::ERROR,
13931                    LogLevel::Warning => MessageType::WARNING,
13932                    LogLevel::Info => MessageType::INFO,
13933                    LogLevel::Log => MessageType::LOG,
13934                },
13935            ),
13936            proto::language_server_log::LogType::Trace(trace_message) => Self::Trace {
13937                verbose_info: trace_message.verbose_info,
13938            },
13939            proto::language_server_log::LogType::Rpc(message) => Self::Rpc {
13940                received: match rpc_message::Kind::from_i32(message.kind)
13941                    .unwrap_or(rpc_message::Kind::Received)
13942                {
13943                    rpc_message::Kind::Received => true,
13944                    rpc_message::Kind::Sent => false,
13945                },
13946            },
13947        }
13948    }
13949}
13950
13951pub struct WorkspaceRefreshTask {
13952    refresh_tx: mpsc::Sender<()>,
13953    progress_tx: mpsc::Sender<()>,
13954    #[allow(dead_code)]
13955    task: Task<()>,
13956}
13957
13958pub enum LanguageServerState {
13959    Starting {
13960        startup: Task<Option<Arc<LanguageServer>>>,
13961        /// List of language servers that will be added to the workspace once it's initialization completes.
13962        pending_workspace_folders: Arc<Mutex<BTreeSet<Uri>>>,
13963    },
13964
13965    Running {
13966        adapter: Arc<CachedLspAdapter>,
13967        server: Arc<LanguageServer>,
13968        simulate_disk_based_diagnostics_completion: Option<Task<()>>,
13969        workspace_diagnostics_refresh_tasks: HashMap<Option<String>, WorkspaceRefreshTask>,
13970    },
13971}
13972
13973impl LanguageServerState {
13974    fn add_workspace_folder(&self, uri: Uri) {
13975        match self {
13976            LanguageServerState::Starting {
13977                pending_workspace_folders,
13978                ..
13979            } => {
13980                pending_workspace_folders.lock().insert(uri);
13981            }
13982            LanguageServerState::Running { server, .. } => {
13983                server.add_workspace_folder(uri);
13984            }
13985        }
13986    }
13987    fn _remove_workspace_folder(&self, uri: Uri) {
13988        match self {
13989            LanguageServerState::Starting {
13990                pending_workspace_folders,
13991                ..
13992            } => {
13993                pending_workspace_folders.lock().remove(&uri);
13994            }
13995            LanguageServerState::Running { server, .. } => server.remove_workspace_folder(uri),
13996        }
13997    }
13998}
13999
14000impl std::fmt::Debug for LanguageServerState {
14001    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
14002        match self {
14003            LanguageServerState::Starting { .. } => {
14004                f.debug_struct("LanguageServerState::Starting").finish()
14005            }
14006            LanguageServerState::Running { .. } => {
14007                f.debug_struct("LanguageServerState::Running").finish()
14008            }
14009        }
14010    }
14011}
14012
14013#[derive(Clone, Debug, Serialize)]
14014pub struct LanguageServerProgress {
14015    pub is_disk_based_diagnostics_progress: bool,
14016    pub is_cancellable: bool,
14017    pub title: Option<String>,
14018    pub message: Option<String>,
14019    pub percentage: Option<usize>,
14020    #[serde(skip_serializing)]
14021    pub last_update_at: Instant,
14022}
14023
14024#[derive(Copy, Clone, Debug, Default, PartialEq, Serialize)]
14025pub struct DiagnosticSummary {
14026    pub error_count: usize,
14027    pub warning_count: usize,
14028}
14029
14030impl DiagnosticSummary {
14031    pub fn new<'a, T: 'a>(diagnostics: impl IntoIterator<Item = &'a DiagnosticEntry<T>>) -> Self {
14032        let mut this = Self {
14033            error_count: 0,
14034            warning_count: 0,
14035        };
14036
14037        for entry in diagnostics {
14038            if entry.diagnostic.is_primary {
14039                match entry.diagnostic.severity {
14040                    DiagnosticSeverity::ERROR => this.error_count += 1,
14041                    DiagnosticSeverity::WARNING => this.warning_count += 1,
14042                    _ => {}
14043                }
14044            }
14045        }
14046
14047        this
14048    }
14049
14050    pub fn is_empty(&self) -> bool {
14051        self.error_count == 0 && self.warning_count == 0
14052    }
14053
14054    pub fn to_proto(
14055        self,
14056        language_server_id: LanguageServerId,
14057        path: &RelPath,
14058    ) -> proto::DiagnosticSummary {
14059        proto::DiagnosticSummary {
14060            path: path.to_proto(),
14061            language_server_id: language_server_id.0 as u64,
14062            error_count: self.error_count as u32,
14063            warning_count: self.warning_count as u32,
14064        }
14065    }
14066}
14067
14068#[derive(Clone, Debug)]
14069pub enum CompletionDocumentation {
14070    /// There is no documentation for this completion.
14071    Undocumented,
14072    /// A single line of documentation.
14073    SingleLine(SharedString),
14074    /// Multiple lines of plain text documentation.
14075    MultiLinePlainText(SharedString),
14076    /// Markdown documentation.
14077    MultiLineMarkdown(SharedString),
14078    /// Both single line and multiple lines of plain text documentation.
14079    SingleLineAndMultiLinePlainText {
14080        single_line: SharedString,
14081        plain_text: Option<SharedString>,
14082    },
14083}
14084
14085impl CompletionDocumentation {
14086    #[cfg(any(test, feature = "test-support"))]
14087    pub fn text(&self) -> SharedString {
14088        match self {
14089            CompletionDocumentation::Undocumented => "".into(),
14090            CompletionDocumentation::SingleLine(s) => s.clone(),
14091            CompletionDocumentation::MultiLinePlainText(s) => s.clone(),
14092            CompletionDocumentation::MultiLineMarkdown(s) => s.clone(),
14093            CompletionDocumentation::SingleLineAndMultiLinePlainText { single_line, .. } => {
14094                single_line.clone()
14095            }
14096        }
14097    }
14098}
14099
14100impl From<lsp::Documentation> for CompletionDocumentation {
14101    fn from(docs: lsp::Documentation) -> Self {
14102        match docs {
14103            lsp::Documentation::String(text) => {
14104                if text.lines().count() <= 1 {
14105                    CompletionDocumentation::SingleLine(text.trim().to_string().into())
14106                } else {
14107                    CompletionDocumentation::MultiLinePlainText(text.into())
14108                }
14109            }
14110
14111            lsp::Documentation::MarkupContent(lsp::MarkupContent { kind, value }) => match kind {
14112                lsp::MarkupKind::PlainText => {
14113                    if value.lines().count() <= 1 {
14114                        CompletionDocumentation::SingleLine(value.into())
14115                    } else {
14116                        CompletionDocumentation::MultiLinePlainText(value.into())
14117                    }
14118                }
14119
14120                lsp::MarkupKind::Markdown => {
14121                    CompletionDocumentation::MultiLineMarkdown(value.into())
14122                }
14123            },
14124        }
14125    }
14126}
14127
14128pub enum ResolvedHint {
14129    Resolved(InlayHint),
14130    Resolving(Shared<Task<()>>),
14131}
14132
14133pub fn glob_literal_prefix(glob: &Path) -> PathBuf {
14134    glob.components()
14135        .take_while(|component| match component {
14136            path::Component::Normal(part) => !part.to_string_lossy().contains(['*', '?', '{', '}']),
14137            _ => true,
14138        })
14139        .collect()
14140}
14141
14142pub struct SshLspAdapter {
14143    name: LanguageServerName,
14144    binary: LanguageServerBinary,
14145    initialization_options: Option<String>,
14146    code_action_kinds: Option<Vec<CodeActionKind>>,
14147}
14148
14149impl SshLspAdapter {
14150    pub fn new(
14151        name: LanguageServerName,
14152        binary: LanguageServerBinary,
14153        initialization_options: Option<String>,
14154        code_action_kinds: Option<String>,
14155    ) -> Self {
14156        Self {
14157            name,
14158            binary,
14159            initialization_options,
14160            code_action_kinds: code_action_kinds
14161                .as_ref()
14162                .and_then(|c| serde_json::from_str(c).ok()),
14163        }
14164    }
14165}
14166
14167impl LspInstaller for SshLspAdapter {
14168    type BinaryVersion = ();
14169    async fn check_if_user_installed(
14170        &self,
14171        _: &dyn LspAdapterDelegate,
14172        _: Option<Toolchain>,
14173        _: &AsyncApp,
14174    ) -> Option<LanguageServerBinary> {
14175        Some(self.binary.clone())
14176    }
14177
14178    async fn cached_server_binary(
14179        &self,
14180        _: PathBuf,
14181        _: &dyn LspAdapterDelegate,
14182    ) -> Option<LanguageServerBinary> {
14183        None
14184    }
14185
14186    async fn fetch_latest_server_version(
14187        &self,
14188        _: &dyn LspAdapterDelegate,
14189        _: bool,
14190        _: &mut AsyncApp,
14191    ) -> Result<()> {
14192        anyhow::bail!("SshLspAdapter does not support fetch_latest_server_version")
14193    }
14194
14195    async fn fetch_server_binary(
14196        &self,
14197        _: (),
14198        _: PathBuf,
14199        _: &dyn LspAdapterDelegate,
14200    ) -> Result<LanguageServerBinary> {
14201        anyhow::bail!("SshLspAdapter does not support fetch_server_binary")
14202    }
14203}
14204
14205#[async_trait(?Send)]
14206impl LspAdapter for SshLspAdapter {
14207    fn name(&self) -> LanguageServerName {
14208        self.name.clone()
14209    }
14210
14211    async fn initialization_options(
14212        self: Arc<Self>,
14213        _: &Arc<dyn LspAdapterDelegate>,
14214    ) -> Result<Option<serde_json::Value>> {
14215        let Some(options) = &self.initialization_options else {
14216            return Ok(None);
14217        };
14218        let result = serde_json::from_str(options)?;
14219        Ok(result)
14220    }
14221
14222    fn code_action_kinds(&self) -> Option<Vec<CodeActionKind>> {
14223        self.code_action_kinds.clone()
14224    }
14225}
14226
14227pub fn language_server_settings<'a>(
14228    delegate: &'a dyn LspAdapterDelegate,
14229    language: &LanguageServerName,
14230    cx: &'a App,
14231) -> Option<&'a LspSettings> {
14232    language_server_settings_for(
14233        SettingsLocation {
14234            worktree_id: delegate.worktree_id(),
14235            path: RelPath::empty(),
14236        },
14237        language,
14238        cx,
14239    )
14240}
14241
14242pub fn language_server_settings_for<'a>(
14243    location: SettingsLocation<'a>,
14244    language: &LanguageServerName,
14245    cx: &'a App,
14246) -> Option<&'a LspSettings> {
14247    ProjectSettings::get(Some(location), cx).lsp.get(language)
14248}
14249
14250pub struct LocalLspAdapterDelegate {
14251    lsp_store: WeakEntity<LspStore>,
14252    worktree: worktree::Snapshot,
14253    fs: Arc<dyn Fs>,
14254    http_client: Arc<dyn HttpClient>,
14255    language_registry: Arc<LanguageRegistry>,
14256    load_shell_env_task: Shared<Task<Option<HashMap<String, String>>>>,
14257}
14258
14259impl LocalLspAdapterDelegate {
14260    pub fn new(
14261        language_registry: Arc<LanguageRegistry>,
14262        environment: &Entity<ProjectEnvironment>,
14263        lsp_store: WeakEntity<LspStore>,
14264        worktree: &Entity<Worktree>,
14265        http_client: Arc<dyn HttpClient>,
14266        fs: Arc<dyn Fs>,
14267        cx: &mut App,
14268    ) -> Arc<Self> {
14269        let load_shell_env_task =
14270            environment.update(cx, |env, cx| env.worktree_environment(worktree.clone(), cx));
14271
14272        Arc::new(Self {
14273            lsp_store,
14274            worktree: worktree.read(cx).snapshot(),
14275            fs,
14276            http_client,
14277            language_registry,
14278            load_shell_env_task,
14279        })
14280    }
14281
14282    pub fn from_local_lsp(
14283        local: &LocalLspStore,
14284        worktree: &Entity<Worktree>,
14285        cx: &mut App,
14286    ) -> Arc<Self> {
14287        Self::new(
14288            local.languages.clone(),
14289            &local.environment,
14290            local.weak.clone(),
14291            worktree,
14292            local.http_client.clone(),
14293            local.fs.clone(),
14294            cx,
14295        )
14296    }
14297}
14298
14299#[async_trait]
14300impl LspAdapterDelegate for LocalLspAdapterDelegate {
14301    fn show_notification(&self, message: &str, cx: &mut App) {
14302        self.lsp_store
14303            .update(cx, |_, cx| {
14304                cx.emit(LspStoreEvent::Notification(message.to_owned()))
14305            })
14306            .ok();
14307    }
14308
14309    fn http_client(&self) -> Arc<dyn HttpClient> {
14310        self.http_client.clone()
14311    }
14312
14313    fn worktree_id(&self) -> WorktreeId {
14314        self.worktree.id()
14315    }
14316
14317    fn worktree_root_path(&self) -> &Path {
14318        self.worktree.abs_path().as_ref()
14319    }
14320
14321    fn resolve_executable_path(&self, path: PathBuf) -> PathBuf {
14322        self.worktree.resolve_executable_path(path)
14323    }
14324
14325    async fn shell_env(&self) -> HashMap<String, String> {
14326        let task = self.load_shell_env_task.clone();
14327        task.await.unwrap_or_default()
14328    }
14329
14330    async fn npm_package_installed_version(
14331        &self,
14332        package_name: &str,
14333    ) -> Result<Option<(PathBuf, Version)>> {
14334        let local_package_directory = self.worktree_root_path();
14335        let node_modules_directory = local_package_directory.join("node_modules");
14336
14337        if let Some(version) =
14338            read_package_installed_version(node_modules_directory.clone(), package_name).await?
14339        {
14340            return Ok(Some((node_modules_directory, version)));
14341        }
14342        let Some(npm) = self.which("npm".as_ref()).await else {
14343            log::warn!(
14344                "Failed to find npm executable for {:?}",
14345                local_package_directory
14346            );
14347            return Ok(None);
14348        };
14349
14350        let env = self.shell_env().await;
14351        let output = util::command::new_smol_command(&npm)
14352            .args(["root", "-g"])
14353            .envs(env)
14354            .current_dir(local_package_directory)
14355            .output()
14356            .await?;
14357        let global_node_modules =
14358            PathBuf::from(String::from_utf8_lossy(&output.stdout).to_string());
14359
14360        if let Some(version) =
14361            read_package_installed_version(global_node_modules.clone(), package_name).await?
14362        {
14363            return Ok(Some((global_node_modules, version)));
14364        }
14365        return Ok(None);
14366    }
14367
14368    async fn which(&self, command: &OsStr) -> Option<PathBuf> {
14369        let mut worktree_abs_path = self.worktree_root_path().to_path_buf();
14370        if self.fs.is_file(&worktree_abs_path).await {
14371            worktree_abs_path.pop();
14372        }
14373
14374        let env = self.shell_env().await;
14375
14376        let shell_path = env.get("PATH").cloned();
14377
14378        which::which_in(command, shell_path.as_ref(), worktree_abs_path).ok()
14379    }
14380
14381    async fn try_exec(&self, command: LanguageServerBinary) -> Result<()> {
14382        let mut working_dir = self.worktree_root_path().to_path_buf();
14383        if self.fs.is_file(&working_dir).await {
14384            working_dir.pop();
14385        }
14386        let output = util::command::new_smol_command(&command.path)
14387            .args(command.arguments)
14388            .envs(command.env.clone().unwrap_or_default())
14389            .current_dir(working_dir)
14390            .output()
14391            .await?;
14392
14393        anyhow::ensure!(
14394            output.status.success(),
14395            "{}, stdout: {:?}, stderr: {:?}",
14396            output.status,
14397            String::from_utf8_lossy(&output.stdout),
14398            String::from_utf8_lossy(&output.stderr)
14399        );
14400        Ok(())
14401    }
14402
14403    fn update_status(&self, server_name: LanguageServerName, status: language::BinaryStatus) {
14404        self.language_registry
14405            .update_lsp_binary_status(server_name, status);
14406    }
14407
14408    fn registered_lsp_adapters(&self) -> Vec<Arc<dyn LspAdapter>> {
14409        self.language_registry
14410            .all_lsp_adapters()
14411            .into_iter()
14412            .map(|adapter| adapter.adapter.clone() as Arc<dyn LspAdapter>)
14413            .collect()
14414    }
14415
14416    async fn language_server_download_dir(&self, name: &LanguageServerName) -> Option<Arc<Path>> {
14417        let dir = self.language_registry.language_server_download_dir(name)?;
14418
14419        if !dir.exists() {
14420            smol::fs::create_dir_all(&dir)
14421                .await
14422                .context("failed to create container directory")
14423                .log_err()?;
14424        }
14425
14426        Some(dir)
14427    }
14428
14429    async fn read_text_file(&self, path: &RelPath) -> Result<String> {
14430        let entry = self
14431            .worktree
14432            .entry_for_path(path)
14433            .with_context(|| format!("no worktree entry for path {path:?}"))?;
14434        let abs_path = self.worktree.absolutize(&entry.path);
14435        self.fs.load(&abs_path).await
14436    }
14437}
14438
14439async fn populate_labels_for_symbols(
14440    symbols: Vec<CoreSymbol>,
14441    language_registry: &Arc<LanguageRegistry>,
14442    lsp_adapter: Option<Arc<CachedLspAdapter>>,
14443    output: &mut Vec<Symbol>,
14444) {
14445    #[allow(clippy::mutable_key_type)]
14446    let mut symbols_by_language = HashMap::<Option<Arc<Language>>, Vec<CoreSymbol>>::default();
14447
14448    let mut unknown_paths = BTreeSet::<Arc<str>>::new();
14449    for symbol in symbols {
14450        let Some(file_name) = symbol.path.file_name() else {
14451            continue;
14452        };
14453        let language = language_registry
14454            .load_language_for_file_path(Path::new(file_name))
14455            .await
14456            .ok()
14457            .or_else(|| {
14458                unknown_paths.insert(file_name.into());
14459                None
14460            });
14461        symbols_by_language
14462            .entry(language)
14463            .or_default()
14464            .push(symbol);
14465    }
14466
14467    for unknown_path in unknown_paths {
14468        log::info!("no language found for symbol in file {unknown_path:?}");
14469    }
14470
14471    let mut label_params = Vec::new();
14472    for (language, mut symbols) in symbols_by_language {
14473        label_params.clear();
14474        label_params.extend(
14475            symbols
14476                .iter_mut()
14477                .map(|symbol| (mem::take(&mut symbol.name), symbol.kind)),
14478        );
14479
14480        let mut labels = Vec::new();
14481        if let Some(language) = language {
14482            let lsp_adapter = lsp_adapter.clone().or_else(|| {
14483                language_registry
14484                    .lsp_adapters(&language.name())
14485                    .first()
14486                    .cloned()
14487            });
14488            if let Some(lsp_adapter) = lsp_adapter {
14489                labels = lsp_adapter
14490                    .labels_for_symbols(&label_params, &language)
14491                    .await
14492                    .log_err()
14493                    .unwrap_or_default();
14494            }
14495        }
14496
14497        for ((symbol, (name, _)), label) in symbols
14498            .into_iter()
14499            .zip(label_params.drain(..))
14500            .zip(labels.into_iter().chain(iter::repeat(None)))
14501        {
14502            output.push(Symbol {
14503                language_server_name: symbol.language_server_name,
14504                source_worktree_id: symbol.source_worktree_id,
14505                source_language_server_id: symbol.source_language_server_id,
14506                path: symbol.path,
14507                label: label.unwrap_or_else(|| CodeLabel::plain(name.clone(), None)),
14508                name,
14509                kind: symbol.kind,
14510                range: symbol.range,
14511            });
14512        }
14513    }
14514}
14515
14516fn include_text(server: &lsp::LanguageServer) -> Option<bool> {
14517    match server.capabilities().text_document_sync.as_ref()? {
14518        lsp::TextDocumentSyncCapability::Options(opts) => match opts.save.as_ref()? {
14519            // Server wants didSave but didn't specify includeText.
14520            lsp::TextDocumentSyncSaveOptions::Supported(true) => Some(false),
14521            // Server doesn't want didSave at all.
14522            lsp::TextDocumentSyncSaveOptions::Supported(false) => None,
14523            // Server provided SaveOptions.
14524            lsp::TextDocumentSyncSaveOptions::SaveOptions(save_options) => {
14525                Some(save_options.include_text.unwrap_or(false))
14526            }
14527        },
14528        // We do not have any save info. Kind affects didChange only.
14529        lsp::TextDocumentSyncCapability::Kind(_) => None,
14530    }
14531}
14532
14533/// Completion items are displayed in a `UniformList`.
14534/// Usually, those items are single-line strings, but in LSP responses,
14535/// completion items `label`, `detail` and `label_details.description` may contain newlines or long spaces.
14536/// Many language plugins construct these items by joining these parts together, and we may use `CodeLabel::fallback_for_completion` that uses `label` at least.
14537/// 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,
14538/// breaking the completions menu presentation.
14539///
14540/// 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.
14541pub fn ensure_uniform_list_compatible_label(label: &mut CodeLabel) {
14542    let mut new_text = String::with_capacity(label.text.len());
14543    let mut offset_map = vec![0; label.text.len() + 1];
14544    let mut last_char_was_space = false;
14545    let mut new_idx = 0;
14546    let chars = label.text.char_indices().fuse();
14547    let mut newlines_removed = false;
14548
14549    for (idx, c) in chars {
14550        offset_map[idx] = new_idx;
14551
14552        match c {
14553            '\n' if last_char_was_space => {
14554                newlines_removed = true;
14555            }
14556            '\t' | ' ' if last_char_was_space => {}
14557            '\n' if !last_char_was_space => {
14558                new_text.push(' ');
14559                new_idx += 1;
14560                last_char_was_space = true;
14561                newlines_removed = true;
14562            }
14563            ' ' | '\t' => {
14564                new_text.push(' ');
14565                new_idx += 1;
14566                last_char_was_space = true;
14567            }
14568            _ => {
14569                new_text.push(c);
14570                new_idx += c.len_utf8();
14571                last_char_was_space = false;
14572            }
14573        }
14574    }
14575    offset_map[label.text.len()] = new_idx;
14576
14577    // Only modify the label if newlines were removed.
14578    if !newlines_removed {
14579        return;
14580    }
14581
14582    let last_index = new_idx;
14583    let mut run_ranges_errors = Vec::new();
14584    label.runs.retain_mut(|(range, _)| {
14585        match offset_map.get(range.start) {
14586            Some(&start) => range.start = start,
14587            None => {
14588                run_ranges_errors.push(range.clone());
14589                return false;
14590            }
14591        }
14592
14593        match offset_map.get(range.end) {
14594            Some(&end) => range.end = end,
14595            None => {
14596                run_ranges_errors.push(range.clone());
14597                range.end = last_index;
14598            }
14599        }
14600        true
14601    });
14602    if !run_ranges_errors.is_empty() {
14603        log::error!(
14604            "Completion label has errors in its run ranges: {run_ranges_errors:?}, label text: {}",
14605            label.text
14606        );
14607    }
14608
14609    let mut wrong_filter_range = None;
14610    if label.filter_range == (0..label.text.len()) {
14611        label.filter_range = 0..new_text.len();
14612    } else {
14613        let mut original_filter_range = Some(label.filter_range.clone());
14614        match offset_map.get(label.filter_range.start) {
14615            Some(&start) => label.filter_range.start = start,
14616            None => {
14617                wrong_filter_range = original_filter_range.take();
14618                label.filter_range.start = last_index;
14619            }
14620        }
14621
14622        match offset_map.get(label.filter_range.end) {
14623            Some(&end) => label.filter_range.end = end,
14624            None => {
14625                wrong_filter_range = original_filter_range.take();
14626                label.filter_range.end = last_index;
14627            }
14628        }
14629    }
14630    if let Some(wrong_filter_range) = wrong_filter_range {
14631        log::error!(
14632            "Completion label has an invalid filter range: {wrong_filter_range:?}, label text: {}",
14633            label.text
14634        );
14635    }
14636
14637    label.text = new_text;
14638}