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_lsp_edit, deserialize_version, serialize_anchor,
   73        serialize_lsp_edit, serialize_version,
   74    },
   75    range_from_lsp, range_to_lsp,
   76    row_chunk::RowChunk,
   77};
   78use lsp::{
   79    AdapterServerCapabilities, CodeActionKind, CompletionContext, CompletionOptions,
   80    DiagnosticServerCapabilities, DiagnosticSeverity, DiagnosticTag,
   81    DidChangeWatchedFilesRegistrationOptions, Edit, FileOperationFilter, FileOperationPatternKind,
   82    FileOperationRegistrationOptions, FileRename, FileSystemWatcher, LSP_REQUEST_TIMEOUT,
   83    LanguageServer, LanguageServerBinary, LanguageServerBinaryOptions, LanguageServerId,
   84    LanguageServerName, LanguageServerSelector, LspRequestFuture, MessageActionItem, MessageType,
   85    OneOf, RenameFilesParams, SymbolKind, TextDocumentSyncSaveOptions, TextEdit, Uri,
   86    WillRenameFiles, WorkDoneProgressCancelParams, WorkspaceFolder, notification::DidRenameFiles,
   87};
   88use node_runtime::read_package_installed_version;
   89use parking_lot::Mutex;
   90use postage::{mpsc, sink::Sink, stream::Stream, watch};
   91use rand::prelude::*;
   92use rpc::{
   93    AnyProtoClient, ErrorCode, ErrorExt as _,
   94    proto::{LspRequestId, LspRequestMessage as _},
   95};
   96use 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.as_ref(),
 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            // Don't support formatting ranges via remote
10752            match target {
10753                LspFormatTarget::Buffers => {}
10754                LspFormatTarget::Ranges(_) => {
10755                    zlog::trace!(logger => "Ignoring unsupported remote range formatting request");
10756                    return Task::ready(Ok(ProjectTransaction::default()));
10757                }
10758            }
10759
10760            let buffer_store = self.buffer_store();
10761            cx.spawn(async move |lsp_store, cx| {
10762                zlog::trace!(logger => "Sending remote format request");
10763                let request_timer = zlog::time!(logger => "remote format request");
10764                let result = client
10765                    .request(proto::FormatBuffers {
10766                        project_id,
10767                        trigger: trigger as i32,
10768                        buffer_ids: buffers
10769                            .iter()
10770                            .map(|buffer| buffer.read_with(cx, |buffer, _| buffer.remote_id().to_proto()))
10771                            .collect(),
10772                    })
10773                    .await
10774                    .and_then(|result| result.transaction.context("missing transaction"));
10775                request_timer.end();
10776
10777                zlog::trace!(logger => "Remote format request resolved to {:?}", result.as_ref().map(|_| "<project_transaction>"));
10778
10779                lsp_store.update(cx, |lsp_store, _| {
10780                    lsp_store.update_last_formatting_failure(&result);
10781                })?;
10782
10783                let transaction_response = result?;
10784                let _timer = zlog::time!(logger => "deserializing project transaction");
10785                buffer_store
10786                    .update(cx, |buffer_store, cx| {
10787                        buffer_store.deserialize_project_transaction(
10788                            transaction_response,
10789                            push_to_history,
10790                            cx,
10791                        )
10792                    })
10793                    .await
10794            })
10795        } else {
10796            zlog::trace!(logger => "Not formatting");
10797            Task::ready(Ok(ProjectTransaction::default()))
10798        }
10799    }
10800
10801    async fn handle_format_buffers(
10802        this: Entity<Self>,
10803        envelope: TypedEnvelope<proto::FormatBuffers>,
10804        mut cx: AsyncApp,
10805    ) -> Result<proto::FormatBuffersResponse> {
10806        let sender_id = envelope.original_sender_id().unwrap_or_default();
10807        let format = this.update(&mut cx, |this, cx| {
10808            let mut buffers = HashSet::default();
10809            for buffer_id in &envelope.payload.buffer_ids {
10810                let buffer_id = BufferId::new(*buffer_id)?;
10811                buffers.insert(this.buffer_store.read(cx).get_existing(buffer_id)?);
10812            }
10813            let trigger = FormatTrigger::from_proto(envelope.payload.trigger);
10814            anyhow::Ok(this.format(buffers, LspFormatTarget::Buffers, false, trigger, cx))
10815        })?;
10816
10817        let project_transaction = format.await?;
10818        let project_transaction = this.update(&mut cx, |this, cx| {
10819            this.buffer_store.update(cx, |buffer_store, cx| {
10820                buffer_store.serialize_project_transaction_for_peer(
10821                    project_transaction,
10822                    sender_id,
10823                    cx,
10824                )
10825            })
10826        });
10827        Ok(proto::FormatBuffersResponse {
10828            transaction: Some(project_transaction),
10829        })
10830    }
10831
10832    async fn handle_apply_code_action_kind(
10833        this: Entity<Self>,
10834        envelope: TypedEnvelope<proto::ApplyCodeActionKind>,
10835        mut cx: AsyncApp,
10836    ) -> Result<proto::ApplyCodeActionKindResponse> {
10837        let sender_id = envelope.original_sender_id().unwrap_or_default();
10838        let format = this.update(&mut cx, |this, cx| {
10839            let mut buffers = HashSet::default();
10840            for buffer_id in &envelope.payload.buffer_ids {
10841                let buffer_id = BufferId::new(*buffer_id)?;
10842                buffers.insert(this.buffer_store.read(cx).get_existing(buffer_id)?);
10843            }
10844            let kind = match envelope.payload.kind.as_str() {
10845                "" => CodeActionKind::EMPTY,
10846                "quickfix" => CodeActionKind::QUICKFIX,
10847                "refactor" => CodeActionKind::REFACTOR,
10848                "refactor.extract" => CodeActionKind::REFACTOR_EXTRACT,
10849                "refactor.inline" => CodeActionKind::REFACTOR_INLINE,
10850                "refactor.rewrite" => CodeActionKind::REFACTOR_REWRITE,
10851                "source" => CodeActionKind::SOURCE,
10852                "source.organizeImports" => CodeActionKind::SOURCE_ORGANIZE_IMPORTS,
10853                "source.fixAll" => CodeActionKind::SOURCE_FIX_ALL,
10854                _ => anyhow::bail!(
10855                    "Invalid code action kind {}",
10856                    envelope.payload.kind.as_str()
10857                ),
10858            };
10859            anyhow::Ok(this.apply_code_action_kind(buffers, kind, false, cx))
10860        })?;
10861
10862        let project_transaction = format.await?;
10863        let project_transaction = this.update(&mut cx, |this, cx| {
10864            this.buffer_store.update(cx, |buffer_store, cx| {
10865                buffer_store.serialize_project_transaction_for_peer(
10866                    project_transaction,
10867                    sender_id,
10868                    cx,
10869                )
10870            })
10871        });
10872        Ok(proto::ApplyCodeActionKindResponse {
10873            transaction: Some(project_transaction),
10874        })
10875    }
10876
10877    async fn shutdown_language_server(
10878        server_state: Option<LanguageServerState>,
10879        name: LanguageServerName,
10880        cx: &mut AsyncApp,
10881    ) {
10882        let server = match server_state {
10883            Some(LanguageServerState::Starting { startup, .. }) => {
10884                let mut timer = cx
10885                    .background_executor()
10886                    .timer(SERVER_LAUNCHING_BEFORE_SHUTDOWN_TIMEOUT)
10887                    .fuse();
10888
10889                select! {
10890                    server = startup.fuse() => server,
10891                    () = timer => {
10892                        log::info!("timeout waiting for language server {name} to finish launching before stopping");
10893                        None
10894                    },
10895                }
10896            }
10897
10898            Some(LanguageServerState::Running { server, .. }) => Some(server),
10899
10900            None => None,
10901        };
10902
10903        if let Some(server) = server
10904            && let Some(shutdown) = server.shutdown()
10905        {
10906            shutdown.await;
10907        }
10908    }
10909
10910    // Returns a list of all of the worktrees which no longer have a language server and the root path
10911    // for the stopped server
10912    fn stop_local_language_server(
10913        &mut self,
10914        server_id: LanguageServerId,
10915        cx: &mut Context<Self>,
10916    ) -> Task<()> {
10917        let local = match &mut self.mode {
10918            LspStoreMode::Local(local) => local,
10919            _ => {
10920                return Task::ready(());
10921            }
10922        };
10923
10924        // Remove this server ID from all entries in the given worktree.
10925        local
10926            .language_server_ids
10927            .retain(|_, state| state.id != server_id);
10928        self.buffer_store.update(cx, |buffer_store, cx| {
10929            for buffer in buffer_store.buffers() {
10930                buffer.update(cx, |buffer, cx| {
10931                    buffer.update_diagnostics(server_id, DiagnosticSet::new([], buffer), cx);
10932                    buffer.set_completion_triggers(server_id, Default::default(), cx);
10933                });
10934            }
10935        });
10936
10937        for (worktree_id, summaries) in self.diagnostic_summaries.iter_mut() {
10938            summaries.retain(|path, summaries_by_server_id| {
10939                if summaries_by_server_id.remove(&server_id).is_some() {
10940                    if let Some((client, project_id)) = self.downstream_client.clone() {
10941                        client
10942                            .send(proto::UpdateDiagnosticSummary {
10943                                project_id,
10944                                worktree_id: worktree_id.to_proto(),
10945                                summary: Some(proto::DiagnosticSummary {
10946                                    path: path.as_ref().to_proto(),
10947                                    language_server_id: server_id.0 as u64,
10948                                    error_count: 0,
10949                                    warning_count: 0,
10950                                }),
10951                                more_summaries: Vec::new(),
10952                            })
10953                            .log_err();
10954                    }
10955                    !summaries_by_server_id.is_empty()
10956                } else {
10957                    true
10958                }
10959            });
10960        }
10961
10962        let local = self.as_local_mut().unwrap();
10963        for diagnostics in local.diagnostics.values_mut() {
10964            diagnostics.retain(|_, diagnostics_by_server_id| {
10965                if let Ok(ix) = diagnostics_by_server_id.binary_search_by_key(&server_id, |e| e.0) {
10966                    diagnostics_by_server_id.remove(ix);
10967                    !diagnostics_by_server_id.is_empty()
10968                } else {
10969                    true
10970                }
10971            });
10972        }
10973        local.language_server_watched_paths.remove(&server_id);
10974
10975        let server_state = local.language_servers.remove(&server_id);
10976        self.cleanup_lsp_data(server_id);
10977        let name = self
10978            .language_server_statuses
10979            .remove(&server_id)
10980            .map(|status| status.name)
10981            .or_else(|| {
10982                if let Some(LanguageServerState::Running { adapter, .. }) = server_state.as_ref() {
10983                    Some(adapter.name())
10984                } else {
10985                    None
10986                }
10987            });
10988
10989        if let Some(name) = name {
10990            log::info!("stopping language server {name}");
10991            self.languages
10992                .update_lsp_binary_status(name.clone(), BinaryStatus::Stopping);
10993            cx.notify();
10994
10995            return cx.spawn(async move |lsp_store, cx| {
10996                Self::shutdown_language_server(server_state, name.clone(), cx).await;
10997                lsp_store
10998                    .update(cx, |lsp_store, cx| {
10999                        lsp_store
11000                            .languages
11001                            .update_lsp_binary_status(name, BinaryStatus::Stopped);
11002                        cx.emit(LspStoreEvent::LanguageServerRemoved(server_id));
11003                        cx.notify();
11004                    })
11005                    .ok();
11006            });
11007        }
11008
11009        if server_state.is_some() {
11010            cx.emit(LspStoreEvent::LanguageServerRemoved(server_id));
11011        }
11012        Task::ready(())
11013    }
11014
11015    pub fn stop_all_language_servers(&mut self, cx: &mut Context<Self>) {
11016        if let Some((client, project_id)) = self.upstream_client() {
11017            let request = client.request(proto::StopLanguageServers {
11018                project_id,
11019                buffer_ids: Vec::new(),
11020                also_servers: Vec::new(),
11021                all: true,
11022            });
11023            cx.background_spawn(request).detach_and_log_err(cx);
11024        } else {
11025            let Some(local) = self.as_local_mut() else {
11026                return;
11027            };
11028            let language_servers_to_stop = local
11029                .language_server_ids
11030                .values()
11031                .map(|state| state.id)
11032                .collect();
11033            local.lsp_tree.remove_nodes(&language_servers_to_stop);
11034            let tasks = language_servers_to_stop
11035                .into_iter()
11036                .map(|server| self.stop_local_language_server(server, cx))
11037                .collect::<Vec<_>>();
11038            cx.background_spawn(async move {
11039                futures::future::join_all(tasks).await;
11040            })
11041            .detach();
11042        }
11043    }
11044
11045    pub fn restart_language_servers_for_buffers(
11046        &mut self,
11047        buffers: Vec<Entity<Buffer>>,
11048        only_restart_servers: HashSet<LanguageServerSelector>,
11049        cx: &mut Context<Self>,
11050    ) {
11051        if let Some((client, project_id)) = self.upstream_client() {
11052            let request = client.request(proto::RestartLanguageServers {
11053                project_id,
11054                buffer_ids: buffers
11055                    .into_iter()
11056                    .map(|b| b.read(cx).remote_id().to_proto())
11057                    .collect(),
11058                only_servers: only_restart_servers
11059                    .into_iter()
11060                    .map(|selector| {
11061                        let selector = match selector {
11062                            LanguageServerSelector::Id(language_server_id) => {
11063                                proto::language_server_selector::Selector::ServerId(
11064                                    language_server_id.to_proto(),
11065                                )
11066                            }
11067                            LanguageServerSelector::Name(language_server_name) => {
11068                                proto::language_server_selector::Selector::Name(
11069                                    language_server_name.to_string(),
11070                                )
11071                            }
11072                        };
11073                        proto::LanguageServerSelector {
11074                            selector: Some(selector),
11075                        }
11076                    })
11077                    .collect(),
11078                all: false,
11079            });
11080            cx.background_spawn(request).detach_and_log_err(cx);
11081        } else {
11082            let stop_task = if only_restart_servers.is_empty() {
11083                self.stop_local_language_servers_for_buffers(&buffers, HashSet::default(), cx)
11084            } else {
11085                self.stop_local_language_servers_for_buffers(&[], only_restart_servers.clone(), cx)
11086            };
11087            cx.spawn(async move |lsp_store, cx| {
11088                stop_task.await;
11089                lsp_store.update(cx, |lsp_store, cx| {
11090                    for buffer in buffers {
11091                        lsp_store.register_buffer_with_language_servers(
11092                            &buffer,
11093                            only_restart_servers.clone(),
11094                            true,
11095                            cx,
11096                        );
11097                    }
11098                })
11099            })
11100            .detach();
11101        }
11102    }
11103
11104    pub fn stop_language_servers_for_buffers(
11105        &mut self,
11106        buffers: Vec<Entity<Buffer>>,
11107        also_stop_servers: HashSet<LanguageServerSelector>,
11108        cx: &mut Context<Self>,
11109    ) -> Task<Result<()>> {
11110        if let Some((client, project_id)) = self.upstream_client() {
11111            let request = client.request(proto::StopLanguageServers {
11112                project_id,
11113                buffer_ids: buffers
11114                    .into_iter()
11115                    .map(|b| b.read(cx).remote_id().to_proto())
11116                    .collect(),
11117                also_servers: also_stop_servers
11118                    .into_iter()
11119                    .map(|selector| {
11120                        let selector = match selector {
11121                            LanguageServerSelector::Id(language_server_id) => {
11122                                proto::language_server_selector::Selector::ServerId(
11123                                    language_server_id.to_proto(),
11124                                )
11125                            }
11126                            LanguageServerSelector::Name(language_server_name) => {
11127                                proto::language_server_selector::Selector::Name(
11128                                    language_server_name.to_string(),
11129                                )
11130                            }
11131                        };
11132                        proto::LanguageServerSelector {
11133                            selector: Some(selector),
11134                        }
11135                    })
11136                    .collect(),
11137                all: false,
11138            });
11139            cx.background_spawn(async move {
11140                let _ = request.await?;
11141                Ok(())
11142            })
11143        } else {
11144            let task =
11145                self.stop_local_language_servers_for_buffers(&buffers, also_stop_servers, cx);
11146            cx.background_spawn(async move {
11147                task.await;
11148                Ok(())
11149            })
11150        }
11151    }
11152
11153    fn stop_local_language_servers_for_buffers(
11154        &mut self,
11155        buffers: &[Entity<Buffer>],
11156        also_stop_servers: HashSet<LanguageServerSelector>,
11157        cx: &mut Context<Self>,
11158    ) -> Task<()> {
11159        let Some(local) = self.as_local_mut() else {
11160            return Task::ready(());
11161        };
11162        let mut language_server_names_to_stop = BTreeSet::default();
11163        let mut language_servers_to_stop = also_stop_servers
11164            .into_iter()
11165            .flat_map(|selector| match selector {
11166                LanguageServerSelector::Id(id) => Some(id),
11167                LanguageServerSelector::Name(name) => {
11168                    language_server_names_to_stop.insert(name);
11169                    None
11170                }
11171            })
11172            .collect::<BTreeSet<_>>();
11173
11174        let mut covered_worktrees = HashSet::default();
11175        for buffer in buffers {
11176            buffer.update(cx, |buffer, cx| {
11177                language_servers_to_stop.extend(local.language_server_ids_for_buffer(buffer, cx));
11178                if let Some(worktree_id) = buffer.file().map(|f| f.worktree_id(cx))
11179                    && covered_worktrees.insert(worktree_id)
11180                {
11181                    language_server_names_to_stop.retain(|name| {
11182                        let old_ids_count = language_servers_to_stop.len();
11183                        let all_language_servers_with_this_name = local
11184                            .language_server_ids
11185                            .iter()
11186                            .filter_map(|(seed, state)| seed.name.eq(name).then(|| state.id));
11187                        language_servers_to_stop.extend(all_language_servers_with_this_name);
11188                        old_ids_count == language_servers_to_stop.len()
11189                    });
11190                }
11191            });
11192        }
11193        for name in language_server_names_to_stop {
11194            language_servers_to_stop.extend(
11195                local
11196                    .language_server_ids
11197                    .iter()
11198                    .filter_map(|(seed, v)| seed.name.eq(&name).then(|| v.id)),
11199            );
11200        }
11201
11202        local.lsp_tree.remove_nodes(&language_servers_to_stop);
11203        let tasks = language_servers_to_stop
11204            .into_iter()
11205            .map(|server| self.stop_local_language_server(server, cx))
11206            .collect::<Vec<_>>();
11207
11208        cx.background_spawn(futures::future::join_all(tasks).map(|_| ()))
11209    }
11210
11211    fn get_buffer<'a>(&self, abs_path: &Path, cx: &'a App) -> Option<&'a Buffer> {
11212        let (worktree, relative_path) =
11213            self.worktree_store.read(cx).find_worktree(&abs_path, cx)?;
11214
11215        let project_path = ProjectPath {
11216            worktree_id: worktree.read(cx).id(),
11217            path: relative_path,
11218        };
11219
11220        Some(
11221            self.buffer_store()
11222                .read(cx)
11223                .get_by_path(&project_path)?
11224                .read(cx),
11225        )
11226    }
11227
11228    #[cfg(any(test, feature = "test-support"))]
11229    pub fn update_diagnostics(
11230        &mut self,
11231        server_id: LanguageServerId,
11232        diagnostics: lsp::PublishDiagnosticsParams,
11233        result_id: Option<SharedString>,
11234        source_kind: DiagnosticSourceKind,
11235        disk_based_sources: &[String],
11236        cx: &mut Context<Self>,
11237    ) -> Result<()> {
11238        self.merge_lsp_diagnostics(
11239            source_kind,
11240            vec![DocumentDiagnosticsUpdate {
11241                diagnostics,
11242                result_id,
11243                server_id,
11244                disk_based_sources: Cow::Borrowed(disk_based_sources),
11245                registration_id: None,
11246            }],
11247            |_, _, _| false,
11248            cx,
11249        )
11250    }
11251
11252    pub fn merge_lsp_diagnostics(
11253        &mut self,
11254        source_kind: DiagnosticSourceKind,
11255        lsp_diagnostics: Vec<DocumentDiagnosticsUpdate<lsp::PublishDiagnosticsParams>>,
11256        merge: impl Fn(&lsp::Uri, &Diagnostic, &App) -> bool + Clone,
11257        cx: &mut Context<Self>,
11258    ) -> Result<()> {
11259        anyhow::ensure!(self.mode.is_local(), "called update_diagnostics on remote");
11260        let updates = lsp_diagnostics
11261            .into_iter()
11262            .filter_map(|update| {
11263                let abs_path = update.diagnostics.uri.to_file_path().ok()?;
11264                Some(DocumentDiagnosticsUpdate {
11265                    diagnostics: self.lsp_to_document_diagnostics(
11266                        abs_path,
11267                        source_kind,
11268                        update.server_id,
11269                        update.diagnostics,
11270                        &update.disk_based_sources,
11271                        update.registration_id.clone(),
11272                    ),
11273                    result_id: update.result_id,
11274                    server_id: update.server_id,
11275                    disk_based_sources: update.disk_based_sources,
11276                    registration_id: update.registration_id,
11277                })
11278            })
11279            .collect();
11280        self.merge_diagnostic_entries(updates, merge, cx)?;
11281        Ok(())
11282    }
11283
11284    fn lsp_to_document_diagnostics(
11285        &mut self,
11286        document_abs_path: PathBuf,
11287        source_kind: DiagnosticSourceKind,
11288        server_id: LanguageServerId,
11289        mut lsp_diagnostics: lsp::PublishDiagnosticsParams,
11290        disk_based_sources: &[String],
11291        registration_id: Option<SharedString>,
11292    ) -> DocumentDiagnostics {
11293        let mut diagnostics = Vec::default();
11294        let mut primary_diagnostic_group_ids = HashMap::default();
11295        let mut sources_by_group_id = HashMap::default();
11296        let mut supporting_diagnostics = HashMap::default();
11297
11298        let adapter = self.language_server_adapter_for_id(server_id);
11299
11300        // Ensure that primary diagnostics are always the most severe
11301        lsp_diagnostics
11302            .diagnostics
11303            .sort_by_key(|item| item.severity);
11304
11305        for diagnostic in &lsp_diagnostics.diagnostics {
11306            let source = diagnostic.source.as_ref();
11307            let range = range_from_lsp(diagnostic.range);
11308            let is_supporting = diagnostic
11309                .related_information
11310                .as_ref()
11311                .is_some_and(|infos| {
11312                    infos.iter().any(|info| {
11313                        primary_diagnostic_group_ids.contains_key(&(
11314                            source,
11315                            diagnostic.code.clone(),
11316                            range_from_lsp(info.location.range),
11317                        ))
11318                    })
11319                });
11320
11321            let is_unnecessary = diagnostic
11322                .tags
11323                .as_ref()
11324                .is_some_and(|tags| tags.contains(&DiagnosticTag::UNNECESSARY));
11325
11326            let underline = self
11327                .language_server_adapter_for_id(server_id)
11328                .is_none_or(|adapter| adapter.underline_diagnostic(diagnostic));
11329
11330            if is_supporting {
11331                supporting_diagnostics.insert(
11332                    (source, diagnostic.code.clone(), range),
11333                    (diagnostic.severity, is_unnecessary),
11334                );
11335            } else {
11336                let group_id = post_inc(&mut self.as_local_mut().unwrap().next_diagnostic_group_id);
11337                let is_disk_based =
11338                    source.is_some_and(|source| disk_based_sources.contains(source));
11339
11340                sources_by_group_id.insert(group_id, source);
11341                primary_diagnostic_group_ids
11342                    .insert((source, diagnostic.code.clone(), range.clone()), group_id);
11343
11344                diagnostics.push(DiagnosticEntry {
11345                    range,
11346                    diagnostic: Diagnostic {
11347                        source: diagnostic.source.clone(),
11348                        source_kind,
11349                        code: diagnostic.code.clone(),
11350                        code_description: diagnostic
11351                            .code_description
11352                            .as_ref()
11353                            .and_then(|d| d.href.clone()),
11354                        severity: diagnostic.severity.unwrap_or(DiagnosticSeverity::ERROR),
11355                        markdown: adapter.as_ref().and_then(|adapter| {
11356                            adapter.diagnostic_message_to_markdown(&diagnostic.message)
11357                        }),
11358                        message: diagnostic.message.trim().to_string(),
11359                        group_id,
11360                        is_primary: true,
11361                        is_disk_based,
11362                        is_unnecessary,
11363                        underline,
11364                        data: diagnostic.data.clone(),
11365                        registration_id: registration_id.clone(),
11366                    },
11367                });
11368                if let Some(infos) = &diagnostic.related_information {
11369                    for info in infos {
11370                        if info.location.uri == lsp_diagnostics.uri && !info.message.is_empty() {
11371                            let range = range_from_lsp(info.location.range);
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: DiagnosticSeverity::INFORMATION,
11383                                    markdown: adapter.as_ref().and_then(|adapter| {
11384                                        adapter.diagnostic_message_to_markdown(&info.message)
11385                                    }),
11386                                    message: info.message.trim().to_string(),
11387                                    group_id,
11388                                    is_primary: false,
11389                                    is_disk_based,
11390                                    is_unnecessary: false,
11391                                    underline,
11392                                    data: diagnostic.data.clone(),
11393                                    registration_id: registration_id.clone(),
11394                                },
11395                            });
11396                        }
11397                    }
11398                }
11399            }
11400        }
11401
11402        for entry in &mut diagnostics {
11403            let diagnostic = &mut entry.diagnostic;
11404            if !diagnostic.is_primary {
11405                let source = *sources_by_group_id.get(&diagnostic.group_id).unwrap();
11406                if let Some(&(severity, is_unnecessary)) = supporting_diagnostics.get(&(
11407                    source,
11408                    diagnostic.code.clone(),
11409                    entry.range.clone(),
11410                )) {
11411                    if let Some(severity) = severity {
11412                        diagnostic.severity = severity;
11413                    }
11414                    diagnostic.is_unnecessary = is_unnecessary;
11415                }
11416            }
11417        }
11418
11419        DocumentDiagnostics {
11420            diagnostics,
11421            document_abs_path,
11422            version: lsp_diagnostics.version,
11423        }
11424    }
11425
11426    fn insert_newly_running_language_server(
11427        &mut self,
11428        adapter: Arc<CachedLspAdapter>,
11429        language_server: Arc<LanguageServer>,
11430        server_id: LanguageServerId,
11431        key: LanguageServerSeed,
11432        workspace_folders: Arc<Mutex<BTreeSet<Uri>>>,
11433        cx: &mut Context<Self>,
11434    ) {
11435        let Some(local) = self.as_local_mut() else {
11436            return;
11437        };
11438        // If the language server for this key doesn't match the server id, don't store the
11439        // server. Which will cause it to be dropped, killing the process
11440        if local
11441            .language_server_ids
11442            .get(&key)
11443            .map(|state| state.id != server_id)
11444            .unwrap_or(false)
11445        {
11446            return;
11447        }
11448
11449        // Update language_servers collection with Running variant of LanguageServerState
11450        // indicating that the server is up and running and ready
11451        let workspace_folders = workspace_folders.lock().clone();
11452        language_server.set_workspace_folders(workspace_folders);
11453
11454        let workspace_diagnostics_refresh_tasks = language_server
11455            .capabilities()
11456            .diagnostic_provider
11457            .and_then(|provider| {
11458                local
11459                    .language_server_dynamic_registrations
11460                    .entry(server_id)
11461                    .or_default()
11462                    .diagnostics
11463                    .entry(None)
11464                    .or_insert(provider.clone());
11465                let workspace_refresher =
11466                    lsp_workspace_diagnostics_refresh(None, provider, language_server.clone(), cx)?;
11467
11468                Some((None, workspace_refresher))
11469            })
11470            .into_iter()
11471            .collect();
11472        local.language_servers.insert(
11473            server_id,
11474            LanguageServerState::Running {
11475                workspace_diagnostics_refresh_tasks,
11476                adapter: adapter.clone(),
11477                server: language_server.clone(),
11478                simulate_disk_based_diagnostics_completion: None,
11479            },
11480        );
11481        local
11482            .languages
11483            .update_lsp_binary_status(adapter.name(), BinaryStatus::None);
11484        if let Some(file_ops_caps) = language_server
11485            .capabilities()
11486            .workspace
11487            .as_ref()
11488            .and_then(|ws| ws.file_operations.as_ref())
11489        {
11490            let did_rename_caps = file_ops_caps.did_rename.as_ref();
11491            let will_rename_caps = file_ops_caps.will_rename.as_ref();
11492            if did_rename_caps.or(will_rename_caps).is_some() {
11493                let watcher = RenamePathsWatchedForServer::default()
11494                    .with_did_rename_patterns(did_rename_caps)
11495                    .with_will_rename_patterns(will_rename_caps);
11496                local
11497                    .language_server_paths_watched_for_rename
11498                    .insert(server_id, watcher);
11499            }
11500        }
11501
11502        self.language_server_statuses.insert(
11503            server_id,
11504            LanguageServerStatus {
11505                name: language_server.name(),
11506                server_version: language_server.version(),
11507                pending_work: Default::default(),
11508                has_pending_diagnostic_updates: false,
11509                progress_tokens: Default::default(),
11510                worktree: Some(key.worktree_id),
11511                binary: Some(language_server.binary().clone()),
11512                configuration: Some(language_server.configuration().clone()),
11513                workspace_folders: language_server.workspace_folders(),
11514            },
11515        );
11516
11517        cx.emit(LspStoreEvent::LanguageServerAdded(
11518            server_id,
11519            language_server.name(),
11520            Some(key.worktree_id),
11521        ));
11522
11523        let server_capabilities = language_server.capabilities();
11524        if let Some((downstream_client, project_id)) = self.downstream_client.as_ref() {
11525            downstream_client
11526                .send(proto::StartLanguageServer {
11527                    project_id: *project_id,
11528                    server: Some(proto::LanguageServer {
11529                        id: server_id.to_proto(),
11530                        name: language_server.name().to_string(),
11531                        worktree_id: Some(key.worktree_id.to_proto()),
11532                    }),
11533                    capabilities: serde_json::to_string(&server_capabilities)
11534                        .expect("serializing server LSP capabilities"),
11535                })
11536                .log_err();
11537        }
11538        self.lsp_server_capabilities
11539            .insert(server_id, server_capabilities);
11540
11541        // Tell the language server about every open buffer in the worktree that matches the language.
11542        // Also check for buffers in worktrees that reused this server
11543        let mut worktrees_using_server = vec![key.worktree_id];
11544        if let Some(local) = self.as_local() {
11545            // Find all worktrees that have this server in their language server tree
11546            for (worktree_id, servers) in &local.lsp_tree.instances {
11547                if *worktree_id != key.worktree_id {
11548                    for server_map in servers.roots.values() {
11549                        if server_map
11550                            .values()
11551                            .any(|(node, _)| node.id() == Some(server_id))
11552                        {
11553                            worktrees_using_server.push(*worktree_id);
11554                        }
11555                    }
11556                }
11557            }
11558        }
11559
11560        let mut buffer_paths_registered = Vec::new();
11561        self.buffer_store.clone().update(cx, |buffer_store, cx| {
11562            let mut lsp_adapters = HashMap::default();
11563            for buffer_handle in buffer_store.buffers() {
11564                let buffer = buffer_handle.read(cx);
11565                let file = match File::from_dyn(buffer.file()) {
11566                    Some(file) => file,
11567                    None => continue,
11568                };
11569                let language = match buffer.language() {
11570                    Some(language) => language,
11571                    None => continue,
11572                };
11573
11574                if !worktrees_using_server.contains(&file.worktree.read(cx).id())
11575                    || !lsp_adapters
11576                        .entry(language.name())
11577                        .or_insert_with(|| self.languages.lsp_adapters(&language.name()))
11578                        .iter()
11579                        .any(|a| a.name == key.name)
11580                {
11581                    continue;
11582                }
11583                // didOpen
11584                let file = match file.as_local() {
11585                    Some(file) => file,
11586                    None => continue,
11587                };
11588
11589                let local = self.as_local_mut().unwrap();
11590
11591                let buffer_id = buffer.remote_id();
11592                if local.registered_buffers.contains_key(&buffer_id) {
11593                    let versions = local
11594                        .buffer_snapshots
11595                        .entry(buffer_id)
11596                        .or_default()
11597                        .entry(server_id)
11598                        .and_modify(|_| {
11599                            assert!(
11600                            false,
11601                            "There should not be an existing snapshot for a newly inserted buffer"
11602                        )
11603                        })
11604                        .or_insert_with(|| {
11605                            vec![LspBufferSnapshot {
11606                                version: 0,
11607                                snapshot: buffer.text_snapshot(),
11608                            }]
11609                        });
11610
11611                    let snapshot = versions.last().unwrap();
11612                    let version = snapshot.version;
11613                    let initial_snapshot = &snapshot.snapshot;
11614                    let uri = lsp::Uri::from_file_path(file.abs_path(cx)).unwrap();
11615                    language_server.register_buffer(
11616                        uri,
11617                        adapter.language_id(&language.name()),
11618                        version,
11619                        initial_snapshot.text(),
11620                    );
11621                    buffer_paths_registered.push((buffer_id, file.abs_path(cx)));
11622                    local
11623                        .buffers_opened_in_servers
11624                        .entry(buffer_id)
11625                        .or_default()
11626                        .insert(server_id);
11627                }
11628                buffer_handle.update(cx, |buffer, cx| {
11629                    buffer.set_completion_triggers(
11630                        server_id,
11631                        language_server
11632                            .capabilities()
11633                            .completion_provider
11634                            .as_ref()
11635                            .and_then(|provider| {
11636                                provider
11637                                    .trigger_characters
11638                                    .as_ref()
11639                                    .map(|characters| characters.iter().cloned().collect())
11640                            })
11641                            .unwrap_or_default(),
11642                        cx,
11643                    )
11644                });
11645            }
11646        });
11647
11648        for (buffer_id, abs_path) in buffer_paths_registered {
11649            cx.emit(LspStoreEvent::LanguageServerUpdate {
11650                language_server_id: server_id,
11651                name: Some(adapter.name()),
11652                message: proto::update_language_server::Variant::RegisteredForBuffer(
11653                    proto::RegisteredForBuffer {
11654                        buffer_abs_path: abs_path.to_string_lossy().into_owned(),
11655                        buffer_id: buffer_id.to_proto(),
11656                    },
11657                ),
11658            });
11659        }
11660
11661        cx.notify();
11662    }
11663
11664    pub fn language_servers_running_disk_based_diagnostics(
11665        &self,
11666    ) -> impl Iterator<Item = LanguageServerId> + '_ {
11667        self.language_server_statuses
11668            .iter()
11669            .filter_map(|(id, status)| {
11670                if status.has_pending_diagnostic_updates {
11671                    Some(*id)
11672                } else {
11673                    None
11674                }
11675            })
11676    }
11677
11678    pub(crate) fn cancel_language_server_work_for_buffers(
11679        &mut self,
11680        buffers: impl IntoIterator<Item = Entity<Buffer>>,
11681        cx: &mut Context<Self>,
11682    ) {
11683        if let Some((client, project_id)) = self.upstream_client() {
11684            let request = client.request(proto::CancelLanguageServerWork {
11685                project_id,
11686                work: Some(proto::cancel_language_server_work::Work::Buffers(
11687                    proto::cancel_language_server_work::Buffers {
11688                        buffer_ids: buffers
11689                            .into_iter()
11690                            .map(|b| b.read(cx).remote_id().to_proto())
11691                            .collect(),
11692                    },
11693                )),
11694            });
11695            cx.background_spawn(request).detach_and_log_err(cx);
11696        } else if let Some(local) = self.as_local() {
11697            let servers = buffers
11698                .into_iter()
11699                .flat_map(|buffer| {
11700                    buffer.update(cx, |buffer, cx| {
11701                        local.language_server_ids_for_buffer(buffer, cx).into_iter()
11702                    })
11703                })
11704                .collect::<HashSet<_>>();
11705            for server_id in servers {
11706                self.cancel_language_server_work(server_id, None, cx);
11707            }
11708        }
11709    }
11710
11711    pub(crate) fn cancel_language_server_work(
11712        &mut self,
11713        server_id: LanguageServerId,
11714        token_to_cancel: Option<ProgressToken>,
11715        cx: &mut Context<Self>,
11716    ) {
11717        if let Some(local) = self.as_local() {
11718            let status = self.language_server_statuses.get(&server_id);
11719            let server = local.language_servers.get(&server_id);
11720            if let Some((LanguageServerState::Running { server, .. }, status)) = server.zip(status)
11721            {
11722                for (token, progress) in &status.pending_work {
11723                    if let Some(token_to_cancel) = token_to_cancel.as_ref()
11724                        && token != token_to_cancel
11725                    {
11726                        continue;
11727                    }
11728                    if progress.is_cancellable {
11729                        server
11730                            .notify::<lsp::notification::WorkDoneProgressCancel>(
11731                                WorkDoneProgressCancelParams {
11732                                    token: token.to_lsp(),
11733                                },
11734                            )
11735                            .ok();
11736                    }
11737                }
11738            }
11739        } else if let Some((client, project_id)) = self.upstream_client() {
11740            let request = client.request(proto::CancelLanguageServerWork {
11741                project_id,
11742                work: Some(
11743                    proto::cancel_language_server_work::Work::LanguageServerWork(
11744                        proto::cancel_language_server_work::LanguageServerWork {
11745                            language_server_id: server_id.to_proto(),
11746                            token: token_to_cancel.map(|token| token.to_proto()),
11747                        },
11748                    ),
11749                ),
11750            });
11751            cx.background_spawn(request).detach_and_log_err(cx);
11752        }
11753    }
11754
11755    fn register_supplementary_language_server(
11756        &mut self,
11757        id: LanguageServerId,
11758        name: LanguageServerName,
11759        server: Arc<LanguageServer>,
11760        cx: &mut Context<Self>,
11761    ) {
11762        if let Some(local) = self.as_local_mut() {
11763            local
11764                .supplementary_language_servers
11765                .insert(id, (name.clone(), server));
11766            cx.emit(LspStoreEvent::LanguageServerAdded(id, name, None));
11767        }
11768    }
11769
11770    fn unregister_supplementary_language_server(
11771        &mut self,
11772        id: LanguageServerId,
11773        cx: &mut Context<Self>,
11774    ) {
11775        if let Some(local) = self.as_local_mut() {
11776            local.supplementary_language_servers.remove(&id);
11777            cx.emit(LspStoreEvent::LanguageServerRemoved(id));
11778        }
11779    }
11780
11781    pub(crate) fn supplementary_language_servers(
11782        &self,
11783    ) -> impl '_ + Iterator<Item = (LanguageServerId, LanguageServerName)> {
11784        self.as_local().into_iter().flat_map(|local| {
11785            local
11786                .supplementary_language_servers
11787                .iter()
11788                .map(|(id, (name, _))| (*id, name.clone()))
11789        })
11790    }
11791
11792    pub fn language_server_adapter_for_id(
11793        &self,
11794        id: LanguageServerId,
11795    ) -> Option<Arc<CachedLspAdapter>> {
11796        self.as_local()
11797            .and_then(|local| local.language_servers.get(&id))
11798            .and_then(|language_server_state| match language_server_state {
11799                LanguageServerState::Running { adapter, .. } => Some(adapter.clone()),
11800                _ => None,
11801            })
11802    }
11803
11804    pub(super) fn update_local_worktree_language_servers(
11805        &mut self,
11806        worktree_handle: &Entity<Worktree>,
11807        changes: &[(Arc<RelPath>, ProjectEntryId, PathChange)],
11808        cx: &mut Context<Self>,
11809    ) {
11810        if changes.is_empty() {
11811            return;
11812        }
11813
11814        let Some(local) = self.as_local() else { return };
11815
11816        local.prettier_store.update(cx, |prettier_store, cx| {
11817            prettier_store.update_prettier_settings(worktree_handle, changes, cx)
11818        });
11819
11820        let worktree_id = worktree_handle.read(cx).id();
11821        let mut language_server_ids = local
11822            .language_server_ids
11823            .iter()
11824            .filter_map(|(seed, v)| seed.worktree_id.eq(&worktree_id).then(|| v.id))
11825            .collect::<Vec<_>>();
11826        language_server_ids.sort();
11827        language_server_ids.dedup();
11828
11829        // let abs_path = worktree_handle.read(cx).abs_path();
11830        for server_id in &language_server_ids {
11831            if let Some(LanguageServerState::Running { server, .. }) =
11832                local.language_servers.get(server_id)
11833                && let Some(watched_paths) = local
11834                    .language_server_watched_paths
11835                    .get(server_id)
11836                    .and_then(|paths| paths.worktree_paths.get(&worktree_id))
11837            {
11838                let params = lsp::DidChangeWatchedFilesParams {
11839                    changes: changes
11840                        .iter()
11841                        .filter_map(|(path, _, change)| {
11842                            if !watched_paths.is_match(path.as_std_path()) {
11843                                return None;
11844                            }
11845                            let typ = match change {
11846                                PathChange::Loaded => return None,
11847                                PathChange::Added => lsp::FileChangeType::CREATED,
11848                                PathChange::Removed => lsp::FileChangeType::DELETED,
11849                                PathChange::Updated => lsp::FileChangeType::CHANGED,
11850                                PathChange::AddedOrUpdated => lsp::FileChangeType::CHANGED,
11851                            };
11852                            let uri = lsp::Uri::from_file_path(
11853                                worktree_handle.read(cx).absolutize(&path),
11854                            )
11855                            .ok()?;
11856                            Some(lsp::FileEvent { uri, typ })
11857                        })
11858                        .collect(),
11859                };
11860                if !params.changes.is_empty() {
11861                    server
11862                        .notify::<lsp::notification::DidChangeWatchedFiles>(params)
11863                        .ok();
11864                }
11865            }
11866        }
11867        for (path, _, _) in changes {
11868            if let Some(file_name) = path.file_name()
11869                && local.watched_manifest_filenames.contains(file_name)
11870            {
11871                self.request_workspace_config_refresh();
11872                break;
11873            }
11874        }
11875    }
11876
11877    pub fn wait_for_remote_buffer(
11878        &mut self,
11879        id: BufferId,
11880        cx: &mut Context<Self>,
11881    ) -> Task<Result<Entity<Buffer>>> {
11882        self.buffer_store.update(cx, |buffer_store, cx| {
11883            buffer_store.wait_for_remote_buffer(id, cx)
11884        })
11885    }
11886
11887    fn serialize_symbol(symbol: &Symbol) -> proto::Symbol {
11888        let mut result = proto::Symbol {
11889            language_server_name: symbol.language_server_name.0.to_string(),
11890            source_worktree_id: symbol.source_worktree_id.to_proto(),
11891            language_server_id: symbol.source_language_server_id.to_proto(),
11892            name: symbol.name.clone(),
11893            kind: unsafe { mem::transmute::<lsp::SymbolKind, i32>(symbol.kind) },
11894            start: Some(proto::PointUtf16 {
11895                row: symbol.range.start.0.row,
11896                column: symbol.range.start.0.column,
11897            }),
11898            end: Some(proto::PointUtf16 {
11899                row: symbol.range.end.0.row,
11900                column: symbol.range.end.0.column,
11901            }),
11902            worktree_id: Default::default(),
11903            path: Default::default(),
11904            signature: Default::default(),
11905        };
11906        match &symbol.path {
11907            SymbolLocation::InProject(path) => {
11908                result.worktree_id = path.worktree_id.to_proto();
11909                result.path = path.path.to_proto();
11910            }
11911            SymbolLocation::OutsideProject {
11912                abs_path,
11913                signature,
11914            } => {
11915                result.path = abs_path.to_string_lossy().into_owned();
11916                result.signature = signature.to_vec();
11917            }
11918        }
11919        result
11920    }
11921
11922    fn deserialize_symbol(serialized_symbol: proto::Symbol) -> Result<CoreSymbol> {
11923        let source_worktree_id = WorktreeId::from_proto(serialized_symbol.source_worktree_id);
11924        let worktree_id = WorktreeId::from_proto(serialized_symbol.worktree_id);
11925        let kind = unsafe { mem::transmute::<i32, lsp::SymbolKind>(serialized_symbol.kind) };
11926
11927        let path = if serialized_symbol.signature.is_empty() {
11928            SymbolLocation::InProject(ProjectPath {
11929                worktree_id,
11930                path: RelPath::from_proto(&serialized_symbol.path)
11931                    .context("invalid symbol path")?,
11932            })
11933        } else {
11934            SymbolLocation::OutsideProject {
11935                abs_path: Path::new(&serialized_symbol.path).into(),
11936                signature: serialized_symbol
11937                    .signature
11938                    .try_into()
11939                    .map_err(|_| anyhow!("invalid signature"))?,
11940            }
11941        };
11942
11943        let start = serialized_symbol.start.context("invalid start")?;
11944        let end = serialized_symbol.end.context("invalid end")?;
11945        Ok(CoreSymbol {
11946            language_server_name: LanguageServerName(serialized_symbol.language_server_name.into()),
11947            source_worktree_id,
11948            source_language_server_id: LanguageServerId::from_proto(
11949                serialized_symbol.language_server_id,
11950            ),
11951            path,
11952            name: serialized_symbol.name,
11953            range: Unclipped(PointUtf16::new(start.row, start.column))
11954                ..Unclipped(PointUtf16::new(end.row, end.column)),
11955            kind,
11956        })
11957    }
11958
11959    pub(crate) fn serialize_completion(completion: &CoreCompletion) -> proto::Completion {
11960        let mut serialized_completion = proto::Completion {
11961            old_replace_start: Some(serialize_anchor(&completion.replace_range.start)),
11962            old_replace_end: Some(serialize_anchor(&completion.replace_range.end)),
11963            new_text: completion.new_text.clone(),
11964            ..proto::Completion::default()
11965        };
11966        match &completion.source {
11967            CompletionSource::Lsp {
11968                insert_range,
11969                server_id,
11970                lsp_completion,
11971                lsp_defaults,
11972                resolved,
11973            } => {
11974                let (old_insert_start, old_insert_end) = insert_range
11975                    .as_ref()
11976                    .map(|range| (serialize_anchor(&range.start), serialize_anchor(&range.end)))
11977                    .unzip();
11978
11979                serialized_completion.old_insert_start = old_insert_start;
11980                serialized_completion.old_insert_end = old_insert_end;
11981                serialized_completion.source = proto::completion::Source::Lsp as i32;
11982                serialized_completion.server_id = server_id.0 as u64;
11983                serialized_completion.lsp_completion = serde_json::to_vec(lsp_completion).unwrap();
11984                serialized_completion.lsp_defaults = lsp_defaults
11985                    .as_deref()
11986                    .map(|lsp_defaults| serde_json::to_vec(lsp_defaults).unwrap());
11987                serialized_completion.resolved = *resolved;
11988            }
11989            CompletionSource::BufferWord {
11990                word_range,
11991                resolved,
11992            } => {
11993                serialized_completion.source = proto::completion::Source::BufferWord as i32;
11994                serialized_completion.buffer_word_start = Some(serialize_anchor(&word_range.start));
11995                serialized_completion.buffer_word_end = Some(serialize_anchor(&word_range.end));
11996                serialized_completion.resolved = *resolved;
11997            }
11998            CompletionSource::Custom => {
11999                serialized_completion.source = proto::completion::Source::Custom as i32;
12000                serialized_completion.resolved = true;
12001            }
12002            CompletionSource::Dap { sort_text } => {
12003                serialized_completion.source = proto::completion::Source::Dap as i32;
12004                serialized_completion.sort_text = Some(sort_text.clone());
12005            }
12006        }
12007
12008        serialized_completion
12009    }
12010
12011    pub(crate) fn deserialize_completion(completion: proto::Completion) -> Result<CoreCompletion> {
12012        let old_replace_start = completion
12013            .old_replace_start
12014            .and_then(deserialize_anchor)
12015            .context("invalid old start")?;
12016        let old_replace_end = completion
12017            .old_replace_end
12018            .and_then(deserialize_anchor)
12019            .context("invalid old end")?;
12020        let insert_range = {
12021            match completion.old_insert_start.zip(completion.old_insert_end) {
12022                Some((start, end)) => {
12023                    let start = deserialize_anchor(start).context("invalid insert old start")?;
12024                    let end = deserialize_anchor(end).context("invalid insert old end")?;
12025                    Some(start..end)
12026                }
12027                None => None,
12028            }
12029        };
12030        Ok(CoreCompletion {
12031            replace_range: old_replace_start..old_replace_end,
12032            new_text: completion.new_text,
12033            source: match proto::completion::Source::from_i32(completion.source) {
12034                Some(proto::completion::Source::Custom) => CompletionSource::Custom,
12035                Some(proto::completion::Source::Lsp) => CompletionSource::Lsp {
12036                    insert_range,
12037                    server_id: LanguageServerId::from_proto(completion.server_id),
12038                    lsp_completion: serde_json::from_slice(&completion.lsp_completion)?,
12039                    lsp_defaults: completion
12040                        .lsp_defaults
12041                        .as_deref()
12042                        .map(serde_json::from_slice)
12043                        .transpose()?,
12044                    resolved: completion.resolved,
12045                },
12046                Some(proto::completion::Source::BufferWord) => {
12047                    let word_range = completion
12048                        .buffer_word_start
12049                        .and_then(deserialize_anchor)
12050                        .context("invalid buffer word start")?
12051                        ..completion
12052                            .buffer_word_end
12053                            .and_then(deserialize_anchor)
12054                            .context("invalid buffer word end")?;
12055                    CompletionSource::BufferWord {
12056                        word_range,
12057                        resolved: completion.resolved,
12058                    }
12059                }
12060                Some(proto::completion::Source::Dap) => CompletionSource::Dap {
12061                    sort_text: completion
12062                        .sort_text
12063                        .context("expected sort text to exist")?,
12064                },
12065                _ => anyhow::bail!("Unexpected completion source {}", completion.source),
12066            },
12067        })
12068    }
12069
12070    pub(crate) fn serialize_code_action(action: &CodeAction) -> proto::CodeAction {
12071        let (kind, lsp_action) = match &action.lsp_action {
12072            LspAction::Action(code_action) => (
12073                proto::code_action::Kind::Action as i32,
12074                serde_json::to_vec(code_action).unwrap(),
12075            ),
12076            LspAction::Command(command) => (
12077                proto::code_action::Kind::Command as i32,
12078                serde_json::to_vec(command).unwrap(),
12079            ),
12080            LspAction::CodeLens(code_lens) => (
12081                proto::code_action::Kind::CodeLens as i32,
12082                serde_json::to_vec(code_lens).unwrap(),
12083            ),
12084        };
12085
12086        proto::CodeAction {
12087            server_id: action.server_id.0 as u64,
12088            start: Some(serialize_anchor(&action.range.start)),
12089            end: Some(serialize_anchor(&action.range.end)),
12090            lsp_action,
12091            kind,
12092            resolved: action.resolved,
12093        }
12094    }
12095
12096    pub(crate) fn deserialize_code_action(action: proto::CodeAction) -> Result<CodeAction> {
12097        let start = action
12098            .start
12099            .and_then(deserialize_anchor)
12100            .context("invalid start")?;
12101        let end = action
12102            .end
12103            .and_then(deserialize_anchor)
12104            .context("invalid end")?;
12105        let lsp_action = match proto::code_action::Kind::from_i32(action.kind) {
12106            Some(proto::code_action::Kind::Action) => {
12107                LspAction::Action(serde_json::from_slice(&action.lsp_action)?)
12108            }
12109            Some(proto::code_action::Kind::Command) => {
12110                LspAction::Command(serde_json::from_slice(&action.lsp_action)?)
12111            }
12112            Some(proto::code_action::Kind::CodeLens) => {
12113                LspAction::CodeLens(serde_json::from_slice(&action.lsp_action)?)
12114            }
12115            None => anyhow::bail!("Unknown action kind {}", action.kind),
12116        };
12117        Ok(CodeAction {
12118            server_id: LanguageServerId(action.server_id as usize),
12119            range: start..end,
12120            resolved: action.resolved,
12121            lsp_action,
12122        })
12123    }
12124
12125    fn update_last_formatting_failure<T>(&mut self, formatting_result: &anyhow::Result<T>) {
12126        match &formatting_result {
12127            Ok(_) => self.last_formatting_failure = None,
12128            Err(error) => {
12129                let error_string = format!("{error:#}");
12130                log::error!("Formatting failed: {error_string}");
12131                self.last_formatting_failure
12132                    .replace(error_string.lines().join(" "));
12133            }
12134        }
12135    }
12136
12137    fn cleanup_lsp_data(&mut self, for_server: LanguageServerId) {
12138        self.lsp_server_capabilities.remove(&for_server);
12139        for lsp_data in self.lsp_data.values_mut() {
12140            lsp_data.remove_server_data(for_server);
12141        }
12142        if let Some(local) = self.as_local_mut() {
12143            local.buffer_pull_diagnostics_result_ids.remove(&for_server);
12144            local
12145                .workspace_pull_diagnostics_result_ids
12146                .remove(&for_server);
12147            for buffer_servers in local.buffers_opened_in_servers.values_mut() {
12148                buffer_servers.remove(&for_server);
12149            }
12150        }
12151    }
12152
12153    pub fn result_id_for_buffer_pull(
12154        &self,
12155        server_id: LanguageServerId,
12156        buffer_id: BufferId,
12157        registration_id: &Option<SharedString>,
12158        cx: &App,
12159    ) -> Option<SharedString> {
12160        let abs_path = self
12161            .buffer_store
12162            .read(cx)
12163            .get(buffer_id)
12164            .and_then(|b| File::from_dyn(b.read(cx).file()))
12165            .map(|f| f.abs_path(cx))?;
12166        self.as_local()?
12167            .buffer_pull_diagnostics_result_ids
12168            .get(&server_id)?
12169            .get(registration_id)?
12170            .get(&abs_path)?
12171            .clone()
12172    }
12173
12174    /// Gets all result_ids for a workspace diagnostics pull request.
12175    /// 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.
12176    /// The latter is supposed to be of lower priority as we keep on pulling diagnostics for open buffers eagerly.
12177    pub fn result_ids_for_workspace_refresh(
12178        &self,
12179        server_id: LanguageServerId,
12180        registration_id: &Option<SharedString>,
12181    ) -> HashMap<PathBuf, SharedString> {
12182        let Some(local) = self.as_local() else {
12183            return HashMap::default();
12184        };
12185        local
12186            .workspace_pull_diagnostics_result_ids
12187            .get(&server_id)
12188            .into_iter()
12189            .filter_map(|diagnostics| diagnostics.get(registration_id))
12190            .flatten()
12191            .filter_map(|(abs_path, result_id)| {
12192                let result_id = local
12193                    .buffer_pull_diagnostics_result_ids
12194                    .get(&server_id)
12195                    .and_then(|buffer_ids_result_ids| {
12196                        buffer_ids_result_ids.get(registration_id)?.get(abs_path)
12197                    })
12198                    .cloned()
12199                    .flatten()
12200                    .or_else(|| result_id.clone())?;
12201                Some((abs_path.clone(), result_id))
12202            })
12203            .collect()
12204    }
12205
12206    pub fn pull_workspace_diagnostics(&mut self, server_id: LanguageServerId) {
12207        if let Some(LanguageServerState::Running {
12208            workspace_diagnostics_refresh_tasks,
12209            ..
12210        }) = self
12211            .as_local_mut()
12212            .and_then(|local| local.language_servers.get_mut(&server_id))
12213        {
12214            for diagnostics in workspace_diagnostics_refresh_tasks.values_mut() {
12215                diagnostics.refresh_tx.try_send(()).ok();
12216            }
12217        }
12218    }
12219
12220    /// Refreshes `textDocument/diagnostic` for all open buffers associated with the given server.
12221    /// This is called in response to `workspace/diagnostic/refresh` to comply with the LSP spec,
12222    /// which requires refreshing both workspace and document diagnostics.
12223    pub fn pull_document_diagnostics_for_server(
12224        &mut self,
12225        server_id: LanguageServerId,
12226        cx: &mut Context<Self>,
12227    ) -> Task<()> {
12228        let buffers_to_pull = self
12229            .as_local()
12230            .into_iter()
12231            .flat_map(|local| {
12232                self.buffer_store.read(cx).buffers().filter(|buffer| {
12233                    let buffer_id = buffer.read(cx).remote_id();
12234                    local
12235                        .buffers_opened_in_servers
12236                        .get(&buffer_id)
12237                        .is_some_and(|servers| servers.contains(&server_id))
12238                })
12239            })
12240            .collect::<Vec<_>>();
12241
12242        let pulls = join_all(buffers_to_pull.into_iter().map(|buffer| {
12243            let buffer_path = buffer.read(cx).file().map(|f| f.full_path(cx));
12244            let pull_task = self.pull_diagnostics_for_buffer(buffer, cx);
12245            async move { (buffer_path, pull_task.await) }
12246        }));
12247        cx.background_spawn(async move {
12248            for (pull_task_path, pull_task_result) in pulls.await {
12249                if let Err(e) = pull_task_result {
12250                    match pull_task_path {
12251                        Some(path) => {
12252                            log::error!("Failed to pull diagnostics for buffer {path:?}: {e:#}");
12253                        }
12254                        None => log::error!("Failed to pull diagnostics: {e:#}"),
12255                    }
12256                }
12257            }
12258        })
12259    }
12260
12261    fn apply_workspace_diagnostic_report(
12262        &mut self,
12263        server_id: LanguageServerId,
12264        report: lsp::WorkspaceDiagnosticReportResult,
12265        registration_id: Option<SharedString>,
12266        cx: &mut Context<Self>,
12267    ) {
12268        let mut workspace_diagnostics =
12269            GetDocumentDiagnostics::deserialize_workspace_diagnostics_report(
12270                report,
12271                server_id,
12272                registration_id,
12273            );
12274        workspace_diagnostics.retain(|d| match &d.diagnostics {
12275            LspPullDiagnostics::Response {
12276                server_id,
12277                registration_id,
12278                ..
12279            } => self.diagnostic_registration_exists(*server_id, registration_id),
12280            LspPullDiagnostics::Default => false,
12281        });
12282        let mut unchanged_buffers = HashMap::default();
12283        let workspace_diagnostics_updates = workspace_diagnostics
12284            .into_iter()
12285            .filter_map(
12286                |workspace_diagnostics| match workspace_diagnostics.diagnostics {
12287                    LspPullDiagnostics::Response {
12288                        server_id,
12289                        uri,
12290                        diagnostics,
12291                        registration_id,
12292                    } => Some((
12293                        server_id,
12294                        uri,
12295                        diagnostics,
12296                        workspace_diagnostics.version,
12297                        registration_id,
12298                    )),
12299                    LspPullDiagnostics::Default => None,
12300                },
12301            )
12302            .fold(
12303                HashMap::default(),
12304                |mut acc, (server_id, uri, diagnostics, version, new_registration_id)| {
12305                    let (result_id, diagnostics) = match diagnostics {
12306                        PulledDiagnostics::Unchanged { result_id } => {
12307                            unchanged_buffers
12308                                .entry(new_registration_id.clone())
12309                                .or_insert_with(HashSet::default)
12310                                .insert(uri.clone());
12311                            (Some(result_id), Vec::new())
12312                        }
12313                        PulledDiagnostics::Changed {
12314                            result_id,
12315                            diagnostics,
12316                        } => (result_id, diagnostics),
12317                    };
12318                    let disk_based_sources = Cow::Owned(
12319                        self.language_server_adapter_for_id(server_id)
12320                            .as_ref()
12321                            .map(|adapter| adapter.disk_based_diagnostic_sources.as_slice())
12322                            .unwrap_or(&[])
12323                            .to_vec(),
12324                    );
12325
12326                    let Some(abs_path) = uri.to_file_path().ok() else {
12327                        return acc;
12328                    };
12329                    let Some((worktree, relative_path)) =
12330                        self.worktree_store.read(cx).find_worktree(abs_path.clone(), cx)
12331                    else {
12332                        log::warn!("skipping workspace diagnostics update, no worktree found for path {abs_path:?}");
12333                        return acc;
12334                    };
12335                    let worktree_id = worktree.read(cx).id();
12336                    let project_path = ProjectPath {
12337                        worktree_id,
12338                        path: relative_path,
12339                    };
12340                    if let Some(local_lsp_store) = self.as_local_mut() {
12341                        local_lsp_store.workspace_pull_diagnostics_result_ids.entry(server_id)
12342                            .or_default().entry(new_registration_id.clone()).or_default().insert(abs_path, result_id.clone());
12343                    }
12344                    // The LSP spec recommends that "diagnostics from a document pull should win over diagnostics from a workspace pull."
12345                    // Since we actively pull diagnostics for documents with open buffers, we ignore contents of workspace pulls for these documents.
12346                    if self.buffer_store.read(cx).get_by_path(&project_path).is_none() {
12347                        acc.entry(server_id)
12348                            .or_insert_with(HashMap::default)
12349                            .entry(new_registration_id.clone())
12350                            .or_insert_with(Vec::new)
12351                            .push(DocumentDiagnosticsUpdate {
12352                                server_id,
12353                                diagnostics: lsp::PublishDiagnosticsParams {
12354                                    uri,
12355                                    diagnostics,
12356                                    version,
12357                                },
12358                                result_id,
12359                                disk_based_sources,
12360                                registration_id: new_registration_id,
12361                            });
12362                    }
12363                    acc
12364                },
12365            );
12366
12367        for diagnostic_updates in workspace_diagnostics_updates.into_values() {
12368            for (registration_id, diagnostic_updates) in diagnostic_updates {
12369                self.merge_lsp_diagnostics(
12370                    DiagnosticSourceKind::Pulled,
12371                    diagnostic_updates,
12372                    |document_uri, old_diagnostic, _| match old_diagnostic.source_kind {
12373                        DiagnosticSourceKind::Pulled => {
12374                            old_diagnostic.registration_id != registration_id
12375                                || unchanged_buffers
12376                                    .get(&old_diagnostic.registration_id)
12377                                    .is_some_and(|unchanged_buffers| {
12378                                        unchanged_buffers.contains(&document_uri)
12379                                    })
12380                        }
12381                        DiagnosticSourceKind::Other | DiagnosticSourceKind::Pushed => true,
12382                    },
12383                    cx,
12384                )
12385                .log_err();
12386            }
12387        }
12388    }
12389
12390    fn register_server_capabilities(
12391        &mut self,
12392        server_id: LanguageServerId,
12393        params: lsp::RegistrationParams,
12394        cx: &mut Context<Self>,
12395    ) -> anyhow::Result<()> {
12396        let server = self
12397            .language_server_for_id(server_id)
12398            .with_context(|| format!("no server {server_id} found"))?;
12399        for reg in params.registrations {
12400            match reg.method.as_str() {
12401                "workspace/didChangeWatchedFiles" => {
12402                    if let Some(options) = reg.register_options {
12403                        let notify = if let Some(local_lsp_store) = self.as_local_mut() {
12404                            let caps = serde_json::from_value(options)?;
12405                            local_lsp_store
12406                                .on_lsp_did_change_watched_files(server_id, &reg.id, caps, cx);
12407                            true
12408                        } else {
12409                            false
12410                        };
12411                        if notify {
12412                            notify_server_capabilities_updated(&server, cx);
12413                        }
12414                    }
12415                }
12416                "workspace/didChangeConfiguration" => {
12417                    // Ignore payload since we notify clients of setting changes unconditionally, relying on them pulling the latest settings.
12418                }
12419                "workspace/didChangeWorkspaceFolders" => {
12420                    // In this case register options is an empty object, we can ignore it
12421                    let caps = lsp::WorkspaceFoldersServerCapabilities {
12422                        supported: Some(true),
12423                        change_notifications: Some(OneOf::Right(reg.id)),
12424                    };
12425                    server.update_capabilities(|capabilities| {
12426                        capabilities
12427                            .workspace
12428                            .get_or_insert_default()
12429                            .workspace_folders = Some(caps);
12430                    });
12431                    notify_server_capabilities_updated(&server, cx);
12432                }
12433                "workspace/symbol" => {
12434                    let options = parse_register_capabilities(reg)?;
12435                    server.update_capabilities(|capabilities| {
12436                        capabilities.workspace_symbol_provider = Some(options);
12437                    });
12438                    notify_server_capabilities_updated(&server, cx);
12439                }
12440                "workspace/fileOperations" => {
12441                    if let Some(options) = reg.register_options {
12442                        let caps = serde_json::from_value(options)?;
12443                        server.update_capabilities(|capabilities| {
12444                            capabilities
12445                                .workspace
12446                                .get_or_insert_default()
12447                                .file_operations = Some(caps);
12448                        });
12449                        notify_server_capabilities_updated(&server, cx);
12450                    }
12451                }
12452                "workspace/executeCommand" => {
12453                    if let Some(options) = reg.register_options {
12454                        let options = serde_json::from_value(options)?;
12455                        server.update_capabilities(|capabilities| {
12456                            capabilities.execute_command_provider = Some(options);
12457                        });
12458                        notify_server_capabilities_updated(&server, cx);
12459                    }
12460                }
12461                "textDocument/rangeFormatting" => {
12462                    let options = parse_register_capabilities(reg)?;
12463                    server.update_capabilities(|capabilities| {
12464                        capabilities.document_range_formatting_provider = Some(options);
12465                    });
12466                    notify_server_capabilities_updated(&server, cx);
12467                }
12468                "textDocument/onTypeFormatting" => {
12469                    if let Some(options) = reg
12470                        .register_options
12471                        .map(serde_json::from_value)
12472                        .transpose()?
12473                    {
12474                        server.update_capabilities(|capabilities| {
12475                            capabilities.document_on_type_formatting_provider = Some(options);
12476                        });
12477                        notify_server_capabilities_updated(&server, cx);
12478                    }
12479                }
12480                "textDocument/formatting" => {
12481                    let options = parse_register_capabilities(reg)?;
12482                    server.update_capabilities(|capabilities| {
12483                        capabilities.document_formatting_provider = Some(options);
12484                    });
12485                    notify_server_capabilities_updated(&server, cx);
12486                }
12487                "textDocument/rename" => {
12488                    let options = parse_register_capabilities(reg)?;
12489                    server.update_capabilities(|capabilities| {
12490                        capabilities.rename_provider = Some(options);
12491                    });
12492                    notify_server_capabilities_updated(&server, cx);
12493                }
12494                "textDocument/inlayHint" => {
12495                    let options = parse_register_capabilities(reg)?;
12496                    server.update_capabilities(|capabilities| {
12497                        capabilities.inlay_hint_provider = Some(options);
12498                    });
12499                    notify_server_capabilities_updated(&server, cx);
12500                }
12501                "textDocument/documentSymbol" => {
12502                    let options = parse_register_capabilities(reg)?;
12503                    server.update_capabilities(|capabilities| {
12504                        capabilities.document_symbol_provider = Some(options);
12505                    });
12506                    notify_server_capabilities_updated(&server, cx);
12507                }
12508                "textDocument/codeAction" => {
12509                    let options = parse_register_capabilities(reg)?;
12510                    let provider = match options {
12511                        OneOf::Left(value) => lsp::CodeActionProviderCapability::Simple(value),
12512                        OneOf::Right(caps) => caps,
12513                    };
12514                    server.update_capabilities(|capabilities| {
12515                        capabilities.code_action_provider = Some(provider);
12516                    });
12517                    notify_server_capabilities_updated(&server, cx);
12518                }
12519                "textDocument/definition" => {
12520                    let options = parse_register_capabilities(reg)?;
12521                    server.update_capabilities(|capabilities| {
12522                        capabilities.definition_provider = Some(options);
12523                    });
12524                    notify_server_capabilities_updated(&server, cx);
12525                }
12526                "textDocument/completion" => {
12527                    if let Some(caps) = reg
12528                        .register_options
12529                        .map(serde_json::from_value::<CompletionOptions>)
12530                        .transpose()?
12531                    {
12532                        server.update_capabilities(|capabilities| {
12533                            capabilities.completion_provider = Some(caps.clone());
12534                        });
12535
12536                        if let Some(local) = self.as_local() {
12537                            let mut buffers_with_language_server = Vec::new();
12538                            for handle in self.buffer_store.read(cx).buffers() {
12539                                let buffer_id = handle.read(cx).remote_id();
12540                                if local
12541                                    .buffers_opened_in_servers
12542                                    .get(&buffer_id)
12543                                    .filter(|s| s.contains(&server_id))
12544                                    .is_some()
12545                                {
12546                                    buffers_with_language_server.push(handle);
12547                                }
12548                            }
12549                            let triggers = caps
12550                                .trigger_characters
12551                                .unwrap_or_default()
12552                                .into_iter()
12553                                .collect::<BTreeSet<_>>();
12554                            for handle in buffers_with_language_server {
12555                                let triggers = triggers.clone();
12556                                let _ = handle.update(cx, move |buffer, cx| {
12557                                    buffer.set_completion_triggers(server_id, triggers, cx);
12558                                });
12559                            }
12560                        }
12561                        notify_server_capabilities_updated(&server, cx);
12562                    }
12563                }
12564                "textDocument/hover" => {
12565                    let options = parse_register_capabilities(reg)?;
12566                    let provider = match options {
12567                        OneOf::Left(value) => lsp::HoverProviderCapability::Simple(value),
12568                        OneOf::Right(caps) => caps,
12569                    };
12570                    server.update_capabilities(|capabilities| {
12571                        capabilities.hover_provider = Some(provider);
12572                    });
12573                    notify_server_capabilities_updated(&server, cx);
12574                }
12575                "textDocument/signatureHelp" => {
12576                    if let Some(caps) = reg
12577                        .register_options
12578                        .map(serde_json::from_value)
12579                        .transpose()?
12580                    {
12581                        server.update_capabilities(|capabilities| {
12582                            capabilities.signature_help_provider = Some(caps);
12583                        });
12584                        notify_server_capabilities_updated(&server, cx);
12585                    }
12586                }
12587                "textDocument/didChange" => {
12588                    if let Some(sync_kind) = reg
12589                        .register_options
12590                        .and_then(|opts| opts.get("syncKind").cloned())
12591                        .map(serde_json::from_value::<lsp::TextDocumentSyncKind>)
12592                        .transpose()?
12593                    {
12594                        server.update_capabilities(|capabilities| {
12595                            let mut sync_options =
12596                                Self::take_text_document_sync_options(capabilities);
12597                            sync_options.change = Some(sync_kind);
12598                            capabilities.text_document_sync =
12599                                Some(lsp::TextDocumentSyncCapability::Options(sync_options));
12600                        });
12601                        notify_server_capabilities_updated(&server, cx);
12602                    }
12603                }
12604                "textDocument/didSave" => {
12605                    if let Some(include_text) = reg
12606                        .register_options
12607                        .map(|opts| {
12608                            let transpose = opts
12609                                .get("includeText")
12610                                .cloned()
12611                                .map(serde_json::from_value::<Option<bool>>)
12612                                .transpose();
12613                            match transpose {
12614                                Ok(value) => Ok(value.flatten()),
12615                                Err(e) => Err(e),
12616                            }
12617                        })
12618                        .transpose()?
12619                    {
12620                        server.update_capabilities(|capabilities| {
12621                            let mut sync_options =
12622                                Self::take_text_document_sync_options(capabilities);
12623                            sync_options.save =
12624                                Some(TextDocumentSyncSaveOptions::SaveOptions(lsp::SaveOptions {
12625                                    include_text,
12626                                }));
12627                            capabilities.text_document_sync =
12628                                Some(lsp::TextDocumentSyncCapability::Options(sync_options));
12629                        });
12630                        notify_server_capabilities_updated(&server, cx);
12631                    }
12632                }
12633                "textDocument/codeLens" => {
12634                    if let Some(caps) = reg
12635                        .register_options
12636                        .map(serde_json::from_value)
12637                        .transpose()?
12638                    {
12639                        server.update_capabilities(|capabilities| {
12640                            capabilities.code_lens_provider = Some(caps);
12641                        });
12642                        notify_server_capabilities_updated(&server, cx);
12643                    }
12644                }
12645                "textDocument/diagnostic" => {
12646                    if let Some(caps) = reg
12647                        .register_options
12648                        .map(serde_json::from_value::<DiagnosticServerCapabilities>)
12649                        .transpose()?
12650                    {
12651                        let local = self
12652                            .as_local_mut()
12653                            .context("Expected LSP Store to be local")?;
12654                        let state = local
12655                            .language_servers
12656                            .get_mut(&server_id)
12657                            .context("Could not obtain Language Servers state")?;
12658                        local
12659                            .language_server_dynamic_registrations
12660                            .entry(server_id)
12661                            .or_default()
12662                            .diagnostics
12663                            .insert(Some(reg.id.clone()), caps.clone());
12664
12665                        let supports_workspace_diagnostics =
12666                            |capabilities: &DiagnosticServerCapabilities| match capabilities {
12667                                DiagnosticServerCapabilities::Options(diagnostic_options) => {
12668                                    diagnostic_options.workspace_diagnostics
12669                                }
12670                                DiagnosticServerCapabilities::RegistrationOptions(
12671                                    diagnostic_registration_options,
12672                                ) => {
12673                                    diagnostic_registration_options
12674                                        .diagnostic_options
12675                                        .workspace_diagnostics
12676                                }
12677                            };
12678
12679                        if supports_workspace_diagnostics(&caps) {
12680                            if let LanguageServerState::Running {
12681                                workspace_diagnostics_refresh_tasks,
12682                                ..
12683                            } = state
12684                                && let Some(task) = lsp_workspace_diagnostics_refresh(
12685                                    Some(reg.id.clone()),
12686                                    caps.clone(),
12687                                    server.clone(),
12688                                    cx,
12689                                )
12690                            {
12691                                workspace_diagnostics_refresh_tasks.insert(Some(reg.id), task);
12692                            }
12693                        }
12694
12695                        server.update_capabilities(|capabilities| {
12696                            capabilities.diagnostic_provider = Some(caps);
12697                        });
12698
12699                        notify_server_capabilities_updated(&server, cx);
12700
12701                        self.pull_document_diagnostics_for_server(server_id, cx)
12702                            .detach();
12703                    }
12704                }
12705                "textDocument/documentColor" => {
12706                    let options = parse_register_capabilities(reg)?;
12707                    let provider = match options {
12708                        OneOf::Left(value) => lsp::ColorProviderCapability::Simple(value),
12709                        OneOf::Right(caps) => caps,
12710                    };
12711                    server.update_capabilities(|capabilities| {
12712                        capabilities.color_provider = Some(provider);
12713                    });
12714                    notify_server_capabilities_updated(&server, cx);
12715                }
12716                _ => log::warn!("unhandled capability registration: {reg:?}"),
12717            }
12718        }
12719
12720        Ok(())
12721    }
12722
12723    fn unregister_server_capabilities(
12724        &mut self,
12725        server_id: LanguageServerId,
12726        params: lsp::UnregistrationParams,
12727        cx: &mut Context<Self>,
12728    ) -> anyhow::Result<()> {
12729        let server = self
12730            .language_server_for_id(server_id)
12731            .with_context(|| format!("no server {server_id} found"))?;
12732        for unreg in params.unregisterations.iter() {
12733            match unreg.method.as_str() {
12734                "workspace/didChangeWatchedFiles" => {
12735                    let notify = if let Some(local_lsp_store) = self.as_local_mut() {
12736                        local_lsp_store
12737                            .on_lsp_unregister_did_change_watched_files(server_id, &unreg.id, cx);
12738                        true
12739                    } else {
12740                        false
12741                    };
12742                    if notify {
12743                        notify_server_capabilities_updated(&server, cx);
12744                    }
12745                }
12746                "workspace/didChangeConfiguration" => {
12747                    // Ignore payload since we notify clients of setting changes unconditionally, relying on them pulling the latest settings.
12748                }
12749                "workspace/didChangeWorkspaceFolders" => {
12750                    server.update_capabilities(|capabilities| {
12751                        capabilities
12752                            .workspace
12753                            .get_or_insert_with(|| lsp::WorkspaceServerCapabilities {
12754                                workspace_folders: None,
12755                                file_operations: None,
12756                            })
12757                            .workspace_folders = None;
12758                    });
12759                    notify_server_capabilities_updated(&server, cx);
12760                }
12761                "workspace/symbol" => {
12762                    server.update_capabilities(|capabilities| {
12763                        capabilities.workspace_symbol_provider = None
12764                    });
12765                    notify_server_capabilities_updated(&server, cx);
12766                }
12767                "workspace/fileOperations" => {
12768                    server.update_capabilities(|capabilities| {
12769                        capabilities
12770                            .workspace
12771                            .get_or_insert_with(|| lsp::WorkspaceServerCapabilities {
12772                                workspace_folders: None,
12773                                file_operations: None,
12774                            })
12775                            .file_operations = None;
12776                    });
12777                    notify_server_capabilities_updated(&server, cx);
12778                }
12779                "workspace/executeCommand" => {
12780                    server.update_capabilities(|capabilities| {
12781                        capabilities.execute_command_provider = None;
12782                    });
12783                    notify_server_capabilities_updated(&server, cx);
12784                }
12785                "textDocument/rangeFormatting" => {
12786                    server.update_capabilities(|capabilities| {
12787                        capabilities.document_range_formatting_provider = None
12788                    });
12789                    notify_server_capabilities_updated(&server, cx);
12790                }
12791                "textDocument/onTypeFormatting" => {
12792                    server.update_capabilities(|capabilities| {
12793                        capabilities.document_on_type_formatting_provider = None;
12794                    });
12795                    notify_server_capabilities_updated(&server, cx);
12796                }
12797                "textDocument/formatting" => {
12798                    server.update_capabilities(|capabilities| {
12799                        capabilities.document_formatting_provider = None;
12800                    });
12801                    notify_server_capabilities_updated(&server, cx);
12802                }
12803                "textDocument/rename" => {
12804                    server.update_capabilities(|capabilities| capabilities.rename_provider = None);
12805                    notify_server_capabilities_updated(&server, cx);
12806                }
12807                "textDocument/codeAction" => {
12808                    server.update_capabilities(|capabilities| {
12809                        capabilities.code_action_provider = None;
12810                    });
12811                    notify_server_capabilities_updated(&server, cx);
12812                }
12813                "textDocument/definition" => {
12814                    server.update_capabilities(|capabilities| {
12815                        capabilities.definition_provider = None;
12816                    });
12817                    notify_server_capabilities_updated(&server, cx);
12818                }
12819                "textDocument/completion" => {
12820                    server.update_capabilities(|capabilities| {
12821                        capabilities.completion_provider = None;
12822                    });
12823                    notify_server_capabilities_updated(&server, cx);
12824                }
12825                "textDocument/hover" => {
12826                    server.update_capabilities(|capabilities| {
12827                        capabilities.hover_provider = None;
12828                    });
12829                    notify_server_capabilities_updated(&server, cx);
12830                }
12831                "textDocument/signatureHelp" => {
12832                    server.update_capabilities(|capabilities| {
12833                        capabilities.signature_help_provider = None;
12834                    });
12835                    notify_server_capabilities_updated(&server, cx);
12836                }
12837                "textDocument/didChange" => {
12838                    server.update_capabilities(|capabilities| {
12839                        let mut sync_options = Self::take_text_document_sync_options(capabilities);
12840                        sync_options.change = None;
12841                        capabilities.text_document_sync =
12842                            Some(lsp::TextDocumentSyncCapability::Options(sync_options));
12843                    });
12844                    notify_server_capabilities_updated(&server, cx);
12845                }
12846                "textDocument/didSave" => {
12847                    server.update_capabilities(|capabilities| {
12848                        let mut sync_options = Self::take_text_document_sync_options(capabilities);
12849                        sync_options.save = None;
12850                        capabilities.text_document_sync =
12851                            Some(lsp::TextDocumentSyncCapability::Options(sync_options));
12852                    });
12853                    notify_server_capabilities_updated(&server, cx);
12854                }
12855                "textDocument/codeLens" => {
12856                    server.update_capabilities(|capabilities| {
12857                        capabilities.code_lens_provider = None;
12858                    });
12859                    notify_server_capabilities_updated(&server, cx);
12860                }
12861                "textDocument/diagnostic" => {
12862                    let local = self
12863                        .as_local_mut()
12864                        .context("Expected LSP Store to be local")?;
12865
12866                    let state = local
12867                        .language_servers
12868                        .get_mut(&server_id)
12869                        .context("Could not obtain Language Servers state")?;
12870                    let registrations = local
12871                        .language_server_dynamic_registrations
12872                        .get_mut(&server_id)
12873                        .with_context(|| {
12874                            format!("Expected dynamic registration to exist for server {server_id}")
12875                        })?;
12876                    registrations.diagnostics
12877                        .remove(&Some(unreg.id.clone()))
12878                        .with_context(|| format!(
12879                            "Attempted to unregister non-existent diagnostic registration with ID {}",
12880                            unreg.id)
12881                        )?;
12882                    let removed_last_diagnostic_provider = registrations.diagnostics.is_empty();
12883
12884                    if let LanguageServerState::Running {
12885                        workspace_diagnostics_refresh_tasks,
12886                        ..
12887                    } = state
12888                    {
12889                        workspace_diagnostics_refresh_tasks.remove(&Some(unreg.id.clone()));
12890                    }
12891
12892                    self.clear_unregistered_diagnostics(
12893                        server_id,
12894                        SharedString::from(unreg.id.clone()),
12895                        cx,
12896                    )?;
12897
12898                    if removed_last_diagnostic_provider {
12899                        server.update_capabilities(|capabilities| {
12900                            debug_assert!(capabilities.diagnostic_provider.is_some());
12901                            capabilities.diagnostic_provider = None;
12902                        });
12903                    }
12904
12905                    notify_server_capabilities_updated(&server, cx);
12906                }
12907                "textDocument/documentColor" => {
12908                    server.update_capabilities(|capabilities| {
12909                        capabilities.color_provider = None;
12910                    });
12911                    notify_server_capabilities_updated(&server, cx);
12912                }
12913                _ => log::warn!("unhandled capability unregistration: {unreg:?}"),
12914            }
12915        }
12916
12917        Ok(())
12918    }
12919
12920    fn clear_unregistered_diagnostics(
12921        &mut self,
12922        server_id: LanguageServerId,
12923        cleared_registration_id: SharedString,
12924        cx: &mut Context<Self>,
12925    ) -> anyhow::Result<()> {
12926        let mut affected_abs_paths: HashSet<PathBuf> = HashSet::default();
12927
12928        self.buffer_store.update(cx, |buffer_store, cx| {
12929            for buffer_handle in buffer_store.buffers() {
12930                let buffer = buffer_handle.read(cx);
12931                let abs_path = File::from_dyn(buffer.file()).map(|f| f.abs_path(cx));
12932                let Some(abs_path) = abs_path else {
12933                    continue;
12934                };
12935                affected_abs_paths.insert(abs_path);
12936            }
12937        });
12938
12939        let local = self.as_local().context("Expected LSP Store to be local")?;
12940        for (worktree_id, diagnostics_for_tree) in local.diagnostics.iter() {
12941            let Some(worktree) = self
12942                .worktree_store
12943                .read(cx)
12944                .worktree_for_id(*worktree_id, cx)
12945            else {
12946                continue;
12947            };
12948
12949            for (rel_path, diagnostics_by_server_id) in diagnostics_for_tree.iter() {
12950                if let Ok(ix) = diagnostics_by_server_id.binary_search_by_key(&server_id, |e| e.0) {
12951                    let has_matching_registration =
12952                        diagnostics_by_server_id[ix].1.iter().any(|entry| {
12953                            entry.diagnostic.registration_id.as_ref()
12954                                == Some(&cleared_registration_id)
12955                        });
12956                    if has_matching_registration {
12957                        let abs_path = worktree.read(cx).absolutize(rel_path);
12958                        affected_abs_paths.insert(abs_path);
12959                    }
12960                }
12961            }
12962        }
12963
12964        if affected_abs_paths.is_empty() {
12965            return Ok(());
12966        }
12967
12968        // Send a fake diagnostic update which clears the state for the registration ID
12969        let clears: Vec<DocumentDiagnosticsUpdate<'static, DocumentDiagnostics>> =
12970            affected_abs_paths
12971                .into_iter()
12972                .map(|abs_path| DocumentDiagnosticsUpdate {
12973                    diagnostics: DocumentDiagnostics {
12974                        diagnostics: Vec::new(),
12975                        document_abs_path: abs_path,
12976                        version: None,
12977                    },
12978                    result_id: None,
12979                    registration_id: Some(cleared_registration_id.clone()),
12980                    server_id,
12981                    disk_based_sources: Cow::Borrowed(&[]),
12982                })
12983                .collect();
12984
12985        let merge_registration_id = cleared_registration_id.clone();
12986        self.merge_diagnostic_entries(
12987            clears,
12988            move |_, diagnostic, _| {
12989                if diagnostic.source_kind == DiagnosticSourceKind::Pulled {
12990                    diagnostic.registration_id != Some(merge_registration_id.clone())
12991                } else {
12992                    true
12993                }
12994            },
12995            cx,
12996        )?;
12997
12998        Ok(())
12999    }
13000
13001    async fn deduplicate_range_based_lsp_requests<T>(
13002        lsp_store: &Entity<Self>,
13003        server_id: Option<LanguageServerId>,
13004        lsp_request_id: LspRequestId,
13005        proto_request: &T::ProtoRequest,
13006        range: Range<Anchor>,
13007        cx: &mut AsyncApp,
13008    ) -> Result<()>
13009    where
13010        T: LspCommand,
13011        T::ProtoRequest: proto::LspRequestMessage,
13012    {
13013        let buffer_id = BufferId::new(proto_request.buffer_id())?;
13014        let version = deserialize_version(proto_request.buffer_version());
13015        let buffer = lsp_store.update(cx, |this, cx| {
13016            this.buffer_store.read(cx).get_existing(buffer_id)
13017        })?;
13018        buffer
13019            .update(cx, |buffer, _| buffer.wait_for_version(version))
13020            .await?;
13021        lsp_store.update(cx, |lsp_store, cx| {
13022            let buffer_snapshot = buffer.read(cx).snapshot();
13023            let lsp_data = lsp_store.latest_lsp_data(&buffer, cx);
13024            let chunks_queried_for = lsp_data
13025                .inlay_hints
13026                .applicable_chunks(&[range.to_point(&buffer_snapshot)])
13027                .collect::<Vec<_>>();
13028            match chunks_queried_for.as_slice() {
13029                &[chunk] => {
13030                    let key = LspKey {
13031                        request_type: TypeId::of::<T>(),
13032                        server_queried: server_id,
13033                    };
13034                    let previous_request = lsp_data
13035                        .chunk_lsp_requests
13036                        .entry(key)
13037                        .or_default()
13038                        .insert(chunk, lsp_request_id);
13039                    if let Some((previous_request, running_requests)) =
13040                        previous_request.zip(lsp_data.lsp_requests.get_mut(&key))
13041                    {
13042                        running_requests.remove(&previous_request);
13043                    }
13044                }
13045                _ambiguous_chunks => {
13046                    // Have not found a unique chunk for the query range — be lenient and let the query to be spawned,
13047                    // there, a buffer version-based check will be performed and outdated requests discarded.
13048                }
13049            }
13050            anyhow::Ok(())
13051        })?;
13052
13053        Ok(())
13054    }
13055
13056    async fn query_lsp_locally<T>(
13057        lsp_store: Entity<Self>,
13058        for_server_id: Option<LanguageServerId>,
13059        sender_id: proto::PeerId,
13060        lsp_request_id: LspRequestId,
13061        proto_request: T::ProtoRequest,
13062        position: Option<Anchor>,
13063        cx: &mut AsyncApp,
13064    ) -> Result<()>
13065    where
13066        T: LspCommand + Clone,
13067        T::ProtoRequest: proto::LspRequestMessage,
13068        <T::ProtoRequest as proto::RequestMessage>::Response:
13069            Into<<T::ProtoRequest as proto::LspRequestMessage>::Response>,
13070    {
13071        let buffer_id = BufferId::new(proto_request.buffer_id())?;
13072        let version = deserialize_version(proto_request.buffer_version());
13073        let buffer = lsp_store.update(cx, |this, cx| {
13074            this.buffer_store.read(cx).get_existing(buffer_id)
13075        })?;
13076        buffer
13077            .update(cx, |buffer, _| buffer.wait_for_version(version.clone()))
13078            .await?;
13079        let buffer_version = buffer.read_with(cx, |buffer, _| buffer.version());
13080        let request =
13081            T::from_proto(proto_request, lsp_store.clone(), buffer.clone(), cx.clone()).await?;
13082        let key = LspKey {
13083            request_type: TypeId::of::<T>(),
13084            server_queried: for_server_id,
13085        };
13086        lsp_store.update(cx, |lsp_store, cx| {
13087            let request_task = match for_server_id {
13088                Some(server_id) => {
13089                    let server_task = lsp_store.request_lsp(
13090                        buffer.clone(),
13091                        LanguageServerToQuery::Other(server_id),
13092                        request.clone(),
13093                        cx,
13094                    );
13095                    cx.background_spawn(async move {
13096                        let mut responses = Vec::new();
13097                        match server_task.await {
13098                            Ok(response) => responses.push((server_id, response)),
13099                            // rust-analyzer likes to error with this when its still loading up
13100                            Err(e) if format!("{e:#}").ends_with("content modified") => (),
13101                            Err(e) => log::error!(
13102                                "Error handling response for request {request:?}: {e:#}"
13103                            ),
13104                        }
13105                        responses
13106                    })
13107                }
13108                None => lsp_store.request_multiple_lsp_locally(&buffer, position, request, cx),
13109            };
13110            let lsp_data = lsp_store.latest_lsp_data(&buffer, cx);
13111            if T::ProtoRequest::stop_previous_requests() {
13112                if let Some(lsp_requests) = lsp_data.lsp_requests.get_mut(&key) {
13113                    lsp_requests.clear();
13114                }
13115            }
13116            lsp_data.lsp_requests.entry(key).or_default().insert(
13117                lsp_request_id,
13118                cx.spawn(async move |lsp_store, cx| {
13119                    let response = request_task.await;
13120                    lsp_store
13121                        .update(cx, |lsp_store, cx| {
13122                            if let Some((client, project_id)) = lsp_store.downstream_client.clone()
13123                            {
13124                                let response = response
13125                                    .into_iter()
13126                                    .map(|(server_id, response)| {
13127                                        (
13128                                            server_id.to_proto(),
13129                                            T::response_to_proto(
13130                                                response,
13131                                                lsp_store,
13132                                                sender_id,
13133                                                &buffer_version,
13134                                                cx,
13135                                            )
13136                                            .into(),
13137                                        )
13138                                    })
13139                                    .collect::<HashMap<_, _>>();
13140                                match client.send_lsp_response::<T::ProtoRequest>(
13141                                    project_id,
13142                                    lsp_request_id,
13143                                    response,
13144                                ) {
13145                                    Ok(()) => {}
13146                                    Err(e) => {
13147                                        log::error!("Failed to send LSP response: {e:#}",)
13148                                    }
13149                                }
13150                            }
13151                        })
13152                        .ok();
13153                }),
13154            );
13155        });
13156        Ok(())
13157    }
13158
13159    fn take_text_document_sync_options(
13160        capabilities: &mut lsp::ServerCapabilities,
13161    ) -> lsp::TextDocumentSyncOptions {
13162        match capabilities.text_document_sync.take() {
13163            Some(lsp::TextDocumentSyncCapability::Options(sync_options)) => sync_options,
13164            Some(lsp::TextDocumentSyncCapability::Kind(sync_kind)) => {
13165                let mut sync_options = lsp::TextDocumentSyncOptions::default();
13166                sync_options.change = Some(sync_kind);
13167                sync_options
13168            }
13169            None => lsp::TextDocumentSyncOptions::default(),
13170        }
13171    }
13172
13173    #[cfg(any(test, feature = "test-support"))]
13174    pub fn forget_code_lens_task(&mut self, buffer_id: BufferId) -> Option<CodeLensTask> {
13175        Some(
13176            self.lsp_data
13177                .get_mut(&buffer_id)?
13178                .code_lens
13179                .take()?
13180                .update
13181                .take()?
13182                .1,
13183        )
13184    }
13185
13186    pub fn downstream_client(&self) -> Option<(AnyProtoClient, u64)> {
13187        self.downstream_client.clone()
13188    }
13189
13190    pub fn worktree_store(&self) -> Entity<WorktreeStore> {
13191        self.worktree_store.clone()
13192    }
13193
13194    /// Gets what's stored in the LSP data for the given buffer.
13195    pub fn current_lsp_data(&mut self, buffer_id: BufferId) -> Option<&mut BufferLspData> {
13196        self.lsp_data.get_mut(&buffer_id)
13197    }
13198
13199    /// Gets the most recent LSP data for the given buffer: if the data is absent or out of date,
13200    /// new [`BufferLspData`] will be created to replace the previous state.
13201    pub fn latest_lsp_data(&mut self, buffer: &Entity<Buffer>, cx: &mut App) -> &mut BufferLspData {
13202        let (buffer_id, buffer_version) =
13203            buffer.read_with(cx, |buffer, _| (buffer.remote_id(), buffer.version()));
13204        let lsp_data = self
13205            .lsp_data
13206            .entry(buffer_id)
13207            .or_insert_with(|| BufferLspData::new(buffer, cx));
13208        if buffer_version.changed_since(&lsp_data.buffer_version) {
13209            *lsp_data = BufferLspData::new(buffer, cx);
13210        }
13211        lsp_data
13212    }
13213}
13214
13215// Registration with registerOptions as null, should fallback to true.
13216// https://github.com/microsoft/vscode-languageserver-node/blob/d90a87f9557a0df9142cfb33e251cfa6fe27d970/client/src/common/client.ts#L2133
13217fn parse_register_capabilities<T: serde::de::DeserializeOwned>(
13218    reg: lsp::Registration,
13219) -> Result<OneOf<bool, T>> {
13220    Ok(match reg.register_options {
13221        Some(options) => OneOf::Right(serde_json::from_value::<T>(options)?),
13222        None => OneOf::Left(true),
13223    })
13224}
13225
13226fn subscribe_to_binary_statuses(
13227    languages: &Arc<LanguageRegistry>,
13228    cx: &mut Context<'_, LspStore>,
13229) -> Task<()> {
13230    let mut server_statuses = languages.language_server_binary_statuses();
13231    cx.spawn(async move |lsp_store, cx| {
13232        while let Some((server_name, binary_status)) = server_statuses.next().await {
13233            if lsp_store
13234                .update(cx, |_, cx| {
13235                    let mut message = None;
13236                    let binary_status = match binary_status {
13237                        BinaryStatus::None => proto::ServerBinaryStatus::None,
13238                        BinaryStatus::CheckingForUpdate => {
13239                            proto::ServerBinaryStatus::CheckingForUpdate
13240                        }
13241                        BinaryStatus::Downloading => proto::ServerBinaryStatus::Downloading,
13242                        BinaryStatus::Starting => proto::ServerBinaryStatus::Starting,
13243                        BinaryStatus::Stopping => proto::ServerBinaryStatus::Stopping,
13244                        BinaryStatus::Stopped => proto::ServerBinaryStatus::Stopped,
13245                        BinaryStatus::Failed { error } => {
13246                            message = Some(error);
13247                            proto::ServerBinaryStatus::Failed
13248                        }
13249                    };
13250                    cx.emit(LspStoreEvent::LanguageServerUpdate {
13251                        // Binary updates are about the binary that might not have any language server id at that point.
13252                        // Reuse `LanguageServerUpdate` for them and provide a fake id that won't be used on the receiver side.
13253                        language_server_id: LanguageServerId(0),
13254                        name: Some(server_name),
13255                        message: proto::update_language_server::Variant::StatusUpdate(
13256                            proto::StatusUpdate {
13257                                message,
13258                                status: Some(proto::status_update::Status::Binary(
13259                                    binary_status as i32,
13260                                )),
13261                            },
13262                        ),
13263                    });
13264                })
13265                .is_err()
13266            {
13267                break;
13268            }
13269        }
13270    })
13271}
13272
13273fn lsp_workspace_diagnostics_refresh(
13274    registration_id: Option<String>,
13275    options: DiagnosticServerCapabilities,
13276    server: Arc<LanguageServer>,
13277    cx: &mut Context<'_, LspStore>,
13278) -> Option<WorkspaceRefreshTask> {
13279    let identifier = workspace_diagnostic_identifier(&options)?;
13280    let registration_id_shared = registration_id.as_ref().map(SharedString::from);
13281
13282    let (progress_tx, mut progress_rx) = mpsc::channel(1);
13283    let (mut refresh_tx, mut refresh_rx) = mpsc::channel(1);
13284    refresh_tx.try_send(()).ok();
13285
13286    let workspace_query_language_server = cx.spawn(async move |lsp_store, cx| {
13287        let mut attempts = 0;
13288        let max_attempts = 50;
13289        let mut requests = 0;
13290
13291        loop {
13292            let Some(()) = refresh_rx.recv().await else {
13293                return;
13294            };
13295
13296            'request: loop {
13297                requests += 1;
13298                if attempts > max_attempts {
13299                    log::error!(
13300                        "Failed to pull workspace diagnostics {max_attempts} times, aborting"
13301                    );
13302                    return;
13303                }
13304                let backoff_millis = (50 * (1 << attempts)).clamp(30, 1000);
13305                cx.background_executor()
13306                    .timer(Duration::from_millis(backoff_millis))
13307                    .await;
13308                attempts += 1;
13309
13310                let Ok(previous_result_ids) = lsp_store.update(cx, |lsp_store, _| {
13311                    lsp_store
13312                        .result_ids_for_workspace_refresh(server.server_id(), &registration_id_shared)
13313                        .into_iter()
13314                        .filter_map(|(abs_path, result_id)| {
13315                            let uri = file_path_to_lsp_url(&abs_path).ok()?;
13316                            Some(lsp::PreviousResultId {
13317                                uri,
13318                                value: result_id.to_string(),
13319                            })
13320                        })
13321                        .collect()
13322                }) else {
13323                    return;
13324                };
13325
13326                let token = if let Some(registration_id) = &registration_id {
13327                    format!(
13328                        "workspace/diagnostic/{}/{requests}/{WORKSPACE_DIAGNOSTICS_TOKEN_START}{registration_id}",
13329                        server.server_id(),
13330                    )
13331                } else {
13332                    format!("workspace/diagnostic/{}/{requests}", server.server_id())
13333                };
13334
13335                progress_rx.try_recv().ok();
13336                let timer =
13337                    LanguageServer::default_request_timer(cx.background_executor().clone()).fuse();
13338                let progress = pin!(progress_rx.recv().fuse());
13339                let response_result = server
13340                    .request_with_timer::<lsp::WorkspaceDiagnosticRequest, _>(
13341                        lsp::WorkspaceDiagnosticParams {
13342                            previous_result_ids,
13343                            identifier: identifier.clone(),
13344                            work_done_progress_params: Default::default(),
13345                            partial_result_params: lsp::PartialResultParams {
13346                                partial_result_token: Some(lsp::ProgressToken::String(token)),
13347                            },
13348                        },
13349                        select(timer, progress).then(|either| match either {
13350                            Either::Left((message, ..)) => ready(message).left_future(),
13351                            Either::Right(..) => pending::<String>().right_future(),
13352                        }),
13353                    )
13354                    .await;
13355
13356                // https://microsoft.github.io/language-server-protocol/specifications/lsp/3.17/specification/#diagnostic_refresh
13357                // >  If a server closes a workspace diagnostic pull request the client should re-trigger the request.
13358                match response_result {
13359                    ConnectionResult::Timeout => {
13360                        log::error!("Timeout during workspace diagnostics pull");
13361                        continue 'request;
13362                    }
13363                    ConnectionResult::ConnectionReset => {
13364                        log::error!("Server closed a workspace diagnostics pull request");
13365                        continue 'request;
13366                    }
13367                    ConnectionResult::Result(Err(e)) => {
13368                        log::error!("Error during workspace diagnostics pull: {e:#}");
13369                        break 'request;
13370                    }
13371                    ConnectionResult::Result(Ok(pulled_diagnostics)) => {
13372                        attempts = 0;
13373                        if lsp_store
13374                            .update(cx, |lsp_store, cx| {
13375                                lsp_store.apply_workspace_diagnostic_report(
13376                                    server.server_id(),
13377                                    pulled_diagnostics,
13378                                    registration_id_shared.clone(),
13379                                    cx,
13380                                )
13381                            })
13382                            .is_err()
13383                        {
13384                            return;
13385                        }
13386                        break 'request;
13387                    }
13388                }
13389            }
13390        }
13391    });
13392
13393    Some(WorkspaceRefreshTask {
13394        refresh_tx,
13395        progress_tx,
13396        task: workspace_query_language_server,
13397    })
13398}
13399
13400fn buffer_diagnostic_identifier(options: &DiagnosticServerCapabilities) -> Option<String> {
13401    match &options {
13402        lsp::DiagnosticServerCapabilities::Options(diagnostic_options) => {
13403            diagnostic_options.identifier.clone()
13404        }
13405        lsp::DiagnosticServerCapabilities::RegistrationOptions(registration_options) => {
13406            let diagnostic_options = &registration_options.diagnostic_options;
13407            diagnostic_options.identifier.clone()
13408        }
13409    }
13410}
13411
13412fn workspace_diagnostic_identifier(
13413    options: &DiagnosticServerCapabilities,
13414) -> Option<Option<String>> {
13415    match &options {
13416        lsp::DiagnosticServerCapabilities::Options(diagnostic_options) => {
13417            if !diagnostic_options.workspace_diagnostics {
13418                return None;
13419            }
13420            Some(diagnostic_options.identifier.clone())
13421        }
13422        lsp::DiagnosticServerCapabilities::RegistrationOptions(registration_options) => {
13423            let diagnostic_options = &registration_options.diagnostic_options;
13424            if !diagnostic_options.workspace_diagnostics {
13425                return None;
13426            }
13427            Some(diagnostic_options.identifier.clone())
13428        }
13429    }
13430}
13431
13432fn resolve_word_completion(snapshot: &BufferSnapshot, completion: &mut Completion) {
13433    let CompletionSource::BufferWord {
13434        word_range,
13435        resolved,
13436    } = &mut completion.source
13437    else {
13438        return;
13439    };
13440    if *resolved {
13441        return;
13442    }
13443
13444    if completion.new_text
13445        != snapshot
13446            .text_for_range(word_range.clone())
13447            .collect::<String>()
13448    {
13449        return;
13450    }
13451
13452    let mut offset = 0;
13453    for chunk in snapshot.chunks(word_range.clone(), true) {
13454        let end_offset = offset + chunk.text.len();
13455        if let Some(highlight_id) = chunk.syntax_highlight_id {
13456            completion
13457                .label
13458                .runs
13459                .push((offset..end_offset, highlight_id));
13460        }
13461        offset = end_offset;
13462    }
13463    *resolved = true;
13464}
13465
13466impl EventEmitter<LspStoreEvent> for LspStore {}
13467
13468fn remove_empty_hover_blocks(mut hover: Hover) -> Option<Hover> {
13469    hover
13470        .contents
13471        .retain(|hover_block| !hover_block.text.trim().is_empty());
13472    if hover.contents.is_empty() {
13473        None
13474    } else {
13475        Some(hover)
13476    }
13477}
13478
13479async fn populate_labels_for_completions(
13480    new_completions: Vec<CoreCompletion>,
13481    language: Option<Arc<Language>>,
13482    lsp_adapter: Option<Arc<CachedLspAdapter>>,
13483) -> Vec<Completion> {
13484    let lsp_completions = new_completions
13485        .iter()
13486        .filter_map(|new_completion| {
13487            new_completion
13488                .source
13489                .lsp_completion(true)
13490                .map(|lsp_completion| lsp_completion.into_owned())
13491        })
13492        .collect::<Vec<_>>();
13493
13494    let mut labels = if let Some((language, lsp_adapter)) = language.as_ref().zip(lsp_adapter) {
13495        lsp_adapter
13496            .labels_for_completions(&lsp_completions, language)
13497            .await
13498            .log_err()
13499            .unwrap_or_default()
13500    } else {
13501        Vec::new()
13502    }
13503    .into_iter()
13504    .fuse();
13505
13506    let mut completions = Vec::new();
13507    for completion in new_completions {
13508        match completion.source.lsp_completion(true) {
13509            Some(lsp_completion) => {
13510                let documentation = lsp_completion.documentation.clone().map(|docs| docs.into());
13511
13512                let mut label = labels.next().flatten().unwrap_or_else(|| {
13513                    CodeLabel::fallback_for_completion(&lsp_completion, language.as_deref())
13514                });
13515                ensure_uniform_list_compatible_label(&mut label);
13516                completions.push(Completion {
13517                    label,
13518                    documentation,
13519                    replace_range: completion.replace_range,
13520                    new_text: completion.new_text,
13521                    insert_text_mode: lsp_completion.insert_text_mode,
13522                    source: completion.source,
13523                    icon_path: None,
13524                    confirm: None,
13525                    match_start: None,
13526                    snippet_deduplication_key: None,
13527                });
13528            }
13529            None => {
13530                let mut label = CodeLabel::plain(completion.new_text.clone(), None);
13531                ensure_uniform_list_compatible_label(&mut label);
13532                completions.push(Completion {
13533                    label,
13534                    documentation: None,
13535                    replace_range: completion.replace_range,
13536                    new_text: completion.new_text,
13537                    source: completion.source,
13538                    insert_text_mode: None,
13539                    icon_path: None,
13540                    confirm: None,
13541                    match_start: None,
13542                    snippet_deduplication_key: None,
13543                });
13544            }
13545        }
13546    }
13547    completions
13548}
13549
13550#[derive(Debug)]
13551pub enum LanguageServerToQuery {
13552    /// Query language servers in order of users preference, up until one capable of handling the request is found.
13553    FirstCapable,
13554    /// Query a specific language server.
13555    Other(LanguageServerId),
13556}
13557
13558#[derive(Default)]
13559struct RenamePathsWatchedForServer {
13560    did_rename: Vec<RenameActionPredicate>,
13561    will_rename: Vec<RenameActionPredicate>,
13562}
13563
13564impl RenamePathsWatchedForServer {
13565    fn with_did_rename_patterns(
13566        mut self,
13567        did_rename: Option<&FileOperationRegistrationOptions>,
13568    ) -> Self {
13569        if let Some(did_rename) = did_rename {
13570            self.did_rename = did_rename
13571                .filters
13572                .iter()
13573                .filter_map(|filter| filter.try_into().log_err())
13574                .collect();
13575        }
13576        self
13577    }
13578    fn with_will_rename_patterns(
13579        mut self,
13580        will_rename: Option<&FileOperationRegistrationOptions>,
13581    ) -> Self {
13582        if let Some(will_rename) = will_rename {
13583            self.will_rename = will_rename
13584                .filters
13585                .iter()
13586                .filter_map(|filter| filter.try_into().log_err())
13587                .collect();
13588        }
13589        self
13590    }
13591
13592    fn should_send_did_rename(&self, path: &str, is_dir: bool) -> bool {
13593        self.did_rename.iter().any(|pred| pred.eval(path, is_dir))
13594    }
13595    fn should_send_will_rename(&self, path: &str, is_dir: bool) -> bool {
13596        self.will_rename.iter().any(|pred| pred.eval(path, is_dir))
13597    }
13598}
13599
13600impl TryFrom<&FileOperationFilter> for RenameActionPredicate {
13601    type Error = globset::Error;
13602    fn try_from(ops: &FileOperationFilter) -> Result<Self, globset::Error> {
13603        Ok(Self {
13604            kind: ops.pattern.matches.clone(),
13605            glob: GlobBuilder::new(&ops.pattern.glob)
13606                .case_insensitive(
13607                    ops.pattern
13608                        .options
13609                        .as_ref()
13610                        .is_some_and(|ops| ops.ignore_case.unwrap_or(false)),
13611                )
13612                .build()?
13613                .compile_matcher(),
13614        })
13615    }
13616}
13617struct RenameActionPredicate {
13618    glob: GlobMatcher,
13619    kind: Option<FileOperationPatternKind>,
13620}
13621
13622impl RenameActionPredicate {
13623    // Returns true if language server should be notified
13624    fn eval(&self, path: &str, is_dir: bool) -> bool {
13625        self.kind.as_ref().is_none_or(|kind| {
13626            let expected_kind = if is_dir {
13627                FileOperationPatternKind::Folder
13628            } else {
13629                FileOperationPatternKind::File
13630            };
13631            kind == &expected_kind
13632        }) && self.glob.is_match(path)
13633    }
13634}
13635
13636#[derive(Default)]
13637struct LanguageServerWatchedPaths {
13638    worktree_paths: HashMap<WorktreeId, GlobSet>,
13639    abs_paths: HashMap<Arc<Path>, (GlobSet, Task<()>)>,
13640}
13641
13642#[derive(Default)]
13643struct LanguageServerWatchedPathsBuilder {
13644    worktree_paths: HashMap<WorktreeId, GlobSet>,
13645    abs_paths: HashMap<Arc<Path>, GlobSet>,
13646}
13647
13648impl LanguageServerWatchedPathsBuilder {
13649    fn watch_worktree(&mut self, worktree_id: WorktreeId, glob_set: GlobSet) {
13650        self.worktree_paths.insert(worktree_id, glob_set);
13651    }
13652    fn watch_abs_path(&mut self, path: Arc<Path>, glob_set: GlobSet) {
13653        self.abs_paths.insert(path, glob_set);
13654    }
13655    fn build(
13656        self,
13657        fs: Arc<dyn Fs>,
13658        language_server_id: LanguageServerId,
13659        cx: &mut Context<LspStore>,
13660    ) -> LanguageServerWatchedPaths {
13661        let lsp_store = cx.weak_entity();
13662
13663        const LSP_ABS_PATH_OBSERVE: Duration = Duration::from_millis(100);
13664        let abs_paths = self
13665            .abs_paths
13666            .into_iter()
13667            .map(|(abs_path, globset)| {
13668                let task = cx.spawn({
13669                    let abs_path = abs_path.clone();
13670                    let fs = fs.clone();
13671
13672                    let lsp_store = lsp_store.clone();
13673                    async move |_, cx| {
13674                        maybe!(async move {
13675                            let mut push_updates = fs.watch(&abs_path, LSP_ABS_PATH_OBSERVE).await;
13676                            while let Some(update) = push_updates.0.next().await {
13677                                let action = lsp_store
13678                                    .update(cx, |this, _| {
13679                                        let Some(local) = this.as_local() else {
13680                                            return ControlFlow::Break(());
13681                                        };
13682                                        let Some(watcher) = local
13683                                            .language_server_watched_paths
13684                                            .get(&language_server_id)
13685                                        else {
13686                                            return ControlFlow::Break(());
13687                                        };
13688                                        let (globs, _) = watcher.abs_paths.get(&abs_path).expect(
13689                                            "Watched abs path is not registered with a watcher",
13690                                        );
13691                                        let matching_entries = update
13692                                            .into_iter()
13693                                            .filter(|event| globs.is_match(&event.path))
13694                                            .collect::<Vec<_>>();
13695                                        this.lsp_notify_abs_paths_changed(
13696                                            language_server_id,
13697                                            matching_entries,
13698                                        );
13699                                        ControlFlow::Continue(())
13700                                    })
13701                                    .ok()?;
13702
13703                                if action.is_break() {
13704                                    break;
13705                                }
13706                            }
13707                            Some(())
13708                        })
13709                        .await;
13710                    }
13711                });
13712                (abs_path, (globset, task))
13713            })
13714            .collect();
13715        LanguageServerWatchedPaths {
13716            worktree_paths: self.worktree_paths,
13717            abs_paths,
13718        }
13719    }
13720}
13721
13722struct LspBufferSnapshot {
13723    version: i32,
13724    snapshot: TextBufferSnapshot,
13725}
13726
13727/// A prompt requested by LSP server.
13728#[derive(Clone, Debug)]
13729pub struct LanguageServerPromptRequest {
13730    pub level: PromptLevel,
13731    pub message: String,
13732    pub actions: Vec<MessageActionItem>,
13733    pub lsp_name: String,
13734    pub(crate) response_channel: smol::channel::Sender<MessageActionItem>,
13735}
13736
13737impl LanguageServerPromptRequest {
13738    pub async fn respond(self, index: usize) -> Option<()> {
13739        if let Some(response) = self.actions.into_iter().nth(index) {
13740            self.response_channel.send(response).await.ok()
13741        } else {
13742            None
13743        }
13744    }
13745}
13746impl PartialEq for LanguageServerPromptRequest {
13747    fn eq(&self, other: &Self) -> bool {
13748        self.message == other.message && self.actions == other.actions
13749    }
13750}
13751
13752#[derive(Clone, Debug, PartialEq)]
13753pub enum LanguageServerLogType {
13754    Log(MessageType),
13755    Trace { verbose_info: Option<String> },
13756    Rpc { received: bool },
13757}
13758
13759impl LanguageServerLogType {
13760    pub fn to_proto(&self) -> proto::language_server_log::LogType {
13761        match self {
13762            Self::Log(log_type) => {
13763                use proto::log_message::LogLevel;
13764                let level = match *log_type {
13765                    MessageType::ERROR => LogLevel::Error,
13766                    MessageType::WARNING => LogLevel::Warning,
13767                    MessageType::INFO => LogLevel::Info,
13768                    MessageType::LOG => LogLevel::Log,
13769                    other => {
13770                        log::warn!("Unknown lsp log message type: {other:?}");
13771                        LogLevel::Log
13772                    }
13773                };
13774                proto::language_server_log::LogType::Log(proto::LogMessage {
13775                    level: level as i32,
13776                })
13777            }
13778            Self::Trace { verbose_info } => {
13779                proto::language_server_log::LogType::Trace(proto::TraceMessage {
13780                    verbose_info: verbose_info.to_owned(),
13781                })
13782            }
13783            Self::Rpc { received } => {
13784                let kind = if *received {
13785                    proto::rpc_message::Kind::Received
13786                } else {
13787                    proto::rpc_message::Kind::Sent
13788                };
13789                let kind = kind as i32;
13790                proto::language_server_log::LogType::Rpc(proto::RpcMessage { kind })
13791            }
13792        }
13793    }
13794
13795    pub fn from_proto(log_type: proto::language_server_log::LogType) -> Self {
13796        use proto::log_message::LogLevel;
13797        use proto::rpc_message;
13798        match log_type {
13799            proto::language_server_log::LogType::Log(message_type) => Self::Log(
13800                match LogLevel::from_i32(message_type.level).unwrap_or(LogLevel::Log) {
13801                    LogLevel::Error => MessageType::ERROR,
13802                    LogLevel::Warning => MessageType::WARNING,
13803                    LogLevel::Info => MessageType::INFO,
13804                    LogLevel::Log => MessageType::LOG,
13805                },
13806            ),
13807            proto::language_server_log::LogType::Trace(trace_message) => Self::Trace {
13808                verbose_info: trace_message.verbose_info,
13809            },
13810            proto::language_server_log::LogType::Rpc(message) => Self::Rpc {
13811                received: match rpc_message::Kind::from_i32(message.kind)
13812                    .unwrap_or(rpc_message::Kind::Received)
13813                {
13814                    rpc_message::Kind::Received => true,
13815                    rpc_message::Kind::Sent => false,
13816                },
13817            },
13818        }
13819    }
13820}
13821
13822pub struct WorkspaceRefreshTask {
13823    refresh_tx: mpsc::Sender<()>,
13824    progress_tx: mpsc::Sender<()>,
13825    #[allow(dead_code)]
13826    task: Task<()>,
13827}
13828
13829pub enum LanguageServerState {
13830    Starting {
13831        startup: Task<Option<Arc<LanguageServer>>>,
13832        /// List of language servers that will be added to the workspace once it's initialization completes.
13833        pending_workspace_folders: Arc<Mutex<BTreeSet<Uri>>>,
13834    },
13835
13836    Running {
13837        adapter: Arc<CachedLspAdapter>,
13838        server: Arc<LanguageServer>,
13839        simulate_disk_based_diagnostics_completion: Option<Task<()>>,
13840        workspace_diagnostics_refresh_tasks: HashMap<Option<String>, WorkspaceRefreshTask>,
13841    },
13842}
13843
13844impl LanguageServerState {
13845    fn add_workspace_folder(&self, uri: Uri) {
13846        match self {
13847            LanguageServerState::Starting {
13848                pending_workspace_folders,
13849                ..
13850            } => {
13851                pending_workspace_folders.lock().insert(uri);
13852            }
13853            LanguageServerState::Running { server, .. } => {
13854                server.add_workspace_folder(uri);
13855            }
13856        }
13857    }
13858    fn _remove_workspace_folder(&self, uri: Uri) {
13859        match self {
13860            LanguageServerState::Starting {
13861                pending_workspace_folders,
13862                ..
13863            } => {
13864                pending_workspace_folders.lock().remove(&uri);
13865            }
13866            LanguageServerState::Running { server, .. } => server.remove_workspace_folder(uri),
13867        }
13868    }
13869}
13870
13871impl std::fmt::Debug for LanguageServerState {
13872    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
13873        match self {
13874            LanguageServerState::Starting { .. } => {
13875                f.debug_struct("LanguageServerState::Starting").finish()
13876            }
13877            LanguageServerState::Running { .. } => {
13878                f.debug_struct("LanguageServerState::Running").finish()
13879            }
13880        }
13881    }
13882}
13883
13884#[derive(Clone, Debug, Serialize)]
13885pub struct LanguageServerProgress {
13886    pub is_disk_based_diagnostics_progress: bool,
13887    pub is_cancellable: bool,
13888    pub title: Option<String>,
13889    pub message: Option<String>,
13890    pub percentage: Option<usize>,
13891    #[serde(skip_serializing)]
13892    pub last_update_at: Instant,
13893}
13894
13895#[derive(Copy, Clone, Debug, Default, PartialEq, Serialize)]
13896pub struct DiagnosticSummary {
13897    pub error_count: usize,
13898    pub warning_count: usize,
13899}
13900
13901impl DiagnosticSummary {
13902    pub fn new<'a, T: 'a>(diagnostics: impl IntoIterator<Item = &'a DiagnosticEntry<T>>) -> Self {
13903        let mut this = Self {
13904            error_count: 0,
13905            warning_count: 0,
13906        };
13907
13908        for entry in diagnostics {
13909            if entry.diagnostic.is_primary {
13910                match entry.diagnostic.severity {
13911                    DiagnosticSeverity::ERROR => this.error_count += 1,
13912                    DiagnosticSeverity::WARNING => this.warning_count += 1,
13913                    _ => {}
13914                }
13915            }
13916        }
13917
13918        this
13919    }
13920
13921    pub fn is_empty(&self) -> bool {
13922        self.error_count == 0 && self.warning_count == 0
13923    }
13924
13925    pub fn to_proto(
13926        self,
13927        language_server_id: LanguageServerId,
13928        path: &RelPath,
13929    ) -> proto::DiagnosticSummary {
13930        proto::DiagnosticSummary {
13931            path: path.to_proto(),
13932            language_server_id: language_server_id.0 as u64,
13933            error_count: self.error_count as u32,
13934            warning_count: self.warning_count as u32,
13935        }
13936    }
13937}
13938
13939#[derive(Clone, Debug)]
13940pub enum CompletionDocumentation {
13941    /// There is no documentation for this completion.
13942    Undocumented,
13943    /// A single line of documentation.
13944    SingleLine(SharedString),
13945    /// Multiple lines of plain text documentation.
13946    MultiLinePlainText(SharedString),
13947    /// Markdown documentation.
13948    MultiLineMarkdown(SharedString),
13949    /// Both single line and multiple lines of plain text documentation.
13950    SingleLineAndMultiLinePlainText {
13951        single_line: SharedString,
13952        plain_text: Option<SharedString>,
13953    },
13954}
13955
13956impl CompletionDocumentation {
13957    #[cfg(any(test, feature = "test-support"))]
13958    pub fn text(&self) -> SharedString {
13959        match self {
13960            CompletionDocumentation::Undocumented => "".into(),
13961            CompletionDocumentation::SingleLine(s) => s.clone(),
13962            CompletionDocumentation::MultiLinePlainText(s) => s.clone(),
13963            CompletionDocumentation::MultiLineMarkdown(s) => s.clone(),
13964            CompletionDocumentation::SingleLineAndMultiLinePlainText { single_line, .. } => {
13965                single_line.clone()
13966            }
13967        }
13968    }
13969}
13970
13971impl From<lsp::Documentation> for CompletionDocumentation {
13972    fn from(docs: lsp::Documentation) -> Self {
13973        match docs {
13974            lsp::Documentation::String(text) => {
13975                if text.lines().count() <= 1 {
13976                    CompletionDocumentation::SingleLine(text.trim().to_string().into())
13977                } else {
13978                    CompletionDocumentation::MultiLinePlainText(text.into())
13979                }
13980            }
13981
13982            lsp::Documentation::MarkupContent(lsp::MarkupContent { kind, value }) => match kind {
13983                lsp::MarkupKind::PlainText => {
13984                    if value.lines().count() <= 1 {
13985                        CompletionDocumentation::SingleLine(value.into())
13986                    } else {
13987                        CompletionDocumentation::MultiLinePlainText(value.into())
13988                    }
13989                }
13990
13991                lsp::MarkupKind::Markdown => {
13992                    CompletionDocumentation::MultiLineMarkdown(value.into())
13993                }
13994            },
13995        }
13996    }
13997}
13998
13999pub enum ResolvedHint {
14000    Resolved(InlayHint),
14001    Resolving(Shared<Task<()>>),
14002}
14003
14004fn glob_literal_prefix(glob: &Path) -> PathBuf {
14005    glob.components()
14006        .take_while(|component| match component {
14007            path::Component::Normal(part) => !part.to_string_lossy().contains(['*', '?', '{', '}']),
14008            _ => true,
14009        })
14010        .collect()
14011}
14012
14013pub struct SshLspAdapter {
14014    name: LanguageServerName,
14015    binary: LanguageServerBinary,
14016    initialization_options: Option<String>,
14017    code_action_kinds: Option<Vec<CodeActionKind>>,
14018}
14019
14020impl SshLspAdapter {
14021    pub fn new(
14022        name: LanguageServerName,
14023        binary: LanguageServerBinary,
14024        initialization_options: Option<String>,
14025        code_action_kinds: Option<String>,
14026    ) -> Self {
14027        Self {
14028            name,
14029            binary,
14030            initialization_options,
14031            code_action_kinds: code_action_kinds
14032                .as_ref()
14033                .and_then(|c| serde_json::from_str(c).ok()),
14034        }
14035    }
14036}
14037
14038impl LspInstaller for SshLspAdapter {
14039    type BinaryVersion = ();
14040    async fn check_if_user_installed(
14041        &self,
14042        _: &dyn LspAdapterDelegate,
14043        _: Option<Toolchain>,
14044        _: &AsyncApp,
14045    ) -> Option<LanguageServerBinary> {
14046        Some(self.binary.clone())
14047    }
14048
14049    async fn cached_server_binary(
14050        &self,
14051        _: PathBuf,
14052        _: &dyn LspAdapterDelegate,
14053    ) -> Option<LanguageServerBinary> {
14054        None
14055    }
14056
14057    async fn fetch_latest_server_version(
14058        &self,
14059        _: &dyn LspAdapterDelegate,
14060        _: bool,
14061        _: &mut AsyncApp,
14062    ) -> Result<()> {
14063        anyhow::bail!("SshLspAdapter does not support fetch_latest_server_version")
14064    }
14065
14066    async fn fetch_server_binary(
14067        &self,
14068        _: (),
14069        _: PathBuf,
14070        _: &dyn LspAdapterDelegate,
14071    ) -> Result<LanguageServerBinary> {
14072        anyhow::bail!("SshLspAdapter does not support fetch_server_binary")
14073    }
14074}
14075
14076#[async_trait(?Send)]
14077impl LspAdapter for SshLspAdapter {
14078    fn name(&self) -> LanguageServerName {
14079        self.name.clone()
14080    }
14081
14082    async fn initialization_options(
14083        self: Arc<Self>,
14084        _: &Arc<dyn LspAdapterDelegate>,
14085    ) -> Result<Option<serde_json::Value>> {
14086        let Some(options) = &self.initialization_options else {
14087            return Ok(None);
14088        };
14089        let result = serde_json::from_str(options)?;
14090        Ok(result)
14091    }
14092
14093    fn code_action_kinds(&self) -> Option<Vec<CodeActionKind>> {
14094        self.code_action_kinds.clone()
14095    }
14096}
14097
14098pub fn language_server_settings<'a>(
14099    delegate: &'a dyn LspAdapterDelegate,
14100    language: &LanguageServerName,
14101    cx: &'a App,
14102) -> Option<&'a LspSettings> {
14103    language_server_settings_for(
14104        SettingsLocation {
14105            worktree_id: delegate.worktree_id(),
14106            path: RelPath::empty(),
14107        },
14108        language,
14109        cx,
14110    )
14111}
14112
14113pub fn language_server_settings_for<'a>(
14114    location: SettingsLocation<'a>,
14115    language: &LanguageServerName,
14116    cx: &'a App,
14117) -> Option<&'a LspSettings> {
14118    ProjectSettings::get(Some(location), cx).lsp.get(language)
14119}
14120
14121pub struct LocalLspAdapterDelegate {
14122    lsp_store: WeakEntity<LspStore>,
14123    worktree: worktree::Snapshot,
14124    fs: Arc<dyn Fs>,
14125    http_client: Arc<dyn HttpClient>,
14126    language_registry: Arc<LanguageRegistry>,
14127    load_shell_env_task: Shared<Task<Option<HashMap<String, String>>>>,
14128}
14129
14130impl LocalLspAdapterDelegate {
14131    pub fn new(
14132        language_registry: Arc<LanguageRegistry>,
14133        environment: &Entity<ProjectEnvironment>,
14134        lsp_store: WeakEntity<LspStore>,
14135        worktree: &Entity<Worktree>,
14136        http_client: Arc<dyn HttpClient>,
14137        fs: Arc<dyn Fs>,
14138        cx: &mut App,
14139    ) -> Arc<Self> {
14140        let load_shell_env_task =
14141            environment.update(cx, |env, cx| env.worktree_environment(worktree.clone(), cx));
14142
14143        Arc::new(Self {
14144            lsp_store,
14145            worktree: worktree.read(cx).snapshot(),
14146            fs,
14147            http_client,
14148            language_registry,
14149            load_shell_env_task,
14150        })
14151    }
14152
14153    pub fn from_local_lsp(
14154        local: &LocalLspStore,
14155        worktree: &Entity<Worktree>,
14156        cx: &mut App,
14157    ) -> Arc<Self> {
14158        Self::new(
14159            local.languages.clone(),
14160            &local.environment,
14161            local.weak.clone(),
14162            worktree,
14163            local.http_client.clone(),
14164            local.fs.clone(),
14165            cx,
14166        )
14167    }
14168}
14169
14170#[async_trait]
14171impl LspAdapterDelegate for LocalLspAdapterDelegate {
14172    fn show_notification(&self, message: &str, cx: &mut App) {
14173        self.lsp_store
14174            .update(cx, |_, cx| {
14175                cx.emit(LspStoreEvent::Notification(message.to_owned()))
14176            })
14177            .ok();
14178    }
14179
14180    fn http_client(&self) -> Arc<dyn HttpClient> {
14181        self.http_client.clone()
14182    }
14183
14184    fn worktree_id(&self) -> WorktreeId {
14185        self.worktree.id()
14186    }
14187
14188    fn worktree_root_path(&self) -> &Path {
14189        self.worktree.abs_path().as_ref()
14190    }
14191
14192    fn resolve_executable_path(&self, path: PathBuf) -> PathBuf {
14193        self.worktree.resolve_executable_path(path)
14194    }
14195
14196    async fn shell_env(&self) -> HashMap<String, String> {
14197        let task = self.load_shell_env_task.clone();
14198        task.await.unwrap_or_default()
14199    }
14200
14201    async fn npm_package_installed_version(
14202        &self,
14203        package_name: &str,
14204    ) -> Result<Option<(PathBuf, Version)>> {
14205        let local_package_directory = self.worktree_root_path();
14206        let node_modules_directory = local_package_directory.join("node_modules");
14207
14208        if let Some(version) =
14209            read_package_installed_version(node_modules_directory.clone(), package_name).await?
14210        {
14211            return Ok(Some((node_modules_directory, version)));
14212        }
14213        let Some(npm) = self.which("npm".as_ref()).await else {
14214            log::warn!(
14215                "Failed to find npm executable for {:?}",
14216                local_package_directory
14217            );
14218            return Ok(None);
14219        };
14220
14221        let env = self.shell_env().await;
14222        let output = util::command::new_smol_command(&npm)
14223            .args(["root", "-g"])
14224            .envs(env)
14225            .current_dir(local_package_directory)
14226            .output()
14227            .await?;
14228        let global_node_modules =
14229            PathBuf::from(String::from_utf8_lossy(&output.stdout).to_string());
14230
14231        if let Some(version) =
14232            read_package_installed_version(global_node_modules.clone(), package_name).await?
14233        {
14234            return Ok(Some((global_node_modules, version)));
14235        }
14236        return Ok(None);
14237    }
14238
14239    async fn which(&self, command: &OsStr) -> Option<PathBuf> {
14240        let mut worktree_abs_path = self.worktree_root_path().to_path_buf();
14241        if self.fs.is_file(&worktree_abs_path).await {
14242            worktree_abs_path.pop();
14243        }
14244
14245        let env = self.shell_env().await;
14246
14247        let shell_path = env.get("PATH").cloned();
14248
14249        which::which_in(command, shell_path.as_ref(), worktree_abs_path).ok()
14250    }
14251
14252    async fn try_exec(&self, command: LanguageServerBinary) -> Result<()> {
14253        let mut working_dir = self.worktree_root_path().to_path_buf();
14254        if self.fs.is_file(&working_dir).await {
14255            working_dir.pop();
14256        }
14257        let output = util::command::new_smol_command(&command.path)
14258            .args(command.arguments)
14259            .envs(command.env.clone().unwrap_or_default())
14260            .current_dir(working_dir)
14261            .output()
14262            .await?;
14263
14264        anyhow::ensure!(
14265            output.status.success(),
14266            "{}, stdout: {:?}, stderr: {:?}",
14267            output.status,
14268            String::from_utf8_lossy(&output.stdout),
14269            String::from_utf8_lossy(&output.stderr)
14270        );
14271        Ok(())
14272    }
14273
14274    fn update_status(&self, server_name: LanguageServerName, status: language::BinaryStatus) {
14275        self.language_registry
14276            .update_lsp_binary_status(server_name, status);
14277    }
14278
14279    fn registered_lsp_adapters(&self) -> Vec<Arc<dyn LspAdapter>> {
14280        self.language_registry
14281            .all_lsp_adapters()
14282            .into_iter()
14283            .map(|adapter| adapter.adapter.clone() as Arc<dyn LspAdapter>)
14284            .collect()
14285    }
14286
14287    async fn language_server_download_dir(&self, name: &LanguageServerName) -> Option<Arc<Path>> {
14288        let dir = self.language_registry.language_server_download_dir(name)?;
14289
14290        if !dir.exists() {
14291            smol::fs::create_dir_all(&dir)
14292                .await
14293                .context("failed to create container directory")
14294                .log_err()?;
14295        }
14296
14297        Some(dir)
14298    }
14299
14300    async fn read_text_file(&self, path: &RelPath) -> Result<String> {
14301        let entry = self
14302            .worktree
14303            .entry_for_path(path)
14304            .with_context(|| format!("no worktree entry for path {path:?}"))?;
14305        let abs_path = self.worktree.absolutize(&entry.path);
14306        self.fs.load(&abs_path).await
14307    }
14308}
14309
14310async fn populate_labels_for_symbols(
14311    symbols: Vec<CoreSymbol>,
14312    language_registry: &Arc<LanguageRegistry>,
14313    lsp_adapter: Option<Arc<CachedLspAdapter>>,
14314    output: &mut Vec<Symbol>,
14315) {
14316    #[allow(clippy::mutable_key_type)]
14317    let mut symbols_by_language = HashMap::<Option<Arc<Language>>, Vec<CoreSymbol>>::default();
14318
14319    let mut unknown_paths = BTreeSet::<Arc<str>>::new();
14320    for symbol in symbols {
14321        let Some(file_name) = symbol.path.file_name() else {
14322            continue;
14323        };
14324        let language = language_registry
14325            .load_language_for_file_path(Path::new(file_name))
14326            .await
14327            .ok()
14328            .or_else(|| {
14329                unknown_paths.insert(file_name.into());
14330                None
14331            });
14332        symbols_by_language
14333            .entry(language)
14334            .or_default()
14335            .push(symbol);
14336    }
14337
14338    for unknown_path in unknown_paths {
14339        log::info!("no language found for symbol in file {unknown_path:?}");
14340    }
14341
14342    let mut label_params = Vec::new();
14343    for (language, mut symbols) in symbols_by_language {
14344        label_params.clear();
14345        label_params.extend(
14346            symbols
14347                .iter_mut()
14348                .map(|symbol| (mem::take(&mut symbol.name), symbol.kind)),
14349        );
14350
14351        let mut labels = Vec::new();
14352        if let Some(language) = language {
14353            let lsp_adapter = lsp_adapter.clone().or_else(|| {
14354                language_registry
14355                    .lsp_adapters(&language.name())
14356                    .first()
14357                    .cloned()
14358            });
14359            if let Some(lsp_adapter) = lsp_adapter {
14360                labels = lsp_adapter
14361                    .labels_for_symbols(&label_params, &language)
14362                    .await
14363                    .log_err()
14364                    .unwrap_or_default();
14365            }
14366        }
14367
14368        for ((symbol, (name, _)), label) in symbols
14369            .into_iter()
14370            .zip(label_params.drain(..))
14371            .zip(labels.into_iter().chain(iter::repeat(None)))
14372        {
14373            output.push(Symbol {
14374                language_server_name: symbol.language_server_name,
14375                source_worktree_id: symbol.source_worktree_id,
14376                source_language_server_id: symbol.source_language_server_id,
14377                path: symbol.path,
14378                label: label.unwrap_or_else(|| CodeLabel::plain(name.clone(), None)),
14379                name,
14380                kind: symbol.kind,
14381                range: symbol.range,
14382            });
14383        }
14384    }
14385}
14386
14387fn include_text(server: &lsp::LanguageServer) -> Option<bool> {
14388    match server.capabilities().text_document_sync.as_ref()? {
14389        lsp::TextDocumentSyncCapability::Options(opts) => match opts.save.as_ref()? {
14390            // Server wants didSave but didn't specify includeText.
14391            lsp::TextDocumentSyncSaveOptions::Supported(true) => Some(false),
14392            // Server doesn't want didSave at all.
14393            lsp::TextDocumentSyncSaveOptions::Supported(false) => None,
14394            // Server provided SaveOptions.
14395            lsp::TextDocumentSyncSaveOptions::SaveOptions(save_options) => {
14396                Some(save_options.include_text.unwrap_or(false))
14397            }
14398        },
14399        // We do not have any save info. Kind affects didChange only.
14400        lsp::TextDocumentSyncCapability::Kind(_) => None,
14401    }
14402}
14403
14404/// Completion items are displayed in a `UniformList`.
14405/// Usually, those items are single-line strings, but in LSP responses,
14406/// completion items `label`, `detail` and `label_details.description` may contain newlines or long spaces.
14407/// Many language plugins construct these items by joining these parts together, and we may use `CodeLabel::fallback_for_completion` that uses `label` at least.
14408/// 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,
14409/// breaking the completions menu presentation.
14410///
14411/// 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.
14412fn ensure_uniform_list_compatible_label(label: &mut CodeLabel) {
14413    let mut new_text = String::with_capacity(label.text.len());
14414    let mut offset_map = vec![0; label.text.len() + 1];
14415    let mut last_char_was_space = false;
14416    let mut new_idx = 0;
14417    let chars = label.text.char_indices().fuse();
14418    let mut newlines_removed = false;
14419
14420    for (idx, c) in chars {
14421        offset_map[idx] = new_idx;
14422
14423        match c {
14424            '\n' if last_char_was_space => {
14425                newlines_removed = true;
14426            }
14427            '\t' | ' ' if last_char_was_space => {}
14428            '\n' if !last_char_was_space => {
14429                new_text.push(' ');
14430                new_idx += 1;
14431                last_char_was_space = true;
14432                newlines_removed = true;
14433            }
14434            ' ' | '\t' => {
14435                new_text.push(' ');
14436                new_idx += 1;
14437                last_char_was_space = true;
14438            }
14439            _ => {
14440                new_text.push(c);
14441                new_idx += c.len_utf8();
14442                last_char_was_space = false;
14443            }
14444        }
14445    }
14446    offset_map[label.text.len()] = new_idx;
14447
14448    // Only modify the label if newlines were removed.
14449    if !newlines_removed {
14450        return;
14451    }
14452
14453    let last_index = new_idx;
14454    let mut run_ranges_errors = Vec::new();
14455    label.runs.retain_mut(|(range, _)| {
14456        match offset_map.get(range.start) {
14457            Some(&start) => range.start = start,
14458            None => {
14459                run_ranges_errors.push(range.clone());
14460                return false;
14461            }
14462        }
14463
14464        match offset_map.get(range.end) {
14465            Some(&end) => range.end = end,
14466            None => {
14467                run_ranges_errors.push(range.clone());
14468                range.end = last_index;
14469            }
14470        }
14471        true
14472    });
14473    if !run_ranges_errors.is_empty() {
14474        log::error!(
14475            "Completion label has errors in its run ranges: {run_ranges_errors:?}, label text: {}",
14476            label.text
14477        );
14478    }
14479
14480    let mut wrong_filter_range = None;
14481    if label.filter_range == (0..label.text.len()) {
14482        label.filter_range = 0..new_text.len();
14483    } else {
14484        let mut original_filter_range = Some(label.filter_range.clone());
14485        match offset_map.get(label.filter_range.start) {
14486            Some(&start) => label.filter_range.start = start,
14487            None => {
14488                wrong_filter_range = original_filter_range.take();
14489                label.filter_range.start = last_index;
14490            }
14491        }
14492
14493        match offset_map.get(label.filter_range.end) {
14494            Some(&end) => label.filter_range.end = end,
14495            None => {
14496                wrong_filter_range = original_filter_range.take();
14497                label.filter_range.end = last_index;
14498            }
14499        }
14500    }
14501    if let Some(wrong_filter_range) = wrong_filter_range {
14502        log::error!(
14503            "Completion label has an invalid filter range: {wrong_filter_range:?}, label text: {}",
14504            label.text
14505        );
14506    }
14507
14508    label.text = new_text;
14509}
14510
14511#[cfg(test)]
14512mod tests {
14513    use language::HighlightId;
14514
14515    use super::*;
14516
14517    #[test]
14518    fn test_glob_literal_prefix() {
14519        assert_eq!(glob_literal_prefix(Path::new("**/*.js")), Path::new(""));
14520        assert_eq!(
14521            glob_literal_prefix(Path::new("node_modules/**/*.js")),
14522            Path::new("node_modules")
14523        );
14524        assert_eq!(
14525            glob_literal_prefix(Path::new("foo/{bar,baz}.js")),
14526            Path::new("foo")
14527        );
14528        assert_eq!(
14529            glob_literal_prefix(Path::new("foo/bar/baz.js")),
14530            Path::new("foo/bar/baz.js")
14531        );
14532
14533        #[cfg(target_os = "windows")]
14534        {
14535            assert_eq!(glob_literal_prefix(Path::new("**\\*.js")), Path::new(""));
14536            assert_eq!(
14537                glob_literal_prefix(Path::new("node_modules\\**/*.js")),
14538                Path::new("node_modules")
14539            );
14540            assert_eq!(
14541                glob_literal_prefix(Path::new("foo/{bar,baz}.js")),
14542                Path::new("foo")
14543            );
14544            assert_eq!(
14545                glob_literal_prefix(Path::new("foo\\bar\\baz.js")),
14546                Path::new("foo/bar/baz.js")
14547            );
14548        }
14549    }
14550
14551    #[test]
14552    fn test_multi_len_chars_normalization() {
14553        let mut label = CodeLabel::new(
14554            "myElˇ (parameter) myElˇ: {\n    foo: string;\n}".to_string(),
14555            0..6,
14556            vec![(0..6, HighlightId(1))],
14557        );
14558        ensure_uniform_list_compatible_label(&mut label);
14559        assert_eq!(
14560            label,
14561            CodeLabel::new(
14562                "myElˇ (parameter) myElˇ: { foo: string; }".to_string(),
14563                0..6,
14564                vec![(0..6, HighlightId(1))],
14565            )
14566        );
14567    }
14568
14569    #[test]
14570    fn test_trailing_newline_in_completion_documentation() {
14571        let doc = lsp::Documentation::String(
14572            "Inappropriate argument value (of correct type).\n".to_string(),
14573        );
14574        let completion_doc: CompletionDocumentation = doc.into();
14575        assert!(
14576            matches!(completion_doc, CompletionDocumentation::SingleLine(s) if s == "Inappropriate argument value (of correct type).")
14577        );
14578
14579        let doc = lsp::Documentation::String("  some value  \n".to_string());
14580        let completion_doc: CompletionDocumentation = doc.into();
14581        assert!(matches!(
14582            completion_doc,
14583            CompletionDocumentation::SingleLine(s) if s == "some value"
14584        ));
14585    }
14586}