lsp_store.rs

    1//! LSP store provides unified access to the language server protocol.
    2//! The consumers of LSP store can interact with language servers without knowing exactly which language server they're interacting with.
    3//!
    4//! # Local/Remote LSP Stores
    5//! This module is split up into three distinct parts:
    6//! - [`LocalLspStore`], which is ran on the host machine (either project host or SSH host), that manages the lifecycle of language servers.
    7//! - [`RemoteLspStore`], which is ran on the remote machine (project guests) which is mostly about passing through the requests via RPC.
    8//!   The remote stores don't really care about which language server they're running against - they don't usually get to decide which language server is going to responsible for handling their request.
    9//! - [`LspStore`], which unifies the two under one consistent interface for interacting with language servers.
   10//!
   11//! Most of the interesting work happens at the local layer, as bulk of the complexity is with managing the lifecycle of language servers. The actual implementation of the LSP protocol is handled by [`lsp`] crate.
   12pub mod clangd_ext;
   13pub mod json_language_server_ext;
   14pub mod log_store;
   15pub mod lsp_ext_command;
   16pub mod rust_analyzer_ext;
   17pub mod vue_language_server_ext;
   18
   19mod inlay_hint_cache;
   20
   21use self::inlay_hint_cache::BufferInlayHints;
   22use crate::{
   23    CodeAction, ColorPresentation, Completion, CompletionDisplayOptions, CompletionResponse,
   24    CompletionSource, CoreCompletion, DocumentColor, Hover, InlayHint, InlayId, LocationLink,
   25    LspAction, LspPullDiagnostics, ManifestProvidersStore, Project, ProjectItem, ProjectPath,
   26    ProjectTransaction, PulledDiagnostics, ResolveState, Symbol,
   27    buffer_store::{BufferStore, BufferStoreEvent},
   28    environment::ProjectEnvironment,
   29    lsp_command::{self, *},
   30    lsp_store::{
   31        self,
   32        log_store::{GlobalLogStore, LanguageServerKind},
   33    },
   34    manifest_tree::{
   35        LanguageServerTree, LanguageServerTreeNode, LaunchDisposition, ManifestQueryDelegate,
   36        ManifestTree,
   37    },
   38    prettier_store::{self, PrettierStore, PrettierStoreEvent},
   39    project_settings::{LspSettings, ProjectSettings},
   40    toolchain_store::{LocalToolchainStore, ToolchainStoreEvent},
   41    trusted_worktrees::{PathTrust, TrustedWorktrees, TrustedWorktreesEvent},
   42    worktree_store::{WorktreeStore, WorktreeStoreEvent},
   43    yarn::YarnPathStore,
   44};
   45use anyhow::{Context as _, Result, anyhow};
   46use async_trait::async_trait;
   47use client::{TypedEnvelope, proto};
   48use clock::Global;
   49use collections::{BTreeMap, BTreeSet, HashMap, HashSet, btree_map};
   50use futures::{
   51    AsyncWriteExt, Future, FutureExt, StreamExt,
   52    future::{Either, Shared, join_all, pending, select},
   53    select, select_biased,
   54    stream::FuturesUnordered,
   55};
   56use globset::{Glob, GlobBuilder, GlobMatcher, GlobSet, GlobSetBuilder};
   57use gpui::{
   58    App, AppContext, AsyncApp, Context, Entity, EventEmitter, PromptLevel, SharedString,
   59    Subscription, Task, WeakEntity,
   60};
   61use http_client::HttpClient;
   62use itertools::Itertools as _;
   63use language::{
   64    Bias, BinaryStatus, Buffer, BufferRow, BufferSnapshot, CachedLspAdapter, 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::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},
  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);
  148
  149#[derive(Debug, Clone, PartialEq, Eq, PartialOrd, Ord, Hash, Serialize)]
  150pub enum ProgressToken {
  151    Number(i32),
  152    String(SharedString),
  153}
  154
  155impl std::fmt::Display for ProgressToken {
  156    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
  157        match self {
  158            Self::Number(number) => write!(f, "{number}"),
  159            Self::String(string) => write!(f, "{string}"),
  160        }
  161    }
  162}
  163
  164impl ProgressToken {
  165    fn from_lsp(value: lsp::NumberOrString) -> Self {
  166        match value {
  167            lsp::NumberOrString::Number(number) => Self::Number(number),
  168            lsp::NumberOrString::String(string) => Self::String(SharedString::new(string)),
  169        }
  170    }
  171
  172    fn to_lsp(&self) -> lsp::NumberOrString {
  173        match self {
  174            Self::Number(number) => lsp::NumberOrString::Number(*number),
  175            Self::String(string) => lsp::NumberOrString::String(string.to_string()),
  176        }
  177    }
  178
  179    fn from_proto(value: proto::ProgressToken) -> Option<Self> {
  180        Some(match value.value? {
  181            proto::progress_token::Value::Number(number) => Self::Number(number),
  182            proto::progress_token::Value::String(string) => Self::String(SharedString::new(string)),
  183        })
  184    }
  185
  186    fn to_proto(&self) -> proto::ProgressToken {
  187        proto::ProgressToken {
  188            value: Some(match self {
  189                Self::Number(number) => proto::progress_token::Value::Number(*number),
  190                Self::String(string) => proto::progress_token::Value::String(string.to_string()),
  191            }),
  192        }
  193    }
  194}
  195
  196#[derive(Debug, Clone, Copy, PartialEq, Eq)]
  197pub enum FormatTrigger {
  198    Save,
  199    Manual,
  200}
  201
  202pub enum LspFormatTarget {
  203    Buffers,
  204    Ranges(BTreeMap<BufferId, Vec<Range<Anchor>>>),
  205}
  206
  207#[derive(Clone, PartialEq, Eq, Hash)]
  208pub struct OpenLspBufferHandle(Entity<OpenLspBuffer>);
  209
  210struct OpenLspBuffer(Entity<Buffer>);
  211
  212impl FormatTrigger {
  213    fn from_proto(value: i32) -> FormatTrigger {
  214        match value {
  215            0 => FormatTrigger::Save,
  216            1 => FormatTrigger::Manual,
  217            _ => FormatTrigger::Save,
  218        }
  219    }
  220}
  221
  222#[derive(Clone)]
  223struct UnifiedLanguageServer {
  224    id: LanguageServerId,
  225    project_roots: HashSet<Arc<RelPath>>,
  226}
  227
  228#[derive(Clone, Debug, Hash, PartialEq, Eq)]
  229struct LanguageServerSeed {
  230    worktree_id: WorktreeId,
  231    name: LanguageServerName,
  232    toolchain: Option<Toolchain>,
  233    settings: Arc<LspSettings>,
  234}
  235
  236#[derive(Debug)]
  237pub struct DocumentDiagnosticsUpdate<'a, D> {
  238    pub diagnostics: D,
  239    pub result_id: Option<SharedString>,
  240    pub registration_id: Option<SharedString>,
  241    pub server_id: LanguageServerId,
  242    pub disk_based_sources: Cow<'a, [String]>,
  243}
  244
  245pub struct DocumentDiagnostics {
  246    diagnostics: Vec<DiagnosticEntry<Unclipped<PointUtf16>>>,
  247    document_abs_path: PathBuf,
  248    version: Option<i32>,
  249}
  250
  251#[derive(Default, Debug)]
  252struct DynamicRegistrations {
  253    did_change_watched_files: HashMap<String, Vec<FileSystemWatcher>>,
  254    diagnostics: HashMap<Option<String>, DiagnosticServerCapabilities>,
  255}
  256
  257pub struct LocalLspStore {
  258    weak: WeakEntity<LspStore>,
  259    pub worktree_store: Entity<WorktreeStore>,
  260    toolchain_store: Entity<LocalToolchainStore>,
  261    http_client: Arc<dyn HttpClient>,
  262    environment: Entity<ProjectEnvironment>,
  263    fs: Arc<dyn Fs>,
  264    languages: Arc<LanguageRegistry>,
  265    language_server_ids: HashMap<LanguageServerSeed, UnifiedLanguageServer>,
  266    yarn: Entity<YarnPathStore>,
  267    pub language_servers: HashMap<LanguageServerId, LanguageServerState>,
  268    buffers_being_formatted: HashSet<BufferId>,
  269    last_workspace_edits_by_language_server: HashMap<LanguageServerId, ProjectTransaction>,
  270    language_server_watched_paths: HashMap<LanguageServerId, LanguageServerWatchedPaths>,
  271    watched_manifest_filenames: HashSet<ManifestName>,
  272    language_server_paths_watched_for_rename:
  273        HashMap<LanguageServerId, RenamePathsWatchedForServer>,
  274    language_server_dynamic_registrations: HashMap<LanguageServerId, DynamicRegistrations>,
  275    supplementary_language_servers:
  276        HashMap<LanguageServerId, (LanguageServerName, Arc<LanguageServer>)>,
  277    prettier_store: Entity<PrettierStore>,
  278    next_diagnostic_group_id: usize,
  279    diagnostics: HashMap<
  280        WorktreeId,
  281        HashMap<
  282            Arc<RelPath>,
  283            Vec<(
  284                LanguageServerId,
  285                Vec<DiagnosticEntry<Unclipped<PointUtf16>>>,
  286            )>,
  287        >,
  288    >,
  289    buffer_snapshots: HashMap<BufferId, HashMap<LanguageServerId, Vec<LspBufferSnapshot>>>, // buffer_id -> server_id -> vec of snapshots
  290    _subscription: gpui::Subscription,
  291    lsp_tree: LanguageServerTree,
  292    registered_buffers: HashMap<BufferId, usize>,
  293    buffers_opened_in_servers: HashMap<BufferId, HashSet<LanguageServerId>>,
  294    buffer_pull_diagnostics_result_ids: HashMap<
  295        LanguageServerId,
  296        HashMap<Option<SharedString>, HashMap<PathBuf, Option<SharedString>>>,
  297    >,
  298    workspace_pull_diagnostics_result_ids: HashMap<
  299        LanguageServerId,
  300        HashMap<Option<SharedString>, HashMap<PathBuf, Option<SharedString>>>,
  301    >,
  302    restricted_worktrees_tasks: HashMap<WorktreeId, (Subscription, watch::Receiver<bool>)>,
  303}
  304
  305impl LocalLspStore {
  306    /// Returns the running language server for the given ID. Note if the language server is starting, it will not be returned.
  307    pub fn running_language_server_for_id(
  308        &self,
  309        id: LanguageServerId,
  310    ) -> Option<&Arc<LanguageServer>> {
  311        let language_server_state = self.language_servers.get(&id)?;
  312
  313        match language_server_state {
  314            LanguageServerState::Running { server, .. } => Some(server),
  315            LanguageServerState::Starting { .. } => None,
  316        }
  317    }
  318
  319    fn get_or_insert_language_server(
  320        &mut self,
  321        worktree_handle: &Entity<Worktree>,
  322        delegate: Arc<LocalLspAdapterDelegate>,
  323        disposition: &Arc<LaunchDisposition>,
  324        language_name: &LanguageName,
  325        cx: &mut App,
  326    ) -> LanguageServerId {
  327        let key = LanguageServerSeed {
  328            worktree_id: worktree_handle.read(cx).id(),
  329            name: disposition.server_name.clone(),
  330            settings: disposition.settings.clone(),
  331            toolchain: disposition.toolchain.clone(),
  332        };
  333        if let Some(state) = self.language_server_ids.get_mut(&key) {
  334            state.project_roots.insert(disposition.path.path.clone());
  335            state.id
  336        } else {
  337            let adapter = self
  338                .languages
  339                .lsp_adapters(language_name)
  340                .into_iter()
  341                .find(|adapter| adapter.name() == disposition.server_name)
  342                .expect("To find LSP adapter");
  343            let new_language_server_id = self.start_language_server(
  344                worktree_handle,
  345                delegate,
  346                adapter,
  347                disposition.settings.clone(),
  348                key.clone(),
  349                cx,
  350            );
  351            if let Some(state) = self.language_server_ids.get_mut(&key) {
  352                state.project_roots.insert(disposition.path.path.clone());
  353            } else {
  354                debug_assert!(
  355                    false,
  356                    "Expected `start_language_server` to ensure that `key` exists in a map"
  357                );
  358            }
  359            new_language_server_id
  360        }
  361    }
  362
  363    fn start_language_server(
  364        &mut self,
  365        worktree_handle: &Entity<Worktree>,
  366        delegate: Arc<LocalLspAdapterDelegate>,
  367        adapter: Arc<CachedLspAdapter>,
  368        settings: Arc<LspSettings>,
  369        key: LanguageServerSeed,
  370        cx: &mut App,
  371    ) -> LanguageServerId {
  372        let worktree = worktree_handle.read(cx);
  373
  374        let worktree_id = worktree.id();
  375        let worktree_abs_path = worktree.abs_path();
  376        let toolchain = key.toolchain.clone();
  377        let override_options = settings.initialization_options.clone();
  378
  379        let stderr_capture = Arc::new(Mutex::new(Some(String::new())));
  380
  381        let server_id = self.languages.next_language_server_id();
  382        log::trace!(
  383            "attempting to start language server {:?}, path: {worktree_abs_path:?}, id: {server_id}",
  384            adapter.name.0
  385        );
  386
  387        let wait_until_worktree_trust =
  388            TrustedWorktrees::try_get_global(cx).and_then(|trusted_worktrees| {
  389                let can_trust = trusted_worktrees.update(cx, |trusted_worktrees, cx| {
  390                    trusted_worktrees.can_trust(&self.worktree_store, worktree_id, cx)
  391                });
  392                if can_trust {
  393                    self.restricted_worktrees_tasks.remove(&worktree_id);
  394                    None
  395                } else {
  396                    match self.restricted_worktrees_tasks.entry(worktree_id) {
  397                        hash_map::Entry::Occupied(o) => Some(o.get().1.clone()),
  398                        hash_map::Entry::Vacant(v) => {
  399                            let (mut tx, rx) = watch::channel::<bool>();
  400                            let lsp_store = self.weak.clone();
  401                            let subscription = cx.subscribe(&trusted_worktrees, move |_, e, cx| {
  402                                if let TrustedWorktreesEvent::Trusted(_, trusted_paths) = e {
  403                                    if trusted_paths.contains(&PathTrust::Worktree(worktree_id)) {
  404                                        tx.blocking_send(true).ok();
  405                                        lsp_store
  406                                            .update(cx, |lsp_store, _| {
  407                                                if let Some(local_lsp_store) =
  408                                                    lsp_store.as_local_mut()
  409                                                {
  410                                                    local_lsp_store
  411                                                        .restricted_worktrees_tasks
  412                                                        .remove(&worktree_id);
  413                                                }
  414                                            })
  415                                            .ok();
  416                                    }
  417                                }
  418                            });
  419                            v.insert((subscription, rx.clone()));
  420                            Some(rx)
  421                        }
  422                    }
  423                }
  424            });
  425        let update_binary_status = wait_until_worktree_trust.is_none();
  426
  427        let binary = self.get_language_server_binary(
  428            worktree_abs_path.clone(),
  429            adapter.clone(),
  430            settings,
  431            toolchain.clone(),
  432            delegate.clone(),
  433            true,
  434            wait_until_worktree_trust,
  435            cx,
  436        );
  437        let pending_workspace_folders = Arc::<Mutex<BTreeSet<Uri>>>::default();
  438
  439        let pending_server = cx.spawn({
  440            let adapter = adapter.clone();
  441            let server_name = adapter.name.clone();
  442            let stderr_capture = stderr_capture.clone();
  443            #[cfg(any(test, feature = "test-support"))]
  444            let lsp_store = self.weak.clone();
  445            let pending_workspace_folders = pending_workspace_folders.clone();
  446            async move |cx| {
  447                let binary = binary.await?;
  448                #[cfg(any(test, feature = "test-support"))]
  449                if let Some(server) = lsp_store
  450                    .update(&mut cx.clone(), |this, cx| {
  451                        this.languages.create_fake_language_server(
  452                            server_id,
  453                            &server_name,
  454                            binary.clone(),
  455                            &mut cx.to_async(),
  456                        )
  457                    })
  458                    .ok()
  459                    .flatten()
  460                {
  461                    return Ok(server);
  462                }
  463
  464                let code_action_kinds = adapter.code_action_kinds();
  465                lsp::LanguageServer::new(
  466                    stderr_capture,
  467                    server_id,
  468                    server_name,
  469                    binary,
  470                    &worktree_abs_path,
  471                    code_action_kinds,
  472                    Some(pending_workspace_folders),
  473                    cx,
  474                )
  475            }
  476        });
  477
  478        let startup = {
  479            let server_name = adapter.name.0.clone();
  480            let delegate = delegate as Arc<dyn LspAdapterDelegate>;
  481            let key = key.clone();
  482            let adapter = adapter.clone();
  483            let lsp_store = self.weak.clone();
  484            let pending_workspace_folders = pending_workspace_folders.clone();
  485
  486            let pull_diagnostics = ProjectSettings::get_global(cx)
  487                .diagnostics
  488                .lsp_pull_diagnostics
  489                .enabled;
  490            cx.spawn(async move |cx| {
  491                let result = async {
  492                    let language_server = pending_server.await?;
  493
  494                    let workspace_config = Self::workspace_configuration_for_adapter(
  495                        adapter.adapter.clone(),
  496                        &delegate,
  497                        toolchain,
  498                        None,
  499                        cx,
  500                    )
  501                    .await?;
  502
  503                    let mut initialization_options = Self::initialization_options_for_adapter(
  504                        adapter.adapter.clone(),
  505                        &delegate,
  506                    )
  507                    .await?;
  508
  509                    match (&mut initialization_options, override_options) {
  510                        (Some(initialization_options), Some(override_options)) => {
  511                            merge_json_value_into(override_options, initialization_options);
  512                        }
  513                        (None, override_options) => initialization_options = override_options,
  514                        _ => {}
  515                    }
  516
  517                    let initialization_params = cx.update(|cx| {
  518                        let mut params =
  519                            language_server.default_initialize_params(pull_diagnostics, cx);
  520                        params.initialization_options = initialization_options;
  521                        adapter.adapter.prepare_initialize_params(params, cx)
  522                    })?;
  523
  524                    Self::setup_lsp_messages(
  525                        lsp_store.clone(),
  526                        &language_server,
  527                        delegate.clone(),
  528                        adapter.clone(),
  529                    );
  530
  531                    let did_change_configuration_params = lsp::DidChangeConfigurationParams {
  532                        settings: workspace_config,
  533                    };
  534                    let language_server = cx
  535                        .update(|cx| {
  536                            language_server.initialize(
  537                                initialization_params,
  538                                Arc::new(did_change_configuration_params.clone()),
  539                                cx,
  540                            )
  541                        })
  542                        .await
  543                        .inspect_err(|_| {
  544                            if let Some(lsp_store) = lsp_store.upgrade() {
  545                                lsp_store.update(cx, |lsp_store, cx| {
  546                                    lsp_store.cleanup_lsp_data(server_id);
  547                                    cx.emit(LspStoreEvent::LanguageServerRemoved(server_id))
  548                                });
  549                            }
  550                        })?;
  551
  552                    language_server.notify::<lsp::notification::DidChangeConfiguration>(
  553                        did_change_configuration_params,
  554                    )?;
  555
  556                    anyhow::Ok(language_server)
  557                }
  558                .await;
  559
  560                match result {
  561                    Ok(server) => {
  562                        lsp_store
  563                            .update(cx, |lsp_store, cx| {
  564                                lsp_store.insert_newly_running_language_server(
  565                                    adapter,
  566                                    server.clone(),
  567                                    server_id,
  568                                    key,
  569                                    pending_workspace_folders,
  570                                    cx,
  571                                );
  572                            })
  573                            .ok();
  574                        stderr_capture.lock().take();
  575                        Some(server)
  576                    }
  577
  578                    Err(err) => {
  579                        let log = stderr_capture.lock().take().unwrap_or_default();
  580                        delegate.update_status(
  581                            adapter.name(),
  582                            BinaryStatus::Failed {
  583                                error: if log.is_empty() {
  584                                    format!("{err:#}")
  585                                } else {
  586                                    format!("{err:#}\n-- stderr --\n{log}")
  587                                },
  588                            },
  589                        );
  590                        log::error!(
  591                            "Failed to start language server {server_name:?}: {}",
  592                            redact_command(&format!("{err:?}"))
  593                        );
  594                        if !log.is_empty() {
  595                            log::error!("server stderr: {}", redact_command(&log));
  596                        }
  597                        None
  598                    }
  599                }
  600            })
  601        };
  602        let state = LanguageServerState::Starting {
  603            startup,
  604            pending_workspace_folders,
  605        };
  606
  607        if update_binary_status {
  608            self.languages
  609                .update_lsp_binary_status(adapter.name(), BinaryStatus::Starting);
  610        }
  611
  612        self.language_servers.insert(server_id, state);
  613        self.language_server_ids
  614            .entry(key)
  615            .or_insert(UnifiedLanguageServer {
  616                id: server_id,
  617                project_roots: Default::default(),
  618            });
  619        server_id
  620    }
  621
  622    fn get_language_server_binary(
  623        &self,
  624        worktree_abs_path: Arc<Path>,
  625        adapter: Arc<CachedLspAdapter>,
  626        settings: Arc<LspSettings>,
  627        toolchain: Option<Toolchain>,
  628        delegate: Arc<dyn LspAdapterDelegate>,
  629        allow_binary_download: bool,
  630        wait_until_worktree_trust: Option<watch::Receiver<bool>>,
  631        cx: &mut App,
  632    ) -> Task<Result<LanguageServerBinary>> {
  633        if let Some(settings) = &settings.binary
  634            && let Some(path) = settings.path.as_ref().map(PathBuf::from)
  635        {
  636            let settings = settings.clone();
  637            let languages = self.languages.clone();
  638            return cx.background_spawn(async move {
  639                if let Some(mut wait_until_worktree_trust) = wait_until_worktree_trust {
  640                    let already_trusted =  *wait_until_worktree_trust.borrow();
  641                    if !already_trusted {
  642                        log::info!(
  643                            "Waiting for worktree {worktree_abs_path:?} to be trusted, before starting language server {}",
  644                            adapter.name(),
  645                        );
  646                        while let Some(worktree_trusted) = wait_until_worktree_trust.recv().await {
  647                            if worktree_trusted {
  648                                break;
  649                            }
  650                        }
  651                        log::info!(
  652                            "Worktree {worktree_abs_path:?} is trusted, starting language server {}",
  653                            adapter.name(),
  654                        );
  655                    }
  656                    languages
  657                        .update_lsp_binary_status(adapter.name(), BinaryStatus::Starting);
  658                }
  659                let mut env = delegate.shell_env().await;
  660                env.extend(settings.env.unwrap_or_default());
  661
  662                Ok(LanguageServerBinary {
  663                    path: delegate.resolve_executable_path(path),
  664                    env: Some(env),
  665                    arguments: settings
  666                        .arguments
  667                        .unwrap_or_default()
  668                        .iter()
  669                        .map(Into::into)
  670                        .collect(),
  671                })
  672            });
  673        }
  674        let lsp_binary_options = LanguageServerBinaryOptions {
  675            allow_path_lookup: !settings
  676                .binary
  677                .as_ref()
  678                .and_then(|b| b.ignore_system_version)
  679                .unwrap_or_default(),
  680            allow_binary_download,
  681            pre_release: settings
  682                .fetch
  683                .as_ref()
  684                .and_then(|f| f.pre_release)
  685                .unwrap_or(false),
  686        };
  687
  688        cx.spawn(async move |cx| {
  689            if let Some(mut wait_until_worktree_trust) = wait_until_worktree_trust {
  690                let already_trusted =  *wait_until_worktree_trust.borrow();
  691                if !already_trusted {
  692                    log::info!(
  693                        "Waiting for worktree {worktree_abs_path:?} to be trusted, before starting language server {}",
  694                        adapter.name(),
  695                    );
  696                    while let Some(worktree_trusted) = wait_until_worktree_trust.recv().await {
  697                        if worktree_trusted {
  698                            break;
  699                        }
  700                    }
  701                    log::info!(
  702                        "Worktree {worktree_abs_path:?} is trusted, starting language server {}",
  703                            adapter.name(),
  704                    );
  705                }
  706            }
  707
  708            let (existing_binary, maybe_download_binary) = adapter
  709                .clone()
  710                .get_language_server_command(delegate.clone(), toolchain, lsp_binary_options, cx)
  711                .await
  712                .await;
  713
  714            delegate.update_status(adapter.name.clone(), BinaryStatus::None);
  715
  716            let mut binary = match (existing_binary, maybe_download_binary) {
  717                (binary, None) => binary?,
  718                (Err(_), Some(downloader)) => downloader.await?,
  719                (Ok(existing_binary), Some(downloader)) => {
  720                    let mut download_timeout = cx
  721                        .background_executor()
  722                        .timer(SERVER_DOWNLOAD_TIMEOUT)
  723                        .fuse();
  724                    let mut downloader = downloader.fuse();
  725                    futures::select! {
  726                        _ = download_timeout => {
  727                            // Return existing binary and kick the existing work to the background.
  728                            cx.spawn(async move |_| downloader.await).detach();
  729                            Ok(existing_binary)
  730                        },
  731                        downloaded_or_existing_binary = downloader => {
  732                            // If download fails, this results in the existing binary.
  733                            downloaded_or_existing_binary
  734                        }
  735                    }?
  736                }
  737            };
  738            let mut shell_env = delegate.shell_env().await;
  739
  740            shell_env.extend(binary.env.unwrap_or_default());
  741
  742            if let Some(settings) = settings.binary.as_ref() {
  743                if let Some(arguments) = &settings.arguments {
  744                    binary.arguments = arguments.iter().map(Into::into).collect();
  745                }
  746                if let Some(env) = &settings.env {
  747                    shell_env.extend(env.iter().map(|(k, v)| (k.clone(), v.clone())));
  748                }
  749            }
  750
  751            binary.env = Some(shell_env);
  752            Ok(binary)
  753        })
  754    }
  755
  756    fn setup_lsp_messages(
  757        lsp_store: WeakEntity<LspStore>,
  758        language_server: &LanguageServer,
  759        delegate: Arc<dyn LspAdapterDelegate>,
  760        adapter: Arc<CachedLspAdapter>,
  761    ) {
  762        let name = language_server.name();
  763        let server_id = language_server.server_id();
  764        language_server
  765            .on_notification::<lsp::notification::PublishDiagnostics, _>({
  766                let adapter = adapter.clone();
  767                let this = lsp_store.clone();
  768                move |mut params, cx| {
  769                    let adapter = adapter.clone();
  770                    if let Some(this) = this.upgrade() {
  771                        this.update(cx, |this, cx| {
  772                            {
  773                                let buffer = params
  774                                    .uri
  775                                    .to_file_path()
  776                                    .map(|file_path| this.get_buffer(&file_path, cx))
  777                                    .ok()
  778                                    .flatten();
  779                                adapter.process_diagnostics(&mut params, server_id, buffer);
  780                            }
  781
  782                            this.merge_lsp_diagnostics(
  783                                DiagnosticSourceKind::Pushed,
  784                                vec![DocumentDiagnosticsUpdate {
  785                                    server_id,
  786                                    diagnostics: params,
  787                                    result_id: None,
  788                                    disk_based_sources: Cow::Borrowed(
  789                                        &adapter.disk_based_diagnostic_sources,
  790                                    ),
  791                                    registration_id: None,
  792                                }],
  793                                |_, diagnostic, cx| match diagnostic.source_kind {
  794                                    DiagnosticSourceKind::Other | DiagnosticSourceKind::Pushed => {
  795                                        adapter.retain_old_diagnostic(diagnostic, cx)
  796                                    }
  797                                    DiagnosticSourceKind::Pulled => true,
  798                                },
  799                                cx,
  800                            )
  801                            .log_err();
  802                        });
  803                    }
  804                }
  805            })
  806            .detach();
  807        language_server
  808            .on_request::<lsp::request::WorkspaceConfiguration, _, _>({
  809                let adapter = adapter.adapter.clone();
  810                let delegate = delegate.clone();
  811                let this = lsp_store.clone();
  812                move |params, cx| {
  813                    let adapter = adapter.clone();
  814                    let delegate = delegate.clone();
  815                    let this = this.clone();
  816                    let mut cx = cx.clone();
  817                    async move {
  818                        let toolchain_for_id = this
  819                            .update(&mut cx, |this, _| {
  820                                this.as_local()?.language_server_ids.iter().find_map(
  821                                    |(seed, value)| {
  822                                        (value.id == server_id).then(|| seed.toolchain.clone())
  823                                    },
  824                                )
  825                            })?
  826                            .context("Expected the LSP store to be in a local mode")?;
  827
  828                        let mut scope_uri_to_workspace_config = BTreeMap::new();
  829                        for item in &params.items {
  830                            let scope_uri = item.scope_uri.clone();
  831                            let std::collections::btree_map::Entry::Vacant(new_scope_uri) =
  832                                scope_uri_to_workspace_config.entry(scope_uri.clone())
  833                            else {
  834                                // We've already queried workspace configuration of this URI.
  835                                continue;
  836                            };
  837                            let workspace_config = Self::workspace_configuration_for_adapter(
  838                                adapter.clone(),
  839                                &delegate,
  840                                toolchain_for_id.clone(),
  841                                scope_uri,
  842                                &mut cx,
  843                            )
  844                            .await?;
  845                            new_scope_uri.insert(workspace_config);
  846                        }
  847
  848                        Ok(params
  849                            .items
  850                            .into_iter()
  851                            .filter_map(|item| {
  852                                let workspace_config =
  853                                    scope_uri_to_workspace_config.get(&item.scope_uri)?;
  854                                if let Some(section) = &item.section {
  855                                    Some(
  856                                        workspace_config
  857                                            .get(section)
  858                                            .cloned()
  859                                            .unwrap_or(serde_json::Value::Null),
  860                                    )
  861                                } else {
  862                                    Some(workspace_config.clone())
  863                                }
  864                            })
  865                            .collect())
  866                    }
  867                }
  868            })
  869            .detach();
  870
  871        language_server
  872            .on_request::<lsp::request::WorkspaceFoldersRequest, _, _>({
  873                let this = lsp_store.clone();
  874                move |_, cx| {
  875                    let this = this.clone();
  876                    let cx = cx.clone();
  877                    async move {
  878                        let Some(server) =
  879                            this.read_with(&cx, |this, _| this.language_server_for_id(server_id))?
  880                        else {
  881                            return Ok(None);
  882                        };
  883                        let root = server.workspace_folders();
  884                        Ok(Some(
  885                            root.into_iter()
  886                                .map(|uri| WorkspaceFolder {
  887                                    uri,
  888                                    name: Default::default(),
  889                                })
  890                                .collect(),
  891                        ))
  892                    }
  893                }
  894            })
  895            .detach();
  896        // Even though we don't have handling for these requests, respond to them to
  897        // avoid stalling any language server like `gopls` which waits for a response
  898        // to these requests when initializing.
  899        language_server
  900            .on_request::<lsp::request::WorkDoneProgressCreate, _, _>({
  901                let this = lsp_store.clone();
  902                move |params, cx| {
  903                    let this = this.clone();
  904                    let mut cx = cx.clone();
  905                    async move {
  906                        this.update(&mut cx, |this, _| {
  907                            if let Some(status) = this.language_server_statuses.get_mut(&server_id)
  908                            {
  909                                status
  910                                    .progress_tokens
  911                                    .insert(ProgressToken::from_lsp(params.token));
  912                            }
  913                        })?;
  914
  915                        Ok(())
  916                    }
  917                }
  918            })
  919            .detach();
  920
  921        language_server
  922            .on_request::<lsp::request::RegisterCapability, _, _>({
  923                let lsp_store = lsp_store.clone();
  924                move |params, cx| {
  925                    let lsp_store = lsp_store.clone();
  926                    let mut cx = cx.clone();
  927                    async move {
  928                        lsp_store
  929                            .update(&mut cx, |lsp_store, cx| {
  930                                if lsp_store.as_local().is_some() {
  931                                    match lsp_store
  932                                        .register_server_capabilities(server_id, params, cx)
  933                                    {
  934                                        Ok(()) => {}
  935                                        Err(e) => {
  936                                            log::error!(
  937                                                "Failed to register server capabilities: {e:#}"
  938                                            );
  939                                        }
  940                                    };
  941                                }
  942                            })
  943                            .ok();
  944                        Ok(())
  945                    }
  946                }
  947            })
  948            .detach();
  949
  950        language_server
  951            .on_request::<lsp::request::UnregisterCapability, _, _>({
  952                let lsp_store = lsp_store.clone();
  953                move |params, cx| {
  954                    let lsp_store = lsp_store.clone();
  955                    let mut cx = cx.clone();
  956                    async move {
  957                        lsp_store
  958                            .update(&mut cx, |lsp_store, cx| {
  959                                if lsp_store.as_local().is_some() {
  960                                    match lsp_store
  961                                        .unregister_server_capabilities(server_id, params, cx)
  962                                    {
  963                                        Ok(()) => {}
  964                                        Err(e) => {
  965                                            log::error!(
  966                                                "Failed to unregister server capabilities: {e:#}"
  967                                            );
  968                                        }
  969                                    }
  970                                }
  971                            })
  972                            .ok();
  973                        Ok(())
  974                    }
  975                }
  976            })
  977            .detach();
  978
  979        language_server
  980            .on_request::<lsp::request::ApplyWorkspaceEdit, _, _>({
  981                let this = lsp_store.clone();
  982                move |params, cx| {
  983                    let mut cx = cx.clone();
  984                    let this = this.clone();
  985                    async move {
  986                        LocalLspStore::on_lsp_workspace_edit(
  987                            this.clone(),
  988                            params,
  989                            server_id,
  990                            &mut cx,
  991                        )
  992                        .await
  993                    }
  994                }
  995            })
  996            .detach();
  997
  998        language_server
  999            .on_request::<lsp::request::InlayHintRefreshRequest, _, _>({
 1000                let lsp_store = lsp_store.clone();
 1001                let request_id = Arc::new(AtomicUsize::new(0));
 1002                move |(), cx| {
 1003                    let lsp_store = lsp_store.clone();
 1004                    let request_id = request_id.clone();
 1005                    let mut cx = cx.clone();
 1006                    async move {
 1007                        lsp_store
 1008                            .update(&mut cx, |lsp_store, cx| {
 1009                                let request_id =
 1010                                    Some(request_id.fetch_add(1, atomic::Ordering::AcqRel));
 1011                                cx.emit(LspStoreEvent::RefreshInlayHints {
 1012                                    server_id,
 1013                                    request_id,
 1014                                });
 1015                                lsp_store
 1016                                    .downstream_client
 1017                                    .as_ref()
 1018                                    .map(|(client, project_id)| {
 1019                                        client.send(proto::RefreshInlayHints {
 1020                                            project_id: *project_id,
 1021                                            server_id: server_id.to_proto(),
 1022                                            request_id: request_id.map(|id| id as u64),
 1023                                        })
 1024                                    })
 1025                            })?
 1026                            .transpose()?;
 1027                        Ok(())
 1028                    }
 1029                }
 1030            })
 1031            .detach();
 1032
 1033        language_server
 1034            .on_request::<lsp::request::CodeLensRefresh, _, _>({
 1035                let this = lsp_store.clone();
 1036                move |(), cx| {
 1037                    let this = this.clone();
 1038                    let mut cx = cx.clone();
 1039                    async move {
 1040                        this.update(&mut cx, |this, cx| {
 1041                            cx.emit(LspStoreEvent::RefreshCodeLens);
 1042                            this.downstream_client.as_ref().map(|(client, project_id)| {
 1043                                client.send(proto::RefreshCodeLens {
 1044                                    project_id: *project_id,
 1045                                })
 1046                            })
 1047                        })?
 1048                        .transpose()?;
 1049                        Ok(())
 1050                    }
 1051                }
 1052            })
 1053            .detach();
 1054
 1055        language_server
 1056            .on_request::<lsp::request::WorkspaceDiagnosticRefresh, _, _>({
 1057                let this = lsp_store.clone();
 1058                move |(), cx| {
 1059                    let this = this.clone();
 1060                    let mut cx = cx.clone();
 1061                    async move {
 1062                        this.update(&mut cx, |lsp_store, cx| {
 1063                            lsp_store.pull_workspace_diagnostics(server_id);
 1064                            lsp_store
 1065                                .downstream_client
 1066                                .as_ref()
 1067                                .map(|(client, project_id)| {
 1068                                    client.send(proto::PullWorkspaceDiagnostics {
 1069                                        project_id: *project_id,
 1070                                        server_id: server_id.to_proto(),
 1071                                    })
 1072                                })
 1073                                .transpose()?;
 1074                            anyhow::Ok(
 1075                                lsp_store.pull_document_diagnostics_for_server(server_id, cx),
 1076                            )
 1077                        })??
 1078                        .await;
 1079                        Ok(())
 1080                    }
 1081                }
 1082            })
 1083            .detach();
 1084
 1085        language_server
 1086            .on_request::<lsp::request::ShowMessageRequest, _, _>({
 1087                let this = lsp_store.clone();
 1088                let name = name.to_string();
 1089                let adapter = adapter.clone();
 1090                move |params, cx| {
 1091                    let this = this.clone();
 1092                    let name = name.to_string();
 1093                    let adapter = adapter.clone();
 1094                    let mut cx = cx.clone();
 1095                    async move {
 1096                        let actions = params.actions.unwrap_or_default();
 1097                        let message = params.message.clone();
 1098                        let (tx, rx) = smol::channel::bounded(1);
 1099                        let request = LanguageServerPromptRequest {
 1100                            level: match params.typ {
 1101                                lsp::MessageType::ERROR => PromptLevel::Critical,
 1102                                lsp::MessageType::WARNING => PromptLevel::Warning,
 1103                                _ => PromptLevel::Info,
 1104                            },
 1105                            message: params.message,
 1106                            actions,
 1107                            response_channel: tx,
 1108                            lsp_name: name.clone(),
 1109                        };
 1110
 1111                        let did_update = this
 1112                            .update(&mut cx, |_, cx| {
 1113                                cx.emit(LspStoreEvent::LanguageServerPrompt(request));
 1114                            })
 1115                            .is_ok();
 1116                        if did_update {
 1117                            let response = rx.recv().await.ok();
 1118                            if let Some(ref selected_action) = response {
 1119                                let context = language::PromptResponseContext {
 1120                                    message,
 1121                                    selected_action: selected_action.clone(),
 1122                                };
 1123                                adapter.process_prompt_response(&context, &mut cx)
 1124                            }
 1125
 1126                            Ok(response)
 1127                        } else {
 1128                            Ok(None)
 1129                        }
 1130                    }
 1131                }
 1132            })
 1133            .detach();
 1134        language_server
 1135            .on_notification::<lsp::notification::ShowMessage, _>({
 1136                let this = lsp_store.clone();
 1137                let name = name.to_string();
 1138                move |params, cx| {
 1139                    let this = this.clone();
 1140                    let name = name.to_string();
 1141                    let mut cx = cx.clone();
 1142
 1143                    let (tx, _) = smol::channel::bounded(1);
 1144                    let request = LanguageServerPromptRequest {
 1145                        level: match params.typ {
 1146                            lsp::MessageType::ERROR => PromptLevel::Critical,
 1147                            lsp::MessageType::WARNING => PromptLevel::Warning,
 1148                            _ => PromptLevel::Info,
 1149                        },
 1150                        message: params.message,
 1151                        actions: vec![],
 1152                        response_channel: tx,
 1153                        lsp_name: name,
 1154                    };
 1155
 1156                    let _ = this.update(&mut cx, |_, cx| {
 1157                        cx.emit(LspStoreEvent::LanguageServerPrompt(request));
 1158                    });
 1159                }
 1160            })
 1161            .detach();
 1162
 1163        let disk_based_diagnostics_progress_token =
 1164            adapter.disk_based_diagnostics_progress_token.clone();
 1165
 1166        language_server
 1167            .on_notification::<lsp::notification::Progress, _>({
 1168                let this = lsp_store.clone();
 1169                move |params, cx| {
 1170                    if let Some(this) = this.upgrade() {
 1171                        this.update(cx, |this, cx| {
 1172                            this.on_lsp_progress(
 1173                                params,
 1174                                server_id,
 1175                                disk_based_diagnostics_progress_token.clone(),
 1176                                cx,
 1177                            );
 1178                        });
 1179                    }
 1180                }
 1181            })
 1182            .detach();
 1183
 1184        language_server
 1185            .on_notification::<lsp::notification::LogMessage, _>({
 1186                let this = lsp_store.clone();
 1187                move |params, cx| {
 1188                    if let Some(this) = this.upgrade() {
 1189                        this.update(cx, |_, cx| {
 1190                            cx.emit(LspStoreEvent::LanguageServerLog(
 1191                                server_id,
 1192                                LanguageServerLogType::Log(params.typ),
 1193                                params.message,
 1194                            ));
 1195                        });
 1196                    }
 1197                }
 1198            })
 1199            .detach();
 1200
 1201        language_server
 1202            .on_notification::<lsp::notification::LogTrace, _>({
 1203                let this = lsp_store.clone();
 1204                move |params, cx| {
 1205                    let mut cx = cx.clone();
 1206                    if let Some(this) = this.upgrade() {
 1207                        this.update(&mut cx, |_, cx| {
 1208                            cx.emit(LspStoreEvent::LanguageServerLog(
 1209                                server_id,
 1210                                LanguageServerLogType::Trace {
 1211                                    verbose_info: params.verbose,
 1212                                },
 1213                                params.message,
 1214                            ));
 1215                        });
 1216                    }
 1217                }
 1218            })
 1219            .detach();
 1220
 1221        vue_language_server_ext::register_requests(lsp_store.clone(), language_server);
 1222        json_language_server_ext::register_requests(lsp_store.clone(), language_server);
 1223        rust_analyzer_ext::register_notifications(lsp_store.clone(), language_server);
 1224        clangd_ext::register_notifications(lsp_store, language_server, adapter);
 1225    }
 1226
 1227    fn shutdown_language_servers_on_quit(
 1228        &mut self,
 1229        _: &mut Context<LspStore>,
 1230    ) -> impl Future<Output = ()> + use<> {
 1231        let shutdown_futures = self
 1232            .language_servers
 1233            .drain()
 1234            .map(|(_, server_state)| Self::shutdown_server(server_state))
 1235            .collect::<Vec<_>>();
 1236
 1237        async move {
 1238            join_all(shutdown_futures).await;
 1239        }
 1240    }
 1241
 1242    async fn shutdown_server(server_state: LanguageServerState) -> anyhow::Result<()> {
 1243        match server_state {
 1244            LanguageServerState::Running { server, .. } => {
 1245                if let Some(shutdown) = server.shutdown() {
 1246                    shutdown.await;
 1247                }
 1248            }
 1249            LanguageServerState::Starting { startup, .. } => {
 1250                if let Some(server) = startup.await
 1251                    && let Some(shutdown) = server.shutdown()
 1252                {
 1253                    shutdown.await;
 1254                }
 1255            }
 1256        }
 1257        Ok(())
 1258    }
 1259
 1260    fn language_servers_for_worktree(
 1261        &self,
 1262        worktree_id: WorktreeId,
 1263    ) -> impl Iterator<Item = &Arc<LanguageServer>> {
 1264        self.language_server_ids
 1265            .iter()
 1266            .filter_map(move |(seed, state)| {
 1267                if seed.worktree_id != worktree_id {
 1268                    return None;
 1269                }
 1270
 1271                if let Some(LanguageServerState::Running { server, .. }) =
 1272                    self.language_servers.get(&state.id)
 1273                {
 1274                    Some(server)
 1275                } else {
 1276                    None
 1277                }
 1278            })
 1279    }
 1280
 1281    fn language_server_ids_for_project_path(
 1282        &self,
 1283        project_path: ProjectPath,
 1284        language: &Language,
 1285        cx: &mut App,
 1286    ) -> Vec<LanguageServerId> {
 1287        let Some(worktree) = self
 1288            .worktree_store
 1289            .read(cx)
 1290            .worktree_for_id(project_path.worktree_id, cx)
 1291        else {
 1292            return Vec::new();
 1293        };
 1294        let delegate: Arc<dyn ManifestDelegate> =
 1295            Arc::new(ManifestQueryDelegate::new(worktree.read(cx).snapshot()));
 1296
 1297        self.lsp_tree
 1298            .get(
 1299                project_path,
 1300                language.name(),
 1301                language.manifest(),
 1302                &delegate,
 1303                cx,
 1304            )
 1305            .collect::<Vec<_>>()
 1306    }
 1307
 1308    fn language_server_ids_for_buffer(
 1309        &self,
 1310        buffer: &Buffer,
 1311        cx: &mut App,
 1312    ) -> Vec<LanguageServerId> {
 1313        if let Some((file, language)) = File::from_dyn(buffer.file()).zip(buffer.language()) {
 1314            let worktree_id = file.worktree_id(cx);
 1315
 1316            let path: Arc<RelPath> = file
 1317                .path()
 1318                .parent()
 1319                .map(Arc::from)
 1320                .unwrap_or_else(|| file.path().clone());
 1321            let worktree_path = ProjectPath { worktree_id, path };
 1322            self.language_server_ids_for_project_path(worktree_path, language, cx)
 1323        } else {
 1324            Vec::new()
 1325        }
 1326    }
 1327
 1328    fn language_servers_for_buffer<'a>(
 1329        &'a self,
 1330        buffer: &'a Buffer,
 1331        cx: &'a mut App,
 1332    ) -> impl Iterator<Item = (&'a Arc<CachedLspAdapter>, &'a Arc<LanguageServer>)> {
 1333        self.language_server_ids_for_buffer(buffer, cx)
 1334            .into_iter()
 1335            .filter_map(|server_id| match self.language_servers.get(&server_id)? {
 1336                LanguageServerState::Running {
 1337                    adapter, server, ..
 1338                } => Some((adapter, server)),
 1339                _ => None,
 1340            })
 1341    }
 1342
 1343    async fn execute_code_action_kind_locally(
 1344        lsp_store: WeakEntity<LspStore>,
 1345        mut buffers: Vec<Entity<Buffer>>,
 1346        kind: CodeActionKind,
 1347        push_to_history: bool,
 1348        cx: &mut AsyncApp,
 1349    ) -> anyhow::Result<ProjectTransaction> {
 1350        // Do not allow multiple concurrent code actions requests for the
 1351        // same buffer.
 1352        lsp_store.update(cx, |this, cx| {
 1353            let this = this.as_local_mut().unwrap();
 1354            buffers.retain(|buffer| {
 1355                this.buffers_being_formatted
 1356                    .insert(buffer.read(cx).remote_id())
 1357            });
 1358        })?;
 1359        let _cleanup = defer({
 1360            let this = lsp_store.clone();
 1361            let mut cx = cx.clone();
 1362            let buffers = &buffers;
 1363            move || {
 1364                this.update(&mut cx, |this, cx| {
 1365                    let this = this.as_local_mut().unwrap();
 1366                    for buffer in buffers {
 1367                        this.buffers_being_formatted
 1368                            .remove(&buffer.read(cx).remote_id());
 1369                    }
 1370                })
 1371                .ok();
 1372            }
 1373        });
 1374        let mut project_transaction = ProjectTransaction::default();
 1375
 1376        for buffer in &buffers {
 1377            let adapters_and_servers = lsp_store.update(cx, |lsp_store, cx| {
 1378                buffer.update(cx, |buffer, cx| {
 1379                    lsp_store
 1380                        .as_local()
 1381                        .unwrap()
 1382                        .language_servers_for_buffer(buffer, cx)
 1383                        .map(|(adapter, lsp)| (adapter.clone(), lsp.clone()))
 1384                        .collect::<Vec<_>>()
 1385                })
 1386            })?;
 1387            for (_, language_server) in adapters_and_servers.iter() {
 1388                let actions = Self::get_server_code_actions_from_action_kinds(
 1389                    &lsp_store,
 1390                    language_server.server_id(),
 1391                    vec![kind.clone()],
 1392                    buffer,
 1393                    cx,
 1394                )
 1395                .await?;
 1396                Self::execute_code_actions_on_server(
 1397                    &lsp_store,
 1398                    language_server,
 1399                    actions,
 1400                    push_to_history,
 1401                    &mut project_transaction,
 1402                    cx,
 1403                )
 1404                .await?;
 1405            }
 1406        }
 1407        Ok(project_transaction)
 1408    }
 1409
 1410    async fn format_locally(
 1411        lsp_store: WeakEntity<LspStore>,
 1412        mut buffers: Vec<FormattableBuffer>,
 1413        push_to_history: bool,
 1414        trigger: FormatTrigger,
 1415        logger: zlog::Logger,
 1416        cx: &mut AsyncApp,
 1417    ) -> anyhow::Result<ProjectTransaction> {
 1418        // Do not allow multiple concurrent formatting requests for the
 1419        // same buffer.
 1420        lsp_store.update(cx, |this, cx| {
 1421            let this = this.as_local_mut().unwrap();
 1422            buffers.retain(|buffer| {
 1423                this.buffers_being_formatted
 1424                    .insert(buffer.handle.read(cx).remote_id())
 1425            });
 1426        })?;
 1427
 1428        let _cleanup = defer({
 1429            let this = lsp_store.clone();
 1430            let mut cx = cx.clone();
 1431            let buffers = &buffers;
 1432            move || {
 1433                this.update(&mut cx, |this, cx| {
 1434                    let this = this.as_local_mut().unwrap();
 1435                    for buffer in buffers {
 1436                        this.buffers_being_formatted
 1437                            .remove(&buffer.handle.read(cx).remote_id());
 1438                    }
 1439                })
 1440                .ok();
 1441            }
 1442        });
 1443
 1444        let mut project_transaction = ProjectTransaction::default();
 1445
 1446        for buffer in &buffers {
 1447            zlog::debug!(
 1448                logger =>
 1449                "formatting buffer '{:?}'",
 1450                buffer.abs_path.as_ref().unwrap_or(&PathBuf::from("unknown")).display()
 1451            );
 1452            // Create an empty transaction to hold all of the formatting edits.
 1453            let formatting_transaction_id = buffer.handle.update(cx, |buffer, cx| {
 1454                // ensure no transactions created while formatting are
 1455                // grouped with the previous transaction in the history
 1456                // based on the transaction group interval
 1457                buffer.finalize_last_transaction();
 1458                buffer
 1459                    .start_transaction()
 1460                    .context("transaction already open")?;
 1461                buffer.end_transaction(cx);
 1462                let transaction_id = buffer.push_empty_transaction(cx.background_executor().now());
 1463                buffer.finalize_last_transaction();
 1464                anyhow::Ok(transaction_id)
 1465            })?;
 1466
 1467            let result = Self::format_buffer_locally(
 1468                lsp_store.clone(),
 1469                buffer,
 1470                formatting_transaction_id,
 1471                trigger,
 1472                logger,
 1473                cx,
 1474            )
 1475            .await;
 1476
 1477            buffer.handle.update(cx, |buffer, cx| {
 1478                let Some(formatting_transaction) =
 1479                    buffer.get_transaction(formatting_transaction_id).cloned()
 1480                else {
 1481                    zlog::warn!(logger => "no formatting transaction");
 1482                    return;
 1483                };
 1484                if formatting_transaction.edit_ids.is_empty() {
 1485                    zlog::debug!(logger => "no changes made while formatting");
 1486                    buffer.forget_transaction(formatting_transaction_id);
 1487                    return;
 1488                }
 1489                if !push_to_history {
 1490                    zlog::trace!(logger => "forgetting format transaction");
 1491                    buffer.forget_transaction(formatting_transaction.id);
 1492                }
 1493                project_transaction
 1494                    .0
 1495                    .insert(cx.entity(), formatting_transaction);
 1496            });
 1497
 1498            result?;
 1499        }
 1500
 1501        Ok(project_transaction)
 1502    }
 1503
 1504    async fn format_buffer_locally(
 1505        lsp_store: WeakEntity<LspStore>,
 1506        buffer: &FormattableBuffer,
 1507        formatting_transaction_id: clock::Lamport,
 1508        trigger: FormatTrigger,
 1509        logger: zlog::Logger,
 1510        cx: &mut AsyncApp,
 1511    ) -> Result<()> {
 1512        let (adapters_and_servers, settings) = lsp_store.update(cx, |lsp_store, cx| {
 1513            buffer.handle.update(cx, |buffer, cx| {
 1514                let adapters_and_servers = lsp_store
 1515                    .as_local()
 1516                    .unwrap()
 1517                    .language_servers_for_buffer(buffer, cx)
 1518                    .map(|(adapter, lsp)| (adapter.clone(), lsp.clone()))
 1519                    .collect::<Vec<_>>();
 1520                let settings =
 1521                    language_settings(buffer.language().map(|l| l.name()), buffer.file(), cx)
 1522                        .into_owned();
 1523                (adapters_and_servers, settings)
 1524            })
 1525        })?;
 1526
 1527        /// Apply edits to the buffer that will become part of the formatting transaction.
 1528        /// Fails if the buffer has been edited since the start of that transaction.
 1529        fn extend_formatting_transaction(
 1530            buffer: &FormattableBuffer,
 1531            formatting_transaction_id: text::TransactionId,
 1532            cx: &mut AsyncApp,
 1533            operation: impl FnOnce(&mut Buffer, &mut Context<Buffer>),
 1534        ) -> anyhow::Result<()> {
 1535            buffer.handle.update(cx, |buffer, cx| {
 1536                let last_transaction_id = buffer.peek_undo_stack().map(|t| t.transaction_id());
 1537                if last_transaction_id != Some(formatting_transaction_id) {
 1538                    anyhow::bail!("Buffer edited while formatting. Aborting")
 1539                }
 1540                buffer.start_transaction();
 1541                operation(buffer, cx);
 1542                if let Some(transaction_id) = buffer.end_transaction(cx) {
 1543                    buffer.merge_transactions(transaction_id, formatting_transaction_id);
 1544                }
 1545                Ok(())
 1546            })
 1547        }
 1548
 1549        // handle whitespace formatting
 1550        if settings.remove_trailing_whitespace_on_save {
 1551            zlog::trace!(logger => "removing trailing whitespace");
 1552            let diff = buffer
 1553                .handle
 1554                .read_with(cx, |buffer, cx| buffer.remove_trailing_whitespace(cx))
 1555                .await;
 1556            extend_formatting_transaction(buffer, formatting_transaction_id, cx, |buffer, cx| {
 1557                buffer.apply_diff(diff, cx);
 1558            })?;
 1559        }
 1560
 1561        if settings.ensure_final_newline_on_save {
 1562            zlog::trace!(logger => "ensuring final newline");
 1563            extend_formatting_transaction(buffer, formatting_transaction_id, cx, |buffer, cx| {
 1564                buffer.ensure_final_newline(cx);
 1565            })?;
 1566        }
 1567
 1568        // Formatter for `code_actions_on_format` that runs before
 1569        // the rest of the formatters
 1570        let mut code_actions_on_format_formatters = None;
 1571        let should_run_code_actions_on_format = !matches!(
 1572            (trigger, &settings.format_on_save),
 1573            (FormatTrigger::Save, &FormatOnSave::Off)
 1574        );
 1575        if should_run_code_actions_on_format {
 1576            let have_code_actions_to_run_on_format = settings
 1577                .code_actions_on_format
 1578                .values()
 1579                .any(|enabled| *enabled);
 1580            if have_code_actions_to_run_on_format {
 1581                zlog::trace!(logger => "going to run code actions on format");
 1582                code_actions_on_format_formatters = Some(
 1583                    settings
 1584                        .code_actions_on_format
 1585                        .iter()
 1586                        .filter_map(|(action, enabled)| enabled.then_some(action))
 1587                        .cloned()
 1588                        .map(Formatter::CodeAction)
 1589                        .collect::<Vec<_>>(),
 1590                );
 1591            }
 1592        }
 1593
 1594        let formatters = match (trigger, &settings.format_on_save) {
 1595            (FormatTrigger::Save, FormatOnSave::Off) => &[],
 1596            (FormatTrigger::Manual, _) | (FormatTrigger::Save, FormatOnSave::On) => {
 1597                settings.formatter.as_ref()
 1598            }
 1599        };
 1600
 1601        let formatters = code_actions_on_format_formatters
 1602            .iter()
 1603            .flatten()
 1604            .chain(formatters);
 1605
 1606        for formatter in formatters {
 1607            let formatter = if formatter == &Formatter::Auto {
 1608                if settings.prettier.allowed {
 1609                    zlog::trace!(logger => "Formatter set to auto: defaulting to prettier");
 1610                    &Formatter::Prettier
 1611                } else {
 1612                    zlog::trace!(logger => "Formatter set to auto: defaulting to primary language server");
 1613                    &Formatter::LanguageServer(settings::LanguageServerFormatterSpecifier::Current)
 1614                }
 1615            } else {
 1616                formatter
 1617            };
 1618            match formatter {
 1619                Formatter::Auto => unreachable!("Auto resolved above"),
 1620                Formatter::Prettier => {
 1621                    let logger = zlog::scoped!(logger => "prettier");
 1622                    zlog::trace!(logger => "formatting");
 1623                    let _timer = zlog::time!(logger => "Formatting buffer via prettier");
 1624
 1625                    let prettier = lsp_store.read_with(cx, |lsp_store, _cx| {
 1626                        lsp_store.prettier_store().unwrap().downgrade()
 1627                    })?;
 1628                    let diff = prettier_store::format_with_prettier(&prettier, &buffer.handle, cx)
 1629                        .await
 1630                        .transpose()?;
 1631                    let Some(diff) = diff else {
 1632                        zlog::trace!(logger => "No changes");
 1633                        continue;
 1634                    };
 1635
 1636                    extend_formatting_transaction(
 1637                        buffer,
 1638                        formatting_transaction_id,
 1639                        cx,
 1640                        |buffer, cx| {
 1641                            buffer.apply_diff(diff, cx);
 1642                        },
 1643                    )?;
 1644                }
 1645                Formatter::External { command, arguments } => {
 1646                    let logger = zlog::scoped!(logger => "command");
 1647                    zlog::trace!(logger => "formatting");
 1648                    let _timer = zlog::time!(logger => "Formatting buffer via external command");
 1649
 1650                    let diff = Self::format_via_external_command(
 1651                        buffer,
 1652                        &command,
 1653                        arguments.as_deref(),
 1654                        cx,
 1655                    )
 1656                    .await
 1657                    .with_context(|| {
 1658                        format!("Failed to format buffer via external command: {}", command)
 1659                    })?;
 1660                    let Some(diff) = diff else {
 1661                        zlog::trace!(logger => "No changes");
 1662                        continue;
 1663                    };
 1664
 1665                    extend_formatting_transaction(
 1666                        buffer,
 1667                        formatting_transaction_id,
 1668                        cx,
 1669                        |buffer, cx| {
 1670                            buffer.apply_diff(diff, cx);
 1671                        },
 1672                    )?;
 1673                }
 1674                Formatter::LanguageServer(specifier) => {
 1675                    let logger = zlog::scoped!(logger => "language-server");
 1676                    zlog::trace!(logger => "formatting");
 1677                    let _timer = zlog::time!(logger => "Formatting buffer using language server");
 1678
 1679                    let Some(buffer_path_abs) = buffer.abs_path.as_ref() else {
 1680                        zlog::warn!(logger => "Cannot format buffer that is not backed by a file on disk using language servers. Skipping");
 1681                        continue;
 1682                    };
 1683
 1684                    let language_server = match specifier {
 1685                        settings::LanguageServerFormatterSpecifier::Specific { name } => {
 1686                            adapters_and_servers.iter().find_map(|(adapter, server)| {
 1687                                if adapter.name.0.as_ref() == name {
 1688                                    Some(server.clone())
 1689                                } else {
 1690                                    None
 1691                                }
 1692                            })
 1693                        }
 1694                        settings::LanguageServerFormatterSpecifier::Current => {
 1695                            adapters_and_servers.first().map(|e| e.1.clone())
 1696                        }
 1697                    };
 1698
 1699                    let Some(language_server) = language_server else {
 1700                        log::debug!(
 1701                            "No language server found to format buffer '{:?}'. Skipping",
 1702                            buffer_path_abs.as_path().to_string_lossy()
 1703                        );
 1704                        continue;
 1705                    };
 1706
 1707                    zlog::trace!(
 1708                        logger =>
 1709                        "Formatting buffer '{:?}' using language server '{:?}'",
 1710                        buffer_path_abs.as_path().to_string_lossy(),
 1711                        language_server.name()
 1712                    );
 1713
 1714                    let edits = if let Some(ranges) = buffer.ranges.as_ref() {
 1715                        zlog::trace!(logger => "formatting ranges");
 1716                        Self::format_ranges_via_lsp(
 1717                            &lsp_store,
 1718                            &buffer.handle,
 1719                            ranges,
 1720                            buffer_path_abs,
 1721                            &language_server,
 1722                            &settings,
 1723                            cx,
 1724                        )
 1725                        .await
 1726                        .context("Failed to format ranges via language server")?
 1727                    } else {
 1728                        zlog::trace!(logger => "formatting full");
 1729                        Self::format_via_lsp(
 1730                            &lsp_store,
 1731                            &buffer.handle,
 1732                            buffer_path_abs,
 1733                            &language_server,
 1734                            &settings,
 1735                            cx,
 1736                        )
 1737                        .await
 1738                        .context("failed to format via language server")?
 1739                    };
 1740
 1741                    if edits.is_empty() {
 1742                        zlog::trace!(logger => "No changes");
 1743                        continue;
 1744                    }
 1745                    extend_formatting_transaction(
 1746                        buffer,
 1747                        formatting_transaction_id,
 1748                        cx,
 1749                        |buffer, cx| {
 1750                            buffer.edit(edits, None, cx);
 1751                        },
 1752                    )?;
 1753                }
 1754                Formatter::CodeAction(code_action_name) => {
 1755                    let logger = zlog::scoped!(logger => "code-actions");
 1756                    zlog::trace!(logger => "formatting");
 1757                    let _timer = zlog::time!(logger => "Formatting buffer using code actions");
 1758
 1759                    let Some(buffer_path_abs) = buffer.abs_path.as_ref() else {
 1760                        zlog::warn!(logger => "Cannot format buffer that is not backed by a file on disk using code actions. Skipping");
 1761                        continue;
 1762                    };
 1763
 1764                    let code_action_kind: CodeActionKind = code_action_name.clone().into();
 1765                    zlog::trace!(logger => "Attempting to resolve code actions {:?}", &code_action_kind);
 1766
 1767                    let mut actions_and_servers = Vec::new();
 1768
 1769                    for (index, (_, language_server)) in adapters_and_servers.iter().enumerate() {
 1770                        let actions_result = Self::get_server_code_actions_from_action_kinds(
 1771                            &lsp_store,
 1772                            language_server.server_id(),
 1773                            vec![code_action_kind.clone()],
 1774                            &buffer.handle,
 1775                            cx,
 1776                        )
 1777                        .await
 1778                        .with_context(|| {
 1779                            format!(
 1780                                "Failed to resolve code action {:?} with language server {}",
 1781                                code_action_kind,
 1782                                language_server.name()
 1783                            )
 1784                        });
 1785                        let Ok(actions) = actions_result else {
 1786                            // note: it may be better to set result to the error and break formatters here
 1787                            // but for now we try to execute the actions that we can resolve and skip the rest
 1788                            zlog::error!(
 1789                                logger =>
 1790                                "Failed to resolve code action {:?} with language server {}",
 1791                                code_action_kind,
 1792                                language_server.name()
 1793                            );
 1794                            continue;
 1795                        };
 1796                        for action in actions {
 1797                            actions_and_servers.push((action, index));
 1798                        }
 1799                    }
 1800
 1801                    if actions_and_servers.is_empty() {
 1802                        zlog::warn!(logger => "No code actions were resolved, continuing");
 1803                        continue;
 1804                    }
 1805
 1806                    'actions: for (mut action, server_index) in actions_and_servers {
 1807                        let server = &adapters_and_servers[server_index].1;
 1808
 1809                        let describe_code_action = |action: &CodeAction| {
 1810                            format!(
 1811                                "code action '{}' with title \"{}\" on server {}",
 1812                                action
 1813                                    .lsp_action
 1814                                    .action_kind()
 1815                                    .unwrap_or("unknown".into())
 1816                                    .as_str(),
 1817                                action.lsp_action.title(),
 1818                                server.name(),
 1819                            )
 1820                        };
 1821
 1822                        zlog::trace!(logger => "Executing {}", describe_code_action(&action));
 1823
 1824                        if let Err(err) = Self::try_resolve_code_action(server, &mut action).await {
 1825                            zlog::error!(
 1826                                logger =>
 1827                                "Failed to resolve {}. Error: {}",
 1828                                describe_code_action(&action),
 1829                                err
 1830                            );
 1831                            continue;
 1832                        }
 1833
 1834                        if let Some(edit) = action.lsp_action.edit().cloned() {
 1835                            // NOTE: code below duplicated from `Self::deserialize_workspace_edit`
 1836                            // but filters out and logs warnings for code actions that require unreasonably
 1837                            // difficult handling on our part, such as:
 1838                            // - applying edits that call commands
 1839                            //   which can result in arbitrary workspace edits being sent from the server that
 1840                            //   have no way of being tied back to the command that initiated them (i.e. we
 1841                            //   can't know which edits are part of the format request, or if the server is done sending
 1842                            //   actions in response to the command)
 1843                            // - actions that create/delete/modify/rename files other than the one we are formatting
 1844                            //   as we then would need to handle such changes correctly in the local history as well
 1845                            //   as the remote history through the ProjectTransaction
 1846                            // - actions with snippet edits, as these simply don't make sense in the context of a format request
 1847                            // Supporting these actions is not impossible, but not supported as of yet.
 1848                            if edit.changes.is_none() && edit.document_changes.is_none() {
 1849                                zlog::trace!(
 1850                                    logger =>
 1851                                    "No changes for code action. Skipping {}",
 1852                                    describe_code_action(&action),
 1853                                );
 1854                                continue;
 1855                            }
 1856
 1857                            let mut operations = Vec::new();
 1858                            if let Some(document_changes) = edit.document_changes {
 1859                                match document_changes {
 1860                                    lsp::DocumentChanges::Edits(edits) => operations.extend(
 1861                                        edits.into_iter().map(lsp::DocumentChangeOperation::Edit),
 1862                                    ),
 1863                                    lsp::DocumentChanges::Operations(ops) => operations = ops,
 1864                                }
 1865                            } else if let Some(changes) = edit.changes {
 1866                                operations.extend(changes.into_iter().map(|(uri, edits)| {
 1867                                    lsp::DocumentChangeOperation::Edit(lsp::TextDocumentEdit {
 1868                                        text_document:
 1869                                            lsp::OptionalVersionedTextDocumentIdentifier {
 1870                                                uri,
 1871                                                version: None,
 1872                                            },
 1873                                        edits: edits.into_iter().map(Edit::Plain).collect(),
 1874                                    })
 1875                                }));
 1876                            }
 1877
 1878                            let mut edits = Vec::with_capacity(operations.len());
 1879
 1880                            if operations.is_empty() {
 1881                                zlog::trace!(
 1882                                    logger =>
 1883                                    "No changes for code action. Skipping {}",
 1884                                    describe_code_action(&action),
 1885                                );
 1886                                continue;
 1887                            }
 1888                            for operation in operations {
 1889                                let op = match operation {
 1890                                    lsp::DocumentChangeOperation::Edit(op) => op,
 1891                                    lsp::DocumentChangeOperation::Op(_) => {
 1892                                        zlog::warn!(
 1893                                            logger =>
 1894                                            "Code actions which create, delete, or rename files are not supported on format. Skipping {}",
 1895                                            describe_code_action(&action),
 1896                                        );
 1897                                        continue 'actions;
 1898                                    }
 1899                                };
 1900                                let Ok(file_path) = op.text_document.uri.to_file_path() else {
 1901                                    zlog::warn!(
 1902                                        logger =>
 1903                                        "Failed to convert URI '{:?}' to file path. Skipping {}",
 1904                                        &op.text_document.uri,
 1905                                        describe_code_action(&action),
 1906                                    );
 1907                                    continue 'actions;
 1908                                };
 1909                                if &file_path != buffer_path_abs {
 1910                                    zlog::warn!(
 1911                                        logger =>
 1912                                        "File path '{:?}' does not match buffer path '{:?}'. Skipping {}",
 1913                                        file_path,
 1914                                        buffer_path_abs,
 1915                                        describe_code_action(&action),
 1916                                    );
 1917                                    continue 'actions;
 1918                                }
 1919
 1920                                let mut lsp_edits = Vec::new();
 1921                                for edit in op.edits {
 1922                                    match edit {
 1923                                        Edit::Plain(edit) => {
 1924                                            if !lsp_edits.contains(&edit) {
 1925                                                lsp_edits.push(edit);
 1926                                            }
 1927                                        }
 1928                                        Edit::Annotated(edit) => {
 1929                                            if !lsp_edits.contains(&edit.text_edit) {
 1930                                                lsp_edits.push(edit.text_edit);
 1931                                            }
 1932                                        }
 1933                                        Edit::Snippet(_) => {
 1934                                            zlog::warn!(
 1935                                                logger =>
 1936                                                "Code actions which produce snippet edits are not supported during formatting. Skipping {}",
 1937                                                describe_code_action(&action),
 1938                                            );
 1939                                            continue 'actions;
 1940                                        }
 1941                                    }
 1942                                }
 1943                                let edits_result = lsp_store
 1944                                    .update(cx, |lsp_store, cx| {
 1945                                        lsp_store.as_local_mut().unwrap().edits_from_lsp(
 1946                                            &buffer.handle,
 1947                                            lsp_edits,
 1948                                            server.server_id(),
 1949                                            op.text_document.version,
 1950                                            cx,
 1951                                        )
 1952                                    })?
 1953                                    .await;
 1954                                let Ok(resolved_edits) = edits_result else {
 1955                                    zlog::warn!(
 1956                                        logger =>
 1957                                        "Failed to resolve edits from LSP for buffer {:?} while handling {}",
 1958                                        buffer_path_abs.as_path(),
 1959                                        describe_code_action(&action),
 1960                                    );
 1961                                    continue 'actions;
 1962                                };
 1963                                edits.extend(resolved_edits);
 1964                            }
 1965
 1966                            if edits.is_empty() {
 1967                                zlog::warn!(logger => "No edits resolved from LSP");
 1968                                continue;
 1969                            }
 1970
 1971                            extend_formatting_transaction(
 1972                                buffer,
 1973                                formatting_transaction_id,
 1974                                cx,
 1975                                |buffer, cx| {
 1976                                    zlog::info!(
 1977                                        "Applying edits {edits:?}. Content: {:?}",
 1978                                        buffer.text()
 1979                                    );
 1980                                    buffer.edit(edits, None, cx);
 1981                                    zlog::info!("Applied edits. New Content: {:?}", buffer.text());
 1982                                },
 1983                            )?;
 1984                        }
 1985
 1986                        if let Some(command) = action.lsp_action.command() {
 1987                            zlog::warn!(
 1988                                logger =>
 1989                                "Executing code action command '{}'. This may cause formatting to abort unnecessarily as well as splitting formatting into two entries in the undo history",
 1990                                &command.command,
 1991                            );
 1992
 1993                            // bail early if command is invalid
 1994                            let server_capabilities = server.capabilities();
 1995                            let available_commands = server_capabilities
 1996                                .execute_command_provider
 1997                                .as_ref()
 1998                                .map(|options| options.commands.as_slice())
 1999                                .unwrap_or_default();
 2000                            if !available_commands.contains(&command.command) {
 2001                                zlog::warn!(
 2002                                    logger =>
 2003                                    "Cannot execute a command {} not listed in the language server capabilities of server {}",
 2004                                    command.command,
 2005                                    server.name(),
 2006                                );
 2007                                continue;
 2008                            }
 2009
 2010                            // noop so we just ensure buffer hasn't been edited since resolving code actions
 2011                            extend_formatting_transaction(
 2012                                buffer,
 2013                                formatting_transaction_id,
 2014                                cx,
 2015                                |_, _| {},
 2016                            )?;
 2017                            zlog::info!(logger => "Executing command {}", &command.command);
 2018
 2019                            lsp_store.update(cx, |this, _| {
 2020                                this.as_local_mut()
 2021                                    .unwrap()
 2022                                    .last_workspace_edits_by_language_server
 2023                                    .remove(&server.server_id());
 2024                            })?;
 2025
 2026                            let execute_command_result = server
 2027                                .request::<lsp::request::ExecuteCommand>(
 2028                                    lsp::ExecuteCommandParams {
 2029                                        command: command.command.clone(),
 2030                                        arguments: command.arguments.clone().unwrap_or_default(),
 2031                                        ..Default::default()
 2032                                    },
 2033                                )
 2034                                .await
 2035                                .into_response();
 2036
 2037                            if execute_command_result.is_err() {
 2038                                zlog::error!(
 2039                                    logger =>
 2040                                    "Failed to execute command '{}' as part of {}",
 2041                                    &command.command,
 2042                                    describe_code_action(&action),
 2043                                );
 2044                                continue 'actions;
 2045                            }
 2046
 2047                            let mut project_transaction_command =
 2048                                lsp_store.update(cx, |this, _| {
 2049                                    this.as_local_mut()
 2050                                        .unwrap()
 2051                                        .last_workspace_edits_by_language_server
 2052                                        .remove(&server.server_id())
 2053                                        .unwrap_or_default()
 2054                                })?;
 2055
 2056                            if let Some(transaction) =
 2057                                project_transaction_command.0.remove(&buffer.handle)
 2058                            {
 2059                                zlog::trace!(
 2060                                    logger =>
 2061                                    "Successfully captured {} edits that resulted from command {}",
 2062                                    transaction.edit_ids.len(),
 2063                                    &command.command,
 2064                                );
 2065                                let transaction_id_project_transaction = transaction.id;
 2066                                buffer.handle.update(cx, |buffer, _| {
 2067                                    // it may have been removed from history if push_to_history was
 2068                                    // false in deserialize_workspace_edit. If so push it so we
 2069                                    // can merge it with the format transaction
 2070                                    // and pop the combined transaction off the history stack
 2071                                    // later if push_to_history is false
 2072                                    if buffer.get_transaction(transaction.id).is_none() {
 2073                                        buffer.push_transaction(transaction, Instant::now());
 2074                                    }
 2075                                    buffer.merge_transactions(
 2076                                        transaction_id_project_transaction,
 2077                                        formatting_transaction_id,
 2078                                    );
 2079                                });
 2080                            }
 2081
 2082                            if !project_transaction_command.0.is_empty() {
 2083                                let mut extra_buffers = String::new();
 2084                                for buffer in project_transaction_command.0.keys() {
 2085                                    buffer.read_with(cx, |b, cx| {
 2086                                        if let Some(path) = b.project_path(cx) {
 2087                                            if !extra_buffers.is_empty() {
 2088                                                extra_buffers.push_str(", ");
 2089                                            }
 2090                                            extra_buffers.push_str(path.path.as_unix_str());
 2091                                        }
 2092                                    });
 2093                                }
 2094                                zlog::warn!(
 2095                                    logger =>
 2096                                    "Unexpected edits to buffers other than the buffer actively being formatted due to command {}. Impacted buffers: [{}].",
 2097                                    &command.command,
 2098                                    extra_buffers,
 2099                                );
 2100                                // NOTE: if this case is hit, the proper thing to do is to for each buffer, merge the extra transaction
 2101                                // into the existing transaction in project_transaction if there is one, and if there isn't one in project_transaction,
 2102                                // add it so it's included, and merge it into the format transaction when its created later
 2103                            }
 2104                        }
 2105                    }
 2106                }
 2107            }
 2108        }
 2109
 2110        Ok(())
 2111    }
 2112
 2113    pub async fn format_ranges_via_lsp(
 2114        this: &WeakEntity<LspStore>,
 2115        buffer_handle: &Entity<Buffer>,
 2116        ranges: &[Range<Anchor>],
 2117        abs_path: &Path,
 2118        language_server: &Arc<LanguageServer>,
 2119        settings: &LanguageSettings,
 2120        cx: &mut AsyncApp,
 2121    ) -> Result<Vec<(Range<Anchor>, Arc<str>)>> {
 2122        let capabilities = &language_server.capabilities();
 2123        let range_formatting_provider = capabilities.document_range_formatting_provider.as_ref();
 2124        if range_formatting_provider == Some(&OneOf::Left(false)) {
 2125            anyhow::bail!(
 2126                "{} language server does not support range formatting",
 2127                language_server.name()
 2128            );
 2129        }
 2130
 2131        let uri = file_path_to_lsp_url(abs_path)?;
 2132        let text_document = lsp::TextDocumentIdentifier::new(uri);
 2133
 2134        let lsp_edits = {
 2135            let mut lsp_ranges = Vec::new();
 2136            this.update(cx, |_this, cx| {
 2137                // TODO(#22930): In the case of formatting multibuffer selections, this buffer may
 2138                // not have been sent to the language server. This seems like a fairly systemic
 2139                // issue, though, the resolution probably is not specific to formatting.
 2140                //
 2141                // TODO: Instead of using current snapshot, should use the latest snapshot sent to
 2142                // LSP.
 2143                let snapshot = buffer_handle.read(cx).snapshot();
 2144                for range in ranges {
 2145                    lsp_ranges.push(range_to_lsp(range.to_point_utf16(&snapshot))?);
 2146                }
 2147                anyhow::Ok(())
 2148            })??;
 2149
 2150            let mut edits = None;
 2151            for range in lsp_ranges {
 2152                if let Some(mut edit) = language_server
 2153                    .request::<lsp::request::RangeFormatting>(lsp::DocumentRangeFormattingParams {
 2154                        text_document: text_document.clone(),
 2155                        range,
 2156                        options: lsp_command::lsp_formatting_options(settings),
 2157                        work_done_progress_params: Default::default(),
 2158                    })
 2159                    .await
 2160                    .into_response()?
 2161                {
 2162                    edits.get_or_insert_with(Vec::new).append(&mut edit);
 2163                }
 2164            }
 2165            edits
 2166        };
 2167
 2168        if let Some(lsp_edits) = lsp_edits {
 2169            this.update(cx, |this, cx| {
 2170                this.as_local_mut().unwrap().edits_from_lsp(
 2171                    buffer_handle,
 2172                    lsp_edits,
 2173                    language_server.server_id(),
 2174                    None,
 2175                    cx,
 2176                )
 2177            })?
 2178            .await
 2179        } else {
 2180            Ok(Vec::with_capacity(0))
 2181        }
 2182    }
 2183
 2184    async fn format_via_lsp(
 2185        this: &WeakEntity<LspStore>,
 2186        buffer: &Entity<Buffer>,
 2187        abs_path: &Path,
 2188        language_server: &Arc<LanguageServer>,
 2189        settings: &LanguageSettings,
 2190        cx: &mut AsyncApp,
 2191    ) -> Result<Vec<(Range<Anchor>, Arc<str>)>> {
 2192        let logger = zlog::scoped!("lsp_format");
 2193        zlog::debug!(logger => "Formatting via LSP");
 2194
 2195        let uri = file_path_to_lsp_url(abs_path)?;
 2196        let text_document = lsp::TextDocumentIdentifier::new(uri);
 2197        let capabilities = &language_server.capabilities();
 2198
 2199        let formatting_provider = capabilities.document_formatting_provider.as_ref();
 2200        let range_formatting_provider = capabilities.document_range_formatting_provider.as_ref();
 2201
 2202        let lsp_edits = if matches!(formatting_provider, Some(p) if *p != OneOf::Left(false)) {
 2203            let _timer = zlog::time!(logger => "format-full");
 2204            language_server
 2205                .request::<lsp::request::Formatting>(lsp::DocumentFormattingParams {
 2206                    text_document,
 2207                    options: lsp_command::lsp_formatting_options(settings),
 2208                    work_done_progress_params: Default::default(),
 2209                })
 2210                .await
 2211                .into_response()?
 2212        } else if matches!(range_formatting_provider, Some(p) if *p != OneOf::Left(false)) {
 2213            let _timer = zlog::time!(logger => "format-range");
 2214            let buffer_start = lsp::Position::new(0, 0);
 2215            let buffer_end = buffer.read_with(cx, |b, _| point_to_lsp(b.max_point_utf16()));
 2216            language_server
 2217                .request::<lsp::request::RangeFormatting>(lsp::DocumentRangeFormattingParams {
 2218                    text_document: text_document.clone(),
 2219                    range: lsp::Range::new(buffer_start, buffer_end),
 2220                    options: lsp_command::lsp_formatting_options(settings),
 2221                    work_done_progress_params: Default::default(),
 2222                })
 2223                .await
 2224                .into_response()?
 2225        } else {
 2226            None
 2227        };
 2228
 2229        if let Some(lsp_edits) = lsp_edits {
 2230            this.update(cx, |this, cx| {
 2231                this.as_local_mut().unwrap().edits_from_lsp(
 2232                    buffer,
 2233                    lsp_edits,
 2234                    language_server.server_id(),
 2235                    None,
 2236                    cx,
 2237                )
 2238            })?
 2239            .await
 2240        } else {
 2241            Ok(Vec::with_capacity(0))
 2242        }
 2243    }
 2244
 2245    async fn format_via_external_command(
 2246        buffer: &FormattableBuffer,
 2247        command: &str,
 2248        arguments: Option<&[String]>,
 2249        cx: &mut AsyncApp,
 2250    ) -> Result<Option<Diff>> {
 2251        let working_dir_path = buffer.handle.update(cx, |buffer, cx| {
 2252            let file = File::from_dyn(buffer.file())?;
 2253            let worktree = file.worktree.read(cx);
 2254            let mut worktree_path = worktree.abs_path().to_path_buf();
 2255            if worktree.root_entry()?.is_file() {
 2256                worktree_path.pop();
 2257            }
 2258            Some(worktree_path)
 2259        });
 2260
 2261        let mut child = util::command::new_smol_command(command);
 2262
 2263        if let Some(buffer_env) = buffer.env.as_ref() {
 2264            child.envs(buffer_env);
 2265        }
 2266
 2267        if let Some(working_dir_path) = working_dir_path {
 2268            child.current_dir(working_dir_path);
 2269        }
 2270
 2271        if let Some(arguments) = arguments {
 2272            child.args(arguments.iter().map(|arg| {
 2273                if let Some(buffer_abs_path) = buffer.abs_path.as_ref() {
 2274                    arg.replace("{buffer_path}", &buffer_abs_path.to_string_lossy())
 2275                } else {
 2276                    arg.replace("{buffer_path}", "Untitled")
 2277                }
 2278            }));
 2279        }
 2280
 2281        let mut child = child
 2282            .stdin(smol::process::Stdio::piped())
 2283            .stdout(smol::process::Stdio::piped())
 2284            .stderr(smol::process::Stdio::piped())
 2285            .spawn()?;
 2286
 2287        let stdin = child.stdin.as_mut().context("failed to acquire stdin")?;
 2288        let text = buffer
 2289            .handle
 2290            .read_with(cx, |buffer, _| buffer.as_rope().clone());
 2291        for chunk in text.chunks() {
 2292            stdin.write_all(chunk.as_bytes()).await?;
 2293        }
 2294        stdin.flush().await?;
 2295
 2296        let output = child.output().await?;
 2297        anyhow::ensure!(
 2298            output.status.success(),
 2299            "command failed with exit code {:?}:\nstdout: {}\nstderr: {}",
 2300            output.status.code(),
 2301            String::from_utf8_lossy(&output.stdout),
 2302            String::from_utf8_lossy(&output.stderr),
 2303        );
 2304
 2305        let stdout = String::from_utf8(output.stdout)?;
 2306        Ok(Some(
 2307            buffer
 2308                .handle
 2309                .update(cx, |buffer, cx| buffer.diff(stdout, cx))
 2310                .await,
 2311        ))
 2312    }
 2313
 2314    async fn try_resolve_code_action(
 2315        lang_server: &LanguageServer,
 2316        action: &mut CodeAction,
 2317    ) -> anyhow::Result<()> {
 2318        match &mut action.lsp_action {
 2319            LspAction::Action(lsp_action) => {
 2320                if !action.resolved
 2321                    && GetCodeActions::can_resolve_actions(&lang_server.capabilities())
 2322                    && lsp_action.data.is_some()
 2323                    && (lsp_action.command.is_none() || lsp_action.edit.is_none())
 2324                {
 2325                    **lsp_action = lang_server
 2326                        .request::<lsp::request::CodeActionResolveRequest>(*lsp_action.clone())
 2327                        .await
 2328                        .into_response()?;
 2329                }
 2330            }
 2331            LspAction::CodeLens(lens) => {
 2332                if !action.resolved && GetCodeLens::can_resolve_lens(&lang_server.capabilities()) {
 2333                    *lens = lang_server
 2334                        .request::<lsp::request::CodeLensResolve>(lens.clone())
 2335                        .await
 2336                        .into_response()?;
 2337                }
 2338            }
 2339            LspAction::Command(_) => {}
 2340        }
 2341
 2342        action.resolved = true;
 2343        anyhow::Ok(())
 2344    }
 2345
 2346    fn initialize_buffer(&mut self, buffer_handle: &Entity<Buffer>, cx: &mut Context<LspStore>) {
 2347        let buffer = buffer_handle.read(cx);
 2348
 2349        let file = buffer.file().cloned();
 2350
 2351        let Some(file) = File::from_dyn(file.as_ref()) else {
 2352            return;
 2353        };
 2354        if !file.is_local() {
 2355            return;
 2356        }
 2357        let path = ProjectPath::from_file(file, cx);
 2358        let worktree_id = file.worktree_id(cx);
 2359        let language = buffer.language().cloned();
 2360
 2361        if let Some(diagnostics) = self.diagnostics.get(&worktree_id) {
 2362            for (server_id, diagnostics) in
 2363                diagnostics.get(file.path()).cloned().unwrap_or_default()
 2364            {
 2365                self.update_buffer_diagnostics(
 2366                    buffer_handle,
 2367                    server_id,
 2368                    None,
 2369                    None,
 2370                    None,
 2371                    Vec::new(),
 2372                    diagnostics,
 2373                    cx,
 2374                )
 2375                .log_err();
 2376            }
 2377        }
 2378        let Some(language) = language else {
 2379            return;
 2380        };
 2381        let Some(snapshot) = self
 2382            .worktree_store
 2383            .read(cx)
 2384            .worktree_for_id(worktree_id, cx)
 2385            .map(|worktree| worktree.read(cx).snapshot())
 2386        else {
 2387            return;
 2388        };
 2389        let delegate: Arc<dyn ManifestDelegate> = Arc::new(ManifestQueryDelegate::new(snapshot));
 2390
 2391        for server_id in
 2392            self.lsp_tree
 2393                .get(path, language.name(), language.manifest(), &delegate, cx)
 2394        {
 2395            let server = self
 2396                .language_servers
 2397                .get(&server_id)
 2398                .and_then(|server_state| {
 2399                    if let LanguageServerState::Running { server, .. } = server_state {
 2400                        Some(server.clone())
 2401                    } else {
 2402                        None
 2403                    }
 2404                });
 2405            let server = match server {
 2406                Some(server) => server,
 2407                None => continue,
 2408            };
 2409
 2410            buffer_handle.update(cx, |buffer, cx| {
 2411                buffer.set_completion_triggers(
 2412                    server.server_id(),
 2413                    server
 2414                        .capabilities()
 2415                        .completion_provider
 2416                        .as_ref()
 2417                        .and_then(|provider| {
 2418                            provider
 2419                                .trigger_characters
 2420                                .as_ref()
 2421                                .map(|characters| characters.iter().cloned().collect())
 2422                        })
 2423                        .unwrap_or_default(),
 2424                    cx,
 2425                );
 2426            });
 2427        }
 2428    }
 2429
 2430    pub(crate) fn reset_buffer(&mut self, buffer: &Entity<Buffer>, old_file: &File, cx: &mut App) {
 2431        buffer.update(cx, |buffer, cx| {
 2432            let Some(language) = buffer.language() else {
 2433                return;
 2434            };
 2435            let path = ProjectPath {
 2436                worktree_id: old_file.worktree_id(cx),
 2437                path: old_file.path.clone(),
 2438            };
 2439            for server_id in self.language_server_ids_for_project_path(path, language, cx) {
 2440                buffer.update_diagnostics(server_id, DiagnosticSet::new([], buffer), cx);
 2441                buffer.set_completion_triggers(server_id, Default::default(), cx);
 2442            }
 2443        });
 2444    }
 2445
 2446    fn update_buffer_diagnostics(
 2447        &mut self,
 2448        buffer: &Entity<Buffer>,
 2449        server_id: LanguageServerId,
 2450        registration_id: Option<Option<SharedString>>,
 2451        result_id: Option<SharedString>,
 2452        version: Option<i32>,
 2453        new_diagnostics: Vec<DiagnosticEntry<Unclipped<PointUtf16>>>,
 2454        reused_diagnostics: Vec<DiagnosticEntry<Unclipped<PointUtf16>>>,
 2455        cx: &mut Context<LspStore>,
 2456    ) -> Result<()> {
 2457        fn compare_diagnostics(a: &Diagnostic, b: &Diagnostic) -> Ordering {
 2458            Ordering::Equal
 2459                .then_with(|| b.is_primary.cmp(&a.is_primary))
 2460                .then_with(|| a.is_disk_based.cmp(&b.is_disk_based))
 2461                .then_with(|| a.severity.cmp(&b.severity))
 2462                .then_with(|| a.message.cmp(&b.message))
 2463        }
 2464
 2465        let mut diagnostics = Vec::with_capacity(new_diagnostics.len() + reused_diagnostics.len());
 2466        diagnostics.extend(new_diagnostics.into_iter().map(|d| (true, d)));
 2467        diagnostics.extend(reused_diagnostics.into_iter().map(|d| (false, d)));
 2468
 2469        diagnostics.sort_unstable_by(|(_, a), (_, b)| {
 2470            Ordering::Equal
 2471                .then_with(|| a.range.start.cmp(&b.range.start))
 2472                .then_with(|| b.range.end.cmp(&a.range.end))
 2473                .then_with(|| compare_diagnostics(&a.diagnostic, &b.diagnostic))
 2474        });
 2475
 2476        let snapshot = self.buffer_snapshot_for_lsp_version(buffer, server_id, version, cx)?;
 2477
 2478        let edits_since_save = std::cell::LazyCell::new(|| {
 2479            let saved_version = buffer.read(cx).saved_version();
 2480            Patch::new(snapshot.edits_since::<PointUtf16>(saved_version).collect())
 2481        });
 2482
 2483        let mut sanitized_diagnostics = Vec::with_capacity(diagnostics.len());
 2484
 2485        for (new_diagnostic, entry) in diagnostics {
 2486            let start;
 2487            let end;
 2488            if new_diagnostic && entry.diagnostic.is_disk_based {
 2489                // Some diagnostics are based on files on disk instead of buffers'
 2490                // current contents. Adjust these diagnostics' ranges to reflect
 2491                // any unsaved edits.
 2492                // Do not alter the reused ones though, as their coordinates were stored as anchors
 2493                // and were properly adjusted on reuse.
 2494                start = Unclipped((*edits_since_save).old_to_new(entry.range.start.0));
 2495                end = Unclipped((*edits_since_save).old_to_new(entry.range.end.0));
 2496            } else {
 2497                start = entry.range.start;
 2498                end = entry.range.end;
 2499            }
 2500
 2501            let mut range = snapshot.clip_point_utf16(start, Bias::Left)
 2502                ..snapshot.clip_point_utf16(end, Bias::Right);
 2503
 2504            // Expand empty ranges by one codepoint
 2505            if range.start == range.end {
 2506                // This will be go to the next boundary when being clipped
 2507                range.end.column += 1;
 2508                range.end = snapshot.clip_point_utf16(Unclipped(range.end), Bias::Right);
 2509                if range.start == range.end && range.end.column > 0 {
 2510                    range.start.column -= 1;
 2511                    range.start = snapshot.clip_point_utf16(Unclipped(range.start), Bias::Left);
 2512                }
 2513            }
 2514
 2515            sanitized_diagnostics.push(DiagnosticEntry {
 2516                range,
 2517                diagnostic: entry.diagnostic,
 2518            });
 2519        }
 2520        drop(edits_since_save);
 2521
 2522        let set = DiagnosticSet::new(sanitized_diagnostics, &snapshot);
 2523        buffer.update(cx, |buffer, cx| {
 2524            if let Some(registration_id) = registration_id {
 2525                if let Some(abs_path) = File::from_dyn(buffer.file()).map(|f| f.abs_path(cx)) {
 2526                    self.buffer_pull_diagnostics_result_ids
 2527                        .entry(server_id)
 2528                        .or_default()
 2529                        .entry(registration_id)
 2530                        .or_default()
 2531                        .insert(abs_path, result_id);
 2532                }
 2533            }
 2534
 2535            buffer.update_diagnostics(server_id, set, cx)
 2536        });
 2537
 2538        Ok(())
 2539    }
 2540
 2541    fn register_language_server_for_invisible_worktree(
 2542        &mut self,
 2543        worktree: &Entity<Worktree>,
 2544        language_server_id: LanguageServerId,
 2545        cx: &mut App,
 2546    ) {
 2547        let worktree = worktree.read(cx);
 2548        let worktree_id = worktree.id();
 2549        debug_assert!(!worktree.is_visible());
 2550        let Some(mut origin_seed) = self
 2551            .language_server_ids
 2552            .iter()
 2553            .find_map(|(seed, state)| (state.id == language_server_id).then(|| seed.clone()))
 2554        else {
 2555            return;
 2556        };
 2557        origin_seed.worktree_id = worktree_id;
 2558        self.language_server_ids
 2559            .entry(origin_seed)
 2560            .or_insert_with(|| UnifiedLanguageServer {
 2561                id: language_server_id,
 2562                project_roots: Default::default(),
 2563            });
 2564    }
 2565
 2566    fn register_buffer_with_language_servers(
 2567        &mut self,
 2568        buffer_handle: &Entity<Buffer>,
 2569        only_register_servers: HashSet<LanguageServerSelector>,
 2570        cx: &mut Context<LspStore>,
 2571    ) {
 2572        let buffer = buffer_handle.read(cx);
 2573        let buffer_id = buffer.remote_id();
 2574
 2575        let Some(file) = File::from_dyn(buffer.file()) else {
 2576            return;
 2577        };
 2578        if !file.is_local() {
 2579            return;
 2580        }
 2581
 2582        let abs_path = file.abs_path(cx);
 2583        let Some(uri) = file_path_to_lsp_url(&abs_path).log_err() else {
 2584            return;
 2585        };
 2586        let initial_snapshot = buffer.text_snapshot();
 2587        let worktree_id = file.worktree_id(cx);
 2588
 2589        let Some(language) = buffer.language().cloned() else {
 2590            return;
 2591        };
 2592        let path: Arc<RelPath> = file
 2593            .path()
 2594            .parent()
 2595            .map(Arc::from)
 2596            .unwrap_or_else(|| file.path().clone());
 2597        let Some(worktree) = self
 2598            .worktree_store
 2599            .read(cx)
 2600            .worktree_for_id(worktree_id, cx)
 2601        else {
 2602            return;
 2603        };
 2604        let language_name = language.name();
 2605        let (reused, delegate, servers) = self
 2606            .reuse_existing_language_server(&self.lsp_tree, &worktree, &language_name, cx)
 2607            .map(|(delegate, apply)| (true, delegate, apply(&mut self.lsp_tree)))
 2608            .unwrap_or_else(|| {
 2609                let lsp_delegate = LocalLspAdapterDelegate::from_local_lsp(self, &worktree, cx);
 2610                let delegate: Arc<dyn ManifestDelegate> =
 2611                    Arc::new(ManifestQueryDelegate::new(worktree.read(cx).snapshot()));
 2612
 2613                let servers = self
 2614                    .lsp_tree
 2615                    .walk(
 2616                        ProjectPath { worktree_id, path },
 2617                        language.name(),
 2618                        language.manifest(),
 2619                        &delegate,
 2620                        cx,
 2621                    )
 2622                    .collect::<Vec<_>>();
 2623                (false, lsp_delegate, servers)
 2624            });
 2625        let servers_and_adapters = servers
 2626            .into_iter()
 2627            .filter_map(|server_node| {
 2628                if reused && server_node.server_id().is_none() {
 2629                    return None;
 2630                }
 2631                if !only_register_servers.is_empty() {
 2632                    if let Some(server_id) = server_node.server_id()
 2633                        && !only_register_servers.contains(&LanguageServerSelector::Id(server_id))
 2634                    {
 2635                        return None;
 2636                    }
 2637                    if let Some(name) = server_node.name()
 2638                        && !only_register_servers.contains(&LanguageServerSelector::Name(name))
 2639                    {
 2640                        return None;
 2641                    }
 2642                }
 2643
 2644                let server_id = server_node.server_id_or_init(|disposition| {
 2645                    let path = &disposition.path;
 2646
 2647                    {
 2648                        let uri = Uri::from_file_path(worktree.read(cx).absolutize(&path.path));
 2649
 2650                        let server_id = self.get_or_insert_language_server(
 2651                            &worktree,
 2652                            delegate.clone(),
 2653                            disposition,
 2654                            &language_name,
 2655                            cx,
 2656                        );
 2657
 2658                        if let Some(state) = self.language_servers.get(&server_id)
 2659                            && let Ok(uri) = uri
 2660                        {
 2661                            state.add_workspace_folder(uri);
 2662                        };
 2663                        server_id
 2664                    }
 2665                })?;
 2666                let server_state = self.language_servers.get(&server_id)?;
 2667                if let LanguageServerState::Running {
 2668                    server, adapter, ..
 2669                } = server_state
 2670                {
 2671                    Some((server.clone(), adapter.clone()))
 2672                } else {
 2673                    None
 2674                }
 2675            })
 2676            .collect::<Vec<_>>();
 2677        for (server, adapter) in servers_and_adapters {
 2678            buffer_handle.update(cx, |buffer, cx| {
 2679                buffer.set_completion_triggers(
 2680                    server.server_id(),
 2681                    server
 2682                        .capabilities()
 2683                        .completion_provider
 2684                        .as_ref()
 2685                        .and_then(|provider| {
 2686                            provider
 2687                                .trigger_characters
 2688                                .as_ref()
 2689                                .map(|characters| characters.iter().cloned().collect())
 2690                        })
 2691                        .unwrap_or_default(),
 2692                    cx,
 2693                );
 2694            });
 2695
 2696            let snapshot = LspBufferSnapshot {
 2697                version: 0,
 2698                snapshot: initial_snapshot.clone(),
 2699            };
 2700
 2701            let mut registered = false;
 2702            self.buffer_snapshots
 2703                .entry(buffer_id)
 2704                .or_default()
 2705                .entry(server.server_id())
 2706                .or_insert_with(|| {
 2707                    registered = true;
 2708                    server.register_buffer(
 2709                        uri.clone(),
 2710                        adapter.language_id(&language.name()),
 2711                        0,
 2712                        initial_snapshot.text(),
 2713                    );
 2714
 2715                    vec![snapshot]
 2716                });
 2717
 2718            self.buffers_opened_in_servers
 2719                .entry(buffer_id)
 2720                .or_default()
 2721                .insert(server.server_id());
 2722            if registered {
 2723                cx.emit(LspStoreEvent::LanguageServerUpdate {
 2724                    language_server_id: server.server_id(),
 2725                    name: None,
 2726                    message: proto::update_language_server::Variant::RegisteredForBuffer(
 2727                        proto::RegisteredForBuffer {
 2728                            buffer_abs_path: abs_path.to_string_lossy().into_owned(),
 2729                            buffer_id: buffer_id.to_proto(),
 2730                        },
 2731                    ),
 2732                });
 2733            }
 2734        }
 2735    }
 2736
 2737    fn reuse_existing_language_server<'lang_name>(
 2738        &self,
 2739        server_tree: &LanguageServerTree,
 2740        worktree: &Entity<Worktree>,
 2741        language_name: &'lang_name LanguageName,
 2742        cx: &mut App,
 2743    ) -> Option<(
 2744        Arc<LocalLspAdapterDelegate>,
 2745        impl FnOnce(&mut LanguageServerTree) -> Vec<LanguageServerTreeNode> + use<'lang_name>,
 2746    )> {
 2747        if worktree.read(cx).is_visible() {
 2748            return None;
 2749        }
 2750
 2751        let worktree_store = self.worktree_store.read(cx);
 2752        let servers = server_tree
 2753            .instances
 2754            .iter()
 2755            .filter(|(worktree_id, _)| {
 2756                worktree_store
 2757                    .worktree_for_id(**worktree_id, cx)
 2758                    .is_some_and(|worktree| worktree.read(cx).is_visible())
 2759            })
 2760            .flat_map(|(worktree_id, servers)| {
 2761                servers
 2762                    .roots
 2763                    .iter()
 2764                    .flat_map(|(_, language_servers)| language_servers)
 2765                    .map(move |(_, (server_node, server_languages))| {
 2766                        (worktree_id, server_node, server_languages)
 2767                    })
 2768                    .filter(|(_, _, server_languages)| server_languages.contains(language_name))
 2769                    .map(|(worktree_id, server_node, _)| {
 2770                        (
 2771                            *worktree_id,
 2772                            LanguageServerTreeNode::from(Arc::downgrade(server_node)),
 2773                        )
 2774                    })
 2775            })
 2776            .fold(HashMap::default(), |mut acc, (worktree_id, server_node)| {
 2777                acc.entry(worktree_id)
 2778                    .or_insert_with(Vec::new)
 2779                    .push(server_node);
 2780                acc
 2781            })
 2782            .into_values()
 2783            .max_by_key(|servers| servers.len())?;
 2784
 2785        let worktree_id = worktree.read(cx).id();
 2786        let apply = move |tree: &mut LanguageServerTree| {
 2787            for server_node in &servers {
 2788                tree.register_reused(worktree_id, language_name.clone(), server_node.clone());
 2789            }
 2790            servers
 2791        };
 2792
 2793        let delegate = LocalLspAdapterDelegate::from_local_lsp(self, worktree, cx);
 2794        Some((delegate, apply))
 2795    }
 2796
 2797    pub(crate) fn unregister_old_buffer_from_language_servers(
 2798        &mut self,
 2799        buffer: &Entity<Buffer>,
 2800        old_file: &File,
 2801        cx: &mut App,
 2802    ) {
 2803        let old_path = match old_file.as_local() {
 2804            Some(local) => local.abs_path(cx),
 2805            None => return,
 2806        };
 2807
 2808        let Ok(file_url) = lsp::Uri::from_file_path(old_path.as_path()) else {
 2809            debug_panic!("{old_path:?} is not parseable as an URI");
 2810            return;
 2811        };
 2812        self.unregister_buffer_from_language_servers(buffer, &file_url, cx);
 2813    }
 2814
 2815    pub(crate) fn unregister_buffer_from_language_servers(
 2816        &mut self,
 2817        buffer: &Entity<Buffer>,
 2818        file_url: &lsp::Uri,
 2819        cx: &mut App,
 2820    ) {
 2821        buffer.update(cx, |buffer, cx| {
 2822            let mut snapshots = self.buffer_snapshots.remove(&buffer.remote_id());
 2823
 2824            for (_, language_server) in self.language_servers_for_buffer(buffer, cx) {
 2825                if snapshots
 2826                    .as_mut()
 2827                    .is_some_and(|map| map.remove(&language_server.server_id()).is_some())
 2828                {
 2829                    language_server.unregister_buffer(file_url.clone());
 2830                }
 2831            }
 2832        });
 2833    }
 2834
 2835    fn buffer_snapshot_for_lsp_version(
 2836        &mut self,
 2837        buffer: &Entity<Buffer>,
 2838        server_id: LanguageServerId,
 2839        version: Option<i32>,
 2840        cx: &App,
 2841    ) -> Result<TextBufferSnapshot> {
 2842        const OLD_VERSIONS_TO_RETAIN: i32 = 10;
 2843
 2844        if let Some(version) = version {
 2845            let buffer_id = buffer.read(cx).remote_id();
 2846            let snapshots = if let Some(snapshots) = self
 2847                .buffer_snapshots
 2848                .get_mut(&buffer_id)
 2849                .and_then(|m| m.get_mut(&server_id))
 2850            {
 2851                snapshots
 2852            } else if version == 0 {
 2853                // Some language servers report version 0 even if the buffer hasn't been opened yet.
 2854                // We detect this case and treat it as if the version was `None`.
 2855                return Ok(buffer.read(cx).text_snapshot());
 2856            } else {
 2857                anyhow::bail!("no snapshots found for buffer {buffer_id} and server {server_id}");
 2858            };
 2859
 2860            let found_snapshot = snapshots
 2861                    .binary_search_by_key(&version, |e| e.version)
 2862                    .map(|ix| snapshots[ix].snapshot.clone())
 2863                    .map_err(|_| {
 2864                        anyhow!("snapshot not found for buffer {buffer_id} server {server_id} at version {version}")
 2865                    })?;
 2866
 2867            snapshots.retain(|snapshot| snapshot.version + OLD_VERSIONS_TO_RETAIN >= version);
 2868            Ok(found_snapshot)
 2869        } else {
 2870            Ok((buffer.read(cx)).text_snapshot())
 2871        }
 2872    }
 2873
 2874    async fn get_server_code_actions_from_action_kinds(
 2875        lsp_store: &WeakEntity<LspStore>,
 2876        language_server_id: LanguageServerId,
 2877        code_action_kinds: Vec<lsp::CodeActionKind>,
 2878        buffer: &Entity<Buffer>,
 2879        cx: &mut AsyncApp,
 2880    ) -> Result<Vec<CodeAction>> {
 2881        let actions = lsp_store
 2882            .update(cx, move |this, cx| {
 2883                let request = GetCodeActions {
 2884                    range: text::Anchor::min_max_range_for_buffer(buffer.read(cx).remote_id()),
 2885                    kinds: Some(code_action_kinds),
 2886                };
 2887                let server = LanguageServerToQuery::Other(language_server_id);
 2888                this.request_lsp(buffer.clone(), server, request, cx)
 2889            })?
 2890            .await?;
 2891        Ok(actions)
 2892    }
 2893
 2894    pub async fn execute_code_actions_on_server(
 2895        lsp_store: &WeakEntity<LspStore>,
 2896        language_server: &Arc<LanguageServer>,
 2897
 2898        actions: Vec<CodeAction>,
 2899        push_to_history: bool,
 2900        project_transaction: &mut ProjectTransaction,
 2901        cx: &mut AsyncApp,
 2902    ) -> anyhow::Result<()> {
 2903        for mut action in actions {
 2904            Self::try_resolve_code_action(language_server, &mut action)
 2905                .await
 2906                .context("resolving a formatting code action")?;
 2907
 2908            if let Some(edit) = action.lsp_action.edit() {
 2909                if edit.changes.is_none() && edit.document_changes.is_none() {
 2910                    continue;
 2911                }
 2912
 2913                let new = Self::deserialize_workspace_edit(
 2914                    lsp_store.upgrade().context("project dropped")?,
 2915                    edit.clone(),
 2916                    push_to_history,
 2917                    language_server.clone(),
 2918                    cx,
 2919                )
 2920                .await?;
 2921                project_transaction.0.extend(new.0);
 2922            }
 2923
 2924            if let Some(command) = action.lsp_action.command() {
 2925                let server_capabilities = language_server.capabilities();
 2926                let available_commands = server_capabilities
 2927                    .execute_command_provider
 2928                    .as_ref()
 2929                    .map(|options| options.commands.as_slice())
 2930                    .unwrap_or_default();
 2931                if available_commands.contains(&command.command) {
 2932                    lsp_store.update(cx, |lsp_store, _| {
 2933                        if let LspStoreMode::Local(mode) = &mut lsp_store.mode {
 2934                            mode.last_workspace_edits_by_language_server
 2935                                .remove(&language_server.server_id());
 2936                        }
 2937                    })?;
 2938
 2939                    language_server
 2940                        .request::<lsp::request::ExecuteCommand>(lsp::ExecuteCommandParams {
 2941                            command: command.command.clone(),
 2942                            arguments: command.arguments.clone().unwrap_or_default(),
 2943                            ..Default::default()
 2944                        })
 2945                        .await
 2946                        .into_response()
 2947                        .context("execute command")?;
 2948
 2949                    lsp_store.update(cx, |this, _| {
 2950                        if let LspStoreMode::Local(mode) = &mut this.mode {
 2951                            project_transaction.0.extend(
 2952                                mode.last_workspace_edits_by_language_server
 2953                                    .remove(&language_server.server_id())
 2954                                    .unwrap_or_default()
 2955                                    .0,
 2956                            )
 2957                        }
 2958                    })?;
 2959                } else {
 2960                    log::warn!(
 2961                        "Cannot execute a command {} not listed in the language server capabilities",
 2962                        command.command
 2963                    )
 2964                }
 2965            }
 2966        }
 2967        Ok(())
 2968    }
 2969
 2970    pub async fn deserialize_text_edits(
 2971        this: Entity<LspStore>,
 2972        buffer_to_edit: Entity<Buffer>,
 2973        edits: Vec<lsp::TextEdit>,
 2974        push_to_history: bool,
 2975        _: Arc<CachedLspAdapter>,
 2976        language_server: Arc<LanguageServer>,
 2977        cx: &mut AsyncApp,
 2978    ) -> Result<Option<Transaction>> {
 2979        let edits = this
 2980            .update(cx, |this, cx| {
 2981                this.as_local_mut().unwrap().edits_from_lsp(
 2982                    &buffer_to_edit,
 2983                    edits,
 2984                    language_server.server_id(),
 2985                    None,
 2986                    cx,
 2987                )
 2988            })
 2989            .await?;
 2990
 2991        let transaction = buffer_to_edit.update(cx, |buffer, cx| {
 2992            buffer.finalize_last_transaction();
 2993            buffer.start_transaction();
 2994            for (range, text) in edits {
 2995                buffer.edit([(range, text)], None, cx);
 2996            }
 2997
 2998            if buffer.end_transaction(cx).is_some() {
 2999                let transaction = buffer.finalize_last_transaction().unwrap().clone();
 3000                if !push_to_history {
 3001                    buffer.forget_transaction(transaction.id);
 3002                }
 3003                Some(transaction)
 3004            } else {
 3005                None
 3006            }
 3007        });
 3008
 3009        Ok(transaction)
 3010    }
 3011
 3012    #[allow(clippy::type_complexity)]
 3013    pub(crate) fn edits_from_lsp(
 3014        &mut self,
 3015        buffer: &Entity<Buffer>,
 3016        lsp_edits: impl 'static + Send + IntoIterator<Item = lsp::TextEdit>,
 3017        server_id: LanguageServerId,
 3018        version: Option<i32>,
 3019        cx: &mut Context<LspStore>,
 3020    ) -> Task<Result<Vec<(Range<Anchor>, Arc<str>)>>> {
 3021        let snapshot = self.buffer_snapshot_for_lsp_version(buffer, server_id, version, cx);
 3022        cx.background_spawn(async move {
 3023            let snapshot = snapshot?;
 3024            let mut lsp_edits = lsp_edits
 3025                .into_iter()
 3026                .map(|edit| (range_from_lsp(edit.range), edit.new_text))
 3027                .collect::<Vec<_>>();
 3028
 3029            lsp_edits.sort_by_key(|(range, _)| (range.start, range.end));
 3030
 3031            let mut lsp_edits = lsp_edits.into_iter().peekable();
 3032            let mut edits = Vec::new();
 3033            while let Some((range, mut new_text)) = lsp_edits.next() {
 3034                // Clip invalid ranges provided by the language server.
 3035                let mut range = snapshot.clip_point_utf16(range.start, Bias::Left)
 3036                    ..snapshot.clip_point_utf16(range.end, Bias::Left);
 3037
 3038                // Combine any LSP edits that are adjacent.
 3039                //
 3040                // Also, combine LSP edits that are separated from each other by only
 3041                // a newline. This is important because for some code actions,
 3042                // Rust-analyzer rewrites the entire buffer via a series of edits that
 3043                // are separated by unchanged newline characters.
 3044                //
 3045                // In order for the diffing logic below to work properly, any edits that
 3046                // cancel each other out must be combined into one.
 3047                while let Some((next_range, next_text)) = lsp_edits.peek() {
 3048                    if next_range.start.0 > range.end {
 3049                        if next_range.start.0.row > range.end.row + 1
 3050                            || next_range.start.0.column > 0
 3051                            || snapshot.clip_point_utf16(
 3052                                Unclipped(PointUtf16::new(range.end.row, u32::MAX)),
 3053                                Bias::Left,
 3054                            ) > range.end
 3055                        {
 3056                            break;
 3057                        }
 3058                        new_text.push('\n');
 3059                    }
 3060                    range.end = snapshot.clip_point_utf16(next_range.end, Bias::Left);
 3061                    new_text.push_str(next_text);
 3062                    lsp_edits.next();
 3063                }
 3064
 3065                // For multiline edits, perform a diff of the old and new text so that
 3066                // we can identify the changes more precisely, preserving the locations
 3067                // of any anchors positioned in the unchanged regions.
 3068                if range.end.row > range.start.row {
 3069                    let offset = range.start.to_offset(&snapshot);
 3070                    let old_text = snapshot.text_for_range(range).collect::<String>();
 3071                    let range_edits = language::text_diff(old_text.as_str(), &new_text);
 3072                    edits.extend(range_edits.into_iter().map(|(range, replacement)| {
 3073                        (
 3074                            snapshot.anchor_after(offset + range.start)
 3075                                ..snapshot.anchor_before(offset + range.end),
 3076                            replacement,
 3077                        )
 3078                    }));
 3079                } else if range.end == range.start {
 3080                    let anchor = snapshot.anchor_after(range.start);
 3081                    edits.push((anchor..anchor, new_text.into()));
 3082                } else {
 3083                    let edit_start = snapshot.anchor_after(range.start);
 3084                    let edit_end = snapshot.anchor_before(range.end);
 3085                    edits.push((edit_start..edit_end, new_text.into()));
 3086                }
 3087            }
 3088
 3089            Ok(edits)
 3090        })
 3091    }
 3092
 3093    pub(crate) async fn deserialize_workspace_edit(
 3094        this: Entity<LspStore>,
 3095        edit: lsp::WorkspaceEdit,
 3096        push_to_history: bool,
 3097        language_server: Arc<LanguageServer>,
 3098        cx: &mut AsyncApp,
 3099    ) -> Result<ProjectTransaction> {
 3100        let fs = this.read_with(cx, |this, _| this.as_local().unwrap().fs.clone());
 3101
 3102        let mut operations = Vec::new();
 3103        if let Some(document_changes) = edit.document_changes {
 3104            match document_changes {
 3105                lsp::DocumentChanges::Edits(edits) => {
 3106                    operations.extend(edits.into_iter().map(lsp::DocumentChangeOperation::Edit))
 3107                }
 3108                lsp::DocumentChanges::Operations(ops) => operations = ops,
 3109            }
 3110        } else if let Some(changes) = edit.changes {
 3111            operations.extend(changes.into_iter().map(|(uri, edits)| {
 3112                lsp::DocumentChangeOperation::Edit(lsp::TextDocumentEdit {
 3113                    text_document: lsp::OptionalVersionedTextDocumentIdentifier {
 3114                        uri,
 3115                        version: None,
 3116                    },
 3117                    edits: edits.into_iter().map(Edit::Plain).collect(),
 3118                })
 3119            }));
 3120        }
 3121
 3122        let mut project_transaction = ProjectTransaction::default();
 3123        for operation in operations {
 3124            match operation {
 3125                lsp::DocumentChangeOperation::Op(lsp::ResourceOp::Create(op)) => {
 3126                    let abs_path = op
 3127                        .uri
 3128                        .to_file_path()
 3129                        .map_err(|()| anyhow!("can't convert URI to path"))?;
 3130
 3131                    if let Some(parent_path) = abs_path.parent() {
 3132                        fs.create_dir(parent_path).await?;
 3133                    }
 3134                    if abs_path.ends_with("/") {
 3135                        fs.create_dir(&abs_path).await?;
 3136                    } else {
 3137                        fs.create_file(
 3138                            &abs_path,
 3139                            op.options
 3140                                .map(|options| fs::CreateOptions {
 3141                                    overwrite: options.overwrite.unwrap_or(false),
 3142                                    ignore_if_exists: options.ignore_if_exists.unwrap_or(false),
 3143                                })
 3144                                .unwrap_or_default(),
 3145                        )
 3146                        .await?;
 3147                    }
 3148                }
 3149
 3150                lsp::DocumentChangeOperation::Op(lsp::ResourceOp::Rename(op)) => {
 3151                    let source_abs_path = op
 3152                        .old_uri
 3153                        .to_file_path()
 3154                        .map_err(|()| anyhow!("can't convert URI to path"))?;
 3155                    let target_abs_path = op
 3156                        .new_uri
 3157                        .to_file_path()
 3158                        .map_err(|()| anyhow!("can't convert URI to path"))?;
 3159
 3160                    let options = fs::RenameOptions {
 3161                        overwrite: op
 3162                            .options
 3163                            .as_ref()
 3164                            .and_then(|options| options.overwrite)
 3165                            .unwrap_or(false),
 3166                        ignore_if_exists: op
 3167                            .options
 3168                            .as_ref()
 3169                            .and_then(|options| options.ignore_if_exists)
 3170                            .unwrap_or(false),
 3171                        create_parents: true,
 3172                    };
 3173
 3174                    fs.rename(&source_abs_path, &target_abs_path, options)
 3175                        .await?;
 3176                }
 3177
 3178                lsp::DocumentChangeOperation::Op(lsp::ResourceOp::Delete(op)) => {
 3179                    let abs_path = op
 3180                        .uri
 3181                        .to_file_path()
 3182                        .map_err(|()| anyhow!("can't convert URI to path"))?;
 3183                    let options = op
 3184                        .options
 3185                        .map(|options| fs::RemoveOptions {
 3186                            recursive: options.recursive.unwrap_or(false),
 3187                            ignore_if_not_exists: options.ignore_if_not_exists.unwrap_or(false),
 3188                        })
 3189                        .unwrap_or_default();
 3190                    if abs_path.ends_with("/") {
 3191                        fs.remove_dir(&abs_path, options).await?;
 3192                    } else {
 3193                        fs.remove_file(&abs_path, options).await?;
 3194                    }
 3195                }
 3196
 3197                lsp::DocumentChangeOperation::Edit(op) => {
 3198                    let buffer_to_edit = this
 3199                        .update(cx, |this, cx| {
 3200                            this.open_local_buffer_via_lsp(
 3201                                op.text_document.uri.clone(),
 3202                                language_server.server_id(),
 3203                                cx,
 3204                            )
 3205                        })
 3206                        .await?;
 3207
 3208                    let edits = this
 3209                        .update(cx, |this, cx| {
 3210                            let path = buffer_to_edit.read(cx).project_path(cx);
 3211                            let active_entry = this.active_entry;
 3212                            let is_active_entry = path.is_some_and(|project_path| {
 3213                                this.worktree_store
 3214                                    .read(cx)
 3215                                    .entry_for_path(&project_path, cx)
 3216                                    .is_some_and(|entry| Some(entry.id) == active_entry)
 3217                            });
 3218                            let local = this.as_local_mut().unwrap();
 3219
 3220                            let (mut edits, mut snippet_edits) = (vec![], vec![]);
 3221                            for edit in op.edits {
 3222                                match edit {
 3223                                    Edit::Plain(edit) => {
 3224                                        if !edits.contains(&edit) {
 3225                                            edits.push(edit)
 3226                                        }
 3227                                    }
 3228                                    Edit::Annotated(edit) => {
 3229                                        if !edits.contains(&edit.text_edit) {
 3230                                            edits.push(edit.text_edit)
 3231                                        }
 3232                                    }
 3233                                    Edit::Snippet(edit) => {
 3234                                        let Ok(snippet) = Snippet::parse(&edit.snippet.value)
 3235                                        else {
 3236                                            continue;
 3237                                        };
 3238
 3239                                        if is_active_entry {
 3240                                            snippet_edits.push((edit.range, snippet));
 3241                                        } else {
 3242                                            // Since this buffer is not focused, apply a normal edit.
 3243                                            let new_edit = TextEdit {
 3244                                                range: edit.range,
 3245                                                new_text: snippet.text,
 3246                                            };
 3247                                            if !edits.contains(&new_edit) {
 3248                                                edits.push(new_edit);
 3249                                            }
 3250                                        }
 3251                                    }
 3252                                }
 3253                            }
 3254                            if !snippet_edits.is_empty() {
 3255                                let buffer_id = buffer_to_edit.read(cx).remote_id();
 3256                                let version = if let Some(buffer_version) = op.text_document.version
 3257                                {
 3258                                    local
 3259                                        .buffer_snapshot_for_lsp_version(
 3260                                            &buffer_to_edit,
 3261                                            language_server.server_id(),
 3262                                            Some(buffer_version),
 3263                                            cx,
 3264                                        )
 3265                                        .ok()
 3266                                        .map(|snapshot| snapshot.version)
 3267                                } else {
 3268                                    Some(buffer_to_edit.read(cx).saved_version().clone())
 3269                                };
 3270
 3271                                let most_recent_edit =
 3272                                    version.and_then(|version| version.most_recent());
 3273                                // Check if the edit that triggered that edit has been made by this participant.
 3274
 3275                                if let Some(most_recent_edit) = most_recent_edit {
 3276                                    cx.emit(LspStoreEvent::SnippetEdit {
 3277                                        buffer_id,
 3278                                        edits: snippet_edits,
 3279                                        most_recent_edit,
 3280                                    });
 3281                                }
 3282                            }
 3283
 3284                            local.edits_from_lsp(
 3285                                &buffer_to_edit,
 3286                                edits,
 3287                                language_server.server_id(),
 3288                                op.text_document.version,
 3289                                cx,
 3290                            )
 3291                        })
 3292                        .await?;
 3293
 3294                    let transaction = buffer_to_edit.update(cx, |buffer, cx| {
 3295                        buffer.finalize_last_transaction();
 3296                        buffer.start_transaction();
 3297                        for (range, text) in edits {
 3298                            buffer.edit([(range, text)], None, cx);
 3299                        }
 3300
 3301                        buffer.end_transaction(cx).and_then(|transaction_id| {
 3302                            if push_to_history {
 3303                                buffer.finalize_last_transaction();
 3304                                buffer.get_transaction(transaction_id).cloned()
 3305                            } else {
 3306                                buffer.forget_transaction(transaction_id)
 3307                            }
 3308                        })
 3309                    });
 3310                    if let Some(transaction) = transaction {
 3311                        project_transaction.0.insert(buffer_to_edit, transaction);
 3312                    }
 3313                }
 3314            }
 3315        }
 3316
 3317        Ok(project_transaction)
 3318    }
 3319
 3320    async fn on_lsp_workspace_edit(
 3321        this: WeakEntity<LspStore>,
 3322        params: lsp::ApplyWorkspaceEditParams,
 3323        server_id: LanguageServerId,
 3324        cx: &mut AsyncApp,
 3325    ) -> Result<lsp::ApplyWorkspaceEditResponse> {
 3326        let this = this.upgrade().context("project project closed")?;
 3327        let language_server = this
 3328            .read_with(cx, |this, _| this.language_server_for_id(server_id))
 3329            .context("language server not found")?;
 3330        let transaction = Self::deserialize_workspace_edit(
 3331            this.clone(),
 3332            params.edit,
 3333            true,
 3334            language_server.clone(),
 3335            cx,
 3336        )
 3337        .await
 3338        .log_err();
 3339        this.update(cx, |this, cx| {
 3340            if let Some(transaction) = transaction {
 3341                cx.emit(LspStoreEvent::WorkspaceEditApplied(transaction.clone()));
 3342
 3343                this.as_local_mut()
 3344                    .unwrap()
 3345                    .last_workspace_edits_by_language_server
 3346                    .insert(server_id, transaction);
 3347            }
 3348        });
 3349        Ok(lsp::ApplyWorkspaceEditResponse {
 3350            applied: true,
 3351            failed_change: None,
 3352            failure_reason: None,
 3353        })
 3354    }
 3355
 3356    fn remove_worktree(
 3357        &mut self,
 3358        id_to_remove: WorktreeId,
 3359        cx: &mut Context<LspStore>,
 3360    ) -> Vec<LanguageServerId> {
 3361        self.restricted_worktrees_tasks.remove(&id_to_remove);
 3362        self.diagnostics.remove(&id_to_remove);
 3363        self.prettier_store.update(cx, |prettier_store, cx| {
 3364            prettier_store.remove_worktree(id_to_remove, cx);
 3365        });
 3366
 3367        let mut servers_to_remove = BTreeSet::default();
 3368        let mut servers_to_preserve = HashSet::default();
 3369        for (seed, state) in &self.language_server_ids {
 3370            if seed.worktree_id == id_to_remove {
 3371                servers_to_remove.insert(state.id);
 3372            } else {
 3373                servers_to_preserve.insert(state.id);
 3374            }
 3375        }
 3376        servers_to_remove.retain(|server_id| !servers_to_preserve.contains(server_id));
 3377        self.language_server_ids
 3378            .retain(|_, state| !servers_to_remove.contains(&state.id));
 3379        for server_id_to_remove in &servers_to_remove {
 3380            self.language_server_watched_paths
 3381                .remove(server_id_to_remove);
 3382            self.language_server_paths_watched_for_rename
 3383                .remove(server_id_to_remove);
 3384            self.last_workspace_edits_by_language_server
 3385                .remove(server_id_to_remove);
 3386            self.language_servers.remove(server_id_to_remove);
 3387            self.buffer_pull_diagnostics_result_ids
 3388                .remove(server_id_to_remove);
 3389            self.workspace_pull_diagnostics_result_ids
 3390                .remove(server_id_to_remove);
 3391            for buffer_servers in self.buffers_opened_in_servers.values_mut() {
 3392                buffer_servers.remove(server_id_to_remove);
 3393            }
 3394            cx.emit(LspStoreEvent::LanguageServerRemoved(*server_id_to_remove));
 3395        }
 3396        servers_to_remove.into_iter().collect()
 3397    }
 3398
 3399    fn rebuild_watched_paths_inner<'a>(
 3400        &'a self,
 3401        language_server_id: LanguageServerId,
 3402        watchers: impl Iterator<Item = &'a FileSystemWatcher>,
 3403        cx: &mut Context<LspStore>,
 3404    ) -> LanguageServerWatchedPathsBuilder {
 3405        let worktrees = self
 3406            .worktree_store
 3407            .read(cx)
 3408            .worktrees()
 3409            .filter_map(|worktree| {
 3410                self.language_servers_for_worktree(worktree.read(cx).id())
 3411                    .find(|server| server.server_id() == language_server_id)
 3412                    .map(|_| worktree)
 3413            })
 3414            .collect::<Vec<_>>();
 3415
 3416        let mut worktree_globs = HashMap::default();
 3417        let mut abs_globs = HashMap::default();
 3418        log::trace!(
 3419            "Processing new watcher paths for language server with id {}",
 3420            language_server_id
 3421        );
 3422
 3423        for watcher in watchers {
 3424            if let Some((worktree, literal_prefix, pattern)) =
 3425                Self::worktree_and_path_for_file_watcher(&worktrees, watcher, cx)
 3426            {
 3427                worktree.update(cx, |worktree, _| {
 3428                    if let Some((tree, glob)) =
 3429                        worktree.as_local_mut().zip(Glob::new(&pattern).log_err())
 3430                    {
 3431                        tree.add_path_prefix_to_scan(literal_prefix);
 3432                        worktree_globs
 3433                            .entry(tree.id())
 3434                            .or_insert_with(GlobSetBuilder::new)
 3435                            .add(glob);
 3436                    }
 3437                });
 3438            } else {
 3439                let (path, pattern) = match &watcher.glob_pattern {
 3440                    lsp::GlobPattern::String(s) => {
 3441                        let watcher_path = SanitizedPath::new(s);
 3442                        let path = glob_literal_prefix(watcher_path.as_path());
 3443                        let pattern = watcher_path
 3444                            .as_path()
 3445                            .strip_prefix(&path)
 3446                            .map(|p| p.to_string_lossy().into_owned())
 3447                            .unwrap_or_else(|e| {
 3448                                debug_panic!(
 3449                                    "Failed to strip prefix for string pattern: {}, with prefix: {}, with error: {}",
 3450                                    s,
 3451                                    path.display(),
 3452                                    e
 3453                                );
 3454                                watcher_path.as_path().to_string_lossy().into_owned()
 3455                            });
 3456                        (path, pattern)
 3457                    }
 3458                    lsp::GlobPattern::Relative(rp) => {
 3459                        let Ok(mut base_uri) = match &rp.base_uri {
 3460                            lsp::OneOf::Left(workspace_folder) => &workspace_folder.uri,
 3461                            lsp::OneOf::Right(base_uri) => base_uri,
 3462                        }
 3463                        .to_file_path() else {
 3464                            continue;
 3465                        };
 3466
 3467                        let path = glob_literal_prefix(Path::new(&rp.pattern));
 3468                        let pattern = Path::new(&rp.pattern)
 3469                            .strip_prefix(&path)
 3470                            .map(|p| p.to_string_lossy().into_owned())
 3471                            .unwrap_or_else(|e| {
 3472                                debug_panic!(
 3473                                    "Failed to strip prefix for relative pattern: {}, with prefix: {}, with error: {}",
 3474                                    rp.pattern,
 3475                                    path.display(),
 3476                                    e
 3477                                );
 3478                                rp.pattern.clone()
 3479                            });
 3480                        base_uri.push(path);
 3481                        (base_uri, pattern)
 3482                    }
 3483                };
 3484
 3485                if let Some(glob) = Glob::new(&pattern).log_err() {
 3486                    if !path
 3487                        .components()
 3488                        .any(|c| matches!(c, path::Component::Normal(_)))
 3489                    {
 3490                        // For an unrooted glob like `**/Cargo.toml`, watch it within each worktree,
 3491                        // rather than adding a new watcher for `/`.
 3492                        for worktree in &worktrees {
 3493                            worktree_globs
 3494                                .entry(worktree.read(cx).id())
 3495                                .or_insert_with(GlobSetBuilder::new)
 3496                                .add(glob.clone());
 3497                        }
 3498                    } else {
 3499                        abs_globs
 3500                            .entry(path.into())
 3501                            .or_insert_with(GlobSetBuilder::new)
 3502                            .add(glob);
 3503                    }
 3504                }
 3505            }
 3506        }
 3507
 3508        let mut watch_builder = LanguageServerWatchedPathsBuilder::default();
 3509        for (worktree_id, builder) in worktree_globs {
 3510            if let Ok(globset) = builder.build() {
 3511                watch_builder.watch_worktree(worktree_id, globset);
 3512            }
 3513        }
 3514        for (abs_path, builder) in abs_globs {
 3515            if let Ok(globset) = builder.build() {
 3516                watch_builder.watch_abs_path(abs_path, globset);
 3517            }
 3518        }
 3519        watch_builder
 3520    }
 3521
 3522    fn worktree_and_path_for_file_watcher(
 3523        worktrees: &[Entity<Worktree>],
 3524        watcher: &FileSystemWatcher,
 3525        cx: &App,
 3526    ) -> Option<(Entity<Worktree>, Arc<RelPath>, String)> {
 3527        worktrees.iter().find_map(|worktree| {
 3528            let tree = worktree.read(cx);
 3529            let worktree_root_path = tree.abs_path();
 3530            let path_style = tree.path_style();
 3531            match &watcher.glob_pattern {
 3532                lsp::GlobPattern::String(s) => {
 3533                    let watcher_path = SanitizedPath::new(s);
 3534                    let relative = watcher_path
 3535                        .as_path()
 3536                        .strip_prefix(&worktree_root_path)
 3537                        .ok()?;
 3538                    let literal_prefix = glob_literal_prefix(relative);
 3539                    Some((
 3540                        worktree.clone(),
 3541                        RelPath::new(&literal_prefix, path_style).ok()?.into_arc(),
 3542                        relative.to_string_lossy().into_owned(),
 3543                    ))
 3544                }
 3545                lsp::GlobPattern::Relative(rp) => {
 3546                    let base_uri = match &rp.base_uri {
 3547                        lsp::OneOf::Left(workspace_folder) => &workspace_folder.uri,
 3548                        lsp::OneOf::Right(base_uri) => base_uri,
 3549                    }
 3550                    .to_file_path()
 3551                    .ok()?;
 3552                    let relative = base_uri.strip_prefix(&worktree_root_path).ok()?;
 3553                    let mut literal_prefix = relative.to_owned();
 3554                    literal_prefix.push(glob_literal_prefix(Path::new(&rp.pattern)));
 3555                    Some((
 3556                        worktree.clone(),
 3557                        RelPath::new(&literal_prefix, path_style).ok()?.into_arc(),
 3558                        rp.pattern.clone(),
 3559                    ))
 3560                }
 3561            }
 3562        })
 3563    }
 3564
 3565    fn rebuild_watched_paths(
 3566        &mut self,
 3567        language_server_id: LanguageServerId,
 3568        cx: &mut Context<LspStore>,
 3569    ) {
 3570        let Some(registrations) = self
 3571            .language_server_dynamic_registrations
 3572            .get(&language_server_id)
 3573        else {
 3574            return;
 3575        };
 3576
 3577        let watch_builder = self.rebuild_watched_paths_inner(
 3578            language_server_id,
 3579            registrations.did_change_watched_files.values().flatten(),
 3580            cx,
 3581        );
 3582        let watcher = watch_builder.build(self.fs.clone(), language_server_id, cx);
 3583        self.language_server_watched_paths
 3584            .insert(language_server_id, watcher);
 3585
 3586        cx.notify();
 3587    }
 3588
 3589    fn on_lsp_did_change_watched_files(
 3590        &mut self,
 3591        language_server_id: LanguageServerId,
 3592        registration_id: &str,
 3593        params: DidChangeWatchedFilesRegistrationOptions,
 3594        cx: &mut Context<LspStore>,
 3595    ) {
 3596        let registrations = self
 3597            .language_server_dynamic_registrations
 3598            .entry(language_server_id)
 3599            .or_default();
 3600
 3601        registrations
 3602            .did_change_watched_files
 3603            .insert(registration_id.to_string(), params.watchers);
 3604
 3605        self.rebuild_watched_paths(language_server_id, cx);
 3606    }
 3607
 3608    fn on_lsp_unregister_did_change_watched_files(
 3609        &mut self,
 3610        language_server_id: LanguageServerId,
 3611        registration_id: &str,
 3612        cx: &mut Context<LspStore>,
 3613    ) {
 3614        let registrations = self
 3615            .language_server_dynamic_registrations
 3616            .entry(language_server_id)
 3617            .or_default();
 3618
 3619        if registrations
 3620            .did_change_watched_files
 3621            .remove(registration_id)
 3622            .is_some()
 3623        {
 3624            log::info!(
 3625                "language server {}: unregistered workspace/DidChangeWatchedFiles capability with id {}",
 3626                language_server_id,
 3627                registration_id
 3628            );
 3629        } else {
 3630            log::warn!(
 3631                "language server {}: failed to unregister workspace/DidChangeWatchedFiles capability with id {}. not registered.",
 3632                language_server_id,
 3633                registration_id
 3634            );
 3635        }
 3636
 3637        self.rebuild_watched_paths(language_server_id, cx);
 3638    }
 3639
 3640    async fn initialization_options_for_adapter(
 3641        adapter: Arc<dyn LspAdapter>,
 3642        delegate: &Arc<dyn LspAdapterDelegate>,
 3643    ) -> Result<Option<serde_json::Value>> {
 3644        let Some(mut initialization_config) =
 3645            adapter.clone().initialization_options(delegate).await?
 3646        else {
 3647            return Ok(None);
 3648        };
 3649
 3650        for other_adapter in delegate.registered_lsp_adapters() {
 3651            if other_adapter.name() == adapter.name() {
 3652                continue;
 3653            }
 3654            if let Ok(Some(target_config)) = other_adapter
 3655                .clone()
 3656                .additional_initialization_options(adapter.name(), delegate)
 3657                .await
 3658            {
 3659                merge_json_value_into(target_config.clone(), &mut initialization_config);
 3660            }
 3661        }
 3662
 3663        Ok(Some(initialization_config))
 3664    }
 3665
 3666    async fn workspace_configuration_for_adapter(
 3667        adapter: Arc<dyn LspAdapter>,
 3668        delegate: &Arc<dyn LspAdapterDelegate>,
 3669        toolchain: Option<Toolchain>,
 3670        requested_uri: Option<Uri>,
 3671        cx: &mut AsyncApp,
 3672    ) -> Result<serde_json::Value> {
 3673        let mut workspace_config = adapter
 3674            .clone()
 3675            .workspace_configuration(delegate, toolchain, requested_uri, cx)
 3676            .await?;
 3677
 3678        for other_adapter in delegate.registered_lsp_adapters() {
 3679            if other_adapter.name() == adapter.name() {
 3680                continue;
 3681            }
 3682            if let Ok(Some(target_config)) = other_adapter
 3683                .clone()
 3684                .additional_workspace_configuration(adapter.name(), delegate, cx)
 3685                .await
 3686            {
 3687                merge_json_value_into(target_config.clone(), &mut workspace_config);
 3688            }
 3689        }
 3690
 3691        Ok(workspace_config)
 3692    }
 3693
 3694    fn language_server_for_id(&self, id: LanguageServerId) -> Option<Arc<LanguageServer>> {
 3695        if let Some(LanguageServerState::Running { server, .. }) = self.language_servers.get(&id) {
 3696            Some(server.clone())
 3697        } else if let Some((_, server)) = self.supplementary_language_servers.get(&id) {
 3698            Some(Arc::clone(server))
 3699        } else {
 3700            None
 3701        }
 3702    }
 3703}
 3704
 3705fn notify_server_capabilities_updated(server: &LanguageServer, cx: &mut Context<LspStore>) {
 3706    if let Some(capabilities) = serde_json::to_string(&server.capabilities()).ok() {
 3707        cx.emit(LspStoreEvent::LanguageServerUpdate {
 3708            language_server_id: server.server_id(),
 3709            name: Some(server.name()),
 3710            message: proto::update_language_server::Variant::MetadataUpdated(
 3711                proto::ServerMetadataUpdated {
 3712                    capabilities: Some(capabilities),
 3713                    binary: Some(proto::LanguageServerBinaryInfo {
 3714                        path: server.binary().path.to_string_lossy().into_owned(),
 3715                        arguments: server
 3716                            .binary()
 3717                            .arguments
 3718                            .iter()
 3719                            .map(|arg| arg.to_string_lossy().into_owned())
 3720                            .collect(),
 3721                    }),
 3722                    configuration: serde_json::to_string(server.configuration()).ok(),
 3723                    workspace_folders: server
 3724                        .workspace_folders()
 3725                        .iter()
 3726                        .map(|uri| uri.to_string())
 3727                        .collect(),
 3728                },
 3729            ),
 3730        });
 3731    }
 3732}
 3733
 3734#[derive(Debug)]
 3735pub struct FormattableBuffer {
 3736    handle: Entity<Buffer>,
 3737    abs_path: Option<PathBuf>,
 3738    env: Option<HashMap<String, String>>,
 3739    ranges: Option<Vec<Range<Anchor>>>,
 3740}
 3741
 3742pub struct RemoteLspStore {
 3743    upstream_client: Option<AnyProtoClient>,
 3744    upstream_project_id: u64,
 3745}
 3746
 3747pub(crate) enum LspStoreMode {
 3748    Local(LocalLspStore),   // ssh host and collab host
 3749    Remote(RemoteLspStore), // collab guest
 3750}
 3751
 3752impl LspStoreMode {
 3753    fn is_local(&self) -> bool {
 3754        matches!(self, LspStoreMode::Local(_))
 3755    }
 3756}
 3757
 3758pub struct LspStore {
 3759    mode: LspStoreMode,
 3760    last_formatting_failure: Option<String>,
 3761    downstream_client: Option<(AnyProtoClient, u64)>,
 3762    nonce: u128,
 3763    buffer_store: Entity<BufferStore>,
 3764    worktree_store: Entity<WorktreeStore>,
 3765    pub languages: Arc<LanguageRegistry>,
 3766    pub language_server_statuses: BTreeMap<LanguageServerId, LanguageServerStatus>,
 3767    active_entry: Option<ProjectEntryId>,
 3768    _maintain_workspace_config: (Task<Result<()>>, watch::Sender<()>),
 3769    _maintain_buffer_languages: Task<()>,
 3770    diagnostic_summaries:
 3771        HashMap<WorktreeId, HashMap<Arc<RelPath>, HashMap<LanguageServerId, DiagnosticSummary>>>,
 3772    pub lsp_server_capabilities: HashMap<LanguageServerId, lsp::ServerCapabilities>,
 3773    lsp_data: HashMap<BufferId, BufferLspData>,
 3774    next_hint_id: Arc<AtomicUsize>,
 3775}
 3776
 3777#[derive(Debug)]
 3778pub struct BufferLspData {
 3779    buffer_version: Global,
 3780    document_colors: Option<DocumentColorData>,
 3781    code_lens: Option<CodeLensData>,
 3782    inlay_hints: BufferInlayHints,
 3783    lsp_requests: HashMap<LspKey, HashMap<LspRequestId, Task<()>>>,
 3784    chunk_lsp_requests: HashMap<LspKey, HashMap<RowChunk, LspRequestId>>,
 3785}
 3786
 3787#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
 3788struct LspKey {
 3789    request_type: TypeId,
 3790    server_queried: Option<LanguageServerId>,
 3791}
 3792
 3793impl BufferLspData {
 3794    fn new(buffer: &Entity<Buffer>, cx: &mut App) -> Self {
 3795        Self {
 3796            buffer_version: buffer.read(cx).version(),
 3797            document_colors: None,
 3798            code_lens: None,
 3799            inlay_hints: BufferInlayHints::new(buffer, cx),
 3800            lsp_requests: HashMap::default(),
 3801            chunk_lsp_requests: HashMap::default(),
 3802        }
 3803    }
 3804
 3805    fn remove_server_data(&mut self, for_server: LanguageServerId) {
 3806        if let Some(document_colors) = &mut self.document_colors {
 3807            document_colors.colors.remove(&for_server);
 3808            document_colors.cache_version += 1;
 3809        }
 3810
 3811        if let Some(code_lens) = &mut self.code_lens {
 3812            code_lens.lens.remove(&for_server);
 3813        }
 3814
 3815        self.inlay_hints.remove_server_data(for_server);
 3816    }
 3817
 3818    #[cfg(any(test, feature = "test-support"))]
 3819    pub fn inlay_hints(&self) -> &BufferInlayHints {
 3820        &self.inlay_hints
 3821    }
 3822}
 3823
 3824#[derive(Debug, Default, Clone)]
 3825pub struct DocumentColors {
 3826    pub colors: HashSet<DocumentColor>,
 3827    pub cache_version: Option<usize>,
 3828}
 3829
 3830type DocumentColorTask = Shared<Task<std::result::Result<DocumentColors, Arc<anyhow::Error>>>>;
 3831type CodeLensTask = Shared<Task<std::result::Result<Option<Vec<CodeAction>>, Arc<anyhow::Error>>>>;
 3832
 3833#[derive(Debug, Default)]
 3834struct DocumentColorData {
 3835    colors: HashMap<LanguageServerId, HashSet<DocumentColor>>,
 3836    cache_version: usize,
 3837    colors_update: Option<(Global, DocumentColorTask)>,
 3838}
 3839
 3840#[derive(Debug, Default)]
 3841struct CodeLensData {
 3842    lens: HashMap<LanguageServerId, Vec<CodeAction>>,
 3843    update: Option<(Global, CodeLensTask)>,
 3844}
 3845
 3846#[derive(Debug)]
 3847pub enum LspStoreEvent {
 3848    LanguageServerAdded(LanguageServerId, LanguageServerName, Option<WorktreeId>),
 3849    LanguageServerRemoved(LanguageServerId),
 3850    LanguageServerUpdate {
 3851        language_server_id: LanguageServerId,
 3852        name: Option<LanguageServerName>,
 3853        message: proto::update_language_server::Variant,
 3854    },
 3855    LanguageServerLog(LanguageServerId, LanguageServerLogType, String),
 3856    LanguageServerPrompt(LanguageServerPromptRequest),
 3857    LanguageDetected {
 3858        buffer: Entity<Buffer>,
 3859        new_language: Option<Arc<Language>>,
 3860    },
 3861    Notification(String),
 3862    RefreshInlayHints {
 3863        server_id: LanguageServerId,
 3864        request_id: Option<usize>,
 3865    },
 3866    RefreshCodeLens,
 3867    DiagnosticsUpdated {
 3868        server_id: LanguageServerId,
 3869        paths: Vec<ProjectPath>,
 3870    },
 3871    DiskBasedDiagnosticsStarted {
 3872        language_server_id: LanguageServerId,
 3873    },
 3874    DiskBasedDiagnosticsFinished {
 3875        language_server_id: LanguageServerId,
 3876    },
 3877    SnippetEdit {
 3878        buffer_id: BufferId,
 3879        edits: Vec<(lsp::Range, Snippet)>,
 3880        most_recent_edit: clock::Lamport,
 3881    },
 3882    WorkspaceEditApplied(ProjectTransaction),
 3883}
 3884
 3885#[derive(Clone, Debug, Serialize)]
 3886pub struct LanguageServerStatus {
 3887    pub name: LanguageServerName,
 3888    pub server_version: Option<SharedString>,
 3889    pub pending_work: BTreeMap<ProgressToken, LanguageServerProgress>,
 3890    pub has_pending_diagnostic_updates: bool,
 3891    pub progress_tokens: HashSet<ProgressToken>,
 3892    pub worktree: Option<WorktreeId>,
 3893    pub binary: Option<LanguageServerBinary>,
 3894    pub configuration: Option<Value>,
 3895    pub workspace_folders: BTreeSet<Uri>,
 3896}
 3897
 3898#[derive(Clone, Debug)]
 3899struct CoreSymbol {
 3900    pub language_server_name: LanguageServerName,
 3901    pub source_worktree_id: WorktreeId,
 3902    pub source_language_server_id: LanguageServerId,
 3903    pub path: SymbolLocation,
 3904    pub name: String,
 3905    pub kind: lsp::SymbolKind,
 3906    pub range: Range<Unclipped<PointUtf16>>,
 3907}
 3908
 3909#[derive(Clone, Debug, PartialEq, Eq)]
 3910pub enum SymbolLocation {
 3911    InProject(ProjectPath),
 3912    OutsideProject {
 3913        abs_path: Arc<Path>,
 3914        signature: [u8; 32],
 3915    },
 3916}
 3917
 3918impl SymbolLocation {
 3919    fn file_name(&self) -> Option<&str> {
 3920        match self {
 3921            Self::InProject(path) => path.path.file_name(),
 3922            Self::OutsideProject { abs_path, .. } => abs_path.file_name()?.to_str(),
 3923        }
 3924    }
 3925}
 3926
 3927impl LspStore {
 3928    pub fn init(client: &AnyProtoClient) {
 3929        client.add_entity_request_handler(Self::handle_lsp_query);
 3930        client.add_entity_message_handler(Self::handle_lsp_query_response);
 3931        client.add_entity_request_handler(Self::handle_restart_language_servers);
 3932        client.add_entity_request_handler(Self::handle_stop_language_servers);
 3933        client.add_entity_request_handler(Self::handle_cancel_language_server_work);
 3934        client.add_entity_message_handler(Self::handle_start_language_server);
 3935        client.add_entity_message_handler(Self::handle_update_language_server);
 3936        client.add_entity_message_handler(Self::handle_language_server_log);
 3937        client.add_entity_message_handler(Self::handle_update_diagnostic_summary);
 3938        client.add_entity_request_handler(Self::handle_format_buffers);
 3939        client.add_entity_request_handler(Self::handle_apply_code_action_kind);
 3940        client.add_entity_request_handler(Self::handle_resolve_completion_documentation);
 3941        client.add_entity_request_handler(Self::handle_apply_code_action);
 3942        client.add_entity_request_handler(Self::handle_get_project_symbols);
 3943        client.add_entity_request_handler(Self::handle_resolve_inlay_hint);
 3944        client.add_entity_request_handler(Self::handle_get_color_presentation);
 3945        client.add_entity_request_handler(Self::handle_open_buffer_for_symbol);
 3946        client.add_entity_request_handler(Self::handle_refresh_inlay_hints);
 3947        client.add_entity_request_handler(Self::handle_refresh_code_lens);
 3948        client.add_entity_request_handler(Self::handle_on_type_formatting);
 3949        client.add_entity_request_handler(Self::handle_apply_additional_edits_for_completion);
 3950        client.add_entity_request_handler(Self::handle_register_buffer_with_language_servers);
 3951        client.add_entity_request_handler(Self::handle_rename_project_entry);
 3952        client.add_entity_request_handler(Self::handle_pull_workspace_diagnostics);
 3953        client.add_entity_request_handler(Self::handle_lsp_get_completions);
 3954        client.add_entity_request_handler(Self::handle_lsp_command::<GetDocumentHighlights>);
 3955        client.add_entity_request_handler(Self::handle_lsp_command::<GetDocumentSymbols>);
 3956        client.add_entity_request_handler(Self::handle_lsp_command::<PrepareRename>);
 3957        client.add_entity_request_handler(Self::handle_lsp_command::<PerformRename>);
 3958        client.add_entity_request_handler(Self::handle_lsp_command::<LinkedEditingRange>);
 3959
 3960        client.add_entity_request_handler(Self::handle_lsp_ext_cancel_flycheck);
 3961        client.add_entity_request_handler(Self::handle_lsp_ext_run_flycheck);
 3962        client.add_entity_request_handler(Self::handle_lsp_ext_clear_flycheck);
 3963        client.add_entity_request_handler(Self::handle_lsp_command::<lsp_ext_command::ExpandMacro>);
 3964        client.add_entity_request_handler(Self::handle_lsp_command::<lsp_ext_command::OpenDocs>);
 3965        client.add_entity_request_handler(
 3966            Self::handle_lsp_command::<lsp_ext_command::GoToParentModule>,
 3967        );
 3968        client.add_entity_request_handler(
 3969            Self::handle_lsp_command::<lsp_ext_command::GetLspRunnables>,
 3970        );
 3971        client.add_entity_request_handler(
 3972            Self::handle_lsp_command::<lsp_ext_command::SwitchSourceHeader>,
 3973        );
 3974    }
 3975
 3976    pub fn as_remote(&self) -> Option<&RemoteLspStore> {
 3977        match &self.mode {
 3978            LspStoreMode::Remote(remote_lsp_store) => Some(remote_lsp_store),
 3979            _ => None,
 3980        }
 3981    }
 3982
 3983    pub fn as_local(&self) -> Option<&LocalLspStore> {
 3984        match &self.mode {
 3985            LspStoreMode::Local(local_lsp_store) => Some(local_lsp_store),
 3986            _ => None,
 3987        }
 3988    }
 3989
 3990    pub fn as_local_mut(&mut self) -> Option<&mut LocalLspStore> {
 3991        match &mut self.mode {
 3992            LspStoreMode::Local(local_lsp_store) => Some(local_lsp_store),
 3993            _ => None,
 3994        }
 3995    }
 3996
 3997    pub fn upstream_client(&self) -> Option<(AnyProtoClient, u64)> {
 3998        match &self.mode {
 3999            LspStoreMode::Remote(RemoteLspStore {
 4000                upstream_client: Some(upstream_client),
 4001                upstream_project_id,
 4002                ..
 4003            }) => Some((upstream_client.clone(), *upstream_project_id)),
 4004
 4005            LspStoreMode::Remote(RemoteLspStore {
 4006                upstream_client: None,
 4007                ..
 4008            }) => None,
 4009            LspStoreMode::Local(_) => None,
 4010        }
 4011    }
 4012
 4013    pub fn new_local(
 4014        buffer_store: Entity<BufferStore>,
 4015        worktree_store: Entity<WorktreeStore>,
 4016        prettier_store: Entity<PrettierStore>,
 4017        toolchain_store: Entity<LocalToolchainStore>,
 4018        environment: Entity<ProjectEnvironment>,
 4019        manifest_tree: Entity<ManifestTree>,
 4020        languages: Arc<LanguageRegistry>,
 4021        http_client: Arc<dyn HttpClient>,
 4022        fs: Arc<dyn Fs>,
 4023        cx: &mut Context<Self>,
 4024    ) -> Self {
 4025        let yarn = YarnPathStore::new(fs.clone(), cx);
 4026        cx.subscribe(&buffer_store, Self::on_buffer_store_event)
 4027            .detach();
 4028        cx.subscribe(&worktree_store, Self::on_worktree_store_event)
 4029            .detach();
 4030        cx.subscribe(&prettier_store, Self::on_prettier_store_event)
 4031            .detach();
 4032        cx.subscribe(&toolchain_store, Self::on_toolchain_store_event)
 4033            .detach();
 4034        cx.observe_global::<SettingsStore>(Self::on_settings_changed)
 4035            .detach();
 4036        subscribe_to_binary_statuses(&languages, cx).detach();
 4037
 4038        let _maintain_workspace_config = {
 4039            let (sender, receiver) = watch::channel();
 4040            (Self::maintain_workspace_config(receiver, cx), sender)
 4041        };
 4042
 4043        Self {
 4044            mode: LspStoreMode::Local(LocalLspStore {
 4045                weak: cx.weak_entity(),
 4046                worktree_store: worktree_store.clone(),
 4047
 4048                supplementary_language_servers: Default::default(),
 4049                languages: languages.clone(),
 4050                language_server_ids: Default::default(),
 4051                language_servers: Default::default(),
 4052                last_workspace_edits_by_language_server: Default::default(),
 4053                language_server_watched_paths: Default::default(),
 4054                language_server_paths_watched_for_rename: Default::default(),
 4055                language_server_dynamic_registrations: Default::default(),
 4056                buffers_being_formatted: Default::default(),
 4057                buffer_snapshots: Default::default(),
 4058                prettier_store,
 4059                environment,
 4060                http_client,
 4061                fs,
 4062                yarn,
 4063                next_diagnostic_group_id: Default::default(),
 4064                diagnostics: Default::default(),
 4065                _subscription: cx.on_app_quit(|this, cx| {
 4066                    this.as_local_mut()
 4067                        .unwrap()
 4068                        .shutdown_language_servers_on_quit(cx)
 4069                }),
 4070                lsp_tree: LanguageServerTree::new(
 4071                    manifest_tree,
 4072                    languages.clone(),
 4073                    toolchain_store.clone(),
 4074                ),
 4075                toolchain_store,
 4076                registered_buffers: HashMap::default(),
 4077                buffers_opened_in_servers: HashMap::default(),
 4078                buffer_pull_diagnostics_result_ids: HashMap::default(),
 4079                workspace_pull_diagnostics_result_ids: HashMap::default(),
 4080                restricted_worktrees_tasks: HashMap::default(),
 4081                watched_manifest_filenames: ManifestProvidersStore::global(cx)
 4082                    .manifest_file_names(),
 4083            }),
 4084            last_formatting_failure: None,
 4085            downstream_client: None,
 4086            buffer_store,
 4087            worktree_store,
 4088            languages: languages.clone(),
 4089            language_server_statuses: Default::default(),
 4090            nonce: StdRng::from_os_rng().random(),
 4091            diagnostic_summaries: HashMap::default(),
 4092            lsp_server_capabilities: HashMap::default(),
 4093            lsp_data: HashMap::default(),
 4094            next_hint_id: Arc::default(),
 4095            active_entry: None,
 4096            _maintain_workspace_config,
 4097            _maintain_buffer_languages: Self::maintain_buffer_languages(languages, cx),
 4098        }
 4099    }
 4100
 4101    fn send_lsp_proto_request<R: LspCommand>(
 4102        &self,
 4103        buffer: Entity<Buffer>,
 4104        client: AnyProtoClient,
 4105        upstream_project_id: u64,
 4106        request: R,
 4107        cx: &mut Context<LspStore>,
 4108    ) -> Task<anyhow::Result<<R as LspCommand>::Response>> {
 4109        if !self.is_capable_for_proto_request(&buffer, &request, cx) {
 4110            return Task::ready(Ok(R::Response::default()));
 4111        }
 4112        let message = request.to_proto(upstream_project_id, buffer.read(cx));
 4113        cx.spawn(async move |this, cx| {
 4114            let response = client.request(message).await?;
 4115            let this = this.upgrade().context("project dropped")?;
 4116            request
 4117                .response_from_proto(response, this, buffer, cx.clone())
 4118                .await
 4119        })
 4120    }
 4121
 4122    pub(super) fn new_remote(
 4123        buffer_store: Entity<BufferStore>,
 4124        worktree_store: Entity<WorktreeStore>,
 4125        languages: Arc<LanguageRegistry>,
 4126        upstream_client: AnyProtoClient,
 4127        project_id: u64,
 4128        cx: &mut Context<Self>,
 4129    ) -> Self {
 4130        cx.subscribe(&buffer_store, Self::on_buffer_store_event)
 4131            .detach();
 4132        cx.subscribe(&worktree_store, Self::on_worktree_store_event)
 4133            .detach();
 4134        subscribe_to_binary_statuses(&languages, cx).detach();
 4135        let _maintain_workspace_config = {
 4136            let (sender, receiver) = watch::channel();
 4137            (Self::maintain_workspace_config(receiver, cx), sender)
 4138        };
 4139        Self {
 4140            mode: LspStoreMode::Remote(RemoteLspStore {
 4141                upstream_client: Some(upstream_client),
 4142                upstream_project_id: project_id,
 4143            }),
 4144            downstream_client: None,
 4145            last_formatting_failure: None,
 4146            buffer_store,
 4147            worktree_store,
 4148            languages: languages.clone(),
 4149            language_server_statuses: Default::default(),
 4150            nonce: StdRng::from_os_rng().random(),
 4151            diagnostic_summaries: HashMap::default(),
 4152            lsp_server_capabilities: HashMap::default(),
 4153            next_hint_id: Arc::default(),
 4154            lsp_data: HashMap::default(),
 4155            active_entry: None,
 4156
 4157            _maintain_workspace_config,
 4158            _maintain_buffer_languages: Self::maintain_buffer_languages(languages.clone(), cx),
 4159        }
 4160    }
 4161
 4162    fn on_buffer_store_event(
 4163        &mut self,
 4164        _: Entity<BufferStore>,
 4165        event: &BufferStoreEvent,
 4166        cx: &mut Context<Self>,
 4167    ) {
 4168        match event {
 4169            BufferStoreEvent::BufferAdded(buffer) => {
 4170                self.on_buffer_added(buffer, cx).log_err();
 4171            }
 4172            BufferStoreEvent::BufferChangedFilePath { buffer, old_file } => {
 4173                let buffer_id = buffer.read(cx).remote_id();
 4174                if let Some(local) = self.as_local_mut()
 4175                    && let Some(old_file) = File::from_dyn(old_file.as_ref())
 4176                {
 4177                    local.reset_buffer(buffer, old_file, cx);
 4178
 4179                    if local.registered_buffers.contains_key(&buffer_id) {
 4180                        local.unregister_old_buffer_from_language_servers(buffer, old_file, cx);
 4181                    }
 4182                }
 4183
 4184                self.detect_language_for_buffer(buffer, cx);
 4185                if let Some(local) = self.as_local_mut() {
 4186                    local.initialize_buffer(buffer, cx);
 4187                    if local.registered_buffers.contains_key(&buffer_id) {
 4188                        local.register_buffer_with_language_servers(buffer, HashSet::default(), cx);
 4189                    }
 4190                }
 4191            }
 4192            _ => {}
 4193        }
 4194    }
 4195
 4196    fn on_worktree_store_event(
 4197        &mut self,
 4198        _: Entity<WorktreeStore>,
 4199        event: &WorktreeStoreEvent,
 4200        cx: &mut Context<Self>,
 4201    ) {
 4202        match event {
 4203            WorktreeStoreEvent::WorktreeAdded(worktree) => {
 4204                if !worktree.read(cx).is_local() {
 4205                    return;
 4206                }
 4207                cx.subscribe(worktree, |this, worktree, event, cx| match event {
 4208                    worktree::Event::UpdatedEntries(changes) => {
 4209                        this.update_local_worktree_language_servers(&worktree, changes, cx);
 4210                    }
 4211                    worktree::Event::UpdatedGitRepositories(_)
 4212                    | worktree::Event::DeletedEntry(_) => {}
 4213                })
 4214                .detach()
 4215            }
 4216            WorktreeStoreEvent::WorktreeRemoved(_, id) => self.remove_worktree(*id, cx),
 4217            WorktreeStoreEvent::WorktreeUpdateSent(worktree) => {
 4218                worktree.update(cx, |worktree, _cx| self.send_diagnostic_summaries(worktree));
 4219            }
 4220            WorktreeStoreEvent::WorktreeReleased(..)
 4221            | WorktreeStoreEvent::WorktreeOrderChanged
 4222            | WorktreeStoreEvent::WorktreeUpdatedEntries(..)
 4223            | WorktreeStoreEvent::WorktreeUpdatedGitRepositories(..)
 4224            | WorktreeStoreEvent::WorktreeDeletedEntry(..) => {}
 4225        }
 4226    }
 4227
 4228    fn on_prettier_store_event(
 4229        &mut self,
 4230        _: Entity<PrettierStore>,
 4231        event: &PrettierStoreEvent,
 4232        cx: &mut Context<Self>,
 4233    ) {
 4234        match event {
 4235            PrettierStoreEvent::LanguageServerRemoved(prettier_server_id) => {
 4236                self.unregister_supplementary_language_server(*prettier_server_id, cx);
 4237            }
 4238            PrettierStoreEvent::LanguageServerAdded {
 4239                new_server_id,
 4240                name,
 4241                prettier_server,
 4242            } => {
 4243                self.register_supplementary_language_server(
 4244                    *new_server_id,
 4245                    name.clone(),
 4246                    prettier_server.clone(),
 4247                    cx,
 4248                );
 4249            }
 4250        }
 4251    }
 4252
 4253    fn on_toolchain_store_event(
 4254        &mut self,
 4255        _: Entity<LocalToolchainStore>,
 4256        event: &ToolchainStoreEvent,
 4257        _: &mut Context<Self>,
 4258    ) {
 4259        if let ToolchainStoreEvent::ToolchainActivated = event {
 4260            self.request_workspace_config_refresh()
 4261        }
 4262    }
 4263
 4264    fn request_workspace_config_refresh(&mut self) {
 4265        *self._maintain_workspace_config.1.borrow_mut() = ();
 4266    }
 4267
 4268    pub fn prettier_store(&self) -> Option<Entity<PrettierStore>> {
 4269        self.as_local().map(|local| local.prettier_store.clone())
 4270    }
 4271
 4272    fn on_buffer_event(
 4273        &mut self,
 4274        buffer: Entity<Buffer>,
 4275        event: &language::BufferEvent,
 4276        cx: &mut Context<Self>,
 4277    ) {
 4278        match event {
 4279            language::BufferEvent::Edited => {
 4280                self.on_buffer_edited(buffer, cx);
 4281            }
 4282
 4283            language::BufferEvent::Saved => {
 4284                self.on_buffer_saved(buffer, cx);
 4285            }
 4286
 4287            _ => {}
 4288        }
 4289    }
 4290
 4291    fn on_buffer_added(&mut self, buffer: &Entity<Buffer>, cx: &mut Context<Self>) -> Result<()> {
 4292        buffer
 4293            .read(cx)
 4294            .set_language_registry(self.languages.clone());
 4295
 4296        cx.subscribe(buffer, |this, buffer, event, cx| {
 4297            this.on_buffer_event(buffer, event, cx);
 4298        })
 4299        .detach();
 4300
 4301        self.detect_language_for_buffer(buffer, cx);
 4302        if let Some(local) = self.as_local_mut() {
 4303            local.initialize_buffer(buffer, cx);
 4304        }
 4305
 4306        Ok(())
 4307    }
 4308
 4309    pub(crate) fn register_buffer_with_language_servers(
 4310        &mut self,
 4311        buffer: &Entity<Buffer>,
 4312        only_register_servers: HashSet<LanguageServerSelector>,
 4313        ignore_refcounts: bool,
 4314        cx: &mut Context<Self>,
 4315    ) -> OpenLspBufferHandle {
 4316        let buffer_id = buffer.read(cx).remote_id();
 4317        let handle = OpenLspBufferHandle(cx.new(|_| OpenLspBuffer(buffer.clone())));
 4318        if let Some(local) = self.as_local_mut() {
 4319            let refcount = local.registered_buffers.entry(buffer_id).or_insert(0);
 4320            if !ignore_refcounts {
 4321                *refcount += 1;
 4322            }
 4323
 4324            // We run early exits on non-existing buffers AFTER we mark the buffer as registered in order to handle buffer saving.
 4325            // 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
 4326            // 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
 4327            // servers in practice (we don't support non-file URI schemes in our LSP impl).
 4328            let Some(file) = File::from_dyn(buffer.read(cx).file()) else {
 4329                return handle;
 4330            };
 4331            if !file.is_local() {
 4332                return handle;
 4333            }
 4334
 4335            if ignore_refcounts || *refcount == 1 {
 4336                local.register_buffer_with_language_servers(buffer, only_register_servers, cx);
 4337            }
 4338            if !ignore_refcounts {
 4339                cx.observe_release(&handle.0, move |lsp_store, buffer, cx| {
 4340                    let refcount = {
 4341                        let local = lsp_store.as_local_mut().unwrap();
 4342                        let Some(refcount) = local.registered_buffers.get_mut(&buffer_id) else {
 4343                            debug_panic!("bad refcounting");
 4344                            return;
 4345                        };
 4346
 4347                        *refcount -= 1;
 4348                        *refcount
 4349                    };
 4350                    if refcount == 0 {
 4351                        lsp_store.lsp_data.remove(&buffer_id);
 4352                        let local = lsp_store.as_local_mut().unwrap();
 4353                        local.registered_buffers.remove(&buffer_id);
 4354
 4355                        local.buffers_opened_in_servers.remove(&buffer_id);
 4356                        if let Some(file) = File::from_dyn(buffer.0.read(cx).file()).cloned() {
 4357                            local.unregister_old_buffer_from_language_servers(&buffer.0, &file, cx);
 4358
 4359                            let buffer_abs_path = file.abs_path(cx);
 4360                            for (_, buffer_pull_diagnostics_result_ids) in
 4361                                &mut local.buffer_pull_diagnostics_result_ids
 4362                            {
 4363                                buffer_pull_diagnostics_result_ids.retain(
 4364                                    |_, buffer_result_ids| {
 4365                                        buffer_result_ids.remove(&buffer_abs_path);
 4366                                        !buffer_result_ids.is_empty()
 4367                                    },
 4368                                );
 4369                            }
 4370
 4371                            let diagnostic_updates = local
 4372                                .language_servers
 4373                                .keys()
 4374                                .cloned()
 4375                                .map(|server_id| DocumentDiagnosticsUpdate {
 4376                                    diagnostics: DocumentDiagnostics {
 4377                                        document_abs_path: buffer_abs_path.clone(),
 4378                                        version: None,
 4379                                        diagnostics: Vec::new(),
 4380                                    },
 4381                                    result_id: None,
 4382                                    registration_id: None,
 4383                                    server_id: server_id,
 4384                                    disk_based_sources: Cow::Borrowed(&[]),
 4385                                })
 4386                                .collect::<Vec<_>>();
 4387
 4388                            lsp_store
 4389                                .merge_diagnostic_entries(
 4390                                    diagnostic_updates,
 4391                                    |_, diagnostic, _| {
 4392                                        diagnostic.source_kind != DiagnosticSourceKind::Pulled
 4393                                    },
 4394                                    cx,
 4395                                )
 4396                                .context("Clearing diagnostics for the closed buffer")
 4397                                .log_err();
 4398                        }
 4399                    }
 4400                })
 4401                .detach();
 4402            }
 4403        } else if let Some((upstream_client, upstream_project_id)) = self.upstream_client() {
 4404            let buffer_id = buffer.read(cx).remote_id().to_proto();
 4405            cx.background_spawn(async move {
 4406                upstream_client
 4407                    .request(proto::RegisterBufferWithLanguageServers {
 4408                        project_id: upstream_project_id,
 4409                        buffer_id,
 4410                        only_servers: only_register_servers
 4411                            .into_iter()
 4412                            .map(|selector| {
 4413                                let selector = match selector {
 4414                                    LanguageServerSelector::Id(language_server_id) => {
 4415                                        proto::language_server_selector::Selector::ServerId(
 4416                                            language_server_id.to_proto(),
 4417                                        )
 4418                                    }
 4419                                    LanguageServerSelector::Name(language_server_name) => {
 4420                                        proto::language_server_selector::Selector::Name(
 4421                                            language_server_name.to_string(),
 4422                                        )
 4423                                    }
 4424                                };
 4425                                proto::LanguageServerSelector {
 4426                                    selector: Some(selector),
 4427                                }
 4428                            })
 4429                            .collect(),
 4430                    })
 4431                    .await
 4432            })
 4433            .detach();
 4434        } else {
 4435            // Our remote connection got closed
 4436        }
 4437        handle
 4438    }
 4439
 4440    fn maintain_buffer_languages(
 4441        languages: Arc<LanguageRegistry>,
 4442        cx: &mut Context<Self>,
 4443    ) -> Task<()> {
 4444        let mut subscription = languages.subscribe();
 4445        let mut prev_reload_count = languages.reload_count();
 4446        cx.spawn(async move |this, cx| {
 4447            while let Some(()) = subscription.next().await {
 4448                if let Some(this) = this.upgrade() {
 4449                    // If the language registry has been reloaded, then remove and
 4450                    // re-assign the languages on all open buffers.
 4451                    let reload_count = languages.reload_count();
 4452                    if reload_count > prev_reload_count {
 4453                        prev_reload_count = reload_count;
 4454                        this.update(cx, |this, cx| {
 4455                            this.buffer_store.clone().update(cx, |buffer_store, cx| {
 4456                                for buffer in buffer_store.buffers() {
 4457                                    if let Some(f) = File::from_dyn(buffer.read(cx).file()).cloned()
 4458                                    {
 4459                                        buffer.update(cx, |buffer, cx| {
 4460                                            buffer.set_language_async(None, cx)
 4461                                        });
 4462                                        if let Some(local) = this.as_local_mut() {
 4463                                            local.reset_buffer(&buffer, &f, cx);
 4464
 4465                                            if local
 4466                                                .registered_buffers
 4467                                                .contains_key(&buffer.read(cx).remote_id())
 4468                                                && let Some(file_url) =
 4469                                                    file_path_to_lsp_url(&f.abs_path(cx)).log_err()
 4470                                            {
 4471                                                local.unregister_buffer_from_language_servers(
 4472                                                    &buffer, &file_url, cx,
 4473                                                );
 4474                                            }
 4475                                        }
 4476                                    }
 4477                                }
 4478                            });
 4479                        });
 4480                    }
 4481
 4482                    this.update(cx, |this, cx| {
 4483                        let mut plain_text_buffers = Vec::new();
 4484                        let mut buffers_with_unknown_injections = Vec::new();
 4485                        for handle in this.buffer_store.read(cx).buffers() {
 4486                            let buffer = handle.read(cx);
 4487                            if buffer.language().is_none()
 4488                                || buffer.language() == Some(&*language::PLAIN_TEXT)
 4489                            {
 4490                                plain_text_buffers.push(handle);
 4491                            } else if buffer.contains_unknown_injections() {
 4492                                buffers_with_unknown_injections.push(handle);
 4493                            }
 4494                        }
 4495
 4496                        // Deprioritize the invisible worktrees so main worktrees' language servers can be started first,
 4497                        // and reused later in the invisible worktrees.
 4498                        plain_text_buffers.sort_by_key(|buffer| {
 4499                            Reverse(
 4500                                File::from_dyn(buffer.read(cx).file())
 4501                                    .map(|file| file.worktree.read(cx).is_visible()),
 4502                            )
 4503                        });
 4504
 4505                        for buffer in plain_text_buffers {
 4506                            this.detect_language_for_buffer(&buffer, cx);
 4507                            if let Some(local) = this.as_local_mut() {
 4508                                local.initialize_buffer(&buffer, cx);
 4509                                if local
 4510                                    .registered_buffers
 4511                                    .contains_key(&buffer.read(cx).remote_id())
 4512                                {
 4513                                    local.register_buffer_with_language_servers(
 4514                                        &buffer,
 4515                                        HashSet::default(),
 4516                                        cx,
 4517                                    );
 4518                                }
 4519                            }
 4520                        }
 4521
 4522                        for buffer in buffers_with_unknown_injections {
 4523                            buffer.update(cx, |buffer, cx| buffer.reparse(cx, false));
 4524                        }
 4525                    });
 4526                }
 4527            }
 4528        })
 4529    }
 4530
 4531    fn detect_language_for_buffer(
 4532        &mut self,
 4533        buffer_handle: &Entity<Buffer>,
 4534        cx: &mut Context<Self>,
 4535    ) -> Option<language::AvailableLanguage> {
 4536        // If the buffer has a language, set it and start the language server if we haven't already.
 4537        let buffer = buffer_handle.read(cx);
 4538        let file = buffer.file()?;
 4539
 4540        let content = buffer.as_rope();
 4541        let available_language = self.languages.language_for_file(file, Some(content), cx);
 4542        if let Some(available_language) = &available_language {
 4543            if let Some(Ok(Ok(new_language))) = self
 4544                .languages
 4545                .load_language(available_language)
 4546                .now_or_never()
 4547            {
 4548                self.set_language_for_buffer(buffer_handle, new_language, cx);
 4549            }
 4550        } else {
 4551            cx.emit(LspStoreEvent::LanguageDetected {
 4552                buffer: buffer_handle.clone(),
 4553                new_language: None,
 4554            });
 4555        }
 4556
 4557        available_language
 4558    }
 4559
 4560    pub(crate) fn set_language_for_buffer(
 4561        &mut self,
 4562        buffer_entity: &Entity<Buffer>,
 4563        new_language: Arc<Language>,
 4564        cx: &mut Context<Self>,
 4565    ) {
 4566        let buffer = buffer_entity.read(cx);
 4567        let buffer_file = buffer.file().cloned();
 4568        let buffer_id = buffer.remote_id();
 4569        if let Some(local_store) = self.as_local_mut()
 4570            && local_store.registered_buffers.contains_key(&buffer_id)
 4571            && let Some(abs_path) =
 4572                File::from_dyn(buffer_file.as_ref()).map(|file| file.abs_path(cx))
 4573            && let Some(file_url) = file_path_to_lsp_url(&abs_path).log_err()
 4574        {
 4575            local_store.unregister_buffer_from_language_servers(buffer_entity, &file_url, cx);
 4576        }
 4577        buffer_entity.update(cx, |buffer, cx| {
 4578            if buffer
 4579                .language()
 4580                .is_none_or(|old_language| !Arc::ptr_eq(old_language, &new_language))
 4581            {
 4582                buffer.set_language_async(Some(new_language.clone()), cx);
 4583            }
 4584        });
 4585
 4586        let settings =
 4587            language_settings(Some(new_language.name()), buffer_file.as_ref(), cx).into_owned();
 4588        let buffer_file = File::from_dyn(buffer_file.as_ref());
 4589
 4590        let worktree_id = if let Some(file) = buffer_file {
 4591            let worktree = file.worktree.clone();
 4592
 4593            if let Some(local) = self.as_local_mut()
 4594                && local.registered_buffers.contains_key(&buffer_id)
 4595            {
 4596                local.register_buffer_with_language_servers(buffer_entity, HashSet::default(), cx);
 4597            }
 4598            Some(worktree.read(cx).id())
 4599        } else {
 4600            None
 4601        };
 4602
 4603        if settings.prettier.allowed
 4604            && let Some(prettier_plugins) = prettier_store::prettier_plugins_for_language(&settings)
 4605        {
 4606            let prettier_store = self.as_local().map(|s| s.prettier_store.clone());
 4607            if let Some(prettier_store) = prettier_store {
 4608                prettier_store.update(cx, |prettier_store, cx| {
 4609                    prettier_store.install_default_prettier(
 4610                        worktree_id,
 4611                        prettier_plugins.iter().map(|s| Arc::from(s.as_str())),
 4612                        cx,
 4613                    )
 4614                })
 4615            }
 4616        }
 4617
 4618        cx.emit(LspStoreEvent::LanguageDetected {
 4619            buffer: buffer_entity.clone(),
 4620            new_language: Some(new_language),
 4621        })
 4622    }
 4623
 4624    pub fn buffer_store(&self) -> Entity<BufferStore> {
 4625        self.buffer_store.clone()
 4626    }
 4627
 4628    pub fn set_active_entry(&mut self, active_entry: Option<ProjectEntryId>) {
 4629        self.active_entry = active_entry;
 4630    }
 4631
 4632    pub(crate) fn send_diagnostic_summaries(&self, worktree: &mut Worktree) {
 4633        if let Some((client, downstream_project_id)) = self.downstream_client.clone()
 4634            && let Some(diangostic_summaries) = self.diagnostic_summaries.get(&worktree.id())
 4635        {
 4636            let mut summaries = diangostic_summaries.iter().flat_map(|(path, summaries)| {
 4637                summaries
 4638                    .iter()
 4639                    .map(|(server_id, summary)| summary.to_proto(*server_id, path.as_ref()))
 4640            });
 4641            if let Some(summary) = summaries.next() {
 4642                client
 4643                    .send(proto::UpdateDiagnosticSummary {
 4644                        project_id: downstream_project_id,
 4645                        worktree_id: worktree.id().to_proto(),
 4646                        summary: Some(summary),
 4647                        more_summaries: summaries.collect(),
 4648                    })
 4649                    .log_err();
 4650            }
 4651        }
 4652    }
 4653
 4654    fn is_capable_for_proto_request<R>(
 4655        &self,
 4656        buffer: &Entity<Buffer>,
 4657        request: &R,
 4658        cx: &App,
 4659    ) -> bool
 4660    where
 4661        R: LspCommand,
 4662    {
 4663        self.check_if_capable_for_proto_request(
 4664            buffer,
 4665            |capabilities| {
 4666                request.check_capabilities(AdapterServerCapabilities {
 4667                    server_capabilities: capabilities.clone(),
 4668                    code_action_kinds: None,
 4669                })
 4670            },
 4671            cx,
 4672        )
 4673    }
 4674
 4675    fn check_if_capable_for_proto_request<F>(
 4676        &self,
 4677        buffer: &Entity<Buffer>,
 4678        check: F,
 4679        cx: &App,
 4680    ) -> bool
 4681    where
 4682        F: FnMut(&lsp::ServerCapabilities) -> bool,
 4683    {
 4684        let Some(language) = buffer.read(cx).language().cloned() else {
 4685            return false;
 4686        };
 4687        let registered_language_servers = self
 4688            .languages
 4689            .lsp_adapters(&language.name())
 4690            .into_iter()
 4691            .map(|lsp_adapter| lsp_adapter.name())
 4692            .collect::<HashSet<_>>();
 4693        self.language_server_statuses
 4694            .iter()
 4695            .filter_map(|(server_id, server_status)| {
 4696                // Include servers that are either registered for this language OR
 4697                // available to be loaded (for SSH remote mode where adapters like
 4698                // ty/pylsp/pyright are registered via register_available_lsp_adapter
 4699                // but only loaded on the server side)
 4700                let is_relevant = registered_language_servers.contains(&server_status.name)
 4701                    || self.languages.is_lsp_adapter_available(&server_status.name);
 4702                is_relevant.then_some(server_id)
 4703            })
 4704            .filter_map(|server_id| self.lsp_server_capabilities.get(server_id))
 4705            .any(check)
 4706    }
 4707
 4708    fn all_capable_for_proto_request<F>(
 4709        &self,
 4710        buffer: &Entity<Buffer>,
 4711        mut check: F,
 4712        cx: &App,
 4713    ) -> Vec<lsp::LanguageServerId>
 4714    where
 4715        F: FnMut(&lsp::LanguageServerName, &lsp::ServerCapabilities) -> bool,
 4716    {
 4717        let Some(language) = buffer.read(cx).language().cloned() else {
 4718            return Vec::default();
 4719        };
 4720        let registered_language_servers = self
 4721            .languages
 4722            .lsp_adapters(&language.name())
 4723            .into_iter()
 4724            .map(|lsp_adapter| lsp_adapter.name())
 4725            .collect::<HashSet<_>>();
 4726        self.language_server_statuses
 4727            .iter()
 4728            .filter_map(|(server_id, server_status)| {
 4729                // Include servers that are either registered for this language OR
 4730                // available to be loaded (for SSH remote mode where adapters like
 4731                // ty/pylsp/pyright are registered via register_available_lsp_adapter
 4732                // but only loaded on the server side)
 4733                let is_relevant = registered_language_servers.contains(&server_status.name)
 4734                    || self.languages.is_lsp_adapter_available(&server_status.name);
 4735                is_relevant.then_some((server_id, &server_status.name))
 4736            })
 4737            .filter_map(|(server_id, server_name)| {
 4738                self.lsp_server_capabilities
 4739                    .get(server_id)
 4740                    .map(|c| (server_id, server_name, c))
 4741            })
 4742            .filter(|(_, server_name, capabilities)| check(server_name, capabilities))
 4743            .map(|(server_id, _, _)| *server_id)
 4744            .collect()
 4745    }
 4746
 4747    pub fn request_lsp<R>(
 4748        &mut self,
 4749        buffer: Entity<Buffer>,
 4750        server: LanguageServerToQuery,
 4751        request: R,
 4752        cx: &mut Context<Self>,
 4753    ) -> Task<Result<R::Response>>
 4754    where
 4755        R: LspCommand,
 4756        <R::LspRequest as lsp::request::Request>::Result: Send,
 4757        <R::LspRequest as lsp::request::Request>::Params: Send,
 4758    {
 4759        if let Some((upstream_client, upstream_project_id)) = self.upstream_client() {
 4760            return self.send_lsp_proto_request(
 4761                buffer,
 4762                upstream_client,
 4763                upstream_project_id,
 4764                request,
 4765                cx,
 4766            );
 4767        }
 4768
 4769        let Some(language_server) = buffer.update(cx, |buffer, cx| match server {
 4770            LanguageServerToQuery::FirstCapable => self.as_local().and_then(|local| {
 4771                local
 4772                    .language_servers_for_buffer(buffer, cx)
 4773                    .find(|(_, server)| {
 4774                        request.check_capabilities(server.adapter_server_capabilities())
 4775                    })
 4776                    .map(|(_, server)| server.clone())
 4777            }),
 4778            LanguageServerToQuery::Other(id) => self
 4779                .language_server_for_local_buffer(buffer, id, cx)
 4780                .and_then(|(_, server)| {
 4781                    request
 4782                        .check_capabilities(server.adapter_server_capabilities())
 4783                        .then(|| Arc::clone(server))
 4784                }),
 4785        }) else {
 4786            return Task::ready(Ok(Default::default()));
 4787        };
 4788
 4789        let file = File::from_dyn(buffer.read(cx).file()).and_then(File::as_local);
 4790
 4791        let Some(file) = file else {
 4792            return Task::ready(Ok(Default::default()));
 4793        };
 4794
 4795        let lsp_params = match request.to_lsp_params_or_response(
 4796            &file.abs_path(cx),
 4797            buffer.read(cx),
 4798            &language_server,
 4799            cx,
 4800        ) {
 4801            Ok(LspParamsOrResponse::Params(lsp_params)) => lsp_params,
 4802            Ok(LspParamsOrResponse::Response(response)) => return Task::ready(Ok(response)),
 4803            Err(err) => {
 4804                let message = format!(
 4805                    "{} via {} failed: {}",
 4806                    request.display_name(),
 4807                    language_server.name(),
 4808                    err
 4809                );
 4810                // rust-analyzer likes to error with this when its still loading up
 4811                if !message.ends_with("content modified") {
 4812                    log::warn!("{message}");
 4813                }
 4814                return Task::ready(Err(anyhow!(message)));
 4815            }
 4816        };
 4817
 4818        let status = request.status();
 4819        if !request.check_capabilities(language_server.adapter_server_capabilities()) {
 4820            return Task::ready(Ok(Default::default()));
 4821        }
 4822        cx.spawn(async move |this, cx| {
 4823            let lsp_request = language_server.request::<R::LspRequest>(lsp_params);
 4824
 4825            let id = lsp_request.id();
 4826            let _cleanup = if status.is_some() {
 4827                cx.update(|cx| {
 4828                    this.update(cx, |this, cx| {
 4829                        this.on_lsp_work_start(
 4830                            language_server.server_id(),
 4831                            ProgressToken::Number(id),
 4832                            LanguageServerProgress {
 4833                                is_disk_based_diagnostics_progress: false,
 4834                                is_cancellable: false,
 4835                                title: None,
 4836                                message: status.clone(),
 4837                                percentage: None,
 4838                                last_update_at: cx.background_executor().now(),
 4839                            },
 4840                            cx,
 4841                        );
 4842                    })
 4843                })
 4844                .log_err();
 4845
 4846                Some(defer(|| {
 4847                    cx.update(|cx| {
 4848                        this.update(cx, |this, cx| {
 4849                            this.on_lsp_work_end(
 4850                                language_server.server_id(),
 4851                                ProgressToken::Number(id),
 4852                                cx,
 4853                            );
 4854                        })
 4855                    })
 4856                    .log_err();
 4857                }))
 4858            } else {
 4859                None
 4860            };
 4861
 4862            let result = lsp_request.await.into_response();
 4863
 4864            let response = result.map_err(|err| {
 4865                let message = format!(
 4866                    "{} via {} failed: {}",
 4867                    request.display_name(),
 4868                    language_server.name(),
 4869                    err
 4870                );
 4871                // rust-analyzer likes to error with this when its still loading up
 4872                if !message.ends_with("content modified") {
 4873                    log::warn!("{message}");
 4874                }
 4875                anyhow::anyhow!(message)
 4876            })?;
 4877
 4878            request
 4879                .response_from_lsp(
 4880                    response,
 4881                    this.upgrade().context("no app context")?,
 4882                    buffer,
 4883                    language_server.server_id(),
 4884                    cx.clone(),
 4885                )
 4886                .await
 4887        })
 4888    }
 4889
 4890    fn on_settings_changed(&mut self, cx: &mut Context<Self>) {
 4891        let mut language_formatters_to_check = Vec::new();
 4892        for buffer in self.buffer_store.read(cx).buffers() {
 4893            let buffer = buffer.read(cx);
 4894            let buffer_file = File::from_dyn(buffer.file());
 4895            let buffer_language = buffer.language();
 4896            let settings = language_settings(buffer_language.map(|l| l.name()), buffer.file(), cx);
 4897            if buffer_language.is_some() {
 4898                language_formatters_to_check.push((
 4899                    buffer_file.map(|f| f.worktree_id(cx)),
 4900                    settings.into_owned(),
 4901                ));
 4902            }
 4903        }
 4904
 4905        self.request_workspace_config_refresh();
 4906
 4907        if let Some(prettier_store) = self.as_local().map(|s| s.prettier_store.clone()) {
 4908            prettier_store.update(cx, |prettier_store, cx| {
 4909                prettier_store.on_settings_changed(language_formatters_to_check, cx)
 4910            })
 4911        }
 4912
 4913        cx.notify();
 4914    }
 4915
 4916    fn refresh_server_tree(&mut self, cx: &mut Context<Self>) {
 4917        let buffer_store = self.buffer_store.clone();
 4918        let Some(local) = self.as_local_mut() else {
 4919            return;
 4920        };
 4921        let mut adapters = BTreeMap::default();
 4922        let get_adapter = {
 4923            let languages = local.languages.clone();
 4924            let environment = local.environment.clone();
 4925            let weak = local.weak.clone();
 4926            let worktree_store = local.worktree_store.clone();
 4927            let http_client = local.http_client.clone();
 4928            let fs = local.fs.clone();
 4929            move |worktree_id, cx: &mut App| {
 4930                let worktree = worktree_store.read(cx).worktree_for_id(worktree_id, cx)?;
 4931                Some(LocalLspAdapterDelegate::new(
 4932                    languages.clone(),
 4933                    &environment,
 4934                    weak.clone(),
 4935                    &worktree,
 4936                    http_client.clone(),
 4937                    fs.clone(),
 4938                    cx,
 4939                ))
 4940            }
 4941        };
 4942
 4943        let mut messages_to_report = Vec::new();
 4944        let (new_tree, to_stop) = {
 4945            let mut rebase = local.lsp_tree.rebase();
 4946            let buffers = buffer_store
 4947                .read(cx)
 4948                .buffers()
 4949                .filter_map(|buffer| {
 4950                    let raw_buffer = buffer.read(cx);
 4951                    if !local
 4952                        .registered_buffers
 4953                        .contains_key(&raw_buffer.remote_id())
 4954                    {
 4955                        return None;
 4956                    }
 4957                    let file = File::from_dyn(raw_buffer.file()).cloned()?;
 4958                    let language = raw_buffer.language().cloned()?;
 4959                    Some((file, language, raw_buffer.remote_id()))
 4960                })
 4961                .sorted_by_key(|(file, _, _)| Reverse(file.worktree.read(cx).is_visible()));
 4962            for (file, language, buffer_id) in buffers {
 4963                let worktree_id = file.worktree_id(cx);
 4964                let Some(worktree) = local
 4965                    .worktree_store
 4966                    .read(cx)
 4967                    .worktree_for_id(worktree_id, cx)
 4968                else {
 4969                    continue;
 4970                };
 4971
 4972                if let Some((_, apply)) = local.reuse_existing_language_server(
 4973                    rebase.server_tree(),
 4974                    &worktree,
 4975                    &language.name(),
 4976                    cx,
 4977                ) {
 4978                    (apply)(rebase.server_tree());
 4979                } else if let Some(lsp_delegate) = adapters
 4980                    .entry(worktree_id)
 4981                    .or_insert_with(|| get_adapter(worktree_id, cx))
 4982                    .clone()
 4983                {
 4984                    let delegate =
 4985                        Arc::new(ManifestQueryDelegate::new(worktree.read(cx).snapshot()));
 4986                    let path = file
 4987                        .path()
 4988                        .parent()
 4989                        .map(Arc::from)
 4990                        .unwrap_or_else(|| file.path().clone());
 4991                    let worktree_path = ProjectPath { worktree_id, path };
 4992                    let abs_path = file.abs_path(cx);
 4993                    let nodes = rebase
 4994                        .walk(
 4995                            worktree_path,
 4996                            language.name(),
 4997                            language.manifest(),
 4998                            delegate.clone(),
 4999                            cx,
 5000                        )
 5001                        .collect::<Vec<_>>();
 5002                    for node in nodes {
 5003                        let server_id = node.server_id_or_init(|disposition| {
 5004                            let path = &disposition.path;
 5005                            let uri = Uri::from_file_path(worktree.read(cx).absolutize(&path.path));
 5006                            let key = LanguageServerSeed {
 5007                                worktree_id,
 5008                                name: disposition.server_name.clone(),
 5009                                settings: disposition.settings.clone(),
 5010                                toolchain: local.toolchain_store.read(cx).active_toolchain(
 5011                                    path.worktree_id,
 5012                                    &path.path,
 5013                                    language.name(),
 5014                                ),
 5015                            };
 5016                            local.language_server_ids.remove(&key);
 5017
 5018                            let server_id = local.get_or_insert_language_server(
 5019                                &worktree,
 5020                                lsp_delegate.clone(),
 5021                                disposition,
 5022                                &language.name(),
 5023                                cx,
 5024                            );
 5025                            if let Some(state) = local.language_servers.get(&server_id)
 5026                                && let Ok(uri) = uri
 5027                            {
 5028                                state.add_workspace_folder(uri);
 5029                            };
 5030                            server_id
 5031                        });
 5032
 5033                        if let Some(language_server_id) = server_id {
 5034                            messages_to_report.push(LspStoreEvent::LanguageServerUpdate {
 5035                                language_server_id,
 5036                                name: node.name(),
 5037                                message:
 5038                                    proto::update_language_server::Variant::RegisteredForBuffer(
 5039                                        proto::RegisteredForBuffer {
 5040                                            buffer_abs_path: abs_path
 5041                                                .to_string_lossy()
 5042                                                .into_owned(),
 5043                                            buffer_id: buffer_id.to_proto(),
 5044                                        },
 5045                                    ),
 5046                            });
 5047                        }
 5048                    }
 5049                } else {
 5050                    continue;
 5051                }
 5052            }
 5053            rebase.finish()
 5054        };
 5055        for message in messages_to_report {
 5056            cx.emit(message);
 5057        }
 5058        local.lsp_tree = new_tree;
 5059        for (id, _) in to_stop {
 5060            self.stop_local_language_server(id, cx).detach();
 5061        }
 5062    }
 5063
 5064    pub fn apply_code_action(
 5065        &self,
 5066        buffer_handle: Entity<Buffer>,
 5067        mut action: CodeAction,
 5068        push_to_history: bool,
 5069        cx: &mut Context<Self>,
 5070    ) -> Task<Result<ProjectTransaction>> {
 5071        if let Some((upstream_client, project_id)) = self.upstream_client() {
 5072            let request = proto::ApplyCodeAction {
 5073                project_id,
 5074                buffer_id: buffer_handle.read(cx).remote_id().into(),
 5075                action: Some(Self::serialize_code_action(&action)),
 5076            };
 5077            let buffer_store = self.buffer_store();
 5078            cx.spawn(async move |_, cx| {
 5079                let response = upstream_client
 5080                    .request(request)
 5081                    .await?
 5082                    .transaction
 5083                    .context("missing transaction")?;
 5084
 5085                buffer_store
 5086                    .update(cx, |buffer_store, cx| {
 5087                        buffer_store.deserialize_project_transaction(response, push_to_history, cx)
 5088                    })
 5089                    .await
 5090            })
 5091        } else if self.mode.is_local() {
 5092            let Some((_, lang_server)) = buffer_handle.update(cx, |buffer, cx| {
 5093                self.language_server_for_local_buffer(buffer, action.server_id, cx)
 5094                    .map(|(adapter, server)| (adapter.clone(), server.clone()))
 5095            }) else {
 5096                return Task::ready(Ok(ProjectTransaction::default()));
 5097            };
 5098            cx.spawn(async move |this,  cx| {
 5099                LocalLspStore::try_resolve_code_action(&lang_server, &mut action)
 5100                    .await
 5101                    .context("resolving a code action")?;
 5102                if let Some(edit) = action.lsp_action.edit()
 5103                    && (edit.changes.is_some() || edit.document_changes.is_some()) {
 5104                        return LocalLspStore::deserialize_workspace_edit(
 5105                            this.upgrade().context("no app present")?,
 5106                            edit.clone(),
 5107                            push_to_history,
 5108
 5109                            lang_server.clone(),
 5110                            cx,
 5111                        )
 5112                        .await;
 5113                    }
 5114
 5115                if let Some(command) = action.lsp_action.command() {
 5116                    let server_capabilities = lang_server.capabilities();
 5117                    let available_commands = server_capabilities
 5118                        .execute_command_provider
 5119                        .as_ref()
 5120                        .map(|options| options.commands.as_slice())
 5121                        .unwrap_or_default();
 5122                    if available_commands.contains(&command.command) {
 5123                        this.update(cx, |this, _| {
 5124                            this.as_local_mut()
 5125                                .unwrap()
 5126                                .last_workspace_edits_by_language_server
 5127                                .remove(&lang_server.server_id());
 5128                        })?;
 5129
 5130                        let _result = lang_server
 5131                            .request::<lsp::request::ExecuteCommand>(lsp::ExecuteCommandParams {
 5132                                command: command.command.clone(),
 5133                                arguments: command.arguments.clone().unwrap_or_default(),
 5134                                ..lsp::ExecuteCommandParams::default()
 5135                            })
 5136                            .await.into_response()
 5137                            .context("execute command")?;
 5138
 5139                        return this.update(cx, |this, _| {
 5140                            this.as_local_mut()
 5141                                .unwrap()
 5142                                .last_workspace_edits_by_language_server
 5143                                .remove(&lang_server.server_id())
 5144                                .unwrap_or_default()
 5145                        });
 5146                    } else {
 5147                        log::warn!("Cannot execute a command {} not listed in the language server capabilities", command.command);
 5148                    }
 5149                }
 5150
 5151                Ok(ProjectTransaction::default())
 5152            })
 5153        } else {
 5154            Task::ready(Err(anyhow!("no upstream client and not local")))
 5155        }
 5156    }
 5157
 5158    pub fn apply_code_action_kind(
 5159        &mut self,
 5160        buffers: HashSet<Entity<Buffer>>,
 5161        kind: CodeActionKind,
 5162        push_to_history: bool,
 5163        cx: &mut Context<Self>,
 5164    ) -> Task<anyhow::Result<ProjectTransaction>> {
 5165        if self.as_local().is_some() {
 5166            cx.spawn(async move |lsp_store, cx| {
 5167                let buffers = buffers.into_iter().collect::<Vec<_>>();
 5168                let result = LocalLspStore::execute_code_action_kind_locally(
 5169                    lsp_store.clone(),
 5170                    buffers,
 5171                    kind,
 5172                    push_to_history,
 5173                    cx,
 5174                )
 5175                .await;
 5176                lsp_store.update(cx, |lsp_store, _| {
 5177                    lsp_store.update_last_formatting_failure(&result);
 5178                })?;
 5179                result
 5180            })
 5181        } else if let Some((client, project_id)) = self.upstream_client() {
 5182            let buffer_store = self.buffer_store();
 5183            cx.spawn(async move |lsp_store, cx| {
 5184                let result = client
 5185                    .request(proto::ApplyCodeActionKind {
 5186                        project_id,
 5187                        kind: kind.as_str().to_owned(),
 5188                        buffer_ids: buffers
 5189                            .iter()
 5190                            .map(|buffer| {
 5191                                buffer.read_with(cx, |buffer, _| buffer.remote_id().into())
 5192                            })
 5193                            .collect(),
 5194                    })
 5195                    .await
 5196                    .and_then(|result| result.transaction.context("missing transaction"));
 5197                lsp_store.update(cx, |lsp_store, _| {
 5198                    lsp_store.update_last_formatting_failure(&result);
 5199                })?;
 5200
 5201                let transaction_response = result?;
 5202                buffer_store
 5203                    .update(cx, |buffer_store, cx| {
 5204                        buffer_store.deserialize_project_transaction(
 5205                            transaction_response,
 5206                            push_to_history,
 5207                            cx,
 5208                        )
 5209                    })
 5210                    .await
 5211            })
 5212        } else {
 5213            Task::ready(Ok(ProjectTransaction::default()))
 5214        }
 5215    }
 5216
 5217    pub fn resolved_hint(
 5218        &mut self,
 5219        buffer_id: BufferId,
 5220        id: InlayId,
 5221        cx: &mut Context<Self>,
 5222    ) -> Option<ResolvedHint> {
 5223        let buffer = self.buffer_store.read(cx).get(buffer_id)?;
 5224
 5225        let lsp_data = self.lsp_data.get_mut(&buffer_id)?;
 5226        let buffer_lsp_hints = &mut lsp_data.inlay_hints;
 5227        let hint = buffer_lsp_hints.hint_for_id(id)?.clone();
 5228        let (server_id, resolve_data) = match &hint.resolve_state {
 5229            ResolveState::Resolved => return Some(ResolvedHint::Resolved(hint)),
 5230            ResolveState::Resolving => {
 5231                return Some(ResolvedHint::Resolving(
 5232                    buffer_lsp_hints.hint_resolves.get(&id)?.clone(),
 5233                ));
 5234            }
 5235            ResolveState::CanResolve(server_id, resolve_data) => (*server_id, resolve_data.clone()),
 5236        };
 5237
 5238        let resolve_task = self.resolve_inlay_hint(hint, buffer, server_id, cx);
 5239        let buffer_lsp_hints = &mut self.lsp_data.get_mut(&buffer_id)?.inlay_hints;
 5240        let previous_task = buffer_lsp_hints.hint_resolves.insert(
 5241            id,
 5242            cx.spawn(async move |lsp_store, cx| {
 5243                let resolved_hint = resolve_task.await;
 5244                lsp_store
 5245                    .update(cx, |lsp_store, _| {
 5246                        if let Some(old_inlay_hint) = lsp_store
 5247                            .lsp_data
 5248                            .get_mut(&buffer_id)
 5249                            .and_then(|buffer_lsp_data| buffer_lsp_data.inlay_hints.hint_for_id(id))
 5250                        {
 5251                            match resolved_hint {
 5252                                Ok(resolved_hint) => {
 5253                                    *old_inlay_hint = resolved_hint;
 5254                                }
 5255                                Err(e) => {
 5256                                    old_inlay_hint.resolve_state =
 5257                                        ResolveState::CanResolve(server_id, resolve_data);
 5258                                    log::error!("Inlay hint resolve failed: {e:#}");
 5259                                }
 5260                            }
 5261                        }
 5262                    })
 5263                    .ok();
 5264            })
 5265            .shared(),
 5266        );
 5267        debug_assert!(
 5268            previous_task.is_none(),
 5269            "Did not change hint's resolve state after spawning its resolve"
 5270        );
 5271        buffer_lsp_hints.hint_for_id(id)?.resolve_state = ResolveState::Resolving;
 5272        None
 5273    }
 5274
 5275    fn resolve_inlay_hint(
 5276        &self,
 5277        mut hint: InlayHint,
 5278        buffer: Entity<Buffer>,
 5279        server_id: LanguageServerId,
 5280        cx: &mut Context<Self>,
 5281    ) -> Task<anyhow::Result<InlayHint>> {
 5282        if let Some((upstream_client, project_id)) = self.upstream_client() {
 5283            if !self.check_if_capable_for_proto_request(&buffer, InlayHints::can_resolve_inlays, cx)
 5284            {
 5285                hint.resolve_state = ResolveState::Resolved;
 5286                return Task::ready(Ok(hint));
 5287            }
 5288            let request = proto::ResolveInlayHint {
 5289                project_id,
 5290                buffer_id: buffer.read(cx).remote_id().into(),
 5291                language_server_id: server_id.0 as u64,
 5292                hint: Some(InlayHints::project_to_proto_hint(hint.clone())),
 5293            };
 5294            cx.background_spawn(async move {
 5295                let response = upstream_client
 5296                    .request(request)
 5297                    .await
 5298                    .context("inlay hints proto request")?;
 5299                match response.hint {
 5300                    Some(resolved_hint) => InlayHints::proto_to_project_hint(resolved_hint)
 5301                        .context("inlay hints proto resolve response conversion"),
 5302                    None => Ok(hint),
 5303                }
 5304            })
 5305        } else {
 5306            let Some(lang_server) = buffer.update(cx, |buffer, cx| {
 5307                self.language_server_for_local_buffer(buffer, server_id, cx)
 5308                    .map(|(_, server)| server.clone())
 5309            }) else {
 5310                return Task::ready(Ok(hint));
 5311            };
 5312            if !InlayHints::can_resolve_inlays(&lang_server.capabilities()) {
 5313                return Task::ready(Ok(hint));
 5314            }
 5315            let buffer_snapshot = buffer.read(cx).snapshot();
 5316            cx.spawn(async move |_, cx| {
 5317                let resolve_task = lang_server.request::<lsp::request::InlayHintResolveRequest>(
 5318                    InlayHints::project_to_lsp_hint(hint, &buffer_snapshot),
 5319                );
 5320                let resolved_hint = resolve_task
 5321                    .await
 5322                    .into_response()
 5323                    .context("inlay hint resolve LSP request")?;
 5324                let resolved_hint = InlayHints::lsp_to_project_hint(
 5325                    resolved_hint,
 5326                    &buffer,
 5327                    server_id,
 5328                    ResolveState::Resolved,
 5329                    false,
 5330                    cx,
 5331                )
 5332                .await?;
 5333                Ok(resolved_hint)
 5334            })
 5335        }
 5336    }
 5337
 5338    pub fn resolve_color_presentation(
 5339        &mut self,
 5340        mut color: DocumentColor,
 5341        buffer: Entity<Buffer>,
 5342        server_id: LanguageServerId,
 5343        cx: &mut Context<Self>,
 5344    ) -> Task<Result<DocumentColor>> {
 5345        if color.resolved {
 5346            return Task::ready(Ok(color));
 5347        }
 5348
 5349        if let Some((upstream_client, project_id)) = self.upstream_client() {
 5350            let start = color.lsp_range.start;
 5351            let end = color.lsp_range.end;
 5352            let request = proto::GetColorPresentation {
 5353                project_id,
 5354                server_id: server_id.to_proto(),
 5355                buffer_id: buffer.read(cx).remote_id().into(),
 5356                color: Some(proto::ColorInformation {
 5357                    red: color.color.red,
 5358                    green: color.color.green,
 5359                    blue: color.color.blue,
 5360                    alpha: color.color.alpha,
 5361                    lsp_range_start: Some(proto::PointUtf16 {
 5362                        row: start.line,
 5363                        column: start.character,
 5364                    }),
 5365                    lsp_range_end: Some(proto::PointUtf16 {
 5366                        row: end.line,
 5367                        column: end.character,
 5368                    }),
 5369                }),
 5370            };
 5371            cx.background_spawn(async move {
 5372                let response = upstream_client
 5373                    .request(request)
 5374                    .await
 5375                    .context("color presentation proto request")?;
 5376                color.resolved = true;
 5377                color.color_presentations = response
 5378                    .presentations
 5379                    .into_iter()
 5380                    .map(|presentation| ColorPresentation {
 5381                        label: SharedString::from(presentation.label),
 5382                        text_edit: presentation.text_edit.and_then(deserialize_lsp_edit),
 5383                        additional_text_edits: presentation
 5384                            .additional_text_edits
 5385                            .into_iter()
 5386                            .filter_map(deserialize_lsp_edit)
 5387                            .collect(),
 5388                    })
 5389                    .collect();
 5390                Ok(color)
 5391            })
 5392        } else {
 5393            let path = match buffer
 5394                .update(cx, |buffer, cx| {
 5395                    Some(File::from_dyn(buffer.file())?.abs_path(cx))
 5396                })
 5397                .context("buffer with the missing path")
 5398            {
 5399                Ok(path) => path,
 5400                Err(e) => return Task::ready(Err(e)),
 5401            };
 5402            let Some(lang_server) = buffer.update(cx, |buffer, cx| {
 5403                self.language_server_for_local_buffer(buffer, server_id, cx)
 5404                    .map(|(_, server)| server.clone())
 5405            }) else {
 5406                return Task::ready(Ok(color));
 5407            };
 5408            cx.background_spawn(async move {
 5409                let resolve_task = lang_server.request::<lsp::request::ColorPresentationRequest>(
 5410                    lsp::ColorPresentationParams {
 5411                        text_document: make_text_document_identifier(&path)?,
 5412                        color: color.color,
 5413                        range: color.lsp_range,
 5414                        work_done_progress_params: Default::default(),
 5415                        partial_result_params: Default::default(),
 5416                    },
 5417                );
 5418                color.color_presentations = resolve_task
 5419                    .await
 5420                    .into_response()
 5421                    .context("color presentation resolve LSP request")?
 5422                    .into_iter()
 5423                    .map(|presentation| ColorPresentation {
 5424                        label: SharedString::from(presentation.label),
 5425                        text_edit: presentation.text_edit,
 5426                        additional_text_edits: presentation
 5427                            .additional_text_edits
 5428                            .unwrap_or_default(),
 5429                    })
 5430                    .collect();
 5431                color.resolved = true;
 5432                Ok(color)
 5433            })
 5434        }
 5435    }
 5436
 5437    pub(crate) fn linked_edits(
 5438        &mut self,
 5439        buffer: &Entity<Buffer>,
 5440        position: Anchor,
 5441        cx: &mut Context<Self>,
 5442    ) -> Task<Result<Vec<Range<Anchor>>>> {
 5443        let snapshot = buffer.read(cx).snapshot();
 5444        let scope = snapshot.language_scope_at(position);
 5445        let Some(server_id) = self
 5446            .as_local()
 5447            .and_then(|local| {
 5448                buffer.update(cx, |buffer, cx| {
 5449                    local
 5450                        .language_servers_for_buffer(buffer, cx)
 5451                        .filter(|(_, server)| {
 5452                            LinkedEditingRange::check_server_capabilities(server.capabilities())
 5453                        })
 5454                        .filter(|(adapter, _)| {
 5455                            scope
 5456                                .as_ref()
 5457                                .map(|scope| scope.language_allowed(&adapter.name))
 5458                                .unwrap_or(true)
 5459                        })
 5460                        .map(|(_, server)| LanguageServerToQuery::Other(server.server_id()))
 5461                        .next()
 5462                })
 5463            })
 5464            .or_else(|| {
 5465                self.upstream_client()
 5466                    .is_some()
 5467                    .then_some(LanguageServerToQuery::FirstCapable)
 5468            })
 5469            .filter(|_| {
 5470                maybe!({
 5471                    let language = buffer.read(cx).language_at(position)?;
 5472                    Some(
 5473                        language_settings(Some(language.name()), buffer.read(cx).file(), cx)
 5474                            .linked_edits,
 5475                    )
 5476                }) == Some(true)
 5477            })
 5478        else {
 5479            return Task::ready(Ok(Vec::new()));
 5480        };
 5481
 5482        self.request_lsp(
 5483            buffer.clone(),
 5484            server_id,
 5485            LinkedEditingRange { position },
 5486            cx,
 5487        )
 5488    }
 5489
 5490    fn apply_on_type_formatting(
 5491        &mut self,
 5492        buffer: Entity<Buffer>,
 5493        position: Anchor,
 5494        trigger: String,
 5495        cx: &mut Context<Self>,
 5496    ) -> Task<Result<Option<Transaction>>> {
 5497        if let Some((client, project_id)) = self.upstream_client() {
 5498            if !self.check_if_capable_for_proto_request(
 5499                &buffer,
 5500                |capabilities| {
 5501                    OnTypeFormatting::supports_on_type_formatting(&trigger, capabilities)
 5502                },
 5503                cx,
 5504            ) {
 5505                return Task::ready(Ok(None));
 5506            }
 5507            let request = proto::OnTypeFormatting {
 5508                project_id,
 5509                buffer_id: buffer.read(cx).remote_id().into(),
 5510                position: Some(serialize_anchor(&position)),
 5511                trigger,
 5512                version: serialize_version(&buffer.read(cx).version()),
 5513            };
 5514            cx.background_spawn(async move {
 5515                client
 5516                    .request(request)
 5517                    .await?
 5518                    .transaction
 5519                    .map(language::proto::deserialize_transaction)
 5520                    .transpose()
 5521            })
 5522        } else if let Some(local) = self.as_local_mut() {
 5523            let buffer_id = buffer.read(cx).remote_id();
 5524            local.buffers_being_formatted.insert(buffer_id);
 5525            cx.spawn(async move |this, cx| {
 5526                let _cleanup = defer({
 5527                    let this = this.clone();
 5528                    let mut cx = cx.clone();
 5529                    move || {
 5530                        this.update(&mut cx, |this, _| {
 5531                            if let Some(local) = this.as_local_mut() {
 5532                                local.buffers_being_formatted.remove(&buffer_id);
 5533                            }
 5534                        })
 5535                        .ok();
 5536                    }
 5537                });
 5538
 5539                buffer
 5540                    .update(cx, |buffer, _| {
 5541                        buffer.wait_for_edits(Some(position.timestamp))
 5542                    })
 5543                    .await?;
 5544                this.update(cx, |this, cx| {
 5545                    let position = position.to_point_utf16(buffer.read(cx));
 5546                    this.on_type_format(buffer, position, trigger, false, cx)
 5547                })?
 5548                .await
 5549            })
 5550        } else {
 5551            Task::ready(Err(anyhow!("No upstream client or local language server")))
 5552        }
 5553    }
 5554
 5555    pub fn on_type_format<T: ToPointUtf16>(
 5556        &mut self,
 5557        buffer: Entity<Buffer>,
 5558        position: T,
 5559        trigger: String,
 5560        push_to_history: bool,
 5561        cx: &mut Context<Self>,
 5562    ) -> Task<Result<Option<Transaction>>> {
 5563        let position = position.to_point_utf16(buffer.read(cx));
 5564        self.on_type_format_impl(buffer, position, trigger, push_to_history, cx)
 5565    }
 5566
 5567    fn on_type_format_impl(
 5568        &mut self,
 5569        buffer: Entity<Buffer>,
 5570        position: PointUtf16,
 5571        trigger: String,
 5572        push_to_history: bool,
 5573        cx: &mut Context<Self>,
 5574    ) -> Task<Result<Option<Transaction>>> {
 5575        let options = buffer.update(cx, |buffer, cx| {
 5576            lsp_command::lsp_formatting_options(
 5577                language_settings(
 5578                    buffer.language_at(position).map(|l| l.name()),
 5579                    buffer.file(),
 5580                    cx,
 5581                )
 5582                .as_ref(),
 5583            )
 5584        });
 5585
 5586        cx.spawn(async move |this, cx| {
 5587            if let Some(waiter) =
 5588                buffer.update(cx, |buffer, _| buffer.wait_for_autoindent_applied())
 5589            {
 5590                waiter.await?;
 5591            }
 5592            cx.update(|cx| {
 5593                this.update(cx, |this, cx| {
 5594                    this.request_lsp(
 5595                        buffer.clone(),
 5596                        LanguageServerToQuery::FirstCapable,
 5597                        OnTypeFormatting {
 5598                            position,
 5599                            trigger,
 5600                            options,
 5601                            push_to_history,
 5602                        },
 5603                        cx,
 5604                    )
 5605                })
 5606            })?
 5607            .await
 5608        })
 5609    }
 5610
 5611    pub fn definitions(
 5612        &mut self,
 5613        buffer: &Entity<Buffer>,
 5614        position: PointUtf16,
 5615        cx: &mut Context<Self>,
 5616    ) -> Task<Result<Option<Vec<LocationLink>>>> {
 5617        if let Some((upstream_client, project_id)) = self.upstream_client() {
 5618            let request = GetDefinitions { position };
 5619            if !self.is_capable_for_proto_request(buffer, &request, cx) {
 5620                return Task::ready(Ok(None));
 5621            }
 5622            let request_task = upstream_client.request_lsp(
 5623                project_id,
 5624                None,
 5625                LSP_REQUEST_TIMEOUT,
 5626                cx.background_executor().clone(),
 5627                request.to_proto(project_id, buffer.read(cx)),
 5628            );
 5629            let buffer = buffer.clone();
 5630            cx.spawn(async move |weak_lsp_store, cx| {
 5631                let Some(lsp_store) = weak_lsp_store.upgrade() else {
 5632                    return Ok(None);
 5633                };
 5634                let Some(responses) = request_task.await? else {
 5635                    return Ok(None);
 5636                };
 5637                let actions = join_all(responses.payload.into_iter().map(|response| {
 5638                    GetDefinitions { position }.response_from_proto(
 5639                        response.response,
 5640                        lsp_store.clone(),
 5641                        buffer.clone(),
 5642                        cx.clone(),
 5643                    )
 5644                }))
 5645                .await;
 5646
 5647                Ok(Some(
 5648                    actions
 5649                        .into_iter()
 5650                        .collect::<Result<Vec<Vec<_>>>>()?
 5651                        .into_iter()
 5652                        .flatten()
 5653                        .dedup()
 5654                        .collect(),
 5655                ))
 5656            })
 5657        } else {
 5658            let definitions_task = self.request_multiple_lsp_locally(
 5659                buffer,
 5660                Some(position),
 5661                GetDefinitions { position },
 5662                cx,
 5663            );
 5664            cx.background_spawn(async move {
 5665                Ok(Some(
 5666                    definitions_task
 5667                        .await
 5668                        .into_iter()
 5669                        .flat_map(|(_, definitions)| definitions)
 5670                        .dedup()
 5671                        .collect(),
 5672                ))
 5673            })
 5674        }
 5675    }
 5676
 5677    pub fn declarations(
 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 = GetDeclarations { 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                    GetDeclarations { 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 declarations_task = self.request_multiple_lsp_locally(
 5725                buffer,
 5726                Some(position),
 5727                GetDeclarations { position },
 5728                cx,
 5729            );
 5730            cx.background_spawn(async move {
 5731                Ok(Some(
 5732                    declarations_task
 5733                        .await
 5734                        .into_iter()
 5735                        .flat_map(|(_, declarations)| declarations)
 5736                        .dedup()
 5737                        .collect(),
 5738                ))
 5739            })
 5740        }
 5741    }
 5742
 5743    pub fn type_definitions(
 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 = GetTypeDefinitions { 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                    GetTypeDefinitions { 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 type_definitions_task = self.request_multiple_lsp_locally(
 5791                buffer,
 5792                Some(position),
 5793                GetTypeDefinitions { position },
 5794                cx,
 5795            );
 5796            cx.background_spawn(async move {
 5797                Ok(Some(
 5798                    type_definitions_task
 5799                        .await
 5800                        .into_iter()
 5801                        .flat_map(|(_, type_definitions)| type_definitions)
 5802                        .dedup()
 5803                        .collect(),
 5804                ))
 5805            })
 5806        }
 5807    }
 5808
 5809    pub fn implementations(
 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 = GetImplementations { 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                    GetImplementations { 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 implementations_task = self.request_multiple_lsp_locally(
 5857                buffer,
 5858                Some(position),
 5859                GetImplementations { position },
 5860                cx,
 5861            );
 5862            cx.background_spawn(async move {
 5863                Ok(Some(
 5864                    implementations_task
 5865                        .await
 5866                        .into_iter()
 5867                        .flat_map(|(_, implementations)| implementations)
 5868                        .dedup()
 5869                        .collect(),
 5870                ))
 5871            })
 5872        }
 5873    }
 5874
 5875    pub fn references(
 5876        &mut self,
 5877        buffer: &Entity<Buffer>,
 5878        position: PointUtf16,
 5879        cx: &mut Context<Self>,
 5880    ) -> Task<Result<Option<Vec<Location>>>> {
 5881        if let Some((upstream_client, project_id)) = self.upstream_client() {
 5882            let request = GetReferences { position };
 5883            if !self.is_capable_for_proto_request(buffer, &request, cx) {
 5884                return Task::ready(Ok(None));
 5885            }
 5886
 5887            let request_task = upstream_client.request_lsp(
 5888                project_id,
 5889                None,
 5890                LSP_REQUEST_TIMEOUT,
 5891                cx.background_executor().clone(),
 5892                request.to_proto(project_id, buffer.read(cx)),
 5893            );
 5894            let buffer = buffer.clone();
 5895            cx.spawn(async move |weak_lsp_store, cx| {
 5896                let Some(lsp_store) = weak_lsp_store.upgrade() else {
 5897                    return Ok(None);
 5898                };
 5899                let Some(responses) = request_task.await? else {
 5900                    return Ok(None);
 5901                };
 5902
 5903                let locations = join_all(responses.payload.into_iter().map(|lsp_response| {
 5904                    GetReferences { position }.response_from_proto(
 5905                        lsp_response.response,
 5906                        lsp_store.clone(),
 5907                        buffer.clone(),
 5908                        cx.clone(),
 5909                    )
 5910                }))
 5911                .await
 5912                .into_iter()
 5913                .collect::<Result<Vec<Vec<_>>>>()?
 5914                .into_iter()
 5915                .flatten()
 5916                .dedup()
 5917                .collect();
 5918                Ok(Some(locations))
 5919            })
 5920        } else {
 5921            let references_task = self.request_multiple_lsp_locally(
 5922                buffer,
 5923                Some(position),
 5924                GetReferences { position },
 5925                cx,
 5926            );
 5927            cx.background_spawn(async move {
 5928                Ok(Some(
 5929                    references_task
 5930                        .await
 5931                        .into_iter()
 5932                        .flat_map(|(_, references)| references)
 5933                        .dedup()
 5934                        .collect(),
 5935                ))
 5936            })
 5937        }
 5938    }
 5939
 5940    pub fn code_actions(
 5941        &mut self,
 5942        buffer: &Entity<Buffer>,
 5943        range: Range<Anchor>,
 5944        kinds: Option<Vec<CodeActionKind>>,
 5945        cx: &mut Context<Self>,
 5946    ) -> Task<Result<Option<Vec<CodeAction>>>> {
 5947        if let Some((upstream_client, project_id)) = self.upstream_client() {
 5948            let request = GetCodeActions {
 5949                range: range.clone(),
 5950                kinds: kinds.clone(),
 5951            };
 5952            if !self.is_capable_for_proto_request(buffer, &request, cx) {
 5953                return Task::ready(Ok(None));
 5954            }
 5955            let request_task = upstream_client.request_lsp(
 5956                project_id,
 5957                None,
 5958                LSP_REQUEST_TIMEOUT,
 5959                cx.background_executor().clone(),
 5960                request.to_proto(project_id, buffer.read(cx)),
 5961            );
 5962            let buffer = buffer.clone();
 5963            cx.spawn(async move |weak_lsp_store, cx| {
 5964                let Some(lsp_store) = weak_lsp_store.upgrade() else {
 5965                    return Ok(None);
 5966                };
 5967                let Some(responses) = request_task.await? else {
 5968                    return Ok(None);
 5969                };
 5970                let actions = join_all(responses.payload.into_iter().map(|response| {
 5971                    GetCodeActions {
 5972                        range: range.clone(),
 5973                        kinds: kinds.clone(),
 5974                    }
 5975                    .response_from_proto(
 5976                        response.response,
 5977                        lsp_store.clone(),
 5978                        buffer.clone(),
 5979                        cx.clone(),
 5980                    )
 5981                }))
 5982                .await;
 5983
 5984                Ok(Some(
 5985                    actions
 5986                        .into_iter()
 5987                        .collect::<Result<Vec<Vec<_>>>>()?
 5988                        .into_iter()
 5989                        .flatten()
 5990                        .collect(),
 5991                ))
 5992            })
 5993        } else {
 5994            let all_actions_task = self.request_multiple_lsp_locally(
 5995                buffer,
 5996                Some(range.start),
 5997                GetCodeActions { range, kinds },
 5998                cx,
 5999            );
 6000            cx.background_spawn(async move {
 6001                Ok(Some(
 6002                    all_actions_task
 6003                        .await
 6004                        .into_iter()
 6005                        .flat_map(|(_, actions)| actions)
 6006                        .collect(),
 6007                ))
 6008            })
 6009        }
 6010    }
 6011
 6012    pub fn code_lens_actions(
 6013        &mut self,
 6014        buffer: &Entity<Buffer>,
 6015        cx: &mut Context<Self>,
 6016    ) -> CodeLensTask {
 6017        let version_queried_for = buffer.read(cx).version();
 6018        let buffer_id = buffer.read(cx).remote_id();
 6019        let existing_servers = self.as_local().map(|local| {
 6020            local
 6021                .buffers_opened_in_servers
 6022                .get(&buffer_id)
 6023                .cloned()
 6024                .unwrap_or_default()
 6025        });
 6026
 6027        if let Some(lsp_data) = self.current_lsp_data(buffer_id) {
 6028            if let Some(cached_lens) = &lsp_data.code_lens {
 6029                if !version_queried_for.changed_since(&lsp_data.buffer_version) {
 6030                    let has_different_servers = existing_servers.is_some_and(|existing_servers| {
 6031                        existing_servers != cached_lens.lens.keys().copied().collect()
 6032                    });
 6033                    if !has_different_servers {
 6034                        return Task::ready(Ok(Some(
 6035                            cached_lens.lens.values().flatten().cloned().collect(),
 6036                        )))
 6037                        .shared();
 6038                    }
 6039                } else if let Some((updating_for, running_update)) = cached_lens.update.as_ref() {
 6040                    if !version_queried_for.changed_since(updating_for) {
 6041                        return running_update.clone();
 6042                    }
 6043                }
 6044            }
 6045        }
 6046
 6047        let lens_lsp_data = self
 6048            .latest_lsp_data(buffer, cx)
 6049            .code_lens
 6050            .get_or_insert_default();
 6051        let buffer = buffer.clone();
 6052        let query_version_queried_for = version_queried_for.clone();
 6053        let new_task = cx
 6054            .spawn(async move |lsp_store, cx| {
 6055                cx.background_executor()
 6056                    .timer(Duration::from_millis(30))
 6057                    .await;
 6058                let fetched_lens = lsp_store
 6059                    .update(cx, |lsp_store, cx| lsp_store.fetch_code_lens(&buffer, cx))
 6060                    .map_err(Arc::new)?
 6061                    .await
 6062                    .context("fetching code lens")
 6063                    .map_err(Arc::new);
 6064                let fetched_lens = match fetched_lens {
 6065                    Ok(fetched_lens) => fetched_lens,
 6066                    Err(e) => {
 6067                        lsp_store
 6068                            .update(cx, |lsp_store, _| {
 6069                                if let Some(lens_lsp_data) = lsp_store
 6070                                    .lsp_data
 6071                                    .get_mut(&buffer_id)
 6072                                    .and_then(|lsp_data| lsp_data.code_lens.as_mut())
 6073                                {
 6074                                    lens_lsp_data.update = None;
 6075                                }
 6076                            })
 6077                            .ok();
 6078                        return Err(e);
 6079                    }
 6080                };
 6081
 6082                lsp_store
 6083                    .update(cx, |lsp_store, _| {
 6084                        let lsp_data = lsp_store.current_lsp_data(buffer_id)?;
 6085                        let code_lens = lsp_data.code_lens.as_mut()?;
 6086                        if let Some(fetched_lens) = fetched_lens {
 6087                            if lsp_data.buffer_version == query_version_queried_for {
 6088                                code_lens.lens.extend(fetched_lens);
 6089                            } else if !lsp_data
 6090                                .buffer_version
 6091                                .changed_since(&query_version_queried_for)
 6092                            {
 6093                                lsp_data.buffer_version = query_version_queried_for;
 6094                                code_lens.lens = fetched_lens;
 6095                            }
 6096                        }
 6097                        code_lens.update = None;
 6098                        Some(code_lens.lens.values().flatten().cloned().collect())
 6099                    })
 6100                    .map_err(Arc::new)
 6101            })
 6102            .shared();
 6103        lens_lsp_data.update = Some((version_queried_for, new_task.clone()));
 6104        new_task
 6105    }
 6106
 6107    fn fetch_code_lens(
 6108        &mut self,
 6109        buffer: &Entity<Buffer>,
 6110        cx: &mut Context<Self>,
 6111    ) -> Task<Result<Option<HashMap<LanguageServerId, Vec<CodeAction>>>>> {
 6112        if let Some((upstream_client, project_id)) = self.upstream_client() {
 6113            let request = GetCodeLens;
 6114            if !self.is_capable_for_proto_request(buffer, &request, cx) {
 6115                return Task::ready(Ok(None));
 6116            }
 6117            let request_task = upstream_client.request_lsp(
 6118                project_id,
 6119                None,
 6120                LSP_REQUEST_TIMEOUT,
 6121                cx.background_executor().clone(),
 6122                request.to_proto(project_id, buffer.read(cx)),
 6123            );
 6124            let buffer = buffer.clone();
 6125            cx.spawn(async move |weak_lsp_store, cx| {
 6126                let Some(lsp_store) = weak_lsp_store.upgrade() else {
 6127                    return Ok(None);
 6128                };
 6129                let Some(responses) = request_task.await? else {
 6130                    return Ok(None);
 6131                };
 6132
 6133                let code_lens_actions = join_all(responses.payload.into_iter().map(|response| {
 6134                    let lsp_store = lsp_store.clone();
 6135                    let buffer = buffer.clone();
 6136                    let cx = cx.clone();
 6137                    async move {
 6138                        (
 6139                            LanguageServerId::from_proto(response.server_id),
 6140                            GetCodeLens
 6141                                .response_from_proto(response.response, lsp_store, buffer, cx)
 6142                                .await,
 6143                        )
 6144                    }
 6145                }))
 6146                .await;
 6147
 6148                let mut has_errors = false;
 6149                let code_lens_actions = code_lens_actions
 6150                    .into_iter()
 6151                    .filter_map(|(server_id, code_lens)| match code_lens {
 6152                        Ok(code_lens) => Some((server_id, code_lens)),
 6153                        Err(e) => {
 6154                            has_errors = true;
 6155                            log::error!("{e:#}");
 6156                            None
 6157                        }
 6158                    })
 6159                    .collect::<HashMap<_, _>>();
 6160                anyhow::ensure!(
 6161                    !has_errors || !code_lens_actions.is_empty(),
 6162                    "Failed to fetch code lens"
 6163                );
 6164                Ok(Some(code_lens_actions))
 6165            })
 6166        } else {
 6167            let code_lens_actions_task =
 6168                self.request_multiple_lsp_locally(buffer, None::<usize>, GetCodeLens, cx);
 6169            cx.background_spawn(async move {
 6170                Ok(Some(code_lens_actions_task.await.into_iter().collect()))
 6171            })
 6172        }
 6173    }
 6174
 6175    #[inline(never)]
 6176    pub fn completions(
 6177        &self,
 6178        buffer: &Entity<Buffer>,
 6179        position: PointUtf16,
 6180        context: CompletionContext,
 6181        cx: &mut Context<Self>,
 6182    ) -> Task<Result<Vec<CompletionResponse>>> {
 6183        let language_registry = self.languages.clone();
 6184
 6185        if let Some((upstream_client, project_id)) = self.upstream_client() {
 6186            let snapshot = buffer.read(cx).snapshot();
 6187            let offset = position.to_offset(&snapshot);
 6188            let scope = snapshot.language_scope_at(offset);
 6189            let capable_lsps = self.all_capable_for_proto_request(
 6190                buffer,
 6191                |server_name, capabilities| {
 6192                    capabilities.completion_provider.is_some()
 6193                        && scope
 6194                            .as_ref()
 6195                            .map(|scope| scope.language_allowed(server_name))
 6196                            .unwrap_or(true)
 6197                },
 6198                cx,
 6199            );
 6200            if capable_lsps.is_empty() {
 6201                return Task::ready(Ok(Vec::new()));
 6202            }
 6203
 6204            let language = buffer.read(cx).language().cloned();
 6205
 6206            // In the future, we should provide project guests with the names of LSP adapters,
 6207            // so that they can use the correct LSP adapter when computing labels. For now,
 6208            // guests just use the first LSP adapter associated with the buffer's language.
 6209            let lsp_adapter = language.as_ref().and_then(|language| {
 6210                language_registry
 6211                    .lsp_adapters(&language.name())
 6212                    .first()
 6213                    .cloned()
 6214            });
 6215
 6216            let buffer = buffer.clone();
 6217
 6218            cx.spawn(async move |this, cx| {
 6219                let requests = join_all(
 6220                    capable_lsps
 6221                        .into_iter()
 6222                        .map(|id| {
 6223                            let request = GetCompletions {
 6224                                position,
 6225                                context: context.clone(),
 6226                                server_id: Some(id),
 6227                            };
 6228                            let buffer = buffer.clone();
 6229                            let language = language.clone();
 6230                            let lsp_adapter = lsp_adapter.clone();
 6231                            let upstream_client = upstream_client.clone();
 6232                            let response = this
 6233                                .update(cx, |this, cx| {
 6234                                    this.send_lsp_proto_request(
 6235                                        buffer,
 6236                                        upstream_client,
 6237                                        project_id,
 6238                                        request,
 6239                                        cx,
 6240                                    )
 6241                                })
 6242                                .log_err();
 6243                            async move {
 6244                                let response = response?.await.log_err()?;
 6245
 6246                                let completions = populate_labels_for_completions(
 6247                                    response.completions,
 6248                                    language,
 6249                                    lsp_adapter,
 6250                                )
 6251                                .await;
 6252
 6253                                Some(CompletionResponse {
 6254                                    completions,
 6255                                    display_options: CompletionDisplayOptions::default(),
 6256                                    is_incomplete: response.is_incomplete,
 6257                                })
 6258                            }
 6259                        })
 6260                        .collect::<Vec<_>>(),
 6261                );
 6262                Ok(requests.await.into_iter().flatten().collect::<Vec<_>>())
 6263            })
 6264        } else if let Some(local) = self.as_local() {
 6265            let snapshot = buffer.read(cx).snapshot();
 6266            let offset = position.to_offset(&snapshot);
 6267            let scope = snapshot.language_scope_at(offset);
 6268            let language = snapshot.language().cloned();
 6269            let completion_settings = language_settings(
 6270                language.as_ref().map(|language| language.name()),
 6271                buffer.read(cx).file(),
 6272                cx,
 6273            )
 6274            .completions
 6275            .clone();
 6276            if !completion_settings.lsp {
 6277                return Task::ready(Ok(Vec::new()));
 6278            }
 6279
 6280            let server_ids: Vec<_> = buffer.update(cx, |buffer, cx| {
 6281                local
 6282                    .language_servers_for_buffer(buffer, cx)
 6283                    .filter(|(_, server)| server.capabilities().completion_provider.is_some())
 6284                    .filter(|(adapter, _)| {
 6285                        scope
 6286                            .as_ref()
 6287                            .map(|scope| scope.language_allowed(&adapter.name))
 6288                            .unwrap_or(true)
 6289                    })
 6290                    .map(|(_, server)| server.server_id())
 6291                    .collect()
 6292            });
 6293
 6294            let buffer = buffer.clone();
 6295            let lsp_timeout = completion_settings.lsp_fetch_timeout_ms;
 6296            let lsp_timeout = if lsp_timeout > 0 {
 6297                Some(Duration::from_millis(lsp_timeout))
 6298            } else {
 6299                None
 6300            };
 6301            cx.spawn(async move |this,  cx| {
 6302                let mut tasks = Vec::with_capacity(server_ids.len());
 6303                this.update(cx, |lsp_store, cx| {
 6304                    for server_id in server_ids {
 6305                        let lsp_adapter = lsp_store.language_server_adapter_for_id(server_id);
 6306                        let lsp_timeout = lsp_timeout
 6307                            .map(|lsp_timeout| cx.background_executor().timer(lsp_timeout));
 6308                        let mut timeout = cx.background_spawn(async move {
 6309                            match lsp_timeout {
 6310                                Some(lsp_timeout) => {
 6311                                    lsp_timeout.await;
 6312                                    true
 6313                                },
 6314                                None => false,
 6315                            }
 6316                        }).fuse();
 6317                        let mut lsp_request = lsp_store.request_lsp(
 6318                            buffer.clone(),
 6319                            LanguageServerToQuery::Other(server_id),
 6320                            GetCompletions {
 6321                                position,
 6322                                context: context.clone(),
 6323                                server_id: Some(server_id),
 6324                            },
 6325                            cx,
 6326                        ).fuse();
 6327                        let new_task = cx.background_spawn(async move {
 6328                            select_biased! {
 6329                                response = lsp_request => anyhow::Ok(Some(response?)),
 6330                                timeout_happened = timeout => {
 6331                                    if timeout_happened {
 6332                                        log::warn!("Fetching completions from server {server_id} timed out, timeout ms: {}", completion_settings.lsp_fetch_timeout_ms);
 6333                                        Ok(None)
 6334                                    } else {
 6335                                        let completions = lsp_request.await?;
 6336                                        Ok(Some(completions))
 6337                                    }
 6338                                },
 6339                            }
 6340                        });
 6341                        tasks.push((lsp_adapter, new_task));
 6342                    }
 6343                })?;
 6344
 6345                let futures = tasks.into_iter().map(async |(lsp_adapter, task)| {
 6346                    let completion_response = task.await.ok()??;
 6347                    let completions = populate_labels_for_completions(
 6348                            completion_response.completions,
 6349                            language.clone(),
 6350                            lsp_adapter,
 6351                        )
 6352                        .await;
 6353                    Some(CompletionResponse {
 6354                        completions,
 6355                        display_options: CompletionDisplayOptions::default(),
 6356                        is_incomplete: completion_response.is_incomplete,
 6357                    })
 6358                });
 6359
 6360                let responses: Vec<Option<CompletionResponse>> = join_all(futures).await;
 6361
 6362                Ok(responses.into_iter().flatten().collect())
 6363            })
 6364        } else {
 6365            Task::ready(Err(anyhow!("No upstream client or local language server")))
 6366        }
 6367    }
 6368
 6369    pub fn resolve_completions(
 6370        &self,
 6371        buffer: Entity<Buffer>,
 6372        completion_indices: Vec<usize>,
 6373        completions: Rc<RefCell<Box<[Completion]>>>,
 6374        cx: &mut Context<Self>,
 6375    ) -> Task<Result<bool>> {
 6376        let client = self.upstream_client();
 6377        let buffer_id = buffer.read(cx).remote_id();
 6378        let buffer_snapshot = buffer.read(cx).snapshot();
 6379
 6380        if !self.check_if_capable_for_proto_request(
 6381            &buffer,
 6382            GetCompletions::can_resolve_completions,
 6383            cx,
 6384        ) {
 6385            return Task::ready(Ok(false));
 6386        }
 6387        cx.spawn(async move |lsp_store, cx| {
 6388            let mut did_resolve = false;
 6389            if let Some((client, project_id)) = client {
 6390                for completion_index in completion_indices {
 6391                    let server_id = {
 6392                        let completion = &completions.borrow()[completion_index];
 6393                        completion.source.server_id()
 6394                    };
 6395                    if let Some(server_id) = server_id {
 6396                        if Self::resolve_completion_remote(
 6397                            project_id,
 6398                            server_id,
 6399                            buffer_id,
 6400                            completions.clone(),
 6401                            completion_index,
 6402                            client.clone(),
 6403                        )
 6404                        .await
 6405                        .log_err()
 6406                        .is_some()
 6407                        {
 6408                            did_resolve = true;
 6409                        }
 6410                    } else {
 6411                        resolve_word_completion(
 6412                            &buffer_snapshot,
 6413                            &mut completions.borrow_mut()[completion_index],
 6414                        );
 6415                    }
 6416                }
 6417            } else {
 6418                for completion_index in completion_indices {
 6419                    let server_id = {
 6420                        let completion = &completions.borrow()[completion_index];
 6421                        completion.source.server_id()
 6422                    };
 6423                    if let Some(server_id) = server_id {
 6424                        let server_and_adapter = lsp_store
 6425                            .read_with(cx, |lsp_store, _| {
 6426                                let server = lsp_store.language_server_for_id(server_id)?;
 6427                                let adapter =
 6428                                    lsp_store.language_server_adapter_for_id(server.server_id())?;
 6429                                Some((server, adapter))
 6430                            })
 6431                            .ok()
 6432                            .flatten();
 6433                        let Some((server, adapter)) = server_and_adapter else {
 6434                            continue;
 6435                        };
 6436
 6437                        let resolved = Self::resolve_completion_local(
 6438                            server,
 6439                            completions.clone(),
 6440                            completion_index,
 6441                        )
 6442                        .await
 6443                        .log_err()
 6444                        .is_some();
 6445                        if resolved {
 6446                            Self::regenerate_completion_labels(
 6447                                adapter,
 6448                                &buffer_snapshot,
 6449                                completions.clone(),
 6450                                completion_index,
 6451                            )
 6452                            .await
 6453                            .log_err();
 6454                            did_resolve = true;
 6455                        }
 6456                    } else {
 6457                        resolve_word_completion(
 6458                            &buffer_snapshot,
 6459                            &mut completions.borrow_mut()[completion_index],
 6460                        );
 6461                    }
 6462                }
 6463            }
 6464
 6465            Ok(did_resolve)
 6466        })
 6467    }
 6468
 6469    async fn resolve_completion_local(
 6470        server: Arc<lsp::LanguageServer>,
 6471        completions: Rc<RefCell<Box<[Completion]>>>,
 6472        completion_index: usize,
 6473    ) -> Result<()> {
 6474        let server_id = server.server_id();
 6475        if !GetCompletions::can_resolve_completions(&server.capabilities()) {
 6476            return Ok(());
 6477        }
 6478
 6479        let request = {
 6480            let completion = &completions.borrow()[completion_index];
 6481            match &completion.source {
 6482                CompletionSource::Lsp {
 6483                    lsp_completion,
 6484                    resolved,
 6485                    server_id: completion_server_id,
 6486                    ..
 6487                } => {
 6488                    if *resolved {
 6489                        return Ok(());
 6490                    }
 6491                    anyhow::ensure!(
 6492                        server_id == *completion_server_id,
 6493                        "server_id mismatch, querying completion resolve for {server_id} but completion server id is {completion_server_id}"
 6494                    );
 6495                    server.request::<lsp::request::ResolveCompletionItem>(*lsp_completion.clone())
 6496                }
 6497                CompletionSource::BufferWord { .. }
 6498                | CompletionSource::Dap { .. }
 6499                | CompletionSource::Custom => {
 6500                    return Ok(());
 6501                }
 6502            }
 6503        };
 6504        let resolved_completion = request
 6505            .await
 6506            .into_response()
 6507            .context("resolve completion")?;
 6508
 6509        // We must not use any data such as sortText, filterText, insertText and textEdit to edit `Completion` since they are not suppose change during resolve.
 6510        // Refer: https://microsoft.github.io/language-server-protocol/specifications/lsp/3.17/specification/#textDocument_completion
 6511
 6512        let mut completions = completions.borrow_mut();
 6513        let completion = &mut completions[completion_index];
 6514        if let CompletionSource::Lsp {
 6515            lsp_completion,
 6516            resolved,
 6517            server_id: completion_server_id,
 6518            ..
 6519        } = &mut completion.source
 6520        {
 6521            if *resolved {
 6522                return Ok(());
 6523            }
 6524            anyhow::ensure!(
 6525                server_id == *completion_server_id,
 6526                "server_id mismatch, applying completion resolve for {server_id} but completion server id is {completion_server_id}"
 6527            );
 6528            **lsp_completion = resolved_completion;
 6529            *resolved = true;
 6530        }
 6531        Ok(())
 6532    }
 6533
 6534    async fn regenerate_completion_labels(
 6535        adapter: Arc<CachedLspAdapter>,
 6536        snapshot: &BufferSnapshot,
 6537        completions: Rc<RefCell<Box<[Completion]>>>,
 6538        completion_index: usize,
 6539    ) -> Result<()> {
 6540        let completion_item = completions.borrow()[completion_index]
 6541            .source
 6542            .lsp_completion(true)
 6543            .map(Cow::into_owned);
 6544        if let Some(lsp_documentation) = completion_item
 6545            .as_ref()
 6546            .and_then(|completion_item| completion_item.documentation.clone())
 6547        {
 6548            let mut completions = completions.borrow_mut();
 6549            let completion = &mut completions[completion_index];
 6550            completion.documentation = Some(lsp_documentation.into());
 6551        } else {
 6552            let mut completions = completions.borrow_mut();
 6553            let completion = &mut completions[completion_index];
 6554            completion.documentation = Some(CompletionDocumentation::Undocumented);
 6555        }
 6556
 6557        let mut new_label = match completion_item {
 6558            Some(completion_item) => {
 6559                // Some language servers always return `detail` lazily via resolve, regardless of
 6560                // the resolvable properties Zed advertises. Regenerate labels here to handle this.
 6561                // See: https://github.com/yioneko/vtsls/issues/213
 6562                let language = snapshot.language();
 6563                match language {
 6564                    Some(language) => {
 6565                        adapter
 6566                            .labels_for_completions(
 6567                                std::slice::from_ref(&completion_item),
 6568                                language,
 6569                            )
 6570                            .await?
 6571                    }
 6572                    None => Vec::new(),
 6573                }
 6574                .pop()
 6575                .flatten()
 6576                .unwrap_or_else(|| {
 6577                    CodeLabel::fallback_for_completion(
 6578                        &completion_item,
 6579                        language.map(|language| language.as_ref()),
 6580                    )
 6581                })
 6582            }
 6583            None => CodeLabel::plain(
 6584                completions.borrow()[completion_index].new_text.clone(),
 6585                None,
 6586            ),
 6587        };
 6588        ensure_uniform_list_compatible_label(&mut new_label);
 6589
 6590        let mut completions = completions.borrow_mut();
 6591        let completion = &mut completions[completion_index];
 6592        if completion.label.filter_text() == new_label.filter_text() {
 6593            completion.label = new_label;
 6594        } else {
 6595            log::error!(
 6596                "Resolved completion changed display label from {} to {}. \
 6597                 Refusing to apply this because it changes the fuzzy match text from {} to {}",
 6598                completion.label.text(),
 6599                new_label.text(),
 6600                completion.label.filter_text(),
 6601                new_label.filter_text()
 6602            );
 6603        }
 6604
 6605        Ok(())
 6606    }
 6607
 6608    async fn resolve_completion_remote(
 6609        project_id: u64,
 6610        server_id: LanguageServerId,
 6611        buffer_id: BufferId,
 6612        completions: Rc<RefCell<Box<[Completion]>>>,
 6613        completion_index: usize,
 6614        client: AnyProtoClient,
 6615    ) -> Result<()> {
 6616        let lsp_completion = {
 6617            let completion = &completions.borrow()[completion_index];
 6618            match &completion.source {
 6619                CompletionSource::Lsp {
 6620                    lsp_completion,
 6621                    resolved,
 6622                    server_id: completion_server_id,
 6623                    ..
 6624                } => {
 6625                    anyhow::ensure!(
 6626                        server_id == *completion_server_id,
 6627                        "remote server_id mismatch, querying completion resolve for {server_id} but completion server id is {completion_server_id}"
 6628                    );
 6629                    if *resolved {
 6630                        return Ok(());
 6631                    }
 6632                    serde_json::to_string(lsp_completion).unwrap().into_bytes()
 6633                }
 6634                CompletionSource::Custom
 6635                | CompletionSource::Dap { .. }
 6636                | CompletionSource::BufferWord { .. } => {
 6637                    return Ok(());
 6638                }
 6639            }
 6640        };
 6641        let request = proto::ResolveCompletionDocumentation {
 6642            project_id,
 6643            language_server_id: server_id.0 as u64,
 6644            lsp_completion,
 6645            buffer_id: buffer_id.into(),
 6646        };
 6647
 6648        let response = client
 6649            .request(request)
 6650            .await
 6651            .context("completion documentation resolve proto request")?;
 6652        let resolved_lsp_completion = serde_json::from_slice(&response.lsp_completion)?;
 6653
 6654        let documentation = if response.documentation.is_empty() {
 6655            CompletionDocumentation::Undocumented
 6656        } else if response.documentation_is_markdown {
 6657            CompletionDocumentation::MultiLineMarkdown(response.documentation.into())
 6658        } else if response.documentation.lines().count() <= 1 {
 6659            CompletionDocumentation::SingleLine(response.documentation.into())
 6660        } else {
 6661            CompletionDocumentation::MultiLinePlainText(response.documentation.into())
 6662        };
 6663
 6664        let mut completions = completions.borrow_mut();
 6665        let completion = &mut completions[completion_index];
 6666        completion.documentation = Some(documentation);
 6667        if let CompletionSource::Lsp {
 6668            insert_range,
 6669            lsp_completion,
 6670            resolved,
 6671            server_id: completion_server_id,
 6672            lsp_defaults: _,
 6673        } = &mut completion.source
 6674        {
 6675            let completion_insert_range = response
 6676                .old_insert_start
 6677                .and_then(deserialize_anchor)
 6678                .zip(response.old_insert_end.and_then(deserialize_anchor));
 6679            *insert_range = completion_insert_range.map(|(start, end)| start..end);
 6680
 6681            if *resolved {
 6682                return Ok(());
 6683            }
 6684            anyhow::ensure!(
 6685                server_id == *completion_server_id,
 6686                "remote server_id mismatch, applying completion resolve for {server_id} but completion server id is {completion_server_id}"
 6687            );
 6688            **lsp_completion = resolved_lsp_completion;
 6689            *resolved = true;
 6690        }
 6691
 6692        let replace_range = response
 6693            .old_replace_start
 6694            .and_then(deserialize_anchor)
 6695            .zip(response.old_replace_end.and_then(deserialize_anchor));
 6696        if let Some((old_replace_start, old_replace_end)) = replace_range
 6697            && !response.new_text.is_empty()
 6698        {
 6699            completion.new_text = response.new_text;
 6700            completion.replace_range = old_replace_start..old_replace_end;
 6701        }
 6702
 6703        Ok(())
 6704    }
 6705
 6706    pub fn apply_additional_edits_for_completion(
 6707        &self,
 6708        buffer_handle: Entity<Buffer>,
 6709        completions: Rc<RefCell<Box<[Completion]>>>,
 6710        completion_index: usize,
 6711        push_to_history: bool,
 6712        cx: &mut Context<Self>,
 6713    ) -> Task<Result<Option<Transaction>>> {
 6714        if let Some((client, project_id)) = self.upstream_client() {
 6715            let buffer = buffer_handle.read(cx);
 6716            let buffer_id = buffer.remote_id();
 6717            cx.spawn(async move |_, cx| {
 6718                let request = {
 6719                    let completion = completions.borrow()[completion_index].clone();
 6720                    proto::ApplyCompletionAdditionalEdits {
 6721                        project_id,
 6722                        buffer_id: buffer_id.into(),
 6723                        completion: Some(Self::serialize_completion(&CoreCompletion {
 6724                            replace_range: completion.replace_range,
 6725                            new_text: completion.new_text,
 6726                            source: completion.source,
 6727                        })),
 6728                    }
 6729                };
 6730
 6731                if let Some(transaction) = client.request(request).await?.transaction {
 6732                    let transaction = language::proto::deserialize_transaction(transaction)?;
 6733                    buffer_handle
 6734                        .update(cx, |buffer, _| {
 6735                            buffer.wait_for_edits(transaction.edit_ids.iter().copied())
 6736                        })
 6737                        .await?;
 6738                    if push_to_history {
 6739                        buffer_handle.update(cx, |buffer, _| {
 6740                            buffer.push_transaction(transaction.clone(), Instant::now());
 6741                            buffer.finalize_last_transaction();
 6742                        });
 6743                    }
 6744                    Ok(Some(transaction))
 6745                } else {
 6746                    Ok(None)
 6747                }
 6748            })
 6749        } else {
 6750            let Some(server) = buffer_handle.update(cx, |buffer, cx| {
 6751                let completion = &completions.borrow()[completion_index];
 6752                let server_id = completion.source.server_id()?;
 6753                Some(
 6754                    self.language_server_for_local_buffer(buffer, server_id, cx)?
 6755                        .1
 6756                        .clone(),
 6757                )
 6758            }) else {
 6759                return Task::ready(Ok(None));
 6760            };
 6761
 6762            cx.spawn(async move |this, cx| {
 6763                Self::resolve_completion_local(
 6764                    server.clone(),
 6765                    completions.clone(),
 6766                    completion_index,
 6767                )
 6768                .await
 6769                .context("resolving completion")?;
 6770                let completion = completions.borrow()[completion_index].clone();
 6771                let additional_text_edits = completion
 6772                    .source
 6773                    .lsp_completion(true)
 6774                    .as_ref()
 6775                    .and_then(|lsp_completion| lsp_completion.additional_text_edits.clone());
 6776                if let Some(edits) = additional_text_edits {
 6777                    let edits = this
 6778                        .update(cx, |this, cx| {
 6779                            this.as_local_mut().unwrap().edits_from_lsp(
 6780                                &buffer_handle,
 6781                                edits,
 6782                                server.server_id(),
 6783                                None,
 6784                                cx,
 6785                            )
 6786                        })?
 6787                        .await?;
 6788
 6789                    buffer_handle.update(cx, |buffer, cx| {
 6790                        buffer.finalize_last_transaction();
 6791                        buffer.start_transaction();
 6792
 6793                        for (range, text) in edits {
 6794                            let primary = &completion.replace_range;
 6795
 6796                            // Special case: if both ranges start at the very beginning of the file (line 0, column 0),
 6797                            // and the primary completion is just an insertion (empty range), then this is likely
 6798                            // an auto-import scenario and should not be considered overlapping
 6799                            // https://github.com/zed-industries/zed/issues/26136
 6800                            let is_file_start_auto_import = {
 6801                                let snapshot = buffer.snapshot();
 6802                                let primary_start_point = primary.start.to_point(&snapshot);
 6803                                let range_start_point = range.start.to_point(&snapshot);
 6804
 6805                                let result = primary_start_point.row == 0
 6806                                    && primary_start_point.column == 0
 6807                                    && range_start_point.row == 0
 6808                                    && range_start_point.column == 0;
 6809
 6810                                result
 6811                            };
 6812
 6813                            let has_overlap = if is_file_start_auto_import {
 6814                                false
 6815                            } else {
 6816                                let start_within = primary.start.cmp(&range.start, buffer).is_le()
 6817                                    && primary.end.cmp(&range.start, buffer).is_ge();
 6818                                let end_within = range.start.cmp(&primary.end, buffer).is_le()
 6819                                    && range.end.cmp(&primary.end, buffer).is_ge();
 6820                                let result = start_within || end_within;
 6821                                result
 6822                            };
 6823
 6824                            //Skip additional edits which overlap with the primary completion edit
 6825                            //https://github.com/zed-industries/zed/pull/1871
 6826                            if !has_overlap {
 6827                                buffer.edit([(range, text)], None, cx);
 6828                            }
 6829                        }
 6830
 6831                        let transaction = if buffer.end_transaction(cx).is_some() {
 6832                            let transaction = buffer.finalize_last_transaction().unwrap().clone();
 6833                            if !push_to_history {
 6834                                buffer.forget_transaction(transaction.id);
 6835                            }
 6836                            Some(transaction)
 6837                        } else {
 6838                            None
 6839                        };
 6840                        Ok(transaction)
 6841                    })
 6842                } else {
 6843                    Ok(None)
 6844                }
 6845            })
 6846        }
 6847    }
 6848
 6849    pub fn pull_diagnostics(
 6850        &mut self,
 6851        buffer: Entity<Buffer>,
 6852        cx: &mut Context<Self>,
 6853    ) -> Task<Result<Option<Vec<LspPullDiagnostics>>>> {
 6854        let buffer_id = buffer.read(cx).remote_id();
 6855
 6856        if let Some((client, upstream_project_id)) = self.upstream_client() {
 6857            let mut suitable_capabilities = None;
 6858            // Are we capable for proto request?
 6859            let any_server_has_diagnostics_provider = self.check_if_capable_for_proto_request(
 6860                &buffer,
 6861                |capabilities| {
 6862                    if let Some(caps) = &capabilities.diagnostic_provider {
 6863                        suitable_capabilities = Some(caps.clone());
 6864                        true
 6865                    } else {
 6866                        false
 6867                    }
 6868                },
 6869                cx,
 6870            );
 6871            // We don't really care which caps are passed into the request, as they're ignored by RPC anyways.
 6872            let Some(dynamic_caps) = suitable_capabilities else {
 6873                return Task::ready(Ok(None));
 6874            };
 6875            assert!(any_server_has_diagnostics_provider);
 6876
 6877            let identifier = buffer_diagnostic_identifier(&dynamic_caps);
 6878            let request = GetDocumentDiagnostics {
 6879                previous_result_id: None,
 6880                identifier,
 6881                registration_id: None,
 6882            };
 6883            let request_task = client.request_lsp(
 6884                upstream_project_id,
 6885                None,
 6886                LSP_REQUEST_TIMEOUT,
 6887                cx.background_executor().clone(),
 6888                request.to_proto(upstream_project_id, buffer.read(cx)),
 6889            );
 6890            cx.background_spawn(async move {
 6891                // Proto requests cause the diagnostics to be pulled from language server(s) on the local side
 6892                // and then, buffer state updated with the diagnostics received, which will be later propagated to the client.
 6893                // Do not attempt to further process the dummy responses here.
 6894                let _response = request_task.await?;
 6895                Ok(None)
 6896            })
 6897        } else {
 6898            let servers = buffer.update(cx, |buffer, cx| {
 6899                self.running_language_servers_for_local_buffer(buffer, cx)
 6900                    .map(|(_, server)| server.clone())
 6901                    .collect::<Vec<_>>()
 6902            });
 6903
 6904            let pull_diagnostics = servers
 6905                .into_iter()
 6906                .flat_map(|server| {
 6907                    let result = maybe!({
 6908                        let local = self.as_local()?;
 6909                        let server_id = server.server_id();
 6910                        let providers_with_identifiers = local
 6911                            .language_server_dynamic_registrations
 6912                            .get(&server_id)
 6913                            .into_iter()
 6914                            .flat_map(|registrations| registrations.diagnostics.clone())
 6915                            .collect::<Vec<_>>();
 6916                        Some(
 6917                            providers_with_identifiers
 6918                                .into_iter()
 6919                                .map(|(registration_id, dynamic_caps)| {
 6920                                    let identifier = buffer_diagnostic_identifier(&dynamic_caps);
 6921                                    let registration_id = registration_id.map(SharedString::from);
 6922                                    let result_id = self.result_id_for_buffer_pull(
 6923                                        server_id,
 6924                                        buffer_id,
 6925                                        &registration_id,
 6926                                        cx,
 6927                                    );
 6928                                    self.request_lsp(
 6929                                        buffer.clone(),
 6930                                        LanguageServerToQuery::Other(server_id),
 6931                                        GetDocumentDiagnostics {
 6932                                            previous_result_id: result_id,
 6933                                            registration_id,
 6934                                            identifier,
 6935                                        },
 6936                                        cx,
 6937                                    )
 6938                                })
 6939                                .collect::<Vec<_>>(),
 6940                        )
 6941                    });
 6942
 6943                    result.unwrap_or_default()
 6944                })
 6945                .collect::<Vec<_>>();
 6946
 6947            cx.background_spawn(async move {
 6948                let mut responses = Vec::new();
 6949                for diagnostics in join_all(pull_diagnostics).await {
 6950                    responses.extend(diagnostics?);
 6951                }
 6952                Ok(Some(responses))
 6953            })
 6954        }
 6955    }
 6956
 6957    pub fn applicable_inlay_chunks(
 6958        &mut self,
 6959        buffer: &Entity<Buffer>,
 6960        ranges: &[Range<text::Anchor>],
 6961        cx: &mut Context<Self>,
 6962    ) -> Vec<Range<BufferRow>> {
 6963        let buffer_snapshot = buffer.read(cx).snapshot();
 6964        let ranges = ranges
 6965            .iter()
 6966            .map(|range| range.to_point(&buffer_snapshot))
 6967            .collect::<Vec<_>>();
 6968
 6969        self.latest_lsp_data(buffer, cx)
 6970            .inlay_hints
 6971            .applicable_chunks(ranges.as_slice())
 6972            .map(|chunk| chunk.row_range())
 6973            .collect()
 6974    }
 6975
 6976    pub fn invalidate_inlay_hints<'a>(
 6977        &'a mut self,
 6978        for_buffers: impl IntoIterator<Item = &'a BufferId> + 'a,
 6979    ) {
 6980        for buffer_id in for_buffers {
 6981            if let Some(lsp_data) = self.lsp_data.get_mut(buffer_id) {
 6982                lsp_data.inlay_hints.clear();
 6983            }
 6984        }
 6985    }
 6986
 6987    pub fn inlay_hints(
 6988        &mut self,
 6989        invalidate: InvalidationStrategy,
 6990        buffer: Entity<Buffer>,
 6991        ranges: Vec<Range<text::Anchor>>,
 6992        known_chunks: Option<(clock::Global, HashSet<Range<BufferRow>>)>,
 6993        cx: &mut Context<Self>,
 6994    ) -> HashMap<Range<BufferRow>, Task<Result<CacheInlayHints>>> {
 6995        let next_hint_id = self.next_hint_id.clone();
 6996        let lsp_data = self.latest_lsp_data(&buffer, cx);
 6997        let query_version = lsp_data.buffer_version.clone();
 6998        let mut lsp_refresh_requested = false;
 6999        let for_server = if let InvalidationStrategy::RefreshRequested {
 7000            server_id,
 7001            request_id,
 7002        } = invalidate
 7003        {
 7004            let invalidated = lsp_data
 7005                .inlay_hints
 7006                .invalidate_for_server_refresh(server_id, request_id);
 7007            lsp_refresh_requested = invalidated;
 7008            Some(server_id)
 7009        } else {
 7010            None
 7011        };
 7012        let existing_inlay_hints = &mut lsp_data.inlay_hints;
 7013        let known_chunks = known_chunks
 7014            .filter(|(known_version, _)| !lsp_data.buffer_version.changed_since(known_version))
 7015            .map(|(_, known_chunks)| known_chunks)
 7016            .unwrap_or_default();
 7017
 7018        let buffer_snapshot = buffer.read(cx).snapshot();
 7019        let ranges = ranges
 7020            .iter()
 7021            .map(|range| range.to_point(&buffer_snapshot))
 7022            .collect::<Vec<_>>();
 7023
 7024        let mut hint_fetch_tasks = Vec::new();
 7025        let mut cached_inlay_hints = None;
 7026        let mut ranges_to_query = None;
 7027        let applicable_chunks = existing_inlay_hints
 7028            .applicable_chunks(ranges.as_slice())
 7029            .filter(|chunk| !known_chunks.contains(&chunk.row_range()))
 7030            .collect::<Vec<_>>();
 7031        if applicable_chunks.is_empty() {
 7032            return HashMap::default();
 7033        }
 7034
 7035        for row_chunk in applicable_chunks {
 7036            match (
 7037                existing_inlay_hints
 7038                    .cached_hints(&row_chunk)
 7039                    .filter(|_| !lsp_refresh_requested)
 7040                    .cloned(),
 7041                existing_inlay_hints
 7042                    .fetched_hints(&row_chunk)
 7043                    .as_ref()
 7044                    .filter(|_| !lsp_refresh_requested)
 7045                    .cloned(),
 7046            ) {
 7047                (None, None) => {
 7048                    let chunk_range = row_chunk.anchor_range();
 7049                    ranges_to_query
 7050                        .get_or_insert_with(Vec::new)
 7051                        .push((row_chunk, chunk_range));
 7052                }
 7053                (None, Some(fetched_hints)) => hint_fetch_tasks.push((row_chunk, fetched_hints)),
 7054                (Some(cached_hints), None) => {
 7055                    for (server_id, cached_hints) in cached_hints {
 7056                        if for_server.is_none_or(|for_server| for_server == server_id) {
 7057                            cached_inlay_hints
 7058                                .get_or_insert_with(HashMap::default)
 7059                                .entry(row_chunk.row_range())
 7060                                .or_insert_with(HashMap::default)
 7061                                .entry(server_id)
 7062                                .or_insert_with(Vec::new)
 7063                                .extend(cached_hints);
 7064                        }
 7065                    }
 7066                }
 7067                (Some(cached_hints), Some(fetched_hints)) => {
 7068                    hint_fetch_tasks.push((row_chunk, fetched_hints));
 7069                    for (server_id, cached_hints) in cached_hints {
 7070                        if for_server.is_none_or(|for_server| for_server == server_id) {
 7071                            cached_inlay_hints
 7072                                .get_or_insert_with(HashMap::default)
 7073                                .entry(row_chunk.row_range())
 7074                                .or_insert_with(HashMap::default)
 7075                                .entry(server_id)
 7076                                .or_insert_with(Vec::new)
 7077                                .extend(cached_hints);
 7078                        }
 7079                    }
 7080                }
 7081            }
 7082        }
 7083
 7084        if hint_fetch_tasks.is_empty()
 7085            && ranges_to_query
 7086                .as_ref()
 7087                .is_none_or(|ranges| ranges.is_empty())
 7088            && let Some(cached_inlay_hints) = cached_inlay_hints
 7089        {
 7090            cached_inlay_hints
 7091                .into_iter()
 7092                .map(|(row_chunk, hints)| (row_chunk, Task::ready(Ok(hints))))
 7093                .collect()
 7094        } else {
 7095            for (chunk, range_to_query) in ranges_to_query.into_iter().flatten() {
 7096                let next_hint_id = next_hint_id.clone();
 7097                let buffer = buffer.clone();
 7098                let query_version = query_version.clone();
 7099                let new_inlay_hints = cx
 7100                    .spawn(async move |lsp_store, cx| {
 7101                        let new_fetch_task = lsp_store.update(cx, |lsp_store, cx| {
 7102                            lsp_store.fetch_inlay_hints(for_server, &buffer, range_to_query, cx)
 7103                        })?;
 7104                        new_fetch_task
 7105                            .await
 7106                            .and_then(|new_hints_by_server| {
 7107                                lsp_store.update(cx, |lsp_store, cx| {
 7108                                    let lsp_data = lsp_store.latest_lsp_data(&buffer, cx);
 7109                                    let update_cache = lsp_data.buffer_version == query_version;
 7110                                    if new_hints_by_server.is_empty() {
 7111                                        if update_cache {
 7112                                            lsp_data.inlay_hints.invalidate_for_chunk(chunk);
 7113                                        }
 7114                                        HashMap::default()
 7115                                    } else {
 7116                                        new_hints_by_server
 7117                                            .into_iter()
 7118                                            .map(|(server_id, new_hints)| {
 7119                                                let new_hints = new_hints
 7120                                                    .into_iter()
 7121                                                    .map(|new_hint| {
 7122                                                        (
 7123                                                            InlayId::Hint(next_hint_id.fetch_add(
 7124                                                                1,
 7125                                                                atomic::Ordering::AcqRel,
 7126                                                            )),
 7127                                                            new_hint,
 7128                                                        )
 7129                                                    })
 7130                                                    .collect::<Vec<_>>();
 7131                                                if update_cache {
 7132                                                    lsp_data.inlay_hints.insert_new_hints(
 7133                                                        chunk,
 7134                                                        server_id,
 7135                                                        new_hints.clone(),
 7136                                                    );
 7137                                                }
 7138                                                (server_id, new_hints)
 7139                                            })
 7140                                            .collect()
 7141                                    }
 7142                                })
 7143                            })
 7144                            .map_err(Arc::new)
 7145                    })
 7146                    .shared();
 7147
 7148                let fetch_task = lsp_data.inlay_hints.fetched_hints(&chunk);
 7149                *fetch_task = Some(new_inlay_hints.clone());
 7150                hint_fetch_tasks.push((chunk, new_inlay_hints));
 7151            }
 7152
 7153            cached_inlay_hints
 7154                .unwrap_or_default()
 7155                .into_iter()
 7156                .map(|(row_chunk, hints)| (row_chunk, Task::ready(Ok(hints))))
 7157                .chain(hint_fetch_tasks.into_iter().map(|(chunk, hints_fetch)| {
 7158                    (
 7159                        chunk.row_range(),
 7160                        cx.spawn(async move |_, _| {
 7161                            hints_fetch.await.map_err(|e| {
 7162                                if e.error_code() != ErrorCode::Internal {
 7163                                    anyhow!(e.error_code())
 7164                                } else {
 7165                                    anyhow!("{e:#}")
 7166                                }
 7167                            })
 7168                        }),
 7169                    )
 7170                }))
 7171                .collect()
 7172        }
 7173    }
 7174
 7175    fn fetch_inlay_hints(
 7176        &mut self,
 7177        for_server: Option<LanguageServerId>,
 7178        buffer: &Entity<Buffer>,
 7179        range: Range<Anchor>,
 7180        cx: &mut Context<Self>,
 7181    ) -> Task<Result<HashMap<LanguageServerId, Vec<InlayHint>>>> {
 7182        let request = InlayHints {
 7183            range: range.clone(),
 7184        };
 7185        if let Some((upstream_client, project_id)) = self.upstream_client() {
 7186            if !self.is_capable_for_proto_request(buffer, &request, cx) {
 7187                return Task::ready(Ok(HashMap::default()));
 7188            }
 7189            let request_task = upstream_client.request_lsp(
 7190                project_id,
 7191                for_server.map(|id| id.to_proto()),
 7192                LSP_REQUEST_TIMEOUT,
 7193                cx.background_executor().clone(),
 7194                request.to_proto(project_id, buffer.read(cx)),
 7195            );
 7196            let buffer = buffer.clone();
 7197            cx.spawn(async move |weak_lsp_store, cx| {
 7198                let Some(lsp_store) = weak_lsp_store.upgrade() else {
 7199                    return Ok(HashMap::default());
 7200                };
 7201                let Some(responses) = request_task.await? else {
 7202                    return Ok(HashMap::default());
 7203                };
 7204
 7205                let inlay_hints = join_all(responses.payload.into_iter().map(|response| {
 7206                    let lsp_store = lsp_store.clone();
 7207                    let buffer = buffer.clone();
 7208                    let cx = cx.clone();
 7209                    let request = request.clone();
 7210                    async move {
 7211                        (
 7212                            LanguageServerId::from_proto(response.server_id),
 7213                            request
 7214                                .response_from_proto(response.response, lsp_store, buffer, cx)
 7215                                .await,
 7216                        )
 7217                    }
 7218                }))
 7219                .await;
 7220
 7221                let buffer_snapshot = buffer.read_with(cx, |buffer, _| buffer.snapshot());
 7222                let mut has_errors = false;
 7223                let inlay_hints = inlay_hints
 7224                    .into_iter()
 7225                    .filter_map(|(server_id, inlay_hints)| match inlay_hints {
 7226                        Ok(inlay_hints) => Some((server_id, inlay_hints)),
 7227                        Err(e) => {
 7228                            has_errors = true;
 7229                            log::error!("{e:#}");
 7230                            None
 7231                        }
 7232                    })
 7233                    .map(|(server_id, mut new_hints)| {
 7234                        new_hints.retain(|hint| {
 7235                            hint.position.is_valid(&buffer_snapshot)
 7236                                && range.start.is_valid(&buffer_snapshot)
 7237                                && range.end.is_valid(&buffer_snapshot)
 7238                                && hint.position.cmp(&range.start, &buffer_snapshot).is_ge()
 7239                                && hint.position.cmp(&range.end, &buffer_snapshot).is_lt()
 7240                        });
 7241                        (server_id, new_hints)
 7242                    })
 7243                    .collect::<HashMap<_, _>>();
 7244                anyhow::ensure!(
 7245                    !has_errors || !inlay_hints.is_empty(),
 7246                    "Failed to fetch inlay hints"
 7247                );
 7248                Ok(inlay_hints)
 7249            })
 7250        } else {
 7251            let inlay_hints_task = match for_server {
 7252                Some(server_id) => {
 7253                    let server_task = self.request_lsp(
 7254                        buffer.clone(),
 7255                        LanguageServerToQuery::Other(server_id),
 7256                        request,
 7257                        cx,
 7258                    );
 7259                    cx.background_spawn(async move {
 7260                        let mut responses = Vec::new();
 7261                        match server_task.await {
 7262                            Ok(response) => responses.push((server_id, response)),
 7263                            // rust-analyzer likes to error with this when its still loading up
 7264                            Err(e) if format!("{e:#}").ends_with("content modified") => (),
 7265                            Err(e) => log::error!(
 7266                                "Error handling response for inlay hints request: {e:#}"
 7267                            ),
 7268                        }
 7269                        responses
 7270                    })
 7271                }
 7272                None => self.request_multiple_lsp_locally(buffer, None::<usize>, request, cx),
 7273            };
 7274            let buffer_snapshot = buffer.read_with(cx, |buffer, _| buffer.snapshot());
 7275            cx.background_spawn(async move {
 7276                Ok(inlay_hints_task
 7277                    .await
 7278                    .into_iter()
 7279                    .map(|(server_id, mut new_hints)| {
 7280                        new_hints.retain(|hint| {
 7281                            hint.position.is_valid(&buffer_snapshot)
 7282                                && range.start.is_valid(&buffer_snapshot)
 7283                                && range.end.is_valid(&buffer_snapshot)
 7284                                && hint.position.cmp(&range.start, &buffer_snapshot).is_ge()
 7285                                && hint.position.cmp(&range.end, &buffer_snapshot).is_lt()
 7286                        });
 7287                        (server_id, new_hints)
 7288                    })
 7289                    .collect())
 7290            })
 7291        }
 7292    }
 7293
 7294    fn diagnostic_registration_exists(
 7295        &self,
 7296        server_id: LanguageServerId,
 7297        registration_id: &Option<SharedString>,
 7298    ) -> bool {
 7299        let Some(local) = self.as_local() else {
 7300            return false;
 7301        };
 7302        let Some(registrations) = local.language_server_dynamic_registrations.get(&server_id)
 7303        else {
 7304            return false;
 7305        };
 7306        let registration_key = registration_id.as_ref().map(|s| s.to_string());
 7307        registrations.diagnostics.contains_key(&registration_key)
 7308    }
 7309
 7310    pub fn pull_diagnostics_for_buffer(
 7311        &mut self,
 7312        buffer: Entity<Buffer>,
 7313        cx: &mut Context<Self>,
 7314    ) -> Task<anyhow::Result<()>> {
 7315        let diagnostics = self.pull_diagnostics(buffer, cx);
 7316        cx.spawn(async move |lsp_store, cx| {
 7317            let Some(diagnostics) = diagnostics.await.context("pulling diagnostics")? else {
 7318                return Ok(());
 7319            };
 7320            lsp_store.update(cx, |lsp_store, cx| {
 7321                if lsp_store.as_local().is_none() {
 7322                    return;
 7323                }
 7324
 7325                let mut unchanged_buffers = HashMap::default();
 7326                let server_diagnostics_updates = diagnostics
 7327                    .into_iter()
 7328                    .filter_map(|diagnostics_set| match diagnostics_set {
 7329                        LspPullDiagnostics::Response {
 7330                            server_id,
 7331                            uri,
 7332                            diagnostics,
 7333                            registration_id,
 7334                        } => Some((server_id, uri, diagnostics, registration_id)),
 7335                        LspPullDiagnostics::Default => None,
 7336                    })
 7337                    .filter(|(server_id, _, _, registration_id)| {
 7338                        lsp_store.diagnostic_registration_exists(*server_id, registration_id)
 7339                    })
 7340                    .fold(
 7341                        HashMap::default(),
 7342                        |mut acc, (server_id, uri, diagnostics, new_registration_id)| {
 7343                            let (result_id, diagnostics) = match diagnostics {
 7344                                PulledDiagnostics::Unchanged { result_id } => {
 7345                                    unchanged_buffers
 7346                                        .entry(new_registration_id.clone())
 7347                                        .or_insert_with(HashSet::default)
 7348                                        .insert(uri.clone());
 7349                                    (Some(result_id), Vec::new())
 7350                                }
 7351                                PulledDiagnostics::Changed {
 7352                                    result_id,
 7353                                    diagnostics,
 7354                                } => (result_id, diagnostics),
 7355                            };
 7356                            let disk_based_sources = Cow::Owned(
 7357                                lsp_store
 7358                                    .language_server_adapter_for_id(server_id)
 7359                                    .as_ref()
 7360                                    .map(|adapter| adapter.disk_based_diagnostic_sources.as_slice())
 7361                                    .unwrap_or(&[])
 7362                                    .to_vec(),
 7363                            );
 7364                            acc.entry(server_id)
 7365                                .or_insert_with(HashMap::default)
 7366                                .entry(new_registration_id.clone())
 7367                                .or_insert_with(Vec::new)
 7368                                .push(DocumentDiagnosticsUpdate {
 7369                                    server_id,
 7370                                    diagnostics: lsp::PublishDiagnosticsParams {
 7371                                        uri,
 7372                                        diagnostics,
 7373                                        version: None,
 7374                                    },
 7375                                    result_id,
 7376                                    disk_based_sources,
 7377                                    registration_id: new_registration_id,
 7378                                });
 7379                            acc
 7380                        },
 7381                    );
 7382
 7383                for diagnostic_updates in server_diagnostics_updates.into_values() {
 7384                    for (registration_id, diagnostic_updates) in diagnostic_updates {
 7385                        lsp_store
 7386                            .merge_lsp_diagnostics(
 7387                                DiagnosticSourceKind::Pulled,
 7388                                diagnostic_updates,
 7389                                |document_uri, old_diagnostic, _| match old_diagnostic.source_kind {
 7390                                    DiagnosticSourceKind::Pulled => {
 7391                                        old_diagnostic.registration_id != registration_id
 7392                                            || unchanged_buffers
 7393                                                .get(&old_diagnostic.registration_id)
 7394                                                .is_some_and(|unchanged_buffers| {
 7395                                                    unchanged_buffers.contains(&document_uri)
 7396                                                })
 7397                                    }
 7398                                    DiagnosticSourceKind::Other | DiagnosticSourceKind::Pushed => {
 7399                                        true
 7400                                    }
 7401                                },
 7402                                cx,
 7403                            )
 7404                            .log_err();
 7405                    }
 7406                }
 7407            })
 7408        })
 7409    }
 7410
 7411    pub fn document_colors(
 7412        &mut self,
 7413        known_cache_version: Option<usize>,
 7414        buffer: Entity<Buffer>,
 7415        cx: &mut Context<Self>,
 7416    ) -> Option<DocumentColorTask> {
 7417        let version_queried_for = buffer.read(cx).version();
 7418        let buffer_id = buffer.read(cx).remote_id();
 7419
 7420        let current_language_servers = self.as_local().map(|local| {
 7421            local
 7422                .buffers_opened_in_servers
 7423                .get(&buffer_id)
 7424                .cloned()
 7425                .unwrap_or_default()
 7426        });
 7427
 7428        if let Some(lsp_data) = self.current_lsp_data(buffer_id) {
 7429            if let Some(cached_colors) = &lsp_data.document_colors {
 7430                if !version_queried_for.changed_since(&lsp_data.buffer_version) {
 7431                    let has_different_servers =
 7432                        current_language_servers.is_some_and(|current_language_servers| {
 7433                            current_language_servers
 7434                                != cached_colors.colors.keys().copied().collect()
 7435                        });
 7436                    if !has_different_servers {
 7437                        let cache_version = cached_colors.cache_version;
 7438                        if Some(cache_version) == known_cache_version {
 7439                            return None;
 7440                        } else {
 7441                            return Some(
 7442                                Task::ready(Ok(DocumentColors {
 7443                                    colors: cached_colors
 7444                                        .colors
 7445                                        .values()
 7446                                        .flatten()
 7447                                        .cloned()
 7448                                        .collect(),
 7449                                    cache_version: Some(cache_version),
 7450                                }))
 7451                                .shared(),
 7452                            );
 7453                        }
 7454                    }
 7455                }
 7456            }
 7457        }
 7458
 7459        let color_lsp_data = self
 7460            .latest_lsp_data(&buffer, cx)
 7461            .document_colors
 7462            .get_or_insert_default();
 7463        if let Some((updating_for, running_update)) = &color_lsp_data.colors_update
 7464            && !version_queried_for.changed_since(updating_for)
 7465        {
 7466            return Some(running_update.clone());
 7467        }
 7468        let buffer_version_queried_for = version_queried_for.clone();
 7469        let new_task = cx
 7470            .spawn(async move |lsp_store, cx| {
 7471                cx.background_executor()
 7472                    .timer(Duration::from_millis(30))
 7473                    .await;
 7474                let fetched_colors = lsp_store
 7475                    .update(cx, |lsp_store, cx| {
 7476                        lsp_store.fetch_document_colors_for_buffer(&buffer, cx)
 7477                    })?
 7478                    .await
 7479                    .context("fetching document colors")
 7480                    .map_err(Arc::new);
 7481                let fetched_colors = match fetched_colors {
 7482                    Ok(fetched_colors) => {
 7483                        if buffer.update(cx, |buffer, _| {
 7484                            buffer.version() != buffer_version_queried_for
 7485                        }) {
 7486                            return Ok(DocumentColors::default());
 7487                        }
 7488                        fetched_colors
 7489                    }
 7490                    Err(e) => {
 7491                        lsp_store
 7492                            .update(cx, |lsp_store, _| {
 7493                                if let Some(lsp_data) = lsp_store.lsp_data.get_mut(&buffer_id) {
 7494                                    if let Some(document_colors) = &mut lsp_data.document_colors {
 7495                                        document_colors.colors_update = None;
 7496                                    }
 7497                                }
 7498                            })
 7499                            .ok();
 7500                        return Err(e);
 7501                    }
 7502                };
 7503
 7504                lsp_store
 7505                    .update(cx, |lsp_store, cx| {
 7506                        let lsp_data = lsp_store.latest_lsp_data(&buffer, cx);
 7507                        let lsp_colors = lsp_data.document_colors.get_or_insert_default();
 7508
 7509                        if let Some(fetched_colors) = fetched_colors {
 7510                            if lsp_data.buffer_version == buffer_version_queried_for {
 7511                                lsp_colors.colors.extend(fetched_colors);
 7512                                lsp_colors.cache_version += 1;
 7513                            } else if !lsp_data
 7514                                .buffer_version
 7515                                .changed_since(&buffer_version_queried_for)
 7516                            {
 7517                                lsp_data.buffer_version = buffer_version_queried_for;
 7518                                lsp_colors.colors = fetched_colors;
 7519                                lsp_colors.cache_version += 1;
 7520                            }
 7521                        }
 7522                        lsp_colors.colors_update = None;
 7523                        let colors = lsp_colors
 7524                            .colors
 7525                            .values()
 7526                            .flatten()
 7527                            .cloned()
 7528                            .collect::<HashSet<_>>();
 7529                        DocumentColors {
 7530                            colors,
 7531                            cache_version: Some(lsp_colors.cache_version),
 7532                        }
 7533                    })
 7534                    .map_err(Arc::new)
 7535            })
 7536            .shared();
 7537        color_lsp_data.colors_update = Some((version_queried_for, new_task.clone()));
 7538        Some(new_task)
 7539    }
 7540
 7541    fn fetch_document_colors_for_buffer(
 7542        &mut self,
 7543        buffer: &Entity<Buffer>,
 7544        cx: &mut Context<Self>,
 7545    ) -> Task<anyhow::Result<Option<HashMap<LanguageServerId, HashSet<DocumentColor>>>>> {
 7546        if let Some((client, project_id)) = self.upstream_client() {
 7547            let request = GetDocumentColor {};
 7548            if !self.is_capable_for_proto_request(buffer, &request, cx) {
 7549                return Task::ready(Ok(None));
 7550            }
 7551
 7552            let request_task = client.request_lsp(
 7553                project_id,
 7554                None,
 7555                LSP_REQUEST_TIMEOUT,
 7556                cx.background_executor().clone(),
 7557                request.to_proto(project_id, buffer.read(cx)),
 7558            );
 7559            let buffer = buffer.clone();
 7560            cx.spawn(async move |lsp_store, cx| {
 7561                let Some(lsp_store) = lsp_store.upgrade() else {
 7562                    return Ok(None);
 7563                };
 7564                let colors = join_all(
 7565                    request_task
 7566                        .await
 7567                        .log_err()
 7568                        .flatten()
 7569                        .map(|response| response.payload)
 7570                        .unwrap_or_default()
 7571                        .into_iter()
 7572                        .map(|color_response| {
 7573                            let response = request.response_from_proto(
 7574                                color_response.response,
 7575                                lsp_store.clone(),
 7576                                buffer.clone(),
 7577                                cx.clone(),
 7578                            );
 7579                            async move {
 7580                                (
 7581                                    LanguageServerId::from_proto(color_response.server_id),
 7582                                    response.await.log_err().unwrap_or_default(),
 7583                                )
 7584                            }
 7585                        }),
 7586                )
 7587                .await
 7588                .into_iter()
 7589                .fold(HashMap::default(), |mut acc, (server_id, colors)| {
 7590                    acc.entry(server_id)
 7591                        .or_insert_with(HashSet::default)
 7592                        .extend(colors);
 7593                    acc
 7594                });
 7595                Ok(Some(colors))
 7596            })
 7597        } else {
 7598            let document_colors_task =
 7599                self.request_multiple_lsp_locally(buffer, None::<usize>, GetDocumentColor, cx);
 7600            cx.background_spawn(async move {
 7601                Ok(Some(
 7602                    document_colors_task
 7603                        .await
 7604                        .into_iter()
 7605                        .fold(HashMap::default(), |mut acc, (server_id, colors)| {
 7606                            acc.entry(server_id)
 7607                                .or_insert_with(HashSet::default)
 7608                                .extend(colors);
 7609                            acc
 7610                        })
 7611                        .into_iter()
 7612                        .collect(),
 7613                ))
 7614            })
 7615        }
 7616    }
 7617
 7618    pub fn signature_help<T: ToPointUtf16>(
 7619        &mut self,
 7620        buffer: &Entity<Buffer>,
 7621        position: T,
 7622        cx: &mut Context<Self>,
 7623    ) -> Task<Option<Vec<SignatureHelp>>> {
 7624        let position = position.to_point_utf16(buffer.read(cx));
 7625
 7626        if let Some((client, upstream_project_id)) = self.upstream_client() {
 7627            let request = GetSignatureHelp { position };
 7628            if !self.is_capable_for_proto_request(buffer, &request, cx) {
 7629                return Task::ready(None);
 7630            }
 7631            let request_task = client.request_lsp(
 7632                upstream_project_id,
 7633                None,
 7634                LSP_REQUEST_TIMEOUT,
 7635                cx.background_executor().clone(),
 7636                request.to_proto(upstream_project_id, buffer.read(cx)),
 7637            );
 7638            let buffer = buffer.clone();
 7639            cx.spawn(async move |weak_lsp_store, cx| {
 7640                let lsp_store = weak_lsp_store.upgrade()?;
 7641                let signatures = join_all(
 7642                    request_task
 7643                        .await
 7644                        .log_err()
 7645                        .flatten()
 7646                        .map(|response| response.payload)
 7647                        .unwrap_or_default()
 7648                        .into_iter()
 7649                        .map(|response| {
 7650                            let response = GetSignatureHelp { position }.response_from_proto(
 7651                                response.response,
 7652                                lsp_store.clone(),
 7653                                buffer.clone(),
 7654                                cx.clone(),
 7655                            );
 7656                            async move { response.await.log_err().flatten() }
 7657                        }),
 7658                )
 7659                .await
 7660                .into_iter()
 7661                .flatten()
 7662                .collect();
 7663                Some(signatures)
 7664            })
 7665        } else {
 7666            let all_actions_task = self.request_multiple_lsp_locally(
 7667                buffer,
 7668                Some(position),
 7669                GetSignatureHelp { position },
 7670                cx,
 7671            );
 7672            cx.background_spawn(async move {
 7673                Some(
 7674                    all_actions_task
 7675                        .await
 7676                        .into_iter()
 7677                        .flat_map(|(_, actions)| actions)
 7678                        .collect::<Vec<_>>(),
 7679                )
 7680            })
 7681        }
 7682    }
 7683
 7684    pub fn hover(
 7685        &mut self,
 7686        buffer: &Entity<Buffer>,
 7687        position: PointUtf16,
 7688        cx: &mut Context<Self>,
 7689    ) -> Task<Option<Vec<Hover>>> {
 7690        if let Some((client, upstream_project_id)) = self.upstream_client() {
 7691            let request = GetHover { position };
 7692            if !self.is_capable_for_proto_request(buffer, &request, cx) {
 7693                return Task::ready(None);
 7694            }
 7695            let request_task = client.request_lsp(
 7696                upstream_project_id,
 7697                None,
 7698                LSP_REQUEST_TIMEOUT,
 7699                cx.background_executor().clone(),
 7700                request.to_proto(upstream_project_id, buffer.read(cx)),
 7701            );
 7702            let buffer = buffer.clone();
 7703            cx.spawn(async move |weak_lsp_store, cx| {
 7704                let lsp_store = weak_lsp_store.upgrade()?;
 7705                let hovers = join_all(
 7706                    request_task
 7707                        .await
 7708                        .log_err()
 7709                        .flatten()
 7710                        .map(|response| response.payload)
 7711                        .unwrap_or_default()
 7712                        .into_iter()
 7713                        .map(|response| {
 7714                            let response = GetHover { position }.response_from_proto(
 7715                                response.response,
 7716                                lsp_store.clone(),
 7717                                buffer.clone(),
 7718                                cx.clone(),
 7719                            );
 7720                            async move {
 7721                                response
 7722                                    .await
 7723                                    .log_err()
 7724                                    .flatten()
 7725                                    .and_then(remove_empty_hover_blocks)
 7726                            }
 7727                        }),
 7728                )
 7729                .await
 7730                .into_iter()
 7731                .flatten()
 7732                .collect();
 7733                Some(hovers)
 7734            })
 7735        } else {
 7736            let all_actions_task = self.request_multiple_lsp_locally(
 7737                buffer,
 7738                Some(position),
 7739                GetHover { position },
 7740                cx,
 7741            );
 7742            cx.background_spawn(async move {
 7743                Some(
 7744                    all_actions_task
 7745                        .await
 7746                        .into_iter()
 7747                        .filter_map(|(_, hover)| remove_empty_hover_blocks(hover?))
 7748                        .collect::<Vec<Hover>>(),
 7749                )
 7750            })
 7751        }
 7752    }
 7753
 7754    pub fn symbols(&self, query: &str, cx: &mut Context<Self>) -> Task<Result<Vec<Symbol>>> {
 7755        let language_registry = self.languages.clone();
 7756
 7757        if let Some((upstream_client, project_id)) = self.upstream_client().as_ref() {
 7758            let request = upstream_client.request(proto::GetProjectSymbols {
 7759                project_id: *project_id,
 7760                query: query.to_string(),
 7761            });
 7762            cx.foreground_executor().spawn(async move {
 7763                let response = request.await?;
 7764                let mut symbols = Vec::new();
 7765                let core_symbols = response
 7766                    .symbols
 7767                    .into_iter()
 7768                    .filter_map(|symbol| Self::deserialize_symbol(symbol).log_err())
 7769                    .collect::<Vec<_>>();
 7770                populate_labels_for_symbols(core_symbols, &language_registry, None, &mut symbols)
 7771                    .await;
 7772                Ok(symbols)
 7773            })
 7774        } else if let Some(local) = self.as_local() {
 7775            struct WorkspaceSymbolsResult {
 7776                server_id: LanguageServerId,
 7777                lsp_adapter: Arc<CachedLspAdapter>,
 7778                worktree: WeakEntity<Worktree>,
 7779                lsp_symbols: Vec<(String, SymbolKind, lsp::Location)>,
 7780            }
 7781
 7782            let mut requests = Vec::new();
 7783            let mut requested_servers = BTreeSet::new();
 7784            for (seed, state) in local.language_server_ids.iter() {
 7785                let Some(worktree_handle) = self
 7786                    .worktree_store
 7787                    .read(cx)
 7788                    .worktree_for_id(seed.worktree_id, cx)
 7789                else {
 7790                    continue;
 7791                };
 7792                let worktree = worktree_handle.read(cx);
 7793                if !worktree.is_visible() {
 7794                    continue;
 7795                }
 7796
 7797                if !requested_servers.insert(state.id) {
 7798                    continue;
 7799                }
 7800
 7801                let (lsp_adapter, server) = match local.language_servers.get(&state.id) {
 7802                    Some(LanguageServerState::Running {
 7803                        adapter, server, ..
 7804                    }) => (adapter.clone(), server),
 7805
 7806                    _ => continue,
 7807                };
 7808                let supports_workspace_symbol_request =
 7809                    match server.capabilities().workspace_symbol_provider {
 7810                        Some(OneOf::Left(supported)) => supported,
 7811                        Some(OneOf::Right(_)) => true,
 7812                        None => false,
 7813                    };
 7814                if !supports_workspace_symbol_request {
 7815                    continue;
 7816                }
 7817                let worktree_handle = worktree_handle.clone();
 7818                let server_id = server.server_id();
 7819                requests.push(
 7820                    server
 7821                        .request::<lsp::request::WorkspaceSymbolRequest>(
 7822                            lsp::WorkspaceSymbolParams {
 7823                                query: query.to_string(),
 7824                                ..Default::default()
 7825                            },
 7826                        )
 7827                        .map(move |response| {
 7828                            let lsp_symbols = response
 7829                                .into_response()
 7830                                .context("workspace symbols request")
 7831                                .log_err()
 7832                                .flatten()
 7833                                .map(|symbol_response| match symbol_response {
 7834                                    lsp::WorkspaceSymbolResponse::Flat(flat_responses) => {
 7835                                        flat_responses
 7836                                            .into_iter()
 7837                                            .map(|lsp_symbol| {
 7838                                                (
 7839                                                    lsp_symbol.name,
 7840                                                    lsp_symbol.kind,
 7841                                                    lsp_symbol.location,
 7842                                                )
 7843                                            })
 7844                                            .collect::<Vec<_>>()
 7845                                    }
 7846                                    lsp::WorkspaceSymbolResponse::Nested(nested_responses) => {
 7847                                        nested_responses
 7848                                            .into_iter()
 7849                                            .filter_map(|lsp_symbol| {
 7850                                                let location = match lsp_symbol.location {
 7851                                                    OneOf::Left(location) => location,
 7852                                                    OneOf::Right(_) => {
 7853                                                        log::error!(
 7854                                                            "Unexpected: client capabilities \
 7855                                                            forbid symbol resolutions in \
 7856                                                            workspace.symbol.resolveSupport"
 7857                                                        );
 7858                                                        return None;
 7859                                                    }
 7860                                                };
 7861                                                Some((lsp_symbol.name, lsp_symbol.kind, location))
 7862                                            })
 7863                                            .collect::<Vec<_>>()
 7864                                    }
 7865                                })
 7866                                .unwrap_or_default();
 7867
 7868                            WorkspaceSymbolsResult {
 7869                                server_id,
 7870                                lsp_adapter,
 7871                                worktree: worktree_handle.downgrade(),
 7872                                lsp_symbols,
 7873                            }
 7874                        }),
 7875                );
 7876            }
 7877
 7878            cx.spawn(async move |this, cx| {
 7879                let responses = futures::future::join_all(requests).await;
 7880                let this = match this.upgrade() {
 7881                    Some(this) => this,
 7882                    None => return Ok(Vec::new()),
 7883                };
 7884
 7885                let mut symbols = Vec::new();
 7886                for result in responses {
 7887                    let core_symbols = this.update(cx, |this, cx| {
 7888                        result
 7889                            .lsp_symbols
 7890                            .into_iter()
 7891                            .filter_map(|(symbol_name, symbol_kind, symbol_location)| {
 7892                                let abs_path = symbol_location.uri.to_file_path().ok()?;
 7893                                let source_worktree = result.worktree.upgrade()?;
 7894                                let source_worktree_id = source_worktree.read(cx).id();
 7895
 7896                                let path = if let Some((tree, rel_path)) =
 7897                                    this.worktree_store.read(cx).find_worktree(&abs_path, cx)
 7898                                {
 7899                                    let worktree_id = tree.read(cx).id();
 7900                                    SymbolLocation::InProject(ProjectPath {
 7901                                        worktree_id,
 7902                                        path: rel_path,
 7903                                    })
 7904                                } else {
 7905                                    SymbolLocation::OutsideProject {
 7906                                        signature: this.symbol_signature(&abs_path),
 7907                                        abs_path: abs_path.into(),
 7908                                    }
 7909                                };
 7910
 7911                                Some(CoreSymbol {
 7912                                    source_language_server_id: result.server_id,
 7913                                    language_server_name: result.lsp_adapter.name.clone(),
 7914                                    source_worktree_id,
 7915                                    path,
 7916                                    kind: symbol_kind,
 7917                                    name: symbol_name,
 7918                                    range: range_from_lsp(symbol_location.range),
 7919                                })
 7920                            })
 7921                            .collect::<Vec<_>>()
 7922                    });
 7923
 7924                    populate_labels_for_symbols(
 7925                        core_symbols,
 7926                        &language_registry,
 7927                        Some(result.lsp_adapter),
 7928                        &mut symbols,
 7929                    )
 7930                    .await;
 7931                }
 7932
 7933                Ok(symbols)
 7934            })
 7935        } else {
 7936            Task::ready(Err(anyhow!("No upstream client or local language server")))
 7937        }
 7938    }
 7939
 7940    pub fn diagnostic_summary(&self, include_ignored: bool, cx: &App) -> DiagnosticSummary {
 7941        let mut summary = DiagnosticSummary::default();
 7942        for (_, _, path_summary) in self.diagnostic_summaries(include_ignored, cx) {
 7943            summary.error_count += path_summary.error_count;
 7944            summary.warning_count += path_summary.warning_count;
 7945        }
 7946        summary
 7947    }
 7948
 7949    /// Returns the diagnostic summary for a specific project path.
 7950    pub fn diagnostic_summary_for_path(
 7951        &self,
 7952        project_path: &ProjectPath,
 7953        _: &App,
 7954    ) -> DiagnosticSummary {
 7955        if let Some(summaries) = self
 7956            .diagnostic_summaries
 7957            .get(&project_path.worktree_id)
 7958            .and_then(|map| map.get(&project_path.path))
 7959        {
 7960            let (error_count, warning_count) = summaries.iter().fold(
 7961                (0, 0),
 7962                |(error_count, warning_count), (_language_server_id, summary)| {
 7963                    (
 7964                        error_count + summary.error_count,
 7965                        warning_count + summary.warning_count,
 7966                    )
 7967                },
 7968            );
 7969
 7970            DiagnosticSummary {
 7971                error_count,
 7972                warning_count,
 7973            }
 7974        } else {
 7975            DiagnosticSummary::default()
 7976        }
 7977    }
 7978
 7979    pub fn diagnostic_summaries<'a>(
 7980        &'a self,
 7981        include_ignored: bool,
 7982        cx: &'a App,
 7983    ) -> impl Iterator<Item = (ProjectPath, LanguageServerId, DiagnosticSummary)> + 'a {
 7984        self.worktree_store
 7985            .read(cx)
 7986            .visible_worktrees(cx)
 7987            .filter_map(|worktree| {
 7988                let worktree = worktree.read(cx);
 7989                Some((worktree, self.diagnostic_summaries.get(&worktree.id())?))
 7990            })
 7991            .flat_map(move |(worktree, summaries)| {
 7992                let worktree_id = worktree.id();
 7993                summaries
 7994                    .iter()
 7995                    .filter(move |(path, _)| {
 7996                        include_ignored
 7997                            || worktree
 7998                                .entry_for_path(path.as_ref())
 7999                                .is_some_and(|entry| !entry.is_ignored)
 8000                    })
 8001                    .flat_map(move |(path, summaries)| {
 8002                        summaries.iter().map(move |(server_id, summary)| {
 8003                            (
 8004                                ProjectPath {
 8005                                    worktree_id,
 8006                                    path: path.clone(),
 8007                                },
 8008                                *server_id,
 8009                                *summary,
 8010                            )
 8011                        })
 8012                    })
 8013            })
 8014    }
 8015
 8016    pub fn on_buffer_edited(
 8017        &mut self,
 8018        buffer: Entity<Buffer>,
 8019        cx: &mut Context<Self>,
 8020    ) -> Option<()> {
 8021        let language_servers: Vec<_> = buffer.update(cx, |buffer, cx| {
 8022            Some(
 8023                self.as_local()?
 8024                    .language_servers_for_buffer(buffer, cx)
 8025                    .map(|i| i.1.clone())
 8026                    .collect(),
 8027            )
 8028        })?;
 8029
 8030        let buffer = buffer.read(cx);
 8031        let file = File::from_dyn(buffer.file())?;
 8032        let abs_path = file.as_local()?.abs_path(cx);
 8033        let uri = lsp::Uri::from_file_path(&abs_path)
 8034            .ok()
 8035            .with_context(|| format!("Failed to convert path to URI: {}", abs_path.display()))
 8036            .log_err()?;
 8037        let next_snapshot = buffer.text_snapshot();
 8038        for language_server in language_servers {
 8039            let language_server = language_server.clone();
 8040
 8041            let buffer_snapshots = self
 8042                .as_local_mut()?
 8043                .buffer_snapshots
 8044                .get_mut(&buffer.remote_id())
 8045                .and_then(|m| m.get_mut(&language_server.server_id()))?;
 8046            let previous_snapshot = buffer_snapshots.last()?;
 8047
 8048            let build_incremental_change = || {
 8049                buffer
 8050                    .edits_since::<Dimensions<PointUtf16, usize>>(
 8051                        previous_snapshot.snapshot.version(),
 8052                    )
 8053                    .map(|edit| {
 8054                        let edit_start = edit.new.start.0;
 8055                        let edit_end = edit_start + (edit.old.end.0 - edit.old.start.0);
 8056                        let new_text = next_snapshot
 8057                            .text_for_range(edit.new.start.1..edit.new.end.1)
 8058                            .collect();
 8059                        lsp::TextDocumentContentChangeEvent {
 8060                            range: Some(lsp::Range::new(
 8061                                point_to_lsp(edit_start),
 8062                                point_to_lsp(edit_end),
 8063                            )),
 8064                            range_length: None,
 8065                            text: new_text,
 8066                        }
 8067                    })
 8068                    .collect()
 8069            };
 8070
 8071            let document_sync_kind = language_server
 8072                .capabilities()
 8073                .text_document_sync
 8074                .as_ref()
 8075                .and_then(|sync| match sync {
 8076                    lsp::TextDocumentSyncCapability::Kind(kind) => Some(*kind),
 8077                    lsp::TextDocumentSyncCapability::Options(options) => options.change,
 8078                });
 8079
 8080            let content_changes: Vec<_> = match document_sync_kind {
 8081                Some(lsp::TextDocumentSyncKind::FULL) => {
 8082                    vec![lsp::TextDocumentContentChangeEvent {
 8083                        range: None,
 8084                        range_length: None,
 8085                        text: next_snapshot.text(),
 8086                    }]
 8087                }
 8088                Some(lsp::TextDocumentSyncKind::INCREMENTAL) => build_incremental_change(),
 8089                _ => {
 8090                    #[cfg(any(test, feature = "test-support"))]
 8091                    {
 8092                        build_incremental_change()
 8093                    }
 8094
 8095                    #[cfg(not(any(test, feature = "test-support")))]
 8096                    {
 8097                        continue;
 8098                    }
 8099                }
 8100            };
 8101
 8102            let next_version = previous_snapshot.version + 1;
 8103            buffer_snapshots.push(LspBufferSnapshot {
 8104                version: next_version,
 8105                snapshot: next_snapshot.clone(),
 8106            });
 8107
 8108            language_server
 8109                .notify::<lsp::notification::DidChangeTextDocument>(
 8110                    lsp::DidChangeTextDocumentParams {
 8111                        text_document: lsp::VersionedTextDocumentIdentifier::new(
 8112                            uri.clone(),
 8113                            next_version,
 8114                        ),
 8115                        content_changes,
 8116                    },
 8117                )
 8118                .ok();
 8119            self.pull_workspace_diagnostics(language_server.server_id());
 8120        }
 8121
 8122        None
 8123    }
 8124
 8125    pub fn on_buffer_saved(
 8126        &mut self,
 8127        buffer: Entity<Buffer>,
 8128        cx: &mut Context<Self>,
 8129    ) -> Option<()> {
 8130        let file = File::from_dyn(buffer.read(cx).file())?;
 8131        let worktree_id = file.worktree_id(cx);
 8132        let abs_path = file.as_local()?.abs_path(cx);
 8133        let text_document = lsp::TextDocumentIdentifier {
 8134            uri: file_path_to_lsp_url(&abs_path).log_err()?,
 8135        };
 8136        let local = self.as_local()?;
 8137
 8138        for server in local.language_servers_for_worktree(worktree_id) {
 8139            if let Some(include_text) = include_text(server.as_ref()) {
 8140                let text = if include_text {
 8141                    Some(buffer.read(cx).text())
 8142                } else {
 8143                    None
 8144                };
 8145                server
 8146                    .notify::<lsp::notification::DidSaveTextDocument>(
 8147                        lsp::DidSaveTextDocumentParams {
 8148                            text_document: text_document.clone(),
 8149                            text,
 8150                        },
 8151                    )
 8152                    .ok();
 8153            }
 8154        }
 8155
 8156        let language_servers = buffer.update(cx, |buffer, cx| {
 8157            local.language_server_ids_for_buffer(buffer, cx)
 8158        });
 8159        for language_server_id in language_servers {
 8160            self.simulate_disk_based_diagnostics_events_if_needed(language_server_id, cx);
 8161        }
 8162
 8163        None
 8164    }
 8165
 8166    async fn refresh_workspace_configurations(lsp_store: &WeakEntity<Self>, cx: &mut AsyncApp) {
 8167        maybe!(async move {
 8168            let mut refreshed_servers = HashSet::default();
 8169            let servers = lsp_store
 8170                .update(cx, |lsp_store, cx| {
 8171                    let local = lsp_store.as_local()?;
 8172
 8173                    let servers = local
 8174                        .language_server_ids
 8175                        .iter()
 8176                        .filter_map(|(seed, state)| {
 8177                            let worktree = lsp_store
 8178                                .worktree_store
 8179                                .read(cx)
 8180                                .worktree_for_id(seed.worktree_id, cx);
 8181                            let delegate: Arc<dyn LspAdapterDelegate> =
 8182                                worktree.map(|worktree| {
 8183                                    LocalLspAdapterDelegate::new(
 8184                                        local.languages.clone(),
 8185                                        &local.environment,
 8186                                        cx.weak_entity(),
 8187                                        &worktree,
 8188                                        local.http_client.clone(),
 8189                                        local.fs.clone(),
 8190                                        cx,
 8191                                    )
 8192                                })?;
 8193                            let server_id = state.id;
 8194
 8195                            let states = local.language_servers.get(&server_id)?;
 8196
 8197                            match states {
 8198                                LanguageServerState::Starting { .. } => None,
 8199                                LanguageServerState::Running {
 8200                                    adapter, server, ..
 8201                                } => {
 8202                                    let adapter = adapter.clone();
 8203                                    let server = server.clone();
 8204                                    refreshed_servers.insert(server.name());
 8205                                    let toolchain = seed.toolchain.clone();
 8206                                    Some(cx.spawn(async move |_, cx| {
 8207                                        let settings =
 8208                                            LocalLspStore::workspace_configuration_for_adapter(
 8209                                                adapter.adapter.clone(),
 8210                                                &delegate,
 8211                                                toolchain,
 8212                                                None,
 8213                                                cx,
 8214                                            )
 8215                                            .await
 8216                                            .ok()?;
 8217                                        server
 8218                                            .notify::<lsp::notification::DidChangeConfiguration>(
 8219                                                lsp::DidChangeConfigurationParams { settings },
 8220                                            )
 8221                                            .ok()?;
 8222                                        Some(())
 8223                                    }))
 8224                                }
 8225                            }
 8226                        })
 8227                        .collect::<Vec<_>>();
 8228
 8229                    Some(servers)
 8230                })
 8231                .ok()
 8232                .flatten()?;
 8233
 8234            log::debug!("Refreshing workspace configurations for servers {refreshed_servers:?}");
 8235            // TODO this asynchronous job runs concurrently with extension (de)registration and may take enough time for a certain extension
 8236            // to stop and unregister its language server wrapper.
 8237            // This is racy : an extension might have already removed all `local.language_servers` state, but here we `.clone()` and hold onto it anyway.
 8238            // This now causes errors in the logs, we should find a way to remove such servers from the processing everywhere.
 8239            let _: Vec<Option<()>> = join_all(servers).await;
 8240
 8241            Some(())
 8242        })
 8243        .await;
 8244    }
 8245
 8246    fn maintain_workspace_config(
 8247        external_refresh_requests: watch::Receiver<()>,
 8248        cx: &mut Context<Self>,
 8249    ) -> Task<Result<()>> {
 8250        let (mut settings_changed_tx, mut settings_changed_rx) = watch::channel();
 8251        let _ = postage::stream::Stream::try_recv(&mut settings_changed_rx);
 8252
 8253        let settings_observation = cx.observe_global::<SettingsStore>(move |_, _| {
 8254            *settings_changed_tx.borrow_mut() = ();
 8255        });
 8256
 8257        let mut joint_future =
 8258            futures::stream::select(settings_changed_rx, external_refresh_requests);
 8259        // Multiple things can happen when a workspace environment (selected toolchain + settings) change:
 8260        // - 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).
 8261        // - 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.
 8262        // - In the same vein, we might also decide to start a new language server if the workspace configuration *diverges* from the other.
 8263        // - 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,
 8264        // but it is still different to what we had before, we're gonna send out a workspace configuration update.
 8265        cx.spawn(async move |this, cx| {
 8266            while let Some(()) = joint_future.next().await {
 8267                this.update(cx, |this, cx| {
 8268                    this.refresh_server_tree(cx);
 8269                })
 8270                .ok();
 8271
 8272                Self::refresh_workspace_configurations(&this, cx).await;
 8273            }
 8274
 8275            drop(settings_observation);
 8276            anyhow::Ok(())
 8277        })
 8278    }
 8279
 8280    pub fn running_language_servers_for_local_buffer<'a>(
 8281        &'a self,
 8282        buffer: &Buffer,
 8283        cx: &mut App,
 8284    ) -> impl Iterator<Item = (&'a Arc<CachedLspAdapter>, &'a Arc<LanguageServer>)> {
 8285        let local = self.as_local();
 8286        let language_server_ids = local
 8287            .map(|local| local.language_server_ids_for_buffer(buffer, cx))
 8288            .unwrap_or_default();
 8289
 8290        language_server_ids
 8291            .into_iter()
 8292            .filter_map(
 8293                move |server_id| match local?.language_servers.get(&server_id)? {
 8294                    LanguageServerState::Running {
 8295                        adapter, server, ..
 8296                    } => Some((adapter, server)),
 8297                    _ => None,
 8298                },
 8299            )
 8300    }
 8301
 8302    pub fn language_servers_for_local_buffer(
 8303        &self,
 8304        buffer: &Buffer,
 8305        cx: &mut App,
 8306    ) -> Vec<LanguageServerId> {
 8307        let local = self.as_local();
 8308        local
 8309            .map(|local| local.language_server_ids_for_buffer(buffer, cx))
 8310            .unwrap_or_default()
 8311    }
 8312
 8313    pub fn language_server_for_local_buffer<'a>(
 8314        &'a self,
 8315        buffer: &'a Buffer,
 8316        server_id: LanguageServerId,
 8317        cx: &'a mut App,
 8318    ) -> Option<(&'a Arc<CachedLspAdapter>, &'a Arc<LanguageServer>)> {
 8319        self.as_local()?
 8320            .language_servers_for_buffer(buffer, cx)
 8321            .find(|(_, s)| s.server_id() == server_id)
 8322    }
 8323
 8324    fn remove_worktree(&mut self, id_to_remove: WorktreeId, cx: &mut Context<Self>) {
 8325        self.diagnostic_summaries.remove(&id_to_remove);
 8326        if let Some(local) = self.as_local_mut() {
 8327            let to_remove = local.remove_worktree(id_to_remove, cx);
 8328            for server in to_remove {
 8329                self.language_server_statuses.remove(&server);
 8330            }
 8331        }
 8332    }
 8333
 8334    pub fn shared(
 8335        &mut self,
 8336        project_id: u64,
 8337        downstream_client: AnyProtoClient,
 8338        _: &mut Context<Self>,
 8339    ) {
 8340        self.downstream_client = Some((downstream_client.clone(), project_id));
 8341
 8342        for (server_id, status) in &self.language_server_statuses {
 8343            if let Some(server) = self.language_server_for_id(*server_id) {
 8344                downstream_client
 8345                    .send(proto::StartLanguageServer {
 8346                        project_id,
 8347                        server: Some(proto::LanguageServer {
 8348                            id: server_id.to_proto(),
 8349                            name: status.name.to_string(),
 8350                            worktree_id: status.worktree.map(|id| id.to_proto()),
 8351                        }),
 8352                        capabilities: serde_json::to_string(&server.capabilities())
 8353                            .expect("serializing server LSP capabilities"),
 8354                    })
 8355                    .log_err();
 8356            }
 8357        }
 8358    }
 8359
 8360    pub fn disconnected_from_host(&mut self) {
 8361        self.downstream_client.take();
 8362    }
 8363
 8364    pub fn disconnected_from_ssh_remote(&mut self) {
 8365        if let LspStoreMode::Remote(RemoteLspStore {
 8366            upstream_client, ..
 8367        }) = &mut self.mode
 8368        {
 8369            upstream_client.take();
 8370        }
 8371    }
 8372
 8373    pub(crate) fn set_language_server_statuses_from_proto(
 8374        &mut self,
 8375        project: WeakEntity<Project>,
 8376        language_servers: Vec<proto::LanguageServer>,
 8377        server_capabilities: Vec<String>,
 8378        cx: &mut Context<Self>,
 8379    ) {
 8380        let lsp_logs = cx
 8381            .try_global::<GlobalLogStore>()
 8382            .map(|lsp_store| lsp_store.0.clone());
 8383
 8384        self.language_server_statuses = language_servers
 8385            .into_iter()
 8386            .zip(server_capabilities)
 8387            .map(|(server, server_capabilities)| {
 8388                let server_id = LanguageServerId(server.id as usize);
 8389                if let Ok(server_capabilities) = serde_json::from_str(&server_capabilities) {
 8390                    self.lsp_server_capabilities
 8391                        .insert(server_id, server_capabilities);
 8392                }
 8393
 8394                let name = LanguageServerName::from_proto(server.name);
 8395                let worktree = server.worktree_id.map(WorktreeId::from_proto);
 8396
 8397                if let Some(lsp_logs) = &lsp_logs {
 8398                    lsp_logs.update(cx, |lsp_logs, cx| {
 8399                        lsp_logs.add_language_server(
 8400                            // Only remote clients get their language servers set from proto
 8401                            LanguageServerKind::Remote {
 8402                                project: project.clone(),
 8403                            },
 8404                            server_id,
 8405                            Some(name.clone()),
 8406                            worktree,
 8407                            None,
 8408                            cx,
 8409                        );
 8410                    });
 8411                }
 8412
 8413                (
 8414                    server_id,
 8415                    LanguageServerStatus {
 8416                        name,
 8417                        server_version: None,
 8418                        pending_work: Default::default(),
 8419                        has_pending_diagnostic_updates: false,
 8420                        progress_tokens: Default::default(),
 8421                        worktree,
 8422                        binary: None,
 8423                        configuration: None,
 8424                        workspace_folders: BTreeSet::new(),
 8425                    },
 8426                )
 8427            })
 8428            .collect();
 8429    }
 8430
 8431    #[cfg(test)]
 8432    pub fn update_diagnostic_entries(
 8433        &mut self,
 8434        server_id: LanguageServerId,
 8435        abs_path: PathBuf,
 8436        result_id: Option<SharedString>,
 8437        version: Option<i32>,
 8438        diagnostics: Vec<DiagnosticEntry<Unclipped<PointUtf16>>>,
 8439        cx: &mut Context<Self>,
 8440    ) -> anyhow::Result<()> {
 8441        self.merge_diagnostic_entries(
 8442            vec![DocumentDiagnosticsUpdate {
 8443                diagnostics: DocumentDiagnostics {
 8444                    diagnostics,
 8445                    document_abs_path: abs_path,
 8446                    version,
 8447                },
 8448                result_id,
 8449                server_id,
 8450                disk_based_sources: Cow::Borrowed(&[]),
 8451                registration_id: None,
 8452            }],
 8453            |_, _, _| false,
 8454            cx,
 8455        )?;
 8456        Ok(())
 8457    }
 8458
 8459    pub fn merge_diagnostic_entries<'a>(
 8460        &mut self,
 8461        diagnostic_updates: Vec<DocumentDiagnosticsUpdate<'a, DocumentDiagnostics>>,
 8462        merge: impl Fn(&lsp::Uri, &Diagnostic, &App) -> bool + Clone,
 8463        cx: &mut Context<Self>,
 8464    ) -> anyhow::Result<()> {
 8465        let mut diagnostics_summary = None::<proto::UpdateDiagnosticSummary>;
 8466        let mut updated_diagnostics_paths = HashMap::default();
 8467        for mut update in diagnostic_updates {
 8468            let abs_path = &update.diagnostics.document_abs_path;
 8469            let server_id = update.server_id;
 8470            let Some((worktree, relative_path)) =
 8471                self.worktree_store.read(cx).find_worktree(abs_path, cx)
 8472            else {
 8473                log::warn!("skipping diagnostics update, no worktree found for path {abs_path:?}");
 8474                return Ok(());
 8475            };
 8476
 8477            let worktree_id = worktree.read(cx).id();
 8478            let project_path = ProjectPath {
 8479                worktree_id,
 8480                path: relative_path,
 8481            };
 8482
 8483            let document_uri = lsp::Uri::from_file_path(abs_path)
 8484                .map_err(|()| anyhow!("Failed to convert buffer path {abs_path:?} to lsp Uri"))?;
 8485            if let Some(buffer_handle) = self.buffer_store.read(cx).get_by_path(&project_path) {
 8486                let snapshot = buffer_handle.read(cx).snapshot();
 8487                let buffer = buffer_handle.read(cx);
 8488                let reused_diagnostics = buffer
 8489                    .buffer_diagnostics(Some(server_id))
 8490                    .iter()
 8491                    .filter(|v| merge(&document_uri, &v.diagnostic, cx))
 8492                    .map(|v| {
 8493                        let start = Unclipped(v.range.start.to_point_utf16(&snapshot));
 8494                        let end = Unclipped(v.range.end.to_point_utf16(&snapshot));
 8495                        DiagnosticEntry {
 8496                            range: start..end,
 8497                            diagnostic: v.diagnostic.clone(),
 8498                        }
 8499                    })
 8500                    .collect::<Vec<_>>();
 8501
 8502                self.as_local_mut()
 8503                    .context("cannot merge diagnostics on a remote LspStore")?
 8504                    .update_buffer_diagnostics(
 8505                        &buffer_handle,
 8506                        server_id,
 8507                        Some(update.registration_id),
 8508                        update.result_id,
 8509                        update.diagnostics.version,
 8510                        update.diagnostics.diagnostics.clone(),
 8511                        reused_diagnostics.clone(),
 8512                        cx,
 8513                    )?;
 8514
 8515                update.diagnostics.diagnostics.extend(reused_diagnostics);
 8516            } else if let Some(local) = self.as_local() {
 8517                let reused_diagnostics = local
 8518                    .diagnostics
 8519                    .get(&worktree_id)
 8520                    .and_then(|diagnostics_for_tree| diagnostics_for_tree.get(&project_path.path))
 8521                    .and_then(|diagnostics_by_server_id| {
 8522                        diagnostics_by_server_id
 8523                            .binary_search_by_key(&server_id, |e| e.0)
 8524                            .ok()
 8525                            .map(|ix| &diagnostics_by_server_id[ix].1)
 8526                    })
 8527                    .into_iter()
 8528                    .flatten()
 8529                    .filter(|v| merge(&document_uri, &v.diagnostic, cx));
 8530
 8531                update
 8532                    .diagnostics
 8533                    .diagnostics
 8534                    .extend(reused_diagnostics.cloned());
 8535            }
 8536
 8537            let updated = worktree.update(cx, |worktree, cx| {
 8538                self.update_worktree_diagnostics(
 8539                    worktree.id(),
 8540                    server_id,
 8541                    project_path.path.clone(),
 8542                    update.diagnostics.diagnostics,
 8543                    cx,
 8544                )
 8545            })?;
 8546            match updated {
 8547                ControlFlow::Continue(new_summary) => {
 8548                    if let Some((project_id, new_summary)) = new_summary {
 8549                        match &mut diagnostics_summary {
 8550                            Some(diagnostics_summary) => {
 8551                                diagnostics_summary
 8552                                    .more_summaries
 8553                                    .push(proto::DiagnosticSummary {
 8554                                        path: project_path.path.as_ref().to_proto(),
 8555                                        language_server_id: server_id.0 as u64,
 8556                                        error_count: new_summary.error_count,
 8557                                        warning_count: new_summary.warning_count,
 8558                                    })
 8559                            }
 8560                            None => {
 8561                                diagnostics_summary = Some(proto::UpdateDiagnosticSummary {
 8562                                    project_id,
 8563                                    worktree_id: worktree_id.to_proto(),
 8564                                    summary: Some(proto::DiagnosticSummary {
 8565                                        path: project_path.path.as_ref().to_proto(),
 8566                                        language_server_id: server_id.0 as u64,
 8567                                        error_count: new_summary.error_count,
 8568                                        warning_count: new_summary.warning_count,
 8569                                    }),
 8570                                    more_summaries: Vec::new(),
 8571                                })
 8572                            }
 8573                        }
 8574                    }
 8575                    updated_diagnostics_paths
 8576                        .entry(server_id)
 8577                        .or_insert_with(Vec::new)
 8578                        .push(project_path);
 8579                }
 8580                ControlFlow::Break(()) => {}
 8581            }
 8582        }
 8583
 8584        if let Some((diagnostics_summary, (downstream_client, _))) =
 8585            diagnostics_summary.zip(self.downstream_client.as_ref())
 8586        {
 8587            downstream_client.send(diagnostics_summary).log_err();
 8588        }
 8589        for (server_id, paths) in updated_diagnostics_paths {
 8590            cx.emit(LspStoreEvent::DiagnosticsUpdated { server_id, paths });
 8591        }
 8592        Ok(())
 8593    }
 8594
 8595    fn update_worktree_diagnostics(
 8596        &mut self,
 8597        worktree_id: WorktreeId,
 8598        server_id: LanguageServerId,
 8599        path_in_worktree: Arc<RelPath>,
 8600        diagnostics: Vec<DiagnosticEntry<Unclipped<PointUtf16>>>,
 8601        _: &mut Context<Worktree>,
 8602    ) -> Result<ControlFlow<(), Option<(u64, proto::DiagnosticSummary)>>> {
 8603        let local = match &mut self.mode {
 8604            LspStoreMode::Local(local_lsp_store) => local_lsp_store,
 8605            _ => anyhow::bail!("update_worktree_diagnostics called on remote"),
 8606        };
 8607
 8608        let summaries_for_tree = self.diagnostic_summaries.entry(worktree_id).or_default();
 8609        let diagnostics_for_tree = local.diagnostics.entry(worktree_id).or_default();
 8610        let summaries_by_server_id = summaries_for_tree
 8611            .entry(path_in_worktree.clone())
 8612            .or_default();
 8613
 8614        let old_summary = summaries_by_server_id
 8615            .remove(&server_id)
 8616            .unwrap_or_default();
 8617
 8618        let new_summary = DiagnosticSummary::new(&diagnostics);
 8619        if diagnostics.is_empty() {
 8620            if let Some(diagnostics_by_server_id) = diagnostics_for_tree.get_mut(&path_in_worktree)
 8621            {
 8622                if let Ok(ix) = diagnostics_by_server_id.binary_search_by_key(&server_id, |e| e.0) {
 8623                    diagnostics_by_server_id.remove(ix);
 8624                }
 8625                if diagnostics_by_server_id.is_empty() {
 8626                    diagnostics_for_tree.remove(&path_in_worktree);
 8627                }
 8628            }
 8629        } else {
 8630            summaries_by_server_id.insert(server_id, new_summary);
 8631            let diagnostics_by_server_id = diagnostics_for_tree
 8632                .entry(path_in_worktree.clone())
 8633                .or_default();
 8634            match diagnostics_by_server_id.binary_search_by_key(&server_id, |e| e.0) {
 8635                Ok(ix) => {
 8636                    diagnostics_by_server_id[ix] = (server_id, diagnostics);
 8637                }
 8638                Err(ix) => {
 8639                    diagnostics_by_server_id.insert(ix, (server_id, diagnostics));
 8640                }
 8641            }
 8642        }
 8643
 8644        if !old_summary.is_empty() || !new_summary.is_empty() {
 8645            if let Some((_, project_id)) = &self.downstream_client {
 8646                Ok(ControlFlow::Continue(Some((
 8647                    *project_id,
 8648                    proto::DiagnosticSummary {
 8649                        path: path_in_worktree.to_proto(),
 8650                        language_server_id: server_id.0 as u64,
 8651                        error_count: new_summary.error_count as u32,
 8652                        warning_count: new_summary.warning_count as u32,
 8653                    },
 8654                ))))
 8655            } else {
 8656                Ok(ControlFlow::Continue(None))
 8657            }
 8658        } else {
 8659            Ok(ControlFlow::Break(()))
 8660        }
 8661    }
 8662
 8663    pub fn open_buffer_for_symbol(
 8664        &mut self,
 8665        symbol: &Symbol,
 8666        cx: &mut Context<Self>,
 8667    ) -> Task<Result<Entity<Buffer>>> {
 8668        if let Some((client, project_id)) = self.upstream_client() {
 8669            let request = client.request(proto::OpenBufferForSymbol {
 8670                project_id,
 8671                symbol: Some(Self::serialize_symbol(symbol)),
 8672            });
 8673            cx.spawn(async move |this, cx| {
 8674                let response = request.await?;
 8675                let buffer_id = BufferId::new(response.buffer_id)?;
 8676                this.update(cx, |this, cx| this.wait_for_remote_buffer(buffer_id, cx))?
 8677                    .await
 8678            })
 8679        } else if let Some(local) = self.as_local() {
 8680            let is_valid = local.language_server_ids.iter().any(|(seed, state)| {
 8681                seed.worktree_id == symbol.source_worktree_id
 8682                    && state.id == symbol.source_language_server_id
 8683                    && symbol.language_server_name == seed.name
 8684            });
 8685            if !is_valid {
 8686                return Task::ready(Err(anyhow!(
 8687                    "language server for worktree and language not found"
 8688                )));
 8689            };
 8690
 8691            let symbol_abs_path = match &symbol.path {
 8692                SymbolLocation::InProject(project_path) => self
 8693                    .worktree_store
 8694                    .read(cx)
 8695                    .absolutize(&project_path, cx)
 8696                    .context("no such worktree"),
 8697                SymbolLocation::OutsideProject {
 8698                    abs_path,
 8699                    signature: _,
 8700                } => Ok(abs_path.to_path_buf()),
 8701            };
 8702            let symbol_abs_path = match symbol_abs_path {
 8703                Ok(abs_path) => abs_path,
 8704                Err(err) => return Task::ready(Err(err)),
 8705            };
 8706            let symbol_uri = if let Ok(uri) = lsp::Uri::from_file_path(symbol_abs_path) {
 8707                uri
 8708            } else {
 8709                return Task::ready(Err(anyhow!("invalid symbol path")));
 8710            };
 8711
 8712            self.open_local_buffer_via_lsp(symbol_uri, symbol.source_language_server_id, cx)
 8713        } else {
 8714            Task::ready(Err(anyhow!("no upstream client or local store")))
 8715        }
 8716    }
 8717
 8718    pub(crate) fn open_local_buffer_via_lsp(
 8719        &mut self,
 8720        abs_path: lsp::Uri,
 8721        language_server_id: LanguageServerId,
 8722        cx: &mut Context<Self>,
 8723    ) -> Task<Result<Entity<Buffer>>> {
 8724        cx.spawn(async move |lsp_store, cx| {
 8725            // Escape percent-encoded string.
 8726            let current_scheme = abs_path.scheme().to_owned();
 8727            // Uri is immutable, so we can't modify the scheme
 8728
 8729            let abs_path = abs_path
 8730                .to_file_path()
 8731                .map_err(|()| anyhow!("can't convert URI to path"))?;
 8732            let p = abs_path.clone();
 8733            let yarn_worktree = lsp_store
 8734                .update(cx, move |lsp_store, cx| match lsp_store.as_local() {
 8735                    Some(local_lsp_store) => local_lsp_store.yarn.update(cx, |_, cx| {
 8736                        cx.spawn(async move |this, cx| {
 8737                            let t = this
 8738                                .update(cx, |this, cx| this.process_path(&p, &current_scheme, cx))
 8739                                .ok()?;
 8740                            t.await
 8741                        })
 8742                    }),
 8743                    None => Task::ready(None),
 8744                })?
 8745                .await;
 8746            let (worktree_root_target, known_relative_path) =
 8747                if let Some((zip_root, relative_path)) = yarn_worktree {
 8748                    (zip_root, Some(relative_path))
 8749                } else {
 8750                    (Arc::<Path>::from(abs_path.as_path()), None)
 8751                };
 8752            let worktree = lsp_store.update(cx, |lsp_store, cx| {
 8753                lsp_store.worktree_store.update(cx, |worktree_store, cx| {
 8754                    worktree_store.find_worktree(&worktree_root_target, cx)
 8755                })
 8756            })?;
 8757            let (worktree, relative_path, source_ws) = if let Some(result) = worktree {
 8758                let relative_path = known_relative_path.unwrap_or_else(|| result.1.clone());
 8759                (result.0, relative_path, None)
 8760            } else {
 8761                let worktree = lsp_store
 8762                    .update(cx, |lsp_store, cx| {
 8763                        lsp_store.worktree_store.update(cx, |worktree_store, cx| {
 8764                            worktree_store.create_worktree(&worktree_root_target, false, cx)
 8765                        })
 8766                    })?
 8767                    .await?;
 8768                let worktree_root = worktree.read_with(cx, |worktree, _| worktree.abs_path());
 8769                let source_ws = if worktree.read_with(cx, |worktree, _| worktree.is_local()) {
 8770                    lsp_store
 8771                        .update(cx, |lsp_store, cx| {
 8772                            if let Some(local) = lsp_store.as_local_mut() {
 8773                                local.register_language_server_for_invisible_worktree(
 8774                                    &worktree,
 8775                                    language_server_id,
 8776                                    cx,
 8777                                )
 8778                            }
 8779                            match lsp_store.language_server_statuses.get(&language_server_id) {
 8780                                Some(status) => status.worktree,
 8781                                None => None,
 8782                            }
 8783                        })
 8784                        .ok()
 8785                        .flatten()
 8786                        .zip(Some(worktree_root.clone()))
 8787                } else {
 8788                    None
 8789                };
 8790                let relative_path = if let Some(known_path) = known_relative_path {
 8791                    known_path
 8792                } else {
 8793                    RelPath::new(abs_path.strip_prefix(worktree_root)?, PathStyle::local())?
 8794                        .into_arc()
 8795                };
 8796                (worktree, relative_path, source_ws)
 8797            };
 8798            let project_path = ProjectPath {
 8799                worktree_id: worktree.read_with(cx, |worktree, _| worktree.id()),
 8800                path: relative_path,
 8801            };
 8802            let buffer = lsp_store
 8803                .update(cx, |lsp_store, cx| {
 8804                    lsp_store.buffer_store().update(cx, |buffer_store, cx| {
 8805                        buffer_store.open_buffer(project_path, cx)
 8806                    })
 8807                })?
 8808                .await?;
 8809            // we want to adhere to the read-only settings of the worktree we came from in case we opened an invisible one
 8810            if let Some((source_ws, worktree_root)) = source_ws {
 8811                buffer.update(cx, |buffer, cx| {
 8812                    let settings = WorktreeSettings::get(
 8813                        Some(
 8814                            (&ProjectPath {
 8815                                worktree_id: source_ws,
 8816                                path: Arc::from(RelPath::empty()),
 8817                            })
 8818                                .into(),
 8819                        ),
 8820                        cx,
 8821                    );
 8822                    let is_read_only = settings.is_std_path_read_only(&worktree_root);
 8823                    if is_read_only {
 8824                        buffer.set_capability(Capability::ReadOnly, cx);
 8825                    }
 8826                });
 8827            }
 8828            Ok(buffer)
 8829        })
 8830    }
 8831
 8832    fn request_multiple_lsp_locally<P, R>(
 8833        &mut self,
 8834        buffer: &Entity<Buffer>,
 8835        position: Option<P>,
 8836        request: R,
 8837        cx: &mut Context<Self>,
 8838    ) -> Task<Vec<(LanguageServerId, R::Response)>>
 8839    where
 8840        P: ToOffset,
 8841        R: LspCommand + Clone,
 8842        <R::LspRequest as lsp::request::Request>::Result: Send,
 8843        <R::LspRequest as lsp::request::Request>::Params: Send,
 8844    {
 8845        let Some(local) = self.as_local() else {
 8846            return Task::ready(Vec::new());
 8847        };
 8848
 8849        let snapshot = buffer.read(cx).snapshot();
 8850        let scope = position.and_then(|position| snapshot.language_scope_at(position));
 8851
 8852        let server_ids = buffer.update(cx, |buffer, cx| {
 8853            local
 8854                .language_servers_for_buffer(buffer, cx)
 8855                .filter(|(adapter, _)| {
 8856                    scope
 8857                        .as_ref()
 8858                        .map(|scope| scope.language_allowed(&adapter.name))
 8859                        .unwrap_or(true)
 8860                })
 8861                .map(|(_, server)| server.server_id())
 8862                .filter(|server_id| {
 8863                    self.as_local().is_none_or(|local| {
 8864                        local
 8865                            .buffers_opened_in_servers
 8866                            .get(&snapshot.remote_id())
 8867                            .is_some_and(|servers| servers.contains(server_id))
 8868                    })
 8869                })
 8870                .collect::<Vec<_>>()
 8871        });
 8872
 8873        let mut response_results = server_ids
 8874            .into_iter()
 8875            .map(|server_id| {
 8876                let task = self.request_lsp(
 8877                    buffer.clone(),
 8878                    LanguageServerToQuery::Other(server_id),
 8879                    request.clone(),
 8880                    cx,
 8881                );
 8882                async move { (server_id, task.await) }
 8883            })
 8884            .collect::<FuturesUnordered<_>>();
 8885
 8886        cx.background_spawn(async move {
 8887            let mut responses = Vec::with_capacity(response_results.len());
 8888            while let Some((server_id, response_result)) = response_results.next().await {
 8889                match response_result {
 8890                    Ok(response) => responses.push((server_id, response)),
 8891                    // rust-analyzer likes to error with this when its still loading up
 8892                    Err(e) if format!("{e:#}").ends_with("content modified") => (),
 8893                    Err(e) => log::error!("Error handling response for request {request:?}: {e:#}"),
 8894                }
 8895            }
 8896            responses
 8897        })
 8898    }
 8899
 8900    async fn handle_lsp_get_completions(
 8901        this: Entity<Self>,
 8902        envelope: TypedEnvelope<proto::GetCompletions>,
 8903        mut cx: AsyncApp,
 8904    ) -> Result<proto::GetCompletionsResponse> {
 8905        let sender_id = envelope.original_sender_id().unwrap_or_default();
 8906
 8907        let buffer_id = GetCompletions::buffer_id_from_proto(&envelope.payload)?;
 8908        let buffer_handle = this.update(&mut cx, |this, cx| {
 8909            this.buffer_store.read(cx).get_existing(buffer_id)
 8910        })?;
 8911        let request = GetCompletions::from_proto(
 8912            envelope.payload,
 8913            this.clone(),
 8914            buffer_handle.clone(),
 8915            cx.clone(),
 8916        )
 8917        .await?;
 8918
 8919        let server_to_query = match request.server_id {
 8920            Some(server_id) => LanguageServerToQuery::Other(server_id),
 8921            None => LanguageServerToQuery::FirstCapable,
 8922        };
 8923
 8924        let response = this
 8925            .update(&mut cx, |this, cx| {
 8926                this.request_lsp(buffer_handle.clone(), server_to_query, request, cx)
 8927            })
 8928            .await?;
 8929        this.update(&mut cx, |this, cx| {
 8930            Ok(GetCompletions::response_to_proto(
 8931                response,
 8932                this,
 8933                sender_id,
 8934                &buffer_handle.read(cx).version(),
 8935                cx,
 8936            ))
 8937        })
 8938    }
 8939
 8940    async fn handle_lsp_command<T: LspCommand>(
 8941        this: Entity<Self>,
 8942        envelope: TypedEnvelope<T::ProtoRequest>,
 8943        mut cx: AsyncApp,
 8944    ) -> Result<<T::ProtoRequest as proto::RequestMessage>::Response>
 8945    where
 8946        <T::LspRequest as lsp::request::Request>::Params: Send,
 8947        <T::LspRequest as lsp::request::Request>::Result: Send,
 8948    {
 8949        let sender_id = envelope.original_sender_id().unwrap_or_default();
 8950        let buffer_id = T::buffer_id_from_proto(&envelope.payload)?;
 8951        let buffer_handle = this.update(&mut cx, |this, cx| {
 8952            this.buffer_store.read(cx).get_existing(buffer_id)
 8953        })?;
 8954        let request = T::from_proto(
 8955            envelope.payload,
 8956            this.clone(),
 8957            buffer_handle.clone(),
 8958            cx.clone(),
 8959        )
 8960        .await?;
 8961        let response = this
 8962            .update(&mut cx, |this, cx| {
 8963                this.request_lsp(
 8964                    buffer_handle.clone(),
 8965                    LanguageServerToQuery::FirstCapable,
 8966                    request,
 8967                    cx,
 8968                )
 8969            })
 8970            .await?;
 8971        this.update(&mut cx, |this, cx| {
 8972            Ok(T::response_to_proto(
 8973                response,
 8974                this,
 8975                sender_id,
 8976                &buffer_handle.read(cx).version(),
 8977                cx,
 8978            ))
 8979        })
 8980    }
 8981
 8982    async fn handle_lsp_query(
 8983        lsp_store: Entity<Self>,
 8984        envelope: TypedEnvelope<proto::LspQuery>,
 8985        mut cx: AsyncApp,
 8986    ) -> Result<proto::Ack> {
 8987        use proto::lsp_query::Request;
 8988        let sender_id = envelope.original_sender_id().unwrap_or_default();
 8989        let lsp_query = envelope.payload;
 8990        let lsp_request_id = LspRequestId(lsp_query.lsp_request_id);
 8991        let server_id = lsp_query.server_id.map(LanguageServerId::from_proto);
 8992        match lsp_query.request.context("invalid LSP query request")? {
 8993            Request::GetReferences(get_references) => {
 8994                let position = get_references.position.clone().and_then(deserialize_anchor);
 8995                Self::query_lsp_locally::<GetReferences>(
 8996                    lsp_store,
 8997                    server_id,
 8998                    sender_id,
 8999                    lsp_request_id,
 9000                    get_references,
 9001                    position,
 9002                    &mut cx,
 9003                )
 9004                .await?;
 9005            }
 9006            Request::GetDocumentColor(get_document_color) => {
 9007                Self::query_lsp_locally::<GetDocumentColor>(
 9008                    lsp_store,
 9009                    server_id,
 9010                    sender_id,
 9011                    lsp_request_id,
 9012                    get_document_color,
 9013                    None,
 9014                    &mut cx,
 9015                )
 9016                .await?;
 9017            }
 9018            Request::GetHover(get_hover) => {
 9019                let position = get_hover.position.clone().and_then(deserialize_anchor);
 9020                Self::query_lsp_locally::<GetHover>(
 9021                    lsp_store,
 9022                    server_id,
 9023                    sender_id,
 9024                    lsp_request_id,
 9025                    get_hover,
 9026                    position,
 9027                    &mut cx,
 9028                )
 9029                .await?;
 9030            }
 9031            Request::GetCodeActions(get_code_actions) => {
 9032                Self::query_lsp_locally::<GetCodeActions>(
 9033                    lsp_store,
 9034                    server_id,
 9035                    sender_id,
 9036                    lsp_request_id,
 9037                    get_code_actions,
 9038                    None,
 9039                    &mut cx,
 9040                )
 9041                .await?;
 9042            }
 9043            Request::GetSignatureHelp(get_signature_help) => {
 9044                let position = get_signature_help
 9045                    .position
 9046                    .clone()
 9047                    .and_then(deserialize_anchor);
 9048                Self::query_lsp_locally::<GetSignatureHelp>(
 9049                    lsp_store,
 9050                    server_id,
 9051                    sender_id,
 9052                    lsp_request_id,
 9053                    get_signature_help,
 9054                    position,
 9055                    &mut cx,
 9056                )
 9057                .await?;
 9058            }
 9059            Request::GetCodeLens(get_code_lens) => {
 9060                Self::query_lsp_locally::<GetCodeLens>(
 9061                    lsp_store,
 9062                    server_id,
 9063                    sender_id,
 9064                    lsp_request_id,
 9065                    get_code_lens,
 9066                    None,
 9067                    &mut cx,
 9068                )
 9069                .await?;
 9070            }
 9071            Request::GetDefinition(get_definition) => {
 9072                let position = get_definition.position.clone().and_then(deserialize_anchor);
 9073                Self::query_lsp_locally::<GetDefinitions>(
 9074                    lsp_store,
 9075                    server_id,
 9076                    sender_id,
 9077                    lsp_request_id,
 9078                    get_definition,
 9079                    position,
 9080                    &mut cx,
 9081                )
 9082                .await?;
 9083            }
 9084            Request::GetDeclaration(get_declaration) => {
 9085                let position = get_declaration
 9086                    .position
 9087                    .clone()
 9088                    .and_then(deserialize_anchor);
 9089                Self::query_lsp_locally::<GetDeclarations>(
 9090                    lsp_store,
 9091                    server_id,
 9092                    sender_id,
 9093                    lsp_request_id,
 9094                    get_declaration,
 9095                    position,
 9096                    &mut cx,
 9097                )
 9098                .await?;
 9099            }
 9100            Request::GetTypeDefinition(get_type_definition) => {
 9101                let position = get_type_definition
 9102                    .position
 9103                    .clone()
 9104                    .and_then(deserialize_anchor);
 9105                Self::query_lsp_locally::<GetTypeDefinitions>(
 9106                    lsp_store,
 9107                    server_id,
 9108                    sender_id,
 9109                    lsp_request_id,
 9110                    get_type_definition,
 9111                    position,
 9112                    &mut cx,
 9113                )
 9114                .await?;
 9115            }
 9116            Request::GetImplementation(get_implementation) => {
 9117                let position = get_implementation
 9118                    .position
 9119                    .clone()
 9120                    .and_then(deserialize_anchor);
 9121                Self::query_lsp_locally::<GetImplementations>(
 9122                    lsp_store,
 9123                    server_id,
 9124                    sender_id,
 9125                    lsp_request_id,
 9126                    get_implementation,
 9127                    position,
 9128                    &mut cx,
 9129                )
 9130                .await?;
 9131            }
 9132            Request::GetDocumentDiagnostics(get_document_diagnostics) => {
 9133                let buffer_id = BufferId::new(get_document_diagnostics.buffer_id())?;
 9134                let version = deserialize_version(get_document_diagnostics.buffer_version());
 9135                let buffer = lsp_store.update(&mut cx, |this, cx| {
 9136                    this.buffer_store.read(cx).get_existing(buffer_id)
 9137                })?;
 9138                buffer
 9139                    .update(&mut cx, |buffer, _| {
 9140                        buffer.wait_for_version(version.clone())
 9141                    })
 9142                    .await?;
 9143                lsp_store.update(&mut cx, |lsp_store, cx| {
 9144                    let lsp_data = lsp_store.latest_lsp_data(&buffer, cx);
 9145                    let key = LspKey {
 9146                        request_type: TypeId::of::<GetDocumentDiagnostics>(),
 9147                        server_queried: server_id,
 9148                    };
 9149                    if <GetDocumentDiagnostics as LspCommand>::ProtoRequest::stop_previous_requests(
 9150                    ) {
 9151                        if let Some(lsp_requests) = lsp_data.lsp_requests.get_mut(&key) {
 9152                            lsp_requests.clear();
 9153                        };
 9154                    }
 9155
 9156                    let existing_queries = lsp_data.lsp_requests.entry(key).or_default();
 9157                    existing_queries.insert(
 9158                        lsp_request_id,
 9159                        cx.spawn(async move |lsp_store, cx| {
 9160                            let diagnostics_pull = lsp_store.update(cx, |lsp_store, cx| {
 9161                                lsp_store.pull_diagnostics_for_buffer(buffer, cx)
 9162                            });
 9163                            if let Ok(diagnostics_pull) = diagnostics_pull {
 9164                                match diagnostics_pull.await {
 9165                                    Ok(()) => {}
 9166                                    Err(e) => log::error!("Failed to pull diagnostics: {e:#}"),
 9167                                };
 9168                            }
 9169                        }),
 9170                    );
 9171                });
 9172            }
 9173            Request::InlayHints(inlay_hints) => {
 9174                let query_start = inlay_hints
 9175                    .start
 9176                    .clone()
 9177                    .and_then(deserialize_anchor)
 9178                    .context("invalid inlay hints range start")?;
 9179                let query_end = inlay_hints
 9180                    .end
 9181                    .clone()
 9182                    .and_then(deserialize_anchor)
 9183                    .context("invalid inlay hints range end")?;
 9184                Self::deduplicate_range_based_lsp_requests::<InlayHints>(
 9185                    &lsp_store,
 9186                    server_id,
 9187                    lsp_request_id,
 9188                    &inlay_hints,
 9189                    query_start..query_end,
 9190                    &mut cx,
 9191                )
 9192                .await
 9193                .context("preparing inlay hints request")?;
 9194                Self::query_lsp_locally::<InlayHints>(
 9195                    lsp_store,
 9196                    server_id,
 9197                    sender_id,
 9198                    lsp_request_id,
 9199                    inlay_hints,
 9200                    None,
 9201                    &mut cx,
 9202                )
 9203                .await
 9204                .context("querying for inlay hints")?
 9205            }
 9206        }
 9207        Ok(proto::Ack {})
 9208    }
 9209
 9210    async fn handle_lsp_query_response(
 9211        lsp_store: Entity<Self>,
 9212        envelope: TypedEnvelope<proto::LspQueryResponse>,
 9213        cx: AsyncApp,
 9214    ) -> Result<()> {
 9215        lsp_store.read_with(&cx, |lsp_store, _| {
 9216            if let Some((upstream_client, _)) = lsp_store.upstream_client() {
 9217                upstream_client.handle_lsp_response(envelope.clone());
 9218            }
 9219        });
 9220        Ok(())
 9221    }
 9222
 9223    async fn handle_apply_code_action(
 9224        this: Entity<Self>,
 9225        envelope: TypedEnvelope<proto::ApplyCodeAction>,
 9226        mut cx: AsyncApp,
 9227    ) -> Result<proto::ApplyCodeActionResponse> {
 9228        let sender_id = envelope.original_sender_id().unwrap_or_default();
 9229        let action =
 9230            Self::deserialize_code_action(envelope.payload.action.context("invalid action")?)?;
 9231        let apply_code_action = this.update(&mut cx, |this, cx| {
 9232            let buffer_id = BufferId::new(envelope.payload.buffer_id)?;
 9233            let buffer = this.buffer_store.read(cx).get_existing(buffer_id)?;
 9234            anyhow::Ok(this.apply_code_action(buffer, action, false, cx))
 9235        })?;
 9236
 9237        let project_transaction = apply_code_action.await?;
 9238        let project_transaction = this.update(&mut cx, |this, cx| {
 9239            this.buffer_store.update(cx, |buffer_store, cx| {
 9240                buffer_store.serialize_project_transaction_for_peer(
 9241                    project_transaction,
 9242                    sender_id,
 9243                    cx,
 9244                )
 9245            })
 9246        });
 9247        Ok(proto::ApplyCodeActionResponse {
 9248            transaction: Some(project_transaction),
 9249        })
 9250    }
 9251
 9252    async fn handle_register_buffer_with_language_servers(
 9253        this: Entity<Self>,
 9254        envelope: TypedEnvelope<proto::RegisterBufferWithLanguageServers>,
 9255        mut cx: AsyncApp,
 9256    ) -> Result<proto::Ack> {
 9257        let buffer_id = BufferId::new(envelope.payload.buffer_id)?;
 9258        let peer_id = envelope.original_sender_id.unwrap_or(envelope.sender_id);
 9259        this.update(&mut cx, |this, cx| {
 9260            if let Some((upstream_client, upstream_project_id)) = this.upstream_client() {
 9261                return upstream_client.send(proto::RegisterBufferWithLanguageServers {
 9262                    project_id: upstream_project_id,
 9263                    buffer_id: buffer_id.to_proto(),
 9264                    only_servers: envelope.payload.only_servers,
 9265                });
 9266            }
 9267
 9268            let Some(buffer) = this.buffer_store().read(cx).get(buffer_id) else {
 9269                anyhow::bail!("buffer is not open");
 9270            };
 9271
 9272            let handle = this.register_buffer_with_language_servers(
 9273                &buffer,
 9274                envelope
 9275                    .payload
 9276                    .only_servers
 9277                    .into_iter()
 9278                    .filter_map(|selector| {
 9279                        Some(match selector.selector? {
 9280                            proto::language_server_selector::Selector::ServerId(server_id) => {
 9281                                LanguageServerSelector::Id(LanguageServerId::from_proto(server_id))
 9282                            }
 9283                            proto::language_server_selector::Selector::Name(name) => {
 9284                                LanguageServerSelector::Name(LanguageServerName(
 9285                                    SharedString::from(name),
 9286                                ))
 9287                            }
 9288                        })
 9289                    })
 9290                    .collect(),
 9291                false,
 9292                cx,
 9293            );
 9294            this.buffer_store().update(cx, |buffer_store, _| {
 9295                buffer_store.register_shared_lsp_handle(peer_id, buffer_id, handle);
 9296            });
 9297
 9298            Ok(())
 9299        })?;
 9300        Ok(proto::Ack {})
 9301    }
 9302
 9303    async fn handle_rename_project_entry(
 9304        this: Entity<Self>,
 9305        envelope: TypedEnvelope<proto::RenameProjectEntry>,
 9306        mut cx: AsyncApp,
 9307    ) -> Result<proto::ProjectEntryResponse> {
 9308        let entry_id = ProjectEntryId::from_proto(envelope.payload.entry_id);
 9309        let new_worktree_id = WorktreeId::from_proto(envelope.payload.new_worktree_id);
 9310        let new_path =
 9311            RelPath::from_proto(&envelope.payload.new_path).context("invalid relative path")?;
 9312
 9313        let (worktree_store, old_worktree, new_worktree, old_entry) = this
 9314            .update(&mut cx, |this, cx| {
 9315                let (worktree, entry) = this
 9316                    .worktree_store
 9317                    .read(cx)
 9318                    .worktree_and_entry_for_id(entry_id, cx)?;
 9319                let new_worktree = this
 9320                    .worktree_store
 9321                    .read(cx)
 9322                    .worktree_for_id(new_worktree_id, cx)?;
 9323                Some((
 9324                    this.worktree_store.clone(),
 9325                    worktree,
 9326                    new_worktree,
 9327                    entry.clone(),
 9328                ))
 9329            })
 9330            .context("worktree not found")?;
 9331        let (old_abs_path, old_worktree_id) = old_worktree.read_with(&cx, |worktree, _| {
 9332            (worktree.absolutize(&old_entry.path), worktree.id())
 9333        });
 9334        let new_abs_path =
 9335            new_worktree.read_with(&cx, |worktree, _| worktree.absolutize(&new_path));
 9336
 9337        let _transaction = Self::will_rename_entry(
 9338            this.downgrade(),
 9339            old_worktree_id,
 9340            &old_abs_path,
 9341            &new_abs_path,
 9342            old_entry.is_dir(),
 9343            cx.clone(),
 9344        )
 9345        .await;
 9346        let response = WorktreeStore::handle_rename_project_entry(
 9347            worktree_store,
 9348            envelope.payload,
 9349            cx.clone(),
 9350        )
 9351        .await;
 9352        this.read_with(&cx, |this, _| {
 9353            this.did_rename_entry(
 9354                old_worktree_id,
 9355                &old_abs_path,
 9356                &new_abs_path,
 9357                old_entry.is_dir(),
 9358            );
 9359        });
 9360        response
 9361    }
 9362
 9363    async fn handle_update_diagnostic_summary(
 9364        this: Entity<Self>,
 9365        envelope: TypedEnvelope<proto::UpdateDiagnosticSummary>,
 9366        mut cx: AsyncApp,
 9367    ) -> Result<()> {
 9368        this.update(&mut cx, |lsp_store, cx| {
 9369            let worktree_id = WorktreeId::from_proto(envelope.payload.worktree_id);
 9370            let mut updated_diagnostics_paths = HashMap::default();
 9371            let mut diagnostics_summary = None::<proto::UpdateDiagnosticSummary>;
 9372            for message_summary in envelope
 9373                .payload
 9374                .summary
 9375                .into_iter()
 9376                .chain(envelope.payload.more_summaries)
 9377            {
 9378                let project_path = ProjectPath {
 9379                    worktree_id,
 9380                    path: RelPath::from_proto(&message_summary.path).context("invalid path")?,
 9381                };
 9382                let path = project_path.path.clone();
 9383                let server_id = LanguageServerId(message_summary.language_server_id as usize);
 9384                let summary = DiagnosticSummary {
 9385                    error_count: message_summary.error_count as usize,
 9386                    warning_count: message_summary.warning_count as usize,
 9387                };
 9388
 9389                if summary.is_empty() {
 9390                    if let Some(worktree_summaries) =
 9391                        lsp_store.diagnostic_summaries.get_mut(&worktree_id)
 9392                        && let Some(summaries) = worktree_summaries.get_mut(&path)
 9393                    {
 9394                        summaries.remove(&server_id);
 9395                        if summaries.is_empty() {
 9396                            worktree_summaries.remove(&path);
 9397                        }
 9398                    }
 9399                } else {
 9400                    lsp_store
 9401                        .diagnostic_summaries
 9402                        .entry(worktree_id)
 9403                        .or_default()
 9404                        .entry(path)
 9405                        .or_default()
 9406                        .insert(server_id, summary);
 9407                }
 9408
 9409                if let Some((_, project_id)) = &lsp_store.downstream_client {
 9410                    match &mut diagnostics_summary {
 9411                        Some(diagnostics_summary) => {
 9412                            diagnostics_summary
 9413                                .more_summaries
 9414                                .push(proto::DiagnosticSummary {
 9415                                    path: project_path.path.as_ref().to_proto(),
 9416                                    language_server_id: server_id.0 as u64,
 9417                                    error_count: summary.error_count as u32,
 9418                                    warning_count: summary.warning_count as u32,
 9419                                })
 9420                        }
 9421                        None => {
 9422                            diagnostics_summary = Some(proto::UpdateDiagnosticSummary {
 9423                                project_id: *project_id,
 9424                                worktree_id: worktree_id.to_proto(),
 9425                                summary: Some(proto::DiagnosticSummary {
 9426                                    path: project_path.path.as_ref().to_proto(),
 9427                                    language_server_id: server_id.0 as u64,
 9428                                    error_count: summary.error_count as u32,
 9429                                    warning_count: summary.warning_count as u32,
 9430                                }),
 9431                                more_summaries: Vec::new(),
 9432                            })
 9433                        }
 9434                    }
 9435                }
 9436                updated_diagnostics_paths
 9437                    .entry(server_id)
 9438                    .or_insert_with(Vec::new)
 9439                    .push(project_path);
 9440            }
 9441
 9442            if let Some((diagnostics_summary, (downstream_client, _))) =
 9443                diagnostics_summary.zip(lsp_store.downstream_client.as_ref())
 9444            {
 9445                downstream_client.send(diagnostics_summary).log_err();
 9446            }
 9447            for (server_id, paths) in updated_diagnostics_paths {
 9448                cx.emit(LspStoreEvent::DiagnosticsUpdated { server_id, paths });
 9449            }
 9450            Ok(())
 9451        })
 9452    }
 9453
 9454    async fn handle_start_language_server(
 9455        lsp_store: Entity<Self>,
 9456        envelope: TypedEnvelope<proto::StartLanguageServer>,
 9457        mut cx: AsyncApp,
 9458    ) -> Result<()> {
 9459        let server = envelope.payload.server.context("invalid server")?;
 9460        let server_capabilities =
 9461            serde_json::from_str::<lsp::ServerCapabilities>(&envelope.payload.capabilities)
 9462                .with_context(|| {
 9463                    format!(
 9464                        "incorrect server capabilities {}",
 9465                        envelope.payload.capabilities
 9466                    )
 9467                })?;
 9468        lsp_store.update(&mut cx, |lsp_store, cx| {
 9469            let server_id = LanguageServerId(server.id as usize);
 9470            let server_name = LanguageServerName::from_proto(server.name.clone());
 9471            lsp_store
 9472                .lsp_server_capabilities
 9473                .insert(server_id, server_capabilities);
 9474            lsp_store.language_server_statuses.insert(
 9475                server_id,
 9476                LanguageServerStatus {
 9477                    name: server_name.clone(),
 9478                    server_version: None,
 9479                    pending_work: Default::default(),
 9480                    has_pending_diagnostic_updates: false,
 9481                    progress_tokens: Default::default(),
 9482                    worktree: server.worktree_id.map(WorktreeId::from_proto),
 9483                    binary: None,
 9484                    configuration: None,
 9485                    workspace_folders: BTreeSet::new(),
 9486                },
 9487            );
 9488            cx.emit(LspStoreEvent::LanguageServerAdded(
 9489                server_id,
 9490                server_name,
 9491                server.worktree_id.map(WorktreeId::from_proto),
 9492            ));
 9493            cx.notify();
 9494        });
 9495        Ok(())
 9496    }
 9497
 9498    async fn handle_update_language_server(
 9499        lsp_store: Entity<Self>,
 9500        envelope: TypedEnvelope<proto::UpdateLanguageServer>,
 9501        mut cx: AsyncApp,
 9502    ) -> Result<()> {
 9503        lsp_store.update(&mut cx, |lsp_store, cx| {
 9504            let language_server_id = LanguageServerId(envelope.payload.language_server_id as usize);
 9505
 9506            match envelope.payload.variant.context("invalid variant")? {
 9507                proto::update_language_server::Variant::WorkStart(payload) => {
 9508                    lsp_store.on_lsp_work_start(
 9509                        language_server_id,
 9510                        ProgressToken::from_proto(payload.token.context("missing progress token")?)
 9511                            .context("invalid progress token value")?,
 9512                        LanguageServerProgress {
 9513                            title: payload.title,
 9514                            is_disk_based_diagnostics_progress: false,
 9515                            is_cancellable: payload.is_cancellable.unwrap_or(false),
 9516                            message: payload.message,
 9517                            percentage: payload.percentage.map(|p| p as usize),
 9518                            last_update_at: cx.background_executor().now(),
 9519                        },
 9520                        cx,
 9521                    );
 9522                }
 9523                proto::update_language_server::Variant::WorkProgress(payload) => {
 9524                    lsp_store.on_lsp_work_progress(
 9525                        language_server_id,
 9526                        ProgressToken::from_proto(payload.token.context("missing progress token")?)
 9527                            .context("invalid progress token value")?,
 9528                        LanguageServerProgress {
 9529                            title: None,
 9530                            is_disk_based_diagnostics_progress: false,
 9531                            is_cancellable: payload.is_cancellable.unwrap_or(false),
 9532                            message: payload.message,
 9533                            percentage: payload.percentage.map(|p| p as usize),
 9534                            last_update_at: cx.background_executor().now(),
 9535                        },
 9536                        cx,
 9537                    );
 9538                }
 9539
 9540                proto::update_language_server::Variant::WorkEnd(payload) => {
 9541                    lsp_store.on_lsp_work_end(
 9542                        language_server_id,
 9543                        ProgressToken::from_proto(payload.token.context("missing progress token")?)
 9544                            .context("invalid progress token value")?,
 9545                        cx,
 9546                    );
 9547                }
 9548
 9549                proto::update_language_server::Variant::DiskBasedDiagnosticsUpdating(_) => {
 9550                    lsp_store.disk_based_diagnostics_started(language_server_id, cx);
 9551                }
 9552
 9553                proto::update_language_server::Variant::DiskBasedDiagnosticsUpdated(_) => {
 9554                    lsp_store.disk_based_diagnostics_finished(language_server_id, cx)
 9555                }
 9556
 9557                non_lsp @ proto::update_language_server::Variant::StatusUpdate(_)
 9558                | non_lsp @ proto::update_language_server::Variant::RegisteredForBuffer(_)
 9559                | non_lsp @ proto::update_language_server::Variant::MetadataUpdated(_) => {
 9560                    cx.emit(LspStoreEvent::LanguageServerUpdate {
 9561                        language_server_id,
 9562                        name: envelope
 9563                            .payload
 9564                            .server_name
 9565                            .map(SharedString::new)
 9566                            .map(LanguageServerName),
 9567                        message: non_lsp,
 9568                    });
 9569                }
 9570            }
 9571
 9572            Ok(())
 9573        })
 9574    }
 9575
 9576    async fn handle_language_server_log(
 9577        this: Entity<Self>,
 9578        envelope: TypedEnvelope<proto::LanguageServerLog>,
 9579        mut cx: AsyncApp,
 9580    ) -> Result<()> {
 9581        let language_server_id = LanguageServerId(envelope.payload.language_server_id as usize);
 9582        let log_type = envelope
 9583            .payload
 9584            .log_type
 9585            .map(LanguageServerLogType::from_proto)
 9586            .context("invalid language server log type")?;
 9587
 9588        let message = envelope.payload.message;
 9589
 9590        this.update(&mut cx, |_, cx| {
 9591            cx.emit(LspStoreEvent::LanguageServerLog(
 9592                language_server_id,
 9593                log_type,
 9594                message,
 9595            ));
 9596        });
 9597        Ok(())
 9598    }
 9599
 9600    async fn handle_lsp_ext_cancel_flycheck(
 9601        lsp_store: Entity<Self>,
 9602        envelope: TypedEnvelope<proto::LspExtCancelFlycheck>,
 9603        cx: AsyncApp,
 9604    ) -> Result<proto::Ack> {
 9605        let server_id = LanguageServerId(envelope.payload.language_server_id as usize);
 9606        let task = lsp_store.read_with(&cx, |lsp_store, _| {
 9607            if let Some(server) = lsp_store.language_server_for_id(server_id) {
 9608                Some(server.notify::<lsp_store::lsp_ext_command::LspExtCancelFlycheck>(()))
 9609            } else {
 9610                None
 9611            }
 9612        });
 9613        if let Some(task) = task {
 9614            task.context("handling lsp ext cancel flycheck")?;
 9615        }
 9616
 9617        Ok(proto::Ack {})
 9618    }
 9619
 9620    async fn handle_lsp_ext_run_flycheck(
 9621        lsp_store: Entity<Self>,
 9622        envelope: TypedEnvelope<proto::LspExtRunFlycheck>,
 9623        mut cx: AsyncApp,
 9624    ) -> Result<proto::Ack> {
 9625        let server_id = LanguageServerId(envelope.payload.language_server_id as usize);
 9626        lsp_store.update(&mut cx, |lsp_store, cx| {
 9627            if let Some(server) = lsp_store.language_server_for_id(server_id) {
 9628                let text_document = if envelope.payload.current_file_only {
 9629                    let buffer_id = envelope
 9630                        .payload
 9631                        .buffer_id
 9632                        .map(|id| BufferId::new(id))
 9633                        .transpose()?;
 9634                    buffer_id
 9635                        .and_then(|buffer_id| {
 9636                            lsp_store
 9637                                .buffer_store()
 9638                                .read(cx)
 9639                                .get(buffer_id)
 9640                                .and_then(|buffer| {
 9641                                    Some(buffer.read(cx).file()?.as_local()?.abs_path(cx))
 9642                                })
 9643                                .map(|path| make_text_document_identifier(&path))
 9644                        })
 9645                        .transpose()?
 9646                } else {
 9647                    None
 9648                };
 9649                server.notify::<lsp_store::lsp_ext_command::LspExtRunFlycheck>(
 9650                    lsp_store::lsp_ext_command::RunFlycheckParams { text_document },
 9651                )?;
 9652            }
 9653            anyhow::Ok(())
 9654        })?;
 9655
 9656        Ok(proto::Ack {})
 9657    }
 9658
 9659    async fn handle_lsp_ext_clear_flycheck(
 9660        lsp_store: Entity<Self>,
 9661        envelope: TypedEnvelope<proto::LspExtClearFlycheck>,
 9662        cx: AsyncApp,
 9663    ) -> Result<proto::Ack> {
 9664        let server_id = LanguageServerId(envelope.payload.language_server_id as usize);
 9665        lsp_store.read_with(&cx, |lsp_store, _| {
 9666            if let Some(server) = lsp_store.language_server_for_id(server_id) {
 9667                Some(server.notify::<lsp_store::lsp_ext_command::LspExtClearFlycheck>(()))
 9668            } else {
 9669                None
 9670            }
 9671        });
 9672
 9673        Ok(proto::Ack {})
 9674    }
 9675
 9676    pub fn disk_based_diagnostics_started(
 9677        &mut self,
 9678        language_server_id: LanguageServerId,
 9679        cx: &mut Context<Self>,
 9680    ) {
 9681        if let Some(language_server_status) =
 9682            self.language_server_statuses.get_mut(&language_server_id)
 9683        {
 9684            language_server_status.has_pending_diagnostic_updates = true;
 9685        }
 9686
 9687        cx.emit(LspStoreEvent::DiskBasedDiagnosticsStarted { language_server_id });
 9688        cx.emit(LspStoreEvent::LanguageServerUpdate {
 9689            language_server_id,
 9690            name: self
 9691                .language_server_adapter_for_id(language_server_id)
 9692                .map(|adapter| adapter.name()),
 9693            message: proto::update_language_server::Variant::DiskBasedDiagnosticsUpdating(
 9694                Default::default(),
 9695            ),
 9696        })
 9697    }
 9698
 9699    pub fn disk_based_diagnostics_finished(
 9700        &mut self,
 9701        language_server_id: LanguageServerId,
 9702        cx: &mut Context<Self>,
 9703    ) {
 9704        if let Some(language_server_status) =
 9705            self.language_server_statuses.get_mut(&language_server_id)
 9706        {
 9707            language_server_status.has_pending_diagnostic_updates = false;
 9708        }
 9709
 9710        cx.emit(LspStoreEvent::DiskBasedDiagnosticsFinished { language_server_id });
 9711        cx.emit(LspStoreEvent::LanguageServerUpdate {
 9712            language_server_id,
 9713            name: self
 9714                .language_server_adapter_for_id(language_server_id)
 9715                .map(|adapter| adapter.name()),
 9716            message: proto::update_language_server::Variant::DiskBasedDiagnosticsUpdated(
 9717                Default::default(),
 9718            ),
 9719        })
 9720    }
 9721
 9722    // After saving a buffer using a language server that doesn't provide a disk-based progress token,
 9723    // kick off a timer that will reset every time the buffer is saved. If the timer eventually fires,
 9724    // simulate disk-based diagnostics being finished so that other pieces of UI (e.g., project
 9725    // diagnostics view, diagnostic status bar) can update. We don't emit an event right away because
 9726    // the language server might take some time to publish diagnostics.
 9727    fn simulate_disk_based_diagnostics_events_if_needed(
 9728        &mut self,
 9729        language_server_id: LanguageServerId,
 9730        cx: &mut Context<Self>,
 9731    ) {
 9732        const DISK_BASED_DIAGNOSTICS_DEBOUNCE: Duration = Duration::from_secs(1);
 9733
 9734        let Some(LanguageServerState::Running {
 9735            simulate_disk_based_diagnostics_completion,
 9736            adapter,
 9737            ..
 9738        }) = self
 9739            .as_local_mut()
 9740            .and_then(|local_store| local_store.language_servers.get_mut(&language_server_id))
 9741        else {
 9742            return;
 9743        };
 9744
 9745        if adapter.disk_based_diagnostics_progress_token.is_some() {
 9746            return;
 9747        }
 9748
 9749        let prev_task =
 9750            simulate_disk_based_diagnostics_completion.replace(cx.spawn(async move |this, cx| {
 9751                cx.background_executor()
 9752                    .timer(DISK_BASED_DIAGNOSTICS_DEBOUNCE)
 9753                    .await;
 9754
 9755                this.update(cx, |this, cx| {
 9756                    this.disk_based_diagnostics_finished(language_server_id, cx);
 9757
 9758                    if let Some(LanguageServerState::Running {
 9759                        simulate_disk_based_diagnostics_completion,
 9760                        ..
 9761                    }) = this.as_local_mut().and_then(|local_store| {
 9762                        local_store.language_servers.get_mut(&language_server_id)
 9763                    }) {
 9764                        *simulate_disk_based_diagnostics_completion = None;
 9765                    }
 9766                })
 9767                .ok();
 9768            }));
 9769
 9770        if prev_task.is_none() {
 9771            self.disk_based_diagnostics_started(language_server_id, cx);
 9772        }
 9773    }
 9774
 9775    pub fn language_server_statuses(
 9776        &self,
 9777    ) -> impl DoubleEndedIterator<Item = (LanguageServerId, &LanguageServerStatus)> {
 9778        self.language_server_statuses
 9779            .iter()
 9780            .map(|(key, value)| (*key, value))
 9781    }
 9782
 9783    pub(super) fn did_rename_entry(
 9784        &self,
 9785        worktree_id: WorktreeId,
 9786        old_path: &Path,
 9787        new_path: &Path,
 9788        is_dir: bool,
 9789    ) {
 9790        maybe!({
 9791            let local_store = self.as_local()?;
 9792
 9793            let old_uri = lsp::Uri::from_file_path(old_path)
 9794                .ok()
 9795                .map(|uri| uri.to_string())?;
 9796            let new_uri = lsp::Uri::from_file_path(new_path)
 9797                .ok()
 9798                .map(|uri| uri.to_string())?;
 9799
 9800            for language_server in local_store.language_servers_for_worktree(worktree_id) {
 9801                let Some(filter) = local_store
 9802                    .language_server_paths_watched_for_rename
 9803                    .get(&language_server.server_id())
 9804                else {
 9805                    continue;
 9806                };
 9807
 9808                if filter.should_send_did_rename(&old_uri, is_dir) {
 9809                    language_server
 9810                        .notify::<DidRenameFiles>(RenameFilesParams {
 9811                            files: vec![FileRename {
 9812                                old_uri: old_uri.clone(),
 9813                                new_uri: new_uri.clone(),
 9814                            }],
 9815                        })
 9816                        .ok();
 9817                }
 9818            }
 9819            Some(())
 9820        });
 9821    }
 9822
 9823    pub(super) fn will_rename_entry(
 9824        this: WeakEntity<Self>,
 9825        worktree_id: WorktreeId,
 9826        old_path: &Path,
 9827        new_path: &Path,
 9828        is_dir: bool,
 9829        cx: AsyncApp,
 9830    ) -> Task<ProjectTransaction> {
 9831        let old_uri = lsp::Uri::from_file_path(old_path)
 9832            .ok()
 9833            .map(|uri| uri.to_string());
 9834        let new_uri = lsp::Uri::from_file_path(new_path)
 9835            .ok()
 9836            .map(|uri| uri.to_string());
 9837        cx.spawn(async move |cx| {
 9838            let mut tasks = vec![];
 9839            this.update(cx, |this, cx| {
 9840                let local_store = this.as_local()?;
 9841                let old_uri = old_uri?;
 9842                let new_uri = new_uri?;
 9843                for language_server in local_store.language_servers_for_worktree(worktree_id) {
 9844                    let Some(filter) = local_store
 9845                        .language_server_paths_watched_for_rename
 9846                        .get(&language_server.server_id())
 9847                    else {
 9848                        continue;
 9849                    };
 9850
 9851                    if filter.should_send_will_rename(&old_uri, is_dir) {
 9852                        let apply_edit = cx.spawn({
 9853                            let old_uri = old_uri.clone();
 9854                            let new_uri = new_uri.clone();
 9855                            let language_server = language_server.clone();
 9856                            async move |this, cx| {
 9857                                let edit = language_server
 9858                                    .request::<WillRenameFiles>(RenameFilesParams {
 9859                                        files: vec![FileRename { old_uri, new_uri }],
 9860                                    })
 9861                                    .await
 9862                                    .into_response()
 9863                                    .context("will rename files")
 9864                                    .log_err()
 9865                                    .flatten()?;
 9866
 9867                                let transaction = LocalLspStore::deserialize_workspace_edit(
 9868                                    this.upgrade()?,
 9869                                    edit,
 9870                                    false,
 9871                                    language_server.clone(),
 9872                                    cx,
 9873                                )
 9874                                .await
 9875                                .ok()?;
 9876                                Some(transaction)
 9877                            }
 9878                        });
 9879                        tasks.push(apply_edit);
 9880                    }
 9881                }
 9882                Some(())
 9883            })
 9884            .ok()
 9885            .flatten();
 9886            let mut merged_transaction = ProjectTransaction::default();
 9887            for task in tasks {
 9888                // Await on tasks sequentially so that the order of application of edits is deterministic
 9889                // (at least with regards to the order of registration of language servers)
 9890                if let Some(transaction) = task.await {
 9891                    for (buffer, buffer_transaction) in transaction.0 {
 9892                        merged_transaction.0.insert(buffer, buffer_transaction);
 9893                    }
 9894                }
 9895            }
 9896            merged_transaction
 9897        })
 9898    }
 9899
 9900    fn lsp_notify_abs_paths_changed(
 9901        &mut self,
 9902        server_id: LanguageServerId,
 9903        changes: Vec<PathEvent>,
 9904    ) {
 9905        maybe!({
 9906            let server = self.language_server_for_id(server_id)?;
 9907            let changes = changes
 9908                .into_iter()
 9909                .filter_map(|event| {
 9910                    let typ = match event.kind? {
 9911                        PathEventKind::Created => lsp::FileChangeType::CREATED,
 9912                        PathEventKind::Removed => lsp::FileChangeType::DELETED,
 9913                        PathEventKind::Changed => lsp::FileChangeType::CHANGED,
 9914                    };
 9915                    Some(lsp::FileEvent {
 9916                        uri: file_path_to_lsp_url(&event.path).log_err()?,
 9917                        typ,
 9918                    })
 9919                })
 9920                .collect::<Vec<_>>();
 9921            if !changes.is_empty() {
 9922                server
 9923                    .notify::<lsp::notification::DidChangeWatchedFiles>(
 9924                        lsp::DidChangeWatchedFilesParams { changes },
 9925                    )
 9926                    .ok();
 9927            }
 9928            Some(())
 9929        });
 9930    }
 9931
 9932    pub fn language_server_for_id(&self, id: LanguageServerId) -> Option<Arc<LanguageServer>> {
 9933        self.as_local()?.language_server_for_id(id)
 9934    }
 9935
 9936    fn on_lsp_progress(
 9937        &mut self,
 9938        progress_params: lsp::ProgressParams,
 9939        language_server_id: LanguageServerId,
 9940        disk_based_diagnostics_progress_token: Option<String>,
 9941        cx: &mut Context<Self>,
 9942    ) {
 9943        match progress_params.value {
 9944            lsp::ProgressParamsValue::WorkDone(progress) => {
 9945                self.handle_work_done_progress(
 9946                    progress,
 9947                    language_server_id,
 9948                    disk_based_diagnostics_progress_token,
 9949                    ProgressToken::from_lsp(progress_params.token),
 9950                    cx,
 9951                );
 9952            }
 9953            lsp::ProgressParamsValue::WorkspaceDiagnostic(report) => {
 9954                let registration_id = match progress_params.token {
 9955                    lsp::NumberOrString::Number(_) => None,
 9956                    lsp::NumberOrString::String(token) => token
 9957                        .split_once(WORKSPACE_DIAGNOSTICS_TOKEN_START)
 9958                        .map(|(_, id)| id.to_owned()),
 9959                };
 9960                if let Some(LanguageServerState::Running {
 9961                    workspace_diagnostics_refresh_tasks,
 9962                    ..
 9963                }) = self
 9964                    .as_local_mut()
 9965                    .and_then(|local| local.language_servers.get_mut(&language_server_id))
 9966                    && let Some(workspace_diagnostics) =
 9967                        workspace_diagnostics_refresh_tasks.get_mut(&registration_id)
 9968                {
 9969                    workspace_diagnostics.progress_tx.try_send(()).ok();
 9970                    self.apply_workspace_diagnostic_report(
 9971                        language_server_id,
 9972                        report,
 9973                        registration_id.map(SharedString::from),
 9974                        cx,
 9975                    )
 9976                }
 9977            }
 9978        }
 9979    }
 9980
 9981    fn handle_work_done_progress(
 9982        &mut self,
 9983        progress: lsp::WorkDoneProgress,
 9984        language_server_id: LanguageServerId,
 9985        disk_based_diagnostics_progress_token: Option<String>,
 9986        token: ProgressToken,
 9987        cx: &mut Context<Self>,
 9988    ) {
 9989        let language_server_status =
 9990            if let Some(status) = self.language_server_statuses.get_mut(&language_server_id) {
 9991                status
 9992            } else {
 9993                return;
 9994            };
 9995
 9996        if !language_server_status.progress_tokens.contains(&token) {
 9997            return;
 9998        }
 9999
10000        let is_disk_based_diagnostics_progress =
10001            if let (Some(disk_based_token), ProgressToken::String(token)) =
10002                (&disk_based_diagnostics_progress_token, &token)
10003            {
10004                token.starts_with(disk_based_token)
10005            } else {
10006                false
10007            };
10008
10009        match progress {
10010            lsp::WorkDoneProgress::Begin(report) => {
10011                if is_disk_based_diagnostics_progress {
10012                    self.disk_based_diagnostics_started(language_server_id, cx);
10013                }
10014                self.on_lsp_work_start(
10015                    language_server_id,
10016                    token.clone(),
10017                    LanguageServerProgress {
10018                        title: Some(report.title),
10019                        is_disk_based_diagnostics_progress,
10020                        is_cancellable: report.cancellable.unwrap_or(false),
10021                        message: report.message.clone(),
10022                        percentage: report.percentage.map(|p| p as usize),
10023                        last_update_at: cx.background_executor().now(),
10024                    },
10025                    cx,
10026                );
10027            }
10028            lsp::WorkDoneProgress::Report(report) => self.on_lsp_work_progress(
10029                language_server_id,
10030                token,
10031                LanguageServerProgress {
10032                    title: None,
10033                    is_disk_based_diagnostics_progress,
10034                    is_cancellable: report.cancellable.unwrap_or(false),
10035                    message: report.message,
10036                    percentage: report.percentage.map(|p| p as usize),
10037                    last_update_at: cx.background_executor().now(),
10038                },
10039                cx,
10040            ),
10041            lsp::WorkDoneProgress::End(_) => {
10042                language_server_status.progress_tokens.remove(&token);
10043                self.on_lsp_work_end(language_server_id, token.clone(), cx);
10044                if is_disk_based_diagnostics_progress {
10045                    self.disk_based_diagnostics_finished(language_server_id, cx);
10046                }
10047            }
10048        }
10049    }
10050
10051    fn on_lsp_work_start(
10052        &mut self,
10053        language_server_id: LanguageServerId,
10054        token: ProgressToken,
10055        progress: LanguageServerProgress,
10056        cx: &mut Context<Self>,
10057    ) {
10058        if let Some(status) = self.language_server_statuses.get_mut(&language_server_id) {
10059            status.pending_work.insert(token.clone(), progress.clone());
10060            cx.notify();
10061        }
10062        cx.emit(LspStoreEvent::LanguageServerUpdate {
10063            language_server_id,
10064            name: self
10065                .language_server_adapter_for_id(language_server_id)
10066                .map(|adapter| adapter.name()),
10067            message: proto::update_language_server::Variant::WorkStart(proto::LspWorkStart {
10068                token: Some(token.to_proto()),
10069                title: progress.title,
10070                message: progress.message,
10071                percentage: progress.percentage.map(|p| p as u32),
10072                is_cancellable: Some(progress.is_cancellable),
10073            }),
10074        })
10075    }
10076
10077    fn on_lsp_work_progress(
10078        &mut self,
10079        language_server_id: LanguageServerId,
10080        token: ProgressToken,
10081        progress: LanguageServerProgress,
10082        cx: &mut Context<Self>,
10083    ) {
10084        let mut did_update = false;
10085        if let Some(status) = self.language_server_statuses.get_mut(&language_server_id) {
10086            match status.pending_work.entry(token.clone()) {
10087                btree_map::Entry::Vacant(entry) => {
10088                    entry.insert(progress.clone());
10089                    did_update = true;
10090                }
10091                btree_map::Entry::Occupied(mut entry) => {
10092                    let entry = entry.get_mut();
10093                    if (progress.last_update_at - entry.last_update_at)
10094                        >= SERVER_PROGRESS_THROTTLE_TIMEOUT
10095                    {
10096                        entry.last_update_at = progress.last_update_at;
10097                        if progress.message.is_some() {
10098                            entry.message = progress.message.clone();
10099                        }
10100                        if progress.percentage.is_some() {
10101                            entry.percentage = progress.percentage;
10102                        }
10103                        if progress.is_cancellable != entry.is_cancellable {
10104                            entry.is_cancellable = progress.is_cancellable;
10105                        }
10106                        did_update = true;
10107                    }
10108                }
10109            }
10110        }
10111
10112        if did_update {
10113            cx.emit(LspStoreEvent::LanguageServerUpdate {
10114                language_server_id,
10115                name: self
10116                    .language_server_adapter_for_id(language_server_id)
10117                    .map(|adapter| adapter.name()),
10118                message: proto::update_language_server::Variant::WorkProgress(
10119                    proto::LspWorkProgress {
10120                        token: Some(token.to_proto()),
10121                        message: progress.message,
10122                        percentage: progress.percentage.map(|p| p as u32),
10123                        is_cancellable: Some(progress.is_cancellable),
10124                    },
10125                ),
10126            })
10127        }
10128    }
10129
10130    fn on_lsp_work_end(
10131        &mut self,
10132        language_server_id: LanguageServerId,
10133        token: ProgressToken,
10134        cx: &mut Context<Self>,
10135    ) {
10136        if let Some(status) = self.language_server_statuses.get_mut(&language_server_id) {
10137            if let Some(work) = status.pending_work.remove(&token)
10138                && !work.is_disk_based_diagnostics_progress
10139            {
10140                cx.emit(LspStoreEvent::RefreshInlayHints {
10141                    server_id: language_server_id,
10142                    request_id: None,
10143                });
10144            }
10145            cx.notify();
10146        }
10147
10148        cx.emit(LspStoreEvent::LanguageServerUpdate {
10149            language_server_id,
10150            name: self
10151                .language_server_adapter_for_id(language_server_id)
10152                .map(|adapter| adapter.name()),
10153            message: proto::update_language_server::Variant::WorkEnd(proto::LspWorkEnd {
10154                token: Some(token.to_proto()),
10155            }),
10156        })
10157    }
10158
10159    pub async fn handle_resolve_completion_documentation(
10160        this: Entity<Self>,
10161        envelope: TypedEnvelope<proto::ResolveCompletionDocumentation>,
10162        mut cx: AsyncApp,
10163    ) -> Result<proto::ResolveCompletionDocumentationResponse> {
10164        let lsp_completion = serde_json::from_slice(&envelope.payload.lsp_completion)?;
10165
10166        let completion = this
10167            .read_with(&cx, |this, cx| {
10168                let id = LanguageServerId(envelope.payload.language_server_id as usize);
10169                let server = this
10170                    .language_server_for_id(id)
10171                    .with_context(|| format!("No language server {id}"))?;
10172
10173                anyhow::Ok(cx.background_spawn(async move {
10174                    let can_resolve = server
10175                        .capabilities()
10176                        .completion_provider
10177                        .as_ref()
10178                        .and_then(|options| options.resolve_provider)
10179                        .unwrap_or(false);
10180                    if can_resolve {
10181                        server
10182                            .request::<lsp::request::ResolveCompletionItem>(lsp_completion)
10183                            .await
10184                            .into_response()
10185                            .context("resolve completion item")
10186                    } else {
10187                        anyhow::Ok(lsp_completion)
10188                    }
10189                }))
10190            })?
10191            .await?;
10192
10193        let mut documentation_is_markdown = false;
10194        let lsp_completion = serde_json::to_string(&completion)?.into_bytes();
10195        let documentation = match completion.documentation {
10196            Some(lsp::Documentation::String(text)) => text,
10197
10198            Some(lsp::Documentation::MarkupContent(lsp::MarkupContent { kind, value })) => {
10199                documentation_is_markdown = kind == lsp::MarkupKind::Markdown;
10200                value
10201            }
10202
10203            _ => String::new(),
10204        };
10205
10206        // If we have a new buffer_id, that means we're talking to a new client
10207        // and want to check for new text_edits in the completion too.
10208        let mut old_replace_start = None;
10209        let mut old_replace_end = None;
10210        let mut old_insert_start = None;
10211        let mut old_insert_end = None;
10212        let mut new_text = String::default();
10213        if let Ok(buffer_id) = BufferId::new(envelope.payload.buffer_id) {
10214            let buffer_snapshot = this.update(&mut cx, |this, cx| {
10215                let buffer = this.buffer_store.read(cx).get_existing(buffer_id)?;
10216                anyhow::Ok(buffer.read(cx).snapshot())
10217            })?;
10218
10219            if let Some(text_edit) = completion.text_edit.as_ref() {
10220                let edit = parse_completion_text_edit(text_edit, &buffer_snapshot);
10221
10222                if let Some(mut edit) = edit {
10223                    LineEnding::normalize(&mut edit.new_text);
10224
10225                    new_text = edit.new_text;
10226                    old_replace_start = Some(serialize_anchor(&edit.replace_range.start));
10227                    old_replace_end = Some(serialize_anchor(&edit.replace_range.end));
10228                    if let Some(insert_range) = edit.insert_range {
10229                        old_insert_start = Some(serialize_anchor(&insert_range.start));
10230                        old_insert_end = Some(serialize_anchor(&insert_range.end));
10231                    }
10232                }
10233            }
10234        }
10235
10236        Ok(proto::ResolveCompletionDocumentationResponse {
10237            documentation,
10238            documentation_is_markdown,
10239            old_replace_start,
10240            old_replace_end,
10241            new_text,
10242            lsp_completion,
10243            old_insert_start,
10244            old_insert_end,
10245        })
10246    }
10247
10248    async fn handle_on_type_formatting(
10249        this: Entity<Self>,
10250        envelope: TypedEnvelope<proto::OnTypeFormatting>,
10251        mut cx: AsyncApp,
10252    ) -> Result<proto::OnTypeFormattingResponse> {
10253        let on_type_formatting = this.update(&mut cx, |this, cx| {
10254            let buffer_id = BufferId::new(envelope.payload.buffer_id)?;
10255            let buffer = this.buffer_store.read(cx).get_existing(buffer_id)?;
10256            let position = envelope
10257                .payload
10258                .position
10259                .and_then(deserialize_anchor)
10260                .context("invalid position")?;
10261            anyhow::Ok(this.apply_on_type_formatting(
10262                buffer,
10263                position,
10264                envelope.payload.trigger.clone(),
10265                cx,
10266            ))
10267        })?;
10268
10269        let transaction = on_type_formatting
10270            .await?
10271            .as_ref()
10272            .map(language::proto::serialize_transaction);
10273        Ok(proto::OnTypeFormattingResponse { transaction })
10274    }
10275
10276    async fn handle_refresh_inlay_hints(
10277        lsp_store: Entity<Self>,
10278        envelope: TypedEnvelope<proto::RefreshInlayHints>,
10279        mut cx: AsyncApp,
10280    ) -> Result<proto::Ack> {
10281        lsp_store.update(&mut cx, |_, cx| {
10282            cx.emit(LspStoreEvent::RefreshInlayHints {
10283                server_id: LanguageServerId::from_proto(envelope.payload.server_id),
10284                request_id: envelope.payload.request_id.map(|id| id as usize),
10285            });
10286        });
10287        Ok(proto::Ack {})
10288    }
10289
10290    async fn handle_pull_workspace_diagnostics(
10291        lsp_store: Entity<Self>,
10292        envelope: TypedEnvelope<proto::PullWorkspaceDiagnostics>,
10293        mut cx: AsyncApp,
10294    ) -> Result<proto::Ack> {
10295        let server_id = LanguageServerId::from_proto(envelope.payload.server_id);
10296        lsp_store.update(&mut cx, |lsp_store, _| {
10297            lsp_store.pull_workspace_diagnostics(server_id);
10298        });
10299        Ok(proto::Ack {})
10300    }
10301
10302    async fn handle_get_color_presentation(
10303        lsp_store: Entity<Self>,
10304        envelope: TypedEnvelope<proto::GetColorPresentation>,
10305        mut cx: AsyncApp,
10306    ) -> Result<proto::GetColorPresentationResponse> {
10307        let buffer_id = BufferId::new(envelope.payload.buffer_id)?;
10308        let buffer = lsp_store.update(&mut cx, |lsp_store, cx| {
10309            lsp_store.buffer_store.read(cx).get_existing(buffer_id)
10310        })?;
10311
10312        let color = envelope
10313            .payload
10314            .color
10315            .context("invalid color resolve request")?;
10316        let start = color
10317            .lsp_range_start
10318            .context("invalid color resolve request")?;
10319        let end = color
10320            .lsp_range_end
10321            .context("invalid color resolve request")?;
10322
10323        let color = DocumentColor {
10324            lsp_range: lsp::Range {
10325                start: point_to_lsp(PointUtf16::new(start.row, start.column)),
10326                end: point_to_lsp(PointUtf16::new(end.row, end.column)),
10327            },
10328            color: lsp::Color {
10329                red: color.red,
10330                green: color.green,
10331                blue: color.blue,
10332                alpha: color.alpha,
10333            },
10334            resolved: false,
10335            color_presentations: Vec::new(),
10336        };
10337        let resolved_color = lsp_store
10338            .update(&mut cx, |lsp_store, cx| {
10339                lsp_store.resolve_color_presentation(
10340                    color,
10341                    buffer.clone(),
10342                    LanguageServerId(envelope.payload.server_id as usize),
10343                    cx,
10344                )
10345            })
10346            .await
10347            .context("resolving color presentation")?;
10348
10349        Ok(proto::GetColorPresentationResponse {
10350            presentations: resolved_color
10351                .color_presentations
10352                .into_iter()
10353                .map(|presentation| proto::ColorPresentation {
10354                    label: presentation.label.to_string(),
10355                    text_edit: presentation.text_edit.map(serialize_lsp_edit),
10356                    additional_text_edits: presentation
10357                        .additional_text_edits
10358                        .into_iter()
10359                        .map(serialize_lsp_edit)
10360                        .collect(),
10361                })
10362                .collect(),
10363        })
10364    }
10365
10366    async fn handle_resolve_inlay_hint(
10367        lsp_store: Entity<Self>,
10368        envelope: TypedEnvelope<proto::ResolveInlayHint>,
10369        mut cx: AsyncApp,
10370    ) -> Result<proto::ResolveInlayHintResponse> {
10371        let proto_hint = envelope
10372            .payload
10373            .hint
10374            .expect("incorrect protobuf resolve inlay hint message: missing the inlay hint");
10375        let hint = InlayHints::proto_to_project_hint(proto_hint)
10376            .context("resolved proto inlay hint conversion")?;
10377        let buffer = lsp_store.update(&mut cx, |lsp_store, cx| {
10378            let buffer_id = BufferId::new(envelope.payload.buffer_id)?;
10379            lsp_store.buffer_store.read(cx).get_existing(buffer_id)
10380        })?;
10381        let response_hint = lsp_store
10382            .update(&mut cx, |lsp_store, cx| {
10383                lsp_store.resolve_inlay_hint(
10384                    hint,
10385                    buffer,
10386                    LanguageServerId(envelope.payload.language_server_id as usize),
10387                    cx,
10388                )
10389            })
10390            .await
10391            .context("inlay hints fetch")?;
10392        Ok(proto::ResolveInlayHintResponse {
10393            hint: Some(InlayHints::project_to_proto_hint(response_hint)),
10394        })
10395    }
10396
10397    async fn handle_refresh_code_lens(
10398        this: Entity<Self>,
10399        _: TypedEnvelope<proto::RefreshCodeLens>,
10400        mut cx: AsyncApp,
10401    ) -> Result<proto::Ack> {
10402        this.update(&mut cx, |_, cx| {
10403            cx.emit(LspStoreEvent::RefreshCodeLens);
10404        });
10405        Ok(proto::Ack {})
10406    }
10407
10408    async fn handle_open_buffer_for_symbol(
10409        this: Entity<Self>,
10410        envelope: TypedEnvelope<proto::OpenBufferForSymbol>,
10411        mut cx: AsyncApp,
10412    ) -> Result<proto::OpenBufferForSymbolResponse> {
10413        let peer_id = envelope.original_sender_id().unwrap_or_default();
10414        let symbol = envelope.payload.symbol.context("invalid symbol")?;
10415        let symbol = Self::deserialize_symbol(symbol)?;
10416        this.read_with(&cx, |this, _| {
10417            if let SymbolLocation::OutsideProject {
10418                abs_path,
10419                signature,
10420            } = &symbol.path
10421            {
10422                let new_signature = this.symbol_signature(&abs_path);
10423                anyhow::ensure!(&new_signature == signature, "invalid symbol signature");
10424            }
10425            Ok(())
10426        })?;
10427        let buffer = this
10428            .update(&mut cx, |this, cx| {
10429                this.open_buffer_for_symbol(
10430                    &Symbol {
10431                        language_server_name: symbol.language_server_name,
10432                        source_worktree_id: symbol.source_worktree_id,
10433                        source_language_server_id: symbol.source_language_server_id,
10434                        path: symbol.path,
10435                        name: symbol.name,
10436                        kind: symbol.kind,
10437                        range: symbol.range,
10438                        label: CodeLabel::default(),
10439                    },
10440                    cx,
10441                )
10442            })
10443            .await?;
10444
10445        this.update(&mut cx, |this, cx| {
10446            let is_private = buffer
10447                .read(cx)
10448                .file()
10449                .map(|f| f.is_private())
10450                .unwrap_or_default();
10451            if is_private {
10452                Err(anyhow!(rpc::ErrorCode::UnsharedItem))
10453            } else {
10454                this.buffer_store
10455                    .update(cx, |buffer_store, cx| {
10456                        buffer_store.create_buffer_for_peer(&buffer, peer_id, cx)
10457                    })
10458                    .detach_and_log_err(cx);
10459                let buffer_id = buffer.read(cx).remote_id().to_proto();
10460                Ok(proto::OpenBufferForSymbolResponse { buffer_id })
10461            }
10462        })
10463    }
10464
10465    fn symbol_signature(&self, abs_path: &Path) -> [u8; 32] {
10466        let mut hasher = Sha256::new();
10467        hasher.update(abs_path.to_string_lossy().as_bytes());
10468        hasher.update(self.nonce.to_be_bytes());
10469        hasher.finalize().as_slice().try_into().unwrap()
10470    }
10471
10472    pub async fn handle_get_project_symbols(
10473        this: Entity<Self>,
10474        envelope: TypedEnvelope<proto::GetProjectSymbols>,
10475        mut cx: AsyncApp,
10476    ) -> Result<proto::GetProjectSymbolsResponse> {
10477        let symbols = this
10478            .update(&mut cx, |this, cx| {
10479                this.symbols(&envelope.payload.query, cx)
10480            })
10481            .await?;
10482
10483        Ok(proto::GetProjectSymbolsResponse {
10484            symbols: symbols.iter().map(Self::serialize_symbol).collect(),
10485        })
10486    }
10487
10488    pub async fn handle_restart_language_servers(
10489        this: Entity<Self>,
10490        envelope: TypedEnvelope<proto::RestartLanguageServers>,
10491        mut cx: AsyncApp,
10492    ) -> Result<proto::Ack> {
10493        this.update(&mut cx, |lsp_store, cx| {
10494            let buffers =
10495                lsp_store.buffer_ids_to_buffers(envelope.payload.buffer_ids.into_iter(), cx);
10496            lsp_store.restart_language_servers_for_buffers(
10497                buffers,
10498                envelope
10499                    .payload
10500                    .only_servers
10501                    .into_iter()
10502                    .filter_map(|selector| {
10503                        Some(match selector.selector? {
10504                            proto::language_server_selector::Selector::ServerId(server_id) => {
10505                                LanguageServerSelector::Id(LanguageServerId::from_proto(server_id))
10506                            }
10507                            proto::language_server_selector::Selector::Name(name) => {
10508                                LanguageServerSelector::Name(LanguageServerName(
10509                                    SharedString::from(name),
10510                                ))
10511                            }
10512                        })
10513                    })
10514                    .collect(),
10515                cx,
10516            );
10517        });
10518
10519        Ok(proto::Ack {})
10520    }
10521
10522    pub async fn handle_stop_language_servers(
10523        lsp_store: Entity<Self>,
10524        envelope: TypedEnvelope<proto::StopLanguageServers>,
10525        mut cx: AsyncApp,
10526    ) -> Result<proto::Ack> {
10527        lsp_store.update(&mut cx, |lsp_store, cx| {
10528            if envelope.payload.all
10529                && envelope.payload.also_servers.is_empty()
10530                && envelope.payload.buffer_ids.is_empty()
10531            {
10532                lsp_store.stop_all_language_servers(cx);
10533            } else {
10534                let buffers =
10535                    lsp_store.buffer_ids_to_buffers(envelope.payload.buffer_ids.into_iter(), cx);
10536                lsp_store
10537                    .stop_language_servers_for_buffers(
10538                        buffers,
10539                        envelope
10540                            .payload
10541                            .also_servers
10542                            .into_iter()
10543                            .filter_map(|selector| {
10544                                Some(match selector.selector? {
10545                                    proto::language_server_selector::Selector::ServerId(
10546                                        server_id,
10547                                    ) => LanguageServerSelector::Id(LanguageServerId::from_proto(
10548                                        server_id,
10549                                    )),
10550                                    proto::language_server_selector::Selector::Name(name) => {
10551                                        LanguageServerSelector::Name(LanguageServerName(
10552                                            SharedString::from(name),
10553                                        ))
10554                                    }
10555                                })
10556                            })
10557                            .collect(),
10558                        cx,
10559                    )
10560                    .detach_and_log_err(cx);
10561            }
10562        });
10563
10564        Ok(proto::Ack {})
10565    }
10566
10567    pub async fn handle_cancel_language_server_work(
10568        lsp_store: Entity<Self>,
10569        envelope: TypedEnvelope<proto::CancelLanguageServerWork>,
10570        mut cx: AsyncApp,
10571    ) -> Result<proto::Ack> {
10572        lsp_store.update(&mut cx, |lsp_store, cx| {
10573            if let Some(work) = envelope.payload.work {
10574                match work {
10575                    proto::cancel_language_server_work::Work::Buffers(buffers) => {
10576                        let buffers =
10577                            lsp_store.buffer_ids_to_buffers(buffers.buffer_ids.into_iter(), cx);
10578                        lsp_store.cancel_language_server_work_for_buffers(buffers, cx);
10579                    }
10580                    proto::cancel_language_server_work::Work::LanguageServerWork(work) => {
10581                        let server_id = LanguageServerId::from_proto(work.language_server_id);
10582                        let token = work
10583                            .token
10584                            .map(|token| {
10585                                ProgressToken::from_proto(token)
10586                                    .context("invalid work progress token")
10587                            })
10588                            .transpose()?;
10589                        lsp_store.cancel_language_server_work(server_id, token, cx);
10590                    }
10591                }
10592            }
10593            anyhow::Ok(())
10594        })?;
10595
10596        Ok(proto::Ack {})
10597    }
10598
10599    fn buffer_ids_to_buffers(
10600        &mut self,
10601        buffer_ids: impl Iterator<Item = u64>,
10602        cx: &mut Context<Self>,
10603    ) -> Vec<Entity<Buffer>> {
10604        buffer_ids
10605            .into_iter()
10606            .flat_map(|buffer_id| {
10607                self.buffer_store
10608                    .read(cx)
10609                    .get(BufferId::new(buffer_id).log_err()?)
10610            })
10611            .collect::<Vec<_>>()
10612    }
10613
10614    async fn handle_apply_additional_edits_for_completion(
10615        this: Entity<Self>,
10616        envelope: TypedEnvelope<proto::ApplyCompletionAdditionalEdits>,
10617        mut cx: AsyncApp,
10618    ) -> Result<proto::ApplyCompletionAdditionalEditsResponse> {
10619        let (buffer, completion) = this.update(&mut cx, |this, cx| {
10620            let buffer_id = BufferId::new(envelope.payload.buffer_id)?;
10621            let buffer = this.buffer_store.read(cx).get_existing(buffer_id)?;
10622            let completion = Self::deserialize_completion(
10623                envelope.payload.completion.context("invalid completion")?,
10624            )?;
10625            anyhow::Ok((buffer, completion))
10626        })?;
10627
10628        let apply_additional_edits = this.update(&mut cx, |this, cx| {
10629            this.apply_additional_edits_for_completion(
10630                buffer,
10631                Rc::new(RefCell::new(Box::new([Completion {
10632                    replace_range: completion.replace_range,
10633                    new_text: completion.new_text,
10634                    source: completion.source,
10635                    documentation: None,
10636                    label: CodeLabel::default(),
10637                    match_start: None,
10638                    snippet_deduplication_key: None,
10639                    insert_text_mode: None,
10640                    icon_path: None,
10641                    confirm: None,
10642                }]))),
10643                0,
10644                false,
10645                cx,
10646            )
10647        });
10648
10649        Ok(proto::ApplyCompletionAdditionalEditsResponse {
10650            transaction: apply_additional_edits
10651                .await?
10652                .as_ref()
10653                .map(language::proto::serialize_transaction),
10654        })
10655    }
10656
10657    pub fn last_formatting_failure(&self) -> Option<&str> {
10658        self.last_formatting_failure.as_deref()
10659    }
10660
10661    pub fn reset_last_formatting_failure(&mut self) {
10662        self.last_formatting_failure = None;
10663    }
10664
10665    pub fn environment_for_buffer(
10666        &self,
10667        buffer: &Entity<Buffer>,
10668        cx: &mut Context<Self>,
10669    ) -> Shared<Task<Option<HashMap<String, String>>>> {
10670        if let Some(environment) = &self.as_local().map(|local| local.environment.clone()) {
10671            environment.update(cx, |env, cx| {
10672                env.buffer_environment(buffer, &self.worktree_store, cx)
10673            })
10674        } else {
10675            Task::ready(None).shared()
10676        }
10677    }
10678
10679    pub fn format(
10680        &mut self,
10681        buffers: HashSet<Entity<Buffer>>,
10682        target: LspFormatTarget,
10683        push_to_history: bool,
10684        trigger: FormatTrigger,
10685        cx: &mut Context<Self>,
10686    ) -> Task<anyhow::Result<ProjectTransaction>> {
10687        let logger = zlog::scoped!("format");
10688        if self.as_local().is_some() {
10689            zlog::trace!(logger => "Formatting locally");
10690            let logger = zlog::scoped!(logger => "local");
10691            let buffers = buffers
10692                .into_iter()
10693                .map(|buffer_handle| {
10694                    let buffer = buffer_handle.read(cx);
10695                    let buffer_abs_path = File::from_dyn(buffer.file())
10696                        .and_then(|file| file.as_local().map(|f| f.abs_path(cx)));
10697
10698                    (buffer_handle, buffer_abs_path, buffer.remote_id())
10699                })
10700                .collect::<Vec<_>>();
10701
10702            cx.spawn(async move |lsp_store, cx| {
10703                let mut formattable_buffers = Vec::with_capacity(buffers.len());
10704
10705                for (handle, abs_path, id) in buffers {
10706                    let env = lsp_store
10707                        .update(cx, |lsp_store, cx| {
10708                            lsp_store.environment_for_buffer(&handle, cx)
10709                        })?
10710                        .await;
10711
10712                    let ranges = match &target {
10713                        LspFormatTarget::Buffers => None,
10714                        LspFormatTarget::Ranges(ranges) => {
10715                            Some(ranges.get(&id).context("No format ranges provided for buffer")?.clone())
10716                        }
10717                    };
10718
10719                    formattable_buffers.push(FormattableBuffer {
10720                        handle,
10721                        abs_path,
10722                        env,
10723                        ranges,
10724                    });
10725                }
10726                zlog::trace!(logger => "Formatting {:?} buffers", formattable_buffers.len());
10727
10728                let format_timer = zlog::time!(logger => "Formatting buffers");
10729                let result = LocalLspStore::format_locally(
10730                    lsp_store.clone(),
10731                    formattable_buffers,
10732                    push_to_history,
10733                    trigger,
10734                    logger,
10735                    cx,
10736                )
10737                .await;
10738                format_timer.end();
10739
10740                zlog::trace!(logger => "Formatting completed with result {:?}", result.as_ref().map(|_| "<project-transaction>"));
10741
10742                lsp_store.update(cx, |lsp_store, _| {
10743                    lsp_store.update_last_formatting_failure(&result);
10744                })?;
10745
10746                result
10747            })
10748        } else if let Some((client, project_id)) = self.upstream_client() {
10749            zlog::trace!(logger => "Formatting remotely");
10750            let logger = zlog::scoped!(logger => "remote");
10751
10752            let buffer_ranges = match &target {
10753                LspFormatTarget::Buffers => Vec::new(),
10754                LspFormatTarget::Ranges(ranges) => ranges
10755                    .iter()
10756                    .map(|(buffer_id, ranges)| proto::BufferFormatRanges {
10757                        buffer_id: buffer_id.to_proto(),
10758                        ranges: ranges.iter().cloned().map(serialize_anchor_range).collect(),
10759                    })
10760                    .collect(),
10761            };
10762
10763            let buffer_store = self.buffer_store();
10764            cx.spawn(async move |lsp_store, cx| {
10765                zlog::trace!(logger => "Sending remote format request");
10766                let request_timer = zlog::time!(logger => "remote format request");
10767                let result = client
10768                    .request(proto::FormatBuffers {
10769                        project_id,
10770                        trigger: trigger as i32,
10771                        buffer_ids: buffers
10772                            .iter()
10773                            .map(|buffer| buffer.read_with(cx, |buffer, _| buffer.remote_id().to_proto()))
10774                            .collect(),
10775                        buffer_ranges,
10776                    })
10777                    .await
10778                    .and_then(|result| result.transaction.context("missing transaction"));
10779                request_timer.end();
10780
10781                zlog::trace!(logger => "Remote format request resolved to {:?}", result.as_ref().map(|_| "<project_transaction>"));
10782
10783                lsp_store.update(cx, |lsp_store, _| {
10784                    lsp_store.update_last_formatting_failure(&result);
10785                })?;
10786
10787                let transaction_response = result?;
10788                let _timer = zlog::time!(logger => "deserializing project transaction");
10789                buffer_store
10790                    .update(cx, |buffer_store, cx| {
10791                        buffer_store.deserialize_project_transaction(
10792                            transaction_response,
10793                            push_to_history,
10794                            cx,
10795                        )
10796                    })
10797                    .await
10798            })
10799        } else {
10800            zlog::trace!(logger => "Not formatting");
10801            Task::ready(Ok(ProjectTransaction::default()))
10802        }
10803    }
10804
10805    async fn handle_format_buffers(
10806        this: Entity<Self>,
10807        envelope: TypedEnvelope<proto::FormatBuffers>,
10808        mut cx: AsyncApp,
10809    ) -> Result<proto::FormatBuffersResponse> {
10810        let sender_id = envelope.original_sender_id().unwrap_or_default();
10811        let format = this.update(&mut cx, |this, cx| {
10812            let mut buffers = HashSet::default();
10813            for buffer_id in &envelope.payload.buffer_ids {
10814                let buffer_id = BufferId::new(*buffer_id)?;
10815                buffers.insert(this.buffer_store.read(cx).get_existing(buffer_id)?);
10816            }
10817
10818            let target = if envelope.payload.buffer_ranges.is_empty() {
10819                LspFormatTarget::Buffers
10820            } else {
10821                let mut ranges_map = BTreeMap::new();
10822                for buffer_range in &envelope.payload.buffer_ranges {
10823                    let buffer_id = BufferId::new(buffer_range.buffer_id)?;
10824                    let ranges: Result<Vec<_>> = buffer_range
10825                        .ranges
10826                        .iter()
10827                        .map(|range| {
10828                            deserialize_anchor_range(range.clone()).context("invalid anchor range")
10829                        })
10830                        .collect();
10831                    ranges_map.insert(buffer_id, ranges?);
10832                }
10833                LspFormatTarget::Ranges(ranges_map)
10834            };
10835
10836            let trigger = FormatTrigger::from_proto(envelope.payload.trigger);
10837            anyhow::Ok(this.format(buffers, target, false, trigger, cx))
10838        })?;
10839
10840        let project_transaction = format.await?;
10841        let project_transaction = this.update(&mut cx, |this, cx| {
10842            this.buffer_store.update(cx, |buffer_store, cx| {
10843                buffer_store.serialize_project_transaction_for_peer(
10844                    project_transaction,
10845                    sender_id,
10846                    cx,
10847                )
10848            })
10849        });
10850        Ok(proto::FormatBuffersResponse {
10851            transaction: Some(project_transaction),
10852        })
10853    }
10854
10855    async fn handle_apply_code_action_kind(
10856        this: Entity<Self>,
10857        envelope: TypedEnvelope<proto::ApplyCodeActionKind>,
10858        mut cx: AsyncApp,
10859    ) -> Result<proto::ApplyCodeActionKindResponse> {
10860        let sender_id = envelope.original_sender_id().unwrap_or_default();
10861        let format = this.update(&mut cx, |this, cx| {
10862            let mut buffers = HashSet::default();
10863            for buffer_id in &envelope.payload.buffer_ids {
10864                let buffer_id = BufferId::new(*buffer_id)?;
10865                buffers.insert(this.buffer_store.read(cx).get_existing(buffer_id)?);
10866            }
10867            let kind = match envelope.payload.kind.as_str() {
10868                "" => CodeActionKind::EMPTY,
10869                "quickfix" => CodeActionKind::QUICKFIX,
10870                "refactor" => CodeActionKind::REFACTOR,
10871                "refactor.extract" => CodeActionKind::REFACTOR_EXTRACT,
10872                "refactor.inline" => CodeActionKind::REFACTOR_INLINE,
10873                "refactor.rewrite" => CodeActionKind::REFACTOR_REWRITE,
10874                "source" => CodeActionKind::SOURCE,
10875                "source.organizeImports" => CodeActionKind::SOURCE_ORGANIZE_IMPORTS,
10876                "source.fixAll" => CodeActionKind::SOURCE_FIX_ALL,
10877                _ => anyhow::bail!(
10878                    "Invalid code action kind {}",
10879                    envelope.payload.kind.as_str()
10880                ),
10881            };
10882            anyhow::Ok(this.apply_code_action_kind(buffers, kind, false, cx))
10883        })?;
10884
10885        let project_transaction = format.await?;
10886        let project_transaction = this.update(&mut cx, |this, cx| {
10887            this.buffer_store.update(cx, |buffer_store, cx| {
10888                buffer_store.serialize_project_transaction_for_peer(
10889                    project_transaction,
10890                    sender_id,
10891                    cx,
10892                )
10893            })
10894        });
10895        Ok(proto::ApplyCodeActionKindResponse {
10896            transaction: Some(project_transaction),
10897        })
10898    }
10899
10900    async fn shutdown_language_server(
10901        server_state: Option<LanguageServerState>,
10902        name: LanguageServerName,
10903        cx: &mut AsyncApp,
10904    ) {
10905        let server = match server_state {
10906            Some(LanguageServerState::Starting { startup, .. }) => {
10907                let mut timer = cx
10908                    .background_executor()
10909                    .timer(SERVER_LAUNCHING_BEFORE_SHUTDOWN_TIMEOUT)
10910                    .fuse();
10911
10912                select! {
10913                    server = startup.fuse() => server,
10914                    () = timer => {
10915                        log::info!("timeout waiting for language server {name} to finish launching before stopping");
10916                        None
10917                    },
10918                }
10919            }
10920
10921            Some(LanguageServerState::Running { server, .. }) => Some(server),
10922
10923            None => None,
10924        };
10925
10926        if let Some(server) = server
10927            && let Some(shutdown) = server.shutdown()
10928        {
10929            shutdown.await;
10930        }
10931    }
10932
10933    // Returns a list of all of the worktrees which no longer have a language server and the root path
10934    // for the stopped server
10935    fn stop_local_language_server(
10936        &mut self,
10937        server_id: LanguageServerId,
10938        cx: &mut Context<Self>,
10939    ) -> Task<()> {
10940        let local = match &mut self.mode {
10941            LspStoreMode::Local(local) => local,
10942            _ => {
10943                return Task::ready(());
10944            }
10945        };
10946
10947        // Remove this server ID from all entries in the given worktree.
10948        local
10949            .language_server_ids
10950            .retain(|_, state| state.id != server_id);
10951        self.buffer_store.update(cx, |buffer_store, cx| {
10952            for buffer in buffer_store.buffers() {
10953                buffer.update(cx, |buffer, cx| {
10954                    buffer.update_diagnostics(server_id, DiagnosticSet::new([], buffer), cx);
10955                    buffer.set_completion_triggers(server_id, Default::default(), cx);
10956                });
10957            }
10958        });
10959
10960        for (worktree_id, summaries) in self.diagnostic_summaries.iter_mut() {
10961            summaries.retain(|path, summaries_by_server_id| {
10962                if summaries_by_server_id.remove(&server_id).is_some() {
10963                    if let Some((client, project_id)) = self.downstream_client.clone() {
10964                        client
10965                            .send(proto::UpdateDiagnosticSummary {
10966                                project_id,
10967                                worktree_id: worktree_id.to_proto(),
10968                                summary: Some(proto::DiagnosticSummary {
10969                                    path: path.as_ref().to_proto(),
10970                                    language_server_id: server_id.0 as u64,
10971                                    error_count: 0,
10972                                    warning_count: 0,
10973                                }),
10974                                more_summaries: Vec::new(),
10975                            })
10976                            .log_err();
10977                    }
10978                    !summaries_by_server_id.is_empty()
10979                } else {
10980                    true
10981                }
10982            });
10983        }
10984
10985        let local = self.as_local_mut().unwrap();
10986        for diagnostics in local.diagnostics.values_mut() {
10987            diagnostics.retain(|_, diagnostics_by_server_id| {
10988                if let Ok(ix) = diagnostics_by_server_id.binary_search_by_key(&server_id, |e| e.0) {
10989                    diagnostics_by_server_id.remove(ix);
10990                    !diagnostics_by_server_id.is_empty()
10991                } else {
10992                    true
10993                }
10994            });
10995        }
10996        local.language_server_watched_paths.remove(&server_id);
10997
10998        let server_state = local.language_servers.remove(&server_id);
10999        self.cleanup_lsp_data(server_id);
11000        let name = self
11001            .language_server_statuses
11002            .remove(&server_id)
11003            .map(|status| status.name)
11004            .or_else(|| {
11005                if let Some(LanguageServerState::Running { adapter, .. }) = server_state.as_ref() {
11006                    Some(adapter.name())
11007                } else {
11008                    None
11009                }
11010            });
11011
11012        if let Some(name) = name {
11013            log::info!("stopping language server {name}");
11014            self.languages
11015                .update_lsp_binary_status(name.clone(), BinaryStatus::Stopping);
11016            cx.notify();
11017
11018            return cx.spawn(async move |lsp_store, cx| {
11019                Self::shutdown_language_server(server_state, name.clone(), cx).await;
11020                lsp_store
11021                    .update(cx, |lsp_store, cx| {
11022                        lsp_store
11023                            .languages
11024                            .update_lsp_binary_status(name, BinaryStatus::Stopped);
11025                        cx.emit(LspStoreEvent::LanguageServerRemoved(server_id));
11026                        cx.notify();
11027                    })
11028                    .ok();
11029            });
11030        }
11031
11032        if server_state.is_some() {
11033            cx.emit(LspStoreEvent::LanguageServerRemoved(server_id));
11034        }
11035        Task::ready(())
11036    }
11037
11038    pub fn stop_all_language_servers(&mut self, cx: &mut Context<Self>) {
11039        self.shutdown_all_language_servers(cx).detach();
11040    }
11041
11042    pub fn shutdown_all_language_servers(&mut self, cx: &mut Context<Self>) -> Task<()> {
11043        if let Some((client, project_id)) = self.upstream_client() {
11044            let request = client.request(proto::StopLanguageServers {
11045                project_id,
11046                buffer_ids: Vec::new(),
11047                also_servers: Vec::new(),
11048                all: true,
11049            });
11050            cx.background_spawn(async move {
11051                request.await.ok();
11052            })
11053        } else {
11054            let Some(local) = self.as_local_mut() else {
11055                return Task::ready(());
11056            };
11057            let language_servers_to_stop = local
11058                .language_server_ids
11059                .values()
11060                .map(|state| state.id)
11061                .collect();
11062            local.lsp_tree.remove_nodes(&language_servers_to_stop);
11063            let tasks = language_servers_to_stop
11064                .into_iter()
11065                .map(|server| self.stop_local_language_server(server, cx))
11066                .collect::<Vec<_>>();
11067            cx.background_spawn(async move {
11068                futures::future::join_all(tasks).await;
11069            })
11070        }
11071    }
11072
11073    pub fn restart_language_servers_for_buffers(
11074        &mut self,
11075        buffers: Vec<Entity<Buffer>>,
11076        only_restart_servers: HashSet<LanguageServerSelector>,
11077        cx: &mut Context<Self>,
11078    ) {
11079        if let Some((client, project_id)) = self.upstream_client() {
11080            let request = client.request(proto::RestartLanguageServers {
11081                project_id,
11082                buffer_ids: buffers
11083                    .into_iter()
11084                    .map(|b| b.read(cx).remote_id().to_proto())
11085                    .collect(),
11086                only_servers: only_restart_servers
11087                    .into_iter()
11088                    .map(|selector| {
11089                        let selector = match selector {
11090                            LanguageServerSelector::Id(language_server_id) => {
11091                                proto::language_server_selector::Selector::ServerId(
11092                                    language_server_id.to_proto(),
11093                                )
11094                            }
11095                            LanguageServerSelector::Name(language_server_name) => {
11096                                proto::language_server_selector::Selector::Name(
11097                                    language_server_name.to_string(),
11098                                )
11099                            }
11100                        };
11101                        proto::LanguageServerSelector {
11102                            selector: Some(selector),
11103                        }
11104                    })
11105                    .collect(),
11106                all: false,
11107            });
11108            cx.background_spawn(request).detach_and_log_err(cx);
11109        } else {
11110            let stop_task = if only_restart_servers.is_empty() {
11111                self.stop_local_language_servers_for_buffers(&buffers, HashSet::default(), cx)
11112            } else {
11113                self.stop_local_language_servers_for_buffers(&[], only_restart_servers.clone(), cx)
11114            };
11115            cx.spawn(async move |lsp_store, cx| {
11116                stop_task.await;
11117                lsp_store.update(cx, |lsp_store, cx| {
11118                    for buffer in buffers {
11119                        lsp_store.register_buffer_with_language_servers(
11120                            &buffer,
11121                            only_restart_servers.clone(),
11122                            true,
11123                            cx,
11124                        );
11125                    }
11126                })
11127            })
11128            .detach();
11129        }
11130    }
11131
11132    pub fn stop_language_servers_for_buffers(
11133        &mut self,
11134        buffers: Vec<Entity<Buffer>>,
11135        also_stop_servers: HashSet<LanguageServerSelector>,
11136        cx: &mut Context<Self>,
11137    ) -> Task<Result<()>> {
11138        if let Some((client, project_id)) = self.upstream_client() {
11139            let request = client.request(proto::StopLanguageServers {
11140                project_id,
11141                buffer_ids: buffers
11142                    .into_iter()
11143                    .map(|b| b.read(cx).remote_id().to_proto())
11144                    .collect(),
11145                also_servers: also_stop_servers
11146                    .into_iter()
11147                    .map(|selector| {
11148                        let selector = match selector {
11149                            LanguageServerSelector::Id(language_server_id) => {
11150                                proto::language_server_selector::Selector::ServerId(
11151                                    language_server_id.to_proto(),
11152                                )
11153                            }
11154                            LanguageServerSelector::Name(language_server_name) => {
11155                                proto::language_server_selector::Selector::Name(
11156                                    language_server_name.to_string(),
11157                                )
11158                            }
11159                        };
11160                        proto::LanguageServerSelector {
11161                            selector: Some(selector),
11162                        }
11163                    })
11164                    .collect(),
11165                all: false,
11166            });
11167            cx.background_spawn(async move {
11168                let _ = request.await?;
11169                Ok(())
11170            })
11171        } else {
11172            let task =
11173                self.stop_local_language_servers_for_buffers(&buffers, also_stop_servers, cx);
11174            cx.background_spawn(async move {
11175                task.await;
11176                Ok(())
11177            })
11178        }
11179    }
11180
11181    fn stop_local_language_servers_for_buffers(
11182        &mut self,
11183        buffers: &[Entity<Buffer>],
11184        also_stop_servers: HashSet<LanguageServerSelector>,
11185        cx: &mut Context<Self>,
11186    ) -> Task<()> {
11187        let Some(local) = self.as_local_mut() else {
11188            return Task::ready(());
11189        };
11190        let mut language_server_names_to_stop = BTreeSet::default();
11191        let mut language_servers_to_stop = also_stop_servers
11192            .into_iter()
11193            .flat_map(|selector| match selector {
11194                LanguageServerSelector::Id(id) => Some(id),
11195                LanguageServerSelector::Name(name) => {
11196                    language_server_names_to_stop.insert(name);
11197                    None
11198                }
11199            })
11200            .collect::<BTreeSet<_>>();
11201
11202        let mut covered_worktrees = HashSet::default();
11203        for buffer in buffers {
11204            buffer.update(cx, |buffer, cx| {
11205                language_servers_to_stop.extend(local.language_server_ids_for_buffer(buffer, cx));
11206                if let Some(worktree_id) = buffer.file().map(|f| f.worktree_id(cx))
11207                    && covered_worktrees.insert(worktree_id)
11208                {
11209                    language_server_names_to_stop.retain(|name| {
11210                        let old_ids_count = language_servers_to_stop.len();
11211                        let all_language_servers_with_this_name = local
11212                            .language_server_ids
11213                            .iter()
11214                            .filter_map(|(seed, state)| seed.name.eq(name).then(|| state.id));
11215                        language_servers_to_stop.extend(all_language_servers_with_this_name);
11216                        old_ids_count == language_servers_to_stop.len()
11217                    });
11218                }
11219            });
11220        }
11221        for name in language_server_names_to_stop {
11222            language_servers_to_stop.extend(
11223                local
11224                    .language_server_ids
11225                    .iter()
11226                    .filter_map(|(seed, v)| seed.name.eq(&name).then(|| v.id)),
11227            );
11228        }
11229
11230        local.lsp_tree.remove_nodes(&language_servers_to_stop);
11231        let tasks = language_servers_to_stop
11232            .into_iter()
11233            .map(|server| self.stop_local_language_server(server, cx))
11234            .collect::<Vec<_>>();
11235
11236        cx.background_spawn(futures::future::join_all(tasks).map(|_| ()))
11237    }
11238
11239    fn get_buffer<'a>(&self, abs_path: &Path, cx: &'a App) -> Option<&'a Buffer> {
11240        let (worktree, relative_path) =
11241            self.worktree_store.read(cx).find_worktree(&abs_path, cx)?;
11242
11243        let project_path = ProjectPath {
11244            worktree_id: worktree.read(cx).id(),
11245            path: relative_path,
11246        };
11247
11248        Some(
11249            self.buffer_store()
11250                .read(cx)
11251                .get_by_path(&project_path)?
11252                .read(cx),
11253        )
11254    }
11255
11256    #[cfg(any(test, feature = "test-support"))]
11257    pub fn update_diagnostics(
11258        &mut self,
11259        server_id: LanguageServerId,
11260        diagnostics: lsp::PublishDiagnosticsParams,
11261        result_id: Option<SharedString>,
11262        source_kind: DiagnosticSourceKind,
11263        disk_based_sources: &[String],
11264        cx: &mut Context<Self>,
11265    ) -> Result<()> {
11266        self.merge_lsp_diagnostics(
11267            source_kind,
11268            vec![DocumentDiagnosticsUpdate {
11269                diagnostics,
11270                result_id,
11271                server_id,
11272                disk_based_sources: Cow::Borrowed(disk_based_sources),
11273                registration_id: None,
11274            }],
11275            |_, _, _| false,
11276            cx,
11277        )
11278    }
11279
11280    pub fn merge_lsp_diagnostics(
11281        &mut self,
11282        source_kind: DiagnosticSourceKind,
11283        lsp_diagnostics: Vec<DocumentDiagnosticsUpdate<lsp::PublishDiagnosticsParams>>,
11284        merge: impl Fn(&lsp::Uri, &Diagnostic, &App) -> bool + Clone,
11285        cx: &mut Context<Self>,
11286    ) -> Result<()> {
11287        anyhow::ensure!(self.mode.is_local(), "called update_diagnostics on remote");
11288        let updates = lsp_diagnostics
11289            .into_iter()
11290            .filter_map(|update| {
11291                let abs_path = update.diagnostics.uri.to_file_path().ok()?;
11292                Some(DocumentDiagnosticsUpdate {
11293                    diagnostics: self.lsp_to_document_diagnostics(
11294                        abs_path,
11295                        source_kind,
11296                        update.server_id,
11297                        update.diagnostics,
11298                        &update.disk_based_sources,
11299                        update.registration_id.clone(),
11300                    ),
11301                    result_id: update.result_id,
11302                    server_id: update.server_id,
11303                    disk_based_sources: update.disk_based_sources,
11304                    registration_id: update.registration_id,
11305                })
11306            })
11307            .collect();
11308        self.merge_diagnostic_entries(updates, merge, cx)?;
11309        Ok(())
11310    }
11311
11312    fn lsp_to_document_diagnostics(
11313        &mut self,
11314        document_abs_path: PathBuf,
11315        source_kind: DiagnosticSourceKind,
11316        server_id: LanguageServerId,
11317        mut lsp_diagnostics: lsp::PublishDiagnosticsParams,
11318        disk_based_sources: &[String],
11319        registration_id: Option<SharedString>,
11320    ) -> DocumentDiagnostics {
11321        let mut diagnostics = Vec::default();
11322        let mut primary_diagnostic_group_ids = HashMap::default();
11323        let mut sources_by_group_id = HashMap::default();
11324        let mut supporting_diagnostics = HashMap::default();
11325
11326        let adapter = self.language_server_adapter_for_id(server_id);
11327
11328        // Ensure that primary diagnostics are always the most severe
11329        lsp_diagnostics
11330            .diagnostics
11331            .sort_by_key(|item| item.severity);
11332
11333        for diagnostic in &lsp_diagnostics.diagnostics {
11334            let source = diagnostic.source.as_ref();
11335            let range = range_from_lsp(diagnostic.range);
11336            let is_supporting = diagnostic
11337                .related_information
11338                .as_ref()
11339                .is_some_and(|infos| {
11340                    infos.iter().any(|info| {
11341                        primary_diagnostic_group_ids.contains_key(&(
11342                            source,
11343                            diagnostic.code.clone(),
11344                            range_from_lsp(info.location.range),
11345                        ))
11346                    })
11347                });
11348
11349            let is_unnecessary = diagnostic
11350                .tags
11351                .as_ref()
11352                .is_some_and(|tags| tags.contains(&DiagnosticTag::UNNECESSARY));
11353
11354            let underline = self
11355                .language_server_adapter_for_id(server_id)
11356                .is_none_or(|adapter| adapter.underline_diagnostic(diagnostic));
11357
11358            if is_supporting {
11359                supporting_diagnostics.insert(
11360                    (source, diagnostic.code.clone(), range),
11361                    (diagnostic.severity, is_unnecessary),
11362                );
11363            } else {
11364                let group_id = post_inc(&mut self.as_local_mut().unwrap().next_diagnostic_group_id);
11365                let is_disk_based =
11366                    source.is_some_and(|source| disk_based_sources.contains(source));
11367
11368                sources_by_group_id.insert(group_id, source);
11369                primary_diagnostic_group_ids
11370                    .insert((source, diagnostic.code.clone(), range.clone()), group_id);
11371
11372                diagnostics.push(DiagnosticEntry {
11373                    range,
11374                    diagnostic: Diagnostic {
11375                        source: diagnostic.source.clone(),
11376                        source_kind,
11377                        code: diagnostic.code.clone(),
11378                        code_description: diagnostic
11379                            .code_description
11380                            .as_ref()
11381                            .and_then(|d| d.href.clone()),
11382                        severity: diagnostic.severity.unwrap_or(DiagnosticSeverity::ERROR),
11383                        markdown: adapter.as_ref().and_then(|adapter| {
11384                            adapter.diagnostic_message_to_markdown(&diagnostic.message)
11385                        }),
11386                        message: diagnostic.message.trim().to_string(),
11387                        group_id,
11388                        is_primary: true,
11389                        is_disk_based,
11390                        is_unnecessary,
11391                        underline,
11392                        data: diagnostic.data.clone(),
11393                        registration_id: registration_id.clone(),
11394                    },
11395                });
11396                if let Some(infos) = &diagnostic.related_information {
11397                    for info in infos {
11398                        if info.location.uri == lsp_diagnostics.uri && !info.message.is_empty() {
11399                            let range = range_from_lsp(info.location.range);
11400                            diagnostics.push(DiagnosticEntry {
11401                                range,
11402                                diagnostic: Diagnostic {
11403                                    source: diagnostic.source.clone(),
11404                                    source_kind,
11405                                    code: diagnostic.code.clone(),
11406                                    code_description: diagnostic
11407                                        .code_description
11408                                        .as_ref()
11409                                        .and_then(|d| d.href.clone()),
11410                                    severity: DiagnosticSeverity::INFORMATION,
11411                                    markdown: adapter.as_ref().and_then(|adapter| {
11412                                        adapter.diagnostic_message_to_markdown(&info.message)
11413                                    }),
11414                                    message: info.message.trim().to_string(),
11415                                    group_id,
11416                                    is_primary: false,
11417                                    is_disk_based,
11418                                    is_unnecessary: false,
11419                                    underline,
11420                                    data: diagnostic.data.clone(),
11421                                    registration_id: registration_id.clone(),
11422                                },
11423                            });
11424                        }
11425                    }
11426                }
11427            }
11428        }
11429
11430        for entry in &mut diagnostics {
11431            let diagnostic = &mut entry.diagnostic;
11432            if !diagnostic.is_primary {
11433                let source = *sources_by_group_id.get(&diagnostic.group_id).unwrap();
11434                if let Some(&(severity, is_unnecessary)) = supporting_diagnostics.get(&(
11435                    source,
11436                    diagnostic.code.clone(),
11437                    entry.range.clone(),
11438                )) {
11439                    if let Some(severity) = severity {
11440                        diagnostic.severity = severity;
11441                    }
11442                    diagnostic.is_unnecessary = is_unnecessary;
11443                }
11444            }
11445        }
11446
11447        DocumentDiagnostics {
11448            diagnostics,
11449            document_abs_path,
11450            version: lsp_diagnostics.version,
11451        }
11452    }
11453
11454    fn insert_newly_running_language_server(
11455        &mut self,
11456        adapter: Arc<CachedLspAdapter>,
11457        language_server: Arc<LanguageServer>,
11458        server_id: LanguageServerId,
11459        key: LanguageServerSeed,
11460        workspace_folders: Arc<Mutex<BTreeSet<Uri>>>,
11461        cx: &mut Context<Self>,
11462    ) {
11463        let Some(local) = self.as_local_mut() else {
11464            return;
11465        };
11466        // If the language server for this key doesn't match the server id, don't store the
11467        // server. Which will cause it to be dropped, killing the process
11468        if local
11469            .language_server_ids
11470            .get(&key)
11471            .map(|state| state.id != server_id)
11472            .unwrap_or(false)
11473        {
11474            return;
11475        }
11476
11477        // Update language_servers collection with Running variant of LanguageServerState
11478        // indicating that the server is up and running and ready
11479        let workspace_folders = workspace_folders.lock().clone();
11480        language_server.set_workspace_folders(workspace_folders);
11481
11482        let workspace_diagnostics_refresh_tasks = language_server
11483            .capabilities()
11484            .diagnostic_provider
11485            .and_then(|provider| {
11486                local
11487                    .language_server_dynamic_registrations
11488                    .entry(server_id)
11489                    .or_default()
11490                    .diagnostics
11491                    .entry(None)
11492                    .or_insert(provider.clone());
11493                let workspace_refresher =
11494                    lsp_workspace_diagnostics_refresh(None, provider, language_server.clone(), cx)?;
11495
11496                Some((None, workspace_refresher))
11497            })
11498            .into_iter()
11499            .collect();
11500        local.language_servers.insert(
11501            server_id,
11502            LanguageServerState::Running {
11503                workspace_diagnostics_refresh_tasks,
11504                adapter: adapter.clone(),
11505                server: language_server.clone(),
11506                simulate_disk_based_diagnostics_completion: None,
11507            },
11508        );
11509        local
11510            .languages
11511            .update_lsp_binary_status(adapter.name(), BinaryStatus::None);
11512        if let Some(file_ops_caps) = language_server
11513            .capabilities()
11514            .workspace
11515            .as_ref()
11516            .and_then(|ws| ws.file_operations.as_ref())
11517        {
11518            let did_rename_caps = file_ops_caps.did_rename.as_ref();
11519            let will_rename_caps = file_ops_caps.will_rename.as_ref();
11520            if did_rename_caps.or(will_rename_caps).is_some() {
11521                let watcher = RenamePathsWatchedForServer::default()
11522                    .with_did_rename_patterns(did_rename_caps)
11523                    .with_will_rename_patterns(will_rename_caps);
11524                local
11525                    .language_server_paths_watched_for_rename
11526                    .insert(server_id, watcher);
11527            }
11528        }
11529
11530        self.language_server_statuses.insert(
11531            server_id,
11532            LanguageServerStatus {
11533                name: language_server.name(),
11534                server_version: language_server.version(),
11535                pending_work: Default::default(),
11536                has_pending_diagnostic_updates: false,
11537                progress_tokens: Default::default(),
11538                worktree: Some(key.worktree_id),
11539                binary: Some(language_server.binary().clone()),
11540                configuration: Some(language_server.configuration().clone()),
11541                workspace_folders: language_server.workspace_folders(),
11542            },
11543        );
11544
11545        cx.emit(LspStoreEvent::LanguageServerAdded(
11546            server_id,
11547            language_server.name(),
11548            Some(key.worktree_id),
11549        ));
11550
11551        let server_capabilities = language_server.capabilities();
11552        if let Some((downstream_client, project_id)) = self.downstream_client.as_ref() {
11553            downstream_client
11554                .send(proto::StartLanguageServer {
11555                    project_id: *project_id,
11556                    server: Some(proto::LanguageServer {
11557                        id: server_id.to_proto(),
11558                        name: language_server.name().to_string(),
11559                        worktree_id: Some(key.worktree_id.to_proto()),
11560                    }),
11561                    capabilities: serde_json::to_string(&server_capabilities)
11562                        .expect("serializing server LSP capabilities"),
11563                })
11564                .log_err();
11565        }
11566        self.lsp_server_capabilities
11567            .insert(server_id, server_capabilities);
11568
11569        // Tell the language server about every open buffer in the worktree that matches the language.
11570        // Also check for buffers in worktrees that reused this server
11571        let mut worktrees_using_server = vec![key.worktree_id];
11572        if let Some(local) = self.as_local() {
11573            // Find all worktrees that have this server in their language server tree
11574            for (worktree_id, servers) in &local.lsp_tree.instances {
11575                if *worktree_id != key.worktree_id {
11576                    for server_map in servers.roots.values() {
11577                        if server_map
11578                            .values()
11579                            .any(|(node, _)| node.id() == Some(server_id))
11580                        {
11581                            worktrees_using_server.push(*worktree_id);
11582                        }
11583                    }
11584                }
11585            }
11586        }
11587
11588        let mut buffer_paths_registered = Vec::new();
11589        self.buffer_store.clone().update(cx, |buffer_store, cx| {
11590            let mut lsp_adapters = HashMap::default();
11591            for buffer_handle in buffer_store.buffers() {
11592                let buffer = buffer_handle.read(cx);
11593                let file = match File::from_dyn(buffer.file()) {
11594                    Some(file) => file,
11595                    None => continue,
11596                };
11597                let language = match buffer.language() {
11598                    Some(language) => language,
11599                    None => continue,
11600                };
11601
11602                if !worktrees_using_server.contains(&file.worktree.read(cx).id())
11603                    || !lsp_adapters
11604                        .entry(language.name())
11605                        .or_insert_with(|| self.languages.lsp_adapters(&language.name()))
11606                        .iter()
11607                        .any(|a| a.name == key.name)
11608                {
11609                    continue;
11610                }
11611                // didOpen
11612                let file = match file.as_local() {
11613                    Some(file) => file,
11614                    None => continue,
11615                };
11616
11617                let local = self.as_local_mut().unwrap();
11618
11619                let buffer_id = buffer.remote_id();
11620                if local.registered_buffers.contains_key(&buffer_id) {
11621                    let versions = local
11622                        .buffer_snapshots
11623                        .entry(buffer_id)
11624                        .or_default()
11625                        .entry(server_id)
11626                        .and_modify(|_| {
11627                            assert!(
11628                            false,
11629                            "There should not be an existing snapshot for a newly inserted buffer"
11630                        )
11631                        })
11632                        .or_insert_with(|| {
11633                            vec![LspBufferSnapshot {
11634                                version: 0,
11635                                snapshot: buffer.text_snapshot(),
11636                            }]
11637                        });
11638
11639                    let snapshot = versions.last().unwrap();
11640                    let version = snapshot.version;
11641                    let initial_snapshot = &snapshot.snapshot;
11642                    let uri = lsp::Uri::from_file_path(file.abs_path(cx)).unwrap();
11643                    language_server.register_buffer(
11644                        uri,
11645                        adapter.language_id(&language.name()),
11646                        version,
11647                        initial_snapshot.text(),
11648                    );
11649                    buffer_paths_registered.push((buffer_id, file.abs_path(cx)));
11650                    local
11651                        .buffers_opened_in_servers
11652                        .entry(buffer_id)
11653                        .or_default()
11654                        .insert(server_id);
11655                }
11656                buffer_handle.update(cx, |buffer, cx| {
11657                    buffer.set_completion_triggers(
11658                        server_id,
11659                        language_server
11660                            .capabilities()
11661                            .completion_provider
11662                            .as_ref()
11663                            .and_then(|provider| {
11664                                provider
11665                                    .trigger_characters
11666                                    .as_ref()
11667                                    .map(|characters| characters.iter().cloned().collect())
11668                            })
11669                            .unwrap_or_default(),
11670                        cx,
11671                    )
11672                });
11673            }
11674        });
11675
11676        for (buffer_id, abs_path) in buffer_paths_registered {
11677            cx.emit(LspStoreEvent::LanguageServerUpdate {
11678                language_server_id: server_id,
11679                name: Some(adapter.name()),
11680                message: proto::update_language_server::Variant::RegisteredForBuffer(
11681                    proto::RegisteredForBuffer {
11682                        buffer_abs_path: abs_path.to_string_lossy().into_owned(),
11683                        buffer_id: buffer_id.to_proto(),
11684                    },
11685                ),
11686            });
11687        }
11688
11689        cx.notify();
11690    }
11691
11692    pub fn language_servers_running_disk_based_diagnostics(
11693        &self,
11694    ) -> impl Iterator<Item = LanguageServerId> + '_ {
11695        self.language_server_statuses
11696            .iter()
11697            .filter_map(|(id, status)| {
11698                if status.has_pending_diagnostic_updates {
11699                    Some(*id)
11700                } else {
11701                    None
11702                }
11703            })
11704    }
11705
11706    pub(crate) fn cancel_language_server_work_for_buffers(
11707        &mut self,
11708        buffers: impl IntoIterator<Item = Entity<Buffer>>,
11709        cx: &mut Context<Self>,
11710    ) {
11711        if let Some((client, project_id)) = self.upstream_client() {
11712            let request = client.request(proto::CancelLanguageServerWork {
11713                project_id,
11714                work: Some(proto::cancel_language_server_work::Work::Buffers(
11715                    proto::cancel_language_server_work::Buffers {
11716                        buffer_ids: buffers
11717                            .into_iter()
11718                            .map(|b| b.read(cx).remote_id().to_proto())
11719                            .collect(),
11720                    },
11721                )),
11722            });
11723            cx.background_spawn(request).detach_and_log_err(cx);
11724        } else if let Some(local) = self.as_local() {
11725            let servers = buffers
11726                .into_iter()
11727                .flat_map(|buffer| {
11728                    buffer.update(cx, |buffer, cx| {
11729                        local.language_server_ids_for_buffer(buffer, cx).into_iter()
11730                    })
11731                })
11732                .collect::<HashSet<_>>();
11733            for server_id in servers {
11734                self.cancel_language_server_work(server_id, None, cx);
11735            }
11736        }
11737    }
11738
11739    pub(crate) fn cancel_language_server_work(
11740        &mut self,
11741        server_id: LanguageServerId,
11742        token_to_cancel: Option<ProgressToken>,
11743        cx: &mut Context<Self>,
11744    ) {
11745        if let Some(local) = self.as_local() {
11746            let status = self.language_server_statuses.get(&server_id);
11747            let server = local.language_servers.get(&server_id);
11748            if let Some((LanguageServerState::Running { server, .. }, status)) = server.zip(status)
11749            {
11750                for (token, progress) in &status.pending_work {
11751                    if let Some(token_to_cancel) = token_to_cancel.as_ref()
11752                        && token != token_to_cancel
11753                    {
11754                        continue;
11755                    }
11756                    if progress.is_cancellable {
11757                        server
11758                            .notify::<lsp::notification::WorkDoneProgressCancel>(
11759                                WorkDoneProgressCancelParams {
11760                                    token: token.to_lsp(),
11761                                },
11762                            )
11763                            .ok();
11764                    }
11765                }
11766            }
11767        } else if let Some((client, project_id)) = self.upstream_client() {
11768            let request = client.request(proto::CancelLanguageServerWork {
11769                project_id,
11770                work: Some(
11771                    proto::cancel_language_server_work::Work::LanguageServerWork(
11772                        proto::cancel_language_server_work::LanguageServerWork {
11773                            language_server_id: server_id.to_proto(),
11774                            token: token_to_cancel.map(|token| token.to_proto()),
11775                        },
11776                    ),
11777                ),
11778            });
11779            cx.background_spawn(request).detach_and_log_err(cx);
11780        }
11781    }
11782
11783    fn register_supplementary_language_server(
11784        &mut self,
11785        id: LanguageServerId,
11786        name: LanguageServerName,
11787        server: Arc<LanguageServer>,
11788        cx: &mut Context<Self>,
11789    ) {
11790        if let Some(local) = self.as_local_mut() {
11791            local
11792                .supplementary_language_servers
11793                .insert(id, (name.clone(), server));
11794            cx.emit(LspStoreEvent::LanguageServerAdded(id, name, None));
11795        }
11796    }
11797
11798    fn unregister_supplementary_language_server(
11799        &mut self,
11800        id: LanguageServerId,
11801        cx: &mut Context<Self>,
11802    ) {
11803        if let Some(local) = self.as_local_mut() {
11804            local.supplementary_language_servers.remove(&id);
11805            cx.emit(LspStoreEvent::LanguageServerRemoved(id));
11806        }
11807    }
11808
11809    pub(crate) fn supplementary_language_servers(
11810        &self,
11811    ) -> impl '_ + Iterator<Item = (LanguageServerId, LanguageServerName)> {
11812        self.as_local().into_iter().flat_map(|local| {
11813            local
11814                .supplementary_language_servers
11815                .iter()
11816                .map(|(id, (name, _))| (*id, name.clone()))
11817        })
11818    }
11819
11820    pub fn language_server_adapter_for_id(
11821        &self,
11822        id: LanguageServerId,
11823    ) -> Option<Arc<CachedLspAdapter>> {
11824        self.as_local()
11825            .and_then(|local| local.language_servers.get(&id))
11826            .and_then(|language_server_state| match language_server_state {
11827                LanguageServerState::Running { adapter, .. } => Some(adapter.clone()),
11828                _ => None,
11829            })
11830    }
11831
11832    pub(super) fn update_local_worktree_language_servers(
11833        &mut self,
11834        worktree_handle: &Entity<Worktree>,
11835        changes: &[(Arc<RelPath>, ProjectEntryId, PathChange)],
11836        cx: &mut Context<Self>,
11837    ) {
11838        if changes.is_empty() {
11839            return;
11840        }
11841
11842        let Some(local) = self.as_local() else { return };
11843
11844        local.prettier_store.update(cx, |prettier_store, cx| {
11845            prettier_store.update_prettier_settings(worktree_handle, changes, cx)
11846        });
11847
11848        let worktree_id = worktree_handle.read(cx).id();
11849        let mut language_server_ids = local
11850            .language_server_ids
11851            .iter()
11852            .filter_map(|(seed, v)| seed.worktree_id.eq(&worktree_id).then(|| v.id))
11853            .collect::<Vec<_>>();
11854        language_server_ids.sort();
11855        language_server_ids.dedup();
11856
11857        // let abs_path = worktree_handle.read(cx).abs_path();
11858        for server_id in &language_server_ids {
11859            if let Some(LanguageServerState::Running { server, .. }) =
11860                local.language_servers.get(server_id)
11861                && let Some(watched_paths) = local
11862                    .language_server_watched_paths
11863                    .get(server_id)
11864                    .and_then(|paths| paths.worktree_paths.get(&worktree_id))
11865            {
11866                let params = lsp::DidChangeWatchedFilesParams {
11867                    changes: changes
11868                        .iter()
11869                        .filter_map(|(path, _, change)| {
11870                            if !watched_paths.is_match(path.as_std_path()) {
11871                                return None;
11872                            }
11873                            let typ = match change {
11874                                PathChange::Loaded => return None,
11875                                PathChange::Added => lsp::FileChangeType::CREATED,
11876                                PathChange::Removed => lsp::FileChangeType::DELETED,
11877                                PathChange::Updated => lsp::FileChangeType::CHANGED,
11878                                PathChange::AddedOrUpdated => lsp::FileChangeType::CHANGED,
11879                            };
11880                            let uri = lsp::Uri::from_file_path(
11881                                worktree_handle.read(cx).absolutize(&path),
11882                            )
11883                            .ok()?;
11884                            Some(lsp::FileEvent { uri, typ })
11885                        })
11886                        .collect(),
11887                };
11888                if !params.changes.is_empty() {
11889                    server
11890                        .notify::<lsp::notification::DidChangeWatchedFiles>(params)
11891                        .ok();
11892                }
11893            }
11894        }
11895        for (path, _, _) in changes {
11896            if let Some(file_name) = path.file_name()
11897                && local.watched_manifest_filenames.contains(file_name)
11898            {
11899                self.request_workspace_config_refresh();
11900                break;
11901            }
11902        }
11903    }
11904
11905    pub fn wait_for_remote_buffer(
11906        &mut self,
11907        id: BufferId,
11908        cx: &mut Context<Self>,
11909    ) -> Task<Result<Entity<Buffer>>> {
11910        self.buffer_store.update(cx, |buffer_store, cx| {
11911            buffer_store.wait_for_remote_buffer(id, cx)
11912        })
11913    }
11914
11915    fn serialize_symbol(symbol: &Symbol) -> proto::Symbol {
11916        let mut result = proto::Symbol {
11917            language_server_name: symbol.language_server_name.0.to_string(),
11918            source_worktree_id: symbol.source_worktree_id.to_proto(),
11919            language_server_id: symbol.source_language_server_id.to_proto(),
11920            name: symbol.name.clone(),
11921            kind: unsafe { mem::transmute::<lsp::SymbolKind, i32>(symbol.kind) },
11922            start: Some(proto::PointUtf16 {
11923                row: symbol.range.start.0.row,
11924                column: symbol.range.start.0.column,
11925            }),
11926            end: Some(proto::PointUtf16 {
11927                row: symbol.range.end.0.row,
11928                column: symbol.range.end.0.column,
11929            }),
11930            worktree_id: Default::default(),
11931            path: Default::default(),
11932            signature: Default::default(),
11933        };
11934        match &symbol.path {
11935            SymbolLocation::InProject(path) => {
11936                result.worktree_id = path.worktree_id.to_proto();
11937                result.path = path.path.to_proto();
11938            }
11939            SymbolLocation::OutsideProject {
11940                abs_path,
11941                signature,
11942            } => {
11943                result.path = abs_path.to_string_lossy().into_owned();
11944                result.signature = signature.to_vec();
11945            }
11946        }
11947        result
11948    }
11949
11950    fn deserialize_symbol(serialized_symbol: proto::Symbol) -> Result<CoreSymbol> {
11951        let source_worktree_id = WorktreeId::from_proto(serialized_symbol.source_worktree_id);
11952        let worktree_id = WorktreeId::from_proto(serialized_symbol.worktree_id);
11953        let kind = unsafe { mem::transmute::<i32, lsp::SymbolKind>(serialized_symbol.kind) };
11954
11955        let path = if serialized_symbol.signature.is_empty() {
11956            SymbolLocation::InProject(ProjectPath {
11957                worktree_id,
11958                path: RelPath::from_proto(&serialized_symbol.path)
11959                    .context("invalid symbol path")?,
11960            })
11961        } else {
11962            SymbolLocation::OutsideProject {
11963                abs_path: Path::new(&serialized_symbol.path).into(),
11964                signature: serialized_symbol
11965                    .signature
11966                    .try_into()
11967                    .map_err(|_| anyhow!("invalid signature"))?,
11968            }
11969        };
11970
11971        let start = serialized_symbol.start.context("invalid start")?;
11972        let end = serialized_symbol.end.context("invalid end")?;
11973        Ok(CoreSymbol {
11974            language_server_name: LanguageServerName(serialized_symbol.language_server_name.into()),
11975            source_worktree_id,
11976            source_language_server_id: LanguageServerId::from_proto(
11977                serialized_symbol.language_server_id,
11978            ),
11979            path,
11980            name: serialized_symbol.name,
11981            range: Unclipped(PointUtf16::new(start.row, start.column))
11982                ..Unclipped(PointUtf16::new(end.row, end.column)),
11983            kind,
11984        })
11985    }
11986
11987    pub(crate) fn serialize_completion(completion: &CoreCompletion) -> proto::Completion {
11988        let mut serialized_completion = proto::Completion {
11989            old_replace_start: Some(serialize_anchor(&completion.replace_range.start)),
11990            old_replace_end: Some(serialize_anchor(&completion.replace_range.end)),
11991            new_text: completion.new_text.clone(),
11992            ..proto::Completion::default()
11993        };
11994        match &completion.source {
11995            CompletionSource::Lsp {
11996                insert_range,
11997                server_id,
11998                lsp_completion,
11999                lsp_defaults,
12000                resolved,
12001            } => {
12002                let (old_insert_start, old_insert_end) = insert_range
12003                    .as_ref()
12004                    .map(|range| (serialize_anchor(&range.start), serialize_anchor(&range.end)))
12005                    .unzip();
12006
12007                serialized_completion.old_insert_start = old_insert_start;
12008                serialized_completion.old_insert_end = old_insert_end;
12009                serialized_completion.source = proto::completion::Source::Lsp as i32;
12010                serialized_completion.server_id = server_id.0 as u64;
12011                serialized_completion.lsp_completion = serde_json::to_vec(lsp_completion).unwrap();
12012                serialized_completion.lsp_defaults = lsp_defaults
12013                    .as_deref()
12014                    .map(|lsp_defaults| serde_json::to_vec(lsp_defaults).unwrap());
12015                serialized_completion.resolved = *resolved;
12016            }
12017            CompletionSource::BufferWord {
12018                word_range,
12019                resolved,
12020            } => {
12021                serialized_completion.source = proto::completion::Source::BufferWord as i32;
12022                serialized_completion.buffer_word_start = Some(serialize_anchor(&word_range.start));
12023                serialized_completion.buffer_word_end = Some(serialize_anchor(&word_range.end));
12024                serialized_completion.resolved = *resolved;
12025            }
12026            CompletionSource::Custom => {
12027                serialized_completion.source = proto::completion::Source::Custom as i32;
12028                serialized_completion.resolved = true;
12029            }
12030            CompletionSource::Dap { sort_text } => {
12031                serialized_completion.source = proto::completion::Source::Dap as i32;
12032                serialized_completion.sort_text = Some(sort_text.clone());
12033            }
12034        }
12035
12036        serialized_completion
12037    }
12038
12039    pub(crate) fn deserialize_completion(completion: proto::Completion) -> Result<CoreCompletion> {
12040        let old_replace_start = completion
12041            .old_replace_start
12042            .and_then(deserialize_anchor)
12043            .context("invalid old start")?;
12044        let old_replace_end = completion
12045            .old_replace_end
12046            .and_then(deserialize_anchor)
12047            .context("invalid old end")?;
12048        let insert_range = {
12049            match completion.old_insert_start.zip(completion.old_insert_end) {
12050                Some((start, end)) => {
12051                    let start = deserialize_anchor(start).context("invalid insert old start")?;
12052                    let end = deserialize_anchor(end).context("invalid insert old end")?;
12053                    Some(start..end)
12054                }
12055                None => None,
12056            }
12057        };
12058        Ok(CoreCompletion {
12059            replace_range: old_replace_start..old_replace_end,
12060            new_text: completion.new_text,
12061            source: match proto::completion::Source::from_i32(completion.source) {
12062                Some(proto::completion::Source::Custom) => CompletionSource::Custom,
12063                Some(proto::completion::Source::Lsp) => CompletionSource::Lsp {
12064                    insert_range,
12065                    server_id: LanguageServerId::from_proto(completion.server_id),
12066                    lsp_completion: serde_json::from_slice(&completion.lsp_completion)?,
12067                    lsp_defaults: completion
12068                        .lsp_defaults
12069                        .as_deref()
12070                        .map(serde_json::from_slice)
12071                        .transpose()?,
12072                    resolved: completion.resolved,
12073                },
12074                Some(proto::completion::Source::BufferWord) => {
12075                    let word_range = completion
12076                        .buffer_word_start
12077                        .and_then(deserialize_anchor)
12078                        .context("invalid buffer word start")?
12079                        ..completion
12080                            .buffer_word_end
12081                            .and_then(deserialize_anchor)
12082                            .context("invalid buffer word end")?;
12083                    CompletionSource::BufferWord {
12084                        word_range,
12085                        resolved: completion.resolved,
12086                    }
12087                }
12088                Some(proto::completion::Source::Dap) => CompletionSource::Dap {
12089                    sort_text: completion
12090                        .sort_text
12091                        .context("expected sort text to exist")?,
12092                },
12093                _ => anyhow::bail!("Unexpected completion source {}", completion.source),
12094            },
12095        })
12096    }
12097
12098    pub(crate) fn serialize_code_action(action: &CodeAction) -> proto::CodeAction {
12099        let (kind, lsp_action) = match &action.lsp_action {
12100            LspAction::Action(code_action) => (
12101                proto::code_action::Kind::Action as i32,
12102                serde_json::to_vec(code_action).unwrap(),
12103            ),
12104            LspAction::Command(command) => (
12105                proto::code_action::Kind::Command as i32,
12106                serde_json::to_vec(command).unwrap(),
12107            ),
12108            LspAction::CodeLens(code_lens) => (
12109                proto::code_action::Kind::CodeLens as i32,
12110                serde_json::to_vec(code_lens).unwrap(),
12111            ),
12112        };
12113
12114        proto::CodeAction {
12115            server_id: action.server_id.0 as u64,
12116            start: Some(serialize_anchor(&action.range.start)),
12117            end: Some(serialize_anchor(&action.range.end)),
12118            lsp_action,
12119            kind,
12120            resolved: action.resolved,
12121        }
12122    }
12123
12124    pub(crate) fn deserialize_code_action(action: proto::CodeAction) -> Result<CodeAction> {
12125        let start = action
12126            .start
12127            .and_then(deserialize_anchor)
12128            .context("invalid start")?;
12129        let end = action
12130            .end
12131            .and_then(deserialize_anchor)
12132            .context("invalid end")?;
12133        let lsp_action = match proto::code_action::Kind::from_i32(action.kind) {
12134            Some(proto::code_action::Kind::Action) => {
12135                LspAction::Action(serde_json::from_slice(&action.lsp_action)?)
12136            }
12137            Some(proto::code_action::Kind::Command) => {
12138                LspAction::Command(serde_json::from_slice(&action.lsp_action)?)
12139            }
12140            Some(proto::code_action::Kind::CodeLens) => {
12141                LspAction::CodeLens(serde_json::from_slice(&action.lsp_action)?)
12142            }
12143            None => anyhow::bail!("Unknown action kind {}", action.kind),
12144        };
12145        Ok(CodeAction {
12146            server_id: LanguageServerId(action.server_id as usize),
12147            range: start..end,
12148            resolved: action.resolved,
12149            lsp_action,
12150        })
12151    }
12152
12153    fn update_last_formatting_failure<T>(&mut self, formatting_result: &anyhow::Result<T>) {
12154        match &formatting_result {
12155            Ok(_) => self.last_formatting_failure = None,
12156            Err(error) => {
12157                let error_string = format!("{error:#}");
12158                log::error!("Formatting failed: {error_string}");
12159                self.last_formatting_failure
12160                    .replace(error_string.lines().join(" "));
12161            }
12162        }
12163    }
12164
12165    fn cleanup_lsp_data(&mut self, for_server: LanguageServerId) {
12166        self.lsp_server_capabilities.remove(&for_server);
12167        for lsp_data in self.lsp_data.values_mut() {
12168            lsp_data.remove_server_data(for_server);
12169        }
12170        if let Some(local) = self.as_local_mut() {
12171            local.buffer_pull_diagnostics_result_ids.remove(&for_server);
12172            local
12173                .workspace_pull_diagnostics_result_ids
12174                .remove(&for_server);
12175            for buffer_servers in local.buffers_opened_in_servers.values_mut() {
12176                buffer_servers.remove(&for_server);
12177            }
12178        }
12179    }
12180
12181    pub fn result_id_for_buffer_pull(
12182        &self,
12183        server_id: LanguageServerId,
12184        buffer_id: BufferId,
12185        registration_id: &Option<SharedString>,
12186        cx: &App,
12187    ) -> Option<SharedString> {
12188        let abs_path = self
12189            .buffer_store
12190            .read(cx)
12191            .get(buffer_id)
12192            .and_then(|b| File::from_dyn(b.read(cx).file()))
12193            .map(|f| f.abs_path(cx))?;
12194        self.as_local()?
12195            .buffer_pull_diagnostics_result_ids
12196            .get(&server_id)?
12197            .get(registration_id)?
12198            .get(&abs_path)?
12199            .clone()
12200    }
12201
12202    /// Gets all result_ids for a workspace diagnostics pull request.
12203    /// 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.
12204    /// The latter is supposed to be of lower priority as we keep on pulling diagnostics for open buffers eagerly.
12205    pub fn result_ids_for_workspace_refresh(
12206        &self,
12207        server_id: LanguageServerId,
12208        registration_id: &Option<SharedString>,
12209    ) -> HashMap<PathBuf, SharedString> {
12210        let Some(local) = self.as_local() else {
12211            return HashMap::default();
12212        };
12213        local
12214            .workspace_pull_diagnostics_result_ids
12215            .get(&server_id)
12216            .into_iter()
12217            .filter_map(|diagnostics| diagnostics.get(registration_id))
12218            .flatten()
12219            .filter_map(|(abs_path, result_id)| {
12220                let result_id = local
12221                    .buffer_pull_diagnostics_result_ids
12222                    .get(&server_id)
12223                    .and_then(|buffer_ids_result_ids| {
12224                        buffer_ids_result_ids.get(registration_id)?.get(abs_path)
12225                    })
12226                    .cloned()
12227                    .flatten()
12228                    .or_else(|| result_id.clone())?;
12229                Some((abs_path.clone(), result_id))
12230            })
12231            .collect()
12232    }
12233
12234    pub fn pull_workspace_diagnostics(&mut self, server_id: LanguageServerId) {
12235        if let Some(LanguageServerState::Running {
12236            workspace_diagnostics_refresh_tasks,
12237            ..
12238        }) = self
12239            .as_local_mut()
12240            .and_then(|local| local.language_servers.get_mut(&server_id))
12241        {
12242            for diagnostics in workspace_diagnostics_refresh_tasks.values_mut() {
12243                diagnostics.refresh_tx.try_send(()).ok();
12244            }
12245        }
12246    }
12247
12248    /// Refreshes `textDocument/diagnostic` for all open buffers associated with the given server.
12249    /// This is called in response to `workspace/diagnostic/refresh` to comply with the LSP spec,
12250    /// which requires refreshing both workspace and document diagnostics.
12251    pub fn pull_document_diagnostics_for_server(
12252        &mut self,
12253        server_id: LanguageServerId,
12254        cx: &mut Context<Self>,
12255    ) -> Task<()> {
12256        let buffers_to_pull = self
12257            .as_local()
12258            .into_iter()
12259            .flat_map(|local| {
12260                self.buffer_store.read(cx).buffers().filter(|buffer| {
12261                    let buffer_id = buffer.read(cx).remote_id();
12262                    local
12263                        .buffers_opened_in_servers
12264                        .get(&buffer_id)
12265                        .is_some_and(|servers| servers.contains(&server_id))
12266                })
12267            })
12268            .collect::<Vec<_>>();
12269
12270        let pulls = join_all(buffers_to_pull.into_iter().map(|buffer| {
12271            let buffer_path = buffer.read(cx).file().map(|f| f.full_path(cx));
12272            let pull_task = self.pull_diagnostics_for_buffer(buffer, cx);
12273            async move { (buffer_path, pull_task.await) }
12274        }));
12275        cx.background_spawn(async move {
12276            for (pull_task_path, pull_task_result) in pulls.await {
12277                if let Err(e) = pull_task_result {
12278                    match pull_task_path {
12279                        Some(path) => {
12280                            log::error!("Failed to pull diagnostics for buffer {path:?}: {e:#}");
12281                        }
12282                        None => log::error!("Failed to pull diagnostics: {e:#}"),
12283                    }
12284                }
12285            }
12286        })
12287    }
12288
12289    fn apply_workspace_diagnostic_report(
12290        &mut self,
12291        server_id: LanguageServerId,
12292        report: lsp::WorkspaceDiagnosticReportResult,
12293        registration_id: Option<SharedString>,
12294        cx: &mut Context<Self>,
12295    ) {
12296        let mut workspace_diagnostics =
12297            GetDocumentDiagnostics::deserialize_workspace_diagnostics_report(
12298                report,
12299                server_id,
12300                registration_id,
12301            );
12302        workspace_diagnostics.retain(|d| match &d.diagnostics {
12303            LspPullDiagnostics::Response {
12304                server_id,
12305                registration_id,
12306                ..
12307            } => self.diagnostic_registration_exists(*server_id, registration_id),
12308            LspPullDiagnostics::Default => false,
12309        });
12310        let mut unchanged_buffers = HashMap::default();
12311        let workspace_diagnostics_updates = workspace_diagnostics
12312            .into_iter()
12313            .filter_map(
12314                |workspace_diagnostics| match workspace_diagnostics.diagnostics {
12315                    LspPullDiagnostics::Response {
12316                        server_id,
12317                        uri,
12318                        diagnostics,
12319                        registration_id,
12320                    } => Some((
12321                        server_id,
12322                        uri,
12323                        diagnostics,
12324                        workspace_diagnostics.version,
12325                        registration_id,
12326                    )),
12327                    LspPullDiagnostics::Default => None,
12328                },
12329            )
12330            .fold(
12331                HashMap::default(),
12332                |mut acc, (server_id, uri, diagnostics, version, new_registration_id)| {
12333                    let (result_id, diagnostics) = match diagnostics {
12334                        PulledDiagnostics::Unchanged { result_id } => {
12335                            unchanged_buffers
12336                                .entry(new_registration_id.clone())
12337                                .or_insert_with(HashSet::default)
12338                                .insert(uri.clone());
12339                            (Some(result_id), Vec::new())
12340                        }
12341                        PulledDiagnostics::Changed {
12342                            result_id,
12343                            diagnostics,
12344                        } => (result_id, diagnostics),
12345                    };
12346                    let disk_based_sources = Cow::Owned(
12347                        self.language_server_adapter_for_id(server_id)
12348                            .as_ref()
12349                            .map(|adapter| adapter.disk_based_diagnostic_sources.as_slice())
12350                            .unwrap_or(&[])
12351                            .to_vec(),
12352                    );
12353
12354                    let Some(abs_path) = uri.to_file_path().ok() else {
12355                        return acc;
12356                    };
12357                    let Some((worktree, relative_path)) =
12358                        self.worktree_store.read(cx).find_worktree(abs_path.clone(), cx)
12359                    else {
12360                        log::warn!("skipping workspace diagnostics update, no worktree found for path {abs_path:?}");
12361                        return acc;
12362                    };
12363                    let worktree_id = worktree.read(cx).id();
12364                    let project_path = ProjectPath {
12365                        worktree_id,
12366                        path: relative_path,
12367                    };
12368                    if let Some(local_lsp_store) = self.as_local_mut() {
12369                        local_lsp_store.workspace_pull_diagnostics_result_ids.entry(server_id)
12370                            .or_default().entry(new_registration_id.clone()).or_default().insert(abs_path, result_id.clone());
12371                    }
12372                    // The LSP spec recommends that "diagnostics from a document pull should win over diagnostics from a workspace pull."
12373                    // Since we actively pull diagnostics for documents with open buffers, we ignore contents of workspace pulls for these documents.
12374                    if self.buffer_store.read(cx).get_by_path(&project_path).is_none() {
12375                        acc.entry(server_id)
12376                            .or_insert_with(HashMap::default)
12377                            .entry(new_registration_id.clone())
12378                            .or_insert_with(Vec::new)
12379                            .push(DocumentDiagnosticsUpdate {
12380                                server_id,
12381                                diagnostics: lsp::PublishDiagnosticsParams {
12382                                    uri,
12383                                    diagnostics,
12384                                    version,
12385                                },
12386                                result_id,
12387                                disk_based_sources,
12388                                registration_id: new_registration_id,
12389                            });
12390                    }
12391                    acc
12392                },
12393            );
12394
12395        for diagnostic_updates in workspace_diagnostics_updates.into_values() {
12396            for (registration_id, diagnostic_updates) in diagnostic_updates {
12397                self.merge_lsp_diagnostics(
12398                    DiagnosticSourceKind::Pulled,
12399                    diagnostic_updates,
12400                    |document_uri, old_diagnostic, _| match old_diagnostic.source_kind {
12401                        DiagnosticSourceKind::Pulled => {
12402                            old_diagnostic.registration_id != registration_id
12403                                || unchanged_buffers
12404                                    .get(&old_diagnostic.registration_id)
12405                                    .is_some_and(|unchanged_buffers| {
12406                                        unchanged_buffers.contains(&document_uri)
12407                                    })
12408                        }
12409                        DiagnosticSourceKind::Other | DiagnosticSourceKind::Pushed => true,
12410                    },
12411                    cx,
12412                )
12413                .log_err();
12414            }
12415        }
12416    }
12417
12418    fn register_server_capabilities(
12419        &mut self,
12420        server_id: LanguageServerId,
12421        params: lsp::RegistrationParams,
12422        cx: &mut Context<Self>,
12423    ) -> anyhow::Result<()> {
12424        let server = self
12425            .language_server_for_id(server_id)
12426            .with_context(|| format!("no server {server_id} found"))?;
12427        for reg in params.registrations {
12428            match reg.method.as_str() {
12429                "workspace/didChangeWatchedFiles" => {
12430                    if let Some(options) = reg.register_options {
12431                        let notify = if let Some(local_lsp_store) = self.as_local_mut() {
12432                            let caps = serde_json::from_value(options)?;
12433                            local_lsp_store
12434                                .on_lsp_did_change_watched_files(server_id, &reg.id, caps, cx);
12435                            true
12436                        } else {
12437                            false
12438                        };
12439                        if notify {
12440                            notify_server_capabilities_updated(&server, cx);
12441                        }
12442                    }
12443                }
12444                "workspace/didChangeConfiguration" => {
12445                    // Ignore payload since we notify clients of setting changes unconditionally, relying on them pulling the latest settings.
12446                }
12447                "workspace/didChangeWorkspaceFolders" => {
12448                    // In this case register options is an empty object, we can ignore it
12449                    let caps = lsp::WorkspaceFoldersServerCapabilities {
12450                        supported: Some(true),
12451                        change_notifications: Some(OneOf::Right(reg.id)),
12452                    };
12453                    server.update_capabilities(|capabilities| {
12454                        capabilities
12455                            .workspace
12456                            .get_or_insert_default()
12457                            .workspace_folders = Some(caps);
12458                    });
12459                    notify_server_capabilities_updated(&server, cx);
12460                }
12461                "workspace/symbol" => {
12462                    let options = parse_register_capabilities(reg)?;
12463                    server.update_capabilities(|capabilities| {
12464                        capabilities.workspace_symbol_provider = Some(options);
12465                    });
12466                    notify_server_capabilities_updated(&server, cx);
12467                }
12468                "workspace/fileOperations" => {
12469                    if let Some(options) = reg.register_options {
12470                        let caps = serde_json::from_value(options)?;
12471                        server.update_capabilities(|capabilities| {
12472                            capabilities
12473                                .workspace
12474                                .get_or_insert_default()
12475                                .file_operations = Some(caps);
12476                        });
12477                        notify_server_capabilities_updated(&server, cx);
12478                    }
12479                }
12480                "workspace/executeCommand" => {
12481                    if let Some(options) = reg.register_options {
12482                        let options = serde_json::from_value(options)?;
12483                        server.update_capabilities(|capabilities| {
12484                            capabilities.execute_command_provider = Some(options);
12485                        });
12486                        notify_server_capabilities_updated(&server, cx);
12487                    }
12488                }
12489                "textDocument/rangeFormatting" => {
12490                    let options = parse_register_capabilities(reg)?;
12491                    server.update_capabilities(|capabilities| {
12492                        capabilities.document_range_formatting_provider = Some(options);
12493                    });
12494                    notify_server_capabilities_updated(&server, cx);
12495                }
12496                "textDocument/onTypeFormatting" => {
12497                    if let Some(options) = reg
12498                        .register_options
12499                        .map(serde_json::from_value)
12500                        .transpose()?
12501                    {
12502                        server.update_capabilities(|capabilities| {
12503                            capabilities.document_on_type_formatting_provider = Some(options);
12504                        });
12505                        notify_server_capabilities_updated(&server, cx);
12506                    }
12507                }
12508                "textDocument/formatting" => {
12509                    let options = parse_register_capabilities(reg)?;
12510                    server.update_capabilities(|capabilities| {
12511                        capabilities.document_formatting_provider = Some(options);
12512                    });
12513                    notify_server_capabilities_updated(&server, cx);
12514                }
12515                "textDocument/rename" => {
12516                    let options = parse_register_capabilities(reg)?;
12517                    server.update_capabilities(|capabilities| {
12518                        capabilities.rename_provider = Some(options);
12519                    });
12520                    notify_server_capabilities_updated(&server, cx);
12521                }
12522                "textDocument/inlayHint" => {
12523                    let options = parse_register_capabilities(reg)?;
12524                    server.update_capabilities(|capabilities| {
12525                        capabilities.inlay_hint_provider = Some(options);
12526                    });
12527                    notify_server_capabilities_updated(&server, cx);
12528                }
12529                "textDocument/documentSymbol" => {
12530                    let options = parse_register_capabilities(reg)?;
12531                    server.update_capabilities(|capabilities| {
12532                        capabilities.document_symbol_provider = Some(options);
12533                    });
12534                    notify_server_capabilities_updated(&server, cx);
12535                }
12536                "textDocument/codeAction" => {
12537                    let options = parse_register_capabilities(reg)?;
12538                    let provider = match options {
12539                        OneOf::Left(value) => lsp::CodeActionProviderCapability::Simple(value),
12540                        OneOf::Right(caps) => caps,
12541                    };
12542                    server.update_capabilities(|capabilities| {
12543                        capabilities.code_action_provider = Some(provider);
12544                    });
12545                    notify_server_capabilities_updated(&server, cx);
12546                }
12547                "textDocument/definition" => {
12548                    let options = parse_register_capabilities(reg)?;
12549                    server.update_capabilities(|capabilities| {
12550                        capabilities.definition_provider = Some(options);
12551                    });
12552                    notify_server_capabilities_updated(&server, cx);
12553                }
12554                "textDocument/completion" => {
12555                    if let Some(caps) = reg
12556                        .register_options
12557                        .map(serde_json::from_value::<CompletionOptions>)
12558                        .transpose()?
12559                    {
12560                        server.update_capabilities(|capabilities| {
12561                            capabilities.completion_provider = Some(caps.clone());
12562                        });
12563
12564                        if let Some(local) = self.as_local() {
12565                            let mut buffers_with_language_server = Vec::new();
12566                            for handle in self.buffer_store.read(cx).buffers() {
12567                                let buffer_id = handle.read(cx).remote_id();
12568                                if local
12569                                    .buffers_opened_in_servers
12570                                    .get(&buffer_id)
12571                                    .filter(|s| s.contains(&server_id))
12572                                    .is_some()
12573                                {
12574                                    buffers_with_language_server.push(handle);
12575                                }
12576                            }
12577                            let triggers = caps
12578                                .trigger_characters
12579                                .unwrap_or_default()
12580                                .into_iter()
12581                                .collect::<BTreeSet<_>>();
12582                            for handle in buffers_with_language_server {
12583                                let triggers = triggers.clone();
12584                                let _ = handle.update(cx, move |buffer, cx| {
12585                                    buffer.set_completion_triggers(server_id, triggers, cx);
12586                                });
12587                            }
12588                        }
12589                        notify_server_capabilities_updated(&server, cx);
12590                    }
12591                }
12592                "textDocument/hover" => {
12593                    let options = parse_register_capabilities(reg)?;
12594                    let provider = match options {
12595                        OneOf::Left(value) => lsp::HoverProviderCapability::Simple(value),
12596                        OneOf::Right(caps) => caps,
12597                    };
12598                    server.update_capabilities(|capabilities| {
12599                        capabilities.hover_provider = Some(provider);
12600                    });
12601                    notify_server_capabilities_updated(&server, cx);
12602                }
12603                "textDocument/signatureHelp" => {
12604                    if let Some(caps) = reg
12605                        .register_options
12606                        .map(serde_json::from_value)
12607                        .transpose()?
12608                    {
12609                        server.update_capabilities(|capabilities| {
12610                            capabilities.signature_help_provider = Some(caps);
12611                        });
12612                        notify_server_capabilities_updated(&server, cx);
12613                    }
12614                }
12615                "textDocument/didChange" => {
12616                    if let Some(sync_kind) = reg
12617                        .register_options
12618                        .and_then(|opts| opts.get("syncKind").cloned())
12619                        .map(serde_json::from_value::<lsp::TextDocumentSyncKind>)
12620                        .transpose()?
12621                    {
12622                        server.update_capabilities(|capabilities| {
12623                            let mut sync_options =
12624                                Self::take_text_document_sync_options(capabilities);
12625                            sync_options.change = Some(sync_kind);
12626                            capabilities.text_document_sync =
12627                                Some(lsp::TextDocumentSyncCapability::Options(sync_options));
12628                        });
12629                        notify_server_capabilities_updated(&server, cx);
12630                    }
12631                }
12632                "textDocument/didSave" => {
12633                    if let Some(include_text) = reg
12634                        .register_options
12635                        .map(|opts| {
12636                            let transpose = opts
12637                                .get("includeText")
12638                                .cloned()
12639                                .map(serde_json::from_value::<Option<bool>>)
12640                                .transpose();
12641                            match transpose {
12642                                Ok(value) => Ok(value.flatten()),
12643                                Err(e) => Err(e),
12644                            }
12645                        })
12646                        .transpose()?
12647                    {
12648                        server.update_capabilities(|capabilities| {
12649                            let mut sync_options =
12650                                Self::take_text_document_sync_options(capabilities);
12651                            sync_options.save =
12652                                Some(TextDocumentSyncSaveOptions::SaveOptions(lsp::SaveOptions {
12653                                    include_text,
12654                                }));
12655                            capabilities.text_document_sync =
12656                                Some(lsp::TextDocumentSyncCapability::Options(sync_options));
12657                        });
12658                        notify_server_capabilities_updated(&server, cx);
12659                    }
12660                }
12661                "textDocument/codeLens" => {
12662                    if let Some(caps) = reg
12663                        .register_options
12664                        .map(serde_json::from_value)
12665                        .transpose()?
12666                    {
12667                        server.update_capabilities(|capabilities| {
12668                            capabilities.code_lens_provider = Some(caps);
12669                        });
12670                        notify_server_capabilities_updated(&server, cx);
12671                    }
12672                }
12673                "textDocument/diagnostic" => {
12674                    if let Some(caps) = reg
12675                        .register_options
12676                        .map(serde_json::from_value::<DiagnosticServerCapabilities>)
12677                        .transpose()?
12678                    {
12679                        let local = self
12680                            .as_local_mut()
12681                            .context("Expected LSP Store to be local")?;
12682                        let state = local
12683                            .language_servers
12684                            .get_mut(&server_id)
12685                            .context("Could not obtain Language Servers state")?;
12686                        local
12687                            .language_server_dynamic_registrations
12688                            .entry(server_id)
12689                            .or_default()
12690                            .diagnostics
12691                            .insert(Some(reg.id.clone()), caps.clone());
12692
12693                        let supports_workspace_diagnostics =
12694                            |capabilities: &DiagnosticServerCapabilities| match capabilities {
12695                                DiagnosticServerCapabilities::Options(diagnostic_options) => {
12696                                    diagnostic_options.workspace_diagnostics
12697                                }
12698                                DiagnosticServerCapabilities::RegistrationOptions(
12699                                    diagnostic_registration_options,
12700                                ) => {
12701                                    diagnostic_registration_options
12702                                        .diagnostic_options
12703                                        .workspace_diagnostics
12704                                }
12705                            };
12706
12707                        if supports_workspace_diagnostics(&caps) {
12708                            if let LanguageServerState::Running {
12709                                workspace_diagnostics_refresh_tasks,
12710                                ..
12711                            } = state
12712                                && let Some(task) = lsp_workspace_diagnostics_refresh(
12713                                    Some(reg.id.clone()),
12714                                    caps.clone(),
12715                                    server.clone(),
12716                                    cx,
12717                                )
12718                            {
12719                                workspace_diagnostics_refresh_tasks.insert(Some(reg.id), task);
12720                            }
12721                        }
12722
12723                        server.update_capabilities(|capabilities| {
12724                            capabilities.diagnostic_provider = Some(caps);
12725                        });
12726
12727                        notify_server_capabilities_updated(&server, cx);
12728
12729                        self.pull_document_diagnostics_for_server(server_id, cx)
12730                            .detach();
12731                    }
12732                }
12733                "textDocument/documentColor" => {
12734                    let options = parse_register_capabilities(reg)?;
12735                    let provider = match options {
12736                        OneOf::Left(value) => lsp::ColorProviderCapability::Simple(value),
12737                        OneOf::Right(caps) => caps,
12738                    };
12739                    server.update_capabilities(|capabilities| {
12740                        capabilities.color_provider = Some(provider);
12741                    });
12742                    notify_server_capabilities_updated(&server, cx);
12743                }
12744                _ => log::warn!("unhandled capability registration: {reg:?}"),
12745            }
12746        }
12747
12748        Ok(())
12749    }
12750
12751    fn unregister_server_capabilities(
12752        &mut self,
12753        server_id: LanguageServerId,
12754        params: lsp::UnregistrationParams,
12755        cx: &mut Context<Self>,
12756    ) -> anyhow::Result<()> {
12757        let server = self
12758            .language_server_for_id(server_id)
12759            .with_context(|| format!("no server {server_id} found"))?;
12760        for unreg in params.unregisterations.iter() {
12761            match unreg.method.as_str() {
12762                "workspace/didChangeWatchedFiles" => {
12763                    let notify = if let Some(local_lsp_store) = self.as_local_mut() {
12764                        local_lsp_store
12765                            .on_lsp_unregister_did_change_watched_files(server_id, &unreg.id, cx);
12766                        true
12767                    } else {
12768                        false
12769                    };
12770                    if notify {
12771                        notify_server_capabilities_updated(&server, cx);
12772                    }
12773                }
12774                "workspace/didChangeConfiguration" => {
12775                    // Ignore payload since we notify clients of setting changes unconditionally, relying on them pulling the latest settings.
12776                }
12777                "workspace/didChangeWorkspaceFolders" => {
12778                    server.update_capabilities(|capabilities| {
12779                        capabilities
12780                            .workspace
12781                            .get_or_insert_with(|| lsp::WorkspaceServerCapabilities {
12782                                workspace_folders: None,
12783                                file_operations: None,
12784                            })
12785                            .workspace_folders = None;
12786                    });
12787                    notify_server_capabilities_updated(&server, cx);
12788                }
12789                "workspace/symbol" => {
12790                    server.update_capabilities(|capabilities| {
12791                        capabilities.workspace_symbol_provider = None
12792                    });
12793                    notify_server_capabilities_updated(&server, cx);
12794                }
12795                "workspace/fileOperations" => {
12796                    server.update_capabilities(|capabilities| {
12797                        capabilities
12798                            .workspace
12799                            .get_or_insert_with(|| lsp::WorkspaceServerCapabilities {
12800                                workspace_folders: None,
12801                                file_operations: None,
12802                            })
12803                            .file_operations = None;
12804                    });
12805                    notify_server_capabilities_updated(&server, cx);
12806                }
12807                "workspace/executeCommand" => {
12808                    server.update_capabilities(|capabilities| {
12809                        capabilities.execute_command_provider = None;
12810                    });
12811                    notify_server_capabilities_updated(&server, cx);
12812                }
12813                "textDocument/rangeFormatting" => {
12814                    server.update_capabilities(|capabilities| {
12815                        capabilities.document_range_formatting_provider = None
12816                    });
12817                    notify_server_capabilities_updated(&server, cx);
12818                }
12819                "textDocument/onTypeFormatting" => {
12820                    server.update_capabilities(|capabilities| {
12821                        capabilities.document_on_type_formatting_provider = None;
12822                    });
12823                    notify_server_capabilities_updated(&server, cx);
12824                }
12825                "textDocument/formatting" => {
12826                    server.update_capabilities(|capabilities| {
12827                        capabilities.document_formatting_provider = None;
12828                    });
12829                    notify_server_capabilities_updated(&server, cx);
12830                }
12831                "textDocument/rename" => {
12832                    server.update_capabilities(|capabilities| capabilities.rename_provider = None);
12833                    notify_server_capabilities_updated(&server, cx);
12834                }
12835                "textDocument/codeAction" => {
12836                    server.update_capabilities(|capabilities| {
12837                        capabilities.code_action_provider = None;
12838                    });
12839                    notify_server_capabilities_updated(&server, cx);
12840                }
12841                "textDocument/definition" => {
12842                    server.update_capabilities(|capabilities| {
12843                        capabilities.definition_provider = None;
12844                    });
12845                    notify_server_capabilities_updated(&server, cx);
12846                }
12847                "textDocument/completion" => {
12848                    server.update_capabilities(|capabilities| {
12849                        capabilities.completion_provider = None;
12850                    });
12851                    notify_server_capabilities_updated(&server, cx);
12852                }
12853                "textDocument/hover" => {
12854                    server.update_capabilities(|capabilities| {
12855                        capabilities.hover_provider = None;
12856                    });
12857                    notify_server_capabilities_updated(&server, cx);
12858                }
12859                "textDocument/signatureHelp" => {
12860                    server.update_capabilities(|capabilities| {
12861                        capabilities.signature_help_provider = None;
12862                    });
12863                    notify_server_capabilities_updated(&server, cx);
12864                }
12865                "textDocument/didChange" => {
12866                    server.update_capabilities(|capabilities| {
12867                        let mut sync_options = Self::take_text_document_sync_options(capabilities);
12868                        sync_options.change = None;
12869                        capabilities.text_document_sync =
12870                            Some(lsp::TextDocumentSyncCapability::Options(sync_options));
12871                    });
12872                    notify_server_capabilities_updated(&server, cx);
12873                }
12874                "textDocument/didSave" => {
12875                    server.update_capabilities(|capabilities| {
12876                        let mut sync_options = Self::take_text_document_sync_options(capabilities);
12877                        sync_options.save = None;
12878                        capabilities.text_document_sync =
12879                            Some(lsp::TextDocumentSyncCapability::Options(sync_options));
12880                    });
12881                    notify_server_capabilities_updated(&server, cx);
12882                }
12883                "textDocument/codeLens" => {
12884                    server.update_capabilities(|capabilities| {
12885                        capabilities.code_lens_provider = None;
12886                    });
12887                    notify_server_capabilities_updated(&server, cx);
12888                }
12889                "textDocument/diagnostic" => {
12890                    let local = self
12891                        .as_local_mut()
12892                        .context("Expected LSP Store to be local")?;
12893
12894                    let state = local
12895                        .language_servers
12896                        .get_mut(&server_id)
12897                        .context("Could not obtain Language Servers state")?;
12898                    let registrations = local
12899                        .language_server_dynamic_registrations
12900                        .get_mut(&server_id)
12901                        .with_context(|| {
12902                            format!("Expected dynamic registration to exist for server {server_id}")
12903                        })?;
12904                    registrations.diagnostics
12905                        .remove(&Some(unreg.id.clone()))
12906                        .with_context(|| format!(
12907                            "Attempted to unregister non-existent diagnostic registration with ID {}",
12908                            unreg.id)
12909                        )?;
12910                    let removed_last_diagnostic_provider = registrations.diagnostics.is_empty();
12911
12912                    if let LanguageServerState::Running {
12913                        workspace_diagnostics_refresh_tasks,
12914                        ..
12915                    } = state
12916                    {
12917                        workspace_diagnostics_refresh_tasks.remove(&Some(unreg.id.clone()));
12918                    }
12919
12920                    self.clear_unregistered_diagnostics(
12921                        server_id,
12922                        SharedString::from(unreg.id.clone()),
12923                        cx,
12924                    )?;
12925
12926                    if removed_last_diagnostic_provider {
12927                        server.update_capabilities(|capabilities| {
12928                            debug_assert!(capabilities.diagnostic_provider.is_some());
12929                            capabilities.diagnostic_provider = None;
12930                        });
12931                    }
12932
12933                    notify_server_capabilities_updated(&server, cx);
12934                }
12935                "textDocument/documentColor" => {
12936                    server.update_capabilities(|capabilities| {
12937                        capabilities.color_provider = None;
12938                    });
12939                    notify_server_capabilities_updated(&server, cx);
12940                }
12941                _ => log::warn!("unhandled capability unregistration: {unreg:?}"),
12942            }
12943        }
12944
12945        Ok(())
12946    }
12947
12948    fn clear_unregistered_diagnostics(
12949        &mut self,
12950        server_id: LanguageServerId,
12951        cleared_registration_id: SharedString,
12952        cx: &mut Context<Self>,
12953    ) -> anyhow::Result<()> {
12954        let mut affected_abs_paths: HashSet<PathBuf> = HashSet::default();
12955
12956        self.buffer_store.update(cx, |buffer_store, cx| {
12957            for buffer_handle in buffer_store.buffers() {
12958                let buffer = buffer_handle.read(cx);
12959                let abs_path = File::from_dyn(buffer.file()).map(|f| f.abs_path(cx));
12960                let Some(abs_path) = abs_path else {
12961                    continue;
12962                };
12963                affected_abs_paths.insert(abs_path);
12964            }
12965        });
12966
12967        let local = self.as_local().context("Expected LSP Store to be local")?;
12968        for (worktree_id, diagnostics_for_tree) in local.diagnostics.iter() {
12969            let Some(worktree) = self
12970                .worktree_store
12971                .read(cx)
12972                .worktree_for_id(*worktree_id, cx)
12973            else {
12974                continue;
12975            };
12976
12977            for (rel_path, diagnostics_by_server_id) in diagnostics_for_tree.iter() {
12978                if let Ok(ix) = diagnostics_by_server_id.binary_search_by_key(&server_id, |e| e.0) {
12979                    let has_matching_registration =
12980                        diagnostics_by_server_id[ix].1.iter().any(|entry| {
12981                            entry.diagnostic.registration_id.as_ref()
12982                                == Some(&cleared_registration_id)
12983                        });
12984                    if has_matching_registration {
12985                        let abs_path = worktree.read(cx).absolutize(rel_path);
12986                        affected_abs_paths.insert(abs_path);
12987                    }
12988                }
12989            }
12990        }
12991
12992        if affected_abs_paths.is_empty() {
12993            return Ok(());
12994        }
12995
12996        // Send a fake diagnostic update which clears the state for the registration ID
12997        let clears: Vec<DocumentDiagnosticsUpdate<'static, DocumentDiagnostics>> =
12998            affected_abs_paths
12999                .into_iter()
13000                .map(|abs_path| DocumentDiagnosticsUpdate {
13001                    diagnostics: DocumentDiagnostics {
13002                        diagnostics: Vec::new(),
13003                        document_abs_path: abs_path,
13004                        version: None,
13005                    },
13006                    result_id: None,
13007                    registration_id: Some(cleared_registration_id.clone()),
13008                    server_id,
13009                    disk_based_sources: Cow::Borrowed(&[]),
13010                })
13011                .collect();
13012
13013        let merge_registration_id = cleared_registration_id.clone();
13014        self.merge_diagnostic_entries(
13015            clears,
13016            move |_, diagnostic, _| {
13017                if diagnostic.source_kind == DiagnosticSourceKind::Pulled {
13018                    diagnostic.registration_id != Some(merge_registration_id.clone())
13019                } else {
13020                    true
13021                }
13022            },
13023            cx,
13024        )?;
13025
13026        Ok(())
13027    }
13028
13029    async fn deduplicate_range_based_lsp_requests<T>(
13030        lsp_store: &Entity<Self>,
13031        server_id: Option<LanguageServerId>,
13032        lsp_request_id: LspRequestId,
13033        proto_request: &T::ProtoRequest,
13034        range: Range<Anchor>,
13035        cx: &mut AsyncApp,
13036    ) -> Result<()>
13037    where
13038        T: LspCommand,
13039        T::ProtoRequest: proto::LspRequestMessage,
13040    {
13041        let buffer_id = BufferId::new(proto_request.buffer_id())?;
13042        let version = deserialize_version(proto_request.buffer_version());
13043        let buffer = lsp_store.update(cx, |this, cx| {
13044            this.buffer_store.read(cx).get_existing(buffer_id)
13045        })?;
13046        buffer
13047            .update(cx, |buffer, _| buffer.wait_for_version(version))
13048            .await?;
13049        lsp_store.update(cx, |lsp_store, cx| {
13050            let buffer_snapshot = buffer.read(cx).snapshot();
13051            let lsp_data = lsp_store.latest_lsp_data(&buffer, cx);
13052            let chunks_queried_for = lsp_data
13053                .inlay_hints
13054                .applicable_chunks(&[range.to_point(&buffer_snapshot)])
13055                .collect::<Vec<_>>();
13056            match chunks_queried_for.as_slice() {
13057                &[chunk] => {
13058                    let key = LspKey {
13059                        request_type: TypeId::of::<T>(),
13060                        server_queried: server_id,
13061                    };
13062                    let previous_request = lsp_data
13063                        .chunk_lsp_requests
13064                        .entry(key)
13065                        .or_default()
13066                        .insert(chunk, lsp_request_id);
13067                    if let Some((previous_request, running_requests)) =
13068                        previous_request.zip(lsp_data.lsp_requests.get_mut(&key))
13069                    {
13070                        running_requests.remove(&previous_request);
13071                    }
13072                }
13073                _ambiguous_chunks => {
13074                    // Have not found a unique chunk for the query range — be lenient and let the query to be spawned,
13075                    // there, a buffer version-based check will be performed and outdated requests discarded.
13076                }
13077            }
13078            anyhow::Ok(())
13079        })?;
13080
13081        Ok(())
13082    }
13083
13084    async fn query_lsp_locally<T>(
13085        lsp_store: Entity<Self>,
13086        for_server_id: Option<LanguageServerId>,
13087        sender_id: proto::PeerId,
13088        lsp_request_id: LspRequestId,
13089        proto_request: T::ProtoRequest,
13090        position: Option<Anchor>,
13091        cx: &mut AsyncApp,
13092    ) -> Result<()>
13093    where
13094        T: LspCommand + Clone,
13095        T::ProtoRequest: proto::LspRequestMessage,
13096        <T::ProtoRequest as proto::RequestMessage>::Response:
13097            Into<<T::ProtoRequest as proto::LspRequestMessage>::Response>,
13098    {
13099        let buffer_id = BufferId::new(proto_request.buffer_id())?;
13100        let version = deserialize_version(proto_request.buffer_version());
13101        let buffer = lsp_store.update(cx, |this, cx| {
13102            this.buffer_store.read(cx).get_existing(buffer_id)
13103        })?;
13104        buffer
13105            .update(cx, |buffer, _| buffer.wait_for_version(version.clone()))
13106            .await?;
13107        let buffer_version = buffer.read_with(cx, |buffer, _| buffer.version());
13108        let request =
13109            T::from_proto(proto_request, lsp_store.clone(), buffer.clone(), cx.clone()).await?;
13110        let key = LspKey {
13111            request_type: TypeId::of::<T>(),
13112            server_queried: for_server_id,
13113        };
13114        lsp_store.update(cx, |lsp_store, cx| {
13115            let request_task = match for_server_id {
13116                Some(server_id) => {
13117                    let server_task = lsp_store.request_lsp(
13118                        buffer.clone(),
13119                        LanguageServerToQuery::Other(server_id),
13120                        request.clone(),
13121                        cx,
13122                    );
13123                    cx.background_spawn(async move {
13124                        let mut responses = Vec::new();
13125                        match server_task.await {
13126                            Ok(response) => responses.push((server_id, response)),
13127                            // rust-analyzer likes to error with this when its still loading up
13128                            Err(e) if format!("{e:#}").ends_with("content modified") => (),
13129                            Err(e) => log::error!(
13130                                "Error handling response for request {request:?}: {e:#}"
13131                            ),
13132                        }
13133                        responses
13134                    })
13135                }
13136                None => lsp_store.request_multiple_lsp_locally(&buffer, position, request, cx),
13137            };
13138            let lsp_data = lsp_store.latest_lsp_data(&buffer, cx);
13139            if T::ProtoRequest::stop_previous_requests() {
13140                if let Some(lsp_requests) = lsp_data.lsp_requests.get_mut(&key) {
13141                    lsp_requests.clear();
13142                }
13143            }
13144            lsp_data.lsp_requests.entry(key).or_default().insert(
13145                lsp_request_id,
13146                cx.spawn(async move |lsp_store, cx| {
13147                    let response = request_task.await;
13148                    lsp_store
13149                        .update(cx, |lsp_store, cx| {
13150                            if let Some((client, project_id)) = lsp_store.downstream_client.clone()
13151                            {
13152                                let response = response
13153                                    .into_iter()
13154                                    .map(|(server_id, response)| {
13155                                        (
13156                                            server_id.to_proto(),
13157                                            T::response_to_proto(
13158                                                response,
13159                                                lsp_store,
13160                                                sender_id,
13161                                                &buffer_version,
13162                                                cx,
13163                                            )
13164                                            .into(),
13165                                        )
13166                                    })
13167                                    .collect::<HashMap<_, _>>();
13168                                match client.send_lsp_response::<T::ProtoRequest>(
13169                                    project_id,
13170                                    lsp_request_id,
13171                                    response,
13172                                ) {
13173                                    Ok(()) => {}
13174                                    Err(e) => {
13175                                        log::error!("Failed to send LSP response: {e:#}",)
13176                                    }
13177                                }
13178                            }
13179                        })
13180                        .ok();
13181                }),
13182            );
13183        });
13184        Ok(())
13185    }
13186
13187    fn take_text_document_sync_options(
13188        capabilities: &mut lsp::ServerCapabilities,
13189    ) -> lsp::TextDocumentSyncOptions {
13190        match capabilities.text_document_sync.take() {
13191            Some(lsp::TextDocumentSyncCapability::Options(sync_options)) => sync_options,
13192            Some(lsp::TextDocumentSyncCapability::Kind(sync_kind)) => {
13193                let mut sync_options = lsp::TextDocumentSyncOptions::default();
13194                sync_options.change = Some(sync_kind);
13195                sync_options
13196            }
13197            None => lsp::TextDocumentSyncOptions::default(),
13198        }
13199    }
13200
13201    #[cfg(any(test, feature = "test-support"))]
13202    pub fn forget_code_lens_task(&mut self, buffer_id: BufferId) -> Option<CodeLensTask> {
13203        Some(
13204            self.lsp_data
13205                .get_mut(&buffer_id)?
13206                .code_lens
13207                .take()?
13208                .update
13209                .take()?
13210                .1,
13211        )
13212    }
13213
13214    pub fn downstream_client(&self) -> Option<(AnyProtoClient, u64)> {
13215        self.downstream_client.clone()
13216    }
13217
13218    pub fn worktree_store(&self) -> Entity<WorktreeStore> {
13219        self.worktree_store.clone()
13220    }
13221
13222    /// Gets what's stored in the LSP data for the given buffer.
13223    pub fn current_lsp_data(&mut self, buffer_id: BufferId) -> Option<&mut BufferLspData> {
13224        self.lsp_data.get_mut(&buffer_id)
13225    }
13226
13227    /// Gets the most recent LSP data for the given buffer: if the data is absent or out of date,
13228    /// new [`BufferLspData`] will be created to replace the previous state.
13229    pub fn latest_lsp_data(&mut self, buffer: &Entity<Buffer>, cx: &mut App) -> &mut BufferLspData {
13230        let (buffer_id, buffer_version) =
13231            buffer.read_with(cx, |buffer, _| (buffer.remote_id(), buffer.version()));
13232        let lsp_data = self
13233            .lsp_data
13234            .entry(buffer_id)
13235            .or_insert_with(|| BufferLspData::new(buffer, cx));
13236        if buffer_version.changed_since(&lsp_data.buffer_version) {
13237            *lsp_data = BufferLspData::new(buffer, cx);
13238        }
13239        lsp_data
13240    }
13241}
13242
13243// Registration with registerOptions as null, should fallback to true.
13244// https://github.com/microsoft/vscode-languageserver-node/blob/d90a87f9557a0df9142cfb33e251cfa6fe27d970/client/src/common/client.ts#L2133
13245fn parse_register_capabilities<T: serde::de::DeserializeOwned>(
13246    reg: lsp::Registration,
13247) -> Result<OneOf<bool, T>> {
13248    Ok(match reg.register_options {
13249        Some(options) => OneOf::Right(serde_json::from_value::<T>(options)?),
13250        None => OneOf::Left(true),
13251    })
13252}
13253
13254fn subscribe_to_binary_statuses(
13255    languages: &Arc<LanguageRegistry>,
13256    cx: &mut Context<'_, LspStore>,
13257) -> Task<()> {
13258    let mut server_statuses = languages.language_server_binary_statuses();
13259    cx.spawn(async move |lsp_store, cx| {
13260        while let Some((server_name, binary_status)) = server_statuses.next().await {
13261            if lsp_store
13262                .update(cx, |_, cx| {
13263                    let mut message = None;
13264                    let binary_status = match binary_status {
13265                        BinaryStatus::None => proto::ServerBinaryStatus::None,
13266                        BinaryStatus::CheckingForUpdate => {
13267                            proto::ServerBinaryStatus::CheckingForUpdate
13268                        }
13269                        BinaryStatus::Downloading => proto::ServerBinaryStatus::Downloading,
13270                        BinaryStatus::Starting => proto::ServerBinaryStatus::Starting,
13271                        BinaryStatus::Stopping => proto::ServerBinaryStatus::Stopping,
13272                        BinaryStatus::Stopped => proto::ServerBinaryStatus::Stopped,
13273                        BinaryStatus::Failed { error } => {
13274                            message = Some(error);
13275                            proto::ServerBinaryStatus::Failed
13276                        }
13277                    };
13278                    cx.emit(LspStoreEvent::LanguageServerUpdate {
13279                        // Binary updates are about the binary that might not have any language server id at that point.
13280                        // Reuse `LanguageServerUpdate` for them and provide a fake id that won't be used on the receiver side.
13281                        language_server_id: LanguageServerId(0),
13282                        name: Some(server_name),
13283                        message: proto::update_language_server::Variant::StatusUpdate(
13284                            proto::StatusUpdate {
13285                                message,
13286                                status: Some(proto::status_update::Status::Binary(
13287                                    binary_status as i32,
13288                                )),
13289                            },
13290                        ),
13291                    });
13292                })
13293                .is_err()
13294            {
13295                break;
13296            }
13297        }
13298    })
13299}
13300
13301fn lsp_workspace_diagnostics_refresh(
13302    registration_id: Option<String>,
13303    options: DiagnosticServerCapabilities,
13304    server: Arc<LanguageServer>,
13305    cx: &mut Context<'_, LspStore>,
13306) -> Option<WorkspaceRefreshTask> {
13307    let identifier = workspace_diagnostic_identifier(&options)?;
13308    let registration_id_shared = registration_id.as_ref().map(SharedString::from);
13309
13310    let (progress_tx, mut progress_rx) = mpsc::channel(1);
13311    let (mut refresh_tx, mut refresh_rx) = mpsc::channel(1);
13312    refresh_tx.try_send(()).ok();
13313
13314    let workspace_query_language_server = cx.spawn(async move |lsp_store, cx| {
13315        let mut attempts = 0;
13316        let max_attempts = 50;
13317        let mut requests = 0;
13318
13319        loop {
13320            let Some(()) = refresh_rx.recv().await else {
13321                return;
13322            };
13323
13324            'request: loop {
13325                requests += 1;
13326                if attempts > max_attempts {
13327                    log::error!(
13328                        "Failed to pull workspace diagnostics {max_attempts} times, aborting"
13329                    );
13330                    return;
13331                }
13332                let backoff_millis = (50 * (1 << attempts)).clamp(30, 1000);
13333                cx.background_executor()
13334                    .timer(Duration::from_millis(backoff_millis))
13335                    .await;
13336                attempts += 1;
13337
13338                let Ok(previous_result_ids) = lsp_store.update(cx, |lsp_store, _| {
13339                    lsp_store
13340                        .result_ids_for_workspace_refresh(server.server_id(), &registration_id_shared)
13341                        .into_iter()
13342                        .filter_map(|(abs_path, result_id)| {
13343                            let uri = file_path_to_lsp_url(&abs_path).ok()?;
13344                            Some(lsp::PreviousResultId {
13345                                uri,
13346                                value: result_id.to_string(),
13347                            })
13348                        })
13349                        .collect()
13350                }) else {
13351                    return;
13352                };
13353
13354                let token = if let Some(registration_id) = &registration_id {
13355                    format!(
13356                        "workspace/diagnostic/{}/{requests}/{WORKSPACE_DIAGNOSTICS_TOKEN_START}{registration_id}",
13357                        server.server_id(),
13358                    )
13359                } else {
13360                    format!("workspace/diagnostic/{}/{requests}", server.server_id())
13361                };
13362
13363                progress_rx.try_recv().ok();
13364                let timer =
13365                    LanguageServer::default_request_timer(cx.background_executor().clone()).fuse();
13366                let progress = pin!(progress_rx.recv().fuse());
13367                let response_result = server
13368                    .request_with_timer::<lsp::WorkspaceDiagnosticRequest, _>(
13369                        lsp::WorkspaceDiagnosticParams {
13370                            previous_result_ids,
13371                            identifier: identifier.clone(),
13372                            work_done_progress_params: Default::default(),
13373                            partial_result_params: lsp::PartialResultParams {
13374                                partial_result_token: Some(lsp::ProgressToken::String(token)),
13375                            },
13376                        },
13377                        select(timer, progress).then(|either| match either {
13378                            Either::Left((message, ..)) => ready(message).left_future(),
13379                            Either::Right(..) => pending::<String>().right_future(),
13380                        }),
13381                    )
13382                    .await;
13383
13384                // https://microsoft.github.io/language-server-protocol/specifications/lsp/3.17/specification/#diagnostic_refresh
13385                // >  If a server closes a workspace diagnostic pull request the client should re-trigger the request.
13386                match response_result {
13387                    ConnectionResult::Timeout => {
13388                        log::error!("Timeout during workspace diagnostics pull");
13389                        continue 'request;
13390                    }
13391                    ConnectionResult::ConnectionReset => {
13392                        log::error!("Server closed a workspace diagnostics pull request");
13393                        continue 'request;
13394                    }
13395                    ConnectionResult::Result(Err(e)) => {
13396                        log::error!("Error during workspace diagnostics pull: {e:#}");
13397                        break 'request;
13398                    }
13399                    ConnectionResult::Result(Ok(pulled_diagnostics)) => {
13400                        attempts = 0;
13401                        if lsp_store
13402                            .update(cx, |lsp_store, cx| {
13403                                lsp_store.apply_workspace_diagnostic_report(
13404                                    server.server_id(),
13405                                    pulled_diagnostics,
13406                                    registration_id_shared.clone(),
13407                                    cx,
13408                                )
13409                            })
13410                            .is_err()
13411                        {
13412                            return;
13413                        }
13414                        break 'request;
13415                    }
13416                }
13417            }
13418        }
13419    });
13420
13421    Some(WorkspaceRefreshTask {
13422        refresh_tx,
13423        progress_tx,
13424        task: workspace_query_language_server,
13425    })
13426}
13427
13428fn buffer_diagnostic_identifier(options: &DiagnosticServerCapabilities) -> Option<String> {
13429    match &options {
13430        lsp::DiagnosticServerCapabilities::Options(diagnostic_options) => {
13431            diagnostic_options.identifier.clone()
13432        }
13433        lsp::DiagnosticServerCapabilities::RegistrationOptions(registration_options) => {
13434            let diagnostic_options = &registration_options.diagnostic_options;
13435            diagnostic_options.identifier.clone()
13436        }
13437    }
13438}
13439
13440fn workspace_diagnostic_identifier(
13441    options: &DiagnosticServerCapabilities,
13442) -> Option<Option<String>> {
13443    match &options {
13444        lsp::DiagnosticServerCapabilities::Options(diagnostic_options) => {
13445            if !diagnostic_options.workspace_diagnostics {
13446                return None;
13447            }
13448            Some(diagnostic_options.identifier.clone())
13449        }
13450        lsp::DiagnosticServerCapabilities::RegistrationOptions(registration_options) => {
13451            let diagnostic_options = &registration_options.diagnostic_options;
13452            if !diagnostic_options.workspace_diagnostics {
13453                return None;
13454            }
13455            Some(diagnostic_options.identifier.clone())
13456        }
13457    }
13458}
13459
13460fn resolve_word_completion(snapshot: &BufferSnapshot, completion: &mut Completion) {
13461    let CompletionSource::BufferWord {
13462        word_range,
13463        resolved,
13464    } = &mut completion.source
13465    else {
13466        return;
13467    };
13468    if *resolved {
13469        return;
13470    }
13471
13472    if completion.new_text
13473        != snapshot
13474            .text_for_range(word_range.clone())
13475            .collect::<String>()
13476    {
13477        return;
13478    }
13479
13480    let mut offset = 0;
13481    for chunk in snapshot.chunks(word_range.clone(), true) {
13482        let end_offset = offset + chunk.text.len();
13483        if let Some(highlight_id) = chunk.syntax_highlight_id {
13484            completion
13485                .label
13486                .runs
13487                .push((offset..end_offset, highlight_id));
13488        }
13489        offset = end_offset;
13490    }
13491    *resolved = true;
13492}
13493
13494impl EventEmitter<LspStoreEvent> for LspStore {}
13495
13496fn remove_empty_hover_blocks(mut hover: Hover) -> Option<Hover> {
13497    hover
13498        .contents
13499        .retain(|hover_block| !hover_block.text.trim().is_empty());
13500    if hover.contents.is_empty() {
13501        None
13502    } else {
13503        Some(hover)
13504    }
13505}
13506
13507async fn populate_labels_for_completions(
13508    new_completions: Vec<CoreCompletion>,
13509    language: Option<Arc<Language>>,
13510    lsp_adapter: Option<Arc<CachedLspAdapter>>,
13511) -> Vec<Completion> {
13512    let lsp_completions = new_completions
13513        .iter()
13514        .filter_map(|new_completion| {
13515            new_completion
13516                .source
13517                .lsp_completion(true)
13518                .map(|lsp_completion| lsp_completion.into_owned())
13519        })
13520        .collect::<Vec<_>>();
13521
13522    let mut labels = if let Some((language, lsp_adapter)) = language.as_ref().zip(lsp_adapter) {
13523        lsp_adapter
13524            .labels_for_completions(&lsp_completions, language)
13525            .await
13526            .log_err()
13527            .unwrap_or_default()
13528    } else {
13529        Vec::new()
13530    }
13531    .into_iter()
13532    .fuse();
13533
13534    let mut completions = Vec::new();
13535    for completion in new_completions {
13536        match completion.source.lsp_completion(true) {
13537            Some(lsp_completion) => {
13538                let documentation = lsp_completion.documentation.clone().map(|docs| docs.into());
13539
13540                let mut label = labels.next().flatten().unwrap_or_else(|| {
13541                    CodeLabel::fallback_for_completion(&lsp_completion, language.as_deref())
13542                });
13543                ensure_uniform_list_compatible_label(&mut label);
13544                completions.push(Completion {
13545                    label,
13546                    documentation,
13547                    replace_range: completion.replace_range,
13548                    new_text: completion.new_text,
13549                    insert_text_mode: lsp_completion.insert_text_mode,
13550                    source: completion.source,
13551                    icon_path: None,
13552                    confirm: None,
13553                    match_start: None,
13554                    snippet_deduplication_key: None,
13555                });
13556            }
13557            None => {
13558                let mut label = CodeLabel::plain(completion.new_text.clone(), None);
13559                ensure_uniform_list_compatible_label(&mut label);
13560                completions.push(Completion {
13561                    label,
13562                    documentation: None,
13563                    replace_range: completion.replace_range,
13564                    new_text: completion.new_text,
13565                    source: completion.source,
13566                    insert_text_mode: None,
13567                    icon_path: None,
13568                    confirm: None,
13569                    match_start: None,
13570                    snippet_deduplication_key: None,
13571                });
13572            }
13573        }
13574    }
13575    completions
13576}
13577
13578#[derive(Debug)]
13579pub enum LanguageServerToQuery {
13580    /// Query language servers in order of users preference, up until one capable of handling the request is found.
13581    FirstCapable,
13582    /// Query a specific language server.
13583    Other(LanguageServerId),
13584}
13585
13586#[derive(Default)]
13587struct RenamePathsWatchedForServer {
13588    did_rename: Vec<RenameActionPredicate>,
13589    will_rename: Vec<RenameActionPredicate>,
13590}
13591
13592impl RenamePathsWatchedForServer {
13593    fn with_did_rename_patterns(
13594        mut self,
13595        did_rename: Option<&FileOperationRegistrationOptions>,
13596    ) -> Self {
13597        if let Some(did_rename) = did_rename {
13598            self.did_rename = did_rename
13599                .filters
13600                .iter()
13601                .filter_map(|filter| filter.try_into().log_err())
13602                .collect();
13603        }
13604        self
13605    }
13606    fn with_will_rename_patterns(
13607        mut self,
13608        will_rename: Option<&FileOperationRegistrationOptions>,
13609    ) -> Self {
13610        if let Some(will_rename) = will_rename {
13611            self.will_rename = will_rename
13612                .filters
13613                .iter()
13614                .filter_map(|filter| filter.try_into().log_err())
13615                .collect();
13616        }
13617        self
13618    }
13619
13620    fn should_send_did_rename(&self, path: &str, is_dir: bool) -> bool {
13621        self.did_rename.iter().any(|pred| pred.eval(path, is_dir))
13622    }
13623    fn should_send_will_rename(&self, path: &str, is_dir: bool) -> bool {
13624        self.will_rename.iter().any(|pred| pred.eval(path, is_dir))
13625    }
13626}
13627
13628impl TryFrom<&FileOperationFilter> for RenameActionPredicate {
13629    type Error = globset::Error;
13630    fn try_from(ops: &FileOperationFilter) -> Result<Self, globset::Error> {
13631        Ok(Self {
13632            kind: ops.pattern.matches.clone(),
13633            glob: GlobBuilder::new(&ops.pattern.glob)
13634                .case_insensitive(
13635                    ops.pattern
13636                        .options
13637                        .as_ref()
13638                        .is_some_and(|ops| ops.ignore_case.unwrap_or(false)),
13639                )
13640                .build()?
13641                .compile_matcher(),
13642        })
13643    }
13644}
13645struct RenameActionPredicate {
13646    glob: GlobMatcher,
13647    kind: Option<FileOperationPatternKind>,
13648}
13649
13650impl RenameActionPredicate {
13651    // Returns true if language server should be notified
13652    fn eval(&self, path: &str, is_dir: bool) -> bool {
13653        self.kind.as_ref().is_none_or(|kind| {
13654            let expected_kind = if is_dir {
13655                FileOperationPatternKind::Folder
13656            } else {
13657                FileOperationPatternKind::File
13658            };
13659            kind == &expected_kind
13660        }) && self.glob.is_match(path)
13661    }
13662}
13663
13664#[derive(Default)]
13665struct LanguageServerWatchedPaths {
13666    worktree_paths: HashMap<WorktreeId, GlobSet>,
13667    abs_paths: HashMap<Arc<Path>, (GlobSet, Task<()>)>,
13668}
13669
13670#[derive(Default)]
13671struct LanguageServerWatchedPathsBuilder {
13672    worktree_paths: HashMap<WorktreeId, GlobSet>,
13673    abs_paths: HashMap<Arc<Path>, GlobSet>,
13674}
13675
13676impl LanguageServerWatchedPathsBuilder {
13677    fn watch_worktree(&mut self, worktree_id: WorktreeId, glob_set: GlobSet) {
13678        self.worktree_paths.insert(worktree_id, glob_set);
13679    }
13680    fn watch_abs_path(&mut self, path: Arc<Path>, glob_set: GlobSet) {
13681        self.abs_paths.insert(path, glob_set);
13682    }
13683    fn build(
13684        self,
13685        fs: Arc<dyn Fs>,
13686        language_server_id: LanguageServerId,
13687        cx: &mut Context<LspStore>,
13688    ) -> LanguageServerWatchedPaths {
13689        let lsp_store = cx.weak_entity();
13690
13691        const LSP_ABS_PATH_OBSERVE: Duration = Duration::from_millis(100);
13692        let abs_paths = self
13693            .abs_paths
13694            .into_iter()
13695            .map(|(abs_path, globset)| {
13696                let task = cx.spawn({
13697                    let abs_path = abs_path.clone();
13698                    let fs = fs.clone();
13699
13700                    let lsp_store = lsp_store.clone();
13701                    async move |_, cx| {
13702                        maybe!(async move {
13703                            let mut push_updates = fs.watch(&abs_path, LSP_ABS_PATH_OBSERVE).await;
13704                            while let Some(update) = push_updates.0.next().await {
13705                                let action = lsp_store
13706                                    .update(cx, |this, _| {
13707                                        let Some(local) = this.as_local() else {
13708                                            return ControlFlow::Break(());
13709                                        };
13710                                        let Some(watcher) = local
13711                                            .language_server_watched_paths
13712                                            .get(&language_server_id)
13713                                        else {
13714                                            return ControlFlow::Break(());
13715                                        };
13716                                        let (globs, _) = watcher.abs_paths.get(&abs_path).expect(
13717                                            "Watched abs path is not registered with a watcher",
13718                                        );
13719                                        let matching_entries = update
13720                                            .into_iter()
13721                                            .filter(|event| globs.is_match(&event.path))
13722                                            .collect::<Vec<_>>();
13723                                        this.lsp_notify_abs_paths_changed(
13724                                            language_server_id,
13725                                            matching_entries,
13726                                        );
13727                                        ControlFlow::Continue(())
13728                                    })
13729                                    .ok()?;
13730
13731                                if action.is_break() {
13732                                    break;
13733                                }
13734                            }
13735                            Some(())
13736                        })
13737                        .await;
13738                    }
13739                });
13740                (abs_path, (globset, task))
13741            })
13742            .collect();
13743        LanguageServerWatchedPaths {
13744            worktree_paths: self.worktree_paths,
13745            abs_paths,
13746        }
13747    }
13748}
13749
13750struct LspBufferSnapshot {
13751    version: i32,
13752    snapshot: TextBufferSnapshot,
13753}
13754
13755/// A prompt requested by LSP server.
13756#[derive(Clone, Debug)]
13757pub struct LanguageServerPromptRequest {
13758    pub level: PromptLevel,
13759    pub message: String,
13760    pub actions: Vec<MessageActionItem>,
13761    pub lsp_name: String,
13762    pub(crate) response_channel: smol::channel::Sender<MessageActionItem>,
13763}
13764
13765impl LanguageServerPromptRequest {
13766    pub async fn respond(self, index: usize) -> Option<()> {
13767        if let Some(response) = self.actions.into_iter().nth(index) {
13768            self.response_channel.send(response).await.ok()
13769        } else {
13770            None
13771        }
13772    }
13773}
13774impl PartialEq for LanguageServerPromptRequest {
13775    fn eq(&self, other: &Self) -> bool {
13776        self.message == other.message && self.actions == other.actions
13777    }
13778}
13779
13780#[derive(Clone, Debug, PartialEq)]
13781pub enum LanguageServerLogType {
13782    Log(MessageType),
13783    Trace { verbose_info: Option<String> },
13784    Rpc { received: bool },
13785}
13786
13787impl LanguageServerLogType {
13788    pub fn to_proto(&self) -> proto::language_server_log::LogType {
13789        match self {
13790            Self::Log(log_type) => {
13791                use proto::log_message::LogLevel;
13792                let level = match *log_type {
13793                    MessageType::ERROR => LogLevel::Error,
13794                    MessageType::WARNING => LogLevel::Warning,
13795                    MessageType::INFO => LogLevel::Info,
13796                    MessageType::LOG => LogLevel::Log,
13797                    other => {
13798                        log::warn!("Unknown lsp log message type: {other:?}");
13799                        LogLevel::Log
13800                    }
13801                };
13802                proto::language_server_log::LogType::Log(proto::LogMessage {
13803                    level: level as i32,
13804                })
13805            }
13806            Self::Trace { verbose_info } => {
13807                proto::language_server_log::LogType::Trace(proto::TraceMessage {
13808                    verbose_info: verbose_info.to_owned(),
13809                })
13810            }
13811            Self::Rpc { received } => {
13812                let kind = if *received {
13813                    proto::rpc_message::Kind::Received
13814                } else {
13815                    proto::rpc_message::Kind::Sent
13816                };
13817                let kind = kind as i32;
13818                proto::language_server_log::LogType::Rpc(proto::RpcMessage { kind })
13819            }
13820        }
13821    }
13822
13823    pub fn from_proto(log_type: proto::language_server_log::LogType) -> Self {
13824        use proto::log_message::LogLevel;
13825        use proto::rpc_message;
13826        match log_type {
13827            proto::language_server_log::LogType::Log(message_type) => Self::Log(
13828                match LogLevel::from_i32(message_type.level).unwrap_or(LogLevel::Log) {
13829                    LogLevel::Error => MessageType::ERROR,
13830                    LogLevel::Warning => MessageType::WARNING,
13831                    LogLevel::Info => MessageType::INFO,
13832                    LogLevel::Log => MessageType::LOG,
13833                },
13834            ),
13835            proto::language_server_log::LogType::Trace(trace_message) => Self::Trace {
13836                verbose_info: trace_message.verbose_info,
13837            },
13838            proto::language_server_log::LogType::Rpc(message) => Self::Rpc {
13839                received: match rpc_message::Kind::from_i32(message.kind)
13840                    .unwrap_or(rpc_message::Kind::Received)
13841                {
13842                    rpc_message::Kind::Received => true,
13843                    rpc_message::Kind::Sent => false,
13844                },
13845            },
13846        }
13847    }
13848}
13849
13850pub struct WorkspaceRefreshTask {
13851    refresh_tx: mpsc::Sender<()>,
13852    progress_tx: mpsc::Sender<()>,
13853    #[allow(dead_code)]
13854    task: Task<()>,
13855}
13856
13857pub enum LanguageServerState {
13858    Starting {
13859        startup: Task<Option<Arc<LanguageServer>>>,
13860        /// List of language servers that will be added to the workspace once it's initialization completes.
13861        pending_workspace_folders: Arc<Mutex<BTreeSet<Uri>>>,
13862    },
13863
13864    Running {
13865        adapter: Arc<CachedLspAdapter>,
13866        server: Arc<LanguageServer>,
13867        simulate_disk_based_diagnostics_completion: Option<Task<()>>,
13868        workspace_diagnostics_refresh_tasks: HashMap<Option<String>, WorkspaceRefreshTask>,
13869    },
13870}
13871
13872impl LanguageServerState {
13873    fn add_workspace_folder(&self, uri: Uri) {
13874        match self {
13875            LanguageServerState::Starting {
13876                pending_workspace_folders,
13877                ..
13878            } => {
13879                pending_workspace_folders.lock().insert(uri);
13880            }
13881            LanguageServerState::Running { server, .. } => {
13882                server.add_workspace_folder(uri);
13883            }
13884        }
13885    }
13886    fn _remove_workspace_folder(&self, uri: Uri) {
13887        match self {
13888            LanguageServerState::Starting {
13889                pending_workspace_folders,
13890                ..
13891            } => {
13892                pending_workspace_folders.lock().remove(&uri);
13893            }
13894            LanguageServerState::Running { server, .. } => server.remove_workspace_folder(uri),
13895        }
13896    }
13897}
13898
13899impl std::fmt::Debug for LanguageServerState {
13900    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
13901        match self {
13902            LanguageServerState::Starting { .. } => {
13903                f.debug_struct("LanguageServerState::Starting").finish()
13904            }
13905            LanguageServerState::Running { .. } => {
13906                f.debug_struct("LanguageServerState::Running").finish()
13907            }
13908        }
13909    }
13910}
13911
13912#[derive(Clone, Debug, Serialize)]
13913pub struct LanguageServerProgress {
13914    pub is_disk_based_diagnostics_progress: bool,
13915    pub is_cancellable: bool,
13916    pub title: Option<String>,
13917    pub message: Option<String>,
13918    pub percentage: Option<usize>,
13919    #[serde(skip_serializing)]
13920    pub last_update_at: Instant,
13921}
13922
13923#[derive(Copy, Clone, Debug, Default, PartialEq, Serialize)]
13924pub struct DiagnosticSummary {
13925    pub error_count: usize,
13926    pub warning_count: usize,
13927}
13928
13929impl DiagnosticSummary {
13930    pub fn new<'a, T: 'a>(diagnostics: impl IntoIterator<Item = &'a DiagnosticEntry<T>>) -> Self {
13931        let mut this = Self {
13932            error_count: 0,
13933            warning_count: 0,
13934        };
13935
13936        for entry in diagnostics {
13937            if entry.diagnostic.is_primary {
13938                match entry.diagnostic.severity {
13939                    DiagnosticSeverity::ERROR => this.error_count += 1,
13940                    DiagnosticSeverity::WARNING => this.warning_count += 1,
13941                    _ => {}
13942                }
13943            }
13944        }
13945
13946        this
13947    }
13948
13949    pub fn is_empty(&self) -> bool {
13950        self.error_count == 0 && self.warning_count == 0
13951    }
13952
13953    pub fn to_proto(
13954        self,
13955        language_server_id: LanguageServerId,
13956        path: &RelPath,
13957    ) -> proto::DiagnosticSummary {
13958        proto::DiagnosticSummary {
13959            path: path.to_proto(),
13960            language_server_id: language_server_id.0 as u64,
13961            error_count: self.error_count as u32,
13962            warning_count: self.warning_count as u32,
13963        }
13964    }
13965}
13966
13967#[derive(Clone, Debug)]
13968pub enum CompletionDocumentation {
13969    /// There is no documentation for this completion.
13970    Undocumented,
13971    /// A single line of documentation.
13972    SingleLine(SharedString),
13973    /// Multiple lines of plain text documentation.
13974    MultiLinePlainText(SharedString),
13975    /// Markdown documentation.
13976    MultiLineMarkdown(SharedString),
13977    /// Both single line and multiple lines of plain text documentation.
13978    SingleLineAndMultiLinePlainText {
13979        single_line: SharedString,
13980        plain_text: Option<SharedString>,
13981    },
13982}
13983
13984impl CompletionDocumentation {
13985    #[cfg(any(test, feature = "test-support"))]
13986    pub fn text(&self) -> SharedString {
13987        match self {
13988            CompletionDocumentation::Undocumented => "".into(),
13989            CompletionDocumentation::SingleLine(s) => s.clone(),
13990            CompletionDocumentation::MultiLinePlainText(s) => s.clone(),
13991            CompletionDocumentation::MultiLineMarkdown(s) => s.clone(),
13992            CompletionDocumentation::SingleLineAndMultiLinePlainText { single_line, .. } => {
13993                single_line.clone()
13994            }
13995        }
13996    }
13997}
13998
13999impl From<lsp::Documentation> for CompletionDocumentation {
14000    fn from(docs: lsp::Documentation) -> Self {
14001        match docs {
14002            lsp::Documentation::String(text) => {
14003                if text.lines().count() <= 1 {
14004                    CompletionDocumentation::SingleLine(text.trim().to_string().into())
14005                } else {
14006                    CompletionDocumentation::MultiLinePlainText(text.into())
14007                }
14008            }
14009
14010            lsp::Documentation::MarkupContent(lsp::MarkupContent { kind, value }) => match kind {
14011                lsp::MarkupKind::PlainText => {
14012                    if value.lines().count() <= 1 {
14013                        CompletionDocumentation::SingleLine(value.into())
14014                    } else {
14015                        CompletionDocumentation::MultiLinePlainText(value.into())
14016                    }
14017                }
14018
14019                lsp::MarkupKind::Markdown => {
14020                    CompletionDocumentation::MultiLineMarkdown(value.into())
14021                }
14022            },
14023        }
14024    }
14025}
14026
14027pub enum ResolvedHint {
14028    Resolved(InlayHint),
14029    Resolving(Shared<Task<()>>),
14030}
14031
14032fn glob_literal_prefix(glob: &Path) -> PathBuf {
14033    glob.components()
14034        .take_while(|component| match component {
14035            path::Component::Normal(part) => !part.to_string_lossy().contains(['*', '?', '{', '}']),
14036            _ => true,
14037        })
14038        .collect()
14039}
14040
14041pub struct SshLspAdapter {
14042    name: LanguageServerName,
14043    binary: LanguageServerBinary,
14044    initialization_options: Option<String>,
14045    code_action_kinds: Option<Vec<CodeActionKind>>,
14046}
14047
14048impl SshLspAdapter {
14049    pub fn new(
14050        name: LanguageServerName,
14051        binary: LanguageServerBinary,
14052        initialization_options: Option<String>,
14053        code_action_kinds: Option<String>,
14054    ) -> Self {
14055        Self {
14056            name,
14057            binary,
14058            initialization_options,
14059            code_action_kinds: code_action_kinds
14060                .as_ref()
14061                .and_then(|c| serde_json::from_str(c).ok()),
14062        }
14063    }
14064}
14065
14066impl LspInstaller for SshLspAdapter {
14067    type BinaryVersion = ();
14068    async fn check_if_user_installed(
14069        &self,
14070        _: &dyn LspAdapterDelegate,
14071        _: Option<Toolchain>,
14072        _: &AsyncApp,
14073    ) -> Option<LanguageServerBinary> {
14074        Some(self.binary.clone())
14075    }
14076
14077    async fn cached_server_binary(
14078        &self,
14079        _: PathBuf,
14080        _: &dyn LspAdapterDelegate,
14081    ) -> Option<LanguageServerBinary> {
14082        None
14083    }
14084
14085    async fn fetch_latest_server_version(
14086        &self,
14087        _: &dyn LspAdapterDelegate,
14088        _: bool,
14089        _: &mut AsyncApp,
14090    ) -> Result<()> {
14091        anyhow::bail!("SshLspAdapter does not support fetch_latest_server_version")
14092    }
14093
14094    async fn fetch_server_binary(
14095        &self,
14096        _: (),
14097        _: PathBuf,
14098        _: &dyn LspAdapterDelegate,
14099    ) -> Result<LanguageServerBinary> {
14100        anyhow::bail!("SshLspAdapter does not support fetch_server_binary")
14101    }
14102}
14103
14104#[async_trait(?Send)]
14105impl LspAdapter for SshLspAdapter {
14106    fn name(&self) -> LanguageServerName {
14107        self.name.clone()
14108    }
14109
14110    async fn initialization_options(
14111        self: Arc<Self>,
14112        _: &Arc<dyn LspAdapterDelegate>,
14113    ) -> Result<Option<serde_json::Value>> {
14114        let Some(options) = &self.initialization_options else {
14115            return Ok(None);
14116        };
14117        let result = serde_json::from_str(options)?;
14118        Ok(result)
14119    }
14120
14121    fn code_action_kinds(&self) -> Option<Vec<CodeActionKind>> {
14122        self.code_action_kinds.clone()
14123    }
14124}
14125
14126pub fn language_server_settings<'a>(
14127    delegate: &'a dyn LspAdapterDelegate,
14128    language: &LanguageServerName,
14129    cx: &'a App,
14130) -> Option<&'a LspSettings> {
14131    language_server_settings_for(
14132        SettingsLocation {
14133            worktree_id: delegate.worktree_id(),
14134            path: RelPath::empty(),
14135        },
14136        language,
14137        cx,
14138    )
14139}
14140
14141pub fn language_server_settings_for<'a>(
14142    location: SettingsLocation<'a>,
14143    language: &LanguageServerName,
14144    cx: &'a App,
14145) -> Option<&'a LspSettings> {
14146    ProjectSettings::get(Some(location), cx).lsp.get(language)
14147}
14148
14149pub struct LocalLspAdapterDelegate {
14150    lsp_store: WeakEntity<LspStore>,
14151    worktree: worktree::Snapshot,
14152    fs: Arc<dyn Fs>,
14153    http_client: Arc<dyn HttpClient>,
14154    language_registry: Arc<LanguageRegistry>,
14155    load_shell_env_task: Shared<Task<Option<HashMap<String, String>>>>,
14156}
14157
14158impl LocalLspAdapterDelegate {
14159    pub fn new(
14160        language_registry: Arc<LanguageRegistry>,
14161        environment: &Entity<ProjectEnvironment>,
14162        lsp_store: WeakEntity<LspStore>,
14163        worktree: &Entity<Worktree>,
14164        http_client: Arc<dyn HttpClient>,
14165        fs: Arc<dyn Fs>,
14166        cx: &mut App,
14167    ) -> Arc<Self> {
14168        let load_shell_env_task =
14169            environment.update(cx, |env, cx| env.worktree_environment(worktree.clone(), cx));
14170
14171        Arc::new(Self {
14172            lsp_store,
14173            worktree: worktree.read(cx).snapshot(),
14174            fs,
14175            http_client,
14176            language_registry,
14177            load_shell_env_task,
14178        })
14179    }
14180
14181    pub fn from_local_lsp(
14182        local: &LocalLspStore,
14183        worktree: &Entity<Worktree>,
14184        cx: &mut App,
14185    ) -> Arc<Self> {
14186        Self::new(
14187            local.languages.clone(),
14188            &local.environment,
14189            local.weak.clone(),
14190            worktree,
14191            local.http_client.clone(),
14192            local.fs.clone(),
14193            cx,
14194        )
14195    }
14196}
14197
14198#[async_trait]
14199impl LspAdapterDelegate for LocalLspAdapterDelegate {
14200    fn show_notification(&self, message: &str, cx: &mut App) {
14201        self.lsp_store
14202            .update(cx, |_, cx| {
14203                cx.emit(LspStoreEvent::Notification(message.to_owned()))
14204            })
14205            .ok();
14206    }
14207
14208    fn http_client(&self) -> Arc<dyn HttpClient> {
14209        self.http_client.clone()
14210    }
14211
14212    fn worktree_id(&self) -> WorktreeId {
14213        self.worktree.id()
14214    }
14215
14216    fn worktree_root_path(&self) -> &Path {
14217        self.worktree.abs_path().as_ref()
14218    }
14219
14220    fn resolve_executable_path(&self, path: PathBuf) -> PathBuf {
14221        self.worktree.resolve_executable_path(path)
14222    }
14223
14224    async fn shell_env(&self) -> HashMap<String, String> {
14225        let task = self.load_shell_env_task.clone();
14226        task.await.unwrap_or_default()
14227    }
14228
14229    async fn npm_package_installed_version(
14230        &self,
14231        package_name: &str,
14232    ) -> Result<Option<(PathBuf, Version)>> {
14233        let local_package_directory = self.worktree_root_path();
14234        let node_modules_directory = local_package_directory.join("node_modules");
14235
14236        if let Some(version) =
14237            read_package_installed_version(node_modules_directory.clone(), package_name).await?
14238        {
14239            return Ok(Some((node_modules_directory, version)));
14240        }
14241        let Some(npm) = self.which("npm".as_ref()).await else {
14242            log::warn!(
14243                "Failed to find npm executable for {:?}",
14244                local_package_directory
14245            );
14246            return Ok(None);
14247        };
14248
14249        let env = self.shell_env().await;
14250        let output = util::command::new_smol_command(&npm)
14251            .args(["root", "-g"])
14252            .envs(env)
14253            .current_dir(local_package_directory)
14254            .output()
14255            .await?;
14256        let global_node_modules =
14257            PathBuf::from(String::from_utf8_lossy(&output.stdout).to_string());
14258
14259        if let Some(version) =
14260            read_package_installed_version(global_node_modules.clone(), package_name).await?
14261        {
14262            return Ok(Some((global_node_modules, version)));
14263        }
14264        return Ok(None);
14265    }
14266
14267    async fn which(&self, command: &OsStr) -> Option<PathBuf> {
14268        let mut worktree_abs_path = self.worktree_root_path().to_path_buf();
14269        if self.fs.is_file(&worktree_abs_path).await {
14270            worktree_abs_path.pop();
14271        }
14272
14273        let env = self.shell_env().await;
14274
14275        let shell_path = env.get("PATH").cloned();
14276
14277        which::which_in(command, shell_path.as_ref(), worktree_abs_path).ok()
14278    }
14279
14280    async fn try_exec(&self, command: LanguageServerBinary) -> Result<()> {
14281        let mut working_dir = self.worktree_root_path().to_path_buf();
14282        if self.fs.is_file(&working_dir).await {
14283            working_dir.pop();
14284        }
14285        let output = util::command::new_smol_command(&command.path)
14286            .args(command.arguments)
14287            .envs(command.env.clone().unwrap_or_default())
14288            .current_dir(working_dir)
14289            .output()
14290            .await?;
14291
14292        anyhow::ensure!(
14293            output.status.success(),
14294            "{}, stdout: {:?}, stderr: {:?}",
14295            output.status,
14296            String::from_utf8_lossy(&output.stdout),
14297            String::from_utf8_lossy(&output.stderr)
14298        );
14299        Ok(())
14300    }
14301
14302    fn update_status(&self, server_name: LanguageServerName, status: language::BinaryStatus) {
14303        self.language_registry
14304            .update_lsp_binary_status(server_name, status);
14305    }
14306
14307    fn registered_lsp_adapters(&self) -> Vec<Arc<dyn LspAdapter>> {
14308        self.language_registry
14309            .all_lsp_adapters()
14310            .into_iter()
14311            .map(|adapter| adapter.adapter.clone() as Arc<dyn LspAdapter>)
14312            .collect()
14313    }
14314
14315    async fn language_server_download_dir(&self, name: &LanguageServerName) -> Option<Arc<Path>> {
14316        let dir = self.language_registry.language_server_download_dir(name)?;
14317
14318        if !dir.exists() {
14319            smol::fs::create_dir_all(&dir)
14320                .await
14321                .context("failed to create container directory")
14322                .log_err()?;
14323        }
14324
14325        Some(dir)
14326    }
14327
14328    async fn read_text_file(&self, path: &RelPath) -> Result<String> {
14329        let entry = self
14330            .worktree
14331            .entry_for_path(path)
14332            .with_context(|| format!("no worktree entry for path {path:?}"))?;
14333        let abs_path = self.worktree.absolutize(&entry.path);
14334        self.fs.load(&abs_path).await
14335    }
14336}
14337
14338async fn populate_labels_for_symbols(
14339    symbols: Vec<CoreSymbol>,
14340    language_registry: &Arc<LanguageRegistry>,
14341    lsp_adapter: Option<Arc<CachedLspAdapter>>,
14342    output: &mut Vec<Symbol>,
14343) {
14344    #[allow(clippy::mutable_key_type)]
14345    let mut symbols_by_language = HashMap::<Option<Arc<Language>>, Vec<CoreSymbol>>::default();
14346
14347    let mut unknown_paths = BTreeSet::<Arc<str>>::new();
14348    for symbol in symbols {
14349        let Some(file_name) = symbol.path.file_name() else {
14350            continue;
14351        };
14352        let language = language_registry
14353            .load_language_for_file_path(Path::new(file_name))
14354            .await
14355            .ok()
14356            .or_else(|| {
14357                unknown_paths.insert(file_name.into());
14358                None
14359            });
14360        symbols_by_language
14361            .entry(language)
14362            .or_default()
14363            .push(symbol);
14364    }
14365
14366    for unknown_path in unknown_paths {
14367        log::info!("no language found for symbol in file {unknown_path:?}");
14368    }
14369
14370    let mut label_params = Vec::new();
14371    for (language, mut symbols) in symbols_by_language {
14372        label_params.clear();
14373        label_params.extend(
14374            symbols
14375                .iter_mut()
14376                .map(|symbol| (mem::take(&mut symbol.name), symbol.kind)),
14377        );
14378
14379        let mut labels = Vec::new();
14380        if let Some(language) = language {
14381            let lsp_adapter = lsp_adapter.clone().or_else(|| {
14382                language_registry
14383                    .lsp_adapters(&language.name())
14384                    .first()
14385                    .cloned()
14386            });
14387            if let Some(lsp_adapter) = lsp_adapter {
14388                labels = lsp_adapter
14389                    .labels_for_symbols(&label_params, &language)
14390                    .await
14391                    .log_err()
14392                    .unwrap_or_default();
14393            }
14394        }
14395
14396        for ((symbol, (name, _)), label) in symbols
14397            .into_iter()
14398            .zip(label_params.drain(..))
14399            .zip(labels.into_iter().chain(iter::repeat(None)))
14400        {
14401            output.push(Symbol {
14402                language_server_name: symbol.language_server_name,
14403                source_worktree_id: symbol.source_worktree_id,
14404                source_language_server_id: symbol.source_language_server_id,
14405                path: symbol.path,
14406                label: label.unwrap_or_else(|| CodeLabel::plain(name.clone(), None)),
14407                name,
14408                kind: symbol.kind,
14409                range: symbol.range,
14410            });
14411        }
14412    }
14413}
14414
14415fn include_text(server: &lsp::LanguageServer) -> Option<bool> {
14416    match server.capabilities().text_document_sync.as_ref()? {
14417        lsp::TextDocumentSyncCapability::Options(opts) => match opts.save.as_ref()? {
14418            // Server wants didSave but didn't specify includeText.
14419            lsp::TextDocumentSyncSaveOptions::Supported(true) => Some(false),
14420            // Server doesn't want didSave at all.
14421            lsp::TextDocumentSyncSaveOptions::Supported(false) => None,
14422            // Server provided SaveOptions.
14423            lsp::TextDocumentSyncSaveOptions::SaveOptions(save_options) => {
14424                Some(save_options.include_text.unwrap_or(false))
14425            }
14426        },
14427        // We do not have any save info. Kind affects didChange only.
14428        lsp::TextDocumentSyncCapability::Kind(_) => None,
14429    }
14430}
14431
14432/// Completion items are displayed in a `UniformList`.
14433/// Usually, those items are single-line strings, but in LSP responses,
14434/// completion items `label`, `detail` and `label_details.description` may contain newlines or long spaces.
14435/// Many language plugins construct these items by joining these parts together, and we may use `CodeLabel::fallback_for_completion` that uses `label` at least.
14436/// 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,
14437/// breaking the completions menu presentation.
14438///
14439/// 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.
14440fn ensure_uniform_list_compatible_label(label: &mut CodeLabel) {
14441    let mut new_text = String::with_capacity(label.text.len());
14442    let mut offset_map = vec![0; label.text.len() + 1];
14443    let mut last_char_was_space = false;
14444    let mut new_idx = 0;
14445    let chars = label.text.char_indices().fuse();
14446    let mut newlines_removed = false;
14447
14448    for (idx, c) in chars {
14449        offset_map[idx] = new_idx;
14450
14451        match c {
14452            '\n' if last_char_was_space => {
14453                newlines_removed = true;
14454            }
14455            '\t' | ' ' if last_char_was_space => {}
14456            '\n' if !last_char_was_space => {
14457                new_text.push(' ');
14458                new_idx += 1;
14459                last_char_was_space = true;
14460                newlines_removed = true;
14461            }
14462            ' ' | '\t' => {
14463                new_text.push(' ');
14464                new_idx += 1;
14465                last_char_was_space = true;
14466            }
14467            _ => {
14468                new_text.push(c);
14469                new_idx += c.len_utf8();
14470                last_char_was_space = false;
14471            }
14472        }
14473    }
14474    offset_map[label.text.len()] = new_idx;
14475
14476    // Only modify the label if newlines were removed.
14477    if !newlines_removed {
14478        return;
14479    }
14480
14481    let last_index = new_idx;
14482    let mut run_ranges_errors = Vec::new();
14483    label.runs.retain_mut(|(range, _)| {
14484        match offset_map.get(range.start) {
14485            Some(&start) => range.start = start,
14486            None => {
14487                run_ranges_errors.push(range.clone());
14488                return false;
14489            }
14490        }
14491
14492        match offset_map.get(range.end) {
14493            Some(&end) => range.end = end,
14494            None => {
14495                run_ranges_errors.push(range.clone());
14496                range.end = last_index;
14497            }
14498        }
14499        true
14500    });
14501    if !run_ranges_errors.is_empty() {
14502        log::error!(
14503            "Completion label has errors in its run ranges: {run_ranges_errors:?}, label text: {}",
14504            label.text
14505        );
14506    }
14507
14508    let mut wrong_filter_range = None;
14509    if label.filter_range == (0..label.text.len()) {
14510        label.filter_range = 0..new_text.len();
14511    } else {
14512        let mut original_filter_range = Some(label.filter_range.clone());
14513        match offset_map.get(label.filter_range.start) {
14514            Some(&start) => label.filter_range.start = start,
14515            None => {
14516                wrong_filter_range = original_filter_range.take();
14517                label.filter_range.start = last_index;
14518            }
14519        }
14520
14521        match offset_map.get(label.filter_range.end) {
14522            Some(&end) => label.filter_range.end = end,
14523            None => {
14524                wrong_filter_range = original_filter_range.take();
14525                label.filter_range.end = last_index;
14526            }
14527        }
14528    }
14529    if let Some(wrong_filter_range) = wrong_filter_range {
14530        log::error!(
14531            "Completion label has an invalid filter range: {wrong_filter_range:?}, label text: {}",
14532            label.text
14533        );
14534    }
14535
14536    label.text = new_text;
14537}
14538
14539#[cfg(test)]
14540mod tests {
14541    use language::HighlightId;
14542
14543    use super::*;
14544
14545    #[test]
14546    fn test_glob_literal_prefix() {
14547        assert_eq!(glob_literal_prefix(Path::new("**/*.js")), Path::new(""));
14548        assert_eq!(
14549            glob_literal_prefix(Path::new("node_modules/**/*.js")),
14550            Path::new("node_modules")
14551        );
14552        assert_eq!(
14553            glob_literal_prefix(Path::new("foo/{bar,baz}.js")),
14554            Path::new("foo")
14555        );
14556        assert_eq!(
14557            glob_literal_prefix(Path::new("foo/bar/baz.js")),
14558            Path::new("foo/bar/baz.js")
14559        );
14560
14561        #[cfg(target_os = "windows")]
14562        {
14563            assert_eq!(glob_literal_prefix(Path::new("**\\*.js")), Path::new(""));
14564            assert_eq!(
14565                glob_literal_prefix(Path::new("node_modules\\**/*.js")),
14566                Path::new("node_modules")
14567            );
14568            assert_eq!(
14569                glob_literal_prefix(Path::new("foo/{bar,baz}.js")),
14570                Path::new("foo")
14571            );
14572            assert_eq!(
14573                glob_literal_prefix(Path::new("foo\\bar\\baz.js")),
14574                Path::new("foo/bar/baz.js")
14575            );
14576        }
14577    }
14578
14579    #[test]
14580    fn test_multi_len_chars_normalization() {
14581        let mut label = CodeLabel::new(
14582            "myElˇ (parameter) myElˇ: {\n    foo: string;\n}".to_string(),
14583            0..6,
14584            vec![(0..6, HighlightId(1))],
14585        );
14586        ensure_uniform_list_compatible_label(&mut label);
14587        assert_eq!(
14588            label,
14589            CodeLabel::new(
14590                "myElˇ (parameter) myElˇ: { foo: string; }".to_string(),
14591                0..6,
14592                vec![(0..6, HighlightId(1))],
14593            )
14594        );
14595    }
14596
14597    #[test]
14598    fn test_trailing_newline_in_completion_documentation() {
14599        let doc = lsp::Documentation::String(
14600            "Inappropriate argument value (of correct type).\n".to_string(),
14601        );
14602        let completion_doc: CompletionDocumentation = doc.into();
14603        assert!(
14604            matches!(completion_doc, CompletionDocumentation::SingleLine(s) if s == "Inappropriate argument value (of correct type).")
14605        );
14606
14607        let doc = lsp::Documentation::String("  some value  \n".to_string());
14608        let completion_doc: CompletionDocumentation = doc.into();
14609        assert!(matches!(
14610            completion_doc,
14611            CompletionDocumentation::SingleLine(s) if s == "some value"
14612        ));
14613    }
14614}