lsp_store.rs

    1//! LSP store provides unified access to the language server protocol.
    2//! The consumers of LSP store can interact with language servers without knowing exactly which language server they're interacting with.
    3//!
    4//! # Local/Remote LSP Stores
    5//! This module is split up into three distinct parts:
    6//! - [`LocalLspStore`], which is ran on the host machine (either project host or SSH host), that manages the lifecycle of language servers.
    7//! - [`RemoteLspStore`], which is ran on the remote machine (project guests) which is mostly about passing through the requests via RPC.
    8//!   The remote stores don't really care about which language server they're running against - they don't usually get to decide which language server is going to responsible for handling their request.
    9//! - [`LspStore`], which unifies the two under one consistent interface for interacting with language servers.
   10//!
   11//! Most of the interesting work happens at the local layer, as bulk of the complexity is with managing the lifecycle of language servers. The actual implementation of the LSP protocol is handled by [`lsp`] crate.
   12pub mod clangd_ext;
   13pub mod json_language_server_ext;
   14pub mod log_store;
   15pub mod lsp_ext_command;
   16pub mod rust_analyzer_ext;
   17pub mod vue_language_server_ext;
   18
   19mod inlay_hint_cache;
   20
   21use self::inlay_hint_cache::BufferInlayHints;
   22use crate::{
   23    CodeAction, ColorPresentation, Completion, CompletionDisplayOptions, CompletionResponse,
   24    CompletionSource, CoreCompletion, DocumentColor, Hover, InlayHint, InlayId, LocationLink,
   25    LspAction, LspPullDiagnostics, ManifestProvidersStore, Project, ProjectItem, ProjectPath,
   26    ProjectTransaction, PulledDiagnostics, ResolveState, Symbol,
   27    buffer_store::{BufferStore, BufferStoreEvent},
   28    environment::ProjectEnvironment,
   29    lsp_command::{self, *},
   30    lsp_store::{
   31        self,
   32        log_store::{GlobalLogStore, LanguageServerKind},
   33    },
   34    manifest_tree::{
   35        LanguageServerTree, LanguageServerTreeNode, LaunchDisposition, ManifestQueryDelegate,
   36        ManifestTree,
   37    },
   38    prettier_store::{self, PrettierStore, PrettierStoreEvent},
   39    project_settings::{LspSettings, ProjectSettings},
   40    toolchain_store::{LocalToolchainStore, ToolchainStoreEvent},
   41    trusted_worktrees::{PathTrust, TrustedWorktrees, TrustedWorktreesEvent},
   42    worktree_store::{WorktreeStore, WorktreeStoreEvent},
   43    yarn::YarnPathStore,
   44};
   45use anyhow::{Context as _, Result, anyhow};
   46use async_trait::async_trait;
   47use client::{TypedEnvelope, proto};
   48use clock::Global;
   49use collections::{BTreeMap, BTreeSet, HashMap, HashSet, btree_map};
   50use futures::{
   51    AsyncWriteExt, Future, FutureExt, StreamExt,
   52    future::{Either, Shared, join_all, pending, select},
   53    select, select_biased,
   54    stream::FuturesUnordered,
   55};
   56use globset::{Glob, GlobBuilder, GlobMatcher, GlobSet, GlobSetBuilder};
   57use gpui::{
   58    App, AppContext, AsyncApp, Context, Entity, EventEmitter, PromptLevel, SharedString,
   59    Subscription, Task, WeakEntity,
   60};
   61use http_client::HttpClient;
   62use itertools::Itertools as _;
   63use language::{
   64    Bias, BinaryStatus, Buffer, BufferRow, BufferSnapshot, CachedLspAdapter, CodeLabel, Diagnostic,
   65    DiagnosticEntry, DiagnosticSet, DiagnosticSourceKind, Diff, File as _, Language, LanguageName,
   66    LanguageRegistry, LocalFile, LspAdapter, LspAdapterDelegate, LspInstaller, ManifestDelegate,
   67    ManifestName, Patch, PointUtf16, TextBufferSnapshot, ToOffset, ToPointUtf16, Toolchain,
   68    Transaction, Unclipped,
   69    language_settings::{FormatOnSave, Formatter, LanguageSettings, language_settings},
   70    point_to_lsp,
   71    proto::{
   72        deserialize_anchor, deserialize_lsp_edit, deserialize_version, serialize_anchor,
   73        serialize_lsp_edit, serialize_version,
   74    },
   75    range_from_lsp, range_to_lsp,
   76    row_chunk::RowChunk,
   77};
   78use lsp::{
   79    AdapterServerCapabilities, CodeActionKind, CompletionContext, CompletionOptions,
   80    DiagnosticServerCapabilities, DiagnosticSeverity, DiagnosticTag,
   81    DidChangeWatchedFilesRegistrationOptions, Edit, FileOperationFilter, FileOperationPatternKind,
   82    FileOperationRegistrationOptions, FileRename, FileSystemWatcher, LSP_REQUEST_TIMEOUT,
   83    LanguageServer, LanguageServerBinary, LanguageServerBinaryOptions, LanguageServerId,
   84    LanguageServerName, LanguageServerSelector, LspRequestFuture, MessageActionItem, MessageType,
   85    OneOf, RenameFilesParams, SymbolKind, TextDocumentSyncSaveOptions, TextEdit, Uri,
   86    WillRenameFiles, WorkDoneProgressCancelParams, WorkspaceFolder, notification::DidRenameFiles,
   87};
   88use node_runtime::read_package_installed_version;
   89use parking_lot::Mutex;
   90use postage::{mpsc, sink::Sink, stream::Stream, watch};
   91use rand::prelude::*;
   92use rpc::{
   93    AnyProtoClient, ErrorCode, ErrorExt as _,
   94    proto::{LspRequestId, LspRequestMessage as _},
   95};
   96use serde::Serialize;
   97use serde_json::Value;
   98use settings::{Settings, SettingsLocation, SettingsStore};
   99use sha2::{Digest, Sha256};
  100use smol::channel::{Receiver, Sender};
  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    rel_path::RelPath,
  131};
  132
  133pub use fs::*;
  134pub use language::Location;
  135pub use lsp_store::inlay_hint_cache::{CacheInlayHints, InvalidationStrategy};
  136#[cfg(any(test, feature = "test-support"))]
  137pub use prettier::FORMAT_SUFFIX as TEST_PRETTIER_FORMAT_SUFFIX;
  138pub use worktree::{
  139    Entry, EntryKind, FS_WATCH_LATENCY, File, LocalWorktree, PathChange, ProjectEntryId,
  140    UpdatedEntriesSet, UpdatedGitRepositoriesSet, Worktree, WorktreeId, WorktreeSettings,
  141};
  142
  143const SERVER_LAUNCHING_BEFORE_SHUTDOWN_TIMEOUT: Duration = Duration::from_secs(5);
  144pub const SERVER_PROGRESS_THROTTLE_TIMEOUT: Duration = Duration::from_millis(100);
  145const WORKSPACE_DIAGNOSTICS_TOKEN_START: &str = "id:";
  146const SERVER_DOWNLOAD_TIMEOUT: Duration = Duration::from_secs(10);
  147
  148#[derive(Debug, Clone, PartialEq, Eq, PartialOrd, Ord, Hash, Serialize)]
  149pub enum ProgressToken {
  150    Number(i32),
  151    String(SharedString),
  152}
  153
  154impl std::fmt::Display for ProgressToken {
  155    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
  156        match self {
  157            Self::Number(number) => write!(f, "{number}"),
  158            Self::String(string) => write!(f, "{string}"),
  159        }
  160    }
  161}
  162
  163impl ProgressToken {
  164    fn from_lsp(value: lsp::NumberOrString) -> Self {
  165        match value {
  166            lsp::NumberOrString::Number(number) => Self::Number(number),
  167            lsp::NumberOrString::String(string) => Self::String(SharedString::new(string)),
  168        }
  169    }
  170
  171    fn to_lsp(&self) -> lsp::NumberOrString {
  172        match self {
  173            Self::Number(number) => lsp::NumberOrString::Number(*number),
  174            Self::String(string) => lsp::NumberOrString::String(string.to_string()),
  175        }
  176    }
  177
  178    fn from_proto(value: proto::ProgressToken) -> Option<Self> {
  179        Some(match value.value? {
  180            proto::progress_token::Value::Number(number) => Self::Number(number),
  181            proto::progress_token::Value::String(string) => Self::String(SharedString::new(string)),
  182        })
  183    }
  184
  185    fn to_proto(&self) -> proto::ProgressToken {
  186        proto::ProgressToken {
  187            value: Some(match self {
  188                Self::Number(number) => proto::progress_token::Value::Number(*number),
  189                Self::String(string) => proto::progress_token::Value::String(string.to_string()),
  190            }),
  191        }
  192    }
  193}
  194
  195#[derive(Debug, Clone, Copy, PartialEq, Eq)]
  196pub enum FormatTrigger {
  197    Save,
  198    Manual,
  199}
  200
  201pub enum LspFormatTarget {
  202    Buffers,
  203    Ranges(BTreeMap<BufferId, Vec<Range<Anchor>>>),
  204}
  205
  206#[derive(Clone, PartialEq, Eq, Hash)]
  207pub struct OpenLspBufferHandle(Entity<OpenLspBuffer>);
  208
  209struct OpenLspBuffer(Entity<Buffer>);
  210
  211impl FormatTrigger {
  212    fn from_proto(value: i32) -> FormatTrigger {
  213        match value {
  214            0 => FormatTrigger::Save,
  215            1 => FormatTrigger::Manual,
  216            _ => FormatTrigger::Save,
  217        }
  218    }
  219}
  220
  221#[derive(Clone)]
  222struct UnifiedLanguageServer {
  223    id: LanguageServerId,
  224    project_roots: HashSet<Arc<RelPath>>,
  225}
  226
  227#[derive(Clone, Debug, Hash, PartialEq, Eq)]
  228struct LanguageServerSeed {
  229    worktree_id: WorktreeId,
  230    name: LanguageServerName,
  231    toolchain: Option<Toolchain>,
  232    settings: Arc<LspSettings>,
  233}
  234
  235#[derive(Debug)]
  236pub struct DocumentDiagnosticsUpdate<'a, D> {
  237    pub diagnostics: D,
  238    pub result_id: Option<SharedString>,
  239    pub registration_id: Option<SharedString>,
  240    pub server_id: LanguageServerId,
  241    pub disk_based_sources: Cow<'a, [String]>,
  242}
  243
  244pub struct DocumentDiagnostics {
  245    diagnostics: Vec<DiagnosticEntry<Unclipped<PointUtf16>>>,
  246    document_abs_path: PathBuf,
  247    version: Option<i32>,
  248}
  249
  250#[derive(Default, Debug)]
  251struct DynamicRegistrations {
  252    did_change_watched_files: HashMap<String, Vec<FileSystemWatcher>>,
  253    diagnostics: HashMap<Option<String>, DiagnosticServerCapabilities>,
  254}
  255
  256pub struct LocalLspStore {
  257    weak: WeakEntity<LspStore>,
  258    worktree_store: Entity<WorktreeStore>,
  259    toolchain_store: Entity<LocalToolchainStore>,
  260    http_client: Arc<dyn HttpClient>,
  261    environment: Entity<ProjectEnvironment>,
  262    fs: Arc<dyn Fs>,
  263    languages: Arc<LanguageRegistry>,
  264    language_server_ids: HashMap<LanguageServerSeed, UnifiedLanguageServer>,
  265    yarn: Entity<YarnPathStore>,
  266    pub language_servers: HashMap<LanguageServerId, LanguageServerState>,
  267    buffers_being_formatted: HashSet<BufferId>,
  268    last_workspace_edits_by_language_server: HashMap<LanguageServerId, ProjectTransaction>,
  269    language_server_watched_paths: HashMap<LanguageServerId, LanguageServerWatchedPaths>,
  270    watched_manifest_filenames: HashSet<ManifestName>,
  271    language_server_paths_watched_for_rename:
  272        HashMap<LanguageServerId, RenamePathsWatchedForServer>,
  273    language_server_dynamic_registrations: HashMap<LanguageServerId, DynamicRegistrations>,
  274    supplementary_language_servers:
  275        HashMap<LanguageServerId, (LanguageServerName, Arc<LanguageServer>)>,
  276    prettier_store: Entity<PrettierStore>,
  277    next_diagnostic_group_id: usize,
  278    diagnostics: HashMap<
  279        WorktreeId,
  280        HashMap<
  281            Arc<RelPath>,
  282            Vec<(
  283                LanguageServerId,
  284                Vec<DiagnosticEntry<Unclipped<PointUtf16>>>,
  285            )>,
  286        >,
  287    >,
  288    buffer_snapshots: HashMap<BufferId, HashMap<LanguageServerId, Vec<LspBufferSnapshot>>>, // buffer_id -> server_id -> vec of snapshots
  289    _subscription: gpui::Subscription,
  290    lsp_tree: LanguageServerTree,
  291    registered_buffers: HashMap<BufferId, usize>,
  292    buffers_opened_in_servers: HashMap<BufferId, HashSet<LanguageServerId>>,
  293    buffer_pull_diagnostics_result_ids: HashMap<
  294        LanguageServerId,
  295        HashMap<Option<SharedString>, HashMap<PathBuf, Option<SharedString>>>,
  296    >,
  297    workspace_pull_diagnostics_result_ids: HashMap<
  298        LanguageServerId,
  299        HashMap<Option<SharedString>, HashMap<PathBuf, Option<SharedString>>>,
  300    >,
  301    restricted_worktrees_tasks: HashMap<WorktreeId, (Subscription, Receiver<()>)>,
  302}
  303
  304impl LocalLspStore {
  305    /// Returns the running language server for the given ID. Note if the language server is starting, it will not be returned.
  306    pub fn running_language_server_for_id(
  307        &self,
  308        id: LanguageServerId,
  309    ) -> Option<&Arc<LanguageServer>> {
  310        let language_server_state = self.language_servers.get(&id)?;
  311
  312        match language_server_state {
  313            LanguageServerState::Running { server, .. } => Some(server),
  314            LanguageServerState::Starting { .. } => None,
  315        }
  316    }
  317
  318    fn get_or_insert_language_server(
  319        &mut self,
  320        worktree_handle: &Entity<Worktree>,
  321        delegate: Arc<LocalLspAdapterDelegate>,
  322        disposition: &Arc<LaunchDisposition>,
  323        language_name: &LanguageName,
  324        cx: &mut App,
  325    ) -> LanguageServerId {
  326        let key = LanguageServerSeed {
  327            worktree_id: worktree_handle.read(cx).id(),
  328            name: disposition.server_name.clone(),
  329            settings: disposition.settings.clone(),
  330            toolchain: disposition.toolchain.clone(),
  331        };
  332        if let Some(state) = self.language_server_ids.get_mut(&key) {
  333            state.project_roots.insert(disposition.path.path.clone());
  334            state.id
  335        } else {
  336            let adapter = self
  337                .languages
  338                .lsp_adapters(language_name)
  339                .into_iter()
  340                .find(|adapter| adapter.name() == disposition.server_name)
  341                .expect("To find LSP adapter");
  342            let new_language_server_id = self.start_language_server(
  343                worktree_handle,
  344                delegate,
  345                adapter,
  346                disposition.settings.clone(),
  347                key.clone(),
  348                cx,
  349            );
  350            if let Some(state) = self.language_server_ids.get_mut(&key) {
  351                state.project_roots.insert(disposition.path.path.clone());
  352            } else {
  353                debug_assert!(
  354                    false,
  355                    "Expected `start_language_server` to ensure that `key` exists in a map"
  356                );
  357            }
  358            new_language_server_id
  359        }
  360    }
  361
  362    fn start_language_server(
  363        &mut self,
  364        worktree_handle: &Entity<Worktree>,
  365        delegate: Arc<LocalLspAdapterDelegate>,
  366        adapter: Arc<CachedLspAdapter>,
  367        settings: Arc<LspSettings>,
  368        key: LanguageServerSeed,
  369        cx: &mut App,
  370    ) -> LanguageServerId {
  371        let worktree = worktree_handle.read(cx);
  372
  373        let worktree_id = worktree.id();
  374        let worktree_abs_path = worktree.abs_path();
  375        let toolchain = key.toolchain.clone();
  376        let override_options = settings.initialization_options.clone();
  377
  378        let stderr_capture = Arc::new(Mutex::new(Some(String::new())));
  379
  380        let server_id = self.languages.next_language_server_id();
  381        log::trace!(
  382            "attempting to start language server {:?}, path: {worktree_abs_path:?}, id: {server_id}",
  383            adapter.name.0
  384        );
  385
  386        let untrusted_worktree_task =
  387            TrustedWorktrees::try_get_global(cx).and_then(|trusted_worktrees| {
  388                let can_trust = trusted_worktrees.update(cx, |trusted_worktrees, cx| {
  389                    trusted_worktrees.can_trust(&self.worktree_store, worktree_id, cx)
  390                });
  391                if can_trust {
  392                    self.restricted_worktrees_tasks.remove(&worktree_id);
  393                    None
  394                } else {
  395                    match self.restricted_worktrees_tasks.entry(worktree_id) {
  396                        hash_map::Entry::Occupied(o) => Some(o.get().1.clone()),
  397                        hash_map::Entry::Vacant(v) => {
  398                            let (tx, rx) = smol::channel::bounded::<()>(1);
  399                            let subscription = cx.subscribe(&trusted_worktrees, move |_, e, _| {
  400                                if let TrustedWorktreesEvent::Trusted(_, trusted_paths) = e {
  401                                    if trusted_paths.contains(&PathTrust::Worktree(worktree_id)) {
  402                                        tx.send_blocking(()).ok();
  403                                    }
  404                                }
  405                            });
  406                            v.insert((subscription, rx.clone()));
  407                            Some(rx)
  408                        }
  409                    }
  410                }
  411            });
  412        let update_binary_status = untrusted_worktree_task.is_none();
  413
  414        let binary = self.get_language_server_binary(
  415            worktree_abs_path.clone(),
  416            adapter.clone(),
  417            settings,
  418            toolchain.clone(),
  419            delegate.clone(),
  420            true,
  421            untrusted_worktree_task,
  422            cx,
  423        );
  424        let pending_workspace_folders = Arc::<Mutex<BTreeSet<Uri>>>::default();
  425
  426        let pending_server = cx.spawn({
  427            let adapter = adapter.clone();
  428            let server_name = adapter.name.clone();
  429            let stderr_capture = stderr_capture.clone();
  430            #[cfg(any(test, feature = "test-support"))]
  431            let lsp_store = self.weak.clone();
  432            let pending_workspace_folders = pending_workspace_folders.clone();
  433            async move |cx| {
  434                let binary = binary.await?;
  435                #[cfg(any(test, feature = "test-support"))]
  436                if let Some(server) = lsp_store
  437                    .update(&mut cx.clone(), |this, cx| {
  438                        this.languages.create_fake_language_server(
  439                            server_id,
  440                            &server_name,
  441                            binary.clone(),
  442                            &mut cx.to_async(),
  443                        )
  444                    })
  445                    .ok()
  446                    .flatten()
  447                {
  448                    return Ok(server);
  449                }
  450
  451                let code_action_kinds = adapter.code_action_kinds();
  452                lsp::LanguageServer::new(
  453                    stderr_capture,
  454                    server_id,
  455                    server_name,
  456                    binary,
  457                    &worktree_abs_path,
  458                    code_action_kinds,
  459                    Some(pending_workspace_folders),
  460                    cx,
  461                )
  462            }
  463        });
  464
  465        let startup = {
  466            let server_name = adapter.name.0.clone();
  467            let delegate = delegate as Arc<dyn LspAdapterDelegate>;
  468            let key = key.clone();
  469            let adapter = adapter.clone();
  470            let lsp_store = self.weak.clone();
  471            let pending_workspace_folders = pending_workspace_folders.clone();
  472
  473            let pull_diagnostics = ProjectSettings::get_global(cx)
  474                .diagnostics
  475                .lsp_pull_diagnostics
  476                .enabled;
  477            cx.spawn(async move |cx| {
  478                let result = async {
  479                    let language_server = pending_server.await?;
  480
  481                    let workspace_config = Self::workspace_configuration_for_adapter(
  482                        adapter.adapter.clone(),
  483                        &delegate,
  484                        toolchain,
  485                        None,
  486                        cx,
  487                    )
  488                    .await?;
  489
  490                    let mut initialization_options = Self::initialization_options_for_adapter(
  491                        adapter.adapter.clone(),
  492                        &delegate,
  493                    )
  494                    .await?;
  495
  496                    match (&mut initialization_options, override_options) {
  497                        (Some(initialization_options), Some(override_options)) => {
  498                            merge_json_value_into(override_options, initialization_options);
  499                        }
  500                        (None, override_options) => initialization_options = override_options,
  501                        _ => {}
  502                    }
  503
  504                    let initialization_params = cx.update(|cx| {
  505                        let mut params =
  506                            language_server.default_initialize_params(pull_diagnostics, cx);
  507                        params.initialization_options = initialization_options;
  508                        adapter.adapter.prepare_initialize_params(params, cx)
  509                    })??;
  510
  511                    Self::setup_lsp_messages(
  512                        lsp_store.clone(),
  513                        &language_server,
  514                        delegate.clone(),
  515                        adapter.clone(),
  516                    );
  517
  518                    let did_change_configuration_params = lsp::DidChangeConfigurationParams {
  519                        settings: workspace_config,
  520                    };
  521                    let language_server = cx
  522                        .update(|cx| {
  523                            language_server.initialize(
  524                                initialization_params,
  525                                Arc::new(did_change_configuration_params.clone()),
  526                                cx,
  527                            )
  528                        })?
  529                        .await
  530                        .inspect_err(|_| {
  531                            if let Some(lsp_store) = lsp_store.upgrade() {
  532                                lsp_store
  533                                    .update(cx, |lsp_store, cx| {
  534                                        lsp_store.cleanup_lsp_data(server_id);
  535                                        cx.emit(LspStoreEvent::LanguageServerRemoved(server_id))
  536                                    })
  537                                    .ok();
  538                            }
  539                        })?;
  540
  541                    language_server.notify::<lsp::notification::DidChangeConfiguration>(
  542                        did_change_configuration_params,
  543                    )?;
  544
  545                    anyhow::Ok(language_server)
  546                }
  547                .await;
  548
  549                match result {
  550                    Ok(server) => {
  551                        lsp_store
  552                            .update(cx, |lsp_store, cx| {
  553                                lsp_store.insert_newly_running_language_server(
  554                                    adapter,
  555                                    server.clone(),
  556                                    server_id,
  557                                    key,
  558                                    pending_workspace_folders,
  559                                    cx,
  560                                );
  561                            })
  562                            .ok();
  563                        stderr_capture.lock().take();
  564                        Some(server)
  565                    }
  566
  567                    Err(err) => {
  568                        let log = stderr_capture.lock().take().unwrap_or_default();
  569                        delegate.update_status(
  570                            adapter.name(),
  571                            BinaryStatus::Failed {
  572                                error: if log.is_empty() {
  573                                    format!("{err:#}")
  574                                } else {
  575                                    format!("{err:#}\n-- stderr --\n{log}")
  576                                },
  577                            },
  578                        );
  579                        log::error!("Failed to start language server {server_name:?}: {err:?}");
  580                        if !log.is_empty() {
  581                            log::error!("server stderr: {log}");
  582                        }
  583                        None
  584                    }
  585                }
  586            })
  587        };
  588        let state = LanguageServerState::Starting {
  589            startup,
  590            pending_workspace_folders,
  591        };
  592
  593        if update_binary_status {
  594            self.languages
  595                .update_lsp_binary_status(adapter.name(), BinaryStatus::Starting);
  596        }
  597
  598        self.language_servers.insert(server_id, state);
  599        self.language_server_ids
  600            .entry(key)
  601            .or_insert(UnifiedLanguageServer {
  602                id: server_id,
  603                project_roots: Default::default(),
  604            });
  605        server_id
  606    }
  607
  608    fn get_language_server_binary(
  609        &self,
  610        worktree_abs_path: Arc<Path>,
  611        adapter: Arc<CachedLspAdapter>,
  612        settings: Arc<LspSettings>,
  613        toolchain: Option<Toolchain>,
  614        delegate: Arc<dyn LspAdapterDelegate>,
  615        allow_binary_download: bool,
  616        untrusted_worktree_task: Option<Receiver<()>>,
  617        cx: &mut App,
  618    ) -> Task<Result<LanguageServerBinary>> {
  619        if let Some(settings) = &settings.binary
  620            && let Some(path) = settings.path.as_ref().map(PathBuf::from)
  621        {
  622            let settings = settings.clone();
  623            let languages = self.languages.clone();
  624            return cx.background_spawn(async move {
  625                if let Some(untrusted_worktree_task) = untrusted_worktree_task {
  626                    log::info!(
  627                        "Waiting for worktree {worktree_abs_path:?} to be trusted, before starting language server {}",
  628                        adapter.name(),
  629                    );
  630                    untrusted_worktree_task.recv().await.ok();
  631                    log::info!(
  632                        "Worktree {worktree_abs_path:?} is trusted, starting language server {}",
  633                        adapter.name(),
  634                    );
  635                    languages
  636                        .update_lsp_binary_status(adapter.name(), BinaryStatus::Starting);
  637                }
  638                let mut env = delegate.shell_env().await;
  639                env.extend(settings.env.unwrap_or_default());
  640
  641                Ok(LanguageServerBinary {
  642                    path: delegate.resolve_executable_path(path),
  643                    env: Some(env),
  644                    arguments: settings
  645                        .arguments
  646                        .unwrap_or_default()
  647                        .iter()
  648                        .map(Into::into)
  649                        .collect(),
  650                })
  651            });
  652        }
  653        let lsp_binary_options = LanguageServerBinaryOptions {
  654            allow_path_lookup: !settings
  655                .binary
  656                .as_ref()
  657                .and_then(|b| b.ignore_system_version)
  658                .unwrap_or_default(),
  659            allow_binary_download,
  660            pre_release: settings
  661                .fetch
  662                .as_ref()
  663                .and_then(|f| f.pre_release)
  664                .unwrap_or(false),
  665        };
  666
  667        cx.spawn(async move |cx| {
  668            if let Some(untrusted_worktree_task) = untrusted_worktree_task {
  669                log::info!(
  670                    "Waiting for worktree {worktree_abs_path:?} to be trusted, before starting language server {}",
  671                    adapter.name(),
  672                );
  673                untrusted_worktree_task.recv().await.ok();
  674                log::info!(
  675                    "Worktree {worktree_abs_path:?} is trusted, starting language server {}",
  676                    adapter.name(),
  677                );
  678            }
  679
  680            let (existing_binary, maybe_download_binary) = adapter
  681                .clone()
  682                .get_language_server_command(delegate.clone(), toolchain, lsp_binary_options, cx)
  683                .await
  684                .await;
  685
  686            delegate.update_status(adapter.name.clone(), BinaryStatus::None);
  687
  688            let mut binary = match (existing_binary, maybe_download_binary) {
  689                (binary, None) => binary?,
  690                (Err(_), Some(downloader)) => downloader.await?,
  691                (Ok(existing_binary), Some(downloader)) => {
  692                    let mut download_timeout = cx
  693                        .background_executor()
  694                        .timer(SERVER_DOWNLOAD_TIMEOUT)
  695                        .fuse();
  696                    let mut downloader = downloader.fuse();
  697                    futures::select! {
  698                        _ = download_timeout => {
  699                            // Return existing binary and kick the existing work to the background.
  700                            cx.spawn(async move |_| downloader.await).detach();
  701                            Ok(existing_binary)
  702                        },
  703                        downloaded_or_existing_binary = downloader => {
  704                            // If download fails, this results in the existing binary.
  705                            downloaded_or_existing_binary
  706                        }
  707                    }?
  708                }
  709            };
  710            let mut shell_env = delegate.shell_env().await;
  711
  712            shell_env.extend(binary.env.unwrap_or_default());
  713
  714            if let Some(settings) = settings.binary.as_ref() {
  715                if let Some(arguments) = &settings.arguments {
  716                    binary.arguments = arguments.iter().map(Into::into).collect();
  717                }
  718                if let Some(env) = &settings.env {
  719                    shell_env.extend(env.iter().map(|(k, v)| (k.clone(), v.clone())));
  720                }
  721            }
  722
  723            binary.env = Some(shell_env);
  724            Ok(binary)
  725        })
  726    }
  727
  728    fn setup_lsp_messages(
  729        lsp_store: WeakEntity<LspStore>,
  730        language_server: &LanguageServer,
  731        delegate: Arc<dyn LspAdapterDelegate>,
  732        adapter: Arc<CachedLspAdapter>,
  733    ) {
  734        let name = language_server.name();
  735        let server_id = language_server.server_id();
  736        language_server
  737            .on_notification::<lsp::notification::PublishDiagnostics, _>({
  738                let adapter = adapter.clone();
  739                let this = lsp_store.clone();
  740                move |mut params, cx| {
  741                    let adapter = adapter.clone();
  742                    if let Some(this) = this.upgrade() {
  743                        this.update(cx, |this, cx| {
  744                            {
  745                                let buffer = params
  746                                    .uri
  747                                    .to_file_path()
  748                                    .map(|file_path| this.get_buffer(&file_path, cx))
  749                                    .ok()
  750                                    .flatten();
  751                                adapter.process_diagnostics(&mut params, server_id, buffer);
  752                            }
  753
  754                            this.merge_lsp_diagnostics(
  755                                DiagnosticSourceKind::Pushed,
  756                                vec![DocumentDiagnosticsUpdate {
  757                                    server_id,
  758                                    diagnostics: params,
  759                                    result_id: None,
  760                                    disk_based_sources: Cow::Borrowed(
  761                                        &adapter.disk_based_diagnostic_sources,
  762                                    ),
  763                                    registration_id: None,
  764                                }],
  765                                |_, diagnostic, cx| match diagnostic.source_kind {
  766                                    DiagnosticSourceKind::Other | DiagnosticSourceKind::Pushed => {
  767                                        adapter.retain_old_diagnostic(diagnostic, cx)
  768                                    }
  769                                    DiagnosticSourceKind::Pulled => true,
  770                                },
  771                                cx,
  772                            )
  773                            .log_err();
  774                        })
  775                        .ok();
  776                    }
  777                }
  778            })
  779            .detach();
  780        language_server
  781            .on_request::<lsp::request::WorkspaceConfiguration, _, _>({
  782                let adapter = adapter.adapter.clone();
  783                let delegate = delegate.clone();
  784                let this = lsp_store.clone();
  785                move |params, cx| {
  786                    let adapter = adapter.clone();
  787                    let delegate = delegate.clone();
  788                    let this = this.clone();
  789                    let mut cx = cx.clone();
  790                    async move {
  791                        let toolchain_for_id = this
  792                            .update(&mut cx, |this, _| {
  793                                this.as_local()?.language_server_ids.iter().find_map(
  794                                    |(seed, value)| {
  795                                        (value.id == server_id).then(|| seed.toolchain.clone())
  796                                    },
  797                                )
  798                            })?
  799                            .context("Expected the LSP store to be in a local mode")?;
  800
  801                        let mut scope_uri_to_workspace_config = BTreeMap::new();
  802                        for item in &params.items {
  803                            let scope_uri = item.scope_uri.clone();
  804                            let std::collections::btree_map::Entry::Vacant(new_scope_uri) =
  805                                scope_uri_to_workspace_config.entry(scope_uri.clone())
  806                            else {
  807                                // We've already queried workspace configuration of this URI.
  808                                continue;
  809                            };
  810                            let workspace_config = Self::workspace_configuration_for_adapter(
  811                                adapter.clone(),
  812                                &delegate,
  813                                toolchain_for_id.clone(),
  814                                scope_uri,
  815                                &mut cx,
  816                            )
  817                            .await?;
  818                            new_scope_uri.insert(workspace_config);
  819                        }
  820
  821                        Ok(params
  822                            .items
  823                            .into_iter()
  824                            .filter_map(|item| {
  825                                let workspace_config =
  826                                    scope_uri_to_workspace_config.get(&item.scope_uri)?;
  827                                if let Some(section) = &item.section {
  828                                    Some(
  829                                        workspace_config
  830                                            .get(section)
  831                                            .cloned()
  832                                            .unwrap_or(serde_json::Value::Null),
  833                                    )
  834                                } else {
  835                                    Some(workspace_config.clone())
  836                                }
  837                            })
  838                            .collect())
  839                    }
  840                }
  841            })
  842            .detach();
  843
  844        language_server
  845            .on_request::<lsp::request::WorkspaceFoldersRequest, _, _>({
  846                let this = lsp_store.clone();
  847                move |_, cx| {
  848                    let this = this.clone();
  849                    let cx = cx.clone();
  850                    async move {
  851                        let Some(server) =
  852                            this.read_with(&cx, |this, _| this.language_server_for_id(server_id))?
  853                        else {
  854                            return Ok(None);
  855                        };
  856                        let root = server.workspace_folders();
  857                        Ok(Some(
  858                            root.into_iter()
  859                                .map(|uri| WorkspaceFolder {
  860                                    uri,
  861                                    name: Default::default(),
  862                                })
  863                                .collect(),
  864                        ))
  865                    }
  866                }
  867            })
  868            .detach();
  869        // Even though we don't have handling for these requests, respond to them to
  870        // avoid stalling any language server like `gopls` which waits for a response
  871        // to these requests when initializing.
  872        language_server
  873            .on_request::<lsp::request::WorkDoneProgressCreate, _, _>({
  874                let this = lsp_store.clone();
  875                move |params, cx| {
  876                    let this = this.clone();
  877                    let mut cx = cx.clone();
  878                    async move {
  879                        this.update(&mut cx, |this, _| {
  880                            if let Some(status) = this.language_server_statuses.get_mut(&server_id)
  881                            {
  882                                status
  883                                    .progress_tokens
  884                                    .insert(ProgressToken::from_lsp(params.token));
  885                            }
  886                        })?;
  887
  888                        Ok(())
  889                    }
  890                }
  891            })
  892            .detach();
  893
  894        language_server
  895            .on_request::<lsp::request::RegisterCapability, _, _>({
  896                let lsp_store = lsp_store.clone();
  897                move |params, cx| {
  898                    let lsp_store = lsp_store.clone();
  899                    let mut cx = cx.clone();
  900                    async move {
  901                        lsp_store
  902                            .update(&mut cx, |lsp_store, cx| {
  903                                if lsp_store.as_local().is_some() {
  904                                    match lsp_store
  905                                        .register_server_capabilities(server_id, params, cx)
  906                                    {
  907                                        Ok(()) => {}
  908                                        Err(e) => {
  909                                            log::error!(
  910                                                "Failed to register server capabilities: {e:#}"
  911                                            );
  912                                        }
  913                                    };
  914                                }
  915                            })
  916                            .ok();
  917                        Ok(())
  918                    }
  919                }
  920            })
  921            .detach();
  922
  923        language_server
  924            .on_request::<lsp::request::UnregisterCapability, _, _>({
  925                let lsp_store = lsp_store.clone();
  926                move |params, cx| {
  927                    let lsp_store = lsp_store.clone();
  928                    let mut cx = cx.clone();
  929                    async move {
  930                        lsp_store
  931                            .update(&mut cx, |lsp_store, cx| {
  932                                if lsp_store.as_local().is_some() {
  933                                    match lsp_store
  934                                        .unregister_server_capabilities(server_id, params, cx)
  935                                    {
  936                                        Ok(()) => {}
  937                                        Err(e) => {
  938                                            log::error!(
  939                                                "Failed to unregister server capabilities: {e:#}"
  940                                            );
  941                                        }
  942                                    }
  943                                }
  944                            })
  945                            .ok();
  946                        Ok(())
  947                    }
  948                }
  949            })
  950            .detach();
  951
  952        language_server
  953            .on_request::<lsp::request::ApplyWorkspaceEdit, _, _>({
  954                let this = lsp_store.clone();
  955                move |params, cx| {
  956                    let mut cx = cx.clone();
  957                    let this = this.clone();
  958                    async move {
  959                        LocalLspStore::on_lsp_workspace_edit(
  960                            this.clone(),
  961                            params,
  962                            server_id,
  963                            &mut cx,
  964                        )
  965                        .await
  966                    }
  967                }
  968            })
  969            .detach();
  970
  971        language_server
  972            .on_request::<lsp::request::InlayHintRefreshRequest, _, _>({
  973                let lsp_store = lsp_store.clone();
  974                let request_id = Arc::new(AtomicUsize::new(0));
  975                move |(), cx| {
  976                    let lsp_store = lsp_store.clone();
  977                    let request_id = request_id.clone();
  978                    let mut cx = cx.clone();
  979                    async move {
  980                        lsp_store
  981                            .update(&mut cx, |lsp_store, cx| {
  982                                let request_id =
  983                                    Some(request_id.fetch_add(1, atomic::Ordering::AcqRel));
  984                                cx.emit(LspStoreEvent::RefreshInlayHints {
  985                                    server_id,
  986                                    request_id,
  987                                });
  988                                lsp_store
  989                                    .downstream_client
  990                                    .as_ref()
  991                                    .map(|(client, project_id)| {
  992                                        client.send(proto::RefreshInlayHints {
  993                                            project_id: *project_id,
  994                                            server_id: server_id.to_proto(),
  995                                            request_id: request_id.map(|id| id as u64),
  996                                        })
  997                                    })
  998                            })?
  999                            .transpose()?;
 1000                        Ok(())
 1001                    }
 1002                }
 1003            })
 1004            .detach();
 1005
 1006        language_server
 1007            .on_request::<lsp::request::CodeLensRefresh, _, _>({
 1008                let this = lsp_store.clone();
 1009                move |(), cx| {
 1010                    let this = this.clone();
 1011                    let mut cx = cx.clone();
 1012                    async move {
 1013                        this.update(&mut cx, |this, cx| {
 1014                            cx.emit(LspStoreEvent::RefreshCodeLens);
 1015                            this.downstream_client.as_ref().map(|(client, project_id)| {
 1016                                client.send(proto::RefreshCodeLens {
 1017                                    project_id: *project_id,
 1018                                })
 1019                            })
 1020                        })?
 1021                        .transpose()?;
 1022                        Ok(())
 1023                    }
 1024                }
 1025            })
 1026            .detach();
 1027
 1028        language_server
 1029            .on_request::<lsp::request::WorkspaceDiagnosticRefresh, _, _>({
 1030                let this = lsp_store.clone();
 1031                move |(), cx| {
 1032                    let this = this.clone();
 1033                    let mut cx = cx.clone();
 1034                    async move {
 1035                        this.update(&mut cx, |lsp_store, _| {
 1036                            lsp_store.pull_workspace_diagnostics(server_id);
 1037                            lsp_store
 1038                                .downstream_client
 1039                                .as_ref()
 1040                                .map(|(client, project_id)| {
 1041                                    client.send(proto::PullWorkspaceDiagnostics {
 1042                                        project_id: *project_id,
 1043                                        server_id: server_id.to_proto(),
 1044                                    })
 1045                                })
 1046                        })?
 1047                        .transpose()?;
 1048                        Ok(())
 1049                    }
 1050                }
 1051            })
 1052            .detach();
 1053
 1054        language_server
 1055            .on_request::<lsp::request::ShowMessageRequest, _, _>({
 1056                let this = lsp_store.clone();
 1057                let name = name.to_string();
 1058                move |params, cx| {
 1059                    let this = this.clone();
 1060                    let name = name.to_string();
 1061                    let mut cx = cx.clone();
 1062                    async move {
 1063                        let actions = params.actions.unwrap_or_default();
 1064                        let (tx, rx) = smol::channel::bounded(1);
 1065                        let request = LanguageServerPromptRequest {
 1066                            level: match params.typ {
 1067                                lsp::MessageType::ERROR => PromptLevel::Critical,
 1068                                lsp::MessageType::WARNING => PromptLevel::Warning,
 1069                                _ => PromptLevel::Info,
 1070                            },
 1071                            message: params.message,
 1072                            actions,
 1073                            response_channel: tx,
 1074                            lsp_name: name.clone(),
 1075                        };
 1076
 1077                        let did_update = this
 1078                            .update(&mut cx, |_, cx| {
 1079                                cx.emit(LspStoreEvent::LanguageServerPrompt(request));
 1080                            })
 1081                            .is_ok();
 1082                        if did_update {
 1083                            let response = rx.recv().await.ok();
 1084                            Ok(response)
 1085                        } else {
 1086                            Ok(None)
 1087                        }
 1088                    }
 1089                }
 1090            })
 1091            .detach();
 1092        language_server
 1093            .on_notification::<lsp::notification::ShowMessage, _>({
 1094                let this = lsp_store.clone();
 1095                let name = name.to_string();
 1096                move |params, cx| {
 1097                    let this = this.clone();
 1098                    let name = name.to_string();
 1099                    let mut cx = cx.clone();
 1100
 1101                    let (tx, _) = smol::channel::bounded(1);
 1102                    let request = LanguageServerPromptRequest {
 1103                        level: match params.typ {
 1104                            lsp::MessageType::ERROR => PromptLevel::Critical,
 1105                            lsp::MessageType::WARNING => PromptLevel::Warning,
 1106                            _ => PromptLevel::Info,
 1107                        },
 1108                        message: params.message,
 1109                        actions: vec![],
 1110                        response_channel: tx,
 1111                        lsp_name: name,
 1112                    };
 1113
 1114                    let _ = this.update(&mut cx, |_, cx| {
 1115                        cx.emit(LspStoreEvent::LanguageServerPrompt(request));
 1116                    });
 1117                }
 1118            })
 1119            .detach();
 1120
 1121        let disk_based_diagnostics_progress_token =
 1122            adapter.disk_based_diagnostics_progress_token.clone();
 1123
 1124        language_server
 1125            .on_notification::<lsp::notification::Progress, _>({
 1126                let this = lsp_store.clone();
 1127                move |params, cx| {
 1128                    if let Some(this) = this.upgrade() {
 1129                        this.update(cx, |this, cx| {
 1130                            this.on_lsp_progress(
 1131                                params,
 1132                                server_id,
 1133                                disk_based_diagnostics_progress_token.clone(),
 1134                                cx,
 1135                            );
 1136                        })
 1137                        .ok();
 1138                    }
 1139                }
 1140            })
 1141            .detach();
 1142
 1143        language_server
 1144            .on_notification::<lsp::notification::LogMessage, _>({
 1145                let this = lsp_store.clone();
 1146                move |params, cx| {
 1147                    if let Some(this) = this.upgrade() {
 1148                        this.update(cx, |_, cx| {
 1149                            cx.emit(LspStoreEvent::LanguageServerLog(
 1150                                server_id,
 1151                                LanguageServerLogType::Log(params.typ),
 1152                                params.message,
 1153                            ));
 1154                        })
 1155                        .ok();
 1156                    }
 1157                }
 1158            })
 1159            .detach();
 1160
 1161        language_server
 1162            .on_notification::<lsp::notification::LogTrace, _>({
 1163                let this = lsp_store.clone();
 1164                move |params, cx| {
 1165                    let mut cx = cx.clone();
 1166                    if let Some(this) = this.upgrade() {
 1167                        this.update(&mut cx, |_, cx| {
 1168                            cx.emit(LspStoreEvent::LanguageServerLog(
 1169                                server_id,
 1170                                LanguageServerLogType::Trace {
 1171                                    verbose_info: params.verbose,
 1172                                },
 1173                                params.message,
 1174                            ));
 1175                        })
 1176                        .ok();
 1177                    }
 1178                }
 1179            })
 1180            .detach();
 1181
 1182        vue_language_server_ext::register_requests(lsp_store.clone(), language_server);
 1183        json_language_server_ext::register_requests(lsp_store.clone(), language_server);
 1184        rust_analyzer_ext::register_notifications(lsp_store.clone(), language_server);
 1185        clangd_ext::register_notifications(lsp_store, language_server, adapter);
 1186    }
 1187
 1188    fn shutdown_language_servers_on_quit(
 1189        &mut self,
 1190        _: &mut Context<LspStore>,
 1191    ) -> impl Future<Output = ()> + use<> {
 1192        let shutdown_futures = self
 1193            .language_servers
 1194            .drain()
 1195            .map(|(_, server_state)| Self::shutdown_server(server_state))
 1196            .collect::<Vec<_>>();
 1197
 1198        async move {
 1199            join_all(shutdown_futures).await;
 1200        }
 1201    }
 1202
 1203    async fn shutdown_server(server_state: LanguageServerState) -> anyhow::Result<()> {
 1204        match server_state {
 1205            LanguageServerState::Running { server, .. } => {
 1206                if let Some(shutdown) = server.shutdown() {
 1207                    shutdown.await;
 1208                }
 1209            }
 1210            LanguageServerState::Starting { startup, .. } => {
 1211                if let Some(server) = startup.await
 1212                    && let Some(shutdown) = server.shutdown()
 1213                {
 1214                    shutdown.await;
 1215                }
 1216            }
 1217        }
 1218        Ok(())
 1219    }
 1220
 1221    fn language_servers_for_worktree(
 1222        &self,
 1223        worktree_id: WorktreeId,
 1224    ) -> impl Iterator<Item = &Arc<LanguageServer>> {
 1225        self.language_server_ids
 1226            .iter()
 1227            .filter_map(move |(seed, state)| {
 1228                if seed.worktree_id != worktree_id {
 1229                    return None;
 1230                }
 1231
 1232                if let Some(LanguageServerState::Running { server, .. }) =
 1233                    self.language_servers.get(&state.id)
 1234                {
 1235                    Some(server)
 1236                } else {
 1237                    None
 1238                }
 1239            })
 1240    }
 1241
 1242    fn language_server_ids_for_project_path(
 1243        &self,
 1244        project_path: ProjectPath,
 1245        language: &Language,
 1246        cx: &mut App,
 1247    ) -> Vec<LanguageServerId> {
 1248        let Some(worktree) = self
 1249            .worktree_store
 1250            .read(cx)
 1251            .worktree_for_id(project_path.worktree_id, cx)
 1252        else {
 1253            return Vec::new();
 1254        };
 1255        let delegate: Arc<dyn ManifestDelegate> =
 1256            Arc::new(ManifestQueryDelegate::new(worktree.read(cx).snapshot()));
 1257
 1258        self.lsp_tree
 1259            .get(
 1260                project_path,
 1261                language.name(),
 1262                language.manifest(),
 1263                &delegate,
 1264                cx,
 1265            )
 1266            .collect::<Vec<_>>()
 1267    }
 1268
 1269    fn language_server_ids_for_buffer(
 1270        &self,
 1271        buffer: &Buffer,
 1272        cx: &mut App,
 1273    ) -> Vec<LanguageServerId> {
 1274        if let Some((file, language)) = File::from_dyn(buffer.file()).zip(buffer.language()) {
 1275            let worktree_id = file.worktree_id(cx);
 1276
 1277            let path: Arc<RelPath> = file
 1278                .path()
 1279                .parent()
 1280                .map(Arc::from)
 1281                .unwrap_or_else(|| file.path().clone());
 1282            let worktree_path = ProjectPath { worktree_id, path };
 1283            self.language_server_ids_for_project_path(worktree_path, language, cx)
 1284        } else {
 1285            Vec::new()
 1286        }
 1287    }
 1288
 1289    fn language_servers_for_buffer<'a>(
 1290        &'a self,
 1291        buffer: &'a Buffer,
 1292        cx: &'a mut App,
 1293    ) -> impl Iterator<Item = (&'a Arc<CachedLspAdapter>, &'a Arc<LanguageServer>)> {
 1294        self.language_server_ids_for_buffer(buffer, cx)
 1295            .into_iter()
 1296            .filter_map(|server_id| match self.language_servers.get(&server_id)? {
 1297                LanguageServerState::Running {
 1298                    adapter, server, ..
 1299                } => Some((adapter, server)),
 1300                _ => None,
 1301            })
 1302    }
 1303
 1304    async fn execute_code_action_kind_locally(
 1305        lsp_store: WeakEntity<LspStore>,
 1306        mut buffers: Vec<Entity<Buffer>>,
 1307        kind: CodeActionKind,
 1308        push_to_history: bool,
 1309        cx: &mut AsyncApp,
 1310    ) -> anyhow::Result<ProjectTransaction> {
 1311        // Do not allow multiple concurrent code actions requests for the
 1312        // same buffer.
 1313        lsp_store.update(cx, |this, cx| {
 1314            let this = this.as_local_mut().unwrap();
 1315            buffers.retain(|buffer| {
 1316                this.buffers_being_formatted
 1317                    .insert(buffer.read(cx).remote_id())
 1318            });
 1319        })?;
 1320        let _cleanup = defer({
 1321            let this = lsp_store.clone();
 1322            let mut cx = cx.clone();
 1323            let buffers = &buffers;
 1324            move || {
 1325                this.update(&mut cx, |this, cx| {
 1326                    let this = this.as_local_mut().unwrap();
 1327                    for buffer in buffers {
 1328                        this.buffers_being_formatted
 1329                            .remove(&buffer.read(cx).remote_id());
 1330                    }
 1331                })
 1332                .ok();
 1333            }
 1334        });
 1335        let mut project_transaction = ProjectTransaction::default();
 1336
 1337        for buffer in &buffers {
 1338            let adapters_and_servers = lsp_store.update(cx, |lsp_store, cx| {
 1339                buffer.update(cx, |buffer, cx| {
 1340                    lsp_store
 1341                        .as_local()
 1342                        .unwrap()
 1343                        .language_servers_for_buffer(buffer, cx)
 1344                        .map(|(adapter, lsp)| (adapter.clone(), lsp.clone()))
 1345                        .collect::<Vec<_>>()
 1346                })
 1347            })?;
 1348            for (_, language_server) in adapters_and_servers.iter() {
 1349                let actions = Self::get_server_code_actions_from_action_kinds(
 1350                    &lsp_store,
 1351                    language_server.server_id(),
 1352                    vec![kind.clone()],
 1353                    buffer,
 1354                    cx,
 1355                )
 1356                .await?;
 1357                Self::execute_code_actions_on_server(
 1358                    &lsp_store,
 1359                    language_server,
 1360                    actions,
 1361                    push_to_history,
 1362                    &mut project_transaction,
 1363                    cx,
 1364                )
 1365                .await?;
 1366            }
 1367        }
 1368        Ok(project_transaction)
 1369    }
 1370
 1371    async fn format_locally(
 1372        lsp_store: WeakEntity<LspStore>,
 1373        mut buffers: Vec<FormattableBuffer>,
 1374        push_to_history: bool,
 1375        trigger: FormatTrigger,
 1376        logger: zlog::Logger,
 1377        cx: &mut AsyncApp,
 1378    ) -> anyhow::Result<ProjectTransaction> {
 1379        // Do not allow multiple concurrent formatting requests for the
 1380        // same buffer.
 1381        lsp_store.update(cx, |this, cx| {
 1382            let this = this.as_local_mut().unwrap();
 1383            buffers.retain(|buffer| {
 1384                this.buffers_being_formatted
 1385                    .insert(buffer.handle.read(cx).remote_id())
 1386            });
 1387        })?;
 1388
 1389        let _cleanup = defer({
 1390            let this = lsp_store.clone();
 1391            let mut cx = cx.clone();
 1392            let buffers = &buffers;
 1393            move || {
 1394                this.update(&mut cx, |this, cx| {
 1395                    let this = this.as_local_mut().unwrap();
 1396                    for buffer in buffers {
 1397                        this.buffers_being_formatted
 1398                            .remove(&buffer.handle.read(cx).remote_id());
 1399                    }
 1400                })
 1401                .ok();
 1402            }
 1403        });
 1404
 1405        let mut project_transaction = ProjectTransaction::default();
 1406
 1407        for buffer in &buffers {
 1408            zlog::debug!(
 1409                logger =>
 1410                "formatting buffer '{:?}'",
 1411                buffer.abs_path.as_ref().unwrap_or(&PathBuf::from("unknown")).display()
 1412            );
 1413            // Create an empty transaction to hold all of the formatting edits.
 1414            let formatting_transaction_id = buffer.handle.update(cx, |buffer, cx| {
 1415                // ensure no transactions created while formatting are
 1416                // grouped with the previous transaction in the history
 1417                // based on the transaction group interval
 1418                buffer.finalize_last_transaction();
 1419                buffer
 1420                    .start_transaction()
 1421                    .context("transaction already open")?;
 1422                buffer.end_transaction(cx);
 1423                let transaction_id = buffer.push_empty_transaction(cx.background_executor().now());
 1424                buffer.finalize_last_transaction();
 1425                anyhow::Ok(transaction_id)
 1426            })??;
 1427
 1428            let result = Self::format_buffer_locally(
 1429                lsp_store.clone(),
 1430                buffer,
 1431                formatting_transaction_id,
 1432                trigger,
 1433                logger,
 1434                cx,
 1435            )
 1436            .await;
 1437
 1438            buffer.handle.update(cx, |buffer, cx| {
 1439                let Some(formatting_transaction) =
 1440                    buffer.get_transaction(formatting_transaction_id).cloned()
 1441                else {
 1442                    zlog::warn!(logger => "no formatting transaction");
 1443                    return;
 1444                };
 1445                if formatting_transaction.edit_ids.is_empty() {
 1446                    zlog::debug!(logger => "no changes made while formatting");
 1447                    buffer.forget_transaction(formatting_transaction_id);
 1448                    return;
 1449                }
 1450                if !push_to_history {
 1451                    zlog::trace!(logger => "forgetting format transaction");
 1452                    buffer.forget_transaction(formatting_transaction.id);
 1453                }
 1454                project_transaction
 1455                    .0
 1456                    .insert(cx.entity(), formatting_transaction);
 1457            })?;
 1458
 1459            result?;
 1460        }
 1461
 1462        Ok(project_transaction)
 1463    }
 1464
 1465    async fn format_buffer_locally(
 1466        lsp_store: WeakEntity<LspStore>,
 1467        buffer: &FormattableBuffer,
 1468        formatting_transaction_id: clock::Lamport,
 1469        trigger: FormatTrigger,
 1470        logger: zlog::Logger,
 1471        cx: &mut AsyncApp,
 1472    ) -> Result<()> {
 1473        let (adapters_and_servers, settings) = lsp_store.update(cx, |lsp_store, cx| {
 1474            buffer.handle.update(cx, |buffer, cx| {
 1475                let adapters_and_servers = lsp_store
 1476                    .as_local()
 1477                    .unwrap()
 1478                    .language_servers_for_buffer(buffer, cx)
 1479                    .map(|(adapter, lsp)| (adapter.clone(), lsp.clone()))
 1480                    .collect::<Vec<_>>();
 1481                let settings =
 1482                    language_settings(buffer.language().map(|l| l.name()), buffer.file(), cx)
 1483                        .into_owned();
 1484                (adapters_and_servers, settings)
 1485            })
 1486        })?;
 1487
 1488        /// Apply edits to the buffer that will become part of the formatting transaction.
 1489        /// Fails if the buffer has been edited since the start of that transaction.
 1490        fn extend_formatting_transaction(
 1491            buffer: &FormattableBuffer,
 1492            formatting_transaction_id: text::TransactionId,
 1493            cx: &mut AsyncApp,
 1494            operation: impl FnOnce(&mut Buffer, &mut Context<Buffer>),
 1495        ) -> anyhow::Result<()> {
 1496            buffer.handle.update(cx, |buffer, cx| {
 1497                let last_transaction_id = buffer.peek_undo_stack().map(|t| t.transaction_id());
 1498                if last_transaction_id != Some(formatting_transaction_id) {
 1499                    anyhow::bail!("Buffer edited while formatting. Aborting")
 1500                }
 1501                buffer.start_transaction();
 1502                operation(buffer, cx);
 1503                if let Some(transaction_id) = buffer.end_transaction(cx) {
 1504                    buffer.merge_transactions(transaction_id, formatting_transaction_id);
 1505                }
 1506                Ok(())
 1507            })?
 1508        }
 1509
 1510        // handle whitespace formatting
 1511        if settings.remove_trailing_whitespace_on_save {
 1512            zlog::trace!(logger => "removing trailing whitespace");
 1513            let diff = buffer
 1514                .handle
 1515                .read_with(cx, |buffer, cx| buffer.remove_trailing_whitespace(cx))?
 1516                .await;
 1517            extend_formatting_transaction(buffer, formatting_transaction_id, cx, |buffer, cx| {
 1518                buffer.apply_diff(diff, cx);
 1519            })?;
 1520        }
 1521
 1522        if settings.ensure_final_newline_on_save {
 1523            zlog::trace!(logger => "ensuring final newline");
 1524            extend_formatting_transaction(buffer, formatting_transaction_id, cx, |buffer, cx| {
 1525                buffer.ensure_final_newline(cx);
 1526            })?;
 1527        }
 1528
 1529        // Formatter for `code_actions_on_format` that runs before
 1530        // the rest of the formatters
 1531        let mut code_actions_on_format_formatters = None;
 1532        let should_run_code_actions_on_format = !matches!(
 1533            (trigger, &settings.format_on_save),
 1534            (FormatTrigger::Save, &FormatOnSave::Off)
 1535        );
 1536        if should_run_code_actions_on_format {
 1537            let have_code_actions_to_run_on_format = settings
 1538                .code_actions_on_format
 1539                .values()
 1540                .any(|enabled| *enabled);
 1541            if have_code_actions_to_run_on_format {
 1542                zlog::trace!(logger => "going to run code actions on format");
 1543                code_actions_on_format_formatters = Some(
 1544                    settings
 1545                        .code_actions_on_format
 1546                        .iter()
 1547                        .filter_map(|(action, enabled)| enabled.then_some(action))
 1548                        .cloned()
 1549                        .map(Formatter::CodeAction)
 1550                        .collect::<Vec<_>>(),
 1551                );
 1552            }
 1553        }
 1554
 1555        let formatters = match (trigger, &settings.format_on_save) {
 1556            (FormatTrigger::Save, FormatOnSave::Off) => &[],
 1557            (FormatTrigger::Manual, _) | (FormatTrigger::Save, FormatOnSave::On) => {
 1558                settings.formatter.as_ref()
 1559            }
 1560        };
 1561
 1562        let formatters = code_actions_on_format_formatters
 1563            .iter()
 1564            .flatten()
 1565            .chain(formatters);
 1566
 1567        for formatter in formatters {
 1568            let formatter = if formatter == &Formatter::Auto {
 1569                if settings.prettier.allowed {
 1570                    zlog::trace!(logger => "Formatter set to auto: defaulting to prettier");
 1571                    &Formatter::Prettier
 1572                } else {
 1573                    zlog::trace!(logger => "Formatter set to auto: defaulting to primary language server");
 1574                    &Formatter::LanguageServer(settings::LanguageServerFormatterSpecifier::Current)
 1575                }
 1576            } else {
 1577                formatter
 1578            };
 1579            match formatter {
 1580                Formatter::Auto => unreachable!("Auto resolved above"),
 1581                Formatter::Prettier => {
 1582                    let logger = zlog::scoped!(logger => "prettier");
 1583                    zlog::trace!(logger => "formatting");
 1584                    let _timer = zlog::time!(logger => "Formatting buffer via prettier");
 1585
 1586                    let prettier = lsp_store.read_with(cx, |lsp_store, _cx| {
 1587                        lsp_store.prettier_store().unwrap().downgrade()
 1588                    })?;
 1589                    let diff = prettier_store::format_with_prettier(&prettier, &buffer.handle, cx)
 1590                        .await
 1591                        .transpose()?;
 1592                    let Some(diff) = diff else {
 1593                        zlog::trace!(logger => "No changes");
 1594                        continue;
 1595                    };
 1596
 1597                    extend_formatting_transaction(
 1598                        buffer,
 1599                        formatting_transaction_id,
 1600                        cx,
 1601                        |buffer, cx| {
 1602                            buffer.apply_diff(diff, cx);
 1603                        },
 1604                    )?;
 1605                }
 1606                Formatter::External { command, arguments } => {
 1607                    let logger = zlog::scoped!(logger => "command");
 1608                    zlog::trace!(logger => "formatting");
 1609                    let _timer = zlog::time!(logger => "Formatting buffer via external command");
 1610
 1611                    let diff = Self::format_via_external_command(
 1612                        buffer,
 1613                        command.as_ref(),
 1614                        arguments.as_deref(),
 1615                        cx,
 1616                    )
 1617                    .await
 1618                    .with_context(|| {
 1619                        format!("Failed to format buffer via external command: {}", command)
 1620                    })?;
 1621                    let Some(diff) = diff else {
 1622                        zlog::trace!(logger => "No changes");
 1623                        continue;
 1624                    };
 1625
 1626                    extend_formatting_transaction(
 1627                        buffer,
 1628                        formatting_transaction_id,
 1629                        cx,
 1630                        |buffer, cx| {
 1631                            buffer.apply_diff(diff, cx);
 1632                        },
 1633                    )?;
 1634                }
 1635                Formatter::LanguageServer(specifier) => {
 1636                    let logger = zlog::scoped!(logger => "language-server");
 1637                    zlog::trace!(logger => "formatting");
 1638                    let _timer = zlog::time!(logger => "Formatting buffer using language server");
 1639
 1640                    let Some(buffer_path_abs) = buffer.abs_path.as_ref() else {
 1641                        zlog::warn!(logger => "Cannot format buffer that is not backed by a file on disk using language servers. Skipping");
 1642                        continue;
 1643                    };
 1644
 1645                    let language_server = match specifier {
 1646                        settings::LanguageServerFormatterSpecifier::Specific { name } => {
 1647                            adapters_and_servers.iter().find_map(|(adapter, server)| {
 1648                                if adapter.name.0.as_ref() == name {
 1649                                    Some(server.clone())
 1650                                } else {
 1651                                    None
 1652                                }
 1653                            })
 1654                        }
 1655                        settings::LanguageServerFormatterSpecifier::Current => {
 1656                            adapters_and_servers.first().map(|e| e.1.clone())
 1657                        }
 1658                    };
 1659
 1660                    let Some(language_server) = language_server else {
 1661                        log::debug!(
 1662                            "No language server found to format buffer '{:?}'. Skipping",
 1663                            buffer_path_abs.as_path().to_string_lossy()
 1664                        );
 1665                        continue;
 1666                    };
 1667
 1668                    zlog::trace!(
 1669                        logger =>
 1670                        "Formatting buffer '{:?}' using language server '{:?}'",
 1671                        buffer_path_abs.as_path().to_string_lossy(),
 1672                        language_server.name()
 1673                    );
 1674
 1675                    let edits = if let Some(ranges) = buffer.ranges.as_ref() {
 1676                        zlog::trace!(logger => "formatting ranges");
 1677                        Self::format_ranges_via_lsp(
 1678                            &lsp_store,
 1679                            &buffer.handle,
 1680                            ranges,
 1681                            buffer_path_abs,
 1682                            &language_server,
 1683                            &settings,
 1684                            cx,
 1685                        )
 1686                        .await
 1687                        .context("Failed to format ranges via language server")?
 1688                    } else {
 1689                        zlog::trace!(logger => "formatting full");
 1690                        Self::format_via_lsp(
 1691                            &lsp_store,
 1692                            &buffer.handle,
 1693                            buffer_path_abs,
 1694                            &language_server,
 1695                            &settings,
 1696                            cx,
 1697                        )
 1698                        .await
 1699                        .context("failed to format via language server")?
 1700                    };
 1701
 1702                    if edits.is_empty() {
 1703                        zlog::trace!(logger => "No changes");
 1704                        continue;
 1705                    }
 1706                    extend_formatting_transaction(
 1707                        buffer,
 1708                        formatting_transaction_id,
 1709                        cx,
 1710                        |buffer, cx| {
 1711                            buffer.edit(edits, None, cx);
 1712                        },
 1713                    )?;
 1714                }
 1715                Formatter::CodeAction(code_action_name) => {
 1716                    let logger = zlog::scoped!(logger => "code-actions");
 1717                    zlog::trace!(logger => "formatting");
 1718                    let _timer = zlog::time!(logger => "Formatting buffer using code actions");
 1719
 1720                    let Some(buffer_path_abs) = buffer.abs_path.as_ref() else {
 1721                        zlog::warn!(logger => "Cannot format buffer that is not backed by a file on disk using code actions. Skipping");
 1722                        continue;
 1723                    };
 1724
 1725                    let code_action_kind: CodeActionKind = code_action_name.clone().into();
 1726                    zlog::trace!(logger => "Attempting to resolve code actions {:?}", &code_action_kind);
 1727
 1728                    let mut actions_and_servers = Vec::new();
 1729
 1730                    for (index, (_, language_server)) in adapters_and_servers.iter().enumerate() {
 1731                        let actions_result = Self::get_server_code_actions_from_action_kinds(
 1732                            &lsp_store,
 1733                            language_server.server_id(),
 1734                            vec![code_action_kind.clone()],
 1735                            &buffer.handle,
 1736                            cx,
 1737                        )
 1738                        .await
 1739                        .with_context(|| {
 1740                            format!(
 1741                                "Failed to resolve code action {:?} with language server {}",
 1742                                code_action_kind,
 1743                                language_server.name()
 1744                            )
 1745                        });
 1746                        let Ok(actions) = actions_result else {
 1747                            // note: it may be better to set result to the error and break formatters here
 1748                            // but for now we try to execute the actions that we can resolve and skip the rest
 1749                            zlog::error!(
 1750                                logger =>
 1751                                "Failed to resolve code action {:?} with language server {}",
 1752                                code_action_kind,
 1753                                language_server.name()
 1754                            );
 1755                            continue;
 1756                        };
 1757                        for action in actions {
 1758                            actions_and_servers.push((action, index));
 1759                        }
 1760                    }
 1761
 1762                    if actions_and_servers.is_empty() {
 1763                        zlog::warn!(logger => "No code actions were resolved, continuing");
 1764                        continue;
 1765                    }
 1766
 1767                    'actions: for (mut action, server_index) in actions_and_servers {
 1768                        let server = &adapters_and_servers[server_index].1;
 1769
 1770                        let describe_code_action = |action: &CodeAction| {
 1771                            format!(
 1772                                "code action '{}' with title \"{}\" on server {}",
 1773                                action
 1774                                    .lsp_action
 1775                                    .action_kind()
 1776                                    .unwrap_or("unknown".into())
 1777                                    .as_str(),
 1778                                action.lsp_action.title(),
 1779                                server.name(),
 1780                            )
 1781                        };
 1782
 1783                        zlog::trace!(logger => "Executing {}", describe_code_action(&action));
 1784
 1785                        if let Err(err) = Self::try_resolve_code_action(server, &mut action).await {
 1786                            zlog::error!(
 1787                                logger =>
 1788                                "Failed to resolve {}. Error: {}",
 1789                                describe_code_action(&action),
 1790                                err
 1791                            );
 1792                            continue;
 1793                        }
 1794
 1795                        if let Some(edit) = action.lsp_action.edit().cloned() {
 1796                            // NOTE: code below duplicated from `Self::deserialize_workspace_edit`
 1797                            // but filters out and logs warnings for code actions that require unreasonably
 1798                            // difficult handling on our part, such as:
 1799                            // - applying edits that call commands
 1800                            //   which can result in arbitrary workspace edits being sent from the server that
 1801                            //   have no way of being tied back to the command that initiated them (i.e. we
 1802                            //   can't know which edits are part of the format request, or if the server is done sending
 1803                            //   actions in response to the command)
 1804                            // - actions that create/delete/modify/rename files other than the one we are formatting
 1805                            //   as we then would need to handle such changes correctly in the local history as well
 1806                            //   as the remote history through the ProjectTransaction
 1807                            // - actions with snippet edits, as these simply don't make sense in the context of a format request
 1808                            // Supporting these actions is not impossible, but not supported as of yet.
 1809                            if edit.changes.is_none() && edit.document_changes.is_none() {
 1810                                zlog::trace!(
 1811                                    logger =>
 1812                                    "No changes for code action. Skipping {}",
 1813                                    describe_code_action(&action),
 1814                                );
 1815                                continue;
 1816                            }
 1817
 1818                            let mut operations = Vec::new();
 1819                            if let Some(document_changes) = edit.document_changes {
 1820                                match document_changes {
 1821                                    lsp::DocumentChanges::Edits(edits) => operations.extend(
 1822                                        edits.into_iter().map(lsp::DocumentChangeOperation::Edit),
 1823                                    ),
 1824                                    lsp::DocumentChanges::Operations(ops) => operations = ops,
 1825                                }
 1826                            } else if let Some(changes) = edit.changes {
 1827                                operations.extend(changes.into_iter().map(|(uri, edits)| {
 1828                                    lsp::DocumentChangeOperation::Edit(lsp::TextDocumentEdit {
 1829                                        text_document:
 1830                                            lsp::OptionalVersionedTextDocumentIdentifier {
 1831                                                uri,
 1832                                                version: None,
 1833                                            },
 1834                                        edits: edits.into_iter().map(Edit::Plain).collect(),
 1835                                    })
 1836                                }));
 1837                            }
 1838
 1839                            let mut edits = Vec::with_capacity(operations.len());
 1840
 1841                            if operations.is_empty() {
 1842                                zlog::trace!(
 1843                                    logger =>
 1844                                    "No changes for code action. Skipping {}",
 1845                                    describe_code_action(&action),
 1846                                );
 1847                                continue;
 1848                            }
 1849                            for operation in operations {
 1850                                let op = match operation {
 1851                                    lsp::DocumentChangeOperation::Edit(op) => op,
 1852                                    lsp::DocumentChangeOperation::Op(_) => {
 1853                                        zlog::warn!(
 1854                                            logger =>
 1855                                            "Code actions which create, delete, or rename files are not supported on format. Skipping {}",
 1856                                            describe_code_action(&action),
 1857                                        );
 1858                                        continue 'actions;
 1859                                    }
 1860                                };
 1861                                let Ok(file_path) = op.text_document.uri.to_file_path() else {
 1862                                    zlog::warn!(
 1863                                        logger =>
 1864                                        "Failed to convert URI '{:?}' to file path. Skipping {}",
 1865                                        &op.text_document.uri,
 1866                                        describe_code_action(&action),
 1867                                    );
 1868                                    continue 'actions;
 1869                                };
 1870                                if &file_path != buffer_path_abs {
 1871                                    zlog::warn!(
 1872                                        logger =>
 1873                                        "File path '{:?}' does not match buffer path '{:?}'. Skipping {}",
 1874                                        file_path,
 1875                                        buffer_path_abs,
 1876                                        describe_code_action(&action),
 1877                                    );
 1878                                    continue 'actions;
 1879                                }
 1880
 1881                                let mut lsp_edits = Vec::new();
 1882                                for edit in op.edits {
 1883                                    match edit {
 1884                                        Edit::Plain(edit) => {
 1885                                            if !lsp_edits.contains(&edit) {
 1886                                                lsp_edits.push(edit);
 1887                                            }
 1888                                        }
 1889                                        Edit::Annotated(edit) => {
 1890                                            if !lsp_edits.contains(&edit.text_edit) {
 1891                                                lsp_edits.push(edit.text_edit);
 1892                                            }
 1893                                        }
 1894                                        Edit::Snippet(_) => {
 1895                                            zlog::warn!(
 1896                                                logger =>
 1897                                                "Code actions which produce snippet edits are not supported during formatting. Skipping {}",
 1898                                                describe_code_action(&action),
 1899                                            );
 1900                                            continue 'actions;
 1901                                        }
 1902                                    }
 1903                                }
 1904                                let edits_result = lsp_store
 1905                                    .update(cx, |lsp_store, cx| {
 1906                                        lsp_store.as_local_mut().unwrap().edits_from_lsp(
 1907                                            &buffer.handle,
 1908                                            lsp_edits,
 1909                                            server.server_id(),
 1910                                            op.text_document.version,
 1911                                            cx,
 1912                                        )
 1913                                    })?
 1914                                    .await;
 1915                                let Ok(resolved_edits) = edits_result else {
 1916                                    zlog::warn!(
 1917                                        logger =>
 1918                                        "Failed to resolve edits from LSP for buffer {:?} while handling {}",
 1919                                        buffer_path_abs.as_path(),
 1920                                        describe_code_action(&action),
 1921                                    );
 1922                                    continue 'actions;
 1923                                };
 1924                                edits.extend(resolved_edits);
 1925                            }
 1926
 1927                            if edits.is_empty() {
 1928                                zlog::warn!(logger => "No edits resolved from LSP");
 1929                                continue;
 1930                            }
 1931
 1932                            extend_formatting_transaction(
 1933                                buffer,
 1934                                formatting_transaction_id,
 1935                                cx,
 1936                                |buffer, cx| {
 1937                                    zlog::info!(
 1938                                        "Applying edits {edits:?}. Content: {:?}",
 1939                                        buffer.text()
 1940                                    );
 1941                                    buffer.edit(edits, None, cx);
 1942                                    zlog::info!("Applied edits. New Content: {:?}", buffer.text());
 1943                                },
 1944                            )?;
 1945                        }
 1946
 1947                        if let Some(command) = action.lsp_action.command() {
 1948                            zlog::warn!(
 1949                                logger =>
 1950                                "Executing code action command '{}'. This may cause formatting to abort unnecessarily as well as splitting formatting into two entries in the undo history",
 1951                                &command.command,
 1952                            );
 1953
 1954                            // bail early if command is invalid
 1955                            let server_capabilities = server.capabilities();
 1956                            let available_commands = server_capabilities
 1957                                .execute_command_provider
 1958                                .as_ref()
 1959                                .map(|options| options.commands.as_slice())
 1960                                .unwrap_or_default();
 1961                            if !available_commands.contains(&command.command) {
 1962                                zlog::warn!(
 1963                                    logger =>
 1964                                    "Cannot execute a command {} not listed in the language server capabilities of server {}",
 1965                                    command.command,
 1966                                    server.name(),
 1967                                );
 1968                                continue;
 1969                            }
 1970
 1971                            // noop so we just ensure buffer hasn't been edited since resolving code actions
 1972                            extend_formatting_transaction(
 1973                                buffer,
 1974                                formatting_transaction_id,
 1975                                cx,
 1976                                |_, _| {},
 1977                            )?;
 1978                            zlog::info!(logger => "Executing command {}", &command.command);
 1979
 1980                            lsp_store.update(cx, |this, _| {
 1981                                this.as_local_mut()
 1982                                    .unwrap()
 1983                                    .last_workspace_edits_by_language_server
 1984                                    .remove(&server.server_id());
 1985                            })?;
 1986
 1987                            let execute_command_result = server
 1988                                .request::<lsp::request::ExecuteCommand>(
 1989                                    lsp::ExecuteCommandParams {
 1990                                        command: command.command.clone(),
 1991                                        arguments: command.arguments.clone().unwrap_or_default(),
 1992                                        ..Default::default()
 1993                                    },
 1994                                )
 1995                                .await
 1996                                .into_response();
 1997
 1998                            if execute_command_result.is_err() {
 1999                                zlog::error!(
 2000                                    logger =>
 2001                                    "Failed to execute command '{}' as part of {}",
 2002                                    &command.command,
 2003                                    describe_code_action(&action),
 2004                                );
 2005                                continue 'actions;
 2006                            }
 2007
 2008                            let mut project_transaction_command =
 2009                                lsp_store.update(cx, |this, _| {
 2010                                    this.as_local_mut()
 2011                                        .unwrap()
 2012                                        .last_workspace_edits_by_language_server
 2013                                        .remove(&server.server_id())
 2014                                        .unwrap_or_default()
 2015                                })?;
 2016
 2017                            if let Some(transaction) =
 2018                                project_transaction_command.0.remove(&buffer.handle)
 2019                            {
 2020                                zlog::trace!(
 2021                                    logger =>
 2022                                    "Successfully captured {} edits that resulted from command {}",
 2023                                    transaction.edit_ids.len(),
 2024                                    &command.command,
 2025                                );
 2026                                let transaction_id_project_transaction = transaction.id;
 2027                                buffer.handle.update(cx, |buffer, _| {
 2028                                    // it may have been removed from history if push_to_history was
 2029                                    // false in deserialize_workspace_edit. If so push it so we
 2030                                    // can merge it with the format transaction
 2031                                    // and pop the combined transaction off the history stack
 2032                                    // later if push_to_history is false
 2033                                    if buffer.get_transaction(transaction.id).is_none() {
 2034                                        buffer.push_transaction(transaction, Instant::now());
 2035                                    }
 2036                                    buffer.merge_transactions(
 2037                                        transaction_id_project_transaction,
 2038                                        formatting_transaction_id,
 2039                                    );
 2040                                })?;
 2041                            }
 2042
 2043                            if !project_transaction_command.0.is_empty() {
 2044                                let mut extra_buffers = String::new();
 2045                                for buffer in project_transaction_command.0.keys() {
 2046                                    buffer
 2047                                        .read_with(cx, |b, cx| {
 2048                                            if let Some(path) = b.project_path(cx) {
 2049                                                if !extra_buffers.is_empty() {
 2050                                                    extra_buffers.push_str(", ");
 2051                                                }
 2052                                                extra_buffers.push_str(path.path.as_unix_str());
 2053                                            }
 2054                                        })
 2055                                        .ok();
 2056                                }
 2057                                zlog::warn!(
 2058                                    logger =>
 2059                                    "Unexpected edits to buffers other than the buffer actively being formatted due to command {}. Impacted buffers: [{}].",
 2060                                    &command.command,
 2061                                    extra_buffers,
 2062                                );
 2063                                // NOTE: if this case is hit, the proper thing to do is to for each buffer, merge the extra transaction
 2064                                // into the existing transaction in project_transaction if there is one, and if there isn't one in project_transaction,
 2065                                // add it so it's included, and merge it into the format transaction when its created later
 2066                            }
 2067                        }
 2068                    }
 2069                }
 2070            }
 2071        }
 2072
 2073        Ok(())
 2074    }
 2075
 2076    pub async fn format_ranges_via_lsp(
 2077        this: &WeakEntity<LspStore>,
 2078        buffer_handle: &Entity<Buffer>,
 2079        ranges: &[Range<Anchor>],
 2080        abs_path: &Path,
 2081        language_server: &Arc<LanguageServer>,
 2082        settings: &LanguageSettings,
 2083        cx: &mut AsyncApp,
 2084    ) -> Result<Vec<(Range<Anchor>, Arc<str>)>> {
 2085        let capabilities = &language_server.capabilities();
 2086        let range_formatting_provider = capabilities.document_range_formatting_provider.as_ref();
 2087        if range_formatting_provider == Some(&OneOf::Left(false)) {
 2088            anyhow::bail!(
 2089                "{} language server does not support range formatting",
 2090                language_server.name()
 2091            );
 2092        }
 2093
 2094        let uri = file_path_to_lsp_url(abs_path)?;
 2095        let text_document = lsp::TextDocumentIdentifier::new(uri);
 2096
 2097        let lsp_edits = {
 2098            let mut lsp_ranges = Vec::new();
 2099            this.update(cx, |_this, cx| {
 2100                // TODO(#22930): In the case of formatting multibuffer selections, this buffer may
 2101                // not have been sent to the language server. This seems like a fairly systemic
 2102                // issue, though, the resolution probably is not specific to formatting.
 2103                //
 2104                // TODO: Instead of using current snapshot, should use the latest snapshot sent to
 2105                // LSP.
 2106                let snapshot = buffer_handle.read(cx).snapshot();
 2107                for range in ranges {
 2108                    lsp_ranges.push(range_to_lsp(range.to_point_utf16(&snapshot))?);
 2109                }
 2110                anyhow::Ok(())
 2111            })??;
 2112
 2113            let mut edits = None;
 2114            for range in lsp_ranges {
 2115                if let Some(mut edit) = language_server
 2116                    .request::<lsp::request::RangeFormatting>(lsp::DocumentRangeFormattingParams {
 2117                        text_document: text_document.clone(),
 2118                        range,
 2119                        options: lsp_command::lsp_formatting_options(settings),
 2120                        work_done_progress_params: Default::default(),
 2121                    })
 2122                    .await
 2123                    .into_response()?
 2124                {
 2125                    edits.get_or_insert_with(Vec::new).append(&mut edit);
 2126                }
 2127            }
 2128            edits
 2129        };
 2130
 2131        if let Some(lsp_edits) = lsp_edits {
 2132            this.update(cx, |this, cx| {
 2133                this.as_local_mut().unwrap().edits_from_lsp(
 2134                    buffer_handle,
 2135                    lsp_edits,
 2136                    language_server.server_id(),
 2137                    None,
 2138                    cx,
 2139                )
 2140            })?
 2141            .await
 2142        } else {
 2143            Ok(Vec::with_capacity(0))
 2144        }
 2145    }
 2146
 2147    async fn format_via_lsp(
 2148        this: &WeakEntity<LspStore>,
 2149        buffer: &Entity<Buffer>,
 2150        abs_path: &Path,
 2151        language_server: &Arc<LanguageServer>,
 2152        settings: &LanguageSettings,
 2153        cx: &mut AsyncApp,
 2154    ) -> Result<Vec<(Range<Anchor>, Arc<str>)>> {
 2155        let logger = zlog::scoped!("lsp_format");
 2156        zlog::debug!(logger => "Formatting via LSP");
 2157
 2158        let uri = file_path_to_lsp_url(abs_path)?;
 2159        let text_document = lsp::TextDocumentIdentifier::new(uri);
 2160        let capabilities = &language_server.capabilities();
 2161
 2162        let formatting_provider = capabilities.document_formatting_provider.as_ref();
 2163        let range_formatting_provider = capabilities.document_range_formatting_provider.as_ref();
 2164
 2165        let lsp_edits = if matches!(formatting_provider, Some(p) if *p != OneOf::Left(false)) {
 2166            let _timer = zlog::time!(logger => "format-full");
 2167            language_server
 2168                .request::<lsp::request::Formatting>(lsp::DocumentFormattingParams {
 2169                    text_document,
 2170                    options: lsp_command::lsp_formatting_options(settings),
 2171                    work_done_progress_params: Default::default(),
 2172                })
 2173                .await
 2174                .into_response()?
 2175        } else if matches!(range_formatting_provider, Some(p) if *p != OneOf::Left(false)) {
 2176            let _timer = zlog::time!(logger => "format-range");
 2177            let buffer_start = lsp::Position::new(0, 0);
 2178            let buffer_end = buffer.read_with(cx, |b, _| point_to_lsp(b.max_point_utf16()))?;
 2179            language_server
 2180                .request::<lsp::request::RangeFormatting>(lsp::DocumentRangeFormattingParams {
 2181                    text_document: text_document.clone(),
 2182                    range: lsp::Range::new(buffer_start, buffer_end),
 2183                    options: lsp_command::lsp_formatting_options(settings),
 2184                    work_done_progress_params: Default::default(),
 2185                })
 2186                .await
 2187                .into_response()?
 2188        } else {
 2189            None
 2190        };
 2191
 2192        if let Some(lsp_edits) = lsp_edits {
 2193            this.update(cx, |this, cx| {
 2194                this.as_local_mut().unwrap().edits_from_lsp(
 2195                    buffer,
 2196                    lsp_edits,
 2197                    language_server.server_id(),
 2198                    None,
 2199                    cx,
 2200                )
 2201            })?
 2202            .await
 2203        } else {
 2204            Ok(Vec::with_capacity(0))
 2205        }
 2206    }
 2207
 2208    async fn format_via_external_command(
 2209        buffer: &FormattableBuffer,
 2210        command: &str,
 2211        arguments: Option<&[String]>,
 2212        cx: &mut AsyncApp,
 2213    ) -> Result<Option<Diff>> {
 2214        let working_dir_path = buffer.handle.update(cx, |buffer, cx| {
 2215            let file = File::from_dyn(buffer.file())?;
 2216            let worktree = file.worktree.read(cx);
 2217            let mut worktree_path = worktree.abs_path().to_path_buf();
 2218            if worktree.root_entry()?.is_file() {
 2219                worktree_path.pop();
 2220            }
 2221            Some(worktree_path)
 2222        })?;
 2223
 2224        let mut child = util::command::new_smol_command(command);
 2225
 2226        if let Some(buffer_env) = buffer.env.as_ref() {
 2227            child.envs(buffer_env);
 2228        }
 2229
 2230        if let Some(working_dir_path) = working_dir_path {
 2231            child.current_dir(working_dir_path);
 2232        }
 2233
 2234        if let Some(arguments) = arguments {
 2235            child.args(arguments.iter().map(|arg| {
 2236                if let Some(buffer_abs_path) = buffer.abs_path.as_ref() {
 2237                    arg.replace("{buffer_path}", &buffer_abs_path.to_string_lossy())
 2238                } else {
 2239                    arg.replace("{buffer_path}", "Untitled")
 2240                }
 2241            }));
 2242        }
 2243
 2244        let mut child = child
 2245            .stdin(smol::process::Stdio::piped())
 2246            .stdout(smol::process::Stdio::piped())
 2247            .stderr(smol::process::Stdio::piped())
 2248            .spawn()?;
 2249
 2250        let stdin = child.stdin.as_mut().context("failed to acquire stdin")?;
 2251        let text = buffer
 2252            .handle
 2253            .read_with(cx, |buffer, _| buffer.as_rope().clone())?;
 2254        for chunk in text.chunks() {
 2255            stdin.write_all(chunk.as_bytes()).await?;
 2256        }
 2257        stdin.flush().await?;
 2258
 2259        let output = child.output().await?;
 2260        anyhow::ensure!(
 2261            output.status.success(),
 2262            "command failed with exit code {:?}:\nstdout: {}\nstderr: {}",
 2263            output.status.code(),
 2264            String::from_utf8_lossy(&output.stdout),
 2265            String::from_utf8_lossy(&output.stderr),
 2266        );
 2267
 2268        let stdout = String::from_utf8(output.stdout)?;
 2269        Ok(Some(
 2270            buffer
 2271                .handle
 2272                .update(cx, |buffer, cx| buffer.diff(stdout, cx))?
 2273                .await,
 2274        ))
 2275    }
 2276
 2277    async fn try_resolve_code_action(
 2278        lang_server: &LanguageServer,
 2279        action: &mut CodeAction,
 2280    ) -> anyhow::Result<()> {
 2281        match &mut action.lsp_action {
 2282            LspAction::Action(lsp_action) => {
 2283                if !action.resolved
 2284                    && GetCodeActions::can_resolve_actions(&lang_server.capabilities())
 2285                    && lsp_action.data.is_some()
 2286                    && (lsp_action.command.is_none() || lsp_action.edit.is_none())
 2287                {
 2288                    *lsp_action = Box::new(
 2289                        lang_server
 2290                            .request::<lsp::request::CodeActionResolveRequest>(*lsp_action.clone())
 2291                            .await
 2292                            .into_response()?,
 2293                    );
 2294                }
 2295            }
 2296            LspAction::CodeLens(lens) => {
 2297                if !action.resolved && GetCodeLens::can_resolve_lens(&lang_server.capabilities()) {
 2298                    *lens = lang_server
 2299                        .request::<lsp::request::CodeLensResolve>(lens.clone())
 2300                        .await
 2301                        .into_response()?;
 2302                }
 2303            }
 2304            LspAction::Command(_) => {}
 2305        }
 2306
 2307        action.resolved = true;
 2308        anyhow::Ok(())
 2309    }
 2310
 2311    fn initialize_buffer(&mut self, buffer_handle: &Entity<Buffer>, cx: &mut Context<LspStore>) {
 2312        let buffer = buffer_handle.read(cx);
 2313
 2314        let file = buffer.file().cloned();
 2315
 2316        let Some(file) = File::from_dyn(file.as_ref()) else {
 2317            return;
 2318        };
 2319        if !file.is_local() {
 2320            return;
 2321        }
 2322        let path = ProjectPath::from_file(file, cx);
 2323        let worktree_id = file.worktree_id(cx);
 2324        let language = buffer.language().cloned();
 2325
 2326        if let Some(diagnostics) = self.diagnostics.get(&worktree_id) {
 2327            for (server_id, diagnostics) in
 2328                diagnostics.get(file.path()).cloned().unwrap_or_default()
 2329            {
 2330                self.update_buffer_diagnostics(
 2331                    buffer_handle,
 2332                    server_id,
 2333                    None,
 2334                    None,
 2335                    None,
 2336                    Vec::new(),
 2337                    diagnostics,
 2338                    cx,
 2339                )
 2340                .log_err();
 2341            }
 2342        }
 2343        let Some(language) = language else {
 2344            return;
 2345        };
 2346        let Some(snapshot) = self
 2347            .worktree_store
 2348            .read(cx)
 2349            .worktree_for_id(worktree_id, cx)
 2350            .map(|worktree| worktree.read(cx).snapshot())
 2351        else {
 2352            return;
 2353        };
 2354        let delegate: Arc<dyn ManifestDelegate> = Arc::new(ManifestQueryDelegate::new(snapshot));
 2355
 2356        for server_id in
 2357            self.lsp_tree
 2358                .get(path, language.name(), language.manifest(), &delegate, cx)
 2359        {
 2360            let server = self
 2361                .language_servers
 2362                .get(&server_id)
 2363                .and_then(|server_state| {
 2364                    if let LanguageServerState::Running { server, .. } = server_state {
 2365                        Some(server.clone())
 2366                    } else {
 2367                        None
 2368                    }
 2369                });
 2370            let server = match server {
 2371                Some(server) => server,
 2372                None => continue,
 2373            };
 2374
 2375            buffer_handle.update(cx, |buffer, cx| {
 2376                buffer.set_completion_triggers(
 2377                    server.server_id(),
 2378                    server
 2379                        .capabilities()
 2380                        .completion_provider
 2381                        .as_ref()
 2382                        .and_then(|provider| {
 2383                            provider
 2384                                .trigger_characters
 2385                                .as_ref()
 2386                                .map(|characters| characters.iter().cloned().collect())
 2387                        })
 2388                        .unwrap_or_default(),
 2389                    cx,
 2390                );
 2391            });
 2392        }
 2393    }
 2394
 2395    pub(crate) fn reset_buffer(&mut self, buffer: &Entity<Buffer>, old_file: &File, cx: &mut App) {
 2396        buffer.update(cx, |buffer, cx| {
 2397            let Some(language) = buffer.language() else {
 2398                return;
 2399            };
 2400            let path = ProjectPath {
 2401                worktree_id: old_file.worktree_id(cx),
 2402                path: old_file.path.clone(),
 2403            };
 2404            for server_id in self.language_server_ids_for_project_path(path, language, cx) {
 2405                buffer.update_diagnostics(server_id, DiagnosticSet::new([], buffer), cx);
 2406                buffer.set_completion_triggers(server_id, Default::default(), cx);
 2407            }
 2408        });
 2409    }
 2410
 2411    fn update_buffer_diagnostics(
 2412        &mut self,
 2413        buffer: &Entity<Buffer>,
 2414        server_id: LanguageServerId,
 2415        registration_id: Option<Option<SharedString>>,
 2416        result_id: Option<SharedString>,
 2417        version: Option<i32>,
 2418        new_diagnostics: Vec<DiagnosticEntry<Unclipped<PointUtf16>>>,
 2419        reused_diagnostics: Vec<DiagnosticEntry<Unclipped<PointUtf16>>>,
 2420        cx: &mut Context<LspStore>,
 2421    ) -> Result<()> {
 2422        fn compare_diagnostics(a: &Diagnostic, b: &Diagnostic) -> Ordering {
 2423            Ordering::Equal
 2424                .then_with(|| b.is_primary.cmp(&a.is_primary))
 2425                .then_with(|| a.is_disk_based.cmp(&b.is_disk_based))
 2426                .then_with(|| a.severity.cmp(&b.severity))
 2427                .then_with(|| a.message.cmp(&b.message))
 2428        }
 2429
 2430        let mut diagnostics = Vec::with_capacity(new_diagnostics.len() + reused_diagnostics.len());
 2431        diagnostics.extend(new_diagnostics.into_iter().map(|d| (true, d)));
 2432        diagnostics.extend(reused_diagnostics.into_iter().map(|d| (false, d)));
 2433
 2434        diagnostics.sort_unstable_by(|(_, a), (_, b)| {
 2435            Ordering::Equal
 2436                .then_with(|| a.range.start.cmp(&b.range.start))
 2437                .then_with(|| b.range.end.cmp(&a.range.end))
 2438                .then_with(|| compare_diagnostics(&a.diagnostic, &b.diagnostic))
 2439        });
 2440
 2441        let snapshot = self.buffer_snapshot_for_lsp_version(buffer, server_id, version, cx)?;
 2442
 2443        let edits_since_save = std::cell::LazyCell::new(|| {
 2444            let saved_version = buffer.read(cx).saved_version();
 2445            Patch::new(snapshot.edits_since::<PointUtf16>(saved_version).collect())
 2446        });
 2447
 2448        let mut sanitized_diagnostics = Vec::with_capacity(diagnostics.len());
 2449
 2450        for (new_diagnostic, entry) in diagnostics {
 2451            let start;
 2452            let end;
 2453            if new_diagnostic && entry.diagnostic.is_disk_based {
 2454                // Some diagnostics are based on files on disk instead of buffers'
 2455                // current contents. Adjust these diagnostics' ranges to reflect
 2456                // any unsaved edits.
 2457                // Do not alter the reused ones though, as their coordinates were stored as anchors
 2458                // and were properly adjusted on reuse.
 2459                start = Unclipped((*edits_since_save).old_to_new(entry.range.start.0));
 2460                end = Unclipped((*edits_since_save).old_to_new(entry.range.end.0));
 2461            } else {
 2462                start = entry.range.start;
 2463                end = entry.range.end;
 2464            }
 2465
 2466            let mut range = snapshot.clip_point_utf16(start, Bias::Left)
 2467                ..snapshot.clip_point_utf16(end, Bias::Right);
 2468
 2469            // Expand empty ranges by one codepoint
 2470            if range.start == range.end {
 2471                // This will be go to the next boundary when being clipped
 2472                range.end.column += 1;
 2473                range.end = snapshot.clip_point_utf16(Unclipped(range.end), Bias::Right);
 2474                if range.start == range.end && range.end.column > 0 {
 2475                    range.start.column -= 1;
 2476                    range.start = snapshot.clip_point_utf16(Unclipped(range.start), Bias::Left);
 2477                }
 2478            }
 2479
 2480            sanitized_diagnostics.push(DiagnosticEntry {
 2481                range,
 2482                diagnostic: entry.diagnostic,
 2483            });
 2484        }
 2485        drop(edits_since_save);
 2486
 2487        let set = DiagnosticSet::new(sanitized_diagnostics, &snapshot);
 2488        buffer.update(cx, |buffer, cx| {
 2489            if let Some(registration_id) = registration_id {
 2490                if let Some(abs_path) = File::from_dyn(buffer.file()).map(|f| f.abs_path(cx)) {
 2491                    self.buffer_pull_diagnostics_result_ids
 2492                        .entry(server_id)
 2493                        .or_default()
 2494                        .entry(registration_id)
 2495                        .or_default()
 2496                        .insert(abs_path, result_id);
 2497                }
 2498            }
 2499
 2500            buffer.update_diagnostics(server_id, set, cx)
 2501        });
 2502
 2503        Ok(())
 2504    }
 2505
 2506    fn register_language_server_for_invisible_worktree(
 2507        &mut self,
 2508        worktree: &Entity<Worktree>,
 2509        language_server_id: LanguageServerId,
 2510        cx: &mut App,
 2511    ) {
 2512        let worktree = worktree.read(cx);
 2513        let worktree_id = worktree.id();
 2514        debug_assert!(!worktree.is_visible());
 2515        let Some(mut origin_seed) = self
 2516            .language_server_ids
 2517            .iter()
 2518            .find_map(|(seed, state)| (state.id == language_server_id).then(|| seed.clone()))
 2519        else {
 2520            return;
 2521        };
 2522        origin_seed.worktree_id = worktree_id;
 2523        self.language_server_ids
 2524            .entry(origin_seed)
 2525            .or_insert_with(|| UnifiedLanguageServer {
 2526                id: language_server_id,
 2527                project_roots: Default::default(),
 2528            });
 2529    }
 2530
 2531    fn register_buffer_with_language_servers(
 2532        &mut self,
 2533        buffer_handle: &Entity<Buffer>,
 2534        only_register_servers: HashSet<LanguageServerSelector>,
 2535        cx: &mut Context<LspStore>,
 2536    ) {
 2537        let buffer = buffer_handle.read(cx);
 2538        let buffer_id = buffer.remote_id();
 2539
 2540        let Some(file) = File::from_dyn(buffer.file()) else {
 2541            return;
 2542        };
 2543        if !file.is_local() {
 2544            return;
 2545        }
 2546
 2547        let abs_path = file.abs_path(cx);
 2548        let Some(uri) = file_path_to_lsp_url(&abs_path).log_err() else {
 2549            return;
 2550        };
 2551        let initial_snapshot = buffer.text_snapshot();
 2552        let worktree_id = file.worktree_id(cx);
 2553
 2554        let Some(language) = buffer.language().cloned() else {
 2555            return;
 2556        };
 2557        let path: Arc<RelPath> = file
 2558            .path()
 2559            .parent()
 2560            .map(Arc::from)
 2561            .unwrap_or_else(|| file.path().clone());
 2562        let Some(worktree) = self
 2563            .worktree_store
 2564            .read(cx)
 2565            .worktree_for_id(worktree_id, cx)
 2566        else {
 2567            return;
 2568        };
 2569        let language_name = language.name();
 2570        let (reused, delegate, servers) = self
 2571            .reuse_existing_language_server(&self.lsp_tree, &worktree, &language_name, cx)
 2572            .map(|(delegate, apply)| (true, delegate, apply(&mut self.lsp_tree)))
 2573            .unwrap_or_else(|| {
 2574                let lsp_delegate = LocalLspAdapterDelegate::from_local_lsp(self, &worktree, cx);
 2575                let delegate: Arc<dyn ManifestDelegate> =
 2576                    Arc::new(ManifestQueryDelegate::new(worktree.read(cx).snapshot()));
 2577
 2578                let servers = self
 2579                    .lsp_tree
 2580                    .walk(
 2581                        ProjectPath { worktree_id, path },
 2582                        language.name(),
 2583                        language.manifest(),
 2584                        &delegate,
 2585                        cx,
 2586                    )
 2587                    .collect::<Vec<_>>();
 2588                (false, lsp_delegate, servers)
 2589            });
 2590        let servers_and_adapters = servers
 2591            .into_iter()
 2592            .filter_map(|server_node| {
 2593                if reused && server_node.server_id().is_none() {
 2594                    return None;
 2595                }
 2596                if !only_register_servers.is_empty() {
 2597                    if let Some(server_id) = server_node.server_id()
 2598                        && !only_register_servers.contains(&LanguageServerSelector::Id(server_id))
 2599                    {
 2600                        return None;
 2601                    }
 2602                    if let Some(name) = server_node.name()
 2603                        && !only_register_servers.contains(&LanguageServerSelector::Name(name))
 2604                    {
 2605                        return None;
 2606                    }
 2607                }
 2608
 2609                let server_id = server_node.server_id_or_init(|disposition| {
 2610                    let path = &disposition.path;
 2611
 2612                    {
 2613                        let uri = Uri::from_file_path(worktree.read(cx).absolutize(&path.path));
 2614
 2615                        let server_id = self.get_or_insert_language_server(
 2616                            &worktree,
 2617                            delegate.clone(),
 2618                            disposition,
 2619                            &language_name,
 2620                            cx,
 2621                        );
 2622
 2623                        if let Some(state) = self.language_servers.get(&server_id)
 2624                            && let Ok(uri) = uri
 2625                        {
 2626                            state.add_workspace_folder(uri);
 2627                        };
 2628                        server_id
 2629                    }
 2630                })?;
 2631                let server_state = self.language_servers.get(&server_id)?;
 2632                if let LanguageServerState::Running {
 2633                    server, adapter, ..
 2634                } = server_state
 2635                {
 2636                    Some((server.clone(), adapter.clone()))
 2637                } else {
 2638                    None
 2639                }
 2640            })
 2641            .collect::<Vec<_>>();
 2642        for (server, adapter) in servers_and_adapters {
 2643            buffer_handle.update(cx, |buffer, cx| {
 2644                buffer.set_completion_triggers(
 2645                    server.server_id(),
 2646                    server
 2647                        .capabilities()
 2648                        .completion_provider
 2649                        .as_ref()
 2650                        .and_then(|provider| {
 2651                            provider
 2652                                .trigger_characters
 2653                                .as_ref()
 2654                                .map(|characters| characters.iter().cloned().collect())
 2655                        })
 2656                        .unwrap_or_default(),
 2657                    cx,
 2658                );
 2659            });
 2660
 2661            let snapshot = LspBufferSnapshot {
 2662                version: 0,
 2663                snapshot: initial_snapshot.clone(),
 2664            };
 2665
 2666            let mut registered = false;
 2667            self.buffer_snapshots
 2668                .entry(buffer_id)
 2669                .or_default()
 2670                .entry(server.server_id())
 2671                .or_insert_with(|| {
 2672                    registered = true;
 2673                    server.register_buffer(
 2674                        uri.clone(),
 2675                        adapter.language_id(&language.name()),
 2676                        0,
 2677                        initial_snapshot.text(),
 2678                    );
 2679
 2680                    vec![snapshot]
 2681                });
 2682
 2683            self.buffers_opened_in_servers
 2684                .entry(buffer_id)
 2685                .or_default()
 2686                .insert(server.server_id());
 2687            if registered {
 2688                cx.emit(LspStoreEvent::LanguageServerUpdate {
 2689                    language_server_id: server.server_id(),
 2690                    name: None,
 2691                    message: proto::update_language_server::Variant::RegisteredForBuffer(
 2692                        proto::RegisteredForBuffer {
 2693                            buffer_abs_path: abs_path.to_string_lossy().into_owned(),
 2694                            buffer_id: buffer_id.to_proto(),
 2695                        },
 2696                    ),
 2697                });
 2698            }
 2699        }
 2700    }
 2701
 2702    fn reuse_existing_language_server<'lang_name>(
 2703        &self,
 2704        server_tree: &LanguageServerTree,
 2705        worktree: &Entity<Worktree>,
 2706        language_name: &'lang_name LanguageName,
 2707        cx: &mut App,
 2708    ) -> Option<(
 2709        Arc<LocalLspAdapterDelegate>,
 2710        impl FnOnce(&mut LanguageServerTree) -> Vec<LanguageServerTreeNode> + use<'lang_name>,
 2711    )> {
 2712        if worktree.read(cx).is_visible() {
 2713            return None;
 2714        }
 2715
 2716        let worktree_store = self.worktree_store.read(cx);
 2717        let servers = server_tree
 2718            .instances
 2719            .iter()
 2720            .filter(|(worktree_id, _)| {
 2721                worktree_store
 2722                    .worktree_for_id(**worktree_id, cx)
 2723                    .is_some_and(|worktree| worktree.read(cx).is_visible())
 2724            })
 2725            .flat_map(|(worktree_id, servers)| {
 2726                servers
 2727                    .roots
 2728                    .iter()
 2729                    .flat_map(|(_, language_servers)| language_servers)
 2730                    .map(move |(_, (server_node, server_languages))| {
 2731                        (worktree_id, server_node, server_languages)
 2732                    })
 2733                    .filter(|(_, _, server_languages)| server_languages.contains(language_name))
 2734                    .map(|(worktree_id, server_node, _)| {
 2735                        (
 2736                            *worktree_id,
 2737                            LanguageServerTreeNode::from(Arc::downgrade(server_node)),
 2738                        )
 2739                    })
 2740            })
 2741            .fold(HashMap::default(), |mut acc, (worktree_id, server_node)| {
 2742                acc.entry(worktree_id)
 2743                    .or_insert_with(Vec::new)
 2744                    .push(server_node);
 2745                acc
 2746            })
 2747            .into_values()
 2748            .max_by_key(|servers| servers.len())?;
 2749
 2750        let worktree_id = worktree.read(cx).id();
 2751        let apply = move |tree: &mut LanguageServerTree| {
 2752            for server_node in &servers {
 2753                tree.register_reused(worktree_id, language_name.clone(), server_node.clone());
 2754            }
 2755            servers
 2756        };
 2757
 2758        let delegate = LocalLspAdapterDelegate::from_local_lsp(self, worktree, cx);
 2759        Some((delegate, apply))
 2760    }
 2761
 2762    pub(crate) fn unregister_old_buffer_from_language_servers(
 2763        &mut self,
 2764        buffer: &Entity<Buffer>,
 2765        old_file: &File,
 2766        cx: &mut App,
 2767    ) {
 2768        let old_path = match old_file.as_local() {
 2769            Some(local) => local.abs_path(cx),
 2770            None => return,
 2771        };
 2772
 2773        let Ok(file_url) = lsp::Uri::from_file_path(old_path.as_path()) else {
 2774            debug_panic!("{old_path:?} is not parseable as an URI");
 2775            return;
 2776        };
 2777        self.unregister_buffer_from_language_servers(buffer, &file_url, cx);
 2778    }
 2779
 2780    pub(crate) fn unregister_buffer_from_language_servers(
 2781        &mut self,
 2782        buffer: &Entity<Buffer>,
 2783        file_url: &lsp::Uri,
 2784        cx: &mut App,
 2785    ) {
 2786        buffer.update(cx, |buffer, cx| {
 2787            let mut snapshots = self.buffer_snapshots.remove(&buffer.remote_id());
 2788
 2789            for (_, language_server) in self.language_servers_for_buffer(buffer, cx) {
 2790                if snapshots
 2791                    .as_mut()
 2792                    .is_some_and(|map| map.remove(&language_server.server_id()).is_some())
 2793                {
 2794                    language_server.unregister_buffer(file_url.clone());
 2795                }
 2796            }
 2797        });
 2798    }
 2799
 2800    fn buffer_snapshot_for_lsp_version(
 2801        &mut self,
 2802        buffer: &Entity<Buffer>,
 2803        server_id: LanguageServerId,
 2804        version: Option<i32>,
 2805        cx: &App,
 2806    ) -> Result<TextBufferSnapshot> {
 2807        const OLD_VERSIONS_TO_RETAIN: i32 = 10;
 2808
 2809        if let Some(version) = version {
 2810            let buffer_id = buffer.read(cx).remote_id();
 2811            let snapshots = if let Some(snapshots) = self
 2812                .buffer_snapshots
 2813                .get_mut(&buffer_id)
 2814                .and_then(|m| m.get_mut(&server_id))
 2815            {
 2816                snapshots
 2817            } else if version == 0 {
 2818                // Some language servers report version 0 even if the buffer hasn't been opened yet.
 2819                // We detect this case and treat it as if the version was `None`.
 2820                return Ok(buffer.read(cx).text_snapshot());
 2821            } else {
 2822                anyhow::bail!("no snapshots found for buffer {buffer_id} and server {server_id}");
 2823            };
 2824
 2825            let found_snapshot = snapshots
 2826                    .binary_search_by_key(&version, |e| e.version)
 2827                    .map(|ix| snapshots[ix].snapshot.clone())
 2828                    .map_err(|_| {
 2829                        anyhow!("snapshot not found for buffer {buffer_id} server {server_id} at version {version}")
 2830                    })?;
 2831
 2832            snapshots.retain(|snapshot| snapshot.version + OLD_VERSIONS_TO_RETAIN >= version);
 2833            Ok(found_snapshot)
 2834        } else {
 2835            Ok((buffer.read(cx)).text_snapshot())
 2836        }
 2837    }
 2838
 2839    async fn get_server_code_actions_from_action_kinds(
 2840        lsp_store: &WeakEntity<LspStore>,
 2841        language_server_id: LanguageServerId,
 2842        code_action_kinds: Vec<lsp::CodeActionKind>,
 2843        buffer: &Entity<Buffer>,
 2844        cx: &mut AsyncApp,
 2845    ) -> Result<Vec<CodeAction>> {
 2846        let actions = lsp_store
 2847            .update(cx, move |this, cx| {
 2848                let request = GetCodeActions {
 2849                    range: text::Anchor::min_max_range_for_buffer(buffer.read(cx).remote_id()),
 2850                    kinds: Some(code_action_kinds),
 2851                };
 2852                let server = LanguageServerToQuery::Other(language_server_id);
 2853                this.request_lsp(buffer.clone(), server, request, cx)
 2854            })?
 2855            .await?;
 2856        Ok(actions)
 2857    }
 2858
 2859    pub async fn execute_code_actions_on_server(
 2860        lsp_store: &WeakEntity<LspStore>,
 2861        language_server: &Arc<LanguageServer>,
 2862
 2863        actions: Vec<CodeAction>,
 2864        push_to_history: bool,
 2865        project_transaction: &mut ProjectTransaction,
 2866        cx: &mut AsyncApp,
 2867    ) -> anyhow::Result<()> {
 2868        for mut action in actions {
 2869            Self::try_resolve_code_action(language_server, &mut action)
 2870                .await
 2871                .context("resolving a formatting code action")?;
 2872
 2873            if let Some(edit) = action.lsp_action.edit() {
 2874                if edit.changes.is_none() && edit.document_changes.is_none() {
 2875                    continue;
 2876                }
 2877
 2878                let new = Self::deserialize_workspace_edit(
 2879                    lsp_store.upgrade().context("project dropped")?,
 2880                    edit.clone(),
 2881                    push_to_history,
 2882                    language_server.clone(),
 2883                    cx,
 2884                )
 2885                .await?;
 2886                project_transaction.0.extend(new.0);
 2887            }
 2888
 2889            if let Some(command) = action.lsp_action.command() {
 2890                let server_capabilities = language_server.capabilities();
 2891                let available_commands = server_capabilities
 2892                    .execute_command_provider
 2893                    .as_ref()
 2894                    .map(|options| options.commands.as_slice())
 2895                    .unwrap_or_default();
 2896                if available_commands.contains(&command.command) {
 2897                    lsp_store.update(cx, |lsp_store, _| {
 2898                        if let LspStoreMode::Local(mode) = &mut lsp_store.mode {
 2899                            mode.last_workspace_edits_by_language_server
 2900                                .remove(&language_server.server_id());
 2901                        }
 2902                    })?;
 2903
 2904                    language_server
 2905                        .request::<lsp::request::ExecuteCommand>(lsp::ExecuteCommandParams {
 2906                            command: command.command.clone(),
 2907                            arguments: command.arguments.clone().unwrap_or_default(),
 2908                            ..Default::default()
 2909                        })
 2910                        .await
 2911                        .into_response()
 2912                        .context("execute command")?;
 2913
 2914                    lsp_store.update(cx, |this, _| {
 2915                        if let LspStoreMode::Local(mode) = &mut this.mode {
 2916                            project_transaction.0.extend(
 2917                                mode.last_workspace_edits_by_language_server
 2918                                    .remove(&language_server.server_id())
 2919                                    .unwrap_or_default()
 2920                                    .0,
 2921                            )
 2922                        }
 2923                    })?;
 2924                } else {
 2925                    log::warn!(
 2926                        "Cannot execute a command {} not listed in the language server capabilities",
 2927                        command.command
 2928                    )
 2929                }
 2930            }
 2931        }
 2932        Ok(())
 2933    }
 2934
 2935    pub async fn deserialize_text_edits(
 2936        this: Entity<LspStore>,
 2937        buffer_to_edit: Entity<Buffer>,
 2938        edits: Vec<lsp::TextEdit>,
 2939        push_to_history: bool,
 2940        _: Arc<CachedLspAdapter>,
 2941        language_server: Arc<LanguageServer>,
 2942        cx: &mut AsyncApp,
 2943    ) -> Result<Option<Transaction>> {
 2944        let edits = this
 2945            .update(cx, |this, cx| {
 2946                this.as_local_mut().unwrap().edits_from_lsp(
 2947                    &buffer_to_edit,
 2948                    edits,
 2949                    language_server.server_id(),
 2950                    None,
 2951                    cx,
 2952                )
 2953            })?
 2954            .await?;
 2955
 2956        let transaction = buffer_to_edit.update(cx, |buffer, cx| {
 2957            buffer.finalize_last_transaction();
 2958            buffer.start_transaction();
 2959            for (range, text) in edits {
 2960                buffer.edit([(range, text)], None, cx);
 2961            }
 2962
 2963            if buffer.end_transaction(cx).is_some() {
 2964                let transaction = buffer.finalize_last_transaction().unwrap().clone();
 2965                if !push_to_history {
 2966                    buffer.forget_transaction(transaction.id);
 2967                }
 2968                Some(transaction)
 2969            } else {
 2970                None
 2971            }
 2972        })?;
 2973
 2974        Ok(transaction)
 2975    }
 2976
 2977    #[allow(clippy::type_complexity)]
 2978    pub(crate) fn edits_from_lsp(
 2979        &mut self,
 2980        buffer: &Entity<Buffer>,
 2981        lsp_edits: impl 'static + Send + IntoIterator<Item = lsp::TextEdit>,
 2982        server_id: LanguageServerId,
 2983        version: Option<i32>,
 2984        cx: &mut Context<LspStore>,
 2985    ) -> Task<Result<Vec<(Range<Anchor>, Arc<str>)>>> {
 2986        let snapshot = self.buffer_snapshot_for_lsp_version(buffer, server_id, version, cx);
 2987        cx.background_spawn(async move {
 2988            let snapshot = snapshot?;
 2989            let mut lsp_edits = lsp_edits
 2990                .into_iter()
 2991                .map(|edit| (range_from_lsp(edit.range), edit.new_text))
 2992                .collect::<Vec<_>>();
 2993
 2994            lsp_edits.sort_by_key(|(range, _)| (range.start, range.end));
 2995
 2996            let mut lsp_edits = lsp_edits.into_iter().peekable();
 2997            let mut edits = Vec::new();
 2998            while let Some((range, mut new_text)) = lsp_edits.next() {
 2999                // Clip invalid ranges provided by the language server.
 3000                let mut range = snapshot.clip_point_utf16(range.start, Bias::Left)
 3001                    ..snapshot.clip_point_utf16(range.end, Bias::Left);
 3002
 3003                // Combine any LSP edits that are adjacent.
 3004                //
 3005                // Also, combine LSP edits that are separated from each other by only
 3006                // a newline. This is important because for some code actions,
 3007                // Rust-analyzer rewrites the entire buffer via a series of edits that
 3008                // are separated by unchanged newline characters.
 3009                //
 3010                // In order for the diffing logic below to work properly, any edits that
 3011                // cancel each other out must be combined into one.
 3012                while let Some((next_range, next_text)) = lsp_edits.peek() {
 3013                    if next_range.start.0 > range.end {
 3014                        if next_range.start.0.row > range.end.row + 1
 3015                            || next_range.start.0.column > 0
 3016                            || snapshot.clip_point_utf16(
 3017                                Unclipped(PointUtf16::new(range.end.row, u32::MAX)),
 3018                                Bias::Left,
 3019                            ) > range.end
 3020                        {
 3021                            break;
 3022                        }
 3023                        new_text.push('\n');
 3024                    }
 3025                    range.end = snapshot.clip_point_utf16(next_range.end, Bias::Left);
 3026                    new_text.push_str(next_text);
 3027                    lsp_edits.next();
 3028                }
 3029
 3030                // For multiline edits, perform a diff of the old and new text so that
 3031                // we can identify the changes more precisely, preserving the locations
 3032                // of any anchors positioned in the unchanged regions.
 3033                if range.end.row > range.start.row {
 3034                    let offset = range.start.to_offset(&snapshot);
 3035                    let old_text = snapshot.text_for_range(range).collect::<String>();
 3036                    let range_edits = language::text_diff(old_text.as_str(), &new_text);
 3037                    edits.extend(range_edits.into_iter().map(|(range, replacement)| {
 3038                        (
 3039                            snapshot.anchor_after(offset + range.start)
 3040                                ..snapshot.anchor_before(offset + range.end),
 3041                            replacement,
 3042                        )
 3043                    }));
 3044                } else if range.end == range.start {
 3045                    let anchor = snapshot.anchor_after(range.start);
 3046                    edits.push((anchor..anchor, new_text.into()));
 3047                } else {
 3048                    let edit_start = snapshot.anchor_after(range.start);
 3049                    let edit_end = snapshot.anchor_before(range.end);
 3050                    edits.push((edit_start..edit_end, new_text.into()));
 3051                }
 3052            }
 3053
 3054            Ok(edits)
 3055        })
 3056    }
 3057
 3058    pub(crate) async fn deserialize_workspace_edit(
 3059        this: Entity<LspStore>,
 3060        edit: lsp::WorkspaceEdit,
 3061        push_to_history: bool,
 3062        language_server: Arc<LanguageServer>,
 3063        cx: &mut AsyncApp,
 3064    ) -> Result<ProjectTransaction> {
 3065        let fs = this.read_with(cx, |this, _| this.as_local().unwrap().fs.clone())?;
 3066
 3067        let mut operations = Vec::new();
 3068        if let Some(document_changes) = edit.document_changes {
 3069            match document_changes {
 3070                lsp::DocumentChanges::Edits(edits) => {
 3071                    operations.extend(edits.into_iter().map(lsp::DocumentChangeOperation::Edit))
 3072                }
 3073                lsp::DocumentChanges::Operations(ops) => operations = ops,
 3074            }
 3075        } else if let Some(changes) = edit.changes {
 3076            operations.extend(changes.into_iter().map(|(uri, edits)| {
 3077                lsp::DocumentChangeOperation::Edit(lsp::TextDocumentEdit {
 3078                    text_document: lsp::OptionalVersionedTextDocumentIdentifier {
 3079                        uri,
 3080                        version: None,
 3081                    },
 3082                    edits: edits.into_iter().map(Edit::Plain).collect(),
 3083                })
 3084            }));
 3085        }
 3086
 3087        let mut project_transaction = ProjectTransaction::default();
 3088        for operation in operations {
 3089            match operation {
 3090                lsp::DocumentChangeOperation::Op(lsp::ResourceOp::Create(op)) => {
 3091                    let abs_path = op
 3092                        .uri
 3093                        .to_file_path()
 3094                        .map_err(|()| anyhow!("can't convert URI to path"))?;
 3095
 3096                    if let Some(parent_path) = abs_path.parent() {
 3097                        fs.create_dir(parent_path).await?;
 3098                    }
 3099                    if abs_path.ends_with("/") {
 3100                        fs.create_dir(&abs_path).await?;
 3101                    } else {
 3102                        fs.create_file(
 3103                            &abs_path,
 3104                            op.options
 3105                                .map(|options| fs::CreateOptions {
 3106                                    overwrite: options.overwrite.unwrap_or(false),
 3107                                    ignore_if_exists: options.ignore_if_exists.unwrap_or(false),
 3108                                })
 3109                                .unwrap_or_default(),
 3110                        )
 3111                        .await?;
 3112                    }
 3113                }
 3114
 3115                lsp::DocumentChangeOperation::Op(lsp::ResourceOp::Rename(op)) => {
 3116                    let source_abs_path = op
 3117                        .old_uri
 3118                        .to_file_path()
 3119                        .map_err(|()| anyhow!("can't convert URI to path"))?;
 3120                    let target_abs_path = op
 3121                        .new_uri
 3122                        .to_file_path()
 3123                        .map_err(|()| anyhow!("can't convert URI to path"))?;
 3124
 3125                    let options = fs::RenameOptions {
 3126                        overwrite: op
 3127                            .options
 3128                            .as_ref()
 3129                            .and_then(|options| options.overwrite)
 3130                            .unwrap_or(false),
 3131                        ignore_if_exists: op
 3132                            .options
 3133                            .as_ref()
 3134                            .and_then(|options| options.ignore_if_exists)
 3135                            .unwrap_or(false),
 3136                        create_parents: true,
 3137                    };
 3138
 3139                    fs.rename(&source_abs_path, &target_abs_path, options)
 3140                        .await?;
 3141                }
 3142
 3143                lsp::DocumentChangeOperation::Op(lsp::ResourceOp::Delete(op)) => {
 3144                    let abs_path = op
 3145                        .uri
 3146                        .to_file_path()
 3147                        .map_err(|()| anyhow!("can't convert URI to path"))?;
 3148                    let options = op
 3149                        .options
 3150                        .map(|options| fs::RemoveOptions {
 3151                            recursive: options.recursive.unwrap_or(false),
 3152                            ignore_if_not_exists: options.ignore_if_not_exists.unwrap_or(false),
 3153                        })
 3154                        .unwrap_or_default();
 3155                    if abs_path.ends_with("/") {
 3156                        fs.remove_dir(&abs_path, options).await?;
 3157                    } else {
 3158                        fs.remove_file(&abs_path, options).await?;
 3159                    }
 3160                }
 3161
 3162                lsp::DocumentChangeOperation::Edit(op) => {
 3163                    let buffer_to_edit = this
 3164                        .update(cx, |this, cx| {
 3165                            this.open_local_buffer_via_lsp(
 3166                                op.text_document.uri.clone(),
 3167                                language_server.server_id(),
 3168                                cx,
 3169                            )
 3170                        })?
 3171                        .await?;
 3172
 3173                    let edits = this
 3174                        .update(cx, |this, cx| {
 3175                            let path = buffer_to_edit.read(cx).project_path(cx);
 3176                            let active_entry = this.active_entry;
 3177                            let is_active_entry = path.is_some_and(|project_path| {
 3178                                this.worktree_store
 3179                                    .read(cx)
 3180                                    .entry_for_path(&project_path, cx)
 3181                                    .is_some_and(|entry| Some(entry.id) == active_entry)
 3182                            });
 3183                            let local = this.as_local_mut().unwrap();
 3184
 3185                            let (mut edits, mut snippet_edits) = (vec![], vec![]);
 3186                            for edit in op.edits {
 3187                                match edit {
 3188                                    Edit::Plain(edit) => {
 3189                                        if !edits.contains(&edit) {
 3190                                            edits.push(edit)
 3191                                        }
 3192                                    }
 3193                                    Edit::Annotated(edit) => {
 3194                                        if !edits.contains(&edit.text_edit) {
 3195                                            edits.push(edit.text_edit)
 3196                                        }
 3197                                    }
 3198                                    Edit::Snippet(edit) => {
 3199                                        let Ok(snippet) = Snippet::parse(&edit.snippet.value)
 3200                                        else {
 3201                                            continue;
 3202                                        };
 3203
 3204                                        if is_active_entry {
 3205                                            snippet_edits.push((edit.range, snippet));
 3206                                        } else {
 3207                                            // Since this buffer is not focused, apply a normal edit.
 3208                                            let new_edit = TextEdit {
 3209                                                range: edit.range,
 3210                                                new_text: snippet.text,
 3211                                            };
 3212                                            if !edits.contains(&new_edit) {
 3213                                                edits.push(new_edit);
 3214                                            }
 3215                                        }
 3216                                    }
 3217                                }
 3218                            }
 3219                            if !snippet_edits.is_empty() {
 3220                                let buffer_id = buffer_to_edit.read(cx).remote_id();
 3221                                let version = if let Some(buffer_version) = op.text_document.version
 3222                                {
 3223                                    local
 3224                                        .buffer_snapshot_for_lsp_version(
 3225                                            &buffer_to_edit,
 3226                                            language_server.server_id(),
 3227                                            Some(buffer_version),
 3228                                            cx,
 3229                                        )
 3230                                        .ok()
 3231                                        .map(|snapshot| snapshot.version)
 3232                                } else {
 3233                                    Some(buffer_to_edit.read(cx).saved_version().clone())
 3234                                };
 3235
 3236                                let most_recent_edit =
 3237                                    version.and_then(|version| version.most_recent());
 3238                                // Check if the edit that triggered that edit has been made by this participant.
 3239
 3240                                if let Some(most_recent_edit) = most_recent_edit {
 3241                                    cx.emit(LspStoreEvent::SnippetEdit {
 3242                                        buffer_id,
 3243                                        edits: snippet_edits,
 3244                                        most_recent_edit,
 3245                                    });
 3246                                }
 3247                            }
 3248
 3249                            local.edits_from_lsp(
 3250                                &buffer_to_edit,
 3251                                edits,
 3252                                language_server.server_id(),
 3253                                op.text_document.version,
 3254                                cx,
 3255                            )
 3256                        })?
 3257                        .await?;
 3258
 3259                    let transaction = buffer_to_edit.update(cx, |buffer, cx| {
 3260                        buffer.finalize_last_transaction();
 3261                        buffer.start_transaction();
 3262                        for (range, text) in edits {
 3263                            buffer.edit([(range, text)], None, cx);
 3264                        }
 3265
 3266                        buffer.end_transaction(cx).and_then(|transaction_id| {
 3267                            if push_to_history {
 3268                                buffer.finalize_last_transaction();
 3269                                buffer.get_transaction(transaction_id).cloned()
 3270                            } else {
 3271                                buffer.forget_transaction(transaction_id)
 3272                            }
 3273                        })
 3274                    })?;
 3275                    if let Some(transaction) = transaction {
 3276                        project_transaction.0.insert(buffer_to_edit, transaction);
 3277                    }
 3278                }
 3279            }
 3280        }
 3281
 3282        Ok(project_transaction)
 3283    }
 3284
 3285    async fn on_lsp_workspace_edit(
 3286        this: WeakEntity<LspStore>,
 3287        params: lsp::ApplyWorkspaceEditParams,
 3288        server_id: LanguageServerId,
 3289        cx: &mut AsyncApp,
 3290    ) -> Result<lsp::ApplyWorkspaceEditResponse> {
 3291        let this = this.upgrade().context("project project closed")?;
 3292        let language_server = this
 3293            .read_with(cx, |this, _| this.language_server_for_id(server_id))?
 3294            .context("language server not found")?;
 3295        let transaction = Self::deserialize_workspace_edit(
 3296            this.clone(),
 3297            params.edit,
 3298            true,
 3299            language_server.clone(),
 3300            cx,
 3301        )
 3302        .await
 3303        .log_err();
 3304        this.update(cx, |this, _| {
 3305            if let Some(transaction) = transaction {
 3306                this.as_local_mut()
 3307                    .unwrap()
 3308                    .last_workspace_edits_by_language_server
 3309                    .insert(server_id, transaction);
 3310            }
 3311        })?;
 3312        Ok(lsp::ApplyWorkspaceEditResponse {
 3313            applied: true,
 3314            failed_change: None,
 3315            failure_reason: None,
 3316        })
 3317    }
 3318
 3319    fn remove_worktree(
 3320        &mut self,
 3321        id_to_remove: WorktreeId,
 3322        cx: &mut Context<LspStore>,
 3323    ) -> Vec<LanguageServerId> {
 3324        self.restricted_worktrees_tasks.remove(&id_to_remove);
 3325        self.diagnostics.remove(&id_to_remove);
 3326        self.prettier_store.update(cx, |prettier_store, cx| {
 3327            prettier_store.remove_worktree(id_to_remove, cx);
 3328        });
 3329
 3330        let mut servers_to_remove = BTreeSet::default();
 3331        let mut servers_to_preserve = HashSet::default();
 3332        for (seed, state) in &self.language_server_ids {
 3333            if seed.worktree_id == id_to_remove {
 3334                servers_to_remove.insert(state.id);
 3335            } else {
 3336                servers_to_preserve.insert(state.id);
 3337            }
 3338        }
 3339        servers_to_remove.retain(|server_id| !servers_to_preserve.contains(server_id));
 3340        self.language_server_ids
 3341            .retain(|_, state| !servers_to_remove.contains(&state.id));
 3342        for server_id_to_remove in &servers_to_remove {
 3343            self.language_server_watched_paths
 3344                .remove(server_id_to_remove);
 3345            self.language_server_paths_watched_for_rename
 3346                .remove(server_id_to_remove);
 3347            self.last_workspace_edits_by_language_server
 3348                .remove(server_id_to_remove);
 3349            self.language_servers.remove(server_id_to_remove);
 3350            self.buffer_pull_diagnostics_result_ids
 3351                .remove(server_id_to_remove);
 3352            self.workspace_pull_diagnostics_result_ids
 3353                .remove(server_id_to_remove);
 3354            for buffer_servers in self.buffers_opened_in_servers.values_mut() {
 3355                buffer_servers.remove(server_id_to_remove);
 3356            }
 3357            cx.emit(LspStoreEvent::LanguageServerRemoved(*server_id_to_remove));
 3358        }
 3359        servers_to_remove.into_iter().collect()
 3360    }
 3361
 3362    fn rebuild_watched_paths_inner<'a>(
 3363        &'a self,
 3364        language_server_id: LanguageServerId,
 3365        watchers: impl Iterator<Item = &'a FileSystemWatcher>,
 3366        cx: &mut Context<LspStore>,
 3367    ) -> LanguageServerWatchedPathsBuilder {
 3368        let worktrees = self
 3369            .worktree_store
 3370            .read(cx)
 3371            .worktrees()
 3372            .filter_map(|worktree| {
 3373                self.language_servers_for_worktree(worktree.read(cx).id())
 3374                    .find(|server| server.server_id() == language_server_id)
 3375                    .map(|_| worktree)
 3376            })
 3377            .collect::<Vec<_>>();
 3378
 3379        let mut worktree_globs = HashMap::default();
 3380        let mut abs_globs = HashMap::default();
 3381        log::trace!(
 3382            "Processing new watcher paths for language server with id {}",
 3383            language_server_id
 3384        );
 3385
 3386        for watcher in watchers {
 3387            if let Some((worktree, literal_prefix, pattern)) =
 3388                Self::worktree_and_path_for_file_watcher(&worktrees, watcher, cx)
 3389            {
 3390                worktree.update(cx, |worktree, _| {
 3391                    if let Some((tree, glob)) =
 3392                        worktree.as_local_mut().zip(Glob::new(&pattern).log_err())
 3393                    {
 3394                        tree.add_path_prefix_to_scan(literal_prefix);
 3395                        worktree_globs
 3396                            .entry(tree.id())
 3397                            .or_insert_with(GlobSetBuilder::new)
 3398                            .add(glob);
 3399                    }
 3400                });
 3401            } else {
 3402                let (path, pattern) = match &watcher.glob_pattern {
 3403                    lsp::GlobPattern::String(s) => {
 3404                        let watcher_path = SanitizedPath::new(s);
 3405                        let path = glob_literal_prefix(watcher_path.as_path());
 3406                        let pattern = watcher_path
 3407                            .as_path()
 3408                            .strip_prefix(&path)
 3409                            .map(|p| p.to_string_lossy().into_owned())
 3410                            .unwrap_or_else(|e| {
 3411                                debug_panic!(
 3412                                    "Failed to strip prefix for string pattern: {}, with prefix: {}, with error: {}",
 3413                                    s,
 3414                                    path.display(),
 3415                                    e
 3416                                );
 3417                                watcher_path.as_path().to_string_lossy().into_owned()
 3418                            });
 3419                        (path, pattern)
 3420                    }
 3421                    lsp::GlobPattern::Relative(rp) => {
 3422                        let Ok(mut base_uri) = match &rp.base_uri {
 3423                            lsp::OneOf::Left(workspace_folder) => &workspace_folder.uri,
 3424                            lsp::OneOf::Right(base_uri) => base_uri,
 3425                        }
 3426                        .to_file_path() else {
 3427                            continue;
 3428                        };
 3429
 3430                        let path = glob_literal_prefix(Path::new(&rp.pattern));
 3431                        let pattern = Path::new(&rp.pattern)
 3432                            .strip_prefix(&path)
 3433                            .map(|p| p.to_string_lossy().into_owned())
 3434                            .unwrap_or_else(|e| {
 3435                                debug_panic!(
 3436                                    "Failed to strip prefix for relative pattern: {}, with prefix: {}, with error: {}",
 3437                                    rp.pattern,
 3438                                    path.display(),
 3439                                    e
 3440                                );
 3441                                rp.pattern.clone()
 3442                            });
 3443                        base_uri.push(path);
 3444                        (base_uri, pattern)
 3445                    }
 3446                };
 3447
 3448                if let Some(glob) = Glob::new(&pattern).log_err() {
 3449                    if !path
 3450                        .components()
 3451                        .any(|c| matches!(c, path::Component::Normal(_)))
 3452                    {
 3453                        // For an unrooted glob like `**/Cargo.toml`, watch it within each worktree,
 3454                        // rather than adding a new watcher for `/`.
 3455                        for worktree in &worktrees {
 3456                            worktree_globs
 3457                                .entry(worktree.read(cx).id())
 3458                                .or_insert_with(GlobSetBuilder::new)
 3459                                .add(glob.clone());
 3460                        }
 3461                    } else {
 3462                        abs_globs
 3463                            .entry(path.into())
 3464                            .or_insert_with(GlobSetBuilder::new)
 3465                            .add(glob);
 3466                    }
 3467                }
 3468            }
 3469        }
 3470
 3471        let mut watch_builder = LanguageServerWatchedPathsBuilder::default();
 3472        for (worktree_id, builder) in worktree_globs {
 3473            if let Ok(globset) = builder.build() {
 3474                watch_builder.watch_worktree(worktree_id, globset);
 3475            }
 3476        }
 3477        for (abs_path, builder) in abs_globs {
 3478            if let Ok(globset) = builder.build() {
 3479                watch_builder.watch_abs_path(abs_path, globset);
 3480            }
 3481        }
 3482        watch_builder
 3483    }
 3484
 3485    fn worktree_and_path_for_file_watcher(
 3486        worktrees: &[Entity<Worktree>],
 3487        watcher: &FileSystemWatcher,
 3488        cx: &App,
 3489    ) -> Option<(Entity<Worktree>, Arc<RelPath>, String)> {
 3490        worktrees.iter().find_map(|worktree| {
 3491            let tree = worktree.read(cx);
 3492            let worktree_root_path = tree.abs_path();
 3493            let path_style = tree.path_style();
 3494            match &watcher.glob_pattern {
 3495                lsp::GlobPattern::String(s) => {
 3496                    let watcher_path = SanitizedPath::new(s);
 3497                    let relative = watcher_path
 3498                        .as_path()
 3499                        .strip_prefix(&worktree_root_path)
 3500                        .ok()?;
 3501                    let literal_prefix = glob_literal_prefix(relative);
 3502                    Some((
 3503                        worktree.clone(),
 3504                        RelPath::new(&literal_prefix, path_style).ok()?.into_arc(),
 3505                        relative.to_string_lossy().into_owned(),
 3506                    ))
 3507                }
 3508                lsp::GlobPattern::Relative(rp) => {
 3509                    let base_uri = match &rp.base_uri {
 3510                        lsp::OneOf::Left(workspace_folder) => &workspace_folder.uri,
 3511                        lsp::OneOf::Right(base_uri) => base_uri,
 3512                    }
 3513                    .to_file_path()
 3514                    .ok()?;
 3515                    let relative = base_uri.strip_prefix(&worktree_root_path).ok()?;
 3516                    let mut literal_prefix = relative.to_owned();
 3517                    literal_prefix.push(glob_literal_prefix(Path::new(&rp.pattern)));
 3518                    Some((
 3519                        worktree.clone(),
 3520                        RelPath::new(&literal_prefix, path_style).ok()?.into_arc(),
 3521                        rp.pattern.clone(),
 3522                    ))
 3523                }
 3524            }
 3525        })
 3526    }
 3527
 3528    fn rebuild_watched_paths(
 3529        &mut self,
 3530        language_server_id: LanguageServerId,
 3531        cx: &mut Context<LspStore>,
 3532    ) {
 3533        let Some(registrations) = self
 3534            .language_server_dynamic_registrations
 3535            .get(&language_server_id)
 3536        else {
 3537            return;
 3538        };
 3539
 3540        let watch_builder = self.rebuild_watched_paths_inner(
 3541            language_server_id,
 3542            registrations.did_change_watched_files.values().flatten(),
 3543            cx,
 3544        );
 3545        let watcher = watch_builder.build(self.fs.clone(), language_server_id, cx);
 3546        self.language_server_watched_paths
 3547            .insert(language_server_id, watcher);
 3548
 3549        cx.notify();
 3550    }
 3551
 3552    fn on_lsp_did_change_watched_files(
 3553        &mut self,
 3554        language_server_id: LanguageServerId,
 3555        registration_id: &str,
 3556        params: DidChangeWatchedFilesRegistrationOptions,
 3557        cx: &mut Context<LspStore>,
 3558    ) {
 3559        let registrations = self
 3560            .language_server_dynamic_registrations
 3561            .entry(language_server_id)
 3562            .or_default();
 3563
 3564        registrations
 3565            .did_change_watched_files
 3566            .insert(registration_id.to_string(), params.watchers);
 3567
 3568        self.rebuild_watched_paths(language_server_id, cx);
 3569    }
 3570
 3571    fn on_lsp_unregister_did_change_watched_files(
 3572        &mut self,
 3573        language_server_id: LanguageServerId,
 3574        registration_id: &str,
 3575        cx: &mut Context<LspStore>,
 3576    ) {
 3577        let registrations = self
 3578            .language_server_dynamic_registrations
 3579            .entry(language_server_id)
 3580            .or_default();
 3581
 3582        if registrations
 3583            .did_change_watched_files
 3584            .remove(registration_id)
 3585            .is_some()
 3586        {
 3587            log::info!(
 3588                "language server {}: unregistered workspace/DidChangeWatchedFiles capability with id {}",
 3589                language_server_id,
 3590                registration_id
 3591            );
 3592        } else {
 3593            log::warn!(
 3594                "language server {}: failed to unregister workspace/DidChangeWatchedFiles capability with id {}. not registered.",
 3595                language_server_id,
 3596                registration_id
 3597            );
 3598        }
 3599
 3600        self.rebuild_watched_paths(language_server_id, cx);
 3601    }
 3602
 3603    async fn initialization_options_for_adapter(
 3604        adapter: Arc<dyn LspAdapter>,
 3605        delegate: &Arc<dyn LspAdapterDelegate>,
 3606    ) -> Result<Option<serde_json::Value>> {
 3607        let Some(mut initialization_config) =
 3608            adapter.clone().initialization_options(delegate).await?
 3609        else {
 3610            return Ok(None);
 3611        };
 3612
 3613        for other_adapter in delegate.registered_lsp_adapters() {
 3614            if other_adapter.name() == adapter.name() {
 3615                continue;
 3616            }
 3617            if let Ok(Some(target_config)) = other_adapter
 3618                .clone()
 3619                .additional_initialization_options(adapter.name(), delegate)
 3620                .await
 3621            {
 3622                merge_json_value_into(target_config.clone(), &mut initialization_config);
 3623            }
 3624        }
 3625
 3626        Ok(Some(initialization_config))
 3627    }
 3628
 3629    async fn workspace_configuration_for_adapter(
 3630        adapter: Arc<dyn LspAdapter>,
 3631        delegate: &Arc<dyn LspAdapterDelegate>,
 3632        toolchain: Option<Toolchain>,
 3633        requested_uri: Option<Uri>,
 3634        cx: &mut AsyncApp,
 3635    ) -> Result<serde_json::Value> {
 3636        let mut workspace_config = adapter
 3637            .clone()
 3638            .workspace_configuration(delegate, toolchain, requested_uri, cx)
 3639            .await?;
 3640
 3641        for other_adapter in delegate.registered_lsp_adapters() {
 3642            if other_adapter.name() == adapter.name() {
 3643                continue;
 3644            }
 3645            if let Ok(Some(target_config)) = other_adapter
 3646                .clone()
 3647                .additional_workspace_configuration(adapter.name(), delegate, cx)
 3648                .await
 3649            {
 3650                merge_json_value_into(target_config.clone(), &mut workspace_config);
 3651            }
 3652        }
 3653
 3654        Ok(workspace_config)
 3655    }
 3656
 3657    fn language_server_for_id(&self, id: LanguageServerId) -> Option<Arc<LanguageServer>> {
 3658        if let Some(LanguageServerState::Running { server, .. }) = self.language_servers.get(&id) {
 3659            Some(server.clone())
 3660        } else if let Some((_, server)) = self.supplementary_language_servers.get(&id) {
 3661            Some(Arc::clone(server))
 3662        } else {
 3663            None
 3664        }
 3665    }
 3666}
 3667
 3668fn notify_server_capabilities_updated(server: &LanguageServer, cx: &mut Context<LspStore>) {
 3669    if let Some(capabilities) = serde_json::to_string(&server.capabilities()).ok() {
 3670        cx.emit(LspStoreEvent::LanguageServerUpdate {
 3671            language_server_id: server.server_id(),
 3672            name: Some(server.name()),
 3673            message: proto::update_language_server::Variant::MetadataUpdated(
 3674                proto::ServerMetadataUpdated {
 3675                    capabilities: Some(capabilities),
 3676                    binary: Some(proto::LanguageServerBinaryInfo {
 3677                        path: server.binary().path.to_string_lossy().into_owned(),
 3678                        arguments: server
 3679                            .binary()
 3680                            .arguments
 3681                            .iter()
 3682                            .map(|arg| arg.to_string_lossy().into_owned())
 3683                            .collect(),
 3684                    }),
 3685                    configuration: serde_json::to_string(server.configuration()).ok(),
 3686                    workspace_folders: server
 3687                        .workspace_folders()
 3688                        .iter()
 3689                        .map(|uri| uri.to_string())
 3690                        .collect(),
 3691                },
 3692            ),
 3693        });
 3694    }
 3695}
 3696
 3697#[derive(Debug)]
 3698pub struct FormattableBuffer {
 3699    handle: Entity<Buffer>,
 3700    abs_path: Option<PathBuf>,
 3701    env: Option<HashMap<String, String>>,
 3702    ranges: Option<Vec<Range<Anchor>>>,
 3703}
 3704
 3705pub struct RemoteLspStore {
 3706    upstream_client: Option<AnyProtoClient>,
 3707    upstream_project_id: u64,
 3708}
 3709
 3710pub(crate) enum LspStoreMode {
 3711    Local(LocalLspStore),   // ssh host and collab host
 3712    Remote(RemoteLspStore), // collab guest
 3713}
 3714
 3715impl LspStoreMode {
 3716    fn is_local(&self) -> bool {
 3717        matches!(self, LspStoreMode::Local(_))
 3718    }
 3719}
 3720
 3721pub struct LspStore {
 3722    mode: LspStoreMode,
 3723    last_formatting_failure: Option<String>,
 3724    downstream_client: Option<(AnyProtoClient, u64)>,
 3725    nonce: u128,
 3726    buffer_store: Entity<BufferStore>,
 3727    worktree_store: Entity<WorktreeStore>,
 3728    pub languages: Arc<LanguageRegistry>,
 3729    pub language_server_statuses: BTreeMap<LanguageServerId, LanguageServerStatus>,
 3730    active_entry: Option<ProjectEntryId>,
 3731    _maintain_workspace_config: (Task<Result<()>>, watch::Sender<()>),
 3732    _maintain_buffer_languages: Task<()>,
 3733    diagnostic_summaries:
 3734        HashMap<WorktreeId, HashMap<Arc<RelPath>, HashMap<LanguageServerId, DiagnosticSummary>>>,
 3735    pub lsp_server_capabilities: HashMap<LanguageServerId, lsp::ServerCapabilities>,
 3736    lsp_data: HashMap<BufferId, BufferLspData>,
 3737    next_hint_id: Arc<AtomicUsize>,
 3738}
 3739
 3740#[derive(Debug)]
 3741pub struct BufferLspData {
 3742    buffer_version: Global,
 3743    document_colors: Option<DocumentColorData>,
 3744    code_lens: Option<CodeLensData>,
 3745    inlay_hints: BufferInlayHints,
 3746    lsp_requests: HashMap<LspKey, HashMap<LspRequestId, Task<()>>>,
 3747    chunk_lsp_requests: HashMap<LspKey, HashMap<RowChunk, LspRequestId>>,
 3748}
 3749
 3750#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
 3751struct LspKey {
 3752    request_type: TypeId,
 3753    server_queried: Option<LanguageServerId>,
 3754}
 3755
 3756impl BufferLspData {
 3757    fn new(buffer: &Entity<Buffer>, cx: &mut App) -> Self {
 3758        Self {
 3759            buffer_version: buffer.read(cx).version(),
 3760            document_colors: None,
 3761            code_lens: None,
 3762            inlay_hints: BufferInlayHints::new(buffer, cx),
 3763            lsp_requests: HashMap::default(),
 3764            chunk_lsp_requests: HashMap::default(),
 3765        }
 3766    }
 3767
 3768    fn remove_server_data(&mut self, for_server: LanguageServerId) {
 3769        if let Some(document_colors) = &mut self.document_colors {
 3770            document_colors.colors.remove(&for_server);
 3771            document_colors.cache_version += 1;
 3772        }
 3773
 3774        if let Some(code_lens) = &mut self.code_lens {
 3775            code_lens.lens.remove(&for_server);
 3776        }
 3777
 3778        self.inlay_hints.remove_server_data(for_server);
 3779    }
 3780
 3781    #[cfg(any(test, feature = "test-support"))]
 3782    pub fn inlay_hints(&self) -> &BufferInlayHints {
 3783        &self.inlay_hints
 3784    }
 3785}
 3786
 3787#[derive(Debug, Default, Clone)]
 3788pub struct DocumentColors {
 3789    pub colors: HashSet<DocumentColor>,
 3790    pub cache_version: Option<usize>,
 3791}
 3792
 3793type DocumentColorTask = Shared<Task<std::result::Result<DocumentColors, Arc<anyhow::Error>>>>;
 3794type CodeLensTask = Shared<Task<std::result::Result<Option<Vec<CodeAction>>, Arc<anyhow::Error>>>>;
 3795
 3796#[derive(Debug, Default)]
 3797struct DocumentColorData {
 3798    colors: HashMap<LanguageServerId, HashSet<DocumentColor>>,
 3799    cache_version: usize,
 3800    colors_update: Option<(Global, DocumentColorTask)>,
 3801}
 3802
 3803#[derive(Debug, Default)]
 3804struct CodeLensData {
 3805    lens: HashMap<LanguageServerId, Vec<CodeAction>>,
 3806    update: Option<(Global, CodeLensTask)>,
 3807}
 3808
 3809#[derive(Debug)]
 3810pub enum LspStoreEvent {
 3811    LanguageServerAdded(LanguageServerId, LanguageServerName, Option<WorktreeId>),
 3812    LanguageServerRemoved(LanguageServerId),
 3813    LanguageServerUpdate {
 3814        language_server_id: LanguageServerId,
 3815        name: Option<LanguageServerName>,
 3816        message: proto::update_language_server::Variant,
 3817    },
 3818    LanguageServerLog(LanguageServerId, LanguageServerLogType, String),
 3819    LanguageServerPrompt(LanguageServerPromptRequest),
 3820    LanguageDetected {
 3821        buffer: Entity<Buffer>,
 3822        new_language: Option<Arc<Language>>,
 3823    },
 3824    Notification(String),
 3825    RefreshInlayHints {
 3826        server_id: LanguageServerId,
 3827        request_id: Option<usize>,
 3828    },
 3829    RefreshCodeLens,
 3830    DiagnosticsUpdated {
 3831        server_id: LanguageServerId,
 3832        paths: Vec<ProjectPath>,
 3833    },
 3834    DiskBasedDiagnosticsStarted {
 3835        language_server_id: LanguageServerId,
 3836    },
 3837    DiskBasedDiagnosticsFinished {
 3838        language_server_id: LanguageServerId,
 3839    },
 3840    SnippetEdit {
 3841        buffer_id: BufferId,
 3842        edits: Vec<(lsp::Range, Snippet)>,
 3843        most_recent_edit: clock::Lamport,
 3844    },
 3845}
 3846
 3847#[derive(Clone, Debug, Serialize)]
 3848pub struct LanguageServerStatus {
 3849    pub name: LanguageServerName,
 3850    pub pending_work: BTreeMap<ProgressToken, LanguageServerProgress>,
 3851    pub has_pending_diagnostic_updates: bool,
 3852    pub progress_tokens: HashSet<ProgressToken>,
 3853    pub worktree: Option<WorktreeId>,
 3854    pub binary: Option<LanguageServerBinary>,
 3855    pub configuration: Option<Value>,
 3856    pub workspace_folders: BTreeSet<Uri>,
 3857}
 3858
 3859#[derive(Clone, Debug)]
 3860struct CoreSymbol {
 3861    pub language_server_name: LanguageServerName,
 3862    pub source_worktree_id: WorktreeId,
 3863    pub source_language_server_id: LanguageServerId,
 3864    pub path: SymbolLocation,
 3865    pub name: String,
 3866    pub kind: lsp::SymbolKind,
 3867    pub range: Range<Unclipped<PointUtf16>>,
 3868}
 3869
 3870#[derive(Clone, Debug, PartialEq, Eq)]
 3871pub enum SymbolLocation {
 3872    InProject(ProjectPath),
 3873    OutsideProject {
 3874        abs_path: Arc<Path>,
 3875        signature: [u8; 32],
 3876    },
 3877}
 3878
 3879impl SymbolLocation {
 3880    fn file_name(&self) -> Option<&str> {
 3881        match self {
 3882            Self::InProject(path) => path.path.file_name(),
 3883            Self::OutsideProject { abs_path, .. } => abs_path.file_name()?.to_str(),
 3884        }
 3885    }
 3886}
 3887
 3888impl LspStore {
 3889    pub fn init(client: &AnyProtoClient) {
 3890        client.add_entity_request_handler(Self::handle_lsp_query);
 3891        client.add_entity_message_handler(Self::handle_lsp_query_response);
 3892        client.add_entity_request_handler(Self::handle_restart_language_servers);
 3893        client.add_entity_request_handler(Self::handle_stop_language_servers);
 3894        client.add_entity_request_handler(Self::handle_cancel_language_server_work);
 3895        client.add_entity_message_handler(Self::handle_start_language_server);
 3896        client.add_entity_message_handler(Self::handle_update_language_server);
 3897        client.add_entity_message_handler(Self::handle_language_server_log);
 3898        client.add_entity_message_handler(Self::handle_update_diagnostic_summary);
 3899        client.add_entity_request_handler(Self::handle_format_buffers);
 3900        client.add_entity_request_handler(Self::handle_apply_code_action_kind);
 3901        client.add_entity_request_handler(Self::handle_resolve_completion_documentation);
 3902        client.add_entity_request_handler(Self::handle_apply_code_action);
 3903        client.add_entity_request_handler(Self::handle_get_project_symbols);
 3904        client.add_entity_request_handler(Self::handle_resolve_inlay_hint);
 3905        client.add_entity_request_handler(Self::handle_get_color_presentation);
 3906        client.add_entity_request_handler(Self::handle_open_buffer_for_symbol);
 3907        client.add_entity_request_handler(Self::handle_refresh_inlay_hints);
 3908        client.add_entity_request_handler(Self::handle_refresh_code_lens);
 3909        client.add_entity_request_handler(Self::handle_on_type_formatting);
 3910        client.add_entity_request_handler(Self::handle_apply_additional_edits_for_completion);
 3911        client.add_entity_request_handler(Self::handle_register_buffer_with_language_servers);
 3912        client.add_entity_request_handler(Self::handle_rename_project_entry);
 3913        client.add_entity_request_handler(Self::handle_pull_workspace_diagnostics);
 3914        client.add_entity_request_handler(Self::handle_lsp_get_completions);
 3915        client.add_entity_request_handler(Self::handle_lsp_command::<GetDocumentHighlights>);
 3916        client.add_entity_request_handler(Self::handle_lsp_command::<GetDocumentSymbols>);
 3917        client.add_entity_request_handler(Self::handle_lsp_command::<PrepareRename>);
 3918        client.add_entity_request_handler(Self::handle_lsp_command::<PerformRename>);
 3919        client.add_entity_request_handler(Self::handle_lsp_command::<LinkedEditingRange>);
 3920
 3921        client.add_entity_request_handler(Self::handle_lsp_ext_cancel_flycheck);
 3922        client.add_entity_request_handler(Self::handle_lsp_ext_run_flycheck);
 3923        client.add_entity_request_handler(Self::handle_lsp_ext_clear_flycheck);
 3924        client.add_entity_request_handler(Self::handle_lsp_command::<lsp_ext_command::ExpandMacro>);
 3925        client.add_entity_request_handler(Self::handle_lsp_command::<lsp_ext_command::OpenDocs>);
 3926        client.add_entity_request_handler(
 3927            Self::handle_lsp_command::<lsp_ext_command::GoToParentModule>,
 3928        );
 3929        client.add_entity_request_handler(
 3930            Self::handle_lsp_command::<lsp_ext_command::GetLspRunnables>,
 3931        );
 3932        client.add_entity_request_handler(
 3933            Self::handle_lsp_command::<lsp_ext_command::SwitchSourceHeader>,
 3934        );
 3935    }
 3936
 3937    pub fn as_remote(&self) -> Option<&RemoteLspStore> {
 3938        match &self.mode {
 3939            LspStoreMode::Remote(remote_lsp_store) => Some(remote_lsp_store),
 3940            _ => None,
 3941        }
 3942    }
 3943
 3944    pub fn as_local(&self) -> Option<&LocalLspStore> {
 3945        match &self.mode {
 3946            LspStoreMode::Local(local_lsp_store) => Some(local_lsp_store),
 3947            _ => None,
 3948        }
 3949    }
 3950
 3951    pub fn as_local_mut(&mut self) -> Option<&mut LocalLspStore> {
 3952        match &mut self.mode {
 3953            LspStoreMode::Local(local_lsp_store) => Some(local_lsp_store),
 3954            _ => None,
 3955        }
 3956    }
 3957
 3958    pub fn upstream_client(&self) -> Option<(AnyProtoClient, u64)> {
 3959        match &self.mode {
 3960            LspStoreMode::Remote(RemoteLspStore {
 3961                upstream_client: Some(upstream_client),
 3962                upstream_project_id,
 3963                ..
 3964            }) => Some((upstream_client.clone(), *upstream_project_id)),
 3965
 3966            LspStoreMode::Remote(RemoteLspStore {
 3967                upstream_client: None,
 3968                ..
 3969            }) => None,
 3970            LspStoreMode::Local(_) => None,
 3971        }
 3972    }
 3973
 3974    pub fn new_local(
 3975        buffer_store: Entity<BufferStore>,
 3976        worktree_store: Entity<WorktreeStore>,
 3977        prettier_store: Entity<PrettierStore>,
 3978        toolchain_store: Entity<LocalToolchainStore>,
 3979        environment: Entity<ProjectEnvironment>,
 3980        manifest_tree: Entity<ManifestTree>,
 3981        languages: Arc<LanguageRegistry>,
 3982        http_client: Arc<dyn HttpClient>,
 3983        fs: Arc<dyn Fs>,
 3984        cx: &mut Context<Self>,
 3985    ) -> Self {
 3986        let yarn = YarnPathStore::new(fs.clone(), cx);
 3987        cx.subscribe(&buffer_store, Self::on_buffer_store_event)
 3988            .detach();
 3989        cx.subscribe(&worktree_store, Self::on_worktree_store_event)
 3990            .detach();
 3991        cx.subscribe(&prettier_store, Self::on_prettier_store_event)
 3992            .detach();
 3993        cx.subscribe(&toolchain_store, Self::on_toolchain_store_event)
 3994            .detach();
 3995        cx.observe_global::<SettingsStore>(Self::on_settings_changed)
 3996            .detach();
 3997        subscribe_to_binary_statuses(&languages, cx).detach();
 3998
 3999        let _maintain_workspace_config = {
 4000            let (sender, receiver) = watch::channel();
 4001            (Self::maintain_workspace_config(receiver, cx), sender)
 4002        };
 4003
 4004        Self {
 4005            mode: LspStoreMode::Local(LocalLspStore {
 4006                weak: cx.weak_entity(),
 4007                worktree_store: worktree_store.clone(),
 4008
 4009                supplementary_language_servers: Default::default(),
 4010                languages: languages.clone(),
 4011                language_server_ids: Default::default(),
 4012                language_servers: Default::default(),
 4013                last_workspace_edits_by_language_server: Default::default(),
 4014                language_server_watched_paths: Default::default(),
 4015                language_server_paths_watched_for_rename: Default::default(),
 4016                language_server_dynamic_registrations: Default::default(),
 4017                buffers_being_formatted: Default::default(),
 4018                buffer_snapshots: Default::default(),
 4019                prettier_store,
 4020                environment,
 4021                http_client,
 4022                fs,
 4023                yarn,
 4024                next_diagnostic_group_id: Default::default(),
 4025                diagnostics: Default::default(),
 4026                _subscription: cx.on_app_quit(|this, cx| {
 4027                    this.as_local_mut()
 4028                        .unwrap()
 4029                        .shutdown_language_servers_on_quit(cx)
 4030                }),
 4031                lsp_tree: LanguageServerTree::new(
 4032                    manifest_tree,
 4033                    languages.clone(),
 4034                    toolchain_store.clone(),
 4035                ),
 4036                toolchain_store,
 4037                registered_buffers: HashMap::default(),
 4038                buffers_opened_in_servers: HashMap::default(),
 4039                buffer_pull_diagnostics_result_ids: HashMap::default(),
 4040                workspace_pull_diagnostics_result_ids: HashMap::default(),
 4041                restricted_worktrees_tasks: HashMap::default(),
 4042                watched_manifest_filenames: ManifestProvidersStore::global(cx)
 4043                    .manifest_file_names(),
 4044            }),
 4045            last_formatting_failure: None,
 4046            downstream_client: None,
 4047            buffer_store,
 4048            worktree_store,
 4049            languages: languages.clone(),
 4050            language_server_statuses: Default::default(),
 4051            nonce: StdRng::from_os_rng().random(),
 4052            diagnostic_summaries: HashMap::default(),
 4053            lsp_server_capabilities: HashMap::default(),
 4054            lsp_data: HashMap::default(),
 4055            next_hint_id: Arc::default(),
 4056            active_entry: None,
 4057            _maintain_workspace_config,
 4058            _maintain_buffer_languages: Self::maintain_buffer_languages(languages, cx),
 4059        }
 4060    }
 4061
 4062    fn send_lsp_proto_request<R: LspCommand>(
 4063        &self,
 4064        buffer: Entity<Buffer>,
 4065        client: AnyProtoClient,
 4066        upstream_project_id: u64,
 4067        request: R,
 4068        cx: &mut Context<LspStore>,
 4069    ) -> Task<anyhow::Result<<R as LspCommand>::Response>> {
 4070        if !self.is_capable_for_proto_request(&buffer, &request, cx) {
 4071            return Task::ready(Ok(R::Response::default()));
 4072        }
 4073        let message = request.to_proto(upstream_project_id, buffer.read(cx));
 4074        cx.spawn(async move |this, cx| {
 4075            let response = client.request(message).await?;
 4076            let this = this.upgrade().context("project dropped")?;
 4077            request
 4078                .response_from_proto(response, this, buffer, cx.clone())
 4079                .await
 4080        })
 4081    }
 4082
 4083    pub(super) fn new_remote(
 4084        buffer_store: Entity<BufferStore>,
 4085        worktree_store: Entity<WorktreeStore>,
 4086        languages: Arc<LanguageRegistry>,
 4087        upstream_client: AnyProtoClient,
 4088        project_id: u64,
 4089        cx: &mut Context<Self>,
 4090    ) -> Self {
 4091        cx.subscribe(&buffer_store, Self::on_buffer_store_event)
 4092            .detach();
 4093        cx.subscribe(&worktree_store, Self::on_worktree_store_event)
 4094            .detach();
 4095        subscribe_to_binary_statuses(&languages, cx).detach();
 4096        let _maintain_workspace_config = {
 4097            let (sender, receiver) = watch::channel();
 4098            (Self::maintain_workspace_config(receiver, cx), sender)
 4099        };
 4100        Self {
 4101            mode: LspStoreMode::Remote(RemoteLspStore {
 4102                upstream_client: Some(upstream_client),
 4103                upstream_project_id: project_id,
 4104            }),
 4105            downstream_client: None,
 4106            last_formatting_failure: None,
 4107            buffer_store,
 4108            worktree_store,
 4109            languages: languages.clone(),
 4110            language_server_statuses: Default::default(),
 4111            nonce: StdRng::from_os_rng().random(),
 4112            diagnostic_summaries: HashMap::default(),
 4113            lsp_server_capabilities: HashMap::default(),
 4114            next_hint_id: Arc::default(),
 4115            lsp_data: HashMap::default(),
 4116            active_entry: None,
 4117
 4118            _maintain_workspace_config,
 4119            _maintain_buffer_languages: Self::maintain_buffer_languages(languages.clone(), cx),
 4120        }
 4121    }
 4122
 4123    fn on_buffer_store_event(
 4124        &mut self,
 4125        _: Entity<BufferStore>,
 4126        event: &BufferStoreEvent,
 4127        cx: &mut Context<Self>,
 4128    ) {
 4129        match event {
 4130            BufferStoreEvent::BufferAdded(buffer) => {
 4131                self.on_buffer_added(buffer, cx).log_err();
 4132            }
 4133            BufferStoreEvent::BufferChangedFilePath { buffer, old_file } => {
 4134                let buffer_id = buffer.read(cx).remote_id();
 4135                if let Some(local) = self.as_local_mut()
 4136                    && let Some(old_file) = File::from_dyn(old_file.as_ref())
 4137                {
 4138                    local.reset_buffer(buffer, old_file, cx);
 4139
 4140                    if local.registered_buffers.contains_key(&buffer_id) {
 4141                        local.unregister_old_buffer_from_language_servers(buffer, old_file, cx);
 4142                    }
 4143                }
 4144
 4145                self.detect_language_for_buffer(buffer, cx);
 4146                if let Some(local) = self.as_local_mut() {
 4147                    local.initialize_buffer(buffer, cx);
 4148                    if local.registered_buffers.contains_key(&buffer_id) {
 4149                        local.register_buffer_with_language_servers(buffer, HashSet::default(), cx);
 4150                    }
 4151                }
 4152            }
 4153            _ => {}
 4154        }
 4155    }
 4156
 4157    fn on_worktree_store_event(
 4158        &mut self,
 4159        _: Entity<WorktreeStore>,
 4160        event: &WorktreeStoreEvent,
 4161        cx: &mut Context<Self>,
 4162    ) {
 4163        match event {
 4164            WorktreeStoreEvent::WorktreeAdded(worktree) => {
 4165                if !worktree.read(cx).is_local() {
 4166                    return;
 4167                }
 4168                cx.subscribe(worktree, |this, worktree, event, cx| match event {
 4169                    worktree::Event::UpdatedEntries(changes) => {
 4170                        this.update_local_worktree_language_servers(&worktree, changes, cx);
 4171                    }
 4172                    worktree::Event::UpdatedGitRepositories(_)
 4173                    | worktree::Event::DeletedEntry(_) => {}
 4174                })
 4175                .detach()
 4176            }
 4177            WorktreeStoreEvent::WorktreeRemoved(_, id) => self.remove_worktree(*id, cx),
 4178            WorktreeStoreEvent::WorktreeUpdateSent(worktree) => {
 4179                worktree.update(cx, |worktree, _cx| self.send_diagnostic_summaries(worktree));
 4180            }
 4181            WorktreeStoreEvent::WorktreeReleased(..)
 4182            | WorktreeStoreEvent::WorktreeOrderChanged
 4183            | WorktreeStoreEvent::WorktreeUpdatedEntries(..)
 4184            | WorktreeStoreEvent::WorktreeUpdatedGitRepositories(..)
 4185            | WorktreeStoreEvent::WorktreeDeletedEntry(..) => {}
 4186        }
 4187    }
 4188
 4189    fn on_prettier_store_event(
 4190        &mut self,
 4191        _: Entity<PrettierStore>,
 4192        event: &PrettierStoreEvent,
 4193        cx: &mut Context<Self>,
 4194    ) {
 4195        match event {
 4196            PrettierStoreEvent::LanguageServerRemoved(prettier_server_id) => {
 4197                self.unregister_supplementary_language_server(*prettier_server_id, cx);
 4198            }
 4199            PrettierStoreEvent::LanguageServerAdded {
 4200                new_server_id,
 4201                name,
 4202                prettier_server,
 4203            } => {
 4204                self.register_supplementary_language_server(
 4205                    *new_server_id,
 4206                    name.clone(),
 4207                    prettier_server.clone(),
 4208                    cx,
 4209                );
 4210            }
 4211        }
 4212    }
 4213
 4214    fn on_toolchain_store_event(
 4215        &mut self,
 4216        _: Entity<LocalToolchainStore>,
 4217        event: &ToolchainStoreEvent,
 4218        _: &mut Context<Self>,
 4219    ) {
 4220        if let ToolchainStoreEvent::ToolchainActivated = event {
 4221            self.request_workspace_config_refresh()
 4222        }
 4223    }
 4224
 4225    fn request_workspace_config_refresh(&mut self) {
 4226        *self._maintain_workspace_config.1.borrow_mut() = ();
 4227    }
 4228
 4229    pub fn prettier_store(&self) -> Option<Entity<PrettierStore>> {
 4230        self.as_local().map(|local| local.prettier_store.clone())
 4231    }
 4232
 4233    fn on_buffer_event(
 4234        &mut self,
 4235        buffer: Entity<Buffer>,
 4236        event: &language::BufferEvent,
 4237        cx: &mut Context<Self>,
 4238    ) {
 4239        match event {
 4240            language::BufferEvent::Edited => {
 4241                self.on_buffer_edited(buffer, cx);
 4242            }
 4243
 4244            language::BufferEvent::Saved => {
 4245                self.on_buffer_saved(buffer, cx);
 4246            }
 4247
 4248            _ => {}
 4249        }
 4250    }
 4251
 4252    fn on_buffer_added(&mut self, buffer: &Entity<Buffer>, cx: &mut Context<Self>) -> Result<()> {
 4253        buffer
 4254            .read(cx)
 4255            .set_language_registry(self.languages.clone());
 4256
 4257        cx.subscribe(buffer, |this, buffer, event, cx| {
 4258            this.on_buffer_event(buffer, event, cx);
 4259        })
 4260        .detach();
 4261
 4262        self.detect_language_for_buffer(buffer, cx);
 4263        if let Some(local) = self.as_local_mut() {
 4264            local.initialize_buffer(buffer, cx);
 4265        }
 4266
 4267        Ok(())
 4268    }
 4269
 4270    pub(crate) fn register_buffer_with_language_servers(
 4271        &mut self,
 4272        buffer: &Entity<Buffer>,
 4273        only_register_servers: HashSet<LanguageServerSelector>,
 4274        ignore_refcounts: bool,
 4275        cx: &mut Context<Self>,
 4276    ) -> OpenLspBufferHandle {
 4277        let buffer_id = buffer.read(cx).remote_id();
 4278        let handle = OpenLspBufferHandle(cx.new(|_| OpenLspBuffer(buffer.clone())));
 4279        if let Some(local) = self.as_local_mut() {
 4280            let refcount = local.registered_buffers.entry(buffer_id).or_insert(0);
 4281            if !ignore_refcounts {
 4282                *refcount += 1;
 4283            }
 4284
 4285            // We run early exits on non-existing buffers AFTER we mark the buffer as registered in order to handle buffer saving.
 4286            // 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
 4287            // 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
 4288            // servers in practice (we don't support non-file URI schemes in our LSP impl).
 4289            let Some(file) = File::from_dyn(buffer.read(cx).file()) else {
 4290                return handle;
 4291            };
 4292            if !file.is_local() {
 4293                return handle;
 4294            }
 4295
 4296            if ignore_refcounts || *refcount == 1 {
 4297                local.register_buffer_with_language_servers(buffer, only_register_servers, cx);
 4298            }
 4299            if !ignore_refcounts {
 4300                cx.observe_release(&handle.0, move |lsp_store, buffer, cx| {
 4301                    let refcount = {
 4302                        let local = lsp_store.as_local_mut().unwrap();
 4303                        let Some(refcount) = local.registered_buffers.get_mut(&buffer_id) else {
 4304                            debug_panic!("bad refcounting");
 4305                            return;
 4306                        };
 4307
 4308                        *refcount -= 1;
 4309                        *refcount
 4310                    };
 4311                    if refcount == 0 {
 4312                        lsp_store.lsp_data.remove(&buffer_id);
 4313                        let local = lsp_store.as_local_mut().unwrap();
 4314                        local.registered_buffers.remove(&buffer_id);
 4315
 4316                        local.buffers_opened_in_servers.remove(&buffer_id);
 4317                        if let Some(file) = File::from_dyn(buffer.0.read(cx).file()).cloned() {
 4318                            local.unregister_old_buffer_from_language_servers(&buffer.0, &file, cx);
 4319
 4320                            let buffer_abs_path = file.abs_path(cx);
 4321                            for (_, buffer_pull_diagnostics_result_ids) in
 4322                                &mut local.buffer_pull_diagnostics_result_ids
 4323                            {
 4324                                buffer_pull_diagnostics_result_ids.retain(
 4325                                    |_, buffer_result_ids| {
 4326                                        buffer_result_ids.remove(&buffer_abs_path);
 4327                                        !buffer_result_ids.is_empty()
 4328                                    },
 4329                                );
 4330                            }
 4331
 4332                            let diagnostic_updates = local
 4333                                .language_servers
 4334                                .keys()
 4335                                .cloned()
 4336                                .map(|server_id| DocumentDiagnosticsUpdate {
 4337                                    diagnostics: DocumentDiagnostics {
 4338                                        document_abs_path: buffer_abs_path.clone(),
 4339                                        version: None,
 4340                                        diagnostics: Vec::new(),
 4341                                    },
 4342                                    result_id: None,
 4343                                    registration_id: None,
 4344                                    server_id: server_id,
 4345                                    disk_based_sources: Cow::Borrowed(&[]),
 4346                                })
 4347                                .collect::<Vec<_>>();
 4348
 4349                            lsp_store
 4350                                .merge_diagnostic_entries(
 4351                                    diagnostic_updates,
 4352                                    |_, diagnostic, _| {
 4353                                        diagnostic.source_kind != DiagnosticSourceKind::Pulled
 4354                                    },
 4355                                    cx,
 4356                                )
 4357                                .context("Clearing diagnostics for the closed buffer")
 4358                                .log_err();
 4359                        }
 4360                    }
 4361                })
 4362                .detach();
 4363            }
 4364        } else if let Some((upstream_client, upstream_project_id)) = self.upstream_client() {
 4365            let buffer_id = buffer.read(cx).remote_id().to_proto();
 4366            cx.background_spawn(async move {
 4367                upstream_client
 4368                    .request(proto::RegisterBufferWithLanguageServers {
 4369                        project_id: upstream_project_id,
 4370                        buffer_id,
 4371                        only_servers: only_register_servers
 4372                            .into_iter()
 4373                            .map(|selector| {
 4374                                let selector = match selector {
 4375                                    LanguageServerSelector::Id(language_server_id) => {
 4376                                        proto::language_server_selector::Selector::ServerId(
 4377                                            language_server_id.to_proto(),
 4378                                        )
 4379                                    }
 4380                                    LanguageServerSelector::Name(language_server_name) => {
 4381                                        proto::language_server_selector::Selector::Name(
 4382                                            language_server_name.to_string(),
 4383                                        )
 4384                                    }
 4385                                };
 4386                                proto::LanguageServerSelector {
 4387                                    selector: Some(selector),
 4388                                }
 4389                            })
 4390                            .collect(),
 4391                    })
 4392                    .await
 4393            })
 4394            .detach();
 4395        } else {
 4396            // Our remote connection got closed
 4397        }
 4398        handle
 4399    }
 4400
 4401    fn maintain_buffer_languages(
 4402        languages: Arc<LanguageRegistry>,
 4403        cx: &mut Context<Self>,
 4404    ) -> Task<()> {
 4405        let mut subscription = languages.subscribe();
 4406        let mut prev_reload_count = languages.reload_count();
 4407        cx.spawn(async move |this, cx| {
 4408            while let Some(()) = subscription.next().await {
 4409                if let Some(this) = this.upgrade() {
 4410                    // If the language registry has been reloaded, then remove and
 4411                    // re-assign the languages on all open buffers.
 4412                    let reload_count = languages.reload_count();
 4413                    if reload_count > prev_reload_count {
 4414                        prev_reload_count = reload_count;
 4415                        this.update(cx, |this, cx| {
 4416                            this.buffer_store.clone().update(cx, |buffer_store, cx| {
 4417                                for buffer in buffer_store.buffers() {
 4418                                    if let Some(f) = File::from_dyn(buffer.read(cx).file()).cloned()
 4419                                    {
 4420                                        buffer.update(cx, |buffer, cx| {
 4421                                            buffer.set_language_async(None, cx)
 4422                                        });
 4423                                        if let Some(local) = this.as_local_mut() {
 4424                                            local.reset_buffer(&buffer, &f, cx);
 4425
 4426                                            if local
 4427                                                .registered_buffers
 4428                                                .contains_key(&buffer.read(cx).remote_id())
 4429                                                && let Some(file_url) =
 4430                                                    file_path_to_lsp_url(&f.abs_path(cx)).log_err()
 4431                                            {
 4432                                                local.unregister_buffer_from_language_servers(
 4433                                                    &buffer, &file_url, cx,
 4434                                                );
 4435                                            }
 4436                                        }
 4437                                    }
 4438                                }
 4439                            });
 4440                        })
 4441                        .ok();
 4442                    }
 4443
 4444                    this.update(cx, |this, cx| {
 4445                        let mut plain_text_buffers = Vec::new();
 4446                        let mut buffers_with_unknown_injections = Vec::new();
 4447                        for handle in this.buffer_store.read(cx).buffers() {
 4448                            let buffer = handle.read(cx);
 4449                            if buffer.language().is_none()
 4450                                || buffer.language() == Some(&*language::PLAIN_TEXT)
 4451                            {
 4452                                plain_text_buffers.push(handle);
 4453                            } else if buffer.contains_unknown_injections() {
 4454                                buffers_with_unknown_injections.push(handle);
 4455                            }
 4456                        }
 4457
 4458                        // Deprioritize the invisible worktrees so main worktrees' language servers can be started first,
 4459                        // and reused later in the invisible worktrees.
 4460                        plain_text_buffers.sort_by_key(|buffer| {
 4461                            Reverse(
 4462                                File::from_dyn(buffer.read(cx).file())
 4463                                    .map(|file| file.worktree.read(cx).is_visible()),
 4464                            )
 4465                        });
 4466
 4467                        for buffer in plain_text_buffers {
 4468                            this.detect_language_for_buffer(&buffer, cx);
 4469                            if let Some(local) = this.as_local_mut() {
 4470                                local.initialize_buffer(&buffer, cx);
 4471                                if local
 4472                                    .registered_buffers
 4473                                    .contains_key(&buffer.read(cx).remote_id())
 4474                                {
 4475                                    local.register_buffer_with_language_servers(
 4476                                        &buffer,
 4477                                        HashSet::default(),
 4478                                        cx,
 4479                                    );
 4480                                }
 4481                            }
 4482                        }
 4483
 4484                        for buffer in buffers_with_unknown_injections {
 4485                            buffer.update(cx, |buffer, cx| buffer.reparse(cx, false));
 4486                        }
 4487                    })
 4488                    .ok();
 4489                }
 4490            }
 4491        })
 4492    }
 4493
 4494    fn detect_language_for_buffer(
 4495        &mut self,
 4496        buffer_handle: &Entity<Buffer>,
 4497        cx: &mut Context<Self>,
 4498    ) -> Option<language::AvailableLanguage> {
 4499        // If the buffer has a language, set it and start the language server if we haven't already.
 4500        let buffer = buffer_handle.read(cx);
 4501        let file = buffer.file()?;
 4502
 4503        let content = buffer.as_rope();
 4504        let available_language = self.languages.language_for_file(file, Some(content), cx);
 4505        if let Some(available_language) = &available_language {
 4506            if let Some(Ok(Ok(new_language))) = self
 4507                .languages
 4508                .load_language(available_language)
 4509                .now_or_never()
 4510            {
 4511                self.set_language_for_buffer(buffer_handle, new_language, cx);
 4512            }
 4513        } else {
 4514            cx.emit(LspStoreEvent::LanguageDetected {
 4515                buffer: buffer_handle.clone(),
 4516                new_language: None,
 4517            });
 4518        }
 4519
 4520        available_language
 4521    }
 4522
 4523    pub(crate) fn set_language_for_buffer(
 4524        &mut self,
 4525        buffer_entity: &Entity<Buffer>,
 4526        new_language: Arc<Language>,
 4527        cx: &mut Context<Self>,
 4528    ) {
 4529        let buffer = buffer_entity.read(cx);
 4530        let buffer_file = buffer.file().cloned();
 4531        let buffer_id = buffer.remote_id();
 4532        if let Some(local_store) = self.as_local_mut()
 4533            && local_store.registered_buffers.contains_key(&buffer_id)
 4534            && let Some(abs_path) =
 4535                File::from_dyn(buffer_file.as_ref()).map(|file| file.abs_path(cx))
 4536            && let Some(file_url) = file_path_to_lsp_url(&abs_path).log_err()
 4537        {
 4538            local_store.unregister_buffer_from_language_servers(buffer_entity, &file_url, cx);
 4539        }
 4540        buffer_entity.update(cx, |buffer, cx| {
 4541            if buffer
 4542                .language()
 4543                .is_none_or(|old_language| !Arc::ptr_eq(old_language, &new_language))
 4544            {
 4545                buffer.set_language_async(Some(new_language.clone()), cx);
 4546            }
 4547        });
 4548
 4549        let settings =
 4550            language_settings(Some(new_language.name()), buffer_file.as_ref(), cx).into_owned();
 4551        let buffer_file = File::from_dyn(buffer_file.as_ref());
 4552
 4553        let worktree_id = if let Some(file) = buffer_file {
 4554            let worktree = file.worktree.clone();
 4555
 4556            if let Some(local) = self.as_local_mut()
 4557                && local.registered_buffers.contains_key(&buffer_id)
 4558            {
 4559                local.register_buffer_with_language_servers(buffer_entity, HashSet::default(), cx);
 4560            }
 4561            Some(worktree.read(cx).id())
 4562        } else {
 4563            None
 4564        };
 4565
 4566        if settings.prettier.allowed
 4567            && let Some(prettier_plugins) = prettier_store::prettier_plugins_for_language(&settings)
 4568        {
 4569            let prettier_store = self.as_local().map(|s| s.prettier_store.clone());
 4570            if let Some(prettier_store) = prettier_store {
 4571                prettier_store.update(cx, |prettier_store, cx| {
 4572                    prettier_store.install_default_prettier(
 4573                        worktree_id,
 4574                        prettier_plugins.iter().map(|s| Arc::from(s.as_str())),
 4575                        cx,
 4576                    )
 4577                })
 4578            }
 4579        }
 4580
 4581        cx.emit(LspStoreEvent::LanguageDetected {
 4582            buffer: buffer_entity.clone(),
 4583            new_language: Some(new_language),
 4584        })
 4585    }
 4586
 4587    pub fn buffer_store(&self) -> Entity<BufferStore> {
 4588        self.buffer_store.clone()
 4589    }
 4590
 4591    pub fn set_active_entry(&mut self, active_entry: Option<ProjectEntryId>) {
 4592        self.active_entry = active_entry;
 4593    }
 4594
 4595    pub(crate) fn send_diagnostic_summaries(&self, worktree: &mut Worktree) {
 4596        if let Some((client, downstream_project_id)) = self.downstream_client.clone()
 4597            && let Some(diangostic_summaries) = self.diagnostic_summaries.get(&worktree.id())
 4598        {
 4599            let mut summaries = diangostic_summaries.iter().flat_map(|(path, summaries)| {
 4600                summaries
 4601                    .iter()
 4602                    .map(|(server_id, summary)| summary.to_proto(*server_id, path.as_ref()))
 4603            });
 4604            if let Some(summary) = summaries.next() {
 4605                client
 4606                    .send(proto::UpdateDiagnosticSummary {
 4607                        project_id: downstream_project_id,
 4608                        worktree_id: worktree.id().to_proto(),
 4609                        summary: Some(summary),
 4610                        more_summaries: summaries.collect(),
 4611                    })
 4612                    .log_err();
 4613            }
 4614        }
 4615    }
 4616
 4617    fn is_capable_for_proto_request<R>(
 4618        &self,
 4619        buffer: &Entity<Buffer>,
 4620        request: &R,
 4621        cx: &App,
 4622    ) -> bool
 4623    where
 4624        R: LspCommand,
 4625    {
 4626        self.check_if_capable_for_proto_request(
 4627            buffer,
 4628            |capabilities| {
 4629                request.check_capabilities(AdapterServerCapabilities {
 4630                    server_capabilities: capabilities.clone(),
 4631                    code_action_kinds: None,
 4632                })
 4633            },
 4634            cx,
 4635        )
 4636    }
 4637
 4638    fn check_if_capable_for_proto_request<F>(
 4639        &self,
 4640        buffer: &Entity<Buffer>,
 4641        check: F,
 4642        cx: &App,
 4643    ) -> bool
 4644    where
 4645        F: FnMut(&lsp::ServerCapabilities) -> bool,
 4646    {
 4647        let Some(language) = buffer.read(cx).language().cloned() else {
 4648            return false;
 4649        };
 4650        let relevant_language_servers = self
 4651            .languages
 4652            .lsp_adapters(&language.name())
 4653            .into_iter()
 4654            .map(|lsp_adapter| lsp_adapter.name())
 4655            .collect::<HashSet<_>>();
 4656        self.language_server_statuses
 4657            .iter()
 4658            .filter_map(|(server_id, server_status)| {
 4659                relevant_language_servers
 4660                    .contains(&server_status.name)
 4661                    .then_some(server_id)
 4662            })
 4663            .filter_map(|server_id| self.lsp_server_capabilities.get(server_id))
 4664            .any(check)
 4665    }
 4666
 4667    fn all_capable_for_proto_request<F>(
 4668        &self,
 4669        buffer: &Entity<Buffer>,
 4670        mut check: F,
 4671        cx: &App,
 4672    ) -> Vec<lsp::LanguageServerId>
 4673    where
 4674        F: FnMut(&lsp::LanguageServerName, &lsp::ServerCapabilities) -> bool,
 4675    {
 4676        let Some(language) = buffer.read(cx).language().cloned() else {
 4677            return Vec::default();
 4678        };
 4679        let relevant_language_servers = self
 4680            .languages
 4681            .lsp_adapters(&language.name())
 4682            .into_iter()
 4683            .map(|lsp_adapter| lsp_adapter.name())
 4684            .collect::<HashSet<_>>();
 4685        self.language_server_statuses
 4686            .iter()
 4687            .filter_map(|(server_id, server_status)| {
 4688                relevant_language_servers
 4689                    .contains(&server_status.name)
 4690                    .then_some((server_id, &server_status.name))
 4691            })
 4692            .filter_map(|(server_id, server_name)| {
 4693                self.lsp_server_capabilities
 4694                    .get(server_id)
 4695                    .map(|c| (server_id, server_name, c))
 4696            })
 4697            .filter(|(_, server_name, capabilities)| check(server_name, capabilities))
 4698            .map(|(server_id, _, _)| *server_id)
 4699            .collect()
 4700    }
 4701
 4702    pub fn request_lsp<R>(
 4703        &mut self,
 4704        buffer: Entity<Buffer>,
 4705        server: LanguageServerToQuery,
 4706        request: R,
 4707        cx: &mut Context<Self>,
 4708    ) -> Task<Result<R::Response>>
 4709    where
 4710        R: LspCommand,
 4711        <R::LspRequest as lsp::request::Request>::Result: Send,
 4712        <R::LspRequest as lsp::request::Request>::Params: Send,
 4713    {
 4714        if let Some((upstream_client, upstream_project_id)) = self.upstream_client() {
 4715            return self.send_lsp_proto_request(
 4716                buffer,
 4717                upstream_client,
 4718                upstream_project_id,
 4719                request,
 4720                cx,
 4721            );
 4722        }
 4723
 4724        let Some(language_server) = buffer.update(cx, |buffer, cx| match server {
 4725            LanguageServerToQuery::FirstCapable => self.as_local().and_then(|local| {
 4726                local
 4727                    .language_servers_for_buffer(buffer, cx)
 4728                    .find(|(_, server)| {
 4729                        request.check_capabilities(server.adapter_server_capabilities())
 4730                    })
 4731                    .map(|(_, server)| server.clone())
 4732            }),
 4733            LanguageServerToQuery::Other(id) => self
 4734                .language_server_for_local_buffer(buffer, id, cx)
 4735                .and_then(|(_, server)| {
 4736                    request
 4737                        .check_capabilities(server.adapter_server_capabilities())
 4738                        .then(|| Arc::clone(server))
 4739                }),
 4740        }) else {
 4741            return Task::ready(Ok(Default::default()));
 4742        };
 4743
 4744        let file = File::from_dyn(buffer.read(cx).file()).and_then(File::as_local);
 4745
 4746        let Some(file) = file else {
 4747            return Task::ready(Ok(Default::default()));
 4748        };
 4749
 4750        let lsp_params = match request.to_lsp_params_or_response(
 4751            &file.abs_path(cx),
 4752            buffer.read(cx),
 4753            &language_server,
 4754            cx,
 4755        ) {
 4756            Ok(LspParamsOrResponse::Params(lsp_params)) => lsp_params,
 4757            Ok(LspParamsOrResponse::Response(response)) => return Task::ready(Ok(response)),
 4758            Err(err) => {
 4759                let message = format!(
 4760                    "{} via {} failed: {}",
 4761                    request.display_name(),
 4762                    language_server.name(),
 4763                    err
 4764                );
 4765                // rust-analyzer likes to error with this when its still loading up
 4766                if !message.ends_with("content modified") {
 4767                    log::warn!("{message}");
 4768                }
 4769                return Task::ready(Err(anyhow!(message)));
 4770            }
 4771        };
 4772
 4773        let status = request.status();
 4774        if !request.check_capabilities(language_server.adapter_server_capabilities()) {
 4775            return Task::ready(Ok(Default::default()));
 4776        }
 4777        cx.spawn(async move |this, cx| {
 4778            let lsp_request = language_server.request::<R::LspRequest>(lsp_params);
 4779
 4780            let id = lsp_request.id();
 4781            let _cleanup = if status.is_some() {
 4782                cx.update(|cx| {
 4783                    this.update(cx, |this, cx| {
 4784                        this.on_lsp_work_start(
 4785                            language_server.server_id(),
 4786                            ProgressToken::Number(id),
 4787                            LanguageServerProgress {
 4788                                is_disk_based_diagnostics_progress: false,
 4789                                is_cancellable: false,
 4790                                title: None,
 4791                                message: status.clone(),
 4792                                percentage: None,
 4793                                last_update_at: cx.background_executor().now(),
 4794                            },
 4795                            cx,
 4796                        );
 4797                    })
 4798                })
 4799                .log_err();
 4800
 4801                Some(defer(|| {
 4802                    cx.update(|cx| {
 4803                        this.update(cx, |this, cx| {
 4804                            this.on_lsp_work_end(
 4805                                language_server.server_id(),
 4806                                ProgressToken::Number(id),
 4807                                cx,
 4808                            );
 4809                        })
 4810                    })
 4811                    .log_err();
 4812                }))
 4813            } else {
 4814                None
 4815            };
 4816
 4817            let result = lsp_request.await.into_response();
 4818
 4819            let response = result.map_err(|err| {
 4820                let message = format!(
 4821                    "{} via {} failed: {}",
 4822                    request.display_name(),
 4823                    language_server.name(),
 4824                    err
 4825                );
 4826                // rust-analyzer likes to error with this when its still loading up
 4827                if !message.ends_with("content modified") {
 4828                    log::warn!("{message}");
 4829                }
 4830                anyhow::anyhow!(message)
 4831            })?;
 4832
 4833            request
 4834                .response_from_lsp(
 4835                    response,
 4836                    this.upgrade().context("no app context")?,
 4837                    buffer,
 4838                    language_server.server_id(),
 4839                    cx.clone(),
 4840                )
 4841                .await
 4842        })
 4843    }
 4844
 4845    fn on_settings_changed(&mut self, cx: &mut Context<Self>) {
 4846        let mut language_formatters_to_check = Vec::new();
 4847        for buffer in self.buffer_store.read(cx).buffers() {
 4848            let buffer = buffer.read(cx);
 4849            let buffer_file = File::from_dyn(buffer.file());
 4850            let buffer_language = buffer.language();
 4851            let settings = language_settings(buffer_language.map(|l| l.name()), buffer.file(), cx);
 4852            if buffer_language.is_some() {
 4853                language_formatters_to_check.push((
 4854                    buffer_file.map(|f| f.worktree_id(cx)),
 4855                    settings.into_owned(),
 4856                ));
 4857            }
 4858        }
 4859
 4860        self.request_workspace_config_refresh();
 4861
 4862        if let Some(prettier_store) = self.as_local().map(|s| s.prettier_store.clone()) {
 4863            prettier_store.update(cx, |prettier_store, cx| {
 4864                prettier_store.on_settings_changed(language_formatters_to_check, cx)
 4865            })
 4866        }
 4867
 4868        cx.notify();
 4869    }
 4870
 4871    fn refresh_server_tree(&mut self, cx: &mut Context<Self>) {
 4872        let buffer_store = self.buffer_store.clone();
 4873        let Some(local) = self.as_local_mut() else {
 4874            return;
 4875        };
 4876        let mut adapters = BTreeMap::default();
 4877        let get_adapter = {
 4878            let languages = local.languages.clone();
 4879            let environment = local.environment.clone();
 4880            let weak = local.weak.clone();
 4881            let worktree_store = local.worktree_store.clone();
 4882            let http_client = local.http_client.clone();
 4883            let fs = local.fs.clone();
 4884            move |worktree_id, cx: &mut App| {
 4885                let worktree = worktree_store.read(cx).worktree_for_id(worktree_id, cx)?;
 4886                Some(LocalLspAdapterDelegate::new(
 4887                    languages.clone(),
 4888                    &environment,
 4889                    weak.clone(),
 4890                    &worktree,
 4891                    http_client.clone(),
 4892                    fs.clone(),
 4893                    cx,
 4894                ))
 4895            }
 4896        };
 4897
 4898        let mut messages_to_report = Vec::new();
 4899        let (new_tree, to_stop) = {
 4900            let mut rebase = local.lsp_tree.rebase();
 4901            let buffers = buffer_store
 4902                .read(cx)
 4903                .buffers()
 4904                .filter_map(|buffer| {
 4905                    let raw_buffer = buffer.read(cx);
 4906                    if !local
 4907                        .registered_buffers
 4908                        .contains_key(&raw_buffer.remote_id())
 4909                    {
 4910                        return None;
 4911                    }
 4912                    let file = File::from_dyn(raw_buffer.file()).cloned()?;
 4913                    let language = raw_buffer.language().cloned()?;
 4914                    Some((file, language, raw_buffer.remote_id()))
 4915                })
 4916                .sorted_by_key(|(file, _, _)| Reverse(file.worktree.read(cx).is_visible()));
 4917            for (file, language, buffer_id) in buffers {
 4918                let worktree_id = file.worktree_id(cx);
 4919                let Some(worktree) = local
 4920                    .worktree_store
 4921                    .read(cx)
 4922                    .worktree_for_id(worktree_id, cx)
 4923                else {
 4924                    continue;
 4925                };
 4926
 4927                if let Some((_, apply)) = local.reuse_existing_language_server(
 4928                    rebase.server_tree(),
 4929                    &worktree,
 4930                    &language.name(),
 4931                    cx,
 4932                ) {
 4933                    (apply)(rebase.server_tree());
 4934                } else if let Some(lsp_delegate) = adapters
 4935                    .entry(worktree_id)
 4936                    .or_insert_with(|| get_adapter(worktree_id, cx))
 4937                    .clone()
 4938                {
 4939                    let delegate =
 4940                        Arc::new(ManifestQueryDelegate::new(worktree.read(cx).snapshot()));
 4941                    let path = file
 4942                        .path()
 4943                        .parent()
 4944                        .map(Arc::from)
 4945                        .unwrap_or_else(|| file.path().clone());
 4946                    let worktree_path = ProjectPath { worktree_id, path };
 4947                    let abs_path = file.abs_path(cx);
 4948                    let nodes = rebase
 4949                        .walk(
 4950                            worktree_path,
 4951                            language.name(),
 4952                            language.manifest(),
 4953                            delegate.clone(),
 4954                            cx,
 4955                        )
 4956                        .collect::<Vec<_>>();
 4957                    for node in nodes {
 4958                        let server_id = node.server_id_or_init(|disposition| {
 4959                            let path = &disposition.path;
 4960                            let uri = Uri::from_file_path(worktree.read(cx).absolutize(&path.path));
 4961                            let key = LanguageServerSeed {
 4962                                worktree_id,
 4963                                name: disposition.server_name.clone(),
 4964                                settings: disposition.settings.clone(),
 4965                                toolchain: local.toolchain_store.read(cx).active_toolchain(
 4966                                    path.worktree_id,
 4967                                    &path.path,
 4968                                    language.name(),
 4969                                ),
 4970                            };
 4971                            local.language_server_ids.remove(&key);
 4972
 4973                            let server_id = local.get_or_insert_language_server(
 4974                                &worktree,
 4975                                lsp_delegate.clone(),
 4976                                disposition,
 4977                                &language.name(),
 4978                                cx,
 4979                            );
 4980                            if let Some(state) = local.language_servers.get(&server_id)
 4981                                && let Ok(uri) = uri
 4982                            {
 4983                                state.add_workspace_folder(uri);
 4984                            };
 4985                            server_id
 4986                        });
 4987
 4988                        if let Some(language_server_id) = server_id {
 4989                            messages_to_report.push(LspStoreEvent::LanguageServerUpdate {
 4990                                language_server_id,
 4991                                name: node.name(),
 4992                                message:
 4993                                    proto::update_language_server::Variant::RegisteredForBuffer(
 4994                                        proto::RegisteredForBuffer {
 4995                                            buffer_abs_path: abs_path
 4996                                                .to_string_lossy()
 4997                                                .into_owned(),
 4998                                            buffer_id: buffer_id.to_proto(),
 4999                                        },
 5000                                    ),
 5001                            });
 5002                        }
 5003                    }
 5004                } else {
 5005                    continue;
 5006                }
 5007            }
 5008            rebase.finish()
 5009        };
 5010        for message in messages_to_report {
 5011            cx.emit(message);
 5012        }
 5013        local.lsp_tree = new_tree;
 5014        for (id, _) in to_stop {
 5015            self.stop_local_language_server(id, cx).detach();
 5016        }
 5017    }
 5018
 5019    pub fn apply_code_action(
 5020        &self,
 5021        buffer_handle: Entity<Buffer>,
 5022        mut action: CodeAction,
 5023        push_to_history: bool,
 5024        cx: &mut Context<Self>,
 5025    ) -> Task<Result<ProjectTransaction>> {
 5026        if let Some((upstream_client, project_id)) = self.upstream_client() {
 5027            let request = proto::ApplyCodeAction {
 5028                project_id,
 5029                buffer_id: buffer_handle.read(cx).remote_id().into(),
 5030                action: Some(Self::serialize_code_action(&action)),
 5031            };
 5032            let buffer_store = self.buffer_store();
 5033            cx.spawn(async move |_, cx| {
 5034                let response = upstream_client
 5035                    .request(request)
 5036                    .await?
 5037                    .transaction
 5038                    .context("missing transaction")?;
 5039
 5040                buffer_store
 5041                    .update(cx, |buffer_store, cx| {
 5042                        buffer_store.deserialize_project_transaction(response, push_to_history, cx)
 5043                    })?
 5044                    .await
 5045            })
 5046        } else if self.mode.is_local() {
 5047            let Some((_, lang_server)) = buffer_handle.update(cx, |buffer, cx| {
 5048                self.language_server_for_local_buffer(buffer, action.server_id, cx)
 5049                    .map(|(adapter, server)| (adapter.clone(), server.clone()))
 5050            }) else {
 5051                return Task::ready(Ok(ProjectTransaction::default()));
 5052            };
 5053            cx.spawn(async move |this,  cx| {
 5054                LocalLspStore::try_resolve_code_action(&lang_server, &mut action)
 5055                    .await
 5056                    .context("resolving a code action")?;
 5057                if let Some(edit) = action.lsp_action.edit()
 5058                    && (edit.changes.is_some() || edit.document_changes.is_some()) {
 5059                        return LocalLspStore::deserialize_workspace_edit(
 5060                            this.upgrade().context("no app present")?,
 5061                            edit.clone(),
 5062                            push_to_history,
 5063
 5064                            lang_server.clone(),
 5065                            cx,
 5066                        )
 5067                        .await;
 5068                    }
 5069
 5070                if let Some(command) = action.lsp_action.command() {
 5071                    let server_capabilities = lang_server.capabilities();
 5072                    let available_commands = server_capabilities
 5073                        .execute_command_provider
 5074                        .as_ref()
 5075                        .map(|options| options.commands.as_slice())
 5076                        .unwrap_or_default();
 5077                    if available_commands.contains(&command.command) {
 5078                        this.update(cx, |this, _| {
 5079                            this.as_local_mut()
 5080                                .unwrap()
 5081                                .last_workspace_edits_by_language_server
 5082                                .remove(&lang_server.server_id());
 5083                        })?;
 5084
 5085                        let _result = lang_server
 5086                            .request::<lsp::request::ExecuteCommand>(lsp::ExecuteCommandParams {
 5087                                command: command.command.clone(),
 5088                                arguments: command.arguments.clone().unwrap_or_default(),
 5089                                ..lsp::ExecuteCommandParams::default()
 5090                            })
 5091                            .await.into_response()
 5092                            .context("execute command")?;
 5093
 5094                        return this.update(cx, |this, _| {
 5095                            this.as_local_mut()
 5096                                .unwrap()
 5097                                .last_workspace_edits_by_language_server
 5098                                .remove(&lang_server.server_id())
 5099                                .unwrap_or_default()
 5100                        });
 5101                    } else {
 5102                        log::warn!("Cannot execute a command {} not listed in the language server capabilities", command.command);
 5103                    }
 5104                }
 5105
 5106                Ok(ProjectTransaction::default())
 5107            })
 5108        } else {
 5109            Task::ready(Err(anyhow!("no upstream client and not local")))
 5110        }
 5111    }
 5112
 5113    pub fn apply_code_action_kind(
 5114        &mut self,
 5115        buffers: HashSet<Entity<Buffer>>,
 5116        kind: CodeActionKind,
 5117        push_to_history: bool,
 5118        cx: &mut Context<Self>,
 5119    ) -> Task<anyhow::Result<ProjectTransaction>> {
 5120        if self.as_local().is_some() {
 5121            cx.spawn(async move |lsp_store, cx| {
 5122                let buffers = buffers.into_iter().collect::<Vec<_>>();
 5123                let result = LocalLspStore::execute_code_action_kind_locally(
 5124                    lsp_store.clone(),
 5125                    buffers,
 5126                    kind,
 5127                    push_to_history,
 5128                    cx,
 5129                )
 5130                .await;
 5131                lsp_store.update(cx, |lsp_store, _| {
 5132                    lsp_store.update_last_formatting_failure(&result);
 5133                })?;
 5134                result
 5135            })
 5136        } else if let Some((client, project_id)) = self.upstream_client() {
 5137            let buffer_store = self.buffer_store();
 5138            cx.spawn(async move |lsp_store, cx| {
 5139                let result = client
 5140                    .request(proto::ApplyCodeActionKind {
 5141                        project_id,
 5142                        kind: kind.as_str().to_owned(),
 5143                        buffer_ids: buffers
 5144                            .iter()
 5145                            .map(|buffer| {
 5146                                buffer.read_with(cx, |buffer, _| buffer.remote_id().into())
 5147                            })
 5148                            .collect::<Result<_>>()?,
 5149                    })
 5150                    .await
 5151                    .and_then(|result| result.transaction.context("missing transaction"));
 5152                lsp_store.update(cx, |lsp_store, _| {
 5153                    lsp_store.update_last_formatting_failure(&result);
 5154                })?;
 5155
 5156                let transaction_response = result?;
 5157                buffer_store
 5158                    .update(cx, |buffer_store, cx| {
 5159                        buffer_store.deserialize_project_transaction(
 5160                            transaction_response,
 5161                            push_to_history,
 5162                            cx,
 5163                        )
 5164                    })?
 5165                    .await
 5166            })
 5167        } else {
 5168            Task::ready(Ok(ProjectTransaction::default()))
 5169        }
 5170    }
 5171
 5172    pub fn resolved_hint(
 5173        &mut self,
 5174        buffer_id: BufferId,
 5175        id: InlayId,
 5176        cx: &mut Context<Self>,
 5177    ) -> Option<ResolvedHint> {
 5178        let buffer = self.buffer_store.read(cx).get(buffer_id)?;
 5179
 5180        let lsp_data = self.lsp_data.get_mut(&buffer_id)?;
 5181        let buffer_lsp_hints = &mut lsp_data.inlay_hints;
 5182        let hint = buffer_lsp_hints.hint_for_id(id)?.clone();
 5183        let (server_id, resolve_data) = match &hint.resolve_state {
 5184            ResolveState::Resolved => return Some(ResolvedHint::Resolved(hint)),
 5185            ResolveState::Resolving => {
 5186                return Some(ResolvedHint::Resolving(
 5187                    buffer_lsp_hints.hint_resolves.get(&id)?.clone(),
 5188                ));
 5189            }
 5190            ResolveState::CanResolve(server_id, resolve_data) => (*server_id, resolve_data.clone()),
 5191        };
 5192
 5193        let resolve_task = self.resolve_inlay_hint(hint, buffer, server_id, cx);
 5194        let buffer_lsp_hints = &mut self.lsp_data.get_mut(&buffer_id)?.inlay_hints;
 5195        let previous_task = buffer_lsp_hints.hint_resolves.insert(
 5196            id,
 5197            cx.spawn(async move |lsp_store, cx| {
 5198                let resolved_hint = resolve_task.await;
 5199                lsp_store
 5200                    .update(cx, |lsp_store, _| {
 5201                        if let Some(old_inlay_hint) = lsp_store
 5202                            .lsp_data
 5203                            .get_mut(&buffer_id)
 5204                            .and_then(|buffer_lsp_data| buffer_lsp_data.inlay_hints.hint_for_id(id))
 5205                        {
 5206                            match resolved_hint {
 5207                                Ok(resolved_hint) => {
 5208                                    *old_inlay_hint = resolved_hint;
 5209                                }
 5210                                Err(e) => {
 5211                                    old_inlay_hint.resolve_state =
 5212                                        ResolveState::CanResolve(server_id, resolve_data);
 5213                                    log::error!("Inlay hint resolve failed: {e:#}");
 5214                                }
 5215                            }
 5216                        }
 5217                    })
 5218                    .ok();
 5219            })
 5220            .shared(),
 5221        );
 5222        debug_assert!(
 5223            previous_task.is_none(),
 5224            "Did not change hint's resolve state after spawning its resolve"
 5225        );
 5226        buffer_lsp_hints.hint_for_id(id)?.resolve_state = ResolveState::Resolving;
 5227        None
 5228    }
 5229
 5230    fn resolve_inlay_hint(
 5231        &self,
 5232        mut hint: InlayHint,
 5233        buffer: Entity<Buffer>,
 5234        server_id: LanguageServerId,
 5235        cx: &mut Context<Self>,
 5236    ) -> Task<anyhow::Result<InlayHint>> {
 5237        if let Some((upstream_client, project_id)) = self.upstream_client() {
 5238            if !self.check_if_capable_for_proto_request(&buffer, InlayHints::can_resolve_inlays, cx)
 5239            {
 5240                hint.resolve_state = ResolveState::Resolved;
 5241                return Task::ready(Ok(hint));
 5242            }
 5243            let request = proto::ResolveInlayHint {
 5244                project_id,
 5245                buffer_id: buffer.read(cx).remote_id().into(),
 5246                language_server_id: server_id.0 as u64,
 5247                hint: Some(InlayHints::project_to_proto_hint(hint.clone())),
 5248            };
 5249            cx.background_spawn(async move {
 5250                let response = upstream_client
 5251                    .request(request)
 5252                    .await
 5253                    .context("inlay hints proto request")?;
 5254                match response.hint {
 5255                    Some(resolved_hint) => InlayHints::proto_to_project_hint(resolved_hint)
 5256                        .context("inlay hints proto resolve response conversion"),
 5257                    None => Ok(hint),
 5258                }
 5259            })
 5260        } else {
 5261            let Some(lang_server) = buffer.update(cx, |buffer, cx| {
 5262                self.language_server_for_local_buffer(buffer, server_id, cx)
 5263                    .map(|(_, server)| server.clone())
 5264            }) else {
 5265                return Task::ready(Ok(hint));
 5266            };
 5267            if !InlayHints::can_resolve_inlays(&lang_server.capabilities()) {
 5268                return Task::ready(Ok(hint));
 5269            }
 5270            let buffer_snapshot = buffer.read(cx).snapshot();
 5271            cx.spawn(async move |_, cx| {
 5272                let resolve_task = lang_server.request::<lsp::request::InlayHintResolveRequest>(
 5273                    InlayHints::project_to_lsp_hint(hint, &buffer_snapshot),
 5274                );
 5275                let resolved_hint = resolve_task
 5276                    .await
 5277                    .into_response()
 5278                    .context("inlay hint resolve LSP request")?;
 5279                let resolved_hint = InlayHints::lsp_to_project_hint(
 5280                    resolved_hint,
 5281                    &buffer,
 5282                    server_id,
 5283                    ResolveState::Resolved,
 5284                    false,
 5285                    cx,
 5286                )
 5287                .await?;
 5288                Ok(resolved_hint)
 5289            })
 5290        }
 5291    }
 5292
 5293    pub fn resolve_color_presentation(
 5294        &mut self,
 5295        mut color: DocumentColor,
 5296        buffer: Entity<Buffer>,
 5297        server_id: LanguageServerId,
 5298        cx: &mut Context<Self>,
 5299    ) -> Task<Result<DocumentColor>> {
 5300        if color.resolved {
 5301            return Task::ready(Ok(color));
 5302        }
 5303
 5304        if let Some((upstream_client, project_id)) = self.upstream_client() {
 5305            let start = color.lsp_range.start;
 5306            let end = color.lsp_range.end;
 5307            let request = proto::GetColorPresentation {
 5308                project_id,
 5309                server_id: server_id.to_proto(),
 5310                buffer_id: buffer.read(cx).remote_id().into(),
 5311                color: Some(proto::ColorInformation {
 5312                    red: color.color.red,
 5313                    green: color.color.green,
 5314                    blue: color.color.blue,
 5315                    alpha: color.color.alpha,
 5316                    lsp_range_start: Some(proto::PointUtf16 {
 5317                        row: start.line,
 5318                        column: start.character,
 5319                    }),
 5320                    lsp_range_end: Some(proto::PointUtf16 {
 5321                        row: end.line,
 5322                        column: end.character,
 5323                    }),
 5324                }),
 5325            };
 5326            cx.background_spawn(async move {
 5327                let response = upstream_client
 5328                    .request(request)
 5329                    .await
 5330                    .context("color presentation proto request")?;
 5331                color.resolved = true;
 5332                color.color_presentations = response
 5333                    .presentations
 5334                    .into_iter()
 5335                    .map(|presentation| ColorPresentation {
 5336                        label: SharedString::from(presentation.label),
 5337                        text_edit: presentation.text_edit.and_then(deserialize_lsp_edit),
 5338                        additional_text_edits: presentation
 5339                            .additional_text_edits
 5340                            .into_iter()
 5341                            .filter_map(deserialize_lsp_edit)
 5342                            .collect(),
 5343                    })
 5344                    .collect();
 5345                Ok(color)
 5346            })
 5347        } else {
 5348            let path = match buffer
 5349                .update(cx, |buffer, cx| {
 5350                    Some(File::from_dyn(buffer.file())?.abs_path(cx))
 5351                })
 5352                .context("buffer with the missing path")
 5353            {
 5354                Ok(path) => path,
 5355                Err(e) => return Task::ready(Err(e)),
 5356            };
 5357            let Some(lang_server) = buffer.update(cx, |buffer, cx| {
 5358                self.language_server_for_local_buffer(buffer, server_id, cx)
 5359                    .map(|(_, server)| server.clone())
 5360            }) else {
 5361                return Task::ready(Ok(color));
 5362            };
 5363            cx.background_spawn(async move {
 5364                let resolve_task = lang_server.request::<lsp::request::ColorPresentationRequest>(
 5365                    lsp::ColorPresentationParams {
 5366                        text_document: make_text_document_identifier(&path)?,
 5367                        color: color.color,
 5368                        range: color.lsp_range,
 5369                        work_done_progress_params: Default::default(),
 5370                        partial_result_params: Default::default(),
 5371                    },
 5372                );
 5373                color.color_presentations = resolve_task
 5374                    .await
 5375                    .into_response()
 5376                    .context("color presentation resolve LSP request")?
 5377                    .into_iter()
 5378                    .map(|presentation| ColorPresentation {
 5379                        label: SharedString::from(presentation.label),
 5380                        text_edit: presentation.text_edit,
 5381                        additional_text_edits: presentation
 5382                            .additional_text_edits
 5383                            .unwrap_or_default(),
 5384                    })
 5385                    .collect();
 5386                color.resolved = true;
 5387                Ok(color)
 5388            })
 5389        }
 5390    }
 5391
 5392    pub(crate) fn linked_edits(
 5393        &mut self,
 5394        buffer: &Entity<Buffer>,
 5395        position: Anchor,
 5396        cx: &mut Context<Self>,
 5397    ) -> Task<Result<Vec<Range<Anchor>>>> {
 5398        let snapshot = buffer.read(cx).snapshot();
 5399        let scope = snapshot.language_scope_at(position);
 5400        let Some(server_id) = self
 5401            .as_local()
 5402            .and_then(|local| {
 5403                buffer.update(cx, |buffer, cx| {
 5404                    local
 5405                        .language_servers_for_buffer(buffer, cx)
 5406                        .filter(|(_, server)| {
 5407                            LinkedEditingRange::check_server_capabilities(server.capabilities())
 5408                        })
 5409                        .filter(|(adapter, _)| {
 5410                            scope
 5411                                .as_ref()
 5412                                .map(|scope| scope.language_allowed(&adapter.name))
 5413                                .unwrap_or(true)
 5414                        })
 5415                        .map(|(_, server)| LanguageServerToQuery::Other(server.server_id()))
 5416                        .next()
 5417                })
 5418            })
 5419            .or_else(|| {
 5420                self.upstream_client()
 5421                    .is_some()
 5422                    .then_some(LanguageServerToQuery::FirstCapable)
 5423            })
 5424            .filter(|_| {
 5425                maybe!({
 5426                    let language = buffer.read(cx).language_at(position)?;
 5427                    Some(
 5428                        language_settings(Some(language.name()), buffer.read(cx).file(), cx)
 5429                            .linked_edits,
 5430                    )
 5431                }) == Some(true)
 5432            })
 5433        else {
 5434            return Task::ready(Ok(Vec::new()));
 5435        };
 5436
 5437        self.request_lsp(
 5438            buffer.clone(),
 5439            server_id,
 5440            LinkedEditingRange { position },
 5441            cx,
 5442        )
 5443    }
 5444
 5445    fn apply_on_type_formatting(
 5446        &mut self,
 5447        buffer: Entity<Buffer>,
 5448        position: Anchor,
 5449        trigger: String,
 5450        cx: &mut Context<Self>,
 5451    ) -> Task<Result<Option<Transaction>>> {
 5452        if let Some((client, project_id)) = self.upstream_client() {
 5453            if !self.check_if_capable_for_proto_request(
 5454                &buffer,
 5455                |capabilities| {
 5456                    OnTypeFormatting::supports_on_type_formatting(&trigger, capabilities)
 5457                },
 5458                cx,
 5459            ) {
 5460                return Task::ready(Ok(None));
 5461            }
 5462            let request = proto::OnTypeFormatting {
 5463                project_id,
 5464                buffer_id: buffer.read(cx).remote_id().into(),
 5465                position: Some(serialize_anchor(&position)),
 5466                trigger,
 5467                version: serialize_version(&buffer.read(cx).version()),
 5468            };
 5469            cx.background_spawn(async move {
 5470                client
 5471                    .request(request)
 5472                    .await?
 5473                    .transaction
 5474                    .map(language::proto::deserialize_transaction)
 5475                    .transpose()
 5476            })
 5477        } else if let Some(local) = self.as_local_mut() {
 5478            let buffer_id = buffer.read(cx).remote_id();
 5479            local.buffers_being_formatted.insert(buffer_id);
 5480            cx.spawn(async move |this, cx| {
 5481                let _cleanup = defer({
 5482                    let this = this.clone();
 5483                    let mut cx = cx.clone();
 5484                    move || {
 5485                        this.update(&mut cx, |this, _| {
 5486                            if let Some(local) = this.as_local_mut() {
 5487                                local.buffers_being_formatted.remove(&buffer_id);
 5488                            }
 5489                        })
 5490                        .ok();
 5491                    }
 5492                });
 5493
 5494                buffer
 5495                    .update(cx, |buffer, _| {
 5496                        buffer.wait_for_edits(Some(position.timestamp))
 5497                    })?
 5498                    .await?;
 5499                this.update(cx, |this, cx| {
 5500                    let position = position.to_point_utf16(buffer.read(cx));
 5501                    this.on_type_format(buffer, position, trigger, false, cx)
 5502                })?
 5503                .await
 5504            })
 5505        } else {
 5506            Task::ready(Err(anyhow!("No upstream client or local language server")))
 5507        }
 5508    }
 5509
 5510    pub fn on_type_format<T: ToPointUtf16>(
 5511        &mut self,
 5512        buffer: Entity<Buffer>,
 5513        position: T,
 5514        trigger: String,
 5515        push_to_history: bool,
 5516        cx: &mut Context<Self>,
 5517    ) -> Task<Result<Option<Transaction>>> {
 5518        let position = position.to_point_utf16(buffer.read(cx));
 5519        self.on_type_format_impl(buffer, position, trigger, push_to_history, cx)
 5520    }
 5521
 5522    fn on_type_format_impl(
 5523        &mut self,
 5524        buffer: Entity<Buffer>,
 5525        position: PointUtf16,
 5526        trigger: String,
 5527        push_to_history: bool,
 5528        cx: &mut Context<Self>,
 5529    ) -> Task<Result<Option<Transaction>>> {
 5530        let options = buffer.update(cx, |buffer, cx| {
 5531            lsp_command::lsp_formatting_options(
 5532                language_settings(
 5533                    buffer.language_at(position).map(|l| l.name()),
 5534                    buffer.file(),
 5535                    cx,
 5536                )
 5537                .as_ref(),
 5538            )
 5539        });
 5540
 5541        cx.spawn(async move |this, cx| {
 5542            if let Some(waiter) =
 5543                buffer.update(cx, |buffer, _| buffer.wait_for_autoindent_applied())?
 5544            {
 5545                waiter.await?;
 5546            }
 5547            cx.update(|cx| {
 5548                this.update(cx, |this, cx| {
 5549                    this.request_lsp(
 5550                        buffer.clone(),
 5551                        LanguageServerToQuery::FirstCapable,
 5552                        OnTypeFormatting {
 5553                            position,
 5554                            trigger,
 5555                            options,
 5556                            push_to_history,
 5557                        },
 5558                        cx,
 5559                    )
 5560                })
 5561            })??
 5562            .await
 5563        })
 5564    }
 5565
 5566    pub fn definitions(
 5567        &mut self,
 5568        buffer: &Entity<Buffer>,
 5569        position: PointUtf16,
 5570        cx: &mut Context<Self>,
 5571    ) -> Task<Result<Option<Vec<LocationLink>>>> {
 5572        if let Some((upstream_client, project_id)) = self.upstream_client() {
 5573            let request = GetDefinitions { position };
 5574            if !self.is_capable_for_proto_request(buffer, &request, cx) {
 5575                return Task::ready(Ok(None));
 5576            }
 5577            let request_task = upstream_client.request_lsp(
 5578                project_id,
 5579                None,
 5580                LSP_REQUEST_TIMEOUT,
 5581                cx.background_executor().clone(),
 5582                request.to_proto(project_id, buffer.read(cx)),
 5583            );
 5584            let buffer = buffer.clone();
 5585            cx.spawn(async move |weak_lsp_store, cx| {
 5586                let Some(lsp_store) = weak_lsp_store.upgrade() else {
 5587                    return Ok(None);
 5588                };
 5589                let Some(responses) = request_task.await? else {
 5590                    return Ok(None);
 5591                };
 5592                let actions = join_all(responses.payload.into_iter().map(|response| {
 5593                    GetDefinitions { position }.response_from_proto(
 5594                        response.response,
 5595                        lsp_store.clone(),
 5596                        buffer.clone(),
 5597                        cx.clone(),
 5598                    )
 5599                }))
 5600                .await;
 5601
 5602                Ok(Some(
 5603                    actions
 5604                        .into_iter()
 5605                        .collect::<Result<Vec<Vec<_>>>>()?
 5606                        .into_iter()
 5607                        .flatten()
 5608                        .dedup()
 5609                        .collect(),
 5610                ))
 5611            })
 5612        } else {
 5613            let definitions_task = self.request_multiple_lsp_locally(
 5614                buffer,
 5615                Some(position),
 5616                GetDefinitions { position },
 5617                cx,
 5618            );
 5619            cx.background_spawn(async move {
 5620                Ok(Some(
 5621                    definitions_task
 5622                        .await
 5623                        .into_iter()
 5624                        .flat_map(|(_, definitions)| definitions)
 5625                        .dedup()
 5626                        .collect(),
 5627                ))
 5628            })
 5629        }
 5630    }
 5631
 5632    pub fn declarations(
 5633        &mut self,
 5634        buffer: &Entity<Buffer>,
 5635        position: PointUtf16,
 5636        cx: &mut Context<Self>,
 5637    ) -> Task<Result<Option<Vec<LocationLink>>>> {
 5638        if let Some((upstream_client, project_id)) = self.upstream_client() {
 5639            let request = GetDeclarations { position };
 5640            if !self.is_capable_for_proto_request(buffer, &request, cx) {
 5641                return Task::ready(Ok(None));
 5642            }
 5643            let request_task = upstream_client.request_lsp(
 5644                project_id,
 5645                None,
 5646                LSP_REQUEST_TIMEOUT,
 5647                cx.background_executor().clone(),
 5648                request.to_proto(project_id, buffer.read(cx)),
 5649            );
 5650            let buffer = buffer.clone();
 5651            cx.spawn(async move |weak_lsp_store, cx| {
 5652                let Some(lsp_store) = weak_lsp_store.upgrade() else {
 5653                    return Ok(None);
 5654                };
 5655                let Some(responses) = request_task.await? else {
 5656                    return Ok(None);
 5657                };
 5658                let actions = join_all(responses.payload.into_iter().map(|response| {
 5659                    GetDeclarations { position }.response_from_proto(
 5660                        response.response,
 5661                        lsp_store.clone(),
 5662                        buffer.clone(),
 5663                        cx.clone(),
 5664                    )
 5665                }))
 5666                .await;
 5667
 5668                Ok(Some(
 5669                    actions
 5670                        .into_iter()
 5671                        .collect::<Result<Vec<Vec<_>>>>()?
 5672                        .into_iter()
 5673                        .flatten()
 5674                        .dedup()
 5675                        .collect(),
 5676                ))
 5677            })
 5678        } else {
 5679            let declarations_task = self.request_multiple_lsp_locally(
 5680                buffer,
 5681                Some(position),
 5682                GetDeclarations { position },
 5683                cx,
 5684            );
 5685            cx.background_spawn(async move {
 5686                Ok(Some(
 5687                    declarations_task
 5688                        .await
 5689                        .into_iter()
 5690                        .flat_map(|(_, declarations)| declarations)
 5691                        .dedup()
 5692                        .collect(),
 5693                ))
 5694            })
 5695        }
 5696    }
 5697
 5698    pub fn type_definitions(
 5699        &mut self,
 5700        buffer: &Entity<Buffer>,
 5701        position: PointUtf16,
 5702        cx: &mut Context<Self>,
 5703    ) -> Task<Result<Option<Vec<LocationLink>>>> {
 5704        if let Some((upstream_client, project_id)) = self.upstream_client() {
 5705            let request = GetTypeDefinitions { position };
 5706            if !self.is_capable_for_proto_request(buffer, &request, cx) {
 5707                return Task::ready(Ok(None));
 5708            }
 5709            let request_task = upstream_client.request_lsp(
 5710                project_id,
 5711                None,
 5712                LSP_REQUEST_TIMEOUT,
 5713                cx.background_executor().clone(),
 5714                request.to_proto(project_id, buffer.read(cx)),
 5715            );
 5716            let buffer = buffer.clone();
 5717            cx.spawn(async move |weak_lsp_store, cx| {
 5718                let Some(lsp_store) = weak_lsp_store.upgrade() else {
 5719                    return Ok(None);
 5720                };
 5721                let Some(responses) = request_task.await? else {
 5722                    return Ok(None);
 5723                };
 5724                let actions = join_all(responses.payload.into_iter().map(|response| {
 5725                    GetTypeDefinitions { position }.response_from_proto(
 5726                        response.response,
 5727                        lsp_store.clone(),
 5728                        buffer.clone(),
 5729                        cx.clone(),
 5730                    )
 5731                }))
 5732                .await;
 5733
 5734                Ok(Some(
 5735                    actions
 5736                        .into_iter()
 5737                        .collect::<Result<Vec<Vec<_>>>>()?
 5738                        .into_iter()
 5739                        .flatten()
 5740                        .dedup()
 5741                        .collect(),
 5742                ))
 5743            })
 5744        } else {
 5745            let type_definitions_task = self.request_multiple_lsp_locally(
 5746                buffer,
 5747                Some(position),
 5748                GetTypeDefinitions { position },
 5749                cx,
 5750            );
 5751            cx.background_spawn(async move {
 5752                Ok(Some(
 5753                    type_definitions_task
 5754                        .await
 5755                        .into_iter()
 5756                        .flat_map(|(_, type_definitions)| type_definitions)
 5757                        .dedup()
 5758                        .collect(),
 5759                ))
 5760            })
 5761        }
 5762    }
 5763
 5764    pub fn implementations(
 5765        &mut self,
 5766        buffer: &Entity<Buffer>,
 5767        position: PointUtf16,
 5768        cx: &mut Context<Self>,
 5769    ) -> Task<Result<Option<Vec<LocationLink>>>> {
 5770        if let Some((upstream_client, project_id)) = self.upstream_client() {
 5771            let request = GetImplementations { position };
 5772            if !self.is_capable_for_proto_request(buffer, &request, cx) {
 5773                return Task::ready(Ok(None));
 5774            }
 5775            let request_task = upstream_client.request_lsp(
 5776                project_id,
 5777                None,
 5778                LSP_REQUEST_TIMEOUT,
 5779                cx.background_executor().clone(),
 5780                request.to_proto(project_id, buffer.read(cx)),
 5781            );
 5782            let buffer = buffer.clone();
 5783            cx.spawn(async move |weak_lsp_store, cx| {
 5784                let Some(lsp_store) = weak_lsp_store.upgrade() else {
 5785                    return Ok(None);
 5786                };
 5787                let Some(responses) = request_task.await? else {
 5788                    return Ok(None);
 5789                };
 5790                let actions = join_all(responses.payload.into_iter().map(|response| {
 5791                    GetImplementations { position }.response_from_proto(
 5792                        response.response,
 5793                        lsp_store.clone(),
 5794                        buffer.clone(),
 5795                        cx.clone(),
 5796                    )
 5797                }))
 5798                .await;
 5799
 5800                Ok(Some(
 5801                    actions
 5802                        .into_iter()
 5803                        .collect::<Result<Vec<Vec<_>>>>()?
 5804                        .into_iter()
 5805                        .flatten()
 5806                        .dedup()
 5807                        .collect(),
 5808                ))
 5809            })
 5810        } else {
 5811            let implementations_task = self.request_multiple_lsp_locally(
 5812                buffer,
 5813                Some(position),
 5814                GetImplementations { position },
 5815                cx,
 5816            );
 5817            cx.background_spawn(async move {
 5818                Ok(Some(
 5819                    implementations_task
 5820                        .await
 5821                        .into_iter()
 5822                        .flat_map(|(_, implementations)| implementations)
 5823                        .dedup()
 5824                        .collect(),
 5825                ))
 5826            })
 5827        }
 5828    }
 5829
 5830    pub fn references(
 5831        &mut self,
 5832        buffer: &Entity<Buffer>,
 5833        position: PointUtf16,
 5834        cx: &mut Context<Self>,
 5835    ) -> Task<Result<Option<Vec<Location>>>> {
 5836        if let Some((upstream_client, project_id)) = self.upstream_client() {
 5837            let request = GetReferences { position };
 5838            if !self.is_capable_for_proto_request(buffer, &request, cx) {
 5839                return Task::ready(Ok(None));
 5840            }
 5841
 5842            let request_task = upstream_client.request_lsp(
 5843                project_id,
 5844                None,
 5845                LSP_REQUEST_TIMEOUT,
 5846                cx.background_executor().clone(),
 5847                request.to_proto(project_id, buffer.read(cx)),
 5848            );
 5849            let buffer = buffer.clone();
 5850            cx.spawn(async move |weak_lsp_store, cx| {
 5851                let Some(lsp_store) = weak_lsp_store.upgrade() else {
 5852                    return Ok(None);
 5853                };
 5854                let Some(responses) = request_task.await? else {
 5855                    return Ok(None);
 5856                };
 5857
 5858                let locations = join_all(responses.payload.into_iter().map(|lsp_response| {
 5859                    GetReferences { position }.response_from_proto(
 5860                        lsp_response.response,
 5861                        lsp_store.clone(),
 5862                        buffer.clone(),
 5863                        cx.clone(),
 5864                    )
 5865                }))
 5866                .await
 5867                .into_iter()
 5868                .collect::<Result<Vec<Vec<_>>>>()?
 5869                .into_iter()
 5870                .flatten()
 5871                .dedup()
 5872                .collect();
 5873                Ok(Some(locations))
 5874            })
 5875        } else {
 5876            let references_task = self.request_multiple_lsp_locally(
 5877                buffer,
 5878                Some(position),
 5879                GetReferences { position },
 5880                cx,
 5881            );
 5882            cx.background_spawn(async move {
 5883                Ok(Some(
 5884                    references_task
 5885                        .await
 5886                        .into_iter()
 5887                        .flat_map(|(_, references)| references)
 5888                        .dedup()
 5889                        .collect(),
 5890                ))
 5891            })
 5892        }
 5893    }
 5894
 5895    pub fn code_actions(
 5896        &mut self,
 5897        buffer: &Entity<Buffer>,
 5898        range: Range<Anchor>,
 5899        kinds: Option<Vec<CodeActionKind>>,
 5900        cx: &mut Context<Self>,
 5901    ) -> Task<Result<Option<Vec<CodeAction>>>> {
 5902        if let Some((upstream_client, project_id)) = self.upstream_client() {
 5903            let request = GetCodeActions {
 5904                range: range.clone(),
 5905                kinds: kinds.clone(),
 5906            };
 5907            if !self.is_capable_for_proto_request(buffer, &request, cx) {
 5908                return Task::ready(Ok(None));
 5909            }
 5910            let request_task = upstream_client.request_lsp(
 5911                project_id,
 5912                None,
 5913                LSP_REQUEST_TIMEOUT,
 5914                cx.background_executor().clone(),
 5915                request.to_proto(project_id, buffer.read(cx)),
 5916            );
 5917            let buffer = buffer.clone();
 5918            cx.spawn(async move |weak_lsp_store, cx| {
 5919                let Some(lsp_store) = weak_lsp_store.upgrade() else {
 5920                    return Ok(None);
 5921                };
 5922                let Some(responses) = request_task.await? else {
 5923                    return Ok(None);
 5924                };
 5925                let actions = join_all(responses.payload.into_iter().map(|response| {
 5926                    GetCodeActions {
 5927                        range: range.clone(),
 5928                        kinds: kinds.clone(),
 5929                    }
 5930                    .response_from_proto(
 5931                        response.response,
 5932                        lsp_store.clone(),
 5933                        buffer.clone(),
 5934                        cx.clone(),
 5935                    )
 5936                }))
 5937                .await;
 5938
 5939                Ok(Some(
 5940                    actions
 5941                        .into_iter()
 5942                        .collect::<Result<Vec<Vec<_>>>>()?
 5943                        .into_iter()
 5944                        .flatten()
 5945                        .collect(),
 5946                ))
 5947            })
 5948        } else {
 5949            let all_actions_task = self.request_multiple_lsp_locally(
 5950                buffer,
 5951                Some(range.start),
 5952                GetCodeActions { range, kinds },
 5953                cx,
 5954            );
 5955            cx.background_spawn(async move {
 5956                Ok(Some(
 5957                    all_actions_task
 5958                        .await
 5959                        .into_iter()
 5960                        .flat_map(|(_, actions)| actions)
 5961                        .collect(),
 5962                ))
 5963            })
 5964        }
 5965    }
 5966
 5967    pub fn code_lens_actions(
 5968        &mut self,
 5969        buffer: &Entity<Buffer>,
 5970        cx: &mut Context<Self>,
 5971    ) -> CodeLensTask {
 5972        let version_queried_for = buffer.read(cx).version();
 5973        let buffer_id = buffer.read(cx).remote_id();
 5974        let existing_servers = self.as_local().map(|local| {
 5975            local
 5976                .buffers_opened_in_servers
 5977                .get(&buffer_id)
 5978                .cloned()
 5979                .unwrap_or_default()
 5980        });
 5981
 5982        if let Some(lsp_data) = self.current_lsp_data(buffer_id) {
 5983            if let Some(cached_lens) = &lsp_data.code_lens {
 5984                if !version_queried_for.changed_since(&lsp_data.buffer_version) {
 5985                    let has_different_servers = existing_servers.is_some_and(|existing_servers| {
 5986                        existing_servers != cached_lens.lens.keys().copied().collect()
 5987                    });
 5988                    if !has_different_servers {
 5989                        return Task::ready(Ok(Some(
 5990                            cached_lens.lens.values().flatten().cloned().collect(),
 5991                        )))
 5992                        .shared();
 5993                    }
 5994                } else if let Some((updating_for, running_update)) = cached_lens.update.as_ref() {
 5995                    if !version_queried_for.changed_since(updating_for) {
 5996                        return running_update.clone();
 5997                    }
 5998                }
 5999            }
 6000        }
 6001
 6002        let lens_lsp_data = self
 6003            .latest_lsp_data(buffer, cx)
 6004            .code_lens
 6005            .get_or_insert_default();
 6006        let buffer = buffer.clone();
 6007        let query_version_queried_for = version_queried_for.clone();
 6008        let new_task = cx
 6009            .spawn(async move |lsp_store, cx| {
 6010                cx.background_executor()
 6011                    .timer(Duration::from_millis(30))
 6012                    .await;
 6013                let fetched_lens = lsp_store
 6014                    .update(cx, |lsp_store, cx| lsp_store.fetch_code_lens(&buffer, cx))
 6015                    .map_err(Arc::new)?
 6016                    .await
 6017                    .context("fetching code lens")
 6018                    .map_err(Arc::new);
 6019                let fetched_lens = match fetched_lens {
 6020                    Ok(fetched_lens) => fetched_lens,
 6021                    Err(e) => {
 6022                        lsp_store
 6023                            .update(cx, |lsp_store, _| {
 6024                                if let Some(lens_lsp_data) = lsp_store
 6025                                    .lsp_data
 6026                                    .get_mut(&buffer_id)
 6027                                    .and_then(|lsp_data| lsp_data.code_lens.as_mut())
 6028                                {
 6029                                    lens_lsp_data.update = None;
 6030                                }
 6031                            })
 6032                            .ok();
 6033                        return Err(e);
 6034                    }
 6035                };
 6036
 6037                lsp_store
 6038                    .update(cx, |lsp_store, _| {
 6039                        let lsp_data = lsp_store.current_lsp_data(buffer_id)?;
 6040                        let code_lens = lsp_data.code_lens.as_mut()?;
 6041                        if let Some(fetched_lens) = fetched_lens {
 6042                            if lsp_data.buffer_version == query_version_queried_for {
 6043                                code_lens.lens.extend(fetched_lens);
 6044                            } else if !lsp_data
 6045                                .buffer_version
 6046                                .changed_since(&query_version_queried_for)
 6047                            {
 6048                                lsp_data.buffer_version = query_version_queried_for;
 6049                                code_lens.lens = fetched_lens;
 6050                            }
 6051                        }
 6052                        code_lens.update = None;
 6053                        Some(code_lens.lens.values().flatten().cloned().collect())
 6054                    })
 6055                    .map_err(Arc::new)
 6056            })
 6057            .shared();
 6058        lens_lsp_data.update = Some((version_queried_for, new_task.clone()));
 6059        new_task
 6060    }
 6061
 6062    fn fetch_code_lens(
 6063        &mut self,
 6064        buffer: &Entity<Buffer>,
 6065        cx: &mut Context<Self>,
 6066    ) -> Task<Result<Option<HashMap<LanguageServerId, Vec<CodeAction>>>>> {
 6067        if let Some((upstream_client, project_id)) = self.upstream_client() {
 6068            let request = GetCodeLens;
 6069            if !self.is_capable_for_proto_request(buffer, &request, cx) {
 6070                return Task::ready(Ok(None));
 6071            }
 6072            let request_task = upstream_client.request_lsp(
 6073                project_id,
 6074                None,
 6075                LSP_REQUEST_TIMEOUT,
 6076                cx.background_executor().clone(),
 6077                request.to_proto(project_id, buffer.read(cx)),
 6078            );
 6079            let buffer = buffer.clone();
 6080            cx.spawn(async move |weak_lsp_store, cx| {
 6081                let Some(lsp_store) = weak_lsp_store.upgrade() else {
 6082                    return Ok(None);
 6083                };
 6084                let Some(responses) = request_task.await? else {
 6085                    return Ok(None);
 6086                };
 6087
 6088                let code_lens_actions = join_all(responses.payload.into_iter().map(|response| {
 6089                    let lsp_store = lsp_store.clone();
 6090                    let buffer = buffer.clone();
 6091                    let cx = cx.clone();
 6092                    async move {
 6093                        (
 6094                            LanguageServerId::from_proto(response.server_id),
 6095                            GetCodeLens
 6096                                .response_from_proto(response.response, lsp_store, buffer, cx)
 6097                                .await,
 6098                        )
 6099                    }
 6100                }))
 6101                .await;
 6102
 6103                let mut has_errors = false;
 6104                let code_lens_actions = code_lens_actions
 6105                    .into_iter()
 6106                    .filter_map(|(server_id, code_lens)| match code_lens {
 6107                        Ok(code_lens) => Some((server_id, code_lens)),
 6108                        Err(e) => {
 6109                            has_errors = true;
 6110                            log::error!("{e:#}");
 6111                            None
 6112                        }
 6113                    })
 6114                    .collect::<HashMap<_, _>>();
 6115                anyhow::ensure!(
 6116                    !has_errors || !code_lens_actions.is_empty(),
 6117                    "Failed to fetch code lens"
 6118                );
 6119                Ok(Some(code_lens_actions))
 6120            })
 6121        } else {
 6122            let code_lens_actions_task =
 6123                self.request_multiple_lsp_locally(buffer, None::<usize>, GetCodeLens, cx);
 6124            cx.background_spawn(async move {
 6125                Ok(Some(code_lens_actions_task.await.into_iter().collect()))
 6126            })
 6127        }
 6128    }
 6129
 6130    #[inline(never)]
 6131    pub fn completions(
 6132        &self,
 6133        buffer: &Entity<Buffer>,
 6134        position: PointUtf16,
 6135        context: CompletionContext,
 6136        cx: &mut Context<Self>,
 6137    ) -> Task<Result<Vec<CompletionResponse>>> {
 6138        let language_registry = self.languages.clone();
 6139
 6140        if let Some((upstream_client, project_id)) = self.upstream_client() {
 6141            let snapshot = buffer.read(cx).snapshot();
 6142            let offset = position.to_offset(&snapshot);
 6143            let scope = snapshot.language_scope_at(offset);
 6144            let capable_lsps = self.all_capable_for_proto_request(
 6145                buffer,
 6146                |server_name, capabilities| {
 6147                    capabilities.completion_provider.is_some()
 6148                        && scope
 6149                            .as_ref()
 6150                            .map(|scope| scope.language_allowed(server_name))
 6151                            .unwrap_or(true)
 6152                },
 6153                cx,
 6154            );
 6155            if capable_lsps.is_empty() {
 6156                return Task::ready(Ok(Vec::new()));
 6157            }
 6158
 6159            let language = buffer.read(cx).language().cloned();
 6160
 6161            // In the future, we should provide project guests with the names of LSP adapters,
 6162            // so that they can use the correct LSP adapter when computing labels. For now,
 6163            // guests just use the first LSP adapter associated with the buffer's language.
 6164            let lsp_adapter = language.as_ref().and_then(|language| {
 6165                language_registry
 6166                    .lsp_adapters(&language.name())
 6167                    .first()
 6168                    .cloned()
 6169            });
 6170
 6171            let buffer = buffer.clone();
 6172
 6173            cx.spawn(async move |this, cx| {
 6174                let requests = join_all(
 6175                    capable_lsps
 6176                        .into_iter()
 6177                        .map(|id| {
 6178                            let request = GetCompletions {
 6179                                position,
 6180                                context: context.clone(),
 6181                                server_id: Some(id),
 6182                            };
 6183                            let buffer = buffer.clone();
 6184                            let language = language.clone();
 6185                            let lsp_adapter = lsp_adapter.clone();
 6186                            let upstream_client = upstream_client.clone();
 6187                            let response = this
 6188                                .update(cx, |this, cx| {
 6189                                    this.send_lsp_proto_request(
 6190                                        buffer,
 6191                                        upstream_client,
 6192                                        project_id,
 6193                                        request,
 6194                                        cx,
 6195                                    )
 6196                                })
 6197                                .log_err();
 6198                            async move {
 6199                                let response = response?.await.log_err()?;
 6200
 6201                                let completions = populate_labels_for_completions(
 6202                                    response.completions,
 6203                                    language,
 6204                                    lsp_adapter,
 6205                                )
 6206                                .await;
 6207
 6208                                Some(CompletionResponse {
 6209                                    completions,
 6210                                    display_options: CompletionDisplayOptions::default(),
 6211                                    is_incomplete: response.is_incomplete,
 6212                                })
 6213                            }
 6214                        })
 6215                        .collect::<Vec<_>>(),
 6216                );
 6217                Ok(requests.await.into_iter().flatten().collect::<Vec<_>>())
 6218            })
 6219        } else if let Some(local) = self.as_local() {
 6220            let snapshot = buffer.read(cx).snapshot();
 6221            let offset = position.to_offset(&snapshot);
 6222            let scope = snapshot.language_scope_at(offset);
 6223            let language = snapshot.language().cloned();
 6224            let completion_settings = language_settings(
 6225                language.as_ref().map(|language| language.name()),
 6226                buffer.read(cx).file(),
 6227                cx,
 6228            )
 6229            .completions
 6230            .clone();
 6231            if !completion_settings.lsp {
 6232                return Task::ready(Ok(Vec::new()));
 6233            }
 6234
 6235            let server_ids: Vec<_> = buffer.update(cx, |buffer, cx| {
 6236                local
 6237                    .language_servers_for_buffer(buffer, cx)
 6238                    .filter(|(_, server)| server.capabilities().completion_provider.is_some())
 6239                    .filter(|(adapter, _)| {
 6240                        scope
 6241                            .as_ref()
 6242                            .map(|scope| scope.language_allowed(&adapter.name))
 6243                            .unwrap_or(true)
 6244                    })
 6245                    .map(|(_, server)| server.server_id())
 6246                    .collect()
 6247            });
 6248
 6249            let buffer = buffer.clone();
 6250            let lsp_timeout = completion_settings.lsp_fetch_timeout_ms;
 6251            let lsp_timeout = if lsp_timeout > 0 {
 6252                Some(Duration::from_millis(lsp_timeout))
 6253            } else {
 6254                None
 6255            };
 6256            cx.spawn(async move |this,  cx| {
 6257                let mut tasks = Vec::with_capacity(server_ids.len());
 6258                this.update(cx, |lsp_store, cx| {
 6259                    for server_id in server_ids {
 6260                        let lsp_adapter = lsp_store.language_server_adapter_for_id(server_id);
 6261                        let lsp_timeout = lsp_timeout
 6262                            .map(|lsp_timeout| cx.background_executor().timer(lsp_timeout));
 6263                        let mut timeout = cx.background_spawn(async move {
 6264                            match lsp_timeout {
 6265                                Some(lsp_timeout) => {
 6266                                    lsp_timeout.await;
 6267                                    true
 6268                                },
 6269                                None => false,
 6270                            }
 6271                        }).fuse();
 6272                        let mut lsp_request = lsp_store.request_lsp(
 6273                            buffer.clone(),
 6274                            LanguageServerToQuery::Other(server_id),
 6275                            GetCompletions {
 6276                                position,
 6277                                context: context.clone(),
 6278                                server_id: Some(server_id),
 6279                            },
 6280                            cx,
 6281                        ).fuse();
 6282                        let new_task = cx.background_spawn(async move {
 6283                            select_biased! {
 6284                                response = lsp_request => anyhow::Ok(Some(response?)),
 6285                                timeout_happened = timeout => {
 6286                                    if timeout_happened {
 6287                                        log::warn!("Fetching completions from server {server_id} timed out, timeout ms: {}", completion_settings.lsp_fetch_timeout_ms);
 6288                                        Ok(None)
 6289                                    } else {
 6290                                        let completions = lsp_request.await?;
 6291                                        Ok(Some(completions))
 6292                                    }
 6293                                },
 6294                            }
 6295                        });
 6296                        tasks.push((lsp_adapter, new_task));
 6297                    }
 6298                })?;
 6299
 6300                let futures = tasks.into_iter().map(async |(lsp_adapter, task)| {
 6301                    let completion_response = task.await.ok()??;
 6302                    let completions = populate_labels_for_completions(
 6303                            completion_response.completions,
 6304                            language.clone(),
 6305                            lsp_adapter,
 6306                        )
 6307                        .await;
 6308                    Some(CompletionResponse {
 6309                        completions,
 6310                        display_options: CompletionDisplayOptions::default(),
 6311                        is_incomplete: completion_response.is_incomplete,
 6312                    })
 6313                });
 6314
 6315                let responses: Vec<Option<CompletionResponse>> = join_all(futures).await;
 6316
 6317                Ok(responses.into_iter().flatten().collect())
 6318            })
 6319        } else {
 6320            Task::ready(Err(anyhow!("No upstream client or local language server")))
 6321        }
 6322    }
 6323
 6324    pub fn resolve_completions(
 6325        &self,
 6326        buffer: Entity<Buffer>,
 6327        completion_indices: Vec<usize>,
 6328        completions: Rc<RefCell<Box<[Completion]>>>,
 6329        cx: &mut Context<Self>,
 6330    ) -> Task<Result<bool>> {
 6331        let client = self.upstream_client();
 6332        let buffer_id = buffer.read(cx).remote_id();
 6333        let buffer_snapshot = buffer.read(cx).snapshot();
 6334
 6335        if !self.check_if_capable_for_proto_request(
 6336            &buffer,
 6337            GetCompletions::can_resolve_completions,
 6338            cx,
 6339        ) {
 6340            return Task::ready(Ok(false));
 6341        }
 6342        cx.spawn(async move |lsp_store, cx| {
 6343            let mut did_resolve = false;
 6344            if let Some((client, project_id)) = client {
 6345                for completion_index in completion_indices {
 6346                    let server_id = {
 6347                        let completion = &completions.borrow()[completion_index];
 6348                        completion.source.server_id()
 6349                    };
 6350                    if let Some(server_id) = server_id {
 6351                        if Self::resolve_completion_remote(
 6352                            project_id,
 6353                            server_id,
 6354                            buffer_id,
 6355                            completions.clone(),
 6356                            completion_index,
 6357                            client.clone(),
 6358                        )
 6359                        .await
 6360                        .log_err()
 6361                        .is_some()
 6362                        {
 6363                            did_resolve = true;
 6364                        }
 6365                    } else {
 6366                        resolve_word_completion(
 6367                            &buffer_snapshot,
 6368                            &mut completions.borrow_mut()[completion_index],
 6369                        );
 6370                    }
 6371                }
 6372            } else {
 6373                for completion_index in completion_indices {
 6374                    let server_id = {
 6375                        let completion = &completions.borrow()[completion_index];
 6376                        completion.source.server_id()
 6377                    };
 6378                    if let Some(server_id) = server_id {
 6379                        let server_and_adapter = lsp_store
 6380                            .read_with(cx, |lsp_store, _| {
 6381                                let server = lsp_store.language_server_for_id(server_id)?;
 6382                                let adapter =
 6383                                    lsp_store.language_server_adapter_for_id(server.server_id())?;
 6384                                Some((server, adapter))
 6385                            })
 6386                            .ok()
 6387                            .flatten();
 6388                        let Some((server, adapter)) = server_and_adapter else {
 6389                            continue;
 6390                        };
 6391
 6392                        let resolved = Self::resolve_completion_local(
 6393                            server,
 6394                            completions.clone(),
 6395                            completion_index,
 6396                        )
 6397                        .await
 6398                        .log_err()
 6399                        .is_some();
 6400                        if resolved {
 6401                            Self::regenerate_completion_labels(
 6402                                adapter,
 6403                                &buffer_snapshot,
 6404                                completions.clone(),
 6405                                completion_index,
 6406                            )
 6407                            .await
 6408                            .log_err();
 6409                            did_resolve = true;
 6410                        }
 6411                    } else {
 6412                        resolve_word_completion(
 6413                            &buffer_snapshot,
 6414                            &mut completions.borrow_mut()[completion_index],
 6415                        );
 6416                    }
 6417                }
 6418            }
 6419
 6420            Ok(did_resolve)
 6421        })
 6422    }
 6423
 6424    async fn resolve_completion_local(
 6425        server: Arc<lsp::LanguageServer>,
 6426        completions: Rc<RefCell<Box<[Completion]>>>,
 6427        completion_index: usize,
 6428    ) -> Result<()> {
 6429        let server_id = server.server_id();
 6430        if !GetCompletions::can_resolve_completions(&server.capabilities()) {
 6431            return Ok(());
 6432        }
 6433
 6434        let request = {
 6435            let completion = &completions.borrow()[completion_index];
 6436            match &completion.source {
 6437                CompletionSource::Lsp {
 6438                    lsp_completion,
 6439                    resolved,
 6440                    server_id: completion_server_id,
 6441                    ..
 6442                } => {
 6443                    if *resolved {
 6444                        return Ok(());
 6445                    }
 6446                    anyhow::ensure!(
 6447                        server_id == *completion_server_id,
 6448                        "server_id mismatch, querying completion resolve for {server_id} but completion server id is {completion_server_id}"
 6449                    );
 6450                    server.request::<lsp::request::ResolveCompletionItem>(*lsp_completion.clone())
 6451                }
 6452                CompletionSource::BufferWord { .. }
 6453                | CompletionSource::Dap { .. }
 6454                | CompletionSource::Custom => {
 6455                    return Ok(());
 6456                }
 6457            }
 6458        };
 6459        let resolved_completion = request
 6460            .await
 6461            .into_response()
 6462            .context("resolve completion")?;
 6463
 6464        // We must not use any data such as sortText, filterText, insertText and textEdit to edit `Completion` since they are not suppose change during resolve.
 6465        // Refer: https://microsoft.github.io/language-server-protocol/specifications/lsp/3.17/specification/#textDocument_completion
 6466
 6467        let mut completions = completions.borrow_mut();
 6468        let completion = &mut completions[completion_index];
 6469        if let CompletionSource::Lsp {
 6470            lsp_completion,
 6471            resolved,
 6472            server_id: completion_server_id,
 6473            ..
 6474        } = &mut completion.source
 6475        {
 6476            if *resolved {
 6477                return Ok(());
 6478            }
 6479            anyhow::ensure!(
 6480                server_id == *completion_server_id,
 6481                "server_id mismatch, applying completion resolve for {server_id} but completion server id is {completion_server_id}"
 6482            );
 6483            *lsp_completion = Box::new(resolved_completion);
 6484            *resolved = true;
 6485        }
 6486        Ok(())
 6487    }
 6488
 6489    async fn regenerate_completion_labels(
 6490        adapter: Arc<CachedLspAdapter>,
 6491        snapshot: &BufferSnapshot,
 6492        completions: Rc<RefCell<Box<[Completion]>>>,
 6493        completion_index: usize,
 6494    ) -> Result<()> {
 6495        let completion_item = completions.borrow()[completion_index]
 6496            .source
 6497            .lsp_completion(true)
 6498            .map(Cow::into_owned);
 6499        if let Some(lsp_documentation) = completion_item
 6500            .as_ref()
 6501            .and_then(|completion_item| completion_item.documentation.clone())
 6502        {
 6503            let mut completions = completions.borrow_mut();
 6504            let completion = &mut completions[completion_index];
 6505            completion.documentation = Some(lsp_documentation.into());
 6506        } else {
 6507            let mut completions = completions.borrow_mut();
 6508            let completion = &mut completions[completion_index];
 6509            completion.documentation = Some(CompletionDocumentation::Undocumented);
 6510        }
 6511
 6512        let mut new_label = match completion_item {
 6513            Some(completion_item) => {
 6514                // NB: Zed does not have `details` inside the completion resolve capabilities, but certain language servers violate the spec and do not return `details` immediately, e.g. https://github.com/yioneko/vtsls/issues/213
 6515                // So we have to update the label here anyway...
 6516                let language = snapshot.language();
 6517                match language {
 6518                    Some(language) => {
 6519                        adapter
 6520                            .labels_for_completions(
 6521                                std::slice::from_ref(&completion_item),
 6522                                language,
 6523                            )
 6524                            .await?
 6525                    }
 6526                    None => Vec::new(),
 6527                }
 6528                .pop()
 6529                .flatten()
 6530                .unwrap_or_else(|| {
 6531                    CodeLabel::fallback_for_completion(
 6532                        &completion_item,
 6533                        language.map(|language| language.as_ref()),
 6534                    )
 6535                })
 6536            }
 6537            None => CodeLabel::plain(
 6538                completions.borrow()[completion_index].new_text.clone(),
 6539                None,
 6540            ),
 6541        };
 6542        ensure_uniform_list_compatible_label(&mut new_label);
 6543
 6544        let mut completions = completions.borrow_mut();
 6545        let completion = &mut completions[completion_index];
 6546        if completion.label.filter_text() == new_label.filter_text() {
 6547            completion.label = new_label;
 6548        } else {
 6549            log::error!(
 6550                "Resolved completion changed display label from {} to {}. \
 6551                 Refusing to apply this because it changes the fuzzy match text from {} to {}",
 6552                completion.label.text(),
 6553                new_label.text(),
 6554                completion.label.filter_text(),
 6555                new_label.filter_text()
 6556            );
 6557        }
 6558
 6559        Ok(())
 6560    }
 6561
 6562    async fn resolve_completion_remote(
 6563        project_id: u64,
 6564        server_id: LanguageServerId,
 6565        buffer_id: BufferId,
 6566        completions: Rc<RefCell<Box<[Completion]>>>,
 6567        completion_index: usize,
 6568        client: AnyProtoClient,
 6569    ) -> Result<()> {
 6570        let lsp_completion = {
 6571            let completion = &completions.borrow()[completion_index];
 6572            match &completion.source {
 6573                CompletionSource::Lsp {
 6574                    lsp_completion,
 6575                    resolved,
 6576                    server_id: completion_server_id,
 6577                    ..
 6578                } => {
 6579                    anyhow::ensure!(
 6580                        server_id == *completion_server_id,
 6581                        "remote server_id mismatch, querying completion resolve for {server_id} but completion server id is {completion_server_id}"
 6582                    );
 6583                    if *resolved {
 6584                        return Ok(());
 6585                    }
 6586                    serde_json::to_string(lsp_completion).unwrap().into_bytes()
 6587                }
 6588                CompletionSource::Custom
 6589                | CompletionSource::Dap { .. }
 6590                | CompletionSource::BufferWord { .. } => {
 6591                    return Ok(());
 6592                }
 6593            }
 6594        };
 6595        let request = proto::ResolveCompletionDocumentation {
 6596            project_id,
 6597            language_server_id: server_id.0 as u64,
 6598            lsp_completion,
 6599            buffer_id: buffer_id.into(),
 6600        };
 6601
 6602        let response = client
 6603            .request(request)
 6604            .await
 6605            .context("completion documentation resolve proto request")?;
 6606        let resolved_lsp_completion = serde_json::from_slice(&response.lsp_completion)?;
 6607
 6608        let documentation = if response.documentation.is_empty() {
 6609            CompletionDocumentation::Undocumented
 6610        } else if response.documentation_is_markdown {
 6611            CompletionDocumentation::MultiLineMarkdown(response.documentation.into())
 6612        } else if response.documentation.lines().count() <= 1 {
 6613            CompletionDocumentation::SingleLine(response.documentation.into())
 6614        } else {
 6615            CompletionDocumentation::MultiLinePlainText(response.documentation.into())
 6616        };
 6617
 6618        let mut completions = completions.borrow_mut();
 6619        let completion = &mut completions[completion_index];
 6620        completion.documentation = Some(documentation);
 6621        if let CompletionSource::Lsp {
 6622            insert_range,
 6623            lsp_completion,
 6624            resolved,
 6625            server_id: completion_server_id,
 6626            lsp_defaults: _,
 6627        } = &mut completion.source
 6628        {
 6629            let completion_insert_range = response
 6630                .old_insert_start
 6631                .and_then(deserialize_anchor)
 6632                .zip(response.old_insert_end.and_then(deserialize_anchor));
 6633            *insert_range = completion_insert_range.map(|(start, end)| start..end);
 6634
 6635            if *resolved {
 6636                return Ok(());
 6637            }
 6638            anyhow::ensure!(
 6639                server_id == *completion_server_id,
 6640                "remote server_id mismatch, applying completion resolve for {server_id} but completion server id is {completion_server_id}"
 6641            );
 6642            *lsp_completion = Box::new(resolved_lsp_completion);
 6643            *resolved = true;
 6644        }
 6645
 6646        let replace_range = response
 6647            .old_replace_start
 6648            .and_then(deserialize_anchor)
 6649            .zip(response.old_replace_end.and_then(deserialize_anchor));
 6650        if let Some((old_replace_start, old_replace_end)) = replace_range
 6651            && !response.new_text.is_empty()
 6652        {
 6653            completion.new_text = response.new_text;
 6654            completion.replace_range = old_replace_start..old_replace_end;
 6655        }
 6656
 6657        Ok(())
 6658    }
 6659
 6660    pub fn apply_additional_edits_for_completion(
 6661        &self,
 6662        buffer_handle: Entity<Buffer>,
 6663        completions: Rc<RefCell<Box<[Completion]>>>,
 6664        completion_index: usize,
 6665        push_to_history: bool,
 6666        cx: &mut Context<Self>,
 6667    ) -> Task<Result<Option<Transaction>>> {
 6668        if let Some((client, project_id)) = self.upstream_client() {
 6669            let buffer = buffer_handle.read(cx);
 6670            let buffer_id = buffer.remote_id();
 6671            cx.spawn(async move |_, cx| {
 6672                let request = {
 6673                    let completion = completions.borrow()[completion_index].clone();
 6674                    proto::ApplyCompletionAdditionalEdits {
 6675                        project_id,
 6676                        buffer_id: buffer_id.into(),
 6677                        completion: Some(Self::serialize_completion(&CoreCompletion {
 6678                            replace_range: completion.replace_range,
 6679                            new_text: completion.new_text,
 6680                            source: completion.source,
 6681                        })),
 6682                    }
 6683                };
 6684
 6685                if let Some(transaction) = client.request(request).await?.transaction {
 6686                    let transaction = language::proto::deserialize_transaction(transaction)?;
 6687                    buffer_handle
 6688                        .update(cx, |buffer, _| {
 6689                            buffer.wait_for_edits(transaction.edit_ids.iter().copied())
 6690                        })?
 6691                        .await?;
 6692                    if push_to_history {
 6693                        buffer_handle.update(cx, |buffer, _| {
 6694                            buffer.push_transaction(transaction.clone(), Instant::now());
 6695                            buffer.finalize_last_transaction();
 6696                        })?;
 6697                    }
 6698                    Ok(Some(transaction))
 6699                } else {
 6700                    Ok(None)
 6701                }
 6702            })
 6703        } else {
 6704            let Some(server) = buffer_handle.update(cx, |buffer, cx| {
 6705                let completion = &completions.borrow()[completion_index];
 6706                let server_id = completion.source.server_id()?;
 6707                Some(
 6708                    self.language_server_for_local_buffer(buffer, server_id, cx)?
 6709                        .1
 6710                        .clone(),
 6711                )
 6712            }) else {
 6713                return Task::ready(Ok(None));
 6714            };
 6715
 6716            cx.spawn(async move |this, cx| {
 6717                Self::resolve_completion_local(
 6718                    server.clone(),
 6719                    completions.clone(),
 6720                    completion_index,
 6721                )
 6722                .await
 6723                .context("resolving completion")?;
 6724                let completion = completions.borrow()[completion_index].clone();
 6725                let additional_text_edits = completion
 6726                    .source
 6727                    .lsp_completion(true)
 6728                    .as_ref()
 6729                    .and_then(|lsp_completion| lsp_completion.additional_text_edits.clone());
 6730                if let Some(edits) = additional_text_edits {
 6731                    let edits = this
 6732                        .update(cx, |this, cx| {
 6733                            this.as_local_mut().unwrap().edits_from_lsp(
 6734                                &buffer_handle,
 6735                                edits,
 6736                                server.server_id(),
 6737                                None,
 6738                                cx,
 6739                            )
 6740                        })?
 6741                        .await?;
 6742
 6743                    buffer_handle.update(cx, |buffer, cx| {
 6744                        buffer.finalize_last_transaction();
 6745                        buffer.start_transaction();
 6746
 6747                        for (range, text) in edits {
 6748                            let primary = &completion.replace_range;
 6749
 6750                            // Special case: if both ranges start at the very beginning of the file (line 0, column 0),
 6751                            // and the primary completion is just an insertion (empty range), then this is likely
 6752                            // an auto-import scenario and should not be considered overlapping
 6753                            // https://github.com/zed-industries/zed/issues/26136
 6754                            let is_file_start_auto_import = {
 6755                                let snapshot = buffer.snapshot();
 6756                                let primary_start_point = primary.start.to_point(&snapshot);
 6757                                let range_start_point = range.start.to_point(&snapshot);
 6758
 6759                                let result = primary_start_point.row == 0
 6760                                    && primary_start_point.column == 0
 6761                                    && range_start_point.row == 0
 6762                                    && range_start_point.column == 0;
 6763
 6764                                result
 6765                            };
 6766
 6767                            let has_overlap = if is_file_start_auto_import {
 6768                                false
 6769                            } else {
 6770                                let start_within = primary.start.cmp(&range.start, buffer).is_le()
 6771                                    && primary.end.cmp(&range.start, buffer).is_ge();
 6772                                let end_within = range.start.cmp(&primary.end, buffer).is_le()
 6773                                    && range.end.cmp(&primary.end, buffer).is_ge();
 6774                                let result = start_within || end_within;
 6775                                result
 6776                            };
 6777
 6778                            //Skip additional edits which overlap with the primary completion edit
 6779                            //https://github.com/zed-industries/zed/pull/1871
 6780                            if !has_overlap {
 6781                                buffer.edit([(range, text)], None, cx);
 6782                            }
 6783                        }
 6784
 6785                        let transaction = if buffer.end_transaction(cx).is_some() {
 6786                            let transaction = buffer.finalize_last_transaction().unwrap().clone();
 6787                            if !push_to_history {
 6788                                buffer.forget_transaction(transaction.id);
 6789                            }
 6790                            Some(transaction)
 6791                        } else {
 6792                            None
 6793                        };
 6794                        Ok(transaction)
 6795                    })?
 6796                } else {
 6797                    Ok(None)
 6798                }
 6799            })
 6800        }
 6801    }
 6802
 6803    pub fn pull_diagnostics(
 6804        &mut self,
 6805        buffer: Entity<Buffer>,
 6806        cx: &mut Context<Self>,
 6807    ) -> Task<Result<Option<Vec<LspPullDiagnostics>>>> {
 6808        let buffer_id = buffer.read(cx).remote_id();
 6809
 6810        if let Some((client, upstream_project_id)) = self.upstream_client() {
 6811            let mut suitable_capabilities = None;
 6812            // Are we capable for proto request?
 6813            let any_server_has_diagnostics_provider = self.check_if_capable_for_proto_request(
 6814                &buffer,
 6815                |capabilities| {
 6816                    if let Some(caps) = &capabilities.diagnostic_provider {
 6817                        suitable_capabilities = Some(caps.clone());
 6818                        true
 6819                    } else {
 6820                        false
 6821                    }
 6822                },
 6823                cx,
 6824            );
 6825            // We don't really care which caps are passed into the request, as they're ignored by RPC anyways.
 6826            let Some(dynamic_caps) = suitable_capabilities else {
 6827                return Task::ready(Ok(None));
 6828            };
 6829            assert!(any_server_has_diagnostics_provider);
 6830
 6831            let identifier = buffer_diagnostic_identifier(&dynamic_caps);
 6832            let request = GetDocumentDiagnostics {
 6833                previous_result_id: None,
 6834                identifier,
 6835                registration_id: None,
 6836            };
 6837            let request_task = client.request_lsp(
 6838                upstream_project_id,
 6839                None,
 6840                LSP_REQUEST_TIMEOUT,
 6841                cx.background_executor().clone(),
 6842                request.to_proto(upstream_project_id, buffer.read(cx)),
 6843            );
 6844            cx.background_spawn(async move {
 6845                // Proto requests cause the diagnostics to be pulled from language server(s) on the local side
 6846                // and then, buffer state updated with the diagnostics received, which will be later propagated to the client.
 6847                // Do not attempt to further process the dummy responses here.
 6848                let _response = request_task.await?;
 6849                Ok(None)
 6850            })
 6851        } else {
 6852            let servers = buffer.update(cx, |buffer, cx| {
 6853                self.running_language_servers_for_local_buffer(buffer, cx)
 6854                    .map(|(_, server)| server.clone())
 6855                    .collect::<Vec<_>>()
 6856            });
 6857
 6858            let pull_diagnostics = servers
 6859                .into_iter()
 6860                .flat_map(|server| {
 6861                    let result = maybe!({
 6862                        let local = self.as_local()?;
 6863                        let server_id = server.server_id();
 6864                        let providers_with_identifiers = local
 6865                            .language_server_dynamic_registrations
 6866                            .get(&server_id)
 6867                            .into_iter()
 6868                            .flat_map(|registrations| registrations.diagnostics.clone())
 6869                            .collect::<Vec<_>>();
 6870                        Some(
 6871                            providers_with_identifiers
 6872                                .into_iter()
 6873                                .map(|(registration_id, dynamic_caps)| {
 6874                                    let identifier = buffer_diagnostic_identifier(&dynamic_caps);
 6875                                    let registration_id = registration_id.map(SharedString::from);
 6876                                    let result_id = self.result_id_for_buffer_pull(
 6877                                        server_id,
 6878                                        buffer_id,
 6879                                        &registration_id,
 6880                                        cx,
 6881                                    );
 6882                                    self.request_lsp(
 6883                                        buffer.clone(),
 6884                                        LanguageServerToQuery::Other(server_id),
 6885                                        GetDocumentDiagnostics {
 6886                                            previous_result_id: result_id,
 6887                                            registration_id,
 6888                                            identifier,
 6889                                        },
 6890                                        cx,
 6891                                    )
 6892                                })
 6893                                .collect::<Vec<_>>(),
 6894                        )
 6895                    });
 6896
 6897                    result.unwrap_or_default()
 6898                })
 6899                .collect::<Vec<_>>();
 6900
 6901            cx.background_spawn(async move {
 6902                let mut responses = Vec::new();
 6903                for diagnostics in join_all(pull_diagnostics).await {
 6904                    responses.extend(diagnostics?);
 6905                }
 6906                Ok(Some(responses))
 6907            })
 6908        }
 6909    }
 6910
 6911    pub fn applicable_inlay_chunks(
 6912        &mut self,
 6913        buffer: &Entity<Buffer>,
 6914        ranges: &[Range<text::Anchor>],
 6915        cx: &mut Context<Self>,
 6916    ) -> Vec<Range<BufferRow>> {
 6917        let buffer_snapshot = buffer.read(cx).snapshot();
 6918        let ranges = ranges
 6919            .iter()
 6920            .map(|range| range.to_point(&buffer_snapshot))
 6921            .collect::<Vec<_>>();
 6922
 6923        self.latest_lsp_data(buffer, cx)
 6924            .inlay_hints
 6925            .applicable_chunks(ranges.as_slice())
 6926            .map(|chunk| chunk.row_range())
 6927            .collect()
 6928    }
 6929
 6930    pub fn invalidate_inlay_hints<'a>(
 6931        &'a mut self,
 6932        for_buffers: impl IntoIterator<Item = &'a BufferId> + 'a,
 6933    ) {
 6934        for buffer_id in for_buffers {
 6935            if let Some(lsp_data) = self.lsp_data.get_mut(buffer_id) {
 6936                lsp_data.inlay_hints.clear();
 6937            }
 6938        }
 6939    }
 6940
 6941    pub fn inlay_hints(
 6942        &mut self,
 6943        invalidate: InvalidationStrategy,
 6944        buffer: Entity<Buffer>,
 6945        ranges: Vec<Range<text::Anchor>>,
 6946        known_chunks: Option<(clock::Global, HashSet<Range<BufferRow>>)>,
 6947        cx: &mut Context<Self>,
 6948    ) -> HashMap<Range<BufferRow>, Task<Result<CacheInlayHints>>> {
 6949        let next_hint_id = self.next_hint_id.clone();
 6950        let lsp_data = self.latest_lsp_data(&buffer, cx);
 6951        let query_version = lsp_data.buffer_version.clone();
 6952        let mut lsp_refresh_requested = false;
 6953        let for_server = if let InvalidationStrategy::RefreshRequested {
 6954            server_id,
 6955            request_id,
 6956        } = invalidate
 6957        {
 6958            let invalidated = lsp_data
 6959                .inlay_hints
 6960                .invalidate_for_server_refresh(server_id, request_id);
 6961            lsp_refresh_requested = invalidated;
 6962            Some(server_id)
 6963        } else {
 6964            None
 6965        };
 6966        let existing_inlay_hints = &mut lsp_data.inlay_hints;
 6967        let known_chunks = known_chunks
 6968            .filter(|(known_version, _)| !lsp_data.buffer_version.changed_since(known_version))
 6969            .map(|(_, known_chunks)| known_chunks)
 6970            .unwrap_or_default();
 6971
 6972        let buffer_snapshot = buffer.read(cx).snapshot();
 6973        let ranges = ranges
 6974            .iter()
 6975            .map(|range| range.to_point(&buffer_snapshot))
 6976            .collect::<Vec<_>>();
 6977
 6978        let mut hint_fetch_tasks = Vec::new();
 6979        let mut cached_inlay_hints = None;
 6980        let mut ranges_to_query = None;
 6981        let applicable_chunks = existing_inlay_hints
 6982            .applicable_chunks(ranges.as_slice())
 6983            .filter(|chunk| !known_chunks.contains(&chunk.row_range()))
 6984            .collect::<Vec<_>>();
 6985        if applicable_chunks.is_empty() {
 6986            return HashMap::default();
 6987        }
 6988
 6989        for row_chunk in applicable_chunks {
 6990            match (
 6991                existing_inlay_hints
 6992                    .cached_hints(&row_chunk)
 6993                    .filter(|_| !lsp_refresh_requested)
 6994                    .cloned(),
 6995                existing_inlay_hints
 6996                    .fetched_hints(&row_chunk)
 6997                    .as_ref()
 6998                    .filter(|_| !lsp_refresh_requested)
 6999                    .cloned(),
 7000            ) {
 7001                (None, None) => {
 7002                    let chunk_range = row_chunk.anchor_range();
 7003                    ranges_to_query
 7004                        .get_or_insert_with(Vec::new)
 7005                        .push((row_chunk, chunk_range));
 7006                }
 7007                (None, Some(fetched_hints)) => hint_fetch_tasks.push((row_chunk, fetched_hints)),
 7008                (Some(cached_hints), None) => {
 7009                    for (server_id, cached_hints) in cached_hints {
 7010                        if for_server.is_none_or(|for_server| for_server == server_id) {
 7011                            cached_inlay_hints
 7012                                .get_or_insert_with(HashMap::default)
 7013                                .entry(row_chunk.row_range())
 7014                                .or_insert_with(HashMap::default)
 7015                                .entry(server_id)
 7016                                .or_insert_with(Vec::new)
 7017                                .extend(cached_hints);
 7018                        }
 7019                    }
 7020                }
 7021                (Some(cached_hints), Some(fetched_hints)) => {
 7022                    hint_fetch_tasks.push((row_chunk, fetched_hints));
 7023                    for (server_id, cached_hints) in cached_hints {
 7024                        if for_server.is_none_or(|for_server| for_server == server_id) {
 7025                            cached_inlay_hints
 7026                                .get_or_insert_with(HashMap::default)
 7027                                .entry(row_chunk.row_range())
 7028                                .or_insert_with(HashMap::default)
 7029                                .entry(server_id)
 7030                                .or_insert_with(Vec::new)
 7031                                .extend(cached_hints);
 7032                        }
 7033                    }
 7034                }
 7035            }
 7036        }
 7037
 7038        if hint_fetch_tasks.is_empty()
 7039            && ranges_to_query
 7040                .as_ref()
 7041                .is_none_or(|ranges| ranges.is_empty())
 7042            && let Some(cached_inlay_hints) = cached_inlay_hints
 7043        {
 7044            cached_inlay_hints
 7045                .into_iter()
 7046                .map(|(row_chunk, hints)| (row_chunk, Task::ready(Ok(hints))))
 7047                .collect()
 7048        } else {
 7049            for (chunk, range_to_query) in ranges_to_query.into_iter().flatten() {
 7050                let next_hint_id = next_hint_id.clone();
 7051                let buffer = buffer.clone();
 7052                let query_version = query_version.clone();
 7053                let new_inlay_hints = cx
 7054                    .spawn(async move |lsp_store, cx| {
 7055                        let new_fetch_task = lsp_store.update(cx, |lsp_store, cx| {
 7056                            lsp_store.fetch_inlay_hints(for_server, &buffer, range_to_query, cx)
 7057                        })?;
 7058                        new_fetch_task
 7059                            .await
 7060                            .and_then(|new_hints_by_server| {
 7061                                lsp_store.update(cx, |lsp_store, cx| {
 7062                                    let lsp_data = lsp_store.latest_lsp_data(&buffer, cx);
 7063                                    let update_cache = lsp_data.buffer_version == query_version;
 7064                                    if new_hints_by_server.is_empty() {
 7065                                        if update_cache {
 7066                                            lsp_data.inlay_hints.invalidate_for_chunk(chunk);
 7067                                        }
 7068                                        HashMap::default()
 7069                                    } else {
 7070                                        new_hints_by_server
 7071                                            .into_iter()
 7072                                            .map(|(server_id, new_hints)| {
 7073                                                let new_hints = new_hints
 7074                                                    .into_iter()
 7075                                                    .map(|new_hint| {
 7076                                                        (
 7077                                                            InlayId::Hint(next_hint_id.fetch_add(
 7078                                                                1,
 7079                                                                atomic::Ordering::AcqRel,
 7080                                                            )),
 7081                                                            new_hint,
 7082                                                        )
 7083                                                    })
 7084                                                    .collect::<Vec<_>>();
 7085                                                if update_cache {
 7086                                                    lsp_data.inlay_hints.insert_new_hints(
 7087                                                        chunk,
 7088                                                        server_id,
 7089                                                        new_hints.clone(),
 7090                                                    );
 7091                                                }
 7092                                                (server_id, new_hints)
 7093                                            })
 7094                                            .collect()
 7095                                    }
 7096                                })
 7097                            })
 7098                            .map_err(Arc::new)
 7099                    })
 7100                    .shared();
 7101
 7102                let fetch_task = lsp_data.inlay_hints.fetched_hints(&chunk);
 7103                *fetch_task = Some(new_inlay_hints.clone());
 7104                hint_fetch_tasks.push((chunk, new_inlay_hints));
 7105            }
 7106
 7107            cached_inlay_hints
 7108                .unwrap_or_default()
 7109                .into_iter()
 7110                .map(|(row_chunk, hints)| (row_chunk, Task::ready(Ok(hints))))
 7111                .chain(hint_fetch_tasks.into_iter().map(|(chunk, hints_fetch)| {
 7112                    (
 7113                        chunk.row_range(),
 7114                        cx.spawn(async move |_, _| {
 7115                            hints_fetch.await.map_err(|e| {
 7116                                if e.error_code() != ErrorCode::Internal {
 7117                                    anyhow!(e.error_code())
 7118                                } else {
 7119                                    anyhow!("{e:#}")
 7120                                }
 7121                            })
 7122                        }),
 7123                    )
 7124                }))
 7125                .collect()
 7126        }
 7127    }
 7128
 7129    fn fetch_inlay_hints(
 7130        &mut self,
 7131        for_server: Option<LanguageServerId>,
 7132        buffer: &Entity<Buffer>,
 7133        range: Range<Anchor>,
 7134        cx: &mut Context<Self>,
 7135    ) -> Task<Result<HashMap<LanguageServerId, Vec<InlayHint>>>> {
 7136        let request = InlayHints {
 7137            range: range.clone(),
 7138        };
 7139        if let Some((upstream_client, project_id)) = self.upstream_client() {
 7140            if !self.is_capable_for_proto_request(buffer, &request, cx) {
 7141                return Task::ready(Ok(HashMap::default()));
 7142            }
 7143            let request_task = upstream_client.request_lsp(
 7144                project_id,
 7145                for_server.map(|id| id.to_proto()),
 7146                LSP_REQUEST_TIMEOUT,
 7147                cx.background_executor().clone(),
 7148                request.to_proto(project_id, buffer.read(cx)),
 7149            );
 7150            let buffer = buffer.clone();
 7151            cx.spawn(async move |weak_lsp_store, cx| {
 7152                let Some(lsp_store) = weak_lsp_store.upgrade() else {
 7153                    return Ok(HashMap::default());
 7154                };
 7155                let Some(responses) = request_task.await? else {
 7156                    return Ok(HashMap::default());
 7157                };
 7158
 7159                let inlay_hints = join_all(responses.payload.into_iter().map(|response| {
 7160                    let lsp_store = lsp_store.clone();
 7161                    let buffer = buffer.clone();
 7162                    let cx = cx.clone();
 7163                    let request = request.clone();
 7164                    async move {
 7165                        (
 7166                            LanguageServerId::from_proto(response.server_id),
 7167                            request
 7168                                .response_from_proto(response.response, lsp_store, buffer, cx)
 7169                                .await,
 7170                        )
 7171                    }
 7172                }))
 7173                .await;
 7174
 7175                let buffer_snapshot = buffer.read_with(cx, |buffer, _| buffer.snapshot())?;
 7176                let mut has_errors = false;
 7177                let inlay_hints = inlay_hints
 7178                    .into_iter()
 7179                    .filter_map(|(server_id, inlay_hints)| match inlay_hints {
 7180                        Ok(inlay_hints) => Some((server_id, inlay_hints)),
 7181                        Err(e) => {
 7182                            has_errors = true;
 7183                            log::error!("{e:#}");
 7184                            None
 7185                        }
 7186                    })
 7187                    .map(|(server_id, mut new_hints)| {
 7188                        new_hints.retain(|hint| {
 7189                            hint.position.is_valid(&buffer_snapshot)
 7190                                && range.start.is_valid(&buffer_snapshot)
 7191                                && range.end.is_valid(&buffer_snapshot)
 7192                                && hint.position.cmp(&range.start, &buffer_snapshot).is_ge()
 7193                                && hint.position.cmp(&range.end, &buffer_snapshot).is_lt()
 7194                        });
 7195                        (server_id, new_hints)
 7196                    })
 7197                    .collect::<HashMap<_, _>>();
 7198                anyhow::ensure!(
 7199                    !has_errors || !inlay_hints.is_empty(),
 7200                    "Failed to fetch inlay hints"
 7201                );
 7202                Ok(inlay_hints)
 7203            })
 7204        } else {
 7205            let inlay_hints_task = match for_server {
 7206                Some(server_id) => {
 7207                    let server_task = self.request_lsp(
 7208                        buffer.clone(),
 7209                        LanguageServerToQuery::Other(server_id),
 7210                        request,
 7211                        cx,
 7212                    );
 7213                    cx.background_spawn(async move {
 7214                        let mut responses = Vec::new();
 7215                        match server_task.await {
 7216                            Ok(response) => responses.push((server_id, response)),
 7217                            // rust-analyzer likes to error with this when its still loading up
 7218                            Err(e) if format!("{e:#}").ends_with("content modified") => (),
 7219                            Err(e) => log::error!(
 7220                                "Error handling response for inlay hints request: {e:#}"
 7221                            ),
 7222                        }
 7223                        responses
 7224                    })
 7225                }
 7226                None => self.request_multiple_lsp_locally(buffer, None::<usize>, request, cx),
 7227            };
 7228            let buffer_snapshot = buffer.read_with(cx, |buffer, _| buffer.snapshot());
 7229            cx.background_spawn(async move {
 7230                Ok(inlay_hints_task
 7231                    .await
 7232                    .into_iter()
 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())
 7244            })
 7245        }
 7246    }
 7247
 7248    fn diagnostic_registration_exists(
 7249        &self,
 7250        server_id: LanguageServerId,
 7251        registration_id: &Option<SharedString>,
 7252    ) -> bool {
 7253        let Some(local) = self.as_local() else {
 7254            return false;
 7255        };
 7256        let Some(registrations) = local.language_server_dynamic_registrations.get(&server_id)
 7257        else {
 7258            return false;
 7259        };
 7260        let registration_key = registration_id.as_ref().map(|s| s.to_string());
 7261        registrations.diagnostics.contains_key(&registration_key)
 7262    }
 7263
 7264    pub fn pull_diagnostics_for_buffer(
 7265        &mut self,
 7266        buffer: Entity<Buffer>,
 7267        cx: &mut Context<Self>,
 7268    ) -> Task<anyhow::Result<()>> {
 7269        let diagnostics = self.pull_diagnostics(buffer, cx);
 7270        cx.spawn(async move |lsp_store, cx| {
 7271            let Some(diagnostics) = diagnostics.await.context("pulling diagnostics")? else {
 7272                return Ok(());
 7273            };
 7274            lsp_store.update(cx, |lsp_store, cx| {
 7275                if lsp_store.as_local().is_none() {
 7276                    return;
 7277                }
 7278
 7279                let mut unchanged_buffers = HashMap::default();
 7280                let server_diagnostics_updates = diagnostics
 7281                    .into_iter()
 7282                    .filter_map(|diagnostics_set| match diagnostics_set {
 7283                        LspPullDiagnostics::Response {
 7284                            server_id,
 7285                            uri,
 7286                            diagnostics,
 7287                            registration_id,
 7288                        } => Some((server_id, uri, diagnostics, registration_id)),
 7289                        LspPullDiagnostics::Default => None,
 7290                    })
 7291                    .filter(|(server_id, _, _, registration_id)| {
 7292                        lsp_store.diagnostic_registration_exists(*server_id, registration_id)
 7293                    })
 7294                    .fold(
 7295                        HashMap::default(),
 7296                        |mut acc, (server_id, uri, diagnostics, new_registration_id)| {
 7297                            let (result_id, diagnostics) = match diagnostics {
 7298                                PulledDiagnostics::Unchanged { result_id } => {
 7299                                    unchanged_buffers
 7300                                        .entry(new_registration_id.clone())
 7301                                        .or_insert_with(HashSet::default)
 7302                                        .insert(uri.clone());
 7303                                    (Some(result_id), Vec::new())
 7304                                }
 7305                                PulledDiagnostics::Changed {
 7306                                    result_id,
 7307                                    diagnostics,
 7308                                } => (result_id, diagnostics),
 7309                            };
 7310                            let disk_based_sources = Cow::Owned(
 7311                                lsp_store
 7312                                    .language_server_adapter_for_id(server_id)
 7313                                    .as_ref()
 7314                                    .map(|adapter| adapter.disk_based_diagnostic_sources.as_slice())
 7315                                    .unwrap_or(&[])
 7316                                    .to_vec(),
 7317                            );
 7318                            acc.entry(server_id)
 7319                                .or_insert_with(HashMap::default)
 7320                                .entry(new_registration_id.clone())
 7321                                .or_insert_with(Vec::new)
 7322                                .push(DocumentDiagnosticsUpdate {
 7323                                    server_id,
 7324                                    diagnostics: lsp::PublishDiagnosticsParams {
 7325                                        uri,
 7326                                        diagnostics,
 7327                                        version: None,
 7328                                    },
 7329                                    result_id,
 7330                                    disk_based_sources,
 7331                                    registration_id: new_registration_id,
 7332                                });
 7333                            acc
 7334                        },
 7335                    );
 7336
 7337                for diagnostic_updates in server_diagnostics_updates.into_values() {
 7338                    for (registration_id, diagnostic_updates) in diagnostic_updates {
 7339                        lsp_store
 7340                            .merge_lsp_diagnostics(
 7341                                DiagnosticSourceKind::Pulled,
 7342                                diagnostic_updates,
 7343                                |document_uri, old_diagnostic, _| match old_diagnostic.source_kind {
 7344                                    DiagnosticSourceKind::Pulled => {
 7345                                        old_diagnostic.registration_id != registration_id
 7346                                            || unchanged_buffers
 7347                                                .get(&old_diagnostic.registration_id)
 7348                                                .is_some_and(|unchanged_buffers| {
 7349                                                    unchanged_buffers.contains(&document_uri)
 7350                                                })
 7351                                    }
 7352                                    DiagnosticSourceKind::Other | DiagnosticSourceKind::Pushed => {
 7353                                        true
 7354                                    }
 7355                                },
 7356                                cx,
 7357                            )
 7358                            .log_err();
 7359                    }
 7360                }
 7361            })
 7362        })
 7363    }
 7364
 7365    pub fn document_colors(
 7366        &mut self,
 7367        known_cache_version: Option<usize>,
 7368        buffer: Entity<Buffer>,
 7369        cx: &mut Context<Self>,
 7370    ) -> Option<DocumentColorTask> {
 7371        let version_queried_for = buffer.read(cx).version();
 7372        let buffer_id = buffer.read(cx).remote_id();
 7373
 7374        let current_language_servers = self.as_local().map(|local| {
 7375            local
 7376                .buffers_opened_in_servers
 7377                .get(&buffer_id)
 7378                .cloned()
 7379                .unwrap_or_default()
 7380        });
 7381
 7382        if let Some(lsp_data) = self.current_lsp_data(buffer_id) {
 7383            if let Some(cached_colors) = &lsp_data.document_colors {
 7384                if !version_queried_for.changed_since(&lsp_data.buffer_version) {
 7385                    let has_different_servers =
 7386                        current_language_servers.is_some_and(|current_language_servers| {
 7387                            current_language_servers
 7388                                != cached_colors.colors.keys().copied().collect()
 7389                        });
 7390                    if !has_different_servers {
 7391                        let cache_version = cached_colors.cache_version;
 7392                        if Some(cache_version) == known_cache_version {
 7393                            return None;
 7394                        } else {
 7395                            return Some(
 7396                                Task::ready(Ok(DocumentColors {
 7397                                    colors: cached_colors
 7398                                        .colors
 7399                                        .values()
 7400                                        .flatten()
 7401                                        .cloned()
 7402                                        .collect(),
 7403                                    cache_version: Some(cache_version),
 7404                                }))
 7405                                .shared(),
 7406                            );
 7407                        }
 7408                    }
 7409                }
 7410            }
 7411        }
 7412
 7413        let color_lsp_data = self
 7414            .latest_lsp_data(&buffer, cx)
 7415            .document_colors
 7416            .get_or_insert_default();
 7417        if let Some((updating_for, running_update)) = &color_lsp_data.colors_update
 7418            && !version_queried_for.changed_since(updating_for)
 7419        {
 7420            return Some(running_update.clone());
 7421        }
 7422        let buffer_version_queried_for = version_queried_for.clone();
 7423        let new_task = cx
 7424            .spawn(async move |lsp_store, cx| {
 7425                cx.background_executor()
 7426                    .timer(Duration::from_millis(30))
 7427                    .await;
 7428                let fetched_colors = lsp_store
 7429                    .update(cx, |lsp_store, cx| {
 7430                        lsp_store.fetch_document_colors_for_buffer(&buffer, cx)
 7431                    })?
 7432                    .await
 7433                    .context("fetching document colors")
 7434                    .map_err(Arc::new);
 7435                let fetched_colors = match fetched_colors {
 7436                    Ok(fetched_colors) => {
 7437                        if Some(true)
 7438                            == buffer
 7439                                .update(cx, |buffer, _| {
 7440                                    buffer.version() != buffer_version_queried_for
 7441                                })
 7442                                .ok()
 7443                        {
 7444                            return Ok(DocumentColors::default());
 7445                        }
 7446                        fetched_colors
 7447                    }
 7448                    Err(e) => {
 7449                        lsp_store
 7450                            .update(cx, |lsp_store, _| {
 7451                                if let Some(lsp_data) = lsp_store.lsp_data.get_mut(&buffer_id) {
 7452                                    if let Some(document_colors) = &mut lsp_data.document_colors {
 7453                                        document_colors.colors_update = None;
 7454                                    }
 7455                                }
 7456                            })
 7457                            .ok();
 7458                        return Err(e);
 7459                    }
 7460                };
 7461
 7462                lsp_store
 7463                    .update(cx, |lsp_store, cx| {
 7464                        let lsp_data = lsp_store.latest_lsp_data(&buffer, cx);
 7465                        let lsp_colors = lsp_data.document_colors.get_or_insert_default();
 7466
 7467                        if let Some(fetched_colors) = fetched_colors {
 7468                            if lsp_data.buffer_version == buffer_version_queried_for {
 7469                                lsp_colors.colors.extend(fetched_colors);
 7470                                lsp_colors.cache_version += 1;
 7471                            } else if !lsp_data
 7472                                .buffer_version
 7473                                .changed_since(&buffer_version_queried_for)
 7474                            {
 7475                                lsp_data.buffer_version = buffer_version_queried_for;
 7476                                lsp_colors.colors = fetched_colors;
 7477                                lsp_colors.cache_version += 1;
 7478                            }
 7479                        }
 7480                        lsp_colors.colors_update = None;
 7481                        let colors = lsp_colors
 7482                            .colors
 7483                            .values()
 7484                            .flatten()
 7485                            .cloned()
 7486                            .collect::<HashSet<_>>();
 7487                        DocumentColors {
 7488                            colors,
 7489                            cache_version: Some(lsp_colors.cache_version),
 7490                        }
 7491                    })
 7492                    .map_err(Arc::new)
 7493            })
 7494            .shared();
 7495        color_lsp_data.colors_update = Some((version_queried_for, new_task.clone()));
 7496        Some(new_task)
 7497    }
 7498
 7499    fn fetch_document_colors_for_buffer(
 7500        &mut self,
 7501        buffer: &Entity<Buffer>,
 7502        cx: &mut Context<Self>,
 7503    ) -> Task<anyhow::Result<Option<HashMap<LanguageServerId, HashSet<DocumentColor>>>>> {
 7504        if let Some((client, project_id)) = self.upstream_client() {
 7505            let request = GetDocumentColor {};
 7506            if !self.is_capable_for_proto_request(buffer, &request, cx) {
 7507                return Task::ready(Ok(None));
 7508            }
 7509
 7510            let request_task = client.request_lsp(
 7511                project_id,
 7512                None,
 7513                LSP_REQUEST_TIMEOUT,
 7514                cx.background_executor().clone(),
 7515                request.to_proto(project_id, buffer.read(cx)),
 7516            );
 7517            let buffer = buffer.clone();
 7518            cx.spawn(async move |lsp_store, cx| {
 7519                let Some(lsp_store) = lsp_store.upgrade() else {
 7520                    return Ok(None);
 7521                };
 7522                let colors = join_all(
 7523                    request_task
 7524                        .await
 7525                        .log_err()
 7526                        .flatten()
 7527                        .map(|response| response.payload)
 7528                        .unwrap_or_default()
 7529                        .into_iter()
 7530                        .map(|color_response| {
 7531                            let response = request.response_from_proto(
 7532                                color_response.response,
 7533                                lsp_store.clone(),
 7534                                buffer.clone(),
 7535                                cx.clone(),
 7536                            );
 7537                            async move {
 7538                                (
 7539                                    LanguageServerId::from_proto(color_response.server_id),
 7540                                    response.await.log_err().unwrap_or_default(),
 7541                                )
 7542                            }
 7543                        }),
 7544                )
 7545                .await
 7546                .into_iter()
 7547                .fold(HashMap::default(), |mut acc, (server_id, colors)| {
 7548                    acc.entry(server_id)
 7549                        .or_insert_with(HashSet::default)
 7550                        .extend(colors);
 7551                    acc
 7552                });
 7553                Ok(Some(colors))
 7554            })
 7555        } else {
 7556            let document_colors_task =
 7557                self.request_multiple_lsp_locally(buffer, None::<usize>, GetDocumentColor, cx);
 7558            cx.background_spawn(async move {
 7559                Ok(Some(
 7560                    document_colors_task
 7561                        .await
 7562                        .into_iter()
 7563                        .fold(HashMap::default(), |mut acc, (server_id, colors)| {
 7564                            acc.entry(server_id)
 7565                                .or_insert_with(HashSet::default)
 7566                                .extend(colors);
 7567                            acc
 7568                        })
 7569                        .into_iter()
 7570                        .collect(),
 7571                ))
 7572            })
 7573        }
 7574    }
 7575
 7576    pub fn signature_help<T: ToPointUtf16>(
 7577        &mut self,
 7578        buffer: &Entity<Buffer>,
 7579        position: T,
 7580        cx: &mut Context<Self>,
 7581    ) -> Task<Option<Vec<SignatureHelp>>> {
 7582        let position = position.to_point_utf16(buffer.read(cx));
 7583
 7584        if let Some((client, upstream_project_id)) = self.upstream_client() {
 7585            let request = GetSignatureHelp { position };
 7586            if !self.is_capable_for_proto_request(buffer, &request, cx) {
 7587                return Task::ready(None);
 7588            }
 7589            let request_task = client.request_lsp(
 7590                upstream_project_id,
 7591                None,
 7592                LSP_REQUEST_TIMEOUT,
 7593                cx.background_executor().clone(),
 7594                request.to_proto(upstream_project_id, buffer.read(cx)),
 7595            );
 7596            let buffer = buffer.clone();
 7597            cx.spawn(async move |weak_lsp_store, cx| {
 7598                let lsp_store = weak_lsp_store.upgrade()?;
 7599                let signatures = join_all(
 7600                    request_task
 7601                        .await
 7602                        .log_err()
 7603                        .flatten()
 7604                        .map(|response| response.payload)
 7605                        .unwrap_or_default()
 7606                        .into_iter()
 7607                        .map(|response| {
 7608                            let response = GetSignatureHelp { position }.response_from_proto(
 7609                                response.response,
 7610                                lsp_store.clone(),
 7611                                buffer.clone(),
 7612                                cx.clone(),
 7613                            );
 7614                            async move { response.await.log_err().flatten() }
 7615                        }),
 7616                )
 7617                .await
 7618                .into_iter()
 7619                .flatten()
 7620                .collect();
 7621                Some(signatures)
 7622            })
 7623        } else {
 7624            let all_actions_task = self.request_multiple_lsp_locally(
 7625                buffer,
 7626                Some(position),
 7627                GetSignatureHelp { position },
 7628                cx,
 7629            );
 7630            cx.background_spawn(async move {
 7631                Some(
 7632                    all_actions_task
 7633                        .await
 7634                        .into_iter()
 7635                        .flat_map(|(_, actions)| actions)
 7636                        .collect::<Vec<_>>(),
 7637                )
 7638            })
 7639        }
 7640    }
 7641
 7642    pub fn hover(
 7643        &mut self,
 7644        buffer: &Entity<Buffer>,
 7645        position: PointUtf16,
 7646        cx: &mut Context<Self>,
 7647    ) -> Task<Option<Vec<Hover>>> {
 7648        if let Some((client, upstream_project_id)) = self.upstream_client() {
 7649            let request = GetHover { position };
 7650            if !self.is_capable_for_proto_request(buffer, &request, cx) {
 7651                return Task::ready(None);
 7652            }
 7653            let request_task = client.request_lsp(
 7654                upstream_project_id,
 7655                None,
 7656                LSP_REQUEST_TIMEOUT,
 7657                cx.background_executor().clone(),
 7658                request.to_proto(upstream_project_id, buffer.read(cx)),
 7659            );
 7660            let buffer = buffer.clone();
 7661            cx.spawn(async move |weak_lsp_store, cx| {
 7662                let lsp_store = weak_lsp_store.upgrade()?;
 7663                let hovers = join_all(
 7664                    request_task
 7665                        .await
 7666                        .log_err()
 7667                        .flatten()
 7668                        .map(|response| response.payload)
 7669                        .unwrap_or_default()
 7670                        .into_iter()
 7671                        .map(|response| {
 7672                            let response = GetHover { position }.response_from_proto(
 7673                                response.response,
 7674                                lsp_store.clone(),
 7675                                buffer.clone(),
 7676                                cx.clone(),
 7677                            );
 7678                            async move {
 7679                                response
 7680                                    .await
 7681                                    .log_err()
 7682                                    .flatten()
 7683                                    .and_then(remove_empty_hover_blocks)
 7684                            }
 7685                        }),
 7686                )
 7687                .await
 7688                .into_iter()
 7689                .flatten()
 7690                .collect();
 7691                Some(hovers)
 7692            })
 7693        } else {
 7694            let all_actions_task = self.request_multiple_lsp_locally(
 7695                buffer,
 7696                Some(position),
 7697                GetHover { position },
 7698                cx,
 7699            );
 7700            cx.background_spawn(async move {
 7701                Some(
 7702                    all_actions_task
 7703                        .await
 7704                        .into_iter()
 7705                        .filter_map(|(_, hover)| remove_empty_hover_blocks(hover?))
 7706                        .collect::<Vec<Hover>>(),
 7707                )
 7708            })
 7709        }
 7710    }
 7711
 7712    pub fn symbols(&self, query: &str, cx: &mut Context<Self>) -> Task<Result<Vec<Symbol>>> {
 7713        let language_registry = self.languages.clone();
 7714
 7715        if let Some((upstream_client, project_id)) = self.upstream_client().as_ref() {
 7716            let request = upstream_client.request(proto::GetProjectSymbols {
 7717                project_id: *project_id,
 7718                query: query.to_string(),
 7719            });
 7720            cx.foreground_executor().spawn(async move {
 7721                let response = request.await?;
 7722                let mut symbols = Vec::new();
 7723                let core_symbols = response
 7724                    .symbols
 7725                    .into_iter()
 7726                    .filter_map(|symbol| Self::deserialize_symbol(symbol).log_err())
 7727                    .collect::<Vec<_>>();
 7728                populate_labels_for_symbols(core_symbols, &language_registry, None, &mut symbols)
 7729                    .await;
 7730                Ok(symbols)
 7731            })
 7732        } else if let Some(local) = self.as_local() {
 7733            struct WorkspaceSymbolsResult {
 7734                server_id: LanguageServerId,
 7735                lsp_adapter: Arc<CachedLspAdapter>,
 7736                worktree: WeakEntity<Worktree>,
 7737                lsp_symbols: Vec<(String, SymbolKind, lsp::Location)>,
 7738            }
 7739
 7740            let mut requests = Vec::new();
 7741            let mut requested_servers = BTreeSet::new();
 7742            for (seed, state) in local.language_server_ids.iter() {
 7743                let Some(worktree_handle) = self
 7744                    .worktree_store
 7745                    .read(cx)
 7746                    .worktree_for_id(seed.worktree_id, cx)
 7747                else {
 7748                    continue;
 7749                };
 7750                let worktree = worktree_handle.read(cx);
 7751                if !worktree.is_visible() {
 7752                    continue;
 7753                }
 7754
 7755                if !requested_servers.insert(state.id) {
 7756                    continue;
 7757                }
 7758
 7759                let (lsp_adapter, server) = match local.language_servers.get(&state.id) {
 7760                    Some(LanguageServerState::Running {
 7761                        adapter, server, ..
 7762                    }) => (adapter.clone(), server),
 7763
 7764                    _ => continue,
 7765                };
 7766                let supports_workspace_symbol_request =
 7767                    match server.capabilities().workspace_symbol_provider {
 7768                        Some(OneOf::Left(supported)) => supported,
 7769                        Some(OneOf::Right(_)) => true,
 7770                        None => false,
 7771                    };
 7772                if !supports_workspace_symbol_request {
 7773                    continue;
 7774                }
 7775                let worktree_handle = worktree_handle.clone();
 7776                let server_id = server.server_id();
 7777                requests.push(
 7778                        server
 7779                            .request::<lsp::request::WorkspaceSymbolRequest>(
 7780                                lsp::WorkspaceSymbolParams {
 7781                                    query: query.to_string(),
 7782                                    ..Default::default()
 7783                                },
 7784                            )
 7785                            .map(move |response| {
 7786                                let lsp_symbols = response.into_response()
 7787                                    .context("workspace symbols request")
 7788                                    .log_err()
 7789                                    .flatten()
 7790                                    .map(|symbol_response| match symbol_response {
 7791                                        lsp::WorkspaceSymbolResponse::Flat(flat_responses) => {
 7792                                            flat_responses.into_iter().map(|lsp_symbol| {
 7793                                            (lsp_symbol.name, lsp_symbol.kind, lsp_symbol.location)
 7794                                            }).collect::<Vec<_>>()
 7795                                        }
 7796                                        lsp::WorkspaceSymbolResponse::Nested(nested_responses) => {
 7797                                            nested_responses.into_iter().filter_map(|lsp_symbol| {
 7798                                                let location = match lsp_symbol.location {
 7799                                                    OneOf::Left(location) => location,
 7800                                                    OneOf::Right(_) => {
 7801                                                        log::error!("Unexpected: client capabilities forbid symbol resolutions in workspace.symbol.resolveSupport");
 7802                                                        return None
 7803                                                    }
 7804                                                };
 7805                                                Some((lsp_symbol.name, lsp_symbol.kind, location))
 7806                                            }).collect::<Vec<_>>()
 7807                                        }
 7808                                    }).unwrap_or_default();
 7809
 7810                                WorkspaceSymbolsResult {
 7811                                    server_id,
 7812                                    lsp_adapter,
 7813                                    worktree: worktree_handle.downgrade(),
 7814                                    lsp_symbols,
 7815                                }
 7816                            }),
 7817                    );
 7818            }
 7819
 7820            cx.spawn(async move |this, cx| {
 7821                let responses = futures::future::join_all(requests).await;
 7822                let this = match this.upgrade() {
 7823                    Some(this) => this,
 7824                    None => return Ok(Vec::new()),
 7825                };
 7826
 7827                let mut symbols = Vec::new();
 7828                for result in responses {
 7829                    let core_symbols = this.update(cx, |this, cx| {
 7830                        result
 7831                            .lsp_symbols
 7832                            .into_iter()
 7833                            .filter_map(|(symbol_name, symbol_kind, symbol_location)| {
 7834                                let abs_path = symbol_location.uri.to_file_path().ok()?;
 7835                                let source_worktree = result.worktree.upgrade()?;
 7836                                let source_worktree_id = source_worktree.read(cx).id();
 7837
 7838                                let path = if let Some((tree, rel_path)) =
 7839                                    this.worktree_store.read(cx).find_worktree(&abs_path, cx)
 7840                                {
 7841                                    let worktree_id = tree.read(cx).id();
 7842                                    SymbolLocation::InProject(ProjectPath {
 7843                                        worktree_id,
 7844                                        path: rel_path,
 7845                                    })
 7846                                } else {
 7847                                    SymbolLocation::OutsideProject {
 7848                                        signature: this.symbol_signature(&abs_path),
 7849                                        abs_path: abs_path.into(),
 7850                                    }
 7851                                };
 7852
 7853                                Some(CoreSymbol {
 7854                                    source_language_server_id: result.server_id,
 7855                                    language_server_name: result.lsp_adapter.name.clone(),
 7856                                    source_worktree_id,
 7857                                    path,
 7858                                    kind: symbol_kind,
 7859                                    name: symbol_name,
 7860                                    range: range_from_lsp(symbol_location.range),
 7861                                })
 7862                            })
 7863                            .collect()
 7864                    })?;
 7865
 7866                    populate_labels_for_symbols(
 7867                        core_symbols,
 7868                        &language_registry,
 7869                        Some(result.lsp_adapter),
 7870                        &mut symbols,
 7871                    )
 7872                    .await;
 7873                }
 7874
 7875                Ok(symbols)
 7876            })
 7877        } else {
 7878            Task::ready(Err(anyhow!("No upstream client or local language server")))
 7879        }
 7880    }
 7881
 7882    pub fn diagnostic_summary(&self, include_ignored: bool, cx: &App) -> DiagnosticSummary {
 7883        let mut summary = DiagnosticSummary::default();
 7884        for (_, _, path_summary) in self.diagnostic_summaries(include_ignored, cx) {
 7885            summary.error_count += path_summary.error_count;
 7886            summary.warning_count += path_summary.warning_count;
 7887        }
 7888        summary
 7889    }
 7890
 7891    /// Returns the diagnostic summary for a specific project path.
 7892    pub fn diagnostic_summary_for_path(
 7893        &self,
 7894        project_path: &ProjectPath,
 7895        _: &App,
 7896    ) -> DiagnosticSummary {
 7897        if let Some(summaries) = self
 7898            .diagnostic_summaries
 7899            .get(&project_path.worktree_id)
 7900            .and_then(|map| map.get(&project_path.path))
 7901        {
 7902            let (error_count, warning_count) = summaries.iter().fold(
 7903                (0, 0),
 7904                |(error_count, warning_count), (_language_server_id, summary)| {
 7905                    (
 7906                        error_count + summary.error_count,
 7907                        warning_count + summary.warning_count,
 7908                    )
 7909                },
 7910            );
 7911
 7912            DiagnosticSummary {
 7913                error_count,
 7914                warning_count,
 7915            }
 7916        } else {
 7917            DiagnosticSummary::default()
 7918        }
 7919    }
 7920
 7921    pub fn diagnostic_summaries<'a>(
 7922        &'a self,
 7923        include_ignored: bool,
 7924        cx: &'a App,
 7925    ) -> impl Iterator<Item = (ProjectPath, LanguageServerId, DiagnosticSummary)> + 'a {
 7926        self.worktree_store
 7927            .read(cx)
 7928            .visible_worktrees(cx)
 7929            .filter_map(|worktree| {
 7930                let worktree = worktree.read(cx);
 7931                Some((worktree, self.diagnostic_summaries.get(&worktree.id())?))
 7932            })
 7933            .flat_map(move |(worktree, summaries)| {
 7934                let worktree_id = worktree.id();
 7935                summaries
 7936                    .iter()
 7937                    .filter(move |(path, _)| {
 7938                        include_ignored
 7939                            || worktree
 7940                                .entry_for_path(path.as_ref())
 7941                                .is_some_and(|entry| !entry.is_ignored)
 7942                    })
 7943                    .flat_map(move |(path, summaries)| {
 7944                        summaries.iter().map(move |(server_id, summary)| {
 7945                            (
 7946                                ProjectPath {
 7947                                    worktree_id,
 7948                                    path: path.clone(),
 7949                                },
 7950                                *server_id,
 7951                                *summary,
 7952                            )
 7953                        })
 7954                    })
 7955            })
 7956    }
 7957
 7958    pub fn on_buffer_edited(
 7959        &mut self,
 7960        buffer: Entity<Buffer>,
 7961        cx: &mut Context<Self>,
 7962    ) -> Option<()> {
 7963        let language_servers: Vec<_> = buffer.update(cx, |buffer, cx| {
 7964            Some(
 7965                self.as_local()?
 7966                    .language_servers_for_buffer(buffer, cx)
 7967                    .map(|i| i.1.clone())
 7968                    .collect(),
 7969            )
 7970        })?;
 7971
 7972        let buffer = buffer.read(cx);
 7973        let file = File::from_dyn(buffer.file())?;
 7974        let abs_path = file.as_local()?.abs_path(cx);
 7975        let uri = lsp::Uri::from_file_path(&abs_path)
 7976            .ok()
 7977            .with_context(|| format!("Failed to convert path to URI: {}", abs_path.display()))
 7978            .log_err()?;
 7979        let next_snapshot = buffer.text_snapshot();
 7980        for language_server in language_servers {
 7981            let language_server = language_server.clone();
 7982
 7983            let buffer_snapshots = self
 7984                .as_local_mut()?
 7985                .buffer_snapshots
 7986                .get_mut(&buffer.remote_id())
 7987                .and_then(|m| m.get_mut(&language_server.server_id()))?;
 7988            let previous_snapshot = buffer_snapshots.last()?;
 7989
 7990            let build_incremental_change = || {
 7991                buffer
 7992                    .edits_since::<Dimensions<PointUtf16, usize>>(
 7993                        previous_snapshot.snapshot.version(),
 7994                    )
 7995                    .map(|edit| {
 7996                        let edit_start = edit.new.start.0;
 7997                        let edit_end = edit_start + (edit.old.end.0 - edit.old.start.0);
 7998                        let new_text = next_snapshot
 7999                            .text_for_range(edit.new.start.1..edit.new.end.1)
 8000                            .collect();
 8001                        lsp::TextDocumentContentChangeEvent {
 8002                            range: Some(lsp::Range::new(
 8003                                point_to_lsp(edit_start),
 8004                                point_to_lsp(edit_end),
 8005                            )),
 8006                            range_length: None,
 8007                            text: new_text,
 8008                        }
 8009                    })
 8010                    .collect()
 8011            };
 8012
 8013            let document_sync_kind = language_server
 8014                .capabilities()
 8015                .text_document_sync
 8016                .as_ref()
 8017                .and_then(|sync| match sync {
 8018                    lsp::TextDocumentSyncCapability::Kind(kind) => Some(*kind),
 8019                    lsp::TextDocumentSyncCapability::Options(options) => options.change,
 8020                });
 8021
 8022            let content_changes: Vec<_> = match document_sync_kind {
 8023                Some(lsp::TextDocumentSyncKind::FULL) => {
 8024                    vec![lsp::TextDocumentContentChangeEvent {
 8025                        range: None,
 8026                        range_length: None,
 8027                        text: next_snapshot.text(),
 8028                    }]
 8029                }
 8030                Some(lsp::TextDocumentSyncKind::INCREMENTAL) => build_incremental_change(),
 8031                _ => {
 8032                    #[cfg(any(test, feature = "test-support"))]
 8033                    {
 8034                        build_incremental_change()
 8035                    }
 8036
 8037                    #[cfg(not(any(test, feature = "test-support")))]
 8038                    {
 8039                        continue;
 8040                    }
 8041                }
 8042            };
 8043
 8044            let next_version = previous_snapshot.version + 1;
 8045            buffer_snapshots.push(LspBufferSnapshot {
 8046                version: next_version,
 8047                snapshot: next_snapshot.clone(),
 8048            });
 8049
 8050            language_server
 8051                .notify::<lsp::notification::DidChangeTextDocument>(
 8052                    lsp::DidChangeTextDocumentParams {
 8053                        text_document: lsp::VersionedTextDocumentIdentifier::new(
 8054                            uri.clone(),
 8055                            next_version,
 8056                        ),
 8057                        content_changes,
 8058                    },
 8059                )
 8060                .ok();
 8061            self.pull_workspace_diagnostics(language_server.server_id());
 8062        }
 8063
 8064        None
 8065    }
 8066
 8067    pub fn on_buffer_saved(
 8068        &mut self,
 8069        buffer: Entity<Buffer>,
 8070        cx: &mut Context<Self>,
 8071    ) -> Option<()> {
 8072        let file = File::from_dyn(buffer.read(cx).file())?;
 8073        let worktree_id = file.worktree_id(cx);
 8074        let abs_path = file.as_local()?.abs_path(cx);
 8075        let text_document = lsp::TextDocumentIdentifier {
 8076            uri: file_path_to_lsp_url(&abs_path).log_err()?,
 8077        };
 8078        let local = self.as_local()?;
 8079
 8080        for server in local.language_servers_for_worktree(worktree_id) {
 8081            if let Some(include_text) = include_text(server.as_ref()) {
 8082                let text = if include_text {
 8083                    Some(buffer.read(cx).text())
 8084                } else {
 8085                    None
 8086                };
 8087                server
 8088                    .notify::<lsp::notification::DidSaveTextDocument>(
 8089                        lsp::DidSaveTextDocumentParams {
 8090                            text_document: text_document.clone(),
 8091                            text,
 8092                        },
 8093                    )
 8094                    .ok();
 8095            }
 8096        }
 8097
 8098        let language_servers = buffer.update(cx, |buffer, cx| {
 8099            local.language_server_ids_for_buffer(buffer, cx)
 8100        });
 8101        for language_server_id in language_servers {
 8102            self.simulate_disk_based_diagnostics_events_if_needed(language_server_id, cx);
 8103        }
 8104
 8105        None
 8106    }
 8107
 8108    async fn refresh_workspace_configurations(lsp_store: &WeakEntity<Self>, cx: &mut AsyncApp) {
 8109        maybe!(async move {
 8110            let mut refreshed_servers = HashSet::default();
 8111            let servers = lsp_store
 8112                .update(cx, |lsp_store, cx| {
 8113                    let local = lsp_store.as_local()?;
 8114
 8115                    let servers = local
 8116                        .language_server_ids
 8117                        .iter()
 8118                        .filter_map(|(seed, state)| {
 8119                            let worktree = lsp_store
 8120                                .worktree_store
 8121                                .read(cx)
 8122                                .worktree_for_id(seed.worktree_id, cx);
 8123                            let delegate: Arc<dyn LspAdapterDelegate> =
 8124                                worktree.map(|worktree| {
 8125                                    LocalLspAdapterDelegate::new(
 8126                                        local.languages.clone(),
 8127                                        &local.environment,
 8128                                        cx.weak_entity(),
 8129                                        &worktree,
 8130                                        local.http_client.clone(),
 8131                                        local.fs.clone(),
 8132                                        cx,
 8133                                    )
 8134                                })?;
 8135                            let server_id = state.id;
 8136
 8137                            let states = local.language_servers.get(&server_id)?;
 8138
 8139                            match states {
 8140                                LanguageServerState::Starting { .. } => None,
 8141                                LanguageServerState::Running {
 8142                                    adapter, server, ..
 8143                                } => {
 8144                                    let adapter = adapter.clone();
 8145                                    let server = server.clone();
 8146                                    refreshed_servers.insert(server.name());
 8147                                    let toolchain = seed.toolchain.clone();
 8148                                    Some(cx.spawn(async move |_, cx| {
 8149                                        let settings =
 8150                                            LocalLspStore::workspace_configuration_for_adapter(
 8151                                                adapter.adapter.clone(),
 8152                                                &delegate,
 8153                                                toolchain,
 8154                                                None,
 8155                                                cx,
 8156                                            )
 8157                                            .await
 8158                                            .ok()?;
 8159                                        server
 8160                                            .notify::<lsp::notification::DidChangeConfiguration>(
 8161                                                lsp::DidChangeConfigurationParams { settings },
 8162                                            )
 8163                                            .ok()?;
 8164                                        Some(())
 8165                                    }))
 8166                                }
 8167                            }
 8168                        })
 8169                        .collect::<Vec<_>>();
 8170
 8171                    Some(servers)
 8172                })
 8173                .ok()
 8174                .flatten()?;
 8175
 8176            log::debug!("Refreshing workspace configurations for servers {refreshed_servers:?}");
 8177            // TODO this asynchronous job runs concurrently with extension (de)registration and may take enough time for a certain extension
 8178            // to stop and unregister its language server wrapper.
 8179            // This is racy : an extension might have already removed all `local.language_servers` state, but here we `.clone()` and hold onto it anyway.
 8180            // This now causes errors in the logs, we should find a way to remove such servers from the processing everywhere.
 8181            let _: Vec<Option<()>> = join_all(servers).await;
 8182
 8183            Some(())
 8184        })
 8185        .await;
 8186    }
 8187
 8188    fn maintain_workspace_config(
 8189        external_refresh_requests: watch::Receiver<()>,
 8190        cx: &mut Context<Self>,
 8191    ) -> Task<Result<()>> {
 8192        let (mut settings_changed_tx, mut settings_changed_rx) = watch::channel();
 8193        let _ = postage::stream::Stream::try_recv(&mut settings_changed_rx);
 8194
 8195        let settings_observation = cx.observe_global::<SettingsStore>(move |_, _| {
 8196            *settings_changed_tx.borrow_mut() = ();
 8197        });
 8198
 8199        let mut joint_future =
 8200            futures::stream::select(settings_changed_rx, external_refresh_requests);
 8201        // Multiple things can happen when a workspace environment (selected toolchain + settings) change:
 8202        // - 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).
 8203        // - 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.
 8204        // - In the same vein, we might also decide to start a new language server if the workspace configuration *diverges* from the other.
 8205        // - 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,
 8206        // but it is still different to what we had before, we're gonna send out a workspace configuration update.
 8207        cx.spawn(async move |this, cx| {
 8208            while let Some(()) = joint_future.next().await {
 8209                this.update(cx, |this, cx| {
 8210                    this.refresh_server_tree(cx);
 8211                })
 8212                .ok();
 8213
 8214                Self::refresh_workspace_configurations(&this, cx).await;
 8215            }
 8216
 8217            drop(settings_observation);
 8218            anyhow::Ok(())
 8219        })
 8220    }
 8221
 8222    pub fn running_language_servers_for_local_buffer<'a>(
 8223        &'a self,
 8224        buffer: &Buffer,
 8225        cx: &mut App,
 8226    ) -> impl Iterator<Item = (&'a Arc<CachedLspAdapter>, &'a Arc<LanguageServer>)> {
 8227        let local = self.as_local();
 8228        let language_server_ids = local
 8229            .map(|local| local.language_server_ids_for_buffer(buffer, cx))
 8230            .unwrap_or_default();
 8231
 8232        language_server_ids
 8233            .into_iter()
 8234            .filter_map(
 8235                move |server_id| match local?.language_servers.get(&server_id)? {
 8236                    LanguageServerState::Running {
 8237                        adapter, server, ..
 8238                    } => Some((adapter, server)),
 8239                    _ => None,
 8240                },
 8241            )
 8242    }
 8243
 8244    pub fn language_servers_for_local_buffer(
 8245        &self,
 8246        buffer: &Buffer,
 8247        cx: &mut App,
 8248    ) -> Vec<LanguageServerId> {
 8249        let local = self.as_local();
 8250        local
 8251            .map(|local| local.language_server_ids_for_buffer(buffer, cx))
 8252            .unwrap_or_default()
 8253    }
 8254
 8255    pub fn language_server_for_local_buffer<'a>(
 8256        &'a self,
 8257        buffer: &'a Buffer,
 8258        server_id: LanguageServerId,
 8259        cx: &'a mut App,
 8260    ) -> Option<(&'a Arc<CachedLspAdapter>, &'a Arc<LanguageServer>)> {
 8261        self.as_local()?
 8262            .language_servers_for_buffer(buffer, cx)
 8263            .find(|(_, s)| s.server_id() == server_id)
 8264    }
 8265
 8266    fn remove_worktree(&mut self, id_to_remove: WorktreeId, cx: &mut Context<Self>) {
 8267        self.diagnostic_summaries.remove(&id_to_remove);
 8268        if let Some(local) = self.as_local_mut() {
 8269            let to_remove = local.remove_worktree(id_to_remove, cx);
 8270            for server in to_remove {
 8271                self.language_server_statuses.remove(&server);
 8272            }
 8273        }
 8274    }
 8275
 8276    pub fn shared(
 8277        &mut self,
 8278        project_id: u64,
 8279        downstream_client: AnyProtoClient,
 8280        _: &mut Context<Self>,
 8281    ) {
 8282        self.downstream_client = Some((downstream_client.clone(), project_id));
 8283
 8284        for (server_id, status) in &self.language_server_statuses {
 8285            if let Some(server) = self.language_server_for_id(*server_id) {
 8286                downstream_client
 8287                    .send(proto::StartLanguageServer {
 8288                        project_id,
 8289                        server: Some(proto::LanguageServer {
 8290                            id: server_id.to_proto(),
 8291                            name: status.name.to_string(),
 8292                            worktree_id: status.worktree.map(|id| id.to_proto()),
 8293                        }),
 8294                        capabilities: serde_json::to_string(&server.capabilities())
 8295                            .expect("serializing server LSP capabilities"),
 8296                    })
 8297                    .log_err();
 8298            }
 8299        }
 8300    }
 8301
 8302    pub fn disconnected_from_host(&mut self) {
 8303        self.downstream_client.take();
 8304    }
 8305
 8306    pub fn disconnected_from_ssh_remote(&mut self) {
 8307        if let LspStoreMode::Remote(RemoteLspStore {
 8308            upstream_client, ..
 8309        }) = &mut self.mode
 8310        {
 8311            upstream_client.take();
 8312        }
 8313    }
 8314
 8315    pub(crate) fn set_language_server_statuses_from_proto(
 8316        &mut self,
 8317        project: WeakEntity<Project>,
 8318        language_servers: Vec<proto::LanguageServer>,
 8319        server_capabilities: Vec<String>,
 8320        cx: &mut Context<Self>,
 8321    ) {
 8322        let lsp_logs = cx
 8323            .try_global::<GlobalLogStore>()
 8324            .map(|lsp_store| lsp_store.0.clone());
 8325
 8326        self.language_server_statuses = language_servers
 8327            .into_iter()
 8328            .zip(server_capabilities)
 8329            .map(|(server, server_capabilities)| {
 8330                let server_id = LanguageServerId(server.id as usize);
 8331                if let Ok(server_capabilities) = serde_json::from_str(&server_capabilities) {
 8332                    self.lsp_server_capabilities
 8333                        .insert(server_id, server_capabilities);
 8334                }
 8335
 8336                let name = LanguageServerName::from_proto(server.name);
 8337                let worktree = server.worktree_id.map(WorktreeId::from_proto);
 8338
 8339                if let Some(lsp_logs) = &lsp_logs {
 8340                    lsp_logs.update(cx, |lsp_logs, cx| {
 8341                        lsp_logs.add_language_server(
 8342                            // Only remote clients get their language servers set from proto
 8343                            LanguageServerKind::Remote {
 8344                                project: project.clone(),
 8345                            },
 8346                            server_id,
 8347                            Some(name.clone()),
 8348                            worktree,
 8349                            None,
 8350                            cx,
 8351                        );
 8352                    });
 8353                }
 8354
 8355                (
 8356                    server_id,
 8357                    LanguageServerStatus {
 8358                        name,
 8359                        pending_work: Default::default(),
 8360                        has_pending_diagnostic_updates: false,
 8361                        progress_tokens: Default::default(),
 8362                        worktree,
 8363                        binary: None,
 8364                        configuration: None,
 8365                        workspace_folders: BTreeSet::new(),
 8366                    },
 8367                )
 8368            })
 8369            .collect();
 8370    }
 8371
 8372    #[cfg(test)]
 8373    pub fn update_diagnostic_entries(
 8374        &mut self,
 8375        server_id: LanguageServerId,
 8376        abs_path: PathBuf,
 8377        result_id: Option<SharedString>,
 8378        version: Option<i32>,
 8379        diagnostics: Vec<DiagnosticEntry<Unclipped<PointUtf16>>>,
 8380        cx: &mut Context<Self>,
 8381    ) -> anyhow::Result<()> {
 8382        self.merge_diagnostic_entries(
 8383            vec![DocumentDiagnosticsUpdate {
 8384                diagnostics: DocumentDiagnostics {
 8385                    diagnostics,
 8386                    document_abs_path: abs_path,
 8387                    version,
 8388                },
 8389                result_id,
 8390                server_id,
 8391                disk_based_sources: Cow::Borrowed(&[]),
 8392                registration_id: None,
 8393            }],
 8394            |_, _, _| false,
 8395            cx,
 8396        )?;
 8397        Ok(())
 8398    }
 8399
 8400    pub fn merge_diagnostic_entries<'a>(
 8401        &mut self,
 8402        diagnostic_updates: Vec<DocumentDiagnosticsUpdate<'a, DocumentDiagnostics>>,
 8403        merge: impl Fn(&lsp::Uri, &Diagnostic, &App) -> bool + Clone,
 8404        cx: &mut Context<Self>,
 8405    ) -> anyhow::Result<()> {
 8406        let mut diagnostics_summary = None::<proto::UpdateDiagnosticSummary>;
 8407        let mut updated_diagnostics_paths = HashMap::default();
 8408        for mut update in diagnostic_updates {
 8409            let abs_path = &update.diagnostics.document_abs_path;
 8410            let server_id = update.server_id;
 8411            let Some((worktree, relative_path)) =
 8412                self.worktree_store.read(cx).find_worktree(abs_path, cx)
 8413            else {
 8414                log::warn!("skipping diagnostics update, no worktree found for path {abs_path:?}");
 8415                return Ok(());
 8416            };
 8417
 8418            let worktree_id = worktree.read(cx).id();
 8419            let project_path = ProjectPath {
 8420                worktree_id,
 8421                path: relative_path,
 8422            };
 8423
 8424            let document_uri = lsp::Uri::from_file_path(abs_path)
 8425                .map_err(|()| anyhow!("Failed to convert buffer path {abs_path:?} to lsp Uri"))?;
 8426            if let Some(buffer_handle) = self.buffer_store.read(cx).get_by_path(&project_path) {
 8427                let snapshot = buffer_handle.read(cx).snapshot();
 8428                let buffer = buffer_handle.read(cx);
 8429                let reused_diagnostics = buffer
 8430                    .buffer_diagnostics(Some(server_id))
 8431                    .iter()
 8432                    .filter(|v| merge(&document_uri, &v.diagnostic, cx))
 8433                    .map(|v| {
 8434                        let start = Unclipped(v.range.start.to_point_utf16(&snapshot));
 8435                        let end = Unclipped(v.range.end.to_point_utf16(&snapshot));
 8436                        DiagnosticEntry {
 8437                            range: start..end,
 8438                            diagnostic: v.diagnostic.clone(),
 8439                        }
 8440                    })
 8441                    .collect::<Vec<_>>();
 8442
 8443                self.as_local_mut()
 8444                    .context("cannot merge diagnostics on a remote LspStore")?
 8445                    .update_buffer_diagnostics(
 8446                        &buffer_handle,
 8447                        server_id,
 8448                        Some(update.registration_id),
 8449                        update.result_id,
 8450                        update.diagnostics.version,
 8451                        update.diagnostics.diagnostics.clone(),
 8452                        reused_diagnostics.clone(),
 8453                        cx,
 8454                    )?;
 8455
 8456                update.diagnostics.diagnostics.extend(reused_diagnostics);
 8457            } else if let Some(local) = self.as_local() {
 8458                let reused_diagnostics = local
 8459                    .diagnostics
 8460                    .get(&worktree_id)
 8461                    .and_then(|diagnostics_for_tree| diagnostics_for_tree.get(&project_path.path))
 8462                    .and_then(|diagnostics_by_server_id| {
 8463                        diagnostics_by_server_id
 8464                            .binary_search_by_key(&server_id, |e| e.0)
 8465                            .ok()
 8466                            .map(|ix| &diagnostics_by_server_id[ix].1)
 8467                    })
 8468                    .into_iter()
 8469                    .flatten()
 8470                    .filter(|v| merge(&document_uri, &v.diagnostic, cx));
 8471
 8472                update
 8473                    .diagnostics
 8474                    .diagnostics
 8475                    .extend(reused_diagnostics.cloned());
 8476            }
 8477
 8478            let updated = worktree.update(cx, |worktree, cx| {
 8479                self.update_worktree_diagnostics(
 8480                    worktree.id(),
 8481                    server_id,
 8482                    project_path.path.clone(),
 8483                    update.diagnostics.diagnostics,
 8484                    cx,
 8485                )
 8486            })?;
 8487            match updated {
 8488                ControlFlow::Continue(new_summary) => {
 8489                    if let Some((project_id, new_summary)) = new_summary {
 8490                        match &mut diagnostics_summary {
 8491                            Some(diagnostics_summary) => {
 8492                                diagnostics_summary
 8493                                    .more_summaries
 8494                                    .push(proto::DiagnosticSummary {
 8495                                        path: project_path.path.as_ref().to_proto(),
 8496                                        language_server_id: server_id.0 as u64,
 8497                                        error_count: new_summary.error_count,
 8498                                        warning_count: new_summary.warning_count,
 8499                                    })
 8500                            }
 8501                            None => {
 8502                                diagnostics_summary = Some(proto::UpdateDiagnosticSummary {
 8503                                    project_id,
 8504                                    worktree_id: worktree_id.to_proto(),
 8505                                    summary: Some(proto::DiagnosticSummary {
 8506                                        path: project_path.path.as_ref().to_proto(),
 8507                                        language_server_id: server_id.0 as u64,
 8508                                        error_count: new_summary.error_count,
 8509                                        warning_count: new_summary.warning_count,
 8510                                    }),
 8511                                    more_summaries: Vec::new(),
 8512                                })
 8513                            }
 8514                        }
 8515                    }
 8516                    updated_diagnostics_paths
 8517                        .entry(server_id)
 8518                        .or_insert_with(Vec::new)
 8519                        .push(project_path);
 8520                }
 8521                ControlFlow::Break(()) => {}
 8522            }
 8523        }
 8524
 8525        if let Some((diagnostics_summary, (downstream_client, _))) =
 8526            diagnostics_summary.zip(self.downstream_client.as_ref())
 8527        {
 8528            downstream_client.send(diagnostics_summary).log_err();
 8529        }
 8530        for (server_id, paths) in updated_diagnostics_paths {
 8531            cx.emit(LspStoreEvent::DiagnosticsUpdated { server_id, paths });
 8532        }
 8533        Ok(())
 8534    }
 8535
 8536    fn update_worktree_diagnostics(
 8537        &mut self,
 8538        worktree_id: WorktreeId,
 8539        server_id: LanguageServerId,
 8540        path_in_worktree: Arc<RelPath>,
 8541        diagnostics: Vec<DiagnosticEntry<Unclipped<PointUtf16>>>,
 8542        _: &mut Context<Worktree>,
 8543    ) -> Result<ControlFlow<(), Option<(u64, proto::DiagnosticSummary)>>> {
 8544        let local = match &mut self.mode {
 8545            LspStoreMode::Local(local_lsp_store) => local_lsp_store,
 8546            _ => anyhow::bail!("update_worktree_diagnostics called on remote"),
 8547        };
 8548
 8549        let summaries_for_tree = self.diagnostic_summaries.entry(worktree_id).or_default();
 8550        let diagnostics_for_tree = local.diagnostics.entry(worktree_id).or_default();
 8551        let summaries_by_server_id = summaries_for_tree
 8552            .entry(path_in_worktree.clone())
 8553            .or_default();
 8554
 8555        let old_summary = summaries_by_server_id
 8556            .remove(&server_id)
 8557            .unwrap_or_default();
 8558
 8559        let new_summary = DiagnosticSummary::new(&diagnostics);
 8560        if diagnostics.is_empty() {
 8561            if let Some(diagnostics_by_server_id) = diagnostics_for_tree.get_mut(&path_in_worktree)
 8562            {
 8563                if let Ok(ix) = diagnostics_by_server_id.binary_search_by_key(&server_id, |e| e.0) {
 8564                    diagnostics_by_server_id.remove(ix);
 8565                }
 8566                if diagnostics_by_server_id.is_empty() {
 8567                    diagnostics_for_tree.remove(&path_in_worktree);
 8568                }
 8569            }
 8570        } else {
 8571            summaries_by_server_id.insert(server_id, new_summary);
 8572            let diagnostics_by_server_id = diagnostics_for_tree
 8573                .entry(path_in_worktree.clone())
 8574                .or_default();
 8575            match diagnostics_by_server_id.binary_search_by_key(&server_id, |e| e.0) {
 8576                Ok(ix) => {
 8577                    diagnostics_by_server_id[ix] = (server_id, diagnostics);
 8578                }
 8579                Err(ix) => {
 8580                    diagnostics_by_server_id.insert(ix, (server_id, diagnostics));
 8581                }
 8582            }
 8583        }
 8584
 8585        if !old_summary.is_empty() || !new_summary.is_empty() {
 8586            if let Some((_, project_id)) = &self.downstream_client {
 8587                Ok(ControlFlow::Continue(Some((
 8588                    *project_id,
 8589                    proto::DiagnosticSummary {
 8590                        path: path_in_worktree.to_proto(),
 8591                        language_server_id: server_id.0 as u64,
 8592                        error_count: new_summary.error_count as u32,
 8593                        warning_count: new_summary.warning_count as u32,
 8594                    },
 8595                ))))
 8596            } else {
 8597                Ok(ControlFlow::Continue(None))
 8598            }
 8599        } else {
 8600            Ok(ControlFlow::Break(()))
 8601        }
 8602    }
 8603
 8604    pub fn open_buffer_for_symbol(
 8605        &mut self,
 8606        symbol: &Symbol,
 8607        cx: &mut Context<Self>,
 8608    ) -> Task<Result<Entity<Buffer>>> {
 8609        if let Some((client, project_id)) = self.upstream_client() {
 8610            let request = client.request(proto::OpenBufferForSymbol {
 8611                project_id,
 8612                symbol: Some(Self::serialize_symbol(symbol)),
 8613            });
 8614            cx.spawn(async move |this, cx| {
 8615                let response = request.await?;
 8616                let buffer_id = BufferId::new(response.buffer_id)?;
 8617                this.update(cx, |this, cx| this.wait_for_remote_buffer(buffer_id, cx))?
 8618                    .await
 8619            })
 8620        } else if let Some(local) = self.as_local() {
 8621            let is_valid = local.language_server_ids.iter().any(|(seed, state)| {
 8622                seed.worktree_id == symbol.source_worktree_id
 8623                    && state.id == symbol.source_language_server_id
 8624                    && symbol.language_server_name == seed.name
 8625            });
 8626            if !is_valid {
 8627                return Task::ready(Err(anyhow!(
 8628                    "language server for worktree and language not found"
 8629                )));
 8630            };
 8631
 8632            let symbol_abs_path = match &symbol.path {
 8633                SymbolLocation::InProject(project_path) => self
 8634                    .worktree_store
 8635                    .read(cx)
 8636                    .absolutize(&project_path, cx)
 8637                    .context("no such worktree"),
 8638                SymbolLocation::OutsideProject {
 8639                    abs_path,
 8640                    signature: _,
 8641                } => Ok(abs_path.to_path_buf()),
 8642            };
 8643            let symbol_abs_path = match symbol_abs_path {
 8644                Ok(abs_path) => abs_path,
 8645                Err(err) => return Task::ready(Err(err)),
 8646            };
 8647            let symbol_uri = if let Ok(uri) = lsp::Uri::from_file_path(symbol_abs_path) {
 8648                uri
 8649            } else {
 8650                return Task::ready(Err(anyhow!("invalid symbol path")));
 8651            };
 8652
 8653            self.open_local_buffer_via_lsp(symbol_uri, symbol.source_language_server_id, cx)
 8654        } else {
 8655            Task::ready(Err(anyhow!("no upstream client or local store")))
 8656        }
 8657    }
 8658
 8659    pub(crate) fn open_local_buffer_via_lsp(
 8660        &mut self,
 8661        abs_path: lsp::Uri,
 8662        language_server_id: LanguageServerId,
 8663        cx: &mut Context<Self>,
 8664    ) -> Task<Result<Entity<Buffer>>> {
 8665        cx.spawn(async move |lsp_store, cx| {
 8666            // Escape percent-encoded string.
 8667            let current_scheme = abs_path.scheme().to_owned();
 8668            // Uri is immutable, so we can't modify the scheme
 8669
 8670            let abs_path = abs_path
 8671                .to_file_path()
 8672                .map_err(|()| anyhow!("can't convert URI to path"))?;
 8673            let p = abs_path.clone();
 8674            let yarn_worktree = lsp_store
 8675                .update(cx, move |lsp_store, cx| match lsp_store.as_local() {
 8676                    Some(local_lsp_store) => local_lsp_store.yarn.update(cx, |_, cx| {
 8677                        cx.spawn(async move |this, cx| {
 8678                            let t = this
 8679                                .update(cx, |this, cx| this.process_path(&p, &current_scheme, cx))
 8680                                .ok()?;
 8681                            t.await
 8682                        })
 8683                    }),
 8684                    None => Task::ready(None),
 8685                })?
 8686                .await;
 8687            let (worktree_root_target, known_relative_path) =
 8688                if let Some((zip_root, relative_path)) = yarn_worktree {
 8689                    (zip_root, Some(relative_path))
 8690                } else {
 8691                    (Arc::<Path>::from(abs_path.as_path()), None)
 8692                };
 8693            let (worktree, relative_path) = if let Some(result) =
 8694                lsp_store.update(cx, |lsp_store, cx| {
 8695                    lsp_store.worktree_store.update(cx, |worktree_store, cx| {
 8696                        worktree_store.find_worktree(&worktree_root_target, cx)
 8697                    })
 8698                })? {
 8699                let relative_path = known_relative_path.unwrap_or_else(|| result.1.clone());
 8700                (result.0, relative_path)
 8701            } else {
 8702                let worktree = lsp_store
 8703                    .update(cx, |lsp_store, cx| {
 8704                        lsp_store.worktree_store.update(cx, |worktree_store, cx| {
 8705                            worktree_store.create_worktree(&worktree_root_target, false, cx)
 8706                        })
 8707                    })?
 8708                    .await?;
 8709                if worktree.read_with(cx, |worktree, _| worktree.is_local())? {
 8710                    lsp_store
 8711                        .update(cx, |lsp_store, cx| {
 8712                            if let Some(local) = lsp_store.as_local_mut() {
 8713                                local.register_language_server_for_invisible_worktree(
 8714                                    &worktree,
 8715                                    language_server_id,
 8716                                    cx,
 8717                                )
 8718                            }
 8719                        })
 8720                        .ok();
 8721                }
 8722                let worktree_root = worktree.read_with(cx, |worktree, _| worktree.abs_path())?;
 8723                let relative_path = if let Some(known_path) = known_relative_path {
 8724                    known_path
 8725                } else {
 8726                    RelPath::new(abs_path.strip_prefix(worktree_root)?, PathStyle::local())?
 8727                        .into_arc()
 8728                };
 8729                (worktree, relative_path)
 8730            };
 8731            let project_path = ProjectPath {
 8732                worktree_id: worktree.read_with(cx, |worktree, _| worktree.id())?,
 8733                path: relative_path,
 8734            };
 8735            lsp_store
 8736                .update(cx, |lsp_store, cx| {
 8737                    lsp_store.buffer_store().update(cx, |buffer_store, cx| {
 8738                        buffer_store.open_buffer(project_path, cx)
 8739                    })
 8740                })?
 8741                .await
 8742        })
 8743    }
 8744
 8745    fn request_multiple_lsp_locally<P, R>(
 8746        &mut self,
 8747        buffer: &Entity<Buffer>,
 8748        position: Option<P>,
 8749        request: R,
 8750        cx: &mut Context<Self>,
 8751    ) -> Task<Vec<(LanguageServerId, R::Response)>>
 8752    where
 8753        P: ToOffset,
 8754        R: LspCommand + Clone,
 8755        <R::LspRequest as lsp::request::Request>::Result: Send,
 8756        <R::LspRequest as lsp::request::Request>::Params: Send,
 8757    {
 8758        let Some(local) = self.as_local() else {
 8759            return Task::ready(Vec::new());
 8760        };
 8761
 8762        let snapshot = buffer.read(cx).snapshot();
 8763        let scope = position.and_then(|position| snapshot.language_scope_at(position));
 8764
 8765        let server_ids = buffer.update(cx, |buffer, cx| {
 8766            local
 8767                .language_servers_for_buffer(buffer, cx)
 8768                .filter(|(adapter, _)| {
 8769                    scope
 8770                        .as_ref()
 8771                        .map(|scope| scope.language_allowed(&adapter.name))
 8772                        .unwrap_or(true)
 8773                })
 8774                .map(|(_, server)| server.server_id())
 8775                .filter(|server_id| {
 8776                    self.as_local().is_none_or(|local| {
 8777                        local
 8778                            .buffers_opened_in_servers
 8779                            .get(&snapshot.remote_id())
 8780                            .is_some_and(|servers| servers.contains(server_id))
 8781                    })
 8782                })
 8783                .collect::<Vec<_>>()
 8784        });
 8785
 8786        let mut response_results = server_ids
 8787            .into_iter()
 8788            .map(|server_id| {
 8789                let task = self.request_lsp(
 8790                    buffer.clone(),
 8791                    LanguageServerToQuery::Other(server_id),
 8792                    request.clone(),
 8793                    cx,
 8794                );
 8795                async move { (server_id, task.await) }
 8796            })
 8797            .collect::<FuturesUnordered<_>>();
 8798
 8799        cx.background_spawn(async move {
 8800            let mut responses = Vec::with_capacity(response_results.len());
 8801            while let Some((server_id, response_result)) = response_results.next().await {
 8802                match response_result {
 8803                    Ok(response) => responses.push((server_id, response)),
 8804                    // rust-analyzer likes to error with this when its still loading up
 8805                    Err(e) if format!("{e:#}").ends_with("content modified") => (),
 8806                    Err(e) => log::error!("Error handling response for request {request:?}: {e:#}"),
 8807                }
 8808            }
 8809            responses
 8810        })
 8811    }
 8812
 8813    async fn handle_lsp_get_completions(
 8814        this: Entity<Self>,
 8815        envelope: TypedEnvelope<proto::GetCompletions>,
 8816        mut cx: AsyncApp,
 8817    ) -> Result<proto::GetCompletionsResponse> {
 8818        let sender_id = envelope.original_sender_id().unwrap_or_default();
 8819
 8820        let buffer_id = GetCompletions::buffer_id_from_proto(&envelope.payload)?;
 8821        let buffer_handle = this.update(&mut cx, |this, cx| {
 8822            this.buffer_store.read(cx).get_existing(buffer_id)
 8823        })??;
 8824        let request = GetCompletions::from_proto(
 8825            envelope.payload,
 8826            this.clone(),
 8827            buffer_handle.clone(),
 8828            cx.clone(),
 8829        )
 8830        .await?;
 8831
 8832        let server_to_query = match request.server_id {
 8833            Some(server_id) => LanguageServerToQuery::Other(server_id),
 8834            None => LanguageServerToQuery::FirstCapable,
 8835        };
 8836
 8837        let response = this
 8838            .update(&mut cx, |this, cx| {
 8839                this.request_lsp(buffer_handle.clone(), server_to_query, request, cx)
 8840            })?
 8841            .await?;
 8842        this.update(&mut cx, |this, cx| {
 8843            Ok(GetCompletions::response_to_proto(
 8844                response,
 8845                this,
 8846                sender_id,
 8847                &buffer_handle.read(cx).version(),
 8848                cx,
 8849            ))
 8850        })?
 8851    }
 8852
 8853    async fn handle_lsp_command<T: LspCommand>(
 8854        this: Entity<Self>,
 8855        envelope: TypedEnvelope<T::ProtoRequest>,
 8856        mut cx: AsyncApp,
 8857    ) -> Result<<T::ProtoRequest as proto::RequestMessage>::Response>
 8858    where
 8859        <T::LspRequest as lsp::request::Request>::Params: Send,
 8860        <T::LspRequest as lsp::request::Request>::Result: Send,
 8861    {
 8862        let sender_id = envelope.original_sender_id().unwrap_or_default();
 8863        let buffer_id = T::buffer_id_from_proto(&envelope.payload)?;
 8864        let buffer_handle = this.update(&mut cx, |this, cx| {
 8865            this.buffer_store.read(cx).get_existing(buffer_id)
 8866        })??;
 8867        let request = T::from_proto(
 8868            envelope.payload,
 8869            this.clone(),
 8870            buffer_handle.clone(),
 8871            cx.clone(),
 8872        )
 8873        .await?;
 8874        let response = this
 8875            .update(&mut cx, |this, cx| {
 8876                this.request_lsp(
 8877                    buffer_handle.clone(),
 8878                    LanguageServerToQuery::FirstCapable,
 8879                    request,
 8880                    cx,
 8881                )
 8882            })?
 8883            .await?;
 8884        this.update(&mut cx, |this, cx| {
 8885            Ok(T::response_to_proto(
 8886                response,
 8887                this,
 8888                sender_id,
 8889                &buffer_handle.read(cx).version(),
 8890                cx,
 8891            ))
 8892        })?
 8893    }
 8894
 8895    async fn handle_lsp_query(
 8896        lsp_store: Entity<Self>,
 8897        envelope: TypedEnvelope<proto::LspQuery>,
 8898        mut cx: AsyncApp,
 8899    ) -> Result<proto::Ack> {
 8900        use proto::lsp_query::Request;
 8901        let sender_id = envelope.original_sender_id().unwrap_or_default();
 8902        let lsp_query = envelope.payload;
 8903        let lsp_request_id = LspRequestId(lsp_query.lsp_request_id);
 8904        let server_id = lsp_query.server_id.map(LanguageServerId::from_proto);
 8905        match lsp_query.request.context("invalid LSP query request")? {
 8906            Request::GetReferences(get_references) => {
 8907                let position = get_references.position.clone().and_then(deserialize_anchor);
 8908                Self::query_lsp_locally::<GetReferences>(
 8909                    lsp_store,
 8910                    server_id,
 8911                    sender_id,
 8912                    lsp_request_id,
 8913                    get_references,
 8914                    position,
 8915                    &mut cx,
 8916                )
 8917                .await?;
 8918            }
 8919            Request::GetDocumentColor(get_document_color) => {
 8920                Self::query_lsp_locally::<GetDocumentColor>(
 8921                    lsp_store,
 8922                    server_id,
 8923                    sender_id,
 8924                    lsp_request_id,
 8925                    get_document_color,
 8926                    None,
 8927                    &mut cx,
 8928                )
 8929                .await?;
 8930            }
 8931            Request::GetHover(get_hover) => {
 8932                let position = get_hover.position.clone().and_then(deserialize_anchor);
 8933                Self::query_lsp_locally::<GetHover>(
 8934                    lsp_store,
 8935                    server_id,
 8936                    sender_id,
 8937                    lsp_request_id,
 8938                    get_hover,
 8939                    position,
 8940                    &mut cx,
 8941                )
 8942                .await?;
 8943            }
 8944            Request::GetCodeActions(get_code_actions) => {
 8945                Self::query_lsp_locally::<GetCodeActions>(
 8946                    lsp_store,
 8947                    server_id,
 8948                    sender_id,
 8949                    lsp_request_id,
 8950                    get_code_actions,
 8951                    None,
 8952                    &mut cx,
 8953                )
 8954                .await?;
 8955            }
 8956            Request::GetSignatureHelp(get_signature_help) => {
 8957                let position = get_signature_help
 8958                    .position
 8959                    .clone()
 8960                    .and_then(deserialize_anchor);
 8961                Self::query_lsp_locally::<GetSignatureHelp>(
 8962                    lsp_store,
 8963                    server_id,
 8964                    sender_id,
 8965                    lsp_request_id,
 8966                    get_signature_help,
 8967                    position,
 8968                    &mut cx,
 8969                )
 8970                .await?;
 8971            }
 8972            Request::GetCodeLens(get_code_lens) => {
 8973                Self::query_lsp_locally::<GetCodeLens>(
 8974                    lsp_store,
 8975                    server_id,
 8976                    sender_id,
 8977                    lsp_request_id,
 8978                    get_code_lens,
 8979                    None,
 8980                    &mut cx,
 8981                )
 8982                .await?;
 8983            }
 8984            Request::GetDefinition(get_definition) => {
 8985                let position = get_definition.position.clone().and_then(deserialize_anchor);
 8986                Self::query_lsp_locally::<GetDefinitions>(
 8987                    lsp_store,
 8988                    server_id,
 8989                    sender_id,
 8990                    lsp_request_id,
 8991                    get_definition,
 8992                    position,
 8993                    &mut cx,
 8994                )
 8995                .await?;
 8996            }
 8997            Request::GetDeclaration(get_declaration) => {
 8998                let position = get_declaration
 8999                    .position
 9000                    .clone()
 9001                    .and_then(deserialize_anchor);
 9002                Self::query_lsp_locally::<GetDeclarations>(
 9003                    lsp_store,
 9004                    server_id,
 9005                    sender_id,
 9006                    lsp_request_id,
 9007                    get_declaration,
 9008                    position,
 9009                    &mut cx,
 9010                )
 9011                .await?;
 9012            }
 9013            Request::GetTypeDefinition(get_type_definition) => {
 9014                let position = get_type_definition
 9015                    .position
 9016                    .clone()
 9017                    .and_then(deserialize_anchor);
 9018                Self::query_lsp_locally::<GetTypeDefinitions>(
 9019                    lsp_store,
 9020                    server_id,
 9021                    sender_id,
 9022                    lsp_request_id,
 9023                    get_type_definition,
 9024                    position,
 9025                    &mut cx,
 9026                )
 9027                .await?;
 9028            }
 9029            Request::GetImplementation(get_implementation) => {
 9030                let position = get_implementation
 9031                    .position
 9032                    .clone()
 9033                    .and_then(deserialize_anchor);
 9034                Self::query_lsp_locally::<GetImplementations>(
 9035                    lsp_store,
 9036                    server_id,
 9037                    sender_id,
 9038                    lsp_request_id,
 9039                    get_implementation,
 9040                    position,
 9041                    &mut cx,
 9042                )
 9043                .await?;
 9044            }
 9045            Request::GetDocumentDiagnostics(get_document_diagnostics) => {
 9046                let buffer_id = BufferId::new(get_document_diagnostics.buffer_id())?;
 9047                let version = deserialize_version(get_document_diagnostics.buffer_version());
 9048                let buffer = lsp_store.update(&mut cx, |this, cx| {
 9049                    this.buffer_store.read(cx).get_existing(buffer_id)
 9050                })??;
 9051                buffer
 9052                    .update(&mut cx, |buffer, _| {
 9053                        buffer.wait_for_version(version.clone())
 9054                    })?
 9055                    .await?;
 9056                lsp_store.update(&mut cx, |lsp_store, cx| {
 9057                    let lsp_data = lsp_store.latest_lsp_data(&buffer, cx);
 9058                    let key = LspKey {
 9059                        request_type: TypeId::of::<GetDocumentDiagnostics>(),
 9060                        server_queried: server_id,
 9061                    };
 9062                    if <GetDocumentDiagnostics as LspCommand>::ProtoRequest::stop_previous_requests(
 9063                    ) {
 9064                        if let Some(lsp_requests) = lsp_data.lsp_requests.get_mut(&key) {
 9065                            lsp_requests.clear();
 9066                        };
 9067                    }
 9068
 9069                    let existing_queries = lsp_data.lsp_requests.entry(key).or_default();
 9070                    existing_queries.insert(
 9071                        lsp_request_id,
 9072                        cx.spawn(async move |lsp_store, cx| {
 9073                            let diagnostics_pull = lsp_store
 9074                                .update(cx, |lsp_store, cx| {
 9075                                    lsp_store.pull_diagnostics_for_buffer(buffer, cx)
 9076                                })
 9077                                .ok();
 9078                            if let Some(diagnostics_pull) = diagnostics_pull {
 9079                                match diagnostics_pull.await {
 9080                                    Ok(()) => {}
 9081                                    Err(e) => log::error!("Failed to pull diagnostics: {e:#}"),
 9082                                };
 9083                            }
 9084                        }),
 9085                    );
 9086                })?;
 9087            }
 9088            Request::InlayHints(inlay_hints) => {
 9089                let query_start = inlay_hints
 9090                    .start
 9091                    .clone()
 9092                    .and_then(deserialize_anchor)
 9093                    .context("invalid inlay hints range start")?;
 9094                let query_end = inlay_hints
 9095                    .end
 9096                    .clone()
 9097                    .and_then(deserialize_anchor)
 9098                    .context("invalid inlay hints range end")?;
 9099                Self::deduplicate_range_based_lsp_requests::<InlayHints>(
 9100                    &lsp_store,
 9101                    server_id,
 9102                    lsp_request_id,
 9103                    &inlay_hints,
 9104                    query_start..query_end,
 9105                    &mut cx,
 9106                )
 9107                .await
 9108                .context("preparing inlay hints request")?;
 9109                Self::query_lsp_locally::<InlayHints>(
 9110                    lsp_store,
 9111                    server_id,
 9112                    sender_id,
 9113                    lsp_request_id,
 9114                    inlay_hints,
 9115                    None,
 9116                    &mut cx,
 9117                )
 9118                .await
 9119                .context("querying for inlay hints")?
 9120            }
 9121        }
 9122        Ok(proto::Ack {})
 9123    }
 9124
 9125    async fn handle_lsp_query_response(
 9126        lsp_store: Entity<Self>,
 9127        envelope: TypedEnvelope<proto::LspQueryResponse>,
 9128        cx: AsyncApp,
 9129    ) -> Result<()> {
 9130        lsp_store.read_with(&cx, |lsp_store, _| {
 9131            if let Some((upstream_client, _)) = lsp_store.upstream_client() {
 9132                upstream_client.handle_lsp_response(envelope.clone());
 9133            }
 9134        })?;
 9135        Ok(())
 9136    }
 9137
 9138    async fn handle_apply_code_action(
 9139        this: Entity<Self>,
 9140        envelope: TypedEnvelope<proto::ApplyCodeAction>,
 9141        mut cx: AsyncApp,
 9142    ) -> Result<proto::ApplyCodeActionResponse> {
 9143        let sender_id = envelope.original_sender_id().unwrap_or_default();
 9144        let action =
 9145            Self::deserialize_code_action(envelope.payload.action.context("invalid action")?)?;
 9146        let apply_code_action = this.update(&mut cx, |this, cx| {
 9147            let buffer_id = BufferId::new(envelope.payload.buffer_id)?;
 9148            let buffer = this.buffer_store.read(cx).get_existing(buffer_id)?;
 9149            anyhow::Ok(this.apply_code_action(buffer, action, false, cx))
 9150        })??;
 9151
 9152        let project_transaction = apply_code_action.await?;
 9153        let project_transaction = this.update(&mut cx, |this, cx| {
 9154            this.buffer_store.update(cx, |buffer_store, cx| {
 9155                buffer_store.serialize_project_transaction_for_peer(
 9156                    project_transaction,
 9157                    sender_id,
 9158                    cx,
 9159                )
 9160            })
 9161        })?;
 9162        Ok(proto::ApplyCodeActionResponse {
 9163            transaction: Some(project_transaction),
 9164        })
 9165    }
 9166
 9167    async fn handle_register_buffer_with_language_servers(
 9168        this: Entity<Self>,
 9169        envelope: TypedEnvelope<proto::RegisterBufferWithLanguageServers>,
 9170        mut cx: AsyncApp,
 9171    ) -> Result<proto::Ack> {
 9172        let buffer_id = BufferId::new(envelope.payload.buffer_id)?;
 9173        let peer_id = envelope.original_sender_id.unwrap_or(envelope.sender_id);
 9174        this.update(&mut cx, |this, cx| {
 9175            if let Some((upstream_client, upstream_project_id)) = this.upstream_client() {
 9176                return upstream_client.send(proto::RegisterBufferWithLanguageServers {
 9177                    project_id: upstream_project_id,
 9178                    buffer_id: buffer_id.to_proto(),
 9179                    only_servers: envelope.payload.only_servers,
 9180                });
 9181            }
 9182
 9183            let Some(buffer) = this.buffer_store().read(cx).get(buffer_id) else {
 9184                anyhow::bail!("buffer is not open");
 9185            };
 9186
 9187            let handle = this.register_buffer_with_language_servers(
 9188                &buffer,
 9189                envelope
 9190                    .payload
 9191                    .only_servers
 9192                    .into_iter()
 9193                    .filter_map(|selector| {
 9194                        Some(match selector.selector? {
 9195                            proto::language_server_selector::Selector::ServerId(server_id) => {
 9196                                LanguageServerSelector::Id(LanguageServerId::from_proto(server_id))
 9197                            }
 9198                            proto::language_server_selector::Selector::Name(name) => {
 9199                                LanguageServerSelector::Name(LanguageServerName(
 9200                                    SharedString::from(name),
 9201                                ))
 9202                            }
 9203                        })
 9204                    })
 9205                    .collect(),
 9206                false,
 9207                cx,
 9208            );
 9209            this.buffer_store().update(cx, |buffer_store, _| {
 9210                buffer_store.register_shared_lsp_handle(peer_id, buffer_id, handle);
 9211            });
 9212
 9213            Ok(())
 9214        })??;
 9215        Ok(proto::Ack {})
 9216    }
 9217
 9218    async fn handle_rename_project_entry(
 9219        this: Entity<Self>,
 9220        envelope: TypedEnvelope<proto::RenameProjectEntry>,
 9221        mut cx: AsyncApp,
 9222    ) -> Result<proto::ProjectEntryResponse> {
 9223        let entry_id = ProjectEntryId::from_proto(envelope.payload.entry_id);
 9224        let new_worktree_id = WorktreeId::from_proto(envelope.payload.new_worktree_id);
 9225        let new_path =
 9226            RelPath::from_proto(&envelope.payload.new_path).context("invalid relative path")?;
 9227
 9228        let (worktree_store, old_worktree, new_worktree, old_entry) = this
 9229            .update(&mut cx, |this, cx| {
 9230                let (worktree, entry) = this
 9231                    .worktree_store
 9232                    .read(cx)
 9233                    .worktree_and_entry_for_id(entry_id, cx)?;
 9234                let new_worktree = this
 9235                    .worktree_store
 9236                    .read(cx)
 9237                    .worktree_for_id(new_worktree_id, cx)?;
 9238                Some((
 9239                    this.worktree_store.clone(),
 9240                    worktree,
 9241                    new_worktree,
 9242                    entry.clone(),
 9243                ))
 9244            })?
 9245            .context("worktree not found")?;
 9246        let (old_abs_path, old_worktree_id) = old_worktree.read_with(&cx, |worktree, _| {
 9247            (worktree.absolutize(&old_entry.path), worktree.id())
 9248        })?;
 9249        let new_abs_path =
 9250            new_worktree.read_with(&cx, |worktree, _| worktree.absolutize(&new_path))?;
 9251
 9252        let _transaction = Self::will_rename_entry(
 9253            this.downgrade(),
 9254            old_worktree_id,
 9255            &old_abs_path,
 9256            &new_abs_path,
 9257            old_entry.is_dir(),
 9258            cx.clone(),
 9259        )
 9260        .await;
 9261        let response = WorktreeStore::handle_rename_project_entry(
 9262            worktree_store,
 9263            envelope.payload,
 9264            cx.clone(),
 9265        )
 9266        .await;
 9267        this.read_with(&cx, |this, _| {
 9268            this.did_rename_entry(
 9269                old_worktree_id,
 9270                &old_abs_path,
 9271                &new_abs_path,
 9272                old_entry.is_dir(),
 9273            );
 9274        })
 9275        .ok();
 9276        response
 9277    }
 9278
 9279    async fn handle_update_diagnostic_summary(
 9280        this: Entity<Self>,
 9281        envelope: TypedEnvelope<proto::UpdateDiagnosticSummary>,
 9282        mut cx: AsyncApp,
 9283    ) -> Result<()> {
 9284        this.update(&mut cx, |lsp_store, cx| {
 9285            let worktree_id = WorktreeId::from_proto(envelope.payload.worktree_id);
 9286            let mut updated_diagnostics_paths = HashMap::default();
 9287            let mut diagnostics_summary = None::<proto::UpdateDiagnosticSummary>;
 9288            for message_summary in envelope
 9289                .payload
 9290                .summary
 9291                .into_iter()
 9292                .chain(envelope.payload.more_summaries)
 9293            {
 9294                let project_path = ProjectPath {
 9295                    worktree_id,
 9296                    path: RelPath::from_proto(&message_summary.path).context("invalid path")?,
 9297                };
 9298                let path = project_path.path.clone();
 9299                let server_id = LanguageServerId(message_summary.language_server_id as usize);
 9300                let summary = DiagnosticSummary {
 9301                    error_count: message_summary.error_count as usize,
 9302                    warning_count: message_summary.warning_count as usize,
 9303                };
 9304
 9305                if summary.is_empty() {
 9306                    if let Some(worktree_summaries) =
 9307                        lsp_store.diagnostic_summaries.get_mut(&worktree_id)
 9308                        && let Some(summaries) = worktree_summaries.get_mut(&path)
 9309                    {
 9310                        summaries.remove(&server_id);
 9311                        if summaries.is_empty() {
 9312                            worktree_summaries.remove(&path);
 9313                        }
 9314                    }
 9315                } else {
 9316                    lsp_store
 9317                        .diagnostic_summaries
 9318                        .entry(worktree_id)
 9319                        .or_default()
 9320                        .entry(path)
 9321                        .or_default()
 9322                        .insert(server_id, summary);
 9323                }
 9324
 9325                if let Some((_, project_id)) = &lsp_store.downstream_client {
 9326                    match &mut diagnostics_summary {
 9327                        Some(diagnostics_summary) => {
 9328                            diagnostics_summary
 9329                                .more_summaries
 9330                                .push(proto::DiagnosticSummary {
 9331                                    path: project_path.path.as_ref().to_proto(),
 9332                                    language_server_id: server_id.0 as u64,
 9333                                    error_count: summary.error_count as u32,
 9334                                    warning_count: summary.warning_count as u32,
 9335                                })
 9336                        }
 9337                        None => {
 9338                            diagnostics_summary = Some(proto::UpdateDiagnosticSummary {
 9339                                project_id: *project_id,
 9340                                worktree_id: worktree_id.to_proto(),
 9341                                summary: Some(proto::DiagnosticSummary {
 9342                                    path: project_path.path.as_ref().to_proto(),
 9343                                    language_server_id: server_id.0 as u64,
 9344                                    error_count: summary.error_count as u32,
 9345                                    warning_count: summary.warning_count as u32,
 9346                                }),
 9347                                more_summaries: Vec::new(),
 9348                            })
 9349                        }
 9350                    }
 9351                }
 9352                updated_diagnostics_paths
 9353                    .entry(server_id)
 9354                    .or_insert_with(Vec::new)
 9355                    .push(project_path);
 9356            }
 9357
 9358            if let Some((diagnostics_summary, (downstream_client, _))) =
 9359                diagnostics_summary.zip(lsp_store.downstream_client.as_ref())
 9360            {
 9361                downstream_client.send(diagnostics_summary).log_err();
 9362            }
 9363            for (server_id, paths) in updated_diagnostics_paths {
 9364                cx.emit(LspStoreEvent::DiagnosticsUpdated { server_id, paths });
 9365            }
 9366            Ok(())
 9367        })?
 9368    }
 9369
 9370    async fn handle_start_language_server(
 9371        lsp_store: Entity<Self>,
 9372        envelope: TypedEnvelope<proto::StartLanguageServer>,
 9373        mut cx: AsyncApp,
 9374    ) -> Result<()> {
 9375        let server = envelope.payload.server.context("invalid server")?;
 9376        let server_capabilities =
 9377            serde_json::from_str::<lsp::ServerCapabilities>(&envelope.payload.capabilities)
 9378                .with_context(|| {
 9379                    format!(
 9380                        "incorrect server capabilities {}",
 9381                        envelope.payload.capabilities
 9382                    )
 9383                })?;
 9384        lsp_store.update(&mut cx, |lsp_store, cx| {
 9385            let server_id = LanguageServerId(server.id as usize);
 9386            let server_name = LanguageServerName::from_proto(server.name.clone());
 9387            lsp_store
 9388                .lsp_server_capabilities
 9389                .insert(server_id, server_capabilities);
 9390            lsp_store.language_server_statuses.insert(
 9391                server_id,
 9392                LanguageServerStatus {
 9393                    name: server_name.clone(),
 9394                    pending_work: Default::default(),
 9395                    has_pending_diagnostic_updates: false,
 9396                    progress_tokens: Default::default(),
 9397                    worktree: server.worktree_id.map(WorktreeId::from_proto),
 9398                    binary: None,
 9399                    configuration: None,
 9400                    workspace_folders: BTreeSet::new(),
 9401                },
 9402            );
 9403            cx.emit(LspStoreEvent::LanguageServerAdded(
 9404                server_id,
 9405                server_name,
 9406                server.worktree_id.map(WorktreeId::from_proto),
 9407            ));
 9408            cx.notify();
 9409        })?;
 9410        Ok(())
 9411    }
 9412
 9413    async fn handle_update_language_server(
 9414        lsp_store: Entity<Self>,
 9415        envelope: TypedEnvelope<proto::UpdateLanguageServer>,
 9416        mut cx: AsyncApp,
 9417    ) -> Result<()> {
 9418        lsp_store.update(&mut cx, |lsp_store, cx| {
 9419            let language_server_id = LanguageServerId(envelope.payload.language_server_id as usize);
 9420
 9421            match envelope.payload.variant.context("invalid variant")? {
 9422                proto::update_language_server::Variant::WorkStart(payload) => {
 9423                    lsp_store.on_lsp_work_start(
 9424                        language_server_id,
 9425                        ProgressToken::from_proto(payload.token.context("missing progress token")?)
 9426                            .context("invalid progress token value")?,
 9427                        LanguageServerProgress {
 9428                            title: payload.title,
 9429                            is_disk_based_diagnostics_progress: false,
 9430                            is_cancellable: payload.is_cancellable.unwrap_or(false),
 9431                            message: payload.message,
 9432                            percentage: payload.percentage.map(|p| p as usize),
 9433                            last_update_at: cx.background_executor().now(),
 9434                        },
 9435                        cx,
 9436                    );
 9437                }
 9438                proto::update_language_server::Variant::WorkProgress(payload) => {
 9439                    lsp_store.on_lsp_work_progress(
 9440                        language_server_id,
 9441                        ProgressToken::from_proto(payload.token.context("missing progress token")?)
 9442                            .context("invalid progress token value")?,
 9443                        LanguageServerProgress {
 9444                            title: None,
 9445                            is_disk_based_diagnostics_progress: false,
 9446                            is_cancellable: payload.is_cancellable.unwrap_or(false),
 9447                            message: payload.message,
 9448                            percentage: payload.percentage.map(|p| p as usize),
 9449                            last_update_at: cx.background_executor().now(),
 9450                        },
 9451                        cx,
 9452                    );
 9453                }
 9454
 9455                proto::update_language_server::Variant::WorkEnd(payload) => {
 9456                    lsp_store.on_lsp_work_end(
 9457                        language_server_id,
 9458                        ProgressToken::from_proto(payload.token.context("missing progress token")?)
 9459                            .context("invalid progress token value")?,
 9460                        cx,
 9461                    );
 9462                }
 9463
 9464                proto::update_language_server::Variant::DiskBasedDiagnosticsUpdating(_) => {
 9465                    lsp_store.disk_based_diagnostics_started(language_server_id, cx);
 9466                }
 9467
 9468                proto::update_language_server::Variant::DiskBasedDiagnosticsUpdated(_) => {
 9469                    lsp_store.disk_based_diagnostics_finished(language_server_id, cx)
 9470                }
 9471
 9472                non_lsp @ proto::update_language_server::Variant::StatusUpdate(_)
 9473                | non_lsp @ proto::update_language_server::Variant::RegisteredForBuffer(_)
 9474                | non_lsp @ proto::update_language_server::Variant::MetadataUpdated(_) => {
 9475                    cx.emit(LspStoreEvent::LanguageServerUpdate {
 9476                        language_server_id,
 9477                        name: envelope
 9478                            .payload
 9479                            .server_name
 9480                            .map(SharedString::new)
 9481                            .map(LanguageServerName),
 9482                        message: non_lsp,
 9483                    });
 9484                }
 9485            }
 9486
 9487            Ok(())
 9488        })?
 9489    }
 9490
 9491    async fn handle_language_server_log(
 9492        this: Entity<Self>,
 9493        envelope: TypedEnvelope<proto::LanguageServerLog>,
 9494        mut cx: AsyncApp,
 9495    ) -> Result<()> {
 9496        let language_server_id = LanguageServerId(envelope.payload.language_server_id as usize);
 9497        let log_type = envelope
 9498            .payload
 9499            .log_type
 9500            .map(LanguageServerLogType::from_proto)
 9501            .context("invalid language server log type")?;
 9502
 9503        let message = envelope.payload.message;
 9504
 9505        this.update(&mut cx, |_, cx| {
 9506            cx.emit(LspStoreEvent::LanguageServerLog(
 9507                language_server_id,
 9508                log_type,
 9509                message,
 9510            ));
 9511        })
 9512    }
 9513
 9514    async fn handle_lsp_ext_cancel_flycheck(
 9515        lsp_store: Entity<Self>,
 9516        envelope: TypedEnvelope<proto::LspExtCancelFlycheck>,
 9517        cx: AsyncApp,
 9518    ) -> Result<proto::Ack> {
 9519        let server_id = LanguageServerId(envelope.payload.language_server_id as usize);
 9520        let task = lsp_store.read_with(&cx, |lsp_store, _| {
 9521            if let Some(server) = lsp_store.language_server_for_id(server_id) {
 9522                Some(server.notify::<lsp_store::lsp_ext_command::LspExtCancelFlycheck>(()))
 9523            } else {
 9524                None
 9525            }
 9526        })?;
 9527        if let Some(task) = task {
 9528            task.context("handling lsp ext cancel flycheck")?;
 9529        }
 9530
 9531        Ok(proto::Ack {})
 9532    }
 9533
 9534    async fn handle_lsp_ext_run_flycheck(
 9535        lsp_store: Entity<Self>,
 9536        envelope: TypedEnvelope<proto::LspExtRunFlycheck>,
 9537        mut cx: AsyncApp,
 9538    ) -> Result<proto::Ack> {
 9539        let server_id = LanguageServerId(envelope.payload.language_server_id as usize);
 9540        lsp_store.update(&mut cx, |lsp_store, cx| {
 9541            if let Some(server) = lsp_store.language_server_for_id(server_id) {
 9542                let text_document = if envelope.payload.current_file_only {
 9543                    let buffer_id = envelope
 9544                        .payload
 9545                        .buffer_id
 9546                        .map(|id| BufferId::new(id))
 9547                        .transpose()?;
 9548                    buffer_id
 9549                        .and_then(|buffer_id| {
 9550                            lsp_store
 9551                                .buffer_store()
 9552                                .read(cx)
 9553                                .get(buffer_id)
 9554                                .and_then(|buffer| {
 9555                                    Some(buffer.read(cx).file()?.as_local()?.abs_path(cx))
 9556                                })
 9557                                .map(|path| make_text_document_identifier(&path))
 9558                        })
 9559                        .transpose()?
 9560                } else {
 9561                    None
 9562                };
 9563                server.notify::<lsp_store::lsp_ext_command::LspExtRunFlycheck>(
 9564                    lsp_store::lsp_ext_command::RunFlycheckParams { text_document },
 9565                )?;
 9566            }
 9567            anyhow::Ok(())
 9568        })??;
 9569
 9570        Ok(proto::Ack {})
 9571    }
 9572
 9573    async fn handle_lsp_ext_clear_flycheck(
 9574        lsp_store: Entity<Self>,
 9575        envelope: TypedEnvelope<proto::LspExtClearFlycheck>,
 9576        cx: AsyncApp,
 9577    ) -> Result<proto::Ack> {
 9578        let server_id = LanguageServerId(envelope.payload.language_server_id as usize);
 9579        lsp_store
 9580            .read_with(&cx, |lsp_store, _| {
 9581                if let Some(server) = lsp_store.language_server_for_id(server_id) {
 9582                    Some(server.notify::<lsp_store::lsp_ext_command::LspExtClearFlycheck>(()))
 9583                } else {
 9584                    None
 9585                }
 9586            })
 9587            .context("handling lsp ext clear flycheck")?;
 9588
 9589        Ok(proto::Ack {})
 9590    }
 9591
 9592    pub fn disk_based_diagnostics_started(
 9593        &mut self,
 9594        language_server_id: LanguageServerId,
 9595        cx: &mut Context<Self>,
 9596    ) {
 9597        if let Some(language_server_status) =
 9598            self.language_server_statuses.get_mut(&language_server_id)
 9599        {
 9600            language_server_status.has_pending_diagnostic_updates = true;
 9601        }
 9602
 9603        cx.emit(LspStoreEvent::DiskBasedDiagnosticsStarted { language_server_id });
 9604        cx.emit(LspStoreEvent::LanguageServerUpdate {
 9605            language_server_id,
 9606            name: self
 9607                .language_server_adapter_for_id(language_server_id)
 9608                .map(|adapter| adapter.name()),
 9609            message: proto::update_language_server::Variant::DiskBasedDiagnosticsUpdating(
 9610                Default::default(),
 9611            ),
 9612        })
 9613    }
 9614
 9615    pub fn disk_based_diagnostics_finished(
 9616        &mut self,
 9617        language_server_id: LanguageServerId,
 9618        cx: &mut Context<Self>,
 9619    ) {
 9620        if let Some(language_server_status) =
 9621            self.language_server_statuses.get_mut(&language_server_id)
 9622        {
 9623            language_server_status.has_pending_diagnostic_updates = false;
 9624        }
 9625
 9626        cx.emit(LspStoreEvent::DiskBasedDiagnosticsFinished { language_server_id });
 9627        cx.emit(LspStoreEvent::LanguageServerUpdate {
 9628            language_server_id,
 9629            name: self
 9630                .language_server_adapter_for_id(language_server_id)
 9631                .map(|adapter| adapter.name()),
 9632            message: proto::update_language_server::Variant::DiskBasedDiagnosticsUpdated(
 9633                Default::default(),
 9634            ),
 9635        })
 9636    }
 9637
 9638    // After saving a buffer using a language server that doesn't provide a disk-based progress token,
 9639    // kick off a timer that will reset every time the buffer is saved. If the timer eventually fires,
 9640    // simulate disk-based diagnostics being finished so that other pieces of UI (e.g., project
 9641    // diagnostics view, diagnostic status bar) can update. We don't emit an event right away because
 9642    // the language server might take some time to publish diagnostics.
 9643    fn simulate_disk_based_diagnostics_events_if_needed(
 9644        &mut self,
 9645        language_server_id: LanguageServerId,
 9646        cx: &mut Context<Self>,
 9647    ) {
 9648        const DISK_BASED_DIAGNOSTICS_DEBOUNCE: Duration = Duration::from_secs(1);
 9649
 9650        let Some(LanguageServerState::Running {
 9651            simulate_disk_based_diagnostics_completion,
 9652            adapter,
 9653            ..
 9654        }) = self
 9655            .as_local_mut()
 9656            .and_then(|local_store| local_store.language_servers.get_mut(&language_server_id))
 9657        else {
 9658            return;
 9659        };
 9660
 9661        if adapter.disk_based_diagnostics_progress_token.is_some() {
 9662            return;
 9663        }
 9664
 9665        let prev_task =
 9666            simulate_disk_based_diagnostics_completion.replace(cx.spawn(async move |this, cx| {
 9667                cx.background_executor()
 9668                    .timer(DISK_BASED_DIAGNOSTICS_DEBOUNCE)
 9669                    .await;
 9670
 9671                this.update(cx, |this, cx| {
 9672                    this.disk_based_diagnostics_finished(language_server_id, cx);
 9673
 9674                    if let Some(LanguageServerState::Running {
 9675                        simulate_disk_based_diagnostics_completion,
 9676                        ..
 9677                    }) = this.as_local_mut().and_then(|local_store| {
 9678                        local_store.language_servers.get_mut(&language_server_id)
 9679                    }) {
 9680                        *simulate_disk_based_diagnostics_completion = None;
 9681                    }
 9682                })
 9683                .ok();
 9684            }));
 9685
 9686        if prev_task.is_none() {
 9687            self.disk_based_diagnostics_started(language_server_id, cx);
 9688        }
 9689    }
 9690
 9691    pub fn language_server_statuses(
 9692        &self,
 9693    ) -> impl DoubleEndedIterator<Item = (LanguageServerId, &LanguageServerStatus)> {
 9694        self.language_server_statuses
 9695            .iter()
 9696            .map(|(key, value)| (*key, value))
 9697    }
 9698
 9699    pub(super) fn did_rename_entry(
 9700        &self,
 9701        worktree_id: WorktreeId,
 9702        old_path: &Path,
 9703        new_path: &Path,
 9704        is_dir: bool,
 9705    ) {
 9706        maybe!({
 9707            let local_store = self.as_local()?;
 9708
 9709            let old_uri = lsp::Uri::from_file_path(old_path)
 9710                .ok()
 9711                .map(|uri| uri.to_string())?;
 9712            let new_uri = lsp::Uri::from_file_path(new_path)
 9713                .ok()
 9714                .map(|uri| uri.to_string())?;
 9715
 9716            for language_server in local_store.language_servers_for_worktree(worktree_id) {
 9717                let Some(filter) = local_store
 9718                    .language_server_paths_watched_for_rename
 9719                    .get(&language_server.server_id())
 9720                else {
 9721                    continue;
 9722                };
 9723
 9724                if filter.should_send_did_rename(&old_uri, is_dir) {
 9725                    language_server
 9726                        .notify::<DidRenameFiles>(RenameFilesParams {
 9727                            files: vec![FileRename {
 9728                                old_uri: old_uri.clone(),
 9729                                new_uri: new_uri.clone(),
 9730                            }],
 9731                        })
 9732                        .ok();
 9733                }
 9734            }
 9735            Some(())
 9736        });
 9737    }
 9738
 9739    pub(super) fn will_rename_entry(
 9740        this: WeakEntity<Self>,
 9741        worktree_id: WorktreeId,
 9742        old_path: &Path,
 9743        new_path: &Path,
 9744        is_dir: bool,
 9745        cx: AsyncApp,
 9746    ) -> Task<ProjectTransaction> {
 9747        let old_uri = lsp::Uri::from_file_path(old_path)
 9748            .ok()
 9749            .map(|uri| uri.to_string());
 9750        let new_uri = lsp::Uri::from_file_path(new_path)
 9751            .ok()
 9752            .map(|uri| uri.to_string());
 9753        cx.spawn(async move |cx| {
 9754            let mut tasks = vec![];
 9755            this.update(cx, |this, cx| {
 9756                let local_store = this.as_local()?;
 9757                let old_uri = old_uri?;
 9758                let new_uri = new_uri?;
 9759                for language_server in local_store.language_servers_for_worktree(worktree_id) {
 9760                    let Some(filter) = local_store
 9761                        .language_server_paths_watched_for_rename
 9762                        .get(&language_server.server_id())
 9763                    else {
 9764                        continue;
 9765                    };
 9766
 9767                    if filter.should_send_will_rename(&old_uri, is_dir) {
 9768                        let apply_edit = cx.spawn({
 9769                            let old_uri = old_uri.clone();
 9770                            let new_uri = new_uri.clone();
 9771                            let language_server = language_server.clone();
 9772                            async move |this, cx| {
 9773                                let edit = language_server
 9774                                    .request::<WillRenameFiles>(RenameFilesParams {
 9775                                        files: vec![FileRename { old_uri, new_uri }],
 9776                                    })
 9777                                    .await
 9778                                    .into_response()
 9779                                    .context("will rename files")
 9780                                    .log_err()
 9781                                    .flatten()?;
 9782
 9783                                let transaction = LocalLspStore::deserialize_workspace_edit(
 9784                                    this.upgrade()?,
 9785                                    edit,
 9786                                    false,
 9787                                    language_server.clone(),
 9788                                    cx,
 9789                                )
 9790                                .await
 9791                                .ok()?;
 9792                                Some(transaction)
 9793                            }
 9794                        });
 9795                        tasks.push(apply_edit);
 9796                    }
 9797                }
 9798                Some(())
 9799            })
 9800            .ok()
 9801            .flatten();
 9802            let mut merged_transaction = ProjectTransaction::default();
 9803            for task in tasks {
 9804                // Await on tasks sequentially so that the order of application of edits is deterministic
 9805                // (at least with regards to the order of registration of language servers)
 9806                if let Some(transaction) = task.await {
 9807                    for (buffer, buffer_transaction) in transaction.0 {
 9808                        merged_transaction.0.insert(buffer, buffer_transaction);
 9809                    }
 9810                }
 9811            }
 9812            merged_transaction
 9813        })
 9814    }
 9815
 9816    fn lsp_notify_abs_paths_changed(
 9817        &mut self,
 9818        server_id: LanguageServerId,
 9819        changes: Vec<PathEvent>,
 9820    ) {
 9821        maybe!({
 9822            let server = self.language_server_for_id(server_id)?;
 9823            let changes = changes
 9824                .into_iter()
 9825                .filter_map(|event| {
 9826                    let typ = match event.kind? {
 9827                        PathEventKind::Created => lsp::FileChangeType::CREATED,
 9828                        PathEventKind::Removed => lsp::FileChangeType::DELETED,
 9829                        PathEventKind::Changed => lsp::FileChangeType::CHANGED,
 9830                    };
 9831                    Some(lsp::FileEvent {
 9832                        uri: file_path_to_lsp_url(&event.path).log_err()?,
 9833                        typ,
 9834                    })
 9835                })
 9836                .collect::<Vec<_>>();
 9837            if !changes.is_empty() {
 9838                server
 9839                    .notify::<lsp::notification::DidChangeWatchedFiles>(
 9840                        lsp::DidChangeWatchedFilesParams { changes },
 9841                    )
 9842                    .ok();
 9843            }
 9844            Some(())
 9845        });
 9846    }
 9847
 9848    pub fn language_server_for_id(&self, id: LanguageServerId) -> Option<Arc<LanguageServer>> {
 9849        self.as_local()?.language_server_for_id(id)
 9850    }
 9851
 9852    fn on_lsp_progress(
 9853        &mut self,
 9854        progress_params: lsp::ProgressParams,
 9855        language_server_id: LanguageServerId,
 9856        disk_based_diagnostics_progress_token: Option<String>,
 9857        cx: &mut Context<Self>,
 9858    ) {
 9859        match progress_params.value {
 9860            lsp::ProgressParamsValue::WorkDone(progress) => {
 9861                self.handle_work_done_progress(
 9862                    progress,
 9863                    language_server_id,
 9864                    disk_based_diagnostics_progress_token,
 9865                    ProgressToken::from_lsp(progress_params.token),
 9866                    cx,
 9867                );
 9868            }
 9869            lsp::ProgressParamsValue::WorkspaceDiagnostic(report) => {
 9870                let registration_id = match progress_params.token {
 9871                    lsp::NumberOrString::Number(_) => None,
 9872                    lsp::NumberOrString::String(token) => token
 9873                        .split_once(WORKSPACE_DIAGNOSTICS_TOKEN_START)
 9874                        .map(|(_, id)| id.to_owned()),
 9875                };
 9876                if let Some(LanguageServerState::Running {
 9877                    workspace_diagnostics_refresh_tasks,
 9878                    ..
 9879                }) = self
 9880                    .as_local_mut()
 9881                    .and_then(|local| local.language_servers.get_mut(&language_server_id))
 9882                    && let Some(workspace_diagnostics) =
 9883                        workspace_diagnostics_refresh_tasks.get_mut(&registration_id)
 9884                {
 9885                    workspace_diagnostics.progress_tx.try_send(()).ok();
 9886                    self.apply_workspace_diagnostic_report(
 9887                        language_server_id,
 9888                        report,
 9889                        registration_id.map(SharedString::from),
 9890                        cx,
 9891                    )
 9892                }
 9893            }
 9894        }
 9895    }
 9896
 9897    fn handle_work_done_progress(
 9898        &mut self,
 9899        progress: lsp::WorkDoneProgress,
 9900        language_server_id: LanguageServerId,
 9901        disk_based_diagnostics_progress_token: Option<String>,
 9902        token: ProgressToken,
 9903        cx: &mut Context<Self>,
 9904    ) {
 9905        let language_server_status =
 9906            if let Some(status) = self.language_server_statuses.get_mut(&language_server_id) {
 9907                status
 9908            } else {
 9909                return;
 9910            };
 9911
 9912        if !language_server_status.progress_tokens.contains(&token) {
 9913            return;
 9914        }
 9915
 9916        let is_disk_based_diagnostics_progress =
 9917            if let (Some(disk_based_token), ProgressToken::String(token)) =
 9918                (&disk_based_diagnostics_progress_token, &token)
 9919            {
 9920                token.starts_with(disk_based_token)
 9921            } else {
 9922                false
 9923            };
 9924
 9925        match progress {
 9926            lsp::WorkDoneProgress::Begin(report) => {
 9927                if is_disk_based_diagnostics_progress {
 9928                    self.disk_based_diagnostics_started(language_server_id, cx);
 9929                }
 9930                self.on_lsp_work_start(
 9931                    language_server_id,
 9932                    token.clone(),
 9933                    LanguageServerProgress {
 9934                        title: Some(report.title),
 9935                        is_disk_based_diagnostics_progress,
 9936                        is_cancellable: report.cancellable.unwrap_or(false),
 9937                        message: report.message.clone(),
 9938                        percentage: report.percentage.map(|p| p as usize),
 9939                        last_update_at: cx.background_executor().now(),
 9940                    },
 9941                    cx,
 9942                );
 9943            }
 9944            lsp::WorkDoneProgress::Report(report) => self.on_lsp_work_progress(
 9945                language_server_id,
 9946                token,
 9947                LanguageServerProgress {
 9948                    title: None,
 9949                    is_disk_based_diagnostics_progress,
 9950                    is_cancellable: report.cancellable.unwrap_or(false),
 9951                    message: report.message,
 9952                    percentage: report.percentage.map(|p| p as usize),
 9953                    last_update_at: cx.background_executor().now(),
 9954                },
 9955                cx,
 9956            ),
 9957            lsp::WorkDoneProgress::End(_) => {
 9958                language_server_status.progress_tokens.remove(&token);
 9959                self.on_lsp_work_end(language_server_id, token.clone(), cx);
 9960                if is_disk_based_diagnostics_progress {
 9961                    self.disk_based_diagnostics_finished(language_server_id, cx);
 9962                }
 9963            }
 9964        }
 9965    }
 9966
 9967    fn on_lsp_work_start(
 9968        &mut self,
 9969        language_server_id: LanguageServerId,
 9970        token: ProgressToken,
 9971        progress: LanguageServerProgress,
 9972        cx: &mut Context<Self>,
 9973    ) {
 9974        if let Some(status) = self.language_server_statuses.get_mut(&language_server_id) {
 9975            status.pending_work.insert(token.clone(), progress.clone());
 9976            cx.notify();
 9977        }
 9978        cx.emit(LspStoreEvent::LanguageServerUpdate {
 9979            language_server_id,
 9980            name: self
 9981                .language_server_adapter_for_id(language_server_id)
 9982                .map(|adapter| adapter.name()),
 9983            message: proto::update_language_server::Variant::WorkStart(proto::LspWorkStart {
 9984                token: Some(token.to_proto()),
 9985                title: progress.title,
 9986                message: progress.message,
 9987                percentage: progress.percentage.map(|p| p as u32),
 9988                is_cancellable: Some(progress.is_cancellable),
 9989            }),
 9990        })
 9991    }
 9992
 9993    fn on_lsp_work_progress(
 9994        &mut self,
 9995        language_server_id: LanguageServerId,
 9996        token: ProgressToken,
 9997        progress: LanguageServerProgress,
 9998        cx: &mut Context<Self>,
 9999    ) {
10000        let mut did_update = false;
10001        if let Some(status) = self.language_server_statuses.get_mut(&language_server_id) {
10002            match status.pending_work.entry(token.clone()) {
10003                btree_map::Entry::Vacant(entry) => {
10004                    entry.insert(progress.clone());
10005                    did_update = true;
10006                }
10007                btree_map::Entry::Occupied(mut entry) => {
10008                    let entry = entry.get_mut();
10009                    if (progress.last_update_at - entry.last_update_at)
10010                        >= SERVER_PROGRESS_THROTTLE_TIMEOUT
10011                    {
10012                        entry.last_update_at = progress.last_update_at;
10013                        if progress.message.is_some() {
10014                            entry.message = progress.message.clone();
10015                        }
10016                        if progress.percentage.is_some() {
10017                            entry.percentage = progress.percentage;
10018                        }
10019                        if progress.is_cancellable != entry.is_cancellable {
10020                            entry.is_cancellable = progress.is_cancellable;
10021                        }
10022                        did_update = true;
10023                    }
10024                }
10025            }
10026        }
10027
10028        if did_update {
10029            cx.emit(LspStoreEvent::LanguageServerUpdate {
10030                language_server_id,
10031                name: self
10032                    .language_server_adapter_for_id(language_server_id)
10033                    .map(|adapter| adapter.name()),
10034                message: proto::update_language_server::Variant::WorkProgress(
10035                    proto::LspWorkProgress {
10036                        token: Some(token.to_proto()),
10037                        message: progress.message,
10038                        percentage: progress.percentage.map(|p| p as u32),
10039                        is_cancellable: Some(progress.is_cancellable),
10040                    },
10041                ),
10042            })
10043        }
10044    }
10045
10046    fn on_lsp_work_end(
10047        &mut self,
10048        language_server_id: LanguageServerId,
10049        token: ProgressToken,
10050        cx: &mut Context<Self>,
10051    ) {
10052        if let Some(status) = self.language_server_statuses.get_mut(&language_server_id) {
10053            if let Some(work) = status.pending_work.remove(&token)
10054                && !work.is_disk_based_diagnostics_progress
10055            {
10056                cx.emit(LspStoreEvent::RefreshInlayHints {
10057                    server_id: language_server_id,
10058                    request_id: None,
10059                });
10060            }
10061            cx.notify();
10062        }
10063
10064        cx.emit(LspStoreEvent::LanguageServerUpdate {
10065            language_server_id,
10066            name: self
10067                .language_server_adapter_for_id(language_server_id)
10068                .map(|adapter| adapter.name()),
10069            message: proto::update_language_server::Variant::WorkEnd(proto::LspWorkEnd {
10070                token: Some(token.to_proto()),
10071            }),
10072        })
10073    }
10074
10075    pub async fn handle_resolve_completion_documentation(
10076        this: Entity<Self>,
10077        envelope: TypedEnvelope<proto::ResolveCompletionDocumentation>,
10078        mut cx: AsyncApp,
10079    ) -> Result<proto::ResolveCompletionDocumentationResponse> {
10080        let lsp_completion = serde_json::from_slice(&envelope.payload.lsp_completion)?;
10081
10082        let completion = this
10083            .read_with(&cx, |this, cx| {
10084                let id = LanguageServerId(envelope.payload.language_server_id as usize);
10085                let server = this
10086                    .language_server_for_id(id)
10087                    .with_context(|| format!("No language server {id}"))?;
10088
10089                anyhow::Ok(cx.background_spawn(async move {
10090                    let can_resolve = server
10091                        .capabilities()
10092                        .completion_provider
10093                        .as_ref()
10094                        .and_then(|options| options.resolve_provider)
10095                        .unwrap_or(false);
10096                    if can_resolve {
10097                        server
10098                            .request::<lsp::request::ResolveCompletionItem>(lsp_completion)
10099                            .await
10100                            .into_response()
10101                            .context("resolve completion item")
10102                    } else {
10103                        anyhow::Ok(lsp_completion)
10104                    }
10105                }))
10106            })??
10107            .await?;
10108
10109        let mut documentation_is_markdown = false;
10110        let lsp_completion = serde_json::to_string(&completion)?.into_bytes();
10111        let documentation = match completion.documentation {
10112            Some(lsp::Documentation::String(text)) => text,
10113
10114            Some(lsp::Documentation::MarkupContent(lsp::MarkupContent { kind, value })) => {
10115                documentation_is_markdown = kind == lsp::MarkupKind::Markdown;
10116                value
10117            }
10118
10119            _ => String::new(),
10120        };
10121
10122        // If we have a new buffer_id, that means we're talking to a new client
10123        // and want to check for new text_edits in the completion too.
10124        let mut old_replace_start = None;
10125        let mut old_replace_end = None;
10126        let mut old_insert_start = None;
10127        let mut old_insert_end = None;
10128        let mut new_text = String::default();
10129        if let Ok(buffer_id) = BufferId::new(envelope.payload.buffer_id) {
10130            let buffer_snapshot = this.update(&mut cx, |this, cx| {
10131                let buffer = this.buffer_store.read(cx).get_existing(buffer_id)?;
10132                anyhow::Ok(buffer.read(cx).snapshot())
10133            })??;
10134
10135            if let Some(text_edit) = completion.text_edit.as_ref() {
10136                let edit = parse_completion_text_edit(text_edit, &buffer_snapshot);
10137
10138                if let Some(mut edit) = edit {
10139                    LineEnding::normalize(&mut edit.new_text);
10140
10141                    new_text = edit.new_text;
10142                    old_replace_start = Some(serialize_anchor(&edit.replace_range.start));
10143                    old_replace_end = Some(serialize_anchor(&edit.replace_range.end));
10144                    if let Some(insert_range) = edit.insert_range {
10145                        old_insert_start = Some(serialize_anchor(&insert_range.start));
10146                        old_insert_end = Some(serialize_anchor(&insert_range.end));
10147                    }
10148                }
10149            }
10150        }
10151
10152        Ok(proto::ResolveCompletionDocumentationResponse {
10153            documentation,
10154            documentation_is_markdown,
10155            old_replace_start,
10156            old_replace_end,
10157            new_text,
10158            lsp_completion,
10159            old_insert_start,
10160            old_insert_end,
10161        })
10162    }
10163
10164    async fn handle_on_type_formatting(
10165        this: Entity<Self>,
10166        envelope: TypedEnvelope<proto::OnTypeFormatting>,
10167        mut cx: AsyncApp,
10168    ) -> Result<proto::OnTypeFormattingResponse> {
10169        let on_type_formatting = this.update(&mut cx, |this, cx| {
10170            let buffer_id = BufferId::new(envelope.payload.buffer_id)?;
10171            let buffer = this.buffer_store.read(cx).get_existing(buffer_id)?;
10172            let position = envelope
10173                .payload
10174                .position
10175                .and_then(deserialize_anchor)
10176                .context("invalid position")?;
10177            anyhow::Ok(this.apply_on_type_formatting(
10178                buffer,
10179                position,
10180                envelope.payload.trigger.clone(),
10181                cx,
10182            ))
10183        })??;
10184
10185        let transaction = on_type_formatting
10186            .await?
10187            .as_ref()
10188            .map(language::proto::serialize_transaction);
10189        Ok(proto::OnTypeFormattingResponse { transaction })
10190    }
10191
10192    async fn handle_refresh_inlay_hints(
10193        lsp_store: Entity<Self>,
10194        envelope: TypedEnvelope<proto::RefreshInlayHints>,
10195        mut cx: AsyncApp,
10196    ) -> Result<proto::Ack> {
10197        lsp_store.update(&mut cx, |_, cx| {
10198            cx.emit(LspStoreEvent::RefreshInlayHints {
10199                server_id: LanguageServerId::from_proto(envelope.payload.server_id),
10200                request_id: envelope.payload.request_id.map(|id| id as usize),
10201            });
10202        })?;
10203        Ok(proto::Ack {})
10204    }
10205
10206    async fn handle_pull_workspace_diagnostics(
10207        lsp_store: Entity<Self>,
10208        envelope: TypedEnvelope<proto::PullWorkspaceDiagnostics>,
10209        mut cx: AsyncApp,
10210    ) -> Result<proto::Ack> {
10211        let server_id = LanguageServerId::from_proto(envelope.payload.server_id);
10212        lsp_store.update(&mut cx, |lsp_store, _| {
10213            lsp_store.pull_workspace_diagnostics(server_id);
10214        })?;
10215        Ok(proto::Ack {})
10216    }
10217
10218    async fn handle_get_color_presentation(
10219        lsp_store: Entity<Self>,
10220        envelope: TypedEnvelope<proto::GetColorPresentation>,
10221        mut cx: AsyncApp,
10222    ) -> Result<proto::GetColorPresentationResponse> {
10223        let buffer_id = BufferId::new(envelope.payload.buffer_id)?;
10224        let buffer = lsp_store.update(&mut cx, |lsp_store, cx| {
10225            lsp_store.buffer_store.read(cx).get_existing(buffer_id)
10226        })??;
10227
10228        let color = envelope
10229            .payload
10230            .color
10231            .context("invalid color resolve request")?;
10232        let start = color
10233            .lsp_range_start
10234            .context("invalid color resolve request")?;
10235        let end = color
10236            .lsp_range_end
10237            .context("invalid color resolve request")?;
10238
10239        let color = DocumentColor {
10240            lsp_range: lsp::Range {
10241                start: point_to_lsp(PointUtf16::new(start.row, start.column)),
10242                end: point_to_lsp(PointUtf16::new(end.row, end.column)),
10243            },
10244            color: lsp::Color {
10245                red: color.red,
10246                green: color.green,
10247                blue: color.blue,
10248                alpha: color.alpha,
10249            },
10250            resolved: false,
10251            color_presentations: Vec::new(),
10252        };
10253        let resolved_color = lsp_store
10254            .update(&mut cx, |lsp_store, cx| {
10255                lsp_store.resolve_color_presentation(
10256                    color,
10257                    buffer.clone(),
10258                    LanguageServerId(envelope.payload.server_id as usize),
10259                    cx,
10260                )
10261            })?
10262            .await
10263            .context("resolving color presentation")?;
10264
10265        Ok(proto::GetColorPresentationResponse {
10266            presentations: resolved_color
10267                .color_presentations
10268                .into_iter()
10269                .map(|presentation| proto::ColorPresentation {
10270                    label: presentation.label.to_string(),
10271                    text_edit: presentation.text_edit.map(serialize_lsp_edit),
10272                    additional_text_edits: presentation
10273                        .additional_text_edits
10274                        .into_iter()
10275                        .map(serialize_lsp_edit)
10276                        .collect(),
10277                })
10278                .collect(),
10279        })
10280    }
10281
10282    async fn handle_resolve_inlay_hint(
10283        lsp_store: Entity<Self>,
10284        envelope: TypedEnvelope<proto::ResolveInlayHint>,
10285        mut cx: AsyncApp,
10286    ) -> Result<proto::ResolveInlayHintResponse> {
10287        let proto_hint = envelope
10288            .payload
10289            .hint
10290            .expect("incorrect protobuf resolve inlay hint message: missing the inlay hint");
10291        let hint = InlayHints::proto_to_project_hint(proto_hint)
10292            .context("resolved proto inlay hint conversion")?;
10293        let buffer = lsp_store.update(&mut cx, |lsp_store, cx| {
10294            let buffer_id = BufferId::new(envelope.payload.buffer_id)?;
10295            lsp_store.buffer_store.read(cx).get_existing(buffer_id)
10296        })??;
10297        let response_hint = lsp_store
10298            .update(&mut cx, |lsp_store, cx| {
10299                lsp_store.resolve_inlay_hint(
10300                    hint,
10301                    buffer,
10302                    LanguageServerId(envelope.payload.language_server_id as usize),
10303                    cx,
10304                )
10305            })?
10306            .await
10307            .context("inlay hints fetch")?;
10308        Ok(proto::ResolveInlayHintResponse {
10309            hint: Some(InlayHints::project_to_proto_hint(response_hint)),
10310        })
10311    }
10312
10313    async fn handle_refresh_code_lens(
10314        this: Entity<Self>,
10315        _: TypedEnvelope<proto::RefreshCodeLens>,
10316        mut cx: AsyncApp,
10317    ) -> Result<proto::Ack> {
10318        this.update(&mut cx, |_, cx| {
10319            cx.emit(LspStoreEvent::RefreshCodeLens);
10320        })?;
10321        Ok(proto::Ack {})
10322    }
10323
10324    async fn handle_open_buffer_for_symbol(
10325        this: Entity<Self>,
10326        envelope: TypedEnvelope<proto::OpenBufferForSymbol>,
10327        mut cx: AsyncApp,
10328    ) -> Result<proto::OpenBufferForSymbolResponse> {
10329        let peer_id = envelope.original_sender_id().unwrap_or_default();
10330        let symbol = envelope.payload.symbol.context("invalid symbol")?;
10331        let symbol = Self::deserialize_symbol(symbol)?;
10332        this.read_with(&cx, |this, _| {
10333            if let SymbolLocation::OutsideProject {
10334                abs_path,
10335                signature,
10336            } = &symbol.path
10337            {
10338                let new_signature = this.symbol_signature(&abs_path);
10339                anyhow::ensure!(&new_signature == signature, "invalid symbol signature");
10340            }
10341            Ok(())
10342        })??;
10343        let buffer = this
10344            .update(&mut cx, |this, cx| {
10345                this.open_buffer_for_symbol(
10346                    &Symbol {
10347                        language_server_name: symbol.language_server_name,
10348                        source_worktree_id: symbol.source_worktree_id,
10349                        source_language_server_id: symbol.source_language_server_id,
10350                        path: symbol.path,
10351                        name: symbol.name,
10352                        kind: symbol.kind,
10353                        range: symbol.range,
10354                        label: CodeLabel::default(),
10355                    },
10356                    cx,
10357                )
10358            })?
10359            .await?;
10360
10361        this.update(&mut cx, |this, cx| {
10362            let is_private = buffer
10363                .read(cx)
10364                .file()
10365                .map(|f| f.is_private())
10366                .unwrap_or_default();
10367            if is_private {
10368                Err(anyhow!(rpc::ErrorCode::UnsharedItem))
10369            } else {
10370                this.buffer_store
10371                    .update(cx, |buffer_store, cx| {
10372                        buffer_store.create_buffer_for_peer(&buffer, peer_id, cx)
10373                    })
10374                    .detach_and_log_err(cx);
10375                let buffer_id = buffer.read(cx).remote_id().to_proto();
10376                Ok(proto::OpenBufferForSymbolResponse { buffer_id })
10377            }
10378        })?
10379    }
10380
10381    fn symbol_signature(&self, abs_path: &Path) -> [u8; 32] {
10382        let mut hasher = Sha256::new();
10383        hasher.update(abs_path.to_string_lossy().as_bytes());
10384        hasher.update(self.nonce.to_be_bytes());
10385        hasher.finalize().as_slice().try_into().unwrap()
10386    }
10387
10388    pub async fn handle_get_project_symbols(
10389        this: Entity<Self>,
10390        envelope: TypedEnvelope<proto::GetProjectSymbols>,
10391        mut cx: AsyncApp,
10392    ) -> Result<proto::GetProjectSymbolsResponse> {
10393        let symbols = this
10394            .update(&mut cx, |this, cx| {
10395                this.symbols(&envelope.payload.query, cx)
10396            })?
10397            .await?;
10398
10399        Ok(proto::GetProjectSymbolsResponse {
10400            symbols: symbols.iter().map(Self::serialize_symbol).collect(),
10401        })
10402    }
10403
10404    pub async fn handle_restart_language_servers(
10405        this: Entity<Self>,
10406        envelope: TypedEnvelope<proto::RestartLanguageServers>,
10407        mut cx: AsyncApp,
10408    ) -> Result<proto::Ack> {
10409        this.update(&mut cx, |lsp_store, cx| {
10410            let buffers =
10411                lsp_store.buffer_ids_to_buffers(envelope.payload.buffer_ids.into_iter(), cx);
10412            lsp_store.restart_language_servers_for_buffers(
10413                buffers,
10414                envelope
10415                    .payload
10416                    .only_servers
10417                    .into_iter()
10418                    .filter_map(|selector| {
10419                        Some(match selector.selector? {
10420                            proto::language_server_selector::Selector::ServerId(server_id) => {
10421                                LanguageServerSelector::Id(LanguageServerId::from_proto(server_id))
10422                            }
10423                            proto::language_server_selector::Selector::Name(name) => {
10424                                LanguageServerSelector::Name(LanguageServerName(
10425                                    SharedString::from(name),
10426                                ))
10427                            }
10428                        })
10429                    })
10430                    .collect(),
10431                cx,
10432            );
10433        })?;
10434
10435        Ok(proto::Ack {})
10436    }
10437
10438    pub async fn handle_stop_language_servers(
10439        lsp_store: Entity<Self>,
10440        envelope: TypedEnvelope<proto::StopLanguageServers>,
10441        mut cx: AsyncApp,
10442    ) -> Result<proto::Ack> {
10443        lsp_store.update(&mut cx, |lsp_store, cx| {
10444            if envelope.payload.all
10445                && envelope.payload.also_servers.is_empty()
10446                && envelope.payload.buffer_ids.is_empty()
10447            {
10448                lsp_store.stop_all_language_servers(cx);
10449            } else {
10450                let buffers =
10451                    lsp_store.buffer_ids_to_buffers(envelope.payload.buffer_ids.into_iter(), cx);
10452                lsp_store
10453                    .stop_language_servers_for_buffers(
10454                        buffers,
10455                        envelope
10456                            .payload
10457                            .also_servers
10458                            .into_iter()
10459                            .filter_map(|selector| {
10460                                Some(match selector.selector? {
10461                                    proto::language_server_selector::Selector::ServerId(
10462                                        server_id,
10463                                    ) => LanguageServerSelector::Id(LanguageServerId::from_proto(
10464                                        server_id,
10465                                    )),
10466                                    proto::language_server_selector::Selector::Name(name) => {
10467                                        LanguageServerSelector::Name(LanguageServerName(
10468                                            SharedString::from(name),
10469                                        ))
10470                                    }
10471                                })
10472                            })
10473                            .collect(),
10474                        cx,
10475                    )
10476                    .detach_and_log_err(cx);
10477            }
10478        })?;
10479
10480        Ok(proto::Ack {})
10481    }
10482
10483    pub async fn handle_cancel_language_server_work(
10484        lsp_store: Entity<Self>,
10485        envelope: TypedEnvelope<proto::CancelLanguageServerWork>,
10486        mut cx: AsyncApp,
10487    ) -> Result<proto::Ack> {
10488        lsp_store.update(&mut cx, |lsp_store, cx| {
10489            if let Some(work) = envelope.payload.work {
10490                match work {
10491                    proto::cancel_language_server_work::Work::Buffers(buffers) => {
10492                        let buffers =
10493                            lsp_store.buffer_ids_to_buffers(buffers.buffer_ids.into_iter(), cx);
10494                        lsp_store.cancel_language_server_work_for_buffers(buffers, cx);
10495                    }
10496                    proto::cancel_language_server_work::Work::LanguageServerWork(work) => {
10497                        let server_id = LanguageServerId::from_proto(work.language_server_id);
10498                        let token = work
10499                            .token
10500                            .map(|token| {
10501                                ProgressToken::from_proto(token)
10502                                    .context("invalid work progress token")
10503                            })
10504                            .transpose()?;
10505                        lsp_store.cancel_language_server_work(server_id, token, cx);
10506                    }
10507                }
10508            }
10509            anyhow::Ok(())
10510        })??;
10511
10512        Ok(proto::Ack {})
10513    }
10514
10515    fn buffer_ids_to_buffers(
10516        &mut self,
10517        buffer_ids: impl Iterator<Item = u64>,
10518        cx: &mut Context<Self>,
10519    ) -> Vec<Entity<Buffer>> {
10520        buffer_ids
10521            .into_iter()
10522            .flat_map(|buffer_id| {
10523                self.buffer_store
10524                    .read(cx)
10525                    .get(BufferId::new(buffer_id).log_err()?)
10526            })
10527            .collect::<Vec<_>>()
10528    }
10529
10530    async fn handle_apply_additional_edits_for_completion(
10531        this: Entity<Self>,
10532        envelope: TypedEnvelope<proto::ApplyCompletionAdditionalEdits>,
10533        mut cx: AsyncApp,
10534    ) -> Result<proto::ApplyCompletionAdditionalEditsResponse> {
10535        let (buffer, completion) = this.update(&mut cx, |this, cx| {
10536            let buffer_id = BufferId::new(envelope.payload.buffer_id)?;
10537            let buffer = this.buffer_store.read(cx).get_existing(buffer_id)?;
10538            let completion = Self::deserialize_completion(
10539                envelope.payload.completion.context("invalid completion")?,
10540            )?;
10541            anyhow::Ok((buffer, completion))
10542        })??;
10543
10544        let apply_additional_edits = this.update(&mut cx, |this, cx| {
10545            this.apply_additional_edits_for_completion(
10546                buffer,
10547                Rc::new(RefCell::new(Box::new([Completion {
10548                    replace_range: completion.replace_range,
10549                    new_text: completion.new_text,
10550                    source: completion.source,
10551                    documentation: None,
10552                    label: CodeLabel::default(),
10553                    match_start: None,
10554                    snippet_deduplication_key: None,
10555                    insert_text_mode: None,
10556                    icon_path: None,
10557                    confirm: None,
10558                }]))),
10559                0,
10560                false,
10561                cx,
10562            )
10563        })?;
10564
10565        Ok(proto::ApplyCompletionAdditionalEditsResponse {
10566            transaction: apply_additional_edits
10567                .await?
10568                .as_ref()
10569                .map(language::proto::serialize_transaction),
10570        })
10571    }
10572
10573    pub fn last_formatting_failure(&self) -> Option<&str> {
10574        self.last_formatting_failure.as_deref()
10575    }
10576
10577    pub fn reset_last_formatting_failure(&mut self) {
10578        self.last_formatting_failure = None;
10579    }
10580
10581    pub fn environment_for_buffer(
10582        &self,
10583        buffer: &Entity<Buffer>,
10584        cx: &mut Context<Self>,
10585    ) -> Shared<Task<Option<HashMap<String, String>>>> {
10586        if let Some(environment) = &self.as_local().map(|local| local.environment.clone()) {
10587            environment.update(cx, |env, cx| {
10588                env.buffer_environment(buffer, &self.worktree_store, cx)
10589            })
10590        } else {
10591            Task::ready(None).shared()
10592        }
10593    }
10594
10595    pub fn format(
10596        &mut self,
10597        buffers: HashSet<Entity<Buffer>>,
10598        target: LspFormatTarget,
10599        push_to_history: bool,
10600        trigger: FormatTrigger,
10601        cx: &mut Context<Self>,
10602    ) -> Task<anyhow::Result<ProjectTransaction>> {
10603        let logger = zlog::scoped!("format");
10604        if self.as_local().is_some() {
10605            zlog::trace!(logger => "Formatting locally");
10606            let logger = zlog::scoped!(logger => "local");
10607            let buffers = buffers
10608                .into_iter()
10609                .map(|buffer_handle| {
10610                    let buffer = buffer_handle.read(cx);
10611                    let buffer_abs_path = File::from_dyn(buffer.file())
10612                        .and_then(|file| file.as_local().map(|f| f.abs_path(cx)));
10613
10614                    (buffer_handle, buffer_abs_path, buffer.remote_id())
10615                })
10616                .collect::<Vec<_>>();
10617
10618            cx.spawn(async move |lsp_store, cx| {
10619                let mut formattable_buffers = Vec::with_capacity(buffers.len());
10620
10621                for (handle, abs_path, id) in buffers {
10622                    let env = lsp_store
10623                        .update(cx, |lsp_store, cx| {
10624                            lsp_store.environment_for_buffer(&handle, cx)
10625                        })?
10626                        .await;
10627
10628                    let ranges = match &target {
10629                        LspFormatTarget::Buffers => None,
10630                        LspFormatTarget::Ranges(ranges) => {
10631                            Some(ranges.get(&id).context("No format ranges provided for buffer")?.clone())
10632                        }
10633                    };
10634
10635                    formattable_buffers.push(FormattableBuffer {
10636                        handle,
10637                        abs_path,
10638                        env,
10639                        ranges,
10640                    });
10641                }
10642                zlog::trace!(logger => "Formatting {:?} buffers", formattable_buffers.len());
10643
10644                let format_timer = zlog::time!(logger => "Formatting buffers");
10645                let result = LocalLspStore::format_locally(
10646                    lsp_store.clone(),
10647                    formattable_buffers,
10648                    push_to_history,
10649                    trigger,
10650                    logger,
10651                    cx,
10652                )
10653                .await;
10654                format_timer.end();
10655
10656                zlog::trace!(logger => "Formatting completed with result {:?}", result.as_ref().map(|_| "<project-transaction>"));
10657
10658                lsp_store.update(cx, |lsp_store, _| {
10659                    lsp_store.update_last_formatting_failure(&result);
10660                })?;
10661
10662                result
10663            })
10664        } else if let Some((client, project_id)) = self.upstream_client() {
10665            zlog::trace!(logger => "Formatting remotely");
10666            let logger = zlog::scoped!(logger => "remote");
10667            // Don't support formatting ranges via remote
10668            match target {
10669                LspFormatTarget::Buffers => {}
10670                LspFormatTarget::Ranges(_) => {
10671                    zlog::trace!(logger => "Ignoring unsupported remote range formatting request");
10672                    return Task::ready(Ok(ProjectTransaction::default()));
10673                }
10674            }
10675
10676            let buffer_store = self.buffer_store();
10677            cx.spawn(async move |lsp_store, cx| {
10678                zlog::trace!(logger => "Sending remote format request");
10679                let request_timer = zlog::time!(logger => "remote format request");
10680                let result = client
10681                    .request(proto::FormatBuffers {
10682                        project_id,
10683                        trigger: trigger as i32,
10684                        buffer_ids: buffers
10685                            .iter()
10686                            .map(|buffer| buffer.read_with(cx, |buffer, _| buffer.remote_id().into()))
10687                            .collect::<Result<_>>()?,
10688                    })
10689                    .await
10690                    .and_then(|result| result.transaction.context("missing transaction"));
10691                request_timer.end();
10692
10693                zlog::trace!(logger => "Remote format request resolved to {:?}", result.as_ref().map(|_| "<project_transaction>"));
10694
10695                lsp_store.update(cx, |lsp_store, _| {
10696                    lsp_store.update_last_formatting_failure(&result);
10697                })?;
10698
10699                let transaction_response = result?;
10700                let _timer = zlog::time!(logger => "deserializing project transaction");
10701                buffer_store
10702                    .update(cx, |buffer_store, cx| {
10703                        buffer_store.deserialize_project_transaction(
10704                            transaction_response,
10705                            push_to_history,
10706                            cx,
10707                        )
10708                    })?
10709                    .await
10710            })
10711        } else {
10712            zlog::trace!(logger => "Not formatting");
10713            Task::ready(Ok(ProjectTransaction::default()))
10714        }
10715    }
10716
10717    async fn handle_format_buffers(
10718        this: Entity<Self>,
10719        envelope: TypedEnvelope<proto::FormatBuffers>,
10720        mut cx: AsyncApp,
10721    ) -> Result<proto::FormatBuffersResponse> {
10722        let sender_id = envelope.original_sender_id().unwrap_or_default();
10723        let format = this.update(&mut cx, |this, cx| {
10724            let mut buffers = HashSet::default();
10725            for buffer_id in &envelope.payload.buffer_ids {
10726                let buffer_id = BufferId::new(*buffer_id)?;
10727                buffers.insert(this.buffer_store.read(cx).get_existing(buffer_id)?);
10728            }
10729            let trigger = FormatTrigger::from_proto(envelope.payload.trigger);
10730            anyhow::Ok(this.format(buffers, LspFormatTarget::Buffers, false, trigger, cx))
10731        })??;
10732
10733        let project_transaction = format.await?;
10734        let project_transaction = this.update(&mut cx, |this, cx| {
10735            this.buffer_store.update(cx, |buffer_store, cx| {
10736                buffer_store.serialize_project_transaction_for_peer(
10737                    project_transaction,
10738                    sender_id,
10739                    cx,
10740                )
10741            })
10742        })?;
10743        Ok(proto::FormatBuffersResponse {
10744            transaction: Some(project_transaction),
10745        })
10746    }
10747
10748    async fn handle_apply_code_action_kind(
10749        this: Entity<Self>,
10750        envelope: TypedEnvelope<proto::ApplyCodeActionKind>,
10751        mut cx: AsyncApp,
10752    ) -> Result<proto::ApplyCodeActionKindResponse> {
10753        let sender_id = envelope.original_sender_id().unwrap_or_default();
10754        let format = this.update(&mut cx, |this, cx| {
10755            let mut buffers = HashSet::default();
10756            for buffer_id in &envelope.payload.buffer_ids {
10757                let buffer_id = BufferId::new(*buffer_id)?;
10758                buffers.insert(this.buffer_store.read(cx).get_existing(buffer_id)?);
10759            }
10760            let kind = match envelope.payload.kind.as_str() {
10761                "" => CodeActionKind::EMPTY,
10762                "quickfix" => CodeActionKind::QUICKFIX,
10763                "refactor" => CodeActionKind::REFACTOR,
10764                "refactor.extract" => CodeActionKind::REFACTOR_EXTRACT,
10765                "refactor.inline" => CodeActionKind::REFACTOR_INLINE,
10766                "refactor.rewrite" => CodeActionKind::REFACTOR_REWRITE,
10767                "source" => CodeActionKind::SOURCE,
10768                "source.organizeImports" => CodeActionKind::SOURCE_ORGANIZE_IMPORTS,
10769                "source.fixAll" => CodeActionKind::SOURCE_FIX_ALL,
10770                _ => anyhow::bail!(
10771                    "Invalid code action kind {}",
10772                    envelope.payload.kind.as_str()
10773                ),
10774            };
10775            anyhow::Ok(this.apply_code_action_kind(buffers, kind, false, cx))
10776        })??;
10777
10778        let project_transaction = format.await?;
10779        let project_transaction = this.update(&mut cx, |this, cx| {
10780            this.buffer_store.update(cx, |buffer_store, cx| {
10781                buffer_store.serialize_project_transaction_for_peer(
10782                    project_transaction,
10783                    sender_id,
10784                    cx,
10785                )
10786            })
10787        })?;
10788        Ok(proto::ApplyCodeActionKindResponse {
10789            transaction: Some(project_transaction),
10790        })
10791    }
10792
10793    async fn shutdown_language_server(
10794        server_state: Option<LanguageServerState>,
10795        name: LanguageServerName,
10796        cx: &mut AsyncApp,
10797    ) {
10798        let server = match server_state {
10799            Some(LanguageServerState::Starting { startup, .. }) => {
10800                let mut timer = cx
10801                    .background_executor()
10802                    .timer(SERVER_LAUNCHING_BEFORE_SHUTDOWN_TIMEOUT)
10803                    .fuse();
10804
10805                select! {
10806                    server = startup.fuse() => server,
10807                    () = timer => {
10808                        log::info!("timeout waiting for language server {name} to finish launching before stopping");
10809                        None
10810                    },
10811                }
10812            }
10813
10814            Some(LanguageServerState::Running { server, .. }) => Some(server),
10815
10816            None => None,
10817        };
10818
10819        if let Some(server) = server
10820            && let Some(shutdown) = server.shutdown()
10821        {
10822            shutdown.await;
10823        }
10824    }
10825
10826    // Returns a list of all of the worktrees which no longer have a language server and the root path
10827    // for the stopped server
10828    fn stop_local_language_server(
10829        &mut self,
10830        server_id: LanguageServerId,
10831        cx: &mut Context<Self>,
10832    ) -> Task<()> {
10833        let local = match &mut self.mode {
10834            LspStoreMode::Local(local) => local,
10835            _ => {
10836                return Task::ready(());
10837            }
10838        };
10839
10840        // Remove this server ID from all entries in the given worktree.
10841        local
10842            .language_server_ids
10843            .retain(|_, state| state.id != server_id);
10844        self.buffer_store.update(cx, |buffer_store, cx| {
10845            for buffer in buffer_store.buffers() {
10846                buffer.update(cx, |buffer, cx| {
10847                    buffer.update_diagnostics(server_id, DiagnosticSet::new([], buffer), cx);
10848                    buffer.set_completion_triggers(server_id, Default::default(), cx);
10849                });
10850            }
10851        });
10852
10853        for (worktree_id, summaries) in self.diagnostic_summaries.iter_mut() {
10854            summaries.retain(|path, summaries_by_server_id| {
10855                if summaries_by_server_id.remove(&server_id).is_some() {
10856                    if let Some((client, project_id)) = self.downstream_client.clone() {
10857                        client
10858                            .send(proto::UpdateDiagnosticSummary {
10859                                project_id,
10860                                worktree_id: worktree_id.to_proto(),
10861                                summary: Some(proto::DiagnosticSummary {
10862                                    path: path.as_ref().to_proto(),
10863                                    language_server_id: server_id.0 as u64,
10864                                    error_count: 0,
10865                                    warning_count: 0,
10866                                }),
10867                                more_summaries: Vec::new(),
10868                            })
10869                            .log_err();
10870                    }
10871                    !summaries_by_server_id.is_empty()
10872                } else {
10873                    true
10874                }
10875            });
10876        }
10877
10878        let local = self.as_local_mut().unwrap();
10879        for diagnostics in local.diagnostics.values_mut() {
10880            diagnostics.retain(|_, diagnostics_by_server_id| {
10881                if let Ok(ix) = diagnostics_by_server_id.binary_search_by_key(&server_id, |e| e.0) {
10882                    diagnostics_by_server_id.remove(ix);
10883                    !diagnostics_by_server_id.is_empty()
10884                } else {
10885                    true
10886                }
10887            });
10888        }
10889        local.language_server_watched_paths.remove(&server_id);
10890
10891        let server_state = local.language_servers.remove(&server_id);
10892        self.cleanup_lsp_data(server_id);
10893        let name = self
10894            .language_server_statuses
10895            .remove(&server_id)
10896            .map(|status| status.name)
10897            .or_else(|| {
10898                if let Some(LanguageServerState::Running { adapter, .. }) = server_state.as_ref() {
10899                    Some(adapter.name())
10900                } else {
10901                    None
10902                }
10903            });
10904
10905        if let Some(name) = name {
10906            log::info!("stopping language server {name}");
10907            self.languages
10908                .update_lsp_binary_status(name.clone(), BinaryStatus::Stopping);
10909            cx.notify();
10910
10911            return cx.spawn(async move |lsp_store, cx| {
10912                Self::shutdown_language_server(server_state, name.clone(), cx).await;
10913                lsp_store
10914                    .update(cx, |lsp_store, cx| {
10915                        lsp_store
10916                            .languages
10917                            .update_lsp_binary_status(name, BinaryStatus::Stopped);
10918                        cx.emit(LspStoreEvent::LanguageServerRemoved(server_id));
10919                        cx.notify();
10920                    })
10921                    .ok();
10922            });
10923        }
10924
10925        if server_state.is_some() {
10926            cx.emit(LspStoreEvent::LanguageServerRemoved(server_id));
10927        }
10928        Task::ready(())
10929    }
10930
10931    pub fn stop_all_language_servers(&mut self, cx: &mut Context<Self>) {
10932        if let Some((client, project_id)) = self.upstream_client() {
10933            let request = client.request(proto::StopLanguageServers {
10934                project_id,
10935                buffer_ids: Vec::new(),
10936                also_servers: Vec::new(),
10937                all: true,
10938            });
10939            cx.background_spawn(request).detach_and_log_err(cx);
10940        } else {
10941            let Some(local) = self.as_local_mut() else {
10942                return;
10943            };
10944            let language_servers_to_stop = local
10945                .language_server_ids
10946                .values()
10947                .map(|state| state.id)
10948                .collect();
10949            local.lsp_tree.remove_nodes(&language_servers_to_stop);
10950            let tasks = language_servers_to_stop
10951                .into_iter()
10952                .map(|server| self.stop_local_language_server(server, cx))
10953                .collect::<Vec<_>>();
10954            cx.background_spawn(async move {
10955                futures::future::join_all(tasks).await;
10956            })
10957            .detach();
10958        }
10959    }
10960
10961    pub fn restart_language_servers_for_buffers(
10962        &mut self,
10963        buffers: Vec<Entity<Buffer>>,
10964        only_restart_servers: HashSet<LanguageServerSelector>,
10965        cx: &mut Context<Self>,
10966    ) {
10967        if let Some((client, project_id)) = self.upstream_client() {
10968            let request = client.request(proto::RestartLanguageServers {
10969                project_id,
10970                buffer_ids: buffers
10971                    .into_iter()
10972                    .map(|b| b.read(cx).remote_id().to_proto())
10973                    .collect(),
10974                only_servers: only_restart_servers
10975                    .into_iter()
10976                    .map(|selector| {
10977                        let selector = match selector {
10978                            LanguageServerSelector::Id(language_server_id) => {
10979                                proto::language_server_selector::Selector::ServerId(
10980                                    language_server_id.to_proto(),
10981                                )
10982                            }
10983                            LanguageServerSelector::Name(language_server_name) => {
10984                                proto::language_server_selector::Selector::Name(
10985                                    language_server_name.to_string(),
10986                                )
10987                            }
10988                        };
10989                        proto::LanguageServerSelector {
10990                            selector: Some(selector),
10991                        }
10992                    })
10993                    .collect(),
10994                all: false,
10995            });
10996            cx.background_spawn(request).detach_and_log_err(cx);
10997        } else {
10998            let stop_task = if only_restart_servers.is_empty() {
10999                self.stop_local_language_servers_for_buffers(&buffers, HashSet::default(), cx)
11000            } else {
11001                self.stop_local_language_servers_for_buffers(&[], only_restart_servers.clone(), cx)
11002            };
11003            cx.spawn(async move |lsp_store, cx| {
11004                stop_task.await;
11005                lsp_store
11006                    .update(cx, |lsp_store, cx| {
11007                        for buffer in buffers {
11008                            lsp_store.register_buffer_with_language_servers(
11009                                &buffer,
11010                                only_restart_servers.clone(),
11011                                true,
11012                                cx,
11013                            );
11014                        }
11015                    })
11016                    .ok()
11017            })
11018            .detach();
11019        }
11020    }
11021
11022    pub fn stop_language_servers_for_buffers(
11023        &mut self,
11024        buffers: Vec<Entity<Buffer>>,
11025        also_stop_servers: HashSet<LanguageServerSelector>,
11026        cx: &mut Context<Self>,
11027    ) -> Task<Result<()>> {
11028        if let Some((client, project_id)) = self.upstream_client() {
11029            let request = client.request(proto::StopLanguageServers {
11030                project_id,
11031                buffer_ids: buffers
11032                    .into_iter()
11033                    .map(|b| b.read(cx).remote_id().to_proto())
11034                    .collect(),
11035                also_servers: also_stop_servers
11036                    .into_iter()
11037                    .map(|selector| {
11038                        let selector = match selector {
11039                            LanguageServerSelector::Id(language_server_id) => {
11040                                proto::language_server_selector::Selector::ServerId(
11041                                    language_server_id.to_proto(),
11042                                )
11043                            }
11044                            LanguageServerSelector::Name(language_server_name) => {
11045                                proto::language_server_selector::Selector::Name(
11046                                    language_server_name.to_string(),
11047                                )
11048                            }
11049                        };
11050                        proto::LanguageServerSelector {
11051                            selector: Some(selector),
11052                        }
11053                    })
11054                    .collect(),
11055                all: false,
11056            });
11057            cx.background_spawn(async move {
11058                let _ = request.await?;
11059                Ok(())
11060            })
11061        } else {
11062            let task =
11063                self.stop_local_language_servers_for_buffers(&buffers, also_stop_servers, cx);
11064            cx.background_spawn(async move {
11065                task.await;
11066                Ok(())
11067            })
11068        }
11069    }
11070
11071    fn stop_local_language_servers_for_buffers(
11072        &mut self,
11073        buffers: &[Entity<Buffer>],
11074        also_stop_servers: HashSet<LanguageServerSelector>,
11075        cx: &mut Context<Self>,
11076    ) -> Task<()> {
11077        let Some(local) = self.as_local_mut() else {
11078            return Task::ready(());
11079        };
11080        let mut language_server_names_to_stop = BTreeSet::default();
11081        let mut language_servers_to_stop = also_stop_servers
11082            .into_iter()
11083            .flat_map(|selector| match selector {
11084                LanguageServerSelector::Id(id) => Some(id),
11085                LanguageServerSelector::Name(name) => {
11086                    language_server_names_to_stop.insert(name);
11087                    None
11088                }
11089            })
11090            .collect::<BTreeSet<_>>();
11091
11092        let mut covered_worktrees = HashSet::default();
11093        for buffer in buffers {
11094            buffer.update(cx, |buffer, cx| {
11095                language_servers_to_stop.extend(local.language_server_ids_for_buffer(buffer, cx));
11096                if let Some(worktree_id) = buffer.file().map(|f| f.worktree_id(cx))
11097                    && covered_worktrees.insert(worktree_id)
11098                {
11099                    language_server_names_to_stop.retain(|name| {
11100                        let old_ids_count = language_servers_to_stop.len();
11101                        let all_language_servers_with_this_name = local
11102                            .language_server_ids
11103                            .iter()
11104                            .filter_map(|(seed, state)| seed.name.eq(name).then(|| state.id));
11105                        language_servers_to_stop.extend(all_language_servers_with_this_name);
11106                        old_ids_count == language_servers_to_stop.len()
11107                    });
11108                }
11109            });
11110        }
11111        for name in language_server_names_to_stop {
11112            language_servers_to_stop.extend(
11113                local
11114                    .language_server_ids
11115                    .iter()
11116                    .filter_map(|(seed, v)| seed.name.eq(&name).then(|| v.id)),
11117            );
11118        }
11119
11120        local.lsp_tree.remove_nodes(&language_servers_to_stop);
11121        let tasks = language_servers_to_stop
11122            .into_iter()
11123            .map(|server| self.stop_local_language_server(server, cx))
11124            .collect::<Vec<_>>();
11125
11126        cx.background_spawn(futures::future::join_all(tasks).map(|_| ()))
11127    }
11128
11129    fn get_buffer<'a>(&self, abs_path: &Path, cx: &'a App) -> Option<&'a Buffer> {
11130        let (worktree, relative_path) =
11131            self.worktree_store.read(cx).find_worktree(&abs_path, cx)?;
11132
11133        let project_path = ProjectPath {
11134            worktree_id: worktree.read(cx).id(),
11135            path: relative_path,
11136        };
11137
11138        Some(
11139            self.buffer_store()
11140                .read(cx)
11141                .get_by_path(&project_path)?
11142                .read(cx),
11143        )
11144    }
11145
11146    #[cfg(any(test, feature = "test-support"))]
11147    pub fn update_diagnostics(
11148        &mut self,
11149        server_id: LanguageServerId,
11150        diagnostics: lsp::PublishDiagnosticsParams,
11151        result_id: Option<SharedString>,
11152        source_kind: DiagnosticSourceKind,
11153        disk_based_sources: &[String],
11154        cx: &mut Context<Self>,
11155    ) -> Result<()> {
11156        self.merge_lsp_diagnostics(
11157            source_kind,
11158            vec![DocumentDiagnosticsUpdate {
11159                diagnostics,
11160                result_id,
11161                server_id,
11162                disk_based_sources: Cow::Borrowed(disk_based_sources),
11163                registration_id: None,
11164            }],
11165            |_, _, _| false,
11166            cx,
11167        )
11168    }
11169
11170    pub fn merge_lsp_diagnostics(
11171        &mut self,
11172        source_kind: DiagnosticSourceKind,
11173        lsp_diagnostics: Vec<DocumentDiagnosticsUpdate<lsp::PublishDiagnosticsParams>>,
11174        merge: impl Fn(&lsp::Uri, &Diagnostic, &App) -> bool + Clone,
11175        cx: &mut Context<Self>,
11176    ) -> Result<()> {
11177        anyhow::ensure!(self.mode.is_local(), "called update_diagnostics on remote");
11178        let updates = lsp_diagnostics
11179            .into_iter()
11180            .filter_map(|update| {
11181                let abs_path = update.diagnostics.uri.to_file_path().ok()?;
11182                Some(DocumentDiagnosticsUpdate {
11183                    diagnostics: self.lsp_to_document_diagnostics(
11184                        abs_path,
11185                        source_kind,
11186                        update.server_id,
11187                        update.diagnostics,
11188                        &update.disk_based_sources,
11189                        update.registration_id.clone(),
11190                    ),
11191                    result_id: update.result_id,
11192                    server_id: update.server_id,
11193                    disk_based_sources: update.disk_based_sources,
11194                    registration_id: update.registration_id,
11195                })
11196            })
11197            .collect();
11198        self.merge_diagnostic_entries(updates, merge, cx)?;
11199        Ok(())
11200    }
11201
11202    fn lsp_to_document_diagnostics(
11203        &mut self,
11204        document_abs_path: PathBuf,
11205        source_kind: DiagnosticSourceKind,
11206        server_id: LanguageServerId,
11207        mut lsp_diagnostics: lsp::PublishDiagnosticsParams,
11208        disk_based_sources: &[String],
11209        registration_id: Option<SharedString>,
11210    ) -> DocumentDiagnostics {
11211        let mut diagnostics = Vec::default();
11212        let mut primary_diagnostic_group_ids = HashMap::default();
11213        let mut sources_by_group_id = HashMap::default();
11214        let mut supporting_diagnostics = HashMap::default();
11215
11216        let adapter = self.language_server_adapter_for_id(server_id);
11217
11218        // Ensure that primary diagnostics are always the most severe
11219        lsp_diagnostics
11220            .diagnostics
11221            .sort_by_key(|item| item.severity);
11222
11223        for diagnostic in &lsp_diagnostics.diagnostics {
11224            let source = diagnostic.source.as_ref();
11225            let range = range_from_lsp(diagnostic.range);
11226            let is_supporting = diagnostic
11227                .related_information
11228                .as_ref()
11229                .is_some_and(|infos| {
11230                    infos.iter().any(|info| {
11231                        primary_diagnostic_group_ids.contains_key(&(
11232                            source,
11233                            diagnostic.code.clone(),
11234                            range_from_lsp(info.location.range),
11235                        ))
11236                    })
11237                });
11238
11239            let is_unnecessary = diagnostic
11240                .tags
11241                .as_ref()
11242                .is_some_and(|tags| tags.contains(&DiagnosticTag::UNNECESSARY));
11243
11244            let underline = self
11245                .language_server_adapter_for_id(server_id)
11246                .is_none_or(|adapter| adapter.underline_diagnostic(diagnostic));
11247
11248            if is_supporting {
11249                supporting_diagnostics.insert(
11250                    (source, diagnostic.code.clone(), range),
11251                    (diagnostic.severity, is_unnecessary),
11252                );
11253            } else {
11254                let group_id = post_inc(&mut self.as_local_mut().unwrap().next_diagnostic_group_id);
11255                let is_disk_based =
11256                    source.is_some_and(|source| disk_based_sources.contains(source));
11257
11258                sources_by_group_id.insert(group_id, source);
11259                primary_diagnostic_group_ids
11260                    .insert((source, diagnostic.code.clone(), range.clone()), group_id);
11261
11262                diagnostics.push(DiagnosticEntry {
11263                    range,
11264                    diagnostic: Diagnostic {
11265                        source: diagnostic.source.clone(),
11266                        source_kind,
11267                        code: diagnostic.code.clone(),
11268                        code_description: diagnostic
11269                            .code_description
11270                            .as_ref()
11271                            .and_then(|d| d.href.clone()),
11272                        severity: diagnostic.severity.unwrap_or(DiagnosticSeverity::ERROR),
11273                        markdown: adapter.as_ref().and_then(|adapter| {
11274                            adapter.diagnostic_message_to_markdown(&diagnostic.message)
11275                        }),
11276                        message: diagnostic.message.trim().to_string(),
11277                        group_id,
11278                        is_primary: true,
11279                        is_disk_based,
11280                        is_unnecessary,
11281                        underline,
11282                        data: diagnostic.data.clone(),
11283                        registration_id: registration_id.clone(),
11284                    },
11285                });
11286                if let Some(infos) = &diagnostic.related_information {
11287                    for info in infos {
11288                        if info.location.uri == lsp_diagnostics.uri && !info.message.is_empty() {
11289                            let range = range_from_lsp(info.location.range);
11290                            diagnostics.push(DiagnosticEntry {
11291                                range,
11292                                diagnostic: Diagnostic {
11293                                    source: diagnostic.source.clone(),
11294                                    source_kind,
11295                                    code: diagnostic.code.clone(),
11296                                    code_description: diagnostic
11297                                        .code_description
11298                                        .as_ref()
11299                                        .and_then(|d| d.href.clone()),
11300                                    severity: DiagnosticSeverity::INFORMATION,
11301                                    markdown: adapter.as_ref().and_then(|adapter| {
11302                                        adapter.diagnostic_message_to_markdown(&info.message)
11303                                    }),
11304                                    message: info.message.trim().to_string(),
11305                                    group_id,
11306                                    is_primary: false,
11307                                    is_disk_based,
11308                                    is_unnecessary: false,
11309                                    underline,
11310                                    data: diagnostic.data.clone(),
11311                                    registration_id: registration_id.clone(),
11312                                },
11313                            });
11314                        }
11315                    }
11316                }
11317            }
11318        }
11319
11320        for entry in &mut diagnostics {
11321            let diagnostic = &mut entry.diagnostic;
11322            if !diagnostic.is_primary {
11323                let source = *sources_by_group_id.get(&diagnostic.group_id).unwrap();
11324                if let Some(&(severity, is_unnecessary)) = supporting_diagnostics.get(&(
11325                    source,
11326                    diagnostic.code.clone(),
11327                    entry.range.clone(),
11328                )) {
11329                    if let Some(severity) = severity {
11330                        diagnostic.severity = severity;
11331                    }
11332                    diagnostic.is_unnecessary = is_unnecessary;
11333                }
11334            }
11335        }
11336
11337        DocumentDiagnostics {
11338            diagnostics,
11339            document_abs_path,
11340            version: lsp_diagnostics.version,
11341        }
11342    }
11343
11344    fn insert_newly_running_language_server(
11345        &mut self,
11346        adapter: Arc<CachedLspAdapter>,
11347        language_server: Arc<LanguageServer>,
11348        server_id: LanguageServerId,
11349        key: LanguageServerSeed,
11350        workspace_folders: Arc<Mutex<BTreeSet<Uri>>>,
11351        cx: &mut Context<Self>,
11352    ) {
11353        let Some(local) = self.as_local_mut() else {
11354            return;
11355        };
11356        // If the language server for this key doesn't match the server id, don't store the
11357        // server. Which will cause it to be dropped, killing the process
11358        if local
11359            .language_server_ids
11360            .get(&key)
11361            .map(|state| state.id != server_id)
11362            .unwrap_or(false)
11363        {
11364            return;
11365        }
11366
11367        // Update language_servers collection with Running variant of LanguageServerState
11368        // indicating that the server is up and running and ready
11369        let workspace_folders = workspace_folders.lock().clone();
11370        language_server.set_workspace_folders(workspace_folders);
11371
11372        let workspace_diagnostics_refresh_tasks = language_server
11373            .capabilities()
11374            .diagnostic_provider
11375            .and_then(|provider| {
11376                local
11377                    .language_server_dynamic_registrations
11378                    .entry(server_id)
11379                    .or_default()
11380                    .diagnostics
11381                    .entry(None)
11382                    .or_insert(provider.clone());
11383                let workspace_refresher =
11384                    lsp_workspace_diagnostics_refresh(None, provider, language_server.clone(), cx)?;
11385
11386                Some((None, workspace_refresher))
11387            })
11388            .into_iter()
11389            .collect();
11390        local.language_servers.insert(
11391            server_id,
11392            LanguageServerState::Running {
11393                workspace_diagnostics_refresh_tasks,
11394                adapter: adapter.clone(),
11395                server: language_server.clone(),
11396                simulate_disk_based_diagnostics_completion: None,
11397            },
11398        );
11399        local
11400            .languages
11401            .update_lsp_binary_status(adapter.name(), BinaryStatus::None);
11402        if let Some(file_ops_caps) = language_server
11403            .capabilities()
11404            .workspace
11405            .as_ref()
11406            .and_then(|ws| ws.file_operations.as_ref())
11407        {
11408            let did_rename_caps = file_ops_caps.did_rename.as_ref();
11409            let will_rename_caps = file_ops_caps.will_rename.as_ref();
11410            if did_rename_caps.or(will_rename_caps).is_some() {
11411                let watcher = RenamePathsWatchedForServer::default()
11412                    .with_did_rename_patterns(did_rename_caps)
11413                    .with_will_rename_patterns(will_rename_caps);
11414                local
11415                    .language_server_paths_watched_for_rename
11416                    .insert(server_id, watcher);
11417            }
11418        }
11419
11420        self.language_server_statuses.insert(
11421            server_id,
11422            LanguageServerStatus {
11423                name: language_server.name(),
11424                pending_work: Default::default(),
11425                has_pending_diagnostic_updates: false,
11426                progress_tokens: Default::default(),
11427                worktree: Some(key.worktree_id),
11428                binary: Some(language_server.binary().clone()),
11429                configuration: Some(language_server.configuration().clone()),
11430                workspace_folders: language_server.workspace_folders(),
11431            },
11432        );
11433
11434        cx.emit(LspStoreEvent::LanguageServerAdded(
11435            server_id,
11436            language_server.name(),
11437            Some(key.worktree_id),
11438        ));
11439
11440        let server_capabilities = language_server.capabilities();
11441        if let Some((downstream_client, project_id)) = self.downstream_client.as_ref() {
11442            downstream_client
11443                .send(proto::StartLanguageServer {
11444                    project_id: *project_id,
11445                    server: Some(proto::LanguageServer {
11446                        id: server_id.to_proto(),
11447                        name: language_server.name().to_string(),
11448                        worktree_id: Some(key.worktree_id.to_proto()),
11449                    }),
11450                    capabilities: serde_json::to_string(&server_capabilities)
11451                        .expect("serializing server LSP capabilities"),
11452                })
11453                .log_err();
11454        }
11455        self.lsp_server_capabilities
11456            .insert(server_id, server_capabilities);
11457
11458        // Tell the language server about every open buffer in the worktree that matches the language.
11459        // Also check for buffers in worktrees that reused this server
11460        let mut worktrees_using_server = vec![key.worktree_id];
11461        if let Some(local) = self.as_local() {
11462            // Find all worktrees that have this server in their language server tree
11463            for (worktree_id, servers) in &local.lsp_tree.instances {
11464                if *worktree_id != key.worktree_id {
11465                    for server_map in servers.roots.values() {
11466                        if server_map
11467                            .values()
11468                            .any(|(node, _)| node.id() == Some(server_id))
11469                        {
11470                            worktrees_using_server.push(*worktree_id);
11471                        }
11472                    }
11473                }
11474            }
11475        }
11476
11477        let mut buffer_paths_registered = Vec::new();
11478        self.buffer_store.clone().update(cx, |buffer_store, cx| {
11479            let mut lsp_adapters = HashMap::default();
11480            for buffer_handle in buffer_store.buffers() {
11481                let buffer = buffer_handle.read(cx);
11482                let file = match File::from_dyn(buffer.file()) {
11483                    Some(file) => file,
11484                    None => continue,
11485                };
11486                let language = match buffer.language() {
11487                    Some(language) => language,
11488                    None => continue,
11489                };
11490
11491                if !worktrees_using_server.contains(&file.worktree.read(cx).id())
11492                    || !lsp_adapters
11493                        .entry(language.name())
11494                        .or_insert_with(|| self.languages.lsp_adapters(&language.name()))
11495                        .iter()
11496                        .any(|a| a.name == key.name)
11497                {
11498                    continue;
11499                }
11500                // didOpen
11501                let file = match file.as_local() {
11502                    Some(file) => file,
11503                    None => continue,
11504                };
11505
11506                let local = self.as_local_mut().unwrap();
11507
11508                let buffer_id = buffer.remote_id();
11509                if local.registered_buffers.contains_key(&buffer_id) {
11510                    let versions = local
11511                        .buffer_snapshots
11512                        .entry(buffer_id)
11513                        .or_default()
11514                        .entry(server_id)
11515                        .and_modify(|_| {
11516                            assert!(
11517                            false,
11518                            "There should not be an existing snapshot for a newly inserted buffer"
11519                        )
11520                        })
11521                        .or_insert_with(|| {
11522                            vec![LspBufferSnapshot {
11523                                version: 0,
11524                                snapshot: buffer.text_snapshot(),
11525                            }]
11526                        });
11527
11528                    let snapshot = versions.last().unwrap();
11529                    let version = snapshot.version;
11530                    let initial_snapshot = &snapshot.snapshot;
11531                    let uri = lsp::Uri::from_file_path(file.abs_path(cx)).unwrap();
11532                    language_server.register_buffer(
11533                        uri,
11534                        adapter.language_id(&language.name()),
11535                        version,
11536                        initial_snapshot.text(),
11537                    );
11538                    buffer_paths_registered.push((buffer_id, file.abs_path(cx)));
11539                    local
11540                        .buffers_opened_in_servers
11541                        .entry(buffer_id)
11542                        .or_default()
11543                        .insert(server_id);
11544                }
11545                buffer_handle.update(cx, |buffer, cx| {
11546                    buffer.set_completion_triggers(
11547                        server_id,
11548                        language_server
11549                            .capabilities()
11550                            .completion_provider
11551                            .as_ref()
11552                            .and_then(|provider| {
11553                                provider
11554                                    .trigger_characters
11555                                    .as_ref()
11556                                    .map(|characters| characters.iter().cloned().collect())
11557                            })
11558                            .unwrap_or_default(),
11559                        cx,
11560                    )
11561                });
11562            }
11563        });
11564
11565        for (buffer_id, abs_path) in buffer_paths_registered {
11566            cx.emit(LspStoreEvent::LanguageServerUpdate {
11567                language_server_id: server_id,
11568                name: Some(adapter.name()),
11569                message: proto::update_language_server::Variant::RegisteredForBuffer(
11570                    proto::RegisteredForBuffer {
11571                        buffer_abs_path: abs_path.to_string_lossy().into_owned(),
11572                        buffer_id: buffer_id.to_proto(),
11573                    },
11574                ),
11575            });
11576        }
11577
11578        cx.notify();
11579    }
11580
11581    pub fn language_servers_running_disk_based_diagnostics(
11582        &self,
11583    ) -> impl Iterator<Item = LanguageServerId> + '_ {
11584        self.language_server_statuses
11585            .iter()
11586            .filter_map(|(id, status)| {
11587                if status.has_pending_diagnostic_updates {
11588                    Some(*id)
11589                } else {
11590                    None
11591                }
11592            })
11593    }
11594
11595    pub(crate) fn cancel_language_server_work_for_buffers(
11596        &mut self,
11597        buffers: impl IntoIterator<Item = Entity<Buffer>>,
11598        cx: &mut Context<Self>,
11599    ) {
11600        if let Some((client, project_id)) = self.upstream_client() {
11601            let request = client.request(proto::CancelLanguageServerWork {
11602                project_id,
11603                work: Some(proto::cancel_language_server_work::Work::Buffers(
11604                    proto::cancel_language_server_work::Buffers {
11605                        buffer_ids: buffers
11606                            .into_iter()
11607                            .map(|b| b.read(cx).remote_id().to_proto())
11608                            .collect(),
11609                    },
11610                )),
11611            });
11612            cx.background_spawn(request).detach_and_log_err(cx);
11613        } else if let Some(local) = self.as_local() {
11614            let servers = buffers
11615                .into_iter()
11616                .flat_map(|buffer| {
11617                    buffer.update(cx, |buffer, cx| {
11618                        local.language_server_ids_for_buffer(buffer, cx).into_iter()
11619                    })
11620                })
11621                .collect::<HashSet<_>>();
11622            for server_id in servers {
11623                self.cancel_language_server_work(server_id, None, cx);
11624            }
11625        }
11626    }
11627
11628    pub(crate) fn cancel_language_server_work(
11629        &mut self,
11630        server_id: LanguageServerId,
11631        token_to_cancel: Option<ProgressToken>,
11632        cx: &mut Context<Self>,
11633    ) {
11634        if let Some(local) = self.as_local() {
11635            let status = self.language_server_statuses.get(&server_id);
11636            let server = local.language_servers.get(&server_id);
11637            if let Some((LanguageServerState::Running { server, .. }, status)) = server.zip(status)
11638            {
11639                for (token, progress) in &status.pending_work {
11640                    if let Some(token_to_cancel) = token_to_cancel.as_ref()
11641                        && token != token_to_cancel
11642                    {
11643                        continue;
11644                    }
11645                    if progress.is_cancellable {
11646                        server
11647                            .notify::<lsp::notification::WorkDoneProgressCancel>(
11648                                WorkDoneProgressCancelParams {
11649                                    token: token.to_lsp(),
11650                                },
11651                            )
11652                            .ok();
11653                    }
11654                }
11655            }
11656        } else if let Some((client, project_id)) = self.upstream_client() {
11657            let request = client.request(proto::CancelLanguageServerWork {
11658                project_id,
11659                work: Some(
11660                    proto::cancel_language_server_work::Work::LanguageServerWork(
11661                        proto::cancel_language_server_work::LanguageServerWork {
11662                            language_server_id: server_id.to_proto(),
11663                            token: token_to_cancel.map(|token| token.to_proto()),
11664                        },
11665                    ),
11666                ),
11667            });
11668            cx.background_spawn(request).detach_and_log_err(cx);
11669        }
11670    }
11671
11672    fn register_supplementary_language_server(
11673        &mut self,
11674        id: LanguageServerId,
11675        name: LanguageServerName,
11676        server: Arc<LanguageServer>,
11677        cx: &mut Context<Self>,
11678    ) {
11679        if let Some(local) = self.as_local_mut() {
11680            local
11681                .supplementary_language_servers
11682                .insert(id, (name.clone(), server));
11683            cx.emit(LspStoreEvent::LanguageServerAdded(id, name, None));
11684        }
11685    }
11686
11687    fn unregister_supplementary_language_server(
11688        &mut self,
11689        id: LanguageServerId,
11690        cx: &mut Context<Self>,
11691    ) {
11692        if let Some(local) = self.as_local_mut() {
11693            local.supplementary_language_servers.remove(&id);
11694            cx.emit(LspStoreEvent::LanguageServerRemoved(id));
11695        }
11696    }
11697
11698    pub(crate) fn supplementary_language_servers(
11699        &self,
11700    ) -> impl '_ + Iterator<Item = (LanguageServerId, LanguageServerName)> {
11701        self.as_local().into_iter().flat_map(|local| {
11702            local
11703                .supplementary_language_servers
11704                .iter()
11705                .map(|(id, (name, _))| (*id, name.clone()))
11706        })
11707    }
11708
11709    pub fn language_server_adapter_for_id(
11710        &self,
11711        id: LanguageServerId,
11712    ) -> Option<Arc<CachedLspAdapter>> {
11713        self.as_local()
11714            .and_then(|local| local.language_servers.get(&id))
11715            .and_then(|language_server_state| match language_server_state {
11716                LanguageServerState::Running { adapter, .. } => Some(adapter.clone()),
11717                _ => None,
11718            })
11719    }
11720
11721    pub(super) fn update_local_worktree_language_servers(
11722        &mut self,
11723        worktree_handle: &Entity<Worktree>,
11724        changes: &[(Arc<RelPath>, ProjectEntryId, PathChange)],
11725        cx: &mut Context<Self>,
11726    ) {
11727        if changes.is_empty() {
11728            return;
11729        }
11730
11731        let Some(local) = self.as_local() else { return };
11732
11733        local.prettier_store.update(cx, |prettier_store, cx| {
11734            prettier_store.update_prettier_settings(worktree_handle, changes, cx)
11735        });
11736
11737        let worktree_id = worktree_handle.read(cx).id();
11738        let mut language_server_ids = local
11739            .language_server_ids
11740            .iter()
11741            .filter_map(|(seed, v)| seed.worktree_id.eq(&worktree_id).then(|| v.id))
11742            .collect::<Vec<_>>();
11743        language_server_ids.sort();
11744        language_server_ids.dedup();
11745
11746        // let abs_path = worktree_handle.read(cx).abs_path();
11747        for server_id in &language_server_ids {
11748            if let Some(LanguageServerState::Running { server, .. }) =
11749                local.language_servers.get(server_id)
11750                && let Some(watched_paths) = local
11751                    .language_server_watched_paths
11752                    .get(server_id)
11753                    .and_then(|paths| paths.worktree_paths.get(&worktree_id))
11754            {
11755                let params = lsp::DidChangeWatchedFilesParams {
11756                    changes: changes
11757                        .iter()
11758                        .filter_map(|(path, _, change)| {
11759                            if !watched_paths.is_match(path.as_std_path()) {
11760                                return None;
11761                            }
11762                            let typ = match change {
11763                                PathChange::Loaded => return None,
11764                                PathChange::Added => lsp::FileChangeType::CREATED,
11765                                PathChange::Removed => lsp::FileChangeType::DELETED,
11766                                PathChange::Updated => lsp::FileChangeType::CHANGED,
11767                                PathChange::AddedOrUpdated => lsp::FileChangeType::CHANGED,
11768                            };
11769                            let uri = lsp::Uri::from_file_path(
11770                                worktree_handle.read(cx).absolutize(&path),
11771                            )
11772                            .ok()?;
11773                            Some(lsp::FileEvent { uri, typ })
11774                        })
11775                        .collect(),
11776                };
11777                if !params.changes.is_empty() {
11778                    server
11779                        .notify::<lsp::notification::DidChangeWatchedFiles>(params)
11780                        .ok();
11781                }
11782            }
11783        }
11784        for (path, _, _) in changes {
11785            if let Some(file_name) = path.file_name()
11786                && local.watched_manifest_filenames.contains(file_name)
11787            {
11788                self.request_workspace_config_refresh();
11789                break;
11790            }
11791        }
11792    }
11793
11794    pub fn wait_for_remote_buffer(
11795        &mut self,
11796        id: BufferId,
11797        cx: &mut Context<Self>,
11798    ) -> Task<Result<Entity<Buffer>>> {
11799        self.buffer_store.update(cx, |buffer_store, cx| {
11800            buffer_store.wait_for_remote_buffer(id, cx)
11801        })
11802    }
11803
11804    fn serialize_symbol(symbol: &Symbol) -> proto::Symbol {
11805        let mut result = proto::Symbol {
11806            language_server_name: symbol.language_server_name.0.to_string(),
11807            source_worktree_id: symbol.source_worktree_id.to_proto(),
11808            language_server_id: symbol.source_language_server_id.to_proto(),
11809            name: symbol.name.clone(),
11810            kind: unsafe { mem::transmute::<lsp::SymbolKind, i32>(symbol.kind) },
11811            start: Some(proto::PointUtf16 {
11812                row: symbol.range.start.0.row,
11813                column: symbol.range.start.0.column,
11814            }),
11815            end: Some(proto::PointUtf16 {
11816                row: symbol.range.end.0.row,
11817                column: symbol.range.end.0.column,
11818            }),
11819            worktree_id: Default::default(),
11820            path: Default::default(),
11821            signature: Default::default(),
11822        };
11823        match &symbol.path {
11824            SymbolLocation::InProject(path) => {
11825                result.worktree_id = path.worktree_id.to_proto();
11826                result.path = path.path.to_proto();
11827            }
11828            SymbolLocation::OutsideProject {
11829                abs_path,
11830                signature,
11831            } => {
11832                result.path = abs_path.to_string_lossy().into_owned();
11833                result.signature = signature.to_vec();
11834            }
11835        }
11836        result
11837    }
11838
11839    fn deserialize_symbol(serialized_symbol: proto::Symbol) -> Result<CoreSymbol> {
11840        let source_worktree_id = WorktreeId::from_proto(serialized_symbol.source_worktree_id);
11841        let worktree_id = WorktreeId::from_proto(serialized_symbol.worktree_id);
11842        let kind = unsafe { mem::transmute::<i32, lsp::SymbolKind>(serialized_symbol.kind) };
11843
11844        let path = if serialized_symbol.signature.is_empty() {
11845            SymbolLocation::InProject(ProjectPath {
11846                worktree_id,
11847                path: RelPath::from_proto(&serialized_symbol.path)
11848                    .context("invalid symbol path")?,
11849            })
11850        } else {
11851            SymbolLocation::OutsideProject {
11852                abs_path: Path::new(&serialized_symbol.path).into(),
11853                signature: serialized_symbol
11854                    .signature
11855                    .try_into()
11856                    .map_err(|_| anyhow!("invalid signature"))?,
11857            }
11858        };
11859
11860        let start = serialized_symbol.start.context("invalid start")?;
11861        let end = serialized_symbol.end.context("invalid end")?;
11862        Ok(CoreSymbol {
11863            language_server_name: LanguageServerName(serialized_symbol.language_server_name.into()),
11864            source_worktree_id,
11865            source_language_server_id: LanguageServerId::from_proto(
11866                serialized_symbol.language_server_id,
11867            ),
11868            path,
11869            name: serialized_symbol.name,
11870            range: Unclipped(PointUtf16::new(start.row, start.column))
11871                ..Unclipped(PointUtf16::new(end.row, end.column)),
11872            kind,
11873        })
11874    }
11875
11876    pub(crate) fn serialize_completion(completion: &CoreCompletion) -> proto::Completion {
11877        let mut serialized_completion = proto::Completion {
11878            old_replace_start: Some(serialize_anchor(&completion.replace_range.start)),
11879            old_replace_end: Some(serialize_anchor(&completion.replace_range.end)),
11880            new_text: completion.new_text.clone(),
11881            ..proto::Completion::default()
11882        };
11883        match &completion.source {
11884            CompletionSource::Lsp {
11885                insert_range,
11886                server_id,
11887                lsp_completion,
11888                lsp_defaults,
11889                resolved,
11890            } => {
11891                let (old_insert_start, old_insert_end) = insert_range
11892                    .as_ref()
11893                    .map(|range| (serialize_anchor(&range.start), serialize_anchor(&range.end)))
11894                    .unzip();
11895
11896                serialized_completion.old_insert_start = old_insert_start;
11897                serialized_completion.old_insert_end = old_insert_end;
11898                serialized_completion.source = proto::completion::Source::Lsp as i32;
11899                serialized_completion.server_id = server_id.0 as u64;
11900                serialized_completion.lsp_completion = serde_json::to_vec(lsp_completion).unwrap();
11901                serialized_completion.lsp_defaults = lsp_defaults
11902                    .as_deref()
11903                    .map(|lsp_defaults| serde_json::to_vec(lsp_defaults).unwrap());
11904                serialized_completion.resolved = *resolved;
11905            }
11906            CompletionSource::BufferWord {
11907                word_range,
11908                resolved,
11909            } => {
11910                serialized_completion.source = proto::completion::Source::BufferWord as i32;
11911                serialized_completion.buffer_word_start = Some(serialize_anchor(&word_range.start));
11912                serialized_completion.buffer_word_end = Some(serialize_anchor(&word_range.end));
11913                serialized_completion.resolved = *resolved;
11914            }
11915            CompletionSource::Custom => {
11916                serialized_completion.source = proto::completion::Source::Custom as i32;
11917                serialized_completion.resolved = true;
11918            }
11919            CompletionSource::Dap { sort_text } => {
11920                serialized_completion.source = proto::completion::Source::Dap as i32;
11921                serialized_completion.sort_text = Some(sort_text.clone());
11922            }
11923        }
11924
11925        serialized_completion
11926    }
11927
11928    pub(crate) fn deserialize_completion(completion: proto::Completion) -> Result<CoreCompletion> {
11929        let old_replace_start = completion
11930            .old_replace_start
11931            .and_then(deserialize_anchor)
11932            .context("invalid old start")?;
11933        let old_replace_end = completion
11934            .old_replace_end
11935            .and_then(deserialize_anchor)
11936            .context("invalid old end")?;
11937        let insert_range = {
11938            match completion.old_insert_start.zip(completion.old_insert_end) {
11939                Some((start, end)) => {
11940                    let start = deserialize_anchor(start).context("invalid insert old start")?;
11941                    let end = deserialize_anchor(end).context("invalid insert old end")?;
11942                    Some(start..end)
11943                }
11944                None => None,
11945            }
11946        };
11947        Ok(CoreCompletion {
11948            replace_range: old_replace_start..old_replace_end,
11949            new_text: completion.new_text,
11950            source: match proto::completion::Source::from_i32(completion.source) {
11951                Some(proto::completion::Source::Custom) => CompletionSource::Custom,
11952                Some(proto::completion::Source::Lsp) => CompletionSource::Lsp {
11953                    insert_range,
11954                    server_id: LanguageServerId::from_proto(completion.server_id),
11955                    lsp_completion: serde_json::from_slice(&completion.lsp_completion)?,
11956                    lsp_defaults: completion
11957                        .lsp_defaults
11958                        .as_deref()
11959                        .map(serde_json::from_slice)
11960                        .transpose()?,
11961                    resolved: completion.resolved,
11962                },
11963                Some(proto::completion::Source::BufferWord) => {
11964                    let word_range = completion
11965                        .buffer_word_start
11966                        .and_then(deserialize_anchor)
11967                        .context("invalid buffer word start")?
11968                        ..completion
11969                            .buffer_word_end
11970                            .and_then(deserialize_anchor)
11971                            .context("invalid buffer word end")?;
11972                    CompletionSource::BufferWord {
11973                        word_range,
11974                        resolved: completion.resolved,
11975                    }
11976                }
11977                Some(proto::completion::Source::Dap) => CompletionSource::Dap {
11978                    sort_text: completion
11979                        .sort_text
11980                        .context("expected sort text to exist")?,
11981                },
11982                _ => anyhow::bail!("Unexpected completion source {}", completion.source),
11983            },
11984        })
11985    }
11986
11987    pub(crate) fn serialize_code_action(action: &CodeAction) -> proto::CodeAction {
11988        let (kind, lsp_action) = match &action.lsp_action {
11989            LspAction::Action(code_action) => (
11990                proto::code_action::Kind::Action as i32,
11991                serde_json::to_vec(code_action).unwrap(),
11992            ),
11993            LspAction::Command(command) => (
11994                proto::code_action::Kind::Command as i32,
11995                serde_json::to_vec(command).unwrap(),
11996            ),
11997            LspAction::CodeLens(code_lens) => (
11998                proto::code_action::Kind::CodeLens as i32,
11999                serde_json::to_vec(code_lens).unwrap(),
12000            ),
12001        };
12002
12003        proto::CodeAction {
12004            server_id: action.server_id.0 as u64,
12005            start: Some(serialize_anchor(&action.range.start)),
12006            end: Some(serialize_anchor(&action.range.end)),
12007            lsp_action,
12008            kind,
12009            resolved: action.resolved,
12010        }
12011    }
12012
12013    pub(crate) fn deserialize_code_action(action: proto::CodeAction) -> Result<CodeAction> {
12014        let start = action
12015            .start
12016            .and_then(deserialize_anchor)
12017            .context("invalid start")?;
12018        let end = action
12019            .end
12020            .and_then(deserialize_anchor)
12021            .context("invalid end")?;
12022        let lsp_action = match proto::code_action::Kind::from_i32(action.kind) {
12023            Some(proto::code_action::Kind::Action) => {
12024                LspAction::Action(serde_json::from_slice(&action.lsp_action)?)
12025            }
12026            Some(proto::code_action::Kind::Command) => {
12027                LspAction::Command(serde_json::from_slice(&action.lsp_action)?)
12028            }
12029            Some(proto::code_action::Kind::CodeLens) => {
12030                LspAction::CodeLens(serde_json::from_slice(&action.lsp_action)?)
12031            }
12032            None => anyhow::bail!("Unknown action kind {}", action.kind),
12033        };
12034        Ok(CodeAction {
12035            server_id: LanguageServerId(action.server_id as usize),
12036            range: start..end,
12037            resolved: action.resolved,
12038            lsp_action,
12039        })
12040    }
12041
12042    fn update_last_formatting_failure<T>(&mut self, formatting_result: &anyhow::Result<T>) {
12043        match &formatting_result {
12044            Ok(_) => self.last_formatting_failure = None,
12045            Err(error) => {
12046                let error_string = format!("{error:#}");
12047                log::error!("Formatting failed: {error_string}");
12048                self.last_formatting_failure
12049                    .replace(error_string.lines().join(" "));
12050            }
12051        }
12052    }
12053
12054    fn cleanup_lsp_data(&mut self, for_server: LanguageServerId) {
12055        self.lsp_server_capabilities.remove(&for_server);
12056        for lsp_data in self.lsp_data.values_mut() {
12057            lsp_data.remove_server_data(for_server);
12058        }
12059        if let Some(local) = self.as_local_mut() {
12060            local.buffer_pull_diagnostics_result_ids.remove(&for_server);
12061            local
12062                .workspace_pull_diagnostics_result_ids
12063                .remove(&for_server);
12064            for buffer_servers in local.buffers_opened_in_servers.values_mut() {
12065                buffer_servers.remove(&for_server);
12066            }
12067        }
12068    }
12069
12070    pub fn result_id_for_buffer_pull(
12071        &self,
12072        server_id: LanguageServerId,
12073        buffer_id: BufferId,
12074        registration_id: &Option<SharedString>,
12075        cx: &App,
12076    ) -> Option<SharedString> {
12077        let abs_path = self
12078            .buffer_store
12079            .read(cx)
12080            .get(buffer_id)
12081            .and_then(|b| File::from_dyn(b.read(cx).file()))
12082            .map(|f| f.abs_path(cx))?;
12083        self.as_local()?
12084            .buffer_pull_diagnostics_result_ids
12085            .get(&server_id)?
12086            .get(registration_id)?
12087            .get(&abs_path)?
12088            .clone()
12089    }
12090
12091    /// Gets all result_ids for a workspace diagnostics pull request.
12092    /// 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.
12093    /// The latter is supposed to be of lower priority as we keep on pulling diagnostics for open buffers eagerly.
12094    pub fn result_ids_for_workspace_refresh(
12095        &self,
12096        server_id: LanguageServerId,
12097        registration_id: &Option<SharedString>,
12098    ) -> HashMap<PathBuf, SharedString> {
12099        let Some(local) = self.as_local() else {
12100            return HashMap::default();
12101        };
12102        local
12103            .workspace_pull_diagnostics_result_ids
12104            .get(&server_id)
12105            .into_iter()
12106            .filter_map(|diagnostics| diagnostics.get(registration_id))
12107            .flatten()
12108            .filter_map(|(abs_path, result_id)| {
12109                let result_id = local
12110                    .buffer_pull_diagnostics_result_ids
12111                    .get(&server_id)
12112                    .and_then(|buffer_ids_result_ids| {
12113                        buffer_ids_result_ids.get(registration_id)?.get(abs_path)
12114                    })
12115                    .cloned()
12116                    .flatten()
12117                    .or_else(|| result_id.clone())?;
12118                Some((abs_path.clone(), result_id))
12119            })
12120            .collect()
12121    }
12122
12123    pub fn pull_workspace_diagnostics(&mut self, server_id: LanguageServerId) {
12124        if let Some(LanguageServerState::Running {
12125            workspace_diagnostics_refresh_tasks,
12126            ..
12127        }) = self
12128            .as_local_mut()
12129            .and_then(|local| local.language_servers.get_mut(&server_id))
12130        {
12131            for diagnostics in workspace_diagnostics_refresh_tasks.values_mut() {
12132                diagnostics.refresh_tx.try_send(()).ok();
12133            }
12134        }
12135    }
12136
12137    pub fn pull_workspace_diagnostics_for_buffer(&mut self, buffer_id: BufferId, cx: &mut App) {
12138        let Some(buffer) = self.buffer_store().read(cx).get_existing(buffer_id).ok() else {
12139            return;
12140        };
12141        let Some(local) = self.as_local_mut() else {
12142            return;
12143        };
12144
12145        for server_id in buffer.update(cx, |buffer, cx| {
12146            local.language_server_ids_for_buffer(buffer, cx)
12147        }) {
12148            if let Some(LanguageServerState::Running {
12149                workspace_diagnostics_refresh_tasks,
12150                ..
12151            }) = local.language_servers.get_mut(&server_id)
12152            {
12153                for diagnostics in workspace_diagnostics_refresh_tasks.values_mut() {
12154                    diagnostics.refresh_tx.try_send(()).ok();
12155                }
12156            }
12157        }
12158    }
12159
12160    fn apply_workspace_diagnostic_report(
12161        &mut self,
12162        server_id: LanguageServerId,
12163        report: lsp::WorkspaceDiagnosticReportResult,
12164        registration_id: Option<SharedString>,
12165        cx: &mut Context<Self>,
12166    ) {
12167        let mut workspace_diagnostics =
12168            GetDocumentDiagnostics::deserialize_workspace_diagnostics_report(
12169                report,
12170                server_id,
12171                registration_id,
12172            );
12173        workspace_diagnostics.retain(|d| match &d.diagnostics {
12174            LspPullDiagnostics::Response {
12175                server_id,
12176                registration_id,
12177                ..
12178            } => self.diagnostic_registration_exists(*server_id, registration_id),
12179            LspPullDiagnostics::Default => false,
12180        });
12181        let mut unchanged_buffers = HashMap::default();
12182        let workspace_diagnostics_updates = workspace_diagnostics
12183            .into_iter()
12184            .filter_map(
12185                |workspace_diagnostics| match workspace_diagnostics.diagnostics {
12186                    LspPullDiagnostics::Response {
12187                        server_id,
12188                        uri,
12189                        diagnostics,
12190                        registration_id,
12191                    } => Some((
12192                        server_id,
12193                        uri,
12194                        diagnostics,
12195                        workspace_diagnostics.version,
12196                        registration_id,
12197                    )),
12198                    LspPullDiagnostics::Default => None,
12199                },
12200            )
12201            .fold(
12202                HashMap::default(),
12203                |mut acc, (server_id, uri, diagnostics, version, new_registration_id)| {
12204                    let (result_id, diagnostics) = match diagnostics {
12205                        PulledDiagnostics::Unchanged { result_id } => {
12206                            unchanged_buffers
12207                                .entry(new_registration_id.clone())
12208                                .or_insert_with(HashSet::default)
12209                                .insert(uri.clone());
12210                            (Some(result_id), Vec::new())
12211                        }
12212                        PulledDiagnostics::Changed {
12213                            result_id,
12214                            diagnostics,
12215                        } => (result_id, diagnostics),
12216                    };
12217                    let disk_based_sources = Cow::Owned(
12218                        self.language_server_adapter_for_id(server_id)
12219                            .as_ref()
12220                            .map(|adapter| adapter.disk_based_diagnostic_sources.as_slice())
12221                            .unwrap_or(&[])
12222                            .to_vec(),
12223                    );
12224
12225                    let Some(abs_path) = uri.to_file_path().ok() else {
12226                        return acc;
12227                    };
12228                    let Some((worktree, relative_path)) =
12229                        self.worktree_store.read(cx).find_worktree(abs_path.clone(), cx)
12230                    else {
12231                        log::warn!("skipping workspace diagnostics update, no worktree found for path {abs_path:?}");
12232                        return acc;
12233                    };
12234                    let worktree_id = worktree.read(cx).id();
12235                    let project_path = ProjectPath {
12236                        worktree_id,
12237                        path: relative_path,
12238                    };
12239                    if let Some(local_lsp_store) = self.as_local_mut() {
12240                        local_lsp_store.workspace_pull_diagnostics_result_ids.entry(server_id)
12241                            .or_default().entry(new_registration_id.clone()).or_default().insert(abs_path, result_id.clone());
12242                    }
12243                    // The LSP spec recommends that "diagnostics from a document pull should win over diagnostics from a workspace pull."
12244                    // Since we actively pull diagnostics for documents with open buffers, we ignore contents of workspace pulls for these documents.
12245                    if self.buffer_store.read(cx).get_by_path(&project_path).is_none() {
12246                        acc.entry(server_id)
12247                            .or_insert_with(HashMap::default)
12248                            .entry(new_registration_id.clone())
12249                            .or_insert_with(Vec::new)
12250                            .push(DocumentDiagnosticsUpdate {
12251                                server_id,
12252                                diagnostics: lsp::PublishDiagnosticsParams {
12253                                    uri,
12254                                    diagnostics,
12255                                    version,
12256                                },
12257                                result_id,
12258                                disk_based_sources,
12259                                registration_id: new_registration_id,
12260                            });
12261                    }
12262                    acc
12263                },
12264            );
12265
12266        for diagnostic_updates in workspace_diagnostics_updates.into_values() {
12267            for (registration_id, diagnostic_updates) in diagnostic_updates {
12268                self.merge_lsp_diagnostics(
12269                    DiagnosticSourceKind::Pulled,
12270                    diagnostic_updates,
12271                    |document_uri, old_diagnostic, _| match old_diagnostic.source_kind {
12272                        DiagnosticSourceKind::Pulled => {
12273                            old_diagnostic.registration_id != registration_id
12274                                || unchanged_buffers
12275                                    .get(&old_diagnostic.registration_id)
12276                                    .is_some_and(|unchanged_buffers| {
12277                                        unchanged_buffers.contains(&document_uri)
12278                                    })
12279                        }
12280                        DiagnosticSourceKind::Other | DiagnosticSourceKind::Pushed => true,
12281                    },
12282                    cx,
12283                )
12284                .log_err();
12285            }
12286        }
12287    }
12288
12289    fn register_server_capabilities(
12290        &mut self,
12291        server_id: LanguageServerId,
12292        params: lsp::RegistrationParams,
12293        cx: &mut Context<Self>,
12294    ) -> anyhow::Result<()> {
12295        let server = self
12296            .language_server_for_id(server_id)
12297            .with_context(|| format!("no server {server_id} found"))?;
12298        for reg in params.registrations {
12299            match reg.method.as_str() {
12300                "workspace/didChangeWatchedFiles" => {
12301                    if let Some(options) = reg.register_options {
12302                        let notify = if let Some(local_lsp_store) = self.as_local_mut() {
12303                            let caps = serde_json::from_value(options)?;
12304                            local_lsp_store
12305                                .on_lsp_did_change_watched_files(server_id, &reg.id, caps, cx);
12306                            true
12307                        } else {
12308                            false
12309                        };
12310                        if notify {
12311                            notify_server_capabilities_updated(&server, cx);
12312                        }
12313                    }
12314                }
12315                "workspace/didChangeConfiguration" => {
12316                    // Ignore payload since we notify clients of setting changes unconditionally, relying on them pulling the latest settings.
12317                }
12318                "workspace/didChangeWorkspaceFolders" => {
12319                    // In this case register options is an empty object, we can ignore it
12320                    let caps = lsp::WorkspaceFoldersServerCapabilities {
12321                        supported: Some(true),
12322                        change_notifications: Some(OneOf::Right(reg.id)),
12323                    };
12324                    server.update_capabilities(|capabilities| {
12325                        capabilities
12326                            .workspace
12327                            .get_or_insert_default()
12328                            .workspace_folders = Some(caps);
12329                    });
12330                    notify_server_capabilities_updated(&server, cx);
12331                }
12332                "workspace/symbol" => {
12333                    let options = parse_register_capabilities(reg)?;
12334                    server.update_capabilities(|capabilities| {
12335                        capabilities.workspace_symbol_provider = Some(options);
12336                    });
12337                    notify_server_capabilities_updated(&server, cx);
12338                }
12339                "workspace/fileOperations" => {
12340                    if let Some(options) = reg.register_options {
12341                        let caps = serde_json::from_value(options)?;
12342                        server.update_capabilities(|capabilities| {
12343                            capabilities
12344                                .workspace
12345                                .get_or_insert_default()
12346                                .file_operations = Some(caps);
12347                        });
12348                        notify_server_capabilities_updated(&server, cx);
12349                    }
12350                }
12351                "workspace/executeCommand" => {
12352                    if let Some(options) = reg.register_options {
12353                        let options = serde_json::from_value(options)?;
12354                        server.update_capabilities(|capabilities| {
12355                            capabilities.execute_command_provider = Some(options);
12356                        });
12357                        notify_server_capabilities_updated(&server, cx);
12358                    }
12359                }
12360                "textDocument/rangeFormatting" => {
12361                    let options = parse_register_capabilities(reg)?;
12362                    server.update_capabilities(|capabilities| {
12363                        capabilities.document_range_formatting_provider = Some(options);
12364                    });
12365                    notify_server_capabilities_updated(&server, cx);
12366                }
12367                "textDocument/onTypeFormatting" => {
12368                    if let Some(options) = reg
12369                        .register_options
12370                        .map(serde_json::from_value)
12371                        .transpose()?
12372                    {
12373                        server.update_capabilities(|capabilities| {
12374                            capabilities.document_on_type_formatting_provider = Some(options);
12375                        });
12376                        notify_server_capabilities_updated(&server, cx);
12377                    }
12378                }
12379                "textDocument/formatting" => {
12380                    let options = parse_register_capabilities(reg)?;
12381                    server.update_capabilities(|capabilities| {
12382                        capabilities.document_formatting_provider = Some(options);
12383                    });
12384                    notify_server_capabilities_updated(&server, cx);
12385                }
12386                "textDocument/rename" => {
12387                    let options = parse_register_capabilities(reg)?;
12388                    server.update_capabilities(|capabilities| {
12389                        capabilities.rename_provider = Some(options);
12390                    });
12391                    notify_server_capabilities_updated(&server, cx);
12392                }
12393                "textDocument/inlayHint" => {
12394                    let options = parse_register_capabilities(reg)?;
12395                    server.update_capabilities(|capabilities| {
12396                        capabilities.inlay_hint_provider = Some(options);
12397                    });
12398                    notify_server_capabilities_updated(&server, cx);
12399                }
12400                "textDocument/documentSymbol" => {
12401                    let options = parse_register_capabilities(reg)?;
12402                    server.update_capabilities(|capabilities| {
12403                        capabilities.document_symbol_provider = Some(options);
12404                    });
12405                    notify_server_capabilities_updated(&server, cx);
12406                }
12407                "textDocument/codeAction" => {
12408                    let options = parse_register_capabilities(reg)?;
12409                    let provider = match options {
12410                        OneOf::Left(value) => lsp::CodeActionProviderCapability::Simple(value),
12411                        OneOf::Right(caps) => caps,
12412                    };
12413                    server.update_capabilities(|capabilities| {
12414                        capabilities.code_action_provider = Some(provider);
12415                    });
12416                    notify_server_capabilities_updated(&server, cx);
12417                }
12418                "textDocument/definition" => {
12419                    let options = parse_register_capabilities(reg)?;
12420                    server.update_capabilities(|capabilities| {
12421                        capabilities.definition_provider = Some(options);
12422                    });
12423                    notify_server_capabilities_updated(&server, cx);
12424                }
12425                "textDocument/completion" => {
12426                    if let Some(caps) = reg
12427                        .register_options
12428                        .map(serde_json::from_value::<CompletionOptions>)
12429                        .transpose()?
12430                    {
12431                        server.update_capabilities(|capabilities| {
12432                            capabilities.completion_provider = Some(caps.clone());
12433                        });
12434
12435                        if let Some(local) = self.as_local() {
12436                            let mut buffers_with_language_server = Vec::new();
12437                            for handle in self.buffer_store.read(cx).buffers() {
12438                                let buffer_id = handle.read(cx).remote_id();
12439                                if local
12440                                    .buffers_opened_in_servers
12441                                    .get(&buffer_id)
12442                                    .filter(|s| s.contains(&server_id))
12443                                    .is_some()
12444                                {
12445                                    buffers_with_language_server.push(handle);
12446                                }
12447                            }
12448                            let triggers = caps
12449                                .trigger_characters
12450                                .unwrap_or_default()
12451                                .into_iter()
12452                                .collect::<BTreeSet<_>>();
12453                            for handle in buffers_with_language_server {
12454                                let triggers = triggers.clone();
12455                                let _ = handle.update(cx, move |buffer, cx| {
12456                                    buffer.set_completion_triggers(server_id, triggers, cx);
12457                                });
12458                            }
12459                        }
12460                        notify_server_capabilities_updated(&server, cx);
12461                    }
12462                }
12463                "textDocument/hover" => {
12464                    let options = parse_register_capabilities(reg)?;
12465                    let provider = match options {
12466                        OneOf::Left(value) => lsp::HoverProviderCapability::Simple(value),
12467                        OneOf::Right(caps) => caps,
12468                    };
12469                    server.update_capabilities(|capabilities| {
12470                        capabilities.hover_provider = Some(provider);
12471                    });
12472                    notify_server_capabilities_updated(&server, cx);
12473                }
12474                "textDocument/signatureHelp" => {
12475                    if let Some(caps) = reg
12476                        .register_options
12477                        .map(serde_json::from_value)
12478                        .transpose()?
12479                    {
12480                        server.update_capabilities(|capabilities| {
12481                            capabilities.signature_help_provider = Some(caps);
12482                        });
12483                        notify_server_capabilities_updated(&server, cx);
12484                    }
12485                }
12486                "textDocument/didChange" => {
12487                    if let Some(sync_kind) = reg
12488                        .register_options
12489                        .and_then(|opts| opts.get("syncKind").cloned())
12490                        .map(serde_json::from_value::<lsp::TextDocumentSyncKind>)
12491                        .transpose()?
12492                    {
12493                        server.update_capabilities(|capabilities| {
12494                            let mut sync_options =
12495                                Self::take_text_document_sync_options(capabilities);
12496                            sync_options.change = Some(sync_kind);
12497                            capabilities.text_document_sync =
12498                                Some(lsp::TextDocumentSyncCapability::Options(sync_options));
12499                        });
12500                        notify_server_capabilities_updated(&server, cx);
12501                    }
12502                }
12503                "textDocument/didSave" => {
12504                    if let Some(include_text) = reg
12505                        .register_options
12506                        .map(|opts| {
12507                            let transpose = opts
12508                                .get("includeText")
12509                                .cloned()
12510                                .map(serde_json::from_value::<Option<bool>>)
12511                                .transpose();
12512                            match transpose {
12513                                Ok(value) => Ok(value.flatten()),
12514                                Err(e) => Err(e),
12515                            }
12516                        })
12517                        .transpose()?
12518                    {
12519                        server.update_capabilities(|capabilities| {
12520                            let mut sync_options =
12521                                Self::take_text_document_sync_options(capabilities);
12522                            sync_options.save =
12523                                Some(TextDocumentSyncSaveOptions::SaveOptions(lsp::SaveOptions {
12524                                    include_text,
12525                                }));
12526                            capabilities.text_document_sync =
12527                                Some(lsp::TextDocumentSyncCapability::Options(sync_options));
12528                        });
12529                        notify_server_capabilities_updated(&server, cx);
12530                    }
12531                }
12532                "textDocument/codeLens" => {
12533                    if let Some(caps) = reg
12534                        .register_options
12535                        .map(serde_json::from_value)
12536                        .transpose()?
12537                    {
12538                        server.update_capabilities(|capabilities| {
12539                            capabilities.code_lens_provider = Some(caps);
12540                        });
12541                        notify_server_capabilities_updated(&server, cx);
12542                    }
12543                }
12544                "textDocument/diagnostic" => {
12545                    if let Some(caps) = reg
12546                        .register_options
12547                        .map(serde_json::from_value::<DiagnosticServerCapabilities>)
12548                        .transpose()?
12549                    {
12550                        let local = self
12551                            .as_local_mut()
12552                            .context("Expected LSP Store to be local")?;
12553                        let state = local
12554                            .language_servers
12555                            .get_mut(&server_id)
12556                            .context("Could not obtain Language Servers state")?;
12557                        local
12558                            .language_server_dynamic_registrations
12559                            .entry(server_id)
12560                            .or_default()
12561                            .diagnostics
12562                            .insert(Some(reg.id.clone()), caps.clone());
12563
12564                        let supports_workspace_diagnostics =
12565                            |capabilities: &DiagnosticServerCapabilities| match capabilities {
12566                                DiagnosticServerCapabilities::Options(diagnostic_options) => {
12567                                    diagnostic_options.workspace_diagnostics
12568                                }
12569                                DiagnosticServerCapabilities::RegistrationOptions(
12570                                    diagnostic_registration_options,
12571                                ) => {
12572                                    diagnostic_registration_options
12573                                        .diagnostic_options
12574                                        .workspace_diagnostics
12575                                }
12576                            };
12577
12578                        if supports_workspace_diagnostics(&caps) {
12579                            if let LanguageServerState::Running {
12580                                workspace_diagnostics_refresh_tasks,
12581                                ..
12582                            } = state
12583                                && let Some(task) = lsp_workspace_diagnostics_refresh(
12584                                    Some(reg.id.clone()),
12585                                    caps.clone(),
12586                                    server.clone(),
12587                                    cx,
12588                                )
12589                            {
12590                                workspace_diagnostics_refresh_tasks.insert(Some(reg.id), task);
12591                            }
12592                        }
12593
12594                        server.update_capabilities(|capabilities| {
12595                            capabilities.diagnostic_provider = Some(caps);
12596                        });
12597
12598                        notify_server_capabilities_updated(&server, cx);
12599
12600                        let buffers_to_pull: Vec<_> = self
12601                            .as_local()
12602                            .into_iter()
12603                            .flat_map(|local| {
12604                                self.buffer_store.read(cx).buffers().filter(|buffer| {
12605                                    let buffer_id = buffer.read(cx).remote_id();
12606                                    local
12607                                        .buffers_opened_in_servers
12608                                        .get(&buffer_id)
12609                                        .is_some_and(|servers| servers.contains(&server_id))
12610                                })
12611                            })
12612                            .collect();
12613                        for buffer in buffers_to_pull {
12614                            self.pull_diagnostics_for_buffer(buffer, cx).detach();
12615                        }
12616                    }
12617                }
12618                "textDocument/documentColor" => {
12619                    let options = parse_register_capabilities(reg)?;
12620                    let provider = match options {
12621                        OneOf::Left(value) => lsp::ColorProviderCapability::Simple(value),
12622                        OneOf::Right(caps) => caps,
12623                    };
12624                    server.update_capabilities(|capabilities| {
12625                        capabilities.color_provider = Some(provider);
12626                    });
12627                    notify_server_capabilities_updated(&server, cx);
12628                }
12629                _ => log::warn!("unhandled capability registration: {reg:?}"),
12630            }
12631        }
12632
12633        Ok(())
12634    }
12635
12636    fn unregister_server_capabilities(
12637        &mut self,
12638        server_id: LanguageServerId,
12639        params: lsp::UnregistrationParams,
12640        cx: &mut Context<Self>,
12641    ) -> anyhow::Result<()> {
12642        let server = self
12643            .language_server_for_id(server_id)
12644            .with_context(|| format!("no server {server_id} found"))?;
12645        for unreg in params.unregisterations.iter() {
12646            match unreg.method.as_str() {
12647                "workspace/didChangeWatchedFiles" => {
12648                    let notify = if let Some(local_lsp_store) = self.as_local_mut() {
12649                        local_lsp_store
12650                            .on_lsp_unregister_did_change_watched_files(server_id, &unreg.id, cx);
12651                        true
12652                    } else {
12653                        false
12654                    };
12655                    if notify {
12656                        notify_server_capabilities_updated(&server, cx);
12657                    }
12658                }
12659                "workspace/didChangeConfiguration" => {
12660                    // Ignore payload since we notify clients of setting changes unconditionally, relying on them pulling the latest settings.
12661                }
12662                "workspace/didChangeWorkspaceFolders" => {
12663                    server.update_capabilities(|capabilities| {
12664                        capabilities
12665                            .workspace
12666                            .get_or_insert_with(|| lsp::WorkspaceServerCapabilities {
12667                                workspace_folders: None,
12668                                file_operations: None,
12669                            })
12670                            .workspace_folders = None;
12671                    });
12672                    notify_server_capabilities_updated(&server, cx);
12673                }
12674                "workspace/symbol" => {
12675                    server.update_capabilities(|capabilities| {
12676                        capabilities.workspace_symbol_provider = None
12677                    });
12678                    notify_server_capabilities_updated(&server, cx);
12679                }
12680                "workspace/fileOperations" => {
12681                    server.update_capabilities(|capabilities| {
12682                        capabilities
12683                            .workspace
12684                            .get_or_insert_with(|| lsp::WorkspaceServerCapabilities {
12685                                workspace_folders: None,
12686                                file_operations: None,
12687                            })
12688                            .file_operations = None;
12689                    });
12690                    notify_server_capabilities_updated(&server, cx);
12691                }
12692                "workspace/executeCommand" => {
12693                    server.update_capabilities(|capabilities| {
12694                        capabilities.execute_command_provider = None;
12695                    });
12696                    notify_server_capabilities_updated(&server, cx);
12697                }
12698                "textDocument/rangeFormatting" => {
12699                    server.update_capabilities(|capabilities| {
12700                        capabilities.document_range_formatting_provider = None
12701                    });
12702                    notify_server_capabilities_updated(&server, cx);
12703                }
12704                "textDocument/onTypeFormatting" => {
12705                    server.update_capabilities(|capabilities| {
12706                        capabilities.document_on_type_formatting_provider = None;
12707                    });
12708                    notify_server_capabilities_updated(&server, cx);
12709                }
12710                "textDocument/formatting" => {
12711                    server.update_capabilities(|capabilities| {
12712                        capabilities.document_formatting_provider = None;
12713                    });
12714                    notify_server_capabilities_updated(&server, cx);
12715                }
12716                "textDocument/rename" => {
12717                    server.update_capabilities(|capabilities| capabilities.rename_provider = None);
12718                    notify_server_capabilities_updated(&server, cx);
12719                }
12720                "textDocument/codeAction" => {
12721                    server.update_capabilities(|capabilities| {
12722                        capabilities.code_action_provider = None;
12723                    });
12724                    notify_server_capabilities_updated(&server, cx);
12725                }
12726                "textDocument/definition" => {
12727                    server.update_capabilities(|capabilities| {
12728                        capabilities.definition_provider = None;
12729                    });
12730                    notify_server_capabilities_updated(&server, cx);
12731                }
12732                "textDocument/completion" => {
12733                    server.update_capabilities(|capabilities| {
12734                        capabilities.completion_provider = None;
12735                    });
12736                    notify_server_capabilities_updated(&server, cx);
12737                }
12738                "textDocument/hover" => {
12739                    server.update_capabilities(|capabilities| {
12740                        capabilities.hover_provider = None;
12741                    });
12742                    notify_server_capabilities_updated(&server, cx);
12743                }
12744                "textDocument/signatureHelp" => {
12745                    server.update_capabilities(|capabilities| {
12746                        capabilities.signature_help_provider = None;
12747                    });
12748                    notify_server_capabilities_updated(&server, cx);
12749                }
12750                "textDocument/didChange" => {
12751                    server.update_capabilities(|capabilities| {
12752                        let mut sync_options = Self::take_text_document_sync_options(capabilities);
12753                        sync_options.change = None;
12754                        capabilities.text_document_sync =
12755                            Some(lsp::TextDocumentSyncCapability::Options(sync_options));
12756                    });
12757                    notify_server_capabilities_updated(&server, cx);
12758                }
12759                "textDocument/didSave" => {
12760                    server.update_capabilities(|capabilities| {
12761                        let mut sync_options = Self::take_text_document_sync_options(capabilities);
12762                        sync_options.save = None;
12763                        capabilities.text_document_sync =
12764                            Some(lsp::TextDocumentSyncCapability::Options(sync_options));
12765                    });
12766                    notify_server_capabilities_updated(&server, cx);
12767                }
12768                "textDocument/codeLens" => {
12769                    server.update_capabilities(|capabilities| {
12770                        capabilities.code_lens_provider = None;
12771                    });
12772                    notify_server_capabilities_updated(&server, cx);
12773                }
12774                "textDocument/diagnostic" => {
12775                    let local = self
12776                        .as_local_mut()
12777                        .context("Expected LSP Store to be local")?;
12778
12779                    let state = local
12780                        .language_servers
12781                        .get_mut(&server_id)
12782                        .context("Could not obtain Language Servers state")?;
12783                    let registrations = local
12784                        .language_server_dynamic_registrations
12785                        .get_mut(&server_id)
12786                        .with_context(|| {
12787                            format!("Expected dynamic registration to exist for server {server_id}")
12788                        })?;
12789                    registrations.diagnostics
12790                        .remove(&Some(unreg.id.clone()))
12791                        .with_context(|| format!(
12792                            "Attempted to unregister non-existent diagnostic registration with ID {}",
12793                            unreg.id)
12794                        )?;
12795                    let removed_last_diagnostic_provider = registrations.diagnostics.is_empty();
12796
12797                    if let LanguageServerState::Running {
12798                        workspace_diagnostics_refresh_tasks,
12799                        ..
12800                    } = state
12801                    {
12802                        workspace_diagnostics_refresh_tasks.remove(&Some(unreg.id.clone()));
12803                    }
12804
12805                    self.clear_unregistered_diagnostics(
12806                        server_id,
12807                        SharedString::from(unreg.id.clone()),
12808                        cx,
12809                    )?;
12810
12811                    if removed_last_diagnostic_provider {
12812                        server.update_capabilities(|capabilities| {
12813                            debug_assert!(capabilities.diagnostic_provider.is_some());
12814                            capabilities.diagnostic_provider = None;
12815                        });
12816                    }
12817
12818                    notify_server_capabilities_updated(&server, cx);
12819                }
12820                "textDocument/documentColor" => {
12821                    server.update_capabilities(|capabilities| {
12822                        capabilities.color_provider = None;
12823                    });
12824                    notify_server_capabilities_updated(&server, cx);
12825                }
12826                _ => log::warn!("unhandled capability unregistration: {unreg:?}"),
12827            }
12828        }
12829
12830        Ok(())
12831    }
12832
12833    fn clear_unregistered_diagnostics(
12834        &mut self,
12835        server_id: LanguageServerId,
12836        cleared_registration_id: SharedString,
12837        cx: &mut Context<Self>,
12838    ) -> anyhow::Result<()> {
12839        let mut affected_abs_paths: HashSet<PathBuf> = HashSet::default();
12840
12841        self.buffer_store.update(cx, |buffer_store, cx| {
12842            for buffer_handle in buffer_store.buffers() {
12843                let buffer = buffer_handle.read(cx);
12844                let abs_path = File::from_dyn(buffer.file()).map(|f| f.abs_path(cx));
12845                let Some(abs_path) = abs_path else {
12846                    continue;
12847                };
12848                affected_abs_paths.insert(abs_path);
12849            }
12850        });
12851
12852        let local = self.as_local().context("Expected LSP Store to be local")?;
12853        for (worktree_id, diagnostics_for_tree) in local.diagnostics.iter() {
12854            let Some(worktree) = self
12855                .worktree_store
12856                .read(cx)
12857                .worktree_for_id(*worktree_id, cx)
12858            else {
12859                continue;
12860            };
12861
12862            for (rel_path, diagnostics_by_server_id) in diagnostics_for_tree.iter() {
12863                if let Ok(ix) = diagnostics_by_server_id.binary_search_by_key(&server_id, |e| e.0) {
12864                    let has_matching_registration =
12865                        diagnostics_by_server_id[ix].1.iter().any(|entry| {
12866                            entry.diagnostic.registration_id.as_ref()
12867                                == Some(&cleared_registration_id)
12868                        });
12869                    if has_matching_registration {
12870                        let abs_path = worktree.read(cx).absolutize(rel_path);
12871                        affected_abs_paths.insert(abs_path);
12872                    }
12873                }
12874            }
12875        }
12876
12877        if affected_abs_paths.is_empty() {
12878            return Ok(());
12879        }
12880
12881        // Send a fake diagnostic update which clears the state for the registration ID
12882        let clears: Vec<DocumentDiagnosticsUpdate<'static, DocumentDiagnostics>> =
12883            affected_abs_paths
12884                .into_iter()
12885                .map(|abs_path| DocumentDiagnosticsUpdate {
12886                    diagnostics: DocumentDiagnostics {
12887                        diagnostics: Vec::new(),
12888                        document_abs_path: abs_path,
12889                        version: None,
12890                    },
12891                    result_id: None,
12892                    registration_id: Some(cleared_registration_id.clone()),
12893                    server_id,
12894                    disk_based_sources: Cow::Borrowed(&[]),
12895                })
12896                .collect();
12897
12898        let merge_registration_id = cleared_registration_id.clone();
12899        self.merge_diagnostic_entries(
12900            clears,
12901            move |_, diagnostic, _| {
12902                if diagnostic.source_kind == DiagnosticSourceKind::Pulled {
12903                    diagnostic.registration_id != Some(merge_registration_id.clone())
12904                } else {
12905                    true
12906                }
12907            },
12908            cx,
12909        )?;
12910
12911        Ok(())
12912    }
12913
12914    async fn deduplicate_range_based_lsp_requests<T>(
12915        lsp_store: &Entity<Self>,
12916        server_id: Option<LanguageServerId>,
12917        lsp_request_id: LspRequestId,
12918        proto_request: &T::ProtoRequest,
12919        range: Range<Anchor>,
12920        cx: &mut AsyncApp,
12921    ) -> Result<()>
12922    where
12923        T: LspCommand,
12924        T::ProtoRequest: proto::LspRequestMessage,
12925    {
12926        let buffer_id = BufferId::new(proto_request.buffer_id())?;
12927        let version = deserialize_version(proto_request.buffer_version());
12928        let buffer = lsp_store.update(cx, |this, cx| {
12929            this.buffer_store.read(cx).get_existing(buffer_id)
12930        })??;
12931        buffer
12932            .update(cx, |buffer, _| buffer.wait_for_version(version))?
12933            .await?;
12934        lsp_store.update(cx, |lsp_store, cx| {
12935            let buffer_snapshot = buffer.read(cx).snapshot();
12936            let lsp_data = lsp_store.latest_lsp_data(&buffer, cx);
12937            let chunks_queried_for = lsp_data
12938                .inlay_hints
12939                .applicable_chunks(&[range.to_point(&buffer_snapshot)])
12940                .collect::<Vec<_>>();
12941            match chunks_queried_for.as_slice() {
12942                &[chunk] => {
12943                    let key = LspKey {
12944                        request_type: TypeId::of::<T>(),
12945                        server_queried: server_id,
12946                    };
12947                    let previous_request = lsp_data
12948                        .chunk_lsp_requests
12949                        .entry(key)
12950                        .or_default()
12951                        .insert(chunk, lsp_request_id);
12952                    if let Some((previous_request, running_requests)) =
12953                        previous_request.zip(lsp_data.lsp_requests.get_mut(&key))
12954                    {
12955                        running_requests.remove(&previous_request);
12956                    }
12957                }
12958                _ambiguous_chunks => {
12959                    // Have not found a unique chunk for the query range — be lenient and let the query to be spawned,
12960                    // there, a buffer version-based check will be performed and outdated requests discarded.
12961                }
12962            }
12963            anyhow::Ok(())
12964        })??;
12965
12966        Ok(())
12967    }
12968
12969    async fn query_lsp_locally<T>(
12970        lsp_store: Entity<Self>,
12971        for_server_id: Option<LanguageServerId>,
12972        sender_id: proto::PeerId,
12973        lsp_request_id: LspRequestId,
12974        proto_request: T::ProtoRequest,
12975        position: Option<Anchor>,
12976        cx: &mut AsyncApp,
12977    ) -> Result<()>
12978    where
12979        T: LspCommand + Clone,
12980        T::ProtoRequest: proto::LspRequestMessage,
12981        <T::ProtoRequest as proto::RequestMessage>::Response:
12982            Into<<T::ProtoRequest as proto::LspRequestMessage>::Response>,
12983    {
12984        let buffer_id = BufferId::new(proto_request.buffer_id())?;
12985        let version = deserialize_version(proto_request.buffer_version());
12986        let buffer = lsp_store.update(cx, |this, cx| {
12987            this.buffer_store.read(cx).get_existing(buffer_id)
12988        })??;
12989        buffer
12990            .update(cx, |buffer, _| buffer.wait_for_version(version.clone()))?
12991            .await?;
12992        let buffer_version = buffer.read_with(cx, |buffer, _| buffer.version())?;
12993        let request =
12994            T::from_proto(proto_request, lsp_store.clone(), buffer.clone(), cx.clone()).await?;
12995        let key = LspKey {
12996            request_type: TypeId::of::<T>(),
12997            server_queried: for_server_id,
12998        };
12999        lsp_store.update(cx, |lsp_store, cx| {
13000            let request_task = match for_server_id {
13001                Some(server_id) => {
13002                    let server_task = lsp_store.request_lsp(
13003                        buffer.clone(),
13004                        LanguageServerToQuery::Other(server_id),
13005                        request.clone(),
13006                        cx,
13007                    );
13008                    cx.background_spawn(async move {
13009                        let mut responses = Vec::new();
13010                        match server_task.await {
13011                            Ok(response) => responses.push((server_id, response)),
13012                            // rust-analyzer likes to error with this when its still loading up
13013                            Err(e) if format!("{e:#}").ends_with("content modified") => (),
13014                            Err(e) => log::error!(
13015                                "Error handling response for request {request:?}: {e:#}"
13016                            ),
13017                        }
13018                        responses
13019                    })
13020                }
13021                None => lsp_store.request_multiple_lsp_locally(&buffer, position, request, cx),
13022            };
13023            let lsp_data = lsp_store.latest_lsp_data(&buffer, cx);
13024            if T::ProtoRequest::stop_previous_requests() {
13025                if let Some(lsp_requests) = lsp_data.lsp_requests.get_mut(&key) {
13026                    lsp_requests.clear();
13027                }
13028            }
13029            lsp_data.lsp_requests.entry(key).or_default().insert(
13030                lsp_request_id,
13031                cx.spawn(async move |lsp_store, cx| {
13032                    let response = request_task.await;
13033                    lsp_store
13034                        .update(cx, |lsp_store, cx| {
13035                            if let Some((client, project_id)) = lsp_store.downstream_client.clone()
13036                            {
13037                                let response = response
13038                                    .into_iter()
13039                                    .map(|(server_id, response)| {
13040                                        (
13041                                            server_id.to_proto(),
13042                                            T::response_to_proto(
13043                                                response,
13044                                                lsp_store,
13045                                                sender_id,
13046                                                &buffer_version,
13047                                                cx,
13048                                            )
13049                                            .into(),
13050                                        )
13051                                    })
13052                                    .collect::<HashMap<_, _>>();
13053                                match client.send_lsp_response::<T::ProtoRequest>(
13054                                    project_id,
13055                                    lsp_request_id,
13056                                    response,
13057                                ) {
13058                                    Ok(()) => {}
13059                                    Err(e) => {
13060                                        log::error!("Failed to send LSP response: {e:#}",)
13061                                    }
13062                                }
13063                            }
13064                        })
13065                        .ok();
13066                }),
13067            );
13068        })?;
13069        Ok(())
13070    }
13071
13072    fn take_text_document_sync_options(
13073        capabilities: &mut lsp::ServerCapabilities,
13074    ) -> lsp::TextDocumentSyncOptions {
13075        match capabilities.text_document_sync.take() {
13076            Some(lsp::TextDocumentSyncCapability::Options(sync_options)) => sync_options,
13077            Some(lsp::TextDocumentSyncCapability::Kind(sync_kind)) => {
13078                let mut sync_options = lsp::TextDocumentSyncOptions::default();
13079                sync_options.change = Some(sync_kind);
13080                sync_options
13081            }
13082            None => lsp::TextDocumentSyncOptions::default(),
13083        }
13084    }
13085
13086    #[cfg(any(test, feature = "test-support"))]
13087    pub fn forget_code_lens_task(&mut self, buffer_id: BufferId) -> Option<CodeLensTask> {
13088        Some(
13089            self.lsp_data
13090                .get_mut(&buffer_id)?
13091                .code_lens
13092                .take()?
13093                .update
13094                .take()?
13095                .1,
13096        )
13097    }
13098
13099    pub fn downstream_client(&self) -> Option<(AnyProtoClient, u64)> {
13100        self.downstream_client.clone()
13101    }
13102
13103    pub fn worktree_store(&self) -> Entity<WorktreeStore> {
13104        self.worktree_store.clone()
13105    }
13106
13107    /// Gets what's stored in the LSP data for the given buffer.
13108    pub fn current_lsp_data(&mut self, buffer_id: BufferId) -> Option<&mut BufferLspData> {
13109        self.lsp_data.get_mut(&buffer_id)
13110    }
13111
13112    /// Gets the most recent LSP data for the given buffer: if the data is absent or out of date,
13113    /// new [`BufferLspData`] will be created to replace the previous state.
13114    pub fn latest_lsp_data(&mut self, buffer: &Entity<Buffer>, cx: &mut App) -> &mut BufferLspData {
13115        let (buffer_id, buffer_version) =
13116            buffer.read_with(cx, |buffer, _| (buffer.remote_id(), buffer.version()));
13117        let lsp_data = self
13118            .lsp_data
13119            .entry(buffer_id)
13120            .or_insert_with(|| BufferLspData::new(buffer, cx));
13121        if buffer_version.changed_since(&lsp_data.buffer_version) {
13122            *lsp_data = BufferLspData::new(buffer, cx);
13123        }
13124        lsp_data
13125    }
13126}
13127
13128// Registration with registerOptions as null, should fallback to true.
13129// https://github.com/microsoft/vscode-languageserver-node/blob/d90a87f9557a0df9142cfb33e251cfa6fe27d970/client/src/common/client.ts#L2133
13130fn parse_register_capabilities<T: serde::de::DeserializeOwned>(
13131    reg: lsp::Registration,
13132) -> Result<OneOf<bool, T>> {
13133    Ok(match reg.register_options {
13134        Some(options) => OneOf::Right(serde_json::from_value::<T>(options)?),
13135        None => OneOf::Left(true),
13136    })
13137}
13138
13139fn subscribe_to_binary_statuses(
13140    languages: &Arc<LanguageRegistry>,
13141    cx: &mut Context<'_, LspStore>,
13142) -> Task<()> {
13143    let mut server_statuses = languages.language_server_binary_statuses();
13144    cx.spawn(async move |lsp_store, cx| {
13145        while let Some((server_name, binary_status)) = server_statuses.next().await {
13146            if lsp_store
13147                .update(cx, |_, cx| {
13148                    let mut message = None;
13149                    let binary_status = match binary_status {
13150                        BinaryStatus::None => proto::ServerBinaryStatus::None,
13151                        BinaryStatus::CheckingForUpdate => {
13152                            proto::ServerBinaryStatus::CheckingForUpdate
13153                        }
13154                        BinaryStatus::Downloading => proto::ServerBinaryStatus::Downloading,
13155                        BinaryStatus::Starting => proto::ServerBinaryStatus::Starting,
13156                        BinaryStatus::Stopping => proto::ServerBinaryStatus::Stopping,
13157                        BinaryStatus::Stopped => proto::ServerBinaryStatus::Stopped,
13158                        BinaryStatus::Failed { error } => {
13159                            message = Some(error);
13160                            proto::ServerBinaryStatus::Failed
13161                        }
13162                    };
13163                    cx.emit(LspStoreEvent::LanguageServerUpdate {
13164                        // Binary updates are about the binary that might not have any language server id at that point.
13165                        // Reuse `LanguageServerUpdate` for them and provide a fake id that won't be used on the receiver side.
13166                        language_server_id: LanguageServerId(0),
13167                        name: Some(server_name),
13168                        message: proto::update_language_server::Variant::StatusUpdate(
13169                            proto::StatusUpdate {
13170                                message,
13171                                status: Some(proto::status_update::Status::Binary(
13172                                    binary_status as i32,
13173                                )),
13174                            },
13175                        ),
13176                    });
13177                })
13178                .is_err()
13179            {
13180                break;
13181            }
13182        }
13183    })
13184}
13185
13186fn lsp_workspace_diagnostics_refresh(
13187    registration_id: Option<String>,
13188    options: DiagnosticServerCapabilities,
13189    server: Arc<LanguageServer>,
13190    cx: &mut Context<'_, LspStore>,
13191) -> Option<WorkspaceRefreshTask> {
13192    let identifier = workspace_diagnostic_identifier(&options)?;
13193    let registration_id_shared = registration_id.as_ref().map(SharedString::from);
13194
13195    let (progress_tx, mut progress_rx) = mpsc::channel(1);
13196    let (mut refresh_tx, mut refresh_rx) = mpsc::channel(1);
13197    refresh_tx.try_send(()).ok();
13198
13199    let workspace_query_language_server = cx.spawn(async move |lsp_store, cx| {
13200        let mut attempts = 0;
13201        let max_attempts = 50;
13202        let mut requests = 0;
13203
13204        loop {
13205            let Some(()) = refresh_rx.recv().await else {
13206                return;
13207            };
13208
13209            'request: loop {
13210                requests += 1;
13211                if attempts > max_attempts {
13212                    log::error!(
13213                        "Failed to pull workspace diagnostics {max_attempts} times, aborting"
13214                    );
13215                    return;
13216                }
13217                let backoff_millis = (50 * (1 << attempts)).clamp(30, 1000);
13218                cx.background_executor()
13219                    .timer(Duration::from_millis(backoff_millis))
13220                    .await;
13221                attempts += 1;
13222
13223                let Ok(previous_result_ids) = lsp_store.update(cx, |lsp_store, _| {
13224                    lsp_store
13225                        .result_ids_for_workspace_refresh(server.server_id(), &registration_id_shared)
13226                        .into_iter()
13227                        .filter_map(|(abs_path, result_id)| {
13228                            let uri = file_path_to_lsp_url(&abs_path).ok()?;
13229                            Some(lsp::PreviousResultId {
13230                                uri,
13231                                value: result_id.to_string(),
13232                            })
13233                        })
13234                        .collect()
13235                }) else {
13236                    return;
13237                };
13238
13239                let token = if let Some(registration_id) = &registration_id {
13240                    format!(
13241                        "workspace/diagnostic/{}/{requests}/{WORKSPACE_DIAGNOSTICS_TOKEN_START}{registration_id}",
13242                        server.server_id(),
13243                    )
13244                } else {
13245                    format!("workspace/diagnostic/{}/{requests}", server.server_id())
13246                };
13247
13248                progress_rx.try_recv().ok();
13249                let timer =
13250                    LanguageServer::default_request_timer(cx.background_executor().clone()).fuse();
13251                let progress = pin!(progress_rx.recv().fuse());
13252                let response_result = server
13253                    .request_with_timer::<lsp::WorkspaceDiagnosticRequest, _>(
13254                        lsp::WorkspaceDiagnosticParams {
13255                            previous_result_ids,
13256                            identifier: identifier.clone(),
13257                            work_done_progress_params: Default::default(),
13258                            partial_result_params: lsp::PartialResultParams {
13259                                partial_result_token: Some(lsp::ProgressToken::String(token)),
13260                            },
13261                        },
13262                        select(timer, progress).then(|either| match either {
13263                            Either::Left((message, ..)) => ready(message).left_future(),
13264                            Either::Right(..) => pending::<String>().right_future(),
13265                        }),
13266                    )
13267                    .await;
13268
13269                // https://microsoft.github.io/language-server-protocol/specifications/lsp/3.17/specification/#diagnostic_refresh
13270                // >  If a server closes a workspace diagnostic pull request the client should re-trigger the request.
13271                match response_result {
13272                    ConnectionResult::Timeout => {
13273                        log::error!("Timeout during workspace diagnostics pull");
13274                        continue 'request;
13275                    }
13276                    ConnectionResult::ConnectionReset => {
13277                        log::error!("Server closed a workspace diagnostics pull request");
13278                        continue 'request;
13279                    }
13280                    ConnectionResult::Result(Err(e)) => {
13281                        log::error!("Error during workspace diagnostics pull: {e:#}");
13282                        break 'request;
13283                    }
13284                    ConnectionResult::Result(Ok(pulled_diagnostics)) => {
13285                        attempts = 0;
13286                        if lsp_store
13287                            .update(cx, |lsp_store, cx| {
13288                                lsp_store.apply_workspace_diagnostic_report(
13289                                    server.server_id(),
13290                                    pulled_diagnostics,
13291                                    registration_id_shared.clone(),
13292                                    cx,
13293                                )
13294                            })
13295                            .is_err()
13296                        {
13297                            return;
13298                        }
13299                        break 'request;
13300                    }
13301                }
13302            }
13303        }
13304    });
13305
13306    Some(WorkspaceRefreshTask {
13307        refresh_tx,
13308        progress_tx,
13309        task: workspace_query_language_server,
13310    })
13311}
13312
13313fn buffer_diagnostic_identifier(options: &DiagnosticServerCapabilities) -> Option<String> {
13314    match &options {
13315        lsp::DiagnosticServerCapabilities::Options(diagnostic_options) => {
13316            diagnostic_options.identifier.clone()
13317        }
13318        lsp::DiagnosticServerCapabilities::RegistrationOptions(registration_options) => {
13319            let diagnostic_options = &registration_options.diagnostic_options;
13320            diagnostic_options.identifier.clone()
13321        }
13322    }
13323}
13324
13325fn workspace_diagnostic_identifier(
13326    options: &DiagnosticServerCapabilities,
13327) -> Option<Option<String>> {
13328    match &options {
13329        lsp::DiagnosticServerCapabilities::Options(diagnostic_options) => {
13330            if !diagnostic_options.workspace_diagnostics {
13331                return None;
13332            }
13333            Some(diagnostic_options.identifier.clone())
13334        }
13335        lsp::DiagnosticServerCapabilities::RegistrationOptions(registration_options) => {
13336            let diagnostic_options = &registration_options.diagnostic_options;
13337            if !diagnostic_options.workspace_diagnostics {
13338                return None;
13339            }
13340            Some(diagnostic_options.identifier.clone())
13341        }
13342    }
13343}
13344
13345fn resolve_word_completion(snapshot: &BufferSnapshot, completion: &mut Completion) {
13346    let CompletionSource::BufferWord {
13347        word_range,
13348        resolved,
13349    } = &mut completion.source
13350    else {
13351        return;
13352    };
13353    if *resolved {
13354        return;
13355    }
13356
13357    if completion.new_text
13358        != snapshot
13359            .text_for_range(word_range.clone())
13360            .collect::<String>()
13361    {
13362        return;
13363    }
13364
13365    let mut offset = 0;
13366    for chunk in snapshot.chunks(word_range.clone(), true) {
13367        let end_offset = offset + chunk.text.len();
13368        if let Some(highlight_id) = chunk.syntax_highlight_id {
13369            completion
13370                .label
13371                .runs
13372                .push((offset..end_offset, highlight_id));
13373        }
13374        offset = end_offset;
13375    }
13376    *resolved = true;
13377}
13378
13379impl EventEmitter<LspStoreEvent> for LspStore {}
13380
13381fn remove_empty_hover_blocks(mut hover: Hover) -> Option<Hover> {
13382    hover
13383        .contents
13384        .retain(|hover_block| !hover_block.text.trim().is_empty());
13385    if hover.contents.is_empty() {
13386        None
13387    } else {
13388        Some(hover)
13389    }
13390}
13391
13392async fn populate_labels_for_completions(
13393    new_completions: Vec<CoreCompletion>,
13394    language: Option<Arc<Language>>,
13395    lsp_adapter: Option<Arc<CachedLspAdapter>>,
13396) -> Vec<Completion> {
13397    let lsp_completions = new_completions
13398        .iter()
13399        .filter_map(|new_completion| {
13400            new_completion
13401                .source
13402                .lsp_completion(true)
13403                .map(|lsp_completion| lsp_completion.into_owned())
13404        })
13405        .collect::<Vec<_>>();
13406
13407    let mut labels = if let Some((language, lsp_adapter)) = language.as_ref().zip(lsp_adapter) {
13408        lsp_adapter
13409            .labels_for_completions(&lsp_completions, language)
13410            .await
13411            .log_err()
13412            .unwrap_or_default()
13413    } else {
13414        Vec::new()
13415    }
13416    .into_iter()
13417    .fuse();
13418
13419    let mut completions = Vec::new();
13420    for completion in new_completions {
13421        match completion.source.lsp_completion(true) {
13422            Some(lsp_completion) => {
13423                let documentation = lsp_completion.documentation.clone().map(|docs| docs.into());
13424
13425                let mut label = labels.next().flatten().unwrap_or_else(|| {
13426                    CodeLabel::fallback_for_completion(&lsp_completion, language.as_deref())
13427                });
13428                ensure_uniform_list_compatible_label(&mut label);
13429                completions.push(Completion {
13430                    label,
13431                    documentation,
13432                    replace_range: completion.replace_range,
13433                    new_text: completion.new_text,
13434                    insert_text_mode: lsp_completion.insert_text_mode,
13435                    source: completion.source,
13436                    icon_path: None,
13437                    confirm: None,
13438                    match_start: None,
13439                    snippet_deduplication_key: None,
13440                });
13441            }
13442            None => {
13443                let mut label = CodeLabel::plain(completion.new_text.clone(), None);
13444                ensure_uniform_list_compatible_label(&mut label);
13445                completions.push(Completion {
13446                    label,
13447                    documentation: None,
13448                    replace_range: completion.replace_range,
13449                    new_text: completion.new_text,
13450                    source: completion.source,
13451                    insert_text_mode: None,
13452                    icon_path: None,
13453                    confirm: None,
13454                    match_start: None,
13455                    snippet_deduplication_key: None,
13456                });
13457            }
13458        }
13459    }
13460    completions
13461}
13462
13463#[derive(Debug)]
13464pub enum LanguageServerToQuery {
13465    /// Query language servers in order of users preference, up until one capable of handling the request is found.
13466    FirstCapable,
13467    /// Query a specific language server.
13468    Other(LanguageServerId),
13469}
13470
13471#[derive(Default)]
13472struct RenamePathsWatchedForServer {
13473    did_rename: Vec<RenameActionPredicate>,
13474    will_rename: Vec<RenameActionPredicate>,
13475}
13476
13477impl RenamePathsWatchedForServer {
13478    fn with_did_rename_patterns(
13479        mut self,
13480        did_rename: Option<&FileOperationRegistrationOptions>,
13481    ) -> Self {
13482        if let Some(did_rename) = did_rename {
13483            self.did_rename = did_rename
13484                .filters
13485                .iter()
13486                .filter_map(|filter| filter.try_into().log_err())
13487                .collect();
13488        }
13489        self
13490    }
13491    fn with_will_rename_patterns(
13492        mut self,
13493        will_rename: Option<&FileOperationRegistrationOptions>,
13494    ) -> Self {
13495        if let Some(will_rename) = will_rename {
13496            self.will_rename = will_rename
13497                .filters
13498                .iter()
13499                .filter_map(|filter| filter.try_into().log_err())
13500                .collect();
13501        }
13502        self
13503    }
13504
13505    fn should_send_did_rename(&self, path: &str, is_dir: bool) -> bool {
13506        self.did_rename.iter().any(|pred| pred.eval(path, is_dir))
13507    }
13508    fn should_send_will_rename(&self, path: &str, is_dir: bool) -> bool {
13509        self.will_rename.iter().any(|pred| pred.eval(path, is_dir))
13510    }
13511}
13512
13513impl TryFrom<&FileOperationFilter> for RenameActionPredicate {
13514    type Error = globset::Error;
13515    fn try_from(ops: &FileOperationFilter) -> Result<Self, globset::Error> {
13516        Ok(Self {
13517            kind: ops.pattern.matches.clone(),
13518            glob: GlobBuilder::new(&ops.pattern.glob)
13519                .case_insensitive(
13520                    ops.pattern
13521                        .options
13522                        .as_ref()
13523                        .is_some_and(|ops| ops.ignore_case.unwrap_or(false)),
13524                )
13525                .build()?
13526                .compile_matcher(),
13527        })
13528    }
13529}
13530struct RenameActionPredicate {
13531    glob: GlobMatcher,
13532    kind: Option<FileOperationPatternKind>,
13533}
13534
13535impl RenameActionPredicate {
13536    // Returns true if language server should be notified
13537    fn eval(&self, path: &str, is_dir: bool) -> bool {
13538        self.kind.as_ref().is_none_or(|kind| {
13539            let expected_kind = if is_dir {
13540                FileOperationPatternKind::Folder
13541            } else {
13542                FileOperationPatternKind::File
13543            };
13544            kind == &expected_kind
13545        }) && self.glob.is_match(path)
13546    }
13547}
13548
13549#[derive(Default)]
13550struct LanguageServerWatchedPaths {
13551    worktree_paths: HashMap<WorktreeId, GlobSet>,
13552    abs_paths: HashMap<Arc<Path>, (GlobSet, Task<()>)>,
13553}
13554
13555#[derive(Default)]
13556struct LanguageServerWatchedPathsBuilder {
13557    worktree_paths: HashMap<WorktreeId, GlobSet>,
13558    abs_paths: HashMap<Arc<Path>, GlobSet>,
13559}
13560
13561impl LanguageServerWatchedPathsBuilder {
13562    fn watch_worktree(&mut self, worktree_id: WorktreeId, glob_set: GlobSet) {
13563        self.worktree_paths.insert(worktree_id, glob_set);
13564    }
13565    fn watch_abs_path(&mut self, path: Arc<Path>, glob_set: GlobSet) {
13566        self.abs_paths.insert(path, glob_set);
13567    }
13568    fn build(
13569        self,
13570        fs: Arc<dyn Fs>,
13571        language_server_id: LanguageServerId,
13572        cx: &mut Context<LspStore>,
13573    ) -> LanguageServerWatchedPaths {
13574        let lsp_store = cx.weak_entity();
13575
13576        const LSP_ABS_PATH_OBSERVE: Duration = Duration::from_millis(100);
13577        let abs_paths = self
13578            .abs_paths
13579            .into_iter()
13580            .map(|(abs_path, globset)| {
13581                let task = cx.spawn({
13582                    let abs_path = abs_path.clone();
13583                    let fs = fs.clone();
13584
13585                    let lsp_store = lsp_store.clone();
13586                    async move |_, cx| {
13587                        maybe!(async move {
13588                            let mut push_updates = fs.watch(&abs_path, LSP_ABS_PATH_OBSERVE).await;
13589                            while let Some(update) = push_updates.0.next().await {
13590                                let action = lsp_store
13591                                    .update(cx, |this, _| {
13592                                        let Some(local) = this.as_local() else {
13593                                            return ControlFlow::Break(());
13594                                        };
13595                                        let Some(watcher) = local
13596                                            .language_server_watched_paths
13597                                            .get(&language_server_id)
13598                                        else {
13599                                            return ControlFlow::Break(());
13600                                        };
13601                                        let (globs, _) = watcher.abs_paths.get(&abs_path).expect(
13602                                            "Watched abs path is not registered with a watcher",
13603                                        );
13604                                        let matching_entries = update
13605                                            .into_iter()
13606                                            .filter(|event| globs.is_match(&event.path))
13607                                            .collect::<Vec<_>>();
13608                                        this.lsp_notify_abs_paths_changed(
13609                                            language_server_id,
13610                                            matching_entries,
13611                                        );
13612                                        ControlFlow::Continue(())
13613                                    })
13614                                    .ok()?;
13615
13616                                if action.is_break() {
13617                                    break;
13618                                }
13619                            }
13620                            Some(())
13621                        })
13622                        .await;
13623                    }
13624                });
13625                (abs_path, (globset, task))
13626            })
13627            .collect();
13628        LanguageServerWatchedPaths {
13629            worktree_paths: self.worktree_paths,
13630            abs_paths,
13631        }
13632    }
13633}
13634
13635struct LspBufferSnapshot {
13636    version: i32,
13637    snapshot: TextBufferSnapshot,
13638}
13639
13640/// A prompt requested by LSP server.
13641#[derive(Clone, Debug)]
13642pub struct LanguageServerPromptRequest {
13643    pub level: PromptLevel,
13644    pub message: String,
13645    pub actions: Vec<MessageActionItem>,
13646    pub lsp_name: String,
13647    pub(crate) response_channel: Sender<MessageActionItem>,
13648}
13649
13650impl LanguageServerPromptRequest {
13651    pub async fn respond(self, index: usize) -> Option<()> {
13652        if let Some(response) = self.actions.into_iter().nth(index) {
13653            self.response_channel.send(response).await.ok()
13654        } else {
13655            None
13656        }
13657    }
13658}
13659impl PartialEq for LanguageServerPromptRequest {
13660    fn eq(&self, other: &Self) -> bool {
13661        self.message == other.message && self.actions == other.actions
13662    }
13663}
13664
13665#[derive(Clone, Debug, PartialEq)]
13666pub enum LanguageServerLogType {
13667    Log(MessageType),
13668    Trace { verbose_info: Option<String> },
13669    Rpc { received: bool },
13670}
13671
13672impl LanguageServerLogType {
13673    pub fn to_proto(&self) -> proto::language_server_log::LogType {
13674        match self {
13675            Self::Log(log_type) => {
13676                use proto::log_message::LogLevel;
13677                let level = match *log_type {
13678                    MessageType::ERROR => LogLevel::Error,
13679                    MessageType::WARNING => LogLevel::Warning,
13680                    MessageType::INFO => LogLevel::Info,
13681                    MessageType::LOG => LogLevel::Log,
13682                    other => {
13683                        log::warn!("Unknown lsp log message type: {other:?}");
13684                        LogLevel::Log
13685                    }
13686                };
13687                proto::language_server_log::LogType::Log(proto::LogMessage {
13688                    level: level as i32,
13689                })
13690            }
13691            Self::Trace { verbose_info } => {
13692                proto::language_server_log::LogType::Trace(proto::TraceMessage {
13693                    verbose_info: verbose_info.to_owned(),
13694                })
13695            }
13696            Self::Rpc { received } => {
13697                let kind = if *received {
13698                    proto::rpc_message::Kind::Received
13699                } else {
13700                    proto::rpc_message::Kind::Sent
13701                };
13702                let kind = kind as i32;
13703                proto::language_server_log::LogType::Rpc(proto::RpcMessage { kind })
13704            }
13705        }
13706    }
13707
13708    pub fn from_proto(log_type: proto::language_server_log::LogType) -> Self {
13709        use proto::log_message::LogLevel;
13710        use proto::rpc_message;
13711        match log_type {
13712            proto::language_server_log::LogType::Log(message_type) => Self::Log(
13713                match LogLevel::from_i32(message_type.level).unwrap_or(LogLevel::Log) {
13714                    LogLevel::Error => MessageType::ERROR,
13715                    LogLevel::Warning => MessageType::WARNING,
13716                    LogLevel::Info => MessageType::INFO,
13717                    LogLevel::Log => MessageType::LOG,
13718                },
13719            ),
13720            proto::language_server_log::LogType::Trace(trace_message) => Self::Trace {
13721                verbose_info: trace_message.verbose_info,
13722            },
13723            proto::language_server_log::LogType::Rpc(message) => Self::Rpc {
13724                received: match rpc_message::Kind::from_i32(message.kind)
13725                    .unwrap_or(rpc_message::Kind::Received)
13726                {
13727                    rpc_message::Kind::Received => true,
13728                    rpc_message::Kind::Sent => false,
13729                },
13730            },
13731        }
13732    }
13733}
13734
13735pub struct WorkspaceRefreshTask {
13736    refresh_tx: mpsc::Sender<()>,
13737    progress_tx: mpsc::Sender<()>,
13738    #[allow(dead_code)]
13739    task: Task<()>,
13740}
13741
13742pub enum LanguageServerState {
13743    Starting {
13744        startup: Task<Option<Arc<LanguageServer>>>,
13745        /// List of language servers that will be added to the workspace once it's initialization completes.
13746        pending_workspace_folders: Arc<Mutex<BTreeSet<Uri>>>,
13747    },
13748
13749    Running {
13750        adapter: Arc<CachedLspAdapter>,
13751        server: Arc<LanguageServer>,
13752        simulate_disk_based_diagnostics_completion: Option<Task<()>>,
13753        workspace_diagnostics_refresh_tasks: HashMap<Option<String>, WorkspaceRefreshTask>,
13754    },
13755}
13756
13757impl LanguageServerState {
13758    fn add_workspace_folder(&self, uri: Uri) {
13759        match self {
13760            LanguageServerState::Starting {
13761                pending_workspace_folders,
13762                ..
13763            } => {
13764                pending_workspace_folders.lock().insert(uri);
13765            }
13766            LanguageServerState::Running { server, .. } => {
13767                server.add_workspace_folder(uri);
13768            }
13769        }
13770    }
13771    fn _remove_workspace_folder(&self, uri: Uri) {
13772        match self {
13773            LanguageServerState::Starting {
13774                pending_workspace_folders,
13775                ..
13776            } => {
13777                pending_workspace_folders.lock().remove(&uri);
13778            }
13779            LanguageServerState::Running { server, .. } => server.remove_workspace_folder(uri),
13780        }
13781    }
13782}
13783
13784impl std::fmt::Debug for LanguageServerState {
13785    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
13786        match self {
13787            LanguageServerState::Starting { .. } => {
13788                f.debug_struct("LanguageServerState::Starting").finish()
13789            }
13790            LanguageServerState::Running { .. } => {
13791                f.debug_struct("LanguageServerState::Running").finish()
13792            }
13793        }
13794    }
13795}
13796
13797#[derive(Clone, Debug, Serialize)]
13798pub struct LanguageServerProgress {
13799    pub is_disk_based_diagnostics_progress: bool,
13800    pub is_cancellable: bool,
13801    pub title: Option<String>,
13802    pub message: Option<String>,
13803    pub percentage: Option<usize>,
13804    #[serde(skip_serializing)]
13805    pub last_update_at: Instant,
13806}
13807
13808#[derive(Copy, Clone, Debug, Default, PartialEq, Serialize)]
13809pub struct DiagnosticSummary {
13810    pub error_count: usize,
13811    pub warning_count: usize,
13812}
13813
13814impl DiagnosticSummary {
13815    pub fn new<'a, T: 'a>(diagnostics: impl IntoIterator<Item = &'a DiagnosticEntry<T>>) -> Self {
13816        let mut this = Self {
13817            error_count: 0,
13818            warning_count: 0,
13819        };
13820
13821        for entry in diagnostics {
13822            if entry.diagnostic.is_primary {
13823                match entry.diagnostic.severity {
13824                    DiagnosticSeverity::ERROR => this.error_count += 1,
13825                    DiagnosticSeverity::WARNING => this.warning_count += 1,
13826                    _ => {}
13827                }
13828            }
13829        }
13830
13831        this
13832    }
13833
13834    pub fn is_empty(&self) -> bool {
13835        self.error_count == 0 && self.warning_count == 0
13836    }
13837
13838    pub fn to_proto(
13839        self,
13840        language_server_id: LanguageServerId,
13841        path: &RelPath,
13842    ) -> proto::DiagnosticSummary {
13843        proto::DiagnosticSummary {
13844            path: path.to_proto(),
13845            language_server_id: language_server_id.0 as u64,
13846            error_count: self.error_count as u32,
13847            warning_count: self.warning_count as u32,
13848        }
13849    }
13850}
13851
13852#[derive(Clone, Debug)]
13853pub enum CompletionDocumentation {
13854    /// There is no documentation for this completion.
13855    Undocumented,
13856    /// A single line of documentation.
13857    SingleLine(SharedString),
13858    /// Multiple lines of plain text documentation.
13859    MultiLinePlainText(SharedString),
13860    /// Markdown documentation.
13861    MultiLineMarkdown(SharedString),
13862    /// Both single line and multiple lines of plain text documentation.
13863    SingleLineAndMultiLinePlainText {
13864        single_line: SharedString,
13865        plain_text: Option<SharedString>,
13866    },
13867}
13868
13869impl CompletionDocumentation {
13870    #[cfg(any(test, feature = "test-support"))]
13871    pub fn text(&self) -> SharedString {
13872        match self {
13873            CompletionDocumentation::Undocumented => "".into(),
13874            CompletionDocumentation::SingleLine(s) => s.clone(),
13875            CompletionDocumentation::MultiLinePlainText(s) => s.clone(),
13876            CompletionDocumentation::MultiLineMarkdown(s) => s.clone(),
13877            CompletionDocumentation::SingleLineAndMultiLinePlainText { single_line, .. } => {
13878                single_line.clone()
13879            }
13880        }
13881    }
13882}
13883
13884impl From<lsp::Documentation> for CompletionDocumentation {
13885    fn from(docs: lsp::Documentation) -> Self {
13886        match docs {
13887            lsp::Documentation::String(text) => {
13888                if text.lines().count() <= 1 {
13889                    CompletionDocumentation::SingleLine(text.into())
13890                } else {
13891                    CompletionDocumentation::MultiLinePlainText(text.into())
13892                }
13893            }
13894
13895            lsp::Documentation::MarkupContent(lsp::MarkupContent { kind, value }) => match kind {
13896                lsp::MarkupKind::PlainText => {
13897                    if value.lines().count() <= 1 {
13898                        CompletionDocumentation::SingleLine(value.into())
13899                    } else {
13900                        CompletionDocumentation::MultiLinePlainText(value.into())
13901                    }
13902                }
13903
13904                lsp::MarkupKind::Markdown => {
13905                    CompletionDocumentation::MultiLineMarkdown(value.into())
13906                }
13907            },
13908        }
13909    }
13910}
13911
13912pub enum ResolvedHint {
13913    Resolved(InlayHint),
13914    Resolving(Shared<Task<()>>),
13915}
13916
13917fn glob_literal_prefix(glob: &Path) -> PathBuf {
13918    glob.components()
13919        .take_while(|component| match component {
13920            path::Component::Normal(part) => !part.to_string_lossy().contains(['*', '?', '{', '}']),
13921            _ => true,
13922        })
13923        .collect()
13924}
13925
13926pub struct SshLspAdapter {
13927    name: LanguageServerName,
13928    binary: LanguageServerBinary,
13929    initialization_options: Option<String>,
13930    code_action_kinds: Option<Vec<CodeActionKind>>,
13931}
13932
13933impl SshLspAdapter {
13934    pub fn new(
13935        name: LanguageServerName,
13936        binary: LanguageServerBinary,
13937        initialization_options: Option<String>,
13938        code_action_kinds: Option<String>,
13939    ) -> Self {
13940        Self {
13941            name,
13942            binary,
13943            initialization_options,
13944            code_action_kinds: code_action_kinds
13945                .as_ref()
13946                .and_then(|c| serde_json::from_str(c).ok()),
13947        }
13948    }
13949}
13950
13951impl LspInstaller for SshLspAdapter {
13952    type BinaryVersion = ();
13953    async fn check_if_user_installed(
13954        &self,
13955        _: &dyn LspAdapterDelegate,
13956        _: Option<Toolchain>,
13957        _: &AsyncApp,
13958    ) -> Option<LanguageServerBinary> {
13959        Some(self.binary.clone())
13960    }
13961
13962    async fn cached_server_binary(
13963        &self,
13964        _: PathBuf,
13965        _: &dyn LspAdapterDelegate,
13966    ) -> Option<LanguageServerBinary> {
13967        None
13968    }
13969
13970    async fn fetch_latest_server_version(
13971        &self,
13972        _: &dyn LspAdapterDelegate,
13973        _: bool,
13974        _: &mut AsyncApp,
13975    ) -> Result<()> {
13976        anyhow::bail!("SshLspAdapter does not support fetch_latest_server_version")
13977    }
13978
13979    async fn fetch_server_binary(
13980        &self,
13981        _: (),
13982        _: PathBuf,
13983        _: &dyn LspAdapterDelegate,
13984    ) -> Result<LanguageServerBinary> {
13985        anyhow::bail!("SshLspAdapter does not support fetch_server_binary")
13986    }
13987}
13988
13989#[async_trait(?Send)]
13990impl LspAdapter for SshLspAdapter {
13991    fn name(&self) -> LanguageServerName {
13992        self.name.clone()
13993    }
13994
13995    async fn initialization_options(
13996        self: Arc<Self>,
13997        _: &Arc<dyn LspAdapterDelegate>,
13998    ) -> Result<Option<serde_json::Value>> {
13999        let Some(options) = &self.initialization_options else {
14000            return Ok(None);
14001        };
14002        let result = serde_json::from_str(options)?;
14003        Ok(result)
14004    }
14005
14006    fn code_action_kinds(&self) -> Option<Vec<CodeActionKind>> {
14007        self.code_action_kinds.clone()
14008    }
14009}
14010
14011pub fn language_server_settings<'a>(
14012    delegate: &'a dyn LspAdapterDelegate,
14013    language: &LanguageServerName,
14014    cx: &'a App,
14015) -> Option<&'a LspSettings> {
14016    language_server_settings_for(
14017        SettingsLocation {
14018            worktree_id: delegate.worktree_id(),
14019            path: RelPath::empty(),
14020        },
14021        language,
14022        cx,
14023    )
14024}
14025
14026pub fn language_server_settings_for<'a>(
14027    location: SettingsLocation<'a>,
14028    language: &LanguageServerName,
14029    cx: &'a App,
14030) -> Option<&'a LspSettings> {
14031    ProjectSettings::get(Some(location), cx).lsp.get(language)
14032}
14033
14034pub struct LocalLspAdapterDelegate {
14035    lsp_store: WeakEntity<LspStore>,
14036    worktree: worktree::Snapshot,
14037    fs: Arc<dyn Fs>,
14038    http_client: Arc<dyn HttpClient>,
14039    language_registry: Arc<LanguageRegistry>,
14040    load_shell_env_task: Shared<Task<Option<HashMap<String, String>>>>,
14041}
14042
14043impl LocalLspAdapterDelegate {
14044    pub fn new(
14045        language_registry: Arc<LanguageRegistry>,
14046        environment: &Entity<ProjectEnvironment>,
14047        lsp_store: WeakEntity<LspStore>,
14048        worktree: &Entity<Worktree>,
14049        http_client: Arc<dyn HttpClient>,
14050        fs: Arc<dyn Fs>,
14051        cx: &mut App,
14052    ) -> Arc<Self> {
14053        let load_shell_env_task =
14054            environment.update(cx, |env, cx| env.worktree_environment(worktree.clone(), cx));
14055
14056        Arc::new(Self {
14057            lsp_store,
14058            worktree: worktree.read(cx).snapshot(),
14059            fs,
14060            http_client,
14061            language_registry,
14062            load_shell_env_task,
14063        })
14064    }
14065
14066    fn from_local_lsp(
14067        local: &LocalLspStore,
14068        worktree: &Entity<Worktree>,
14069        cx: &mut App,
14070    ) -> Arc<Self> {
14071        Self::new(
14072            local.languages.clone(),
14073            &local.environment,
14074            local.weak.clone(),
14075            worktree,
14076            local.http_client.clone(),
14077            local.fs.clone(),
14078            cx,
14079        )
14080    }
14081}
14082
14083#[async_trait]
14084impl LspAdapterDelegate for LocalLspAdapterDelegate {
14085    fn show_notification(&self, message: &str, cx: &mut App) {
14086        self.lsp_store
14087            .update(cx, |_, cx| {
14088                cx.emit(LspStoreEvent::Notification(message.to_owned()))
14089            })
14090            .ok();
14091    }
14092
14093    fn http_client(&self) -> Arc<dyn HttpClient> {
14094        self.http_client.clone()
14095    }
14096
14097    fn worktree_id(&self) -> WorktreeId {
14098        self.worktree.id()
14099    }
14100
14101    fn worktree_root_path(&self) -> &Path {
14102        self.worktree.abs_path().as_ref()
14103    }
14104
14105    fn resolve_executable_path(&self, path: PathBuf) -> PathBuf {
14106        self.worktree.resolve_executable_path(path)
14107    }
14108
14109    async fn shell_env(&self) -> HashMap<String, String> {
14110        let task = self.load_shell_env_task.clone();
14111        task.await.unwrap_or_default()
14112    }
14113
14114    async fn npm_package_installed_version(
14115        &self,
14116        package_name: &str,
14117    ) -> Result<Option<(PathBuf, String)>> {
14118        let local_package_directory = self.worktree_root_path();
14119        let node_modules_directory = local_package_directory.join("node_modules");
14120
14121        if let Some(version) =
14122            read_package_installed_version(node_modules_directory.clone(), package_name).await?
14123        {
14124            return Ok(Some((node_modules_directory, version)));
14125        }
14126        let Some(npm) = self.which("npm".as_ref()).await else {
14127            log::warn!(
14128                "Failed to find npm executable for {:?}",
14129                local_package_directory
14130            );
14131            return Ok(None);
14132        };
14133
14134        let env = self.shell_env().await;
14135        let output = util::command::new_smol_command(&npm)
14136            .args(["root", "-g"])
14137            .envs(env)
14138            .current_dir(local_package_directory)
14139            .output()
14140            .await?;
14141        let global_node_modules =
14142            PathBuf::from(String::from_utf8_lossy(&output.stdout).to_string());
14143
14144        if let Some(version) =
14145            read_package_installed_version(global_node_modules.clone(), package_name).await?
14146        {
14147            return Ok(Some((global_node_modules, version)));
14148        }
14149        return Ok(None);
14150    }
14151
14152    async fn which(&self, command: &OsStr) -> Option<PathBuf> {
14153        let mut worktree_abs_path = self.worktree_root_path().to_path_buf();
14154        if self.fs.is_file(&worktree_abs_path).await {
14155            worktree_abs_path.pop();
14156        }
14157
14158        let env = self.shell_env().await;
14159
14160        let shell_path = env.get("PATH").cloned();
14161
14162        which::which_in(command, shell_path.as_ref(), worktree_abs_path).ok()
14163    }
14164
14165    async fn try_exec(&self, command: LanguageServerBinary) -> Result<()> {
14166        let mut working_dir = self.worktree_root_path().to_path_buf();
14167        if self.fs.is_file(&working_dir).await {
14168            working_dir.pop();
14169        }
14170        let output = util::command::new_smol_command(&command.path)
14171            .args(command.arguments)
14172            .envs(command.env.clone().unwrap_or_default())
14173            .current_dir(working_dir)
14174            .output()
14175            .await?;
14176
14177        anyhow::ensure!(
14178            output.status.success(),
14179            "{}, stdout: {:?}, stderr: {:?}",
14180            output.status,
14181            String::from_utf8_lossy(&output.stdout),
14182            String::from_utf8_lossy(&output.stderr)
14183        );
14184        Ok(())
14185    }
14186
14187    fn update_status(&self, server_name: LanguageServerName, status: language::BinaryStatus) {
14188        self.language_registry
14189            .update_lsp_binary_status(server_name, status);
14190    }
14191
14192    fn registered_lsp_adapters(&self) -> Vec<Arc<dyn LspAdapter>> {
14193        self.language_registry
14194            .all_lsp_adapters()
14195            .into_iter()
14196            .map(|adapter| adapter.adapter.clone() as Arc<dyn LspAdapter>)
14197            .collect()
14198    }
14199
14200    async fn language_server_download_dir(&self, name: &LanguageServerName) -> Option<Arc<Path>> {
14201        let dir = self.language_registry.language_server_download_dir(name)?;
14202
14203        if !dir.exists() {
14204            smol::fs::create_dir_all(&dir)
14205                .await
14206                .context("failed to create container directory")
14207                .log_err()?;
14208        }
14209
14210        Some(dir)
14211    }
14212
14213    async fn read_text_file(&self, path: &RelPath) -> Result<String> {
14214        let entry = self
14215            .worktree
14216            .entry_for_path(path)
14217            .with_context(|| format!("no worktree entry for path {path:?}"))?;
14218        let abs_path = self.worktree.absolutize(&entry.path);
14219        self.fs.load(&abs_path).await
14220    }
14221}
14222
14223async fn populate_labels_for_symbols(
14224    symbols: Vec<CoreSymbol>,
14225    language_registry: &Arc<LanguageRegistry>,
14226    lsp_adapter: Option<Arc<CachedLspAdapter>>,
14227    output: &mut Vec<Symbol>,
14228) {
14229    #[allow(clippy::mutable_key_type)]
14230    let mut symbols_by_language = HashMap::<Option<Arc<Language>>, Vec<CoreSymbol>>::default();
14231
14232    let mut unknown_paths = BTreeSet::<Arc<str>>::new();
14233    for symbol in symbols {
14234        let Some(file_name) = symbol.path.file_name() else {
14235            continue;
14236        };
14237        let language = language_registry
14238            .load_language_for_file_path(Path::new(file_name))
14239            .await
14240            .ok()
14241            .or_else(|| {
14242                unknown_paths.insert(file_name.into());
14243                None
14244            });
14245        symbols_by_language
14246            .entry(language)
14247            .or_default()
14248            .push(symbol);
14249    }
14250
14251    for unknown_path in unknown_paths {
14252        log::info!("no language found for symbol in file {unknown_path:?}");
14253    }
14254
14255    let mut label_params = Vec::new();
14256    for (language, mut symbols) in symbols_by_language {
14257        label_params.clear();
14258        label_params.extend(
14259            symbols
14260                .iter_mut()
14261                .map(|symbol| (mem::take(&mut symbol.name), symbol.kind)),
14262        );
14263
14264        let mut labels = Vec::new();
14265        if let Some(language) = language {
14266            let lsp_adapter = lsp_adapter.clone().or_else(|| {
14267                language_registry
14268                    .lsp_adapters(&language.name())
14269                    .first()
14270                    .cloned()
14271            });
14272            if let Some(lsp_adapter) = lsp_adapter {
14273                labels = lsp_adapter
14274                    .labels_for_symbols(&label_params, &language)
14275                    .await
14276                    .log_err()
14277                    .unwrap_or_default();
14278            }
14279        }
14280
14281        for ((symbol, (name, _)), label) in symbols
14282            .into_iter()
14283            .zip(label_params.drain(..))
14284            .zip(labels.into_iter().chain(iter::repeat(None)))
14285        {
14286            output.push(Symbol {
14287                language_server_name: symbol.language_server_name,
14288                source_worktree_id: symbol.source_worktree_id,
14289                source_language_server_id: symbol.source_language_server_id,
14290                path: symbol.path,
14291                label: label.unwrap_or_else(|| CodeLabel::plain(name.clone(), None)),
14292                name,
14293                kind: symbol.kind,
14294                range: symbol.range,
14295            });
14296        }
14297    }
14298}
14299
14300fn include_text(server: &lsp::LanguageServer) -> Option<bool> {
14301    match server.capabilities().text_document_sync.as_ref()? {
14302        lsp::TextDocumentSyncCapability::Options(opts) => match opts.save.as_ref()? {
14303            // Server wants didSave but didn't specify includeText.
14304            lsp::TextDocumentSyncSaveOptions::Supported(true) => Some(false),
14305            // Server doesn't want didSave at all.
14306            lsp::TextDocumentSyncSaveOptions::Supported(false) => None,
14307            // Server provided SaveOptions.
14308            lsp::TextDocumentSyncSaveOptions::SaveOptions(save_options) => {
14309                Some(save_options.include_text.unwrap_or(false))
14310            }
14311        },
14312        // We do not have any save info. Kind affects didChange only.
14313        lsp::TextDocumentSyncCapability::Kind(_) => None,
14314    }
14315}
14316
14317/// Completion items are displayed in a `UniformList`.
14318/// Usually, those items are single-line strings, but in LSP responses,
14319/// completion items `label`, `detail` and `label_details.description` may contain newlines or long spaces.
14320/// Many language plugins construct these items by joining these parts together, and we may use `CodeLabel::fallback_for_completion` that uses `label` at least.
14321/// 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,
14322/// breaking the completions menu presentation.
14323///
14324/// 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.
14325fn ensure_uniform_list_compatible_label(label: &mut CodeLabel) {
14326    let mut new_text = String::with_capacity(label.text.len());
14327    let mut offset_map = vec![0; label.text.len() + 1];
14328    let mut last_char_was_space = false;
14329    let mut new_idx = 0;
14330    let chars = label.text.char_indices().fuse();
14331    let mut newlines_removed = false;
14332
14333    for (idx, c) in chars {
14334        offset_map[idx] = new_idx;
14335
14336        match c {
14337            '\n' if last_char_was_space => {
14338                newlines_removed = true;
14339            }
14340            '\t' | ' ' if last_char_was_space => {}
14341            '\n' if !last_char_was_space => {
14342                new_text.push(' ');
14343                new_idx += 1;
14344                last_char_was_space = true;
14345                newlines_removed = true;
14346            }
14347            ' ' | '\t' => {
14348                new_text.push(' ');
14349                new_idx += 1;
14350                last_char_was_space = true;
14351            }
14352            _ => {
14353                new_text.push(c);
14354                new_idx += c.len_utf8();
14355                last_char_was_space = false;
14356            }
14357        }
14358    }
14359    offset_map[label.text.len()] = new_idx;
14360
14361    // Only modify the label if newlines were removed.
14362    if !newlines_removed {
14363        return;
14364    }
14365
14366    let last_index = new_idx;
14367    let mut run_ranges_errors = Vec::new();
14368    label.runs.retain_mut(|(range, _)| {
14369        match offset_map.get(range.start) {
14370            Some(&start) => range.start = start,
14371            None => {
14372                run_ranges_errors.push(range.clone());
14373                return false;
14374            }
14375        }
14376
14377        match offset_map.get(range.end) {
14378            Some(&end) => range.end = end,
14379            None => {
14380                run_ranges_errors.push(range.clone());
14381                range.end = last_index;
14382            }
14383        }
14384        true
14385    });
14386    if !run_ranges_errors.is_empty() {
14387        log::error!(
14388            "Completion label has errors in its run ranges: {run_ranges_errors:?}, label text: {}",
14389            label.text
14390        );
14391    }
14392
14393    let mut wrong_filter_range = None;
14394    if label.filter_range == (0..label.text.len()) {
14395        label.filter_range = 0..new_text.len();
14396    } else {
14397        let mut original_filter_range = Some(label.filter_range.clone());
14398        match offset_map.get(label.filter_range.start) {
14399            Some(&start) => label.filter_range.start = start,
14400            None => {
14401                wrong_filter_range = original_filter_range.take();
14402                label.filter_range.start = last_index;
14403            }
14404        }
14405
14406        match offset_map.get(label.filter_range.end) {
14407            Some(&end) => label.filter_range.end = end,
14408            None => {
14409                wrong_filter_range = original_filter_range.take();
14410                label.filter_range.end = last_index;
14411            }
14412        }
14413    }
14414    if let Some(wrong_filter_range) = wrong_filter_range {
14415        log::error!(
14416            "Completion label has an invalid filter range: {wrong_filter_range:?}, label text: {}",
14417            label.text
14418        );
14419    }
14420
14421    label.text = new_text;
14422}
14423
14424#[cfg(test)]
14425mod tests {
14426    use language::HighlightId;
14427
14428    use super::*;
14429
14430    #[test]
14431    fn test_glob_literal_prefix() {
14432        assert_eq!(glob_literal_prefix(Path::new("**/*.js")), Path::new(""));
14433        assert_eq!(
14434            glob_literal_prefix(Path::new("node_modules/**/*.js")),
14435            Path::new("node_modules")
14436        );
14437        assert_eq!(
14438            glob_literal_prefix(Path::new("foo/{bar,baz}.js")),
14439            Path::new("foo")
14440        );
14441        assert_eq!(
14442            glob_literal_prefix(Path::new("foo/bar/baz.js")),
14443            Path::new("foo/bar/baz.js")
14444        );
14445
14446        #[cfg(target_os = "windows")]
14447        {
14448            assert_eq!(glob_literal_prefix(Path::new("**\\*.js")), Path::new(""));
14449            assert_eq!(
14450                glob_literal_prefix(Path::new("node_modules\\**/*.js")),
14451                Path::new("node_modules")
14452            );
14453            assert_eq!(
14454                glob_literal_prefix(Path::new("foo/{bar,baz}.js")),
14455                Path::new("foo")
14456            );
14457            assert_eq!(
14458                glob_literal_prefix(Path::new("foo\\bar\\baz.js")),
14459                Path::new("foo/bar/baz.js")
14460            );
14461        }
14462    }
14463
14464    #[test]
14465    fn test_multi_len_chars_normalization() {
14466        let mut label = CodeLabel::new(
14467            "myElˇ (parameter) myElˇ: {\n    foo: string;\n}".to_string(),
14468            0..6,
14469            vec![(0..6, HighlightId(1))],
14470        );
14471        ensure_uniform_list_compatible_label(&mut label);
14472        assert_eq!(
14473            label,
14474            CodeLabel::new(
14475                "myElˇ (parameter) myElˇ: { foo: string; }".to_string(),
14476                0..6,
14477                vec![(0..6, HighlightId(1))],
14478            )
14479        );
14480    }
14481}