lsp_store.rs

    1//! LSP store provides unified access to the language server protocol.
    2//! The consumers of LSP store can interact with language servers without knowing exactly which language server they're interacting with.
    3//!
    4//! # Local/Remote LSP Stores
    5//! This module is split up into three distinct parts:
    6//! - [`LocalLspStore`], which is ran on the host machine (either project host or SSH host), that manages the lifecycle of language servers.
    7//! - [`RemoteLspStore`], which is ran on the remote machine (project guests) which is mostly about passing through the requests via RPC.
    8//!   The remote stores don't really care about which language server they're running against - they don't usually get to decide which language server is going to responsible for handling their request.
    9//! - [`LspStore`], which unifies the two under one consistent interface for interacting with language servers.
   10//!
   11//! Most of the interesting work happens at the local layer, as bulk of the complexity is with managing the lifecycle of language servers. The actual implementation of the LSP protocol is handled by [`lsp`] crate.
   12pub mod clangd_ext;
   13pub mod json_language_server_ext;
   14pub mod log_store;
   15pub mod lsp_ext_command;
   16pub mod rust_analyzer_ext;
   17pub mod vue_language_server_ext;
   18
   19mod inlay_hint_cache;
   20
   21use self::inlay_hint_cache::BufferInlayHints;
   22use crate::{
   23    CodeAction, ColorPresentation, Completion, CompletionDisplayOptions, CompletionResponse,
   24    CompletionSource, CoreCompletion, DocumentColor, Hover, InlayHint, InlayId, LocationLink,
   25    LspAction, LspPullDiagnostics, ManifestProvidersStore, Project, ProjectItem, ProjectPath,
   26    ProjectTransaction, PulledDiagnostics, ResolveState, Symbol,
   27    buffer_store::{BufferStore, BufferStoreEvent},
   28    environment::ProjectEnvironment,
   29    lsp_command::{self, *},
   30    lsp_store::{
   31        self,
   32        log_store::{GlobalLogStore, LanguageServerKind},
   33    },
   34    manifest_tree::{
   35        LanguageServerTree, LanguageServerTreeNode, LaunchDisposition, ManifestQueryDelegate,
   36        ManifestTree,
   37    },
   38    prettier_store::{self, PrettierStore, PrettierStoreEvent},
   39    project_settings::{LspSettings, ProjectSettings},
   40    toolchain_store::{LocalToolchainStore, ToolchainStoreEvent},
   41    trusted_worktrees::{PathTrust, TrustedWorktrees, TrustedWorktreesEvent},
   42    worktree_store::{WorktreeStore, WorktreeStoreEvent},
   43    yarn::YarnPathStore,
   44};
   45use anyhow::{Context as _, Result, anyhow};
   46use async_trait::async_trait;
   47use client::{TypedEnvelope, proto};
   48use clock::Global;
   49use collections::{BTreeMap, BTreeSet, HashMap, HashSet, btree_map};
   50use futures::{
   51    AsyncWriteExt, Future, FutureExt, StreamExt,
   52    future::{Either, Shared, join_all, pending, select},
   53    select, select_biased,
   54    stream::FuturesUnordered,
   55};
   56use globset::{Glob, GlobBuilder, GlobMatcher, GlobSet, GlobSetBuilder};
   57use gpui::{
   58    App, AppContext, AsyncApp, Context, Entity, EventEmitter, PromptLevel, SharedString,
   59    Subscription, Task, WeakEntity,
   60};
   61use http_client::HttpClient;
   62use itertools::Itertools as _;
   63use language::{
   64    Bias, BinaryStatus, Buffer, BufferRow, BufferSnapshot, CachedLspAdapter, Capability, CodeLabel,
   65    Diagnostic, DiagnosticEntry, DiagnosticSet, DiagnosticSourceKind, Diff, File as _, Language,
   66    LanguageName, LanguageRegistry, LocalFile, LspAdapter, LspAdapterDelegate, LspInstaller,
   67    ManifestDelegate, ManifestName, Patch, PointUtf16, TextBufferSnapshot, ToOffset, ToPointUtf16,
   68    Toolchain, Transaction, Unclipped,
   69    language_settings::{FormatOnSave, Formatter, LanguageSettings, language_settings},
   70    point_to_lsp,
   71    proto::{
   72        deserialize_anchor, deserialize_lsp_edit, deserialize_version, serialize_anchor,
   73        serialize_lsp_edit, serialize_version,
   74    },
   75    range_from_lsp, range_to_lsp,
   76    row_chunk::RowChunk,
   77};
   78use lsp::{
   79    AdapterServerCapabilities, CodeActionKind, CompletionContext, CompletionOptions,
   80    DiagnosticServerCapabilities, DiagnosticSeverity, DiagnosticTag,
   81    DidChangeWatchedFilesRegistrationOptions, Edit, FileOperationFilter, FileOperationPatternKind,
   82    FileOperationRegistrationOptions, FileRename, FileSystemWatcher, LSP_REQUEST_TIMEOUT,
   83    LanguageServer, LanguageServerBinary, LanguageServerBinaryOptions, LanguageServerId,
   84    LanguageServerName, LanguageServerSelector, LspRequestFuture, MessageActionItem, MessageType,
   85    OneOf, RenameFilesParams, SymbolKind, TextDocumentSyncSaveOptions, TextEdit, Uri,
   86    WillRenameFiles, WorkDoneProgressCancelParams, WorkspaceFolder, notification::DidRenameFiles,
   87};
   88use node_runtime::read_package_installed_version;
   89use parking_lot::Mutex;
   90use postage::{mpsc, sink::Sink, stream::Stream, watch};
   91use rand::prelude::*;
   92use rpc::{
   93    AnyProtoClient, ErrorCode, ErrorExt as _,
   94    proto::{LspRequestId, LspRequestMessage as _},
   95};
   96use semver::Version;
   97use serde::Serialize;
   98use serde_json::Value;
   99use settings::{Settings, SettingsLocation, SettingsStore};
  100use sha2::{Digest, Sha256};
  101use smol::channel::{Receiver, Sender};
  102use snippet::Snippet;
  103use std::{
  104    any::TypeId,
  105    borrow::Cow,
  106    cell::RefCell,
  107    cmp::{Ordering, Reverse},
  108    collections::hash_map,
  109    convert::TryInto,
  110    ffi::OsStr,
  111    future::ready,
  112    iter, mem,
  113    ops::{ControlFlow, Range},
  114    path::{self, Path, PathBuf},
  115    pin::pin,
  116    rc::Rc,
  117    sync::{
  118        Arc,
  119        atomic::{self, AtomicUsize},
  120    },
  121    time::{Duration, Instant},
  122    vec,
  123};
  124use sum_tree::Dimensions;
  125use text::{Anchor, BufferId, LineEnding, OffsetRangeExt, ToPoint as _};
  126
  127use util::{
  128    ConnectionResult, ResultExt as _, debug_panic, defer, maybe, merge_json_value_into,
  129    paths::{PathStyle, SanitizedPath},
  130    post_inc,
  131    redact::redact_command,
  132    rel_path::RelPath,
  133};
  134
  135pub use fs::*;
  136pub use language::Location;
  137pub use lsp_store::inlay_hint_cache::{CacheInlayHints, InvalidationStrategy};
  138#[cfg(any(test, feature = "test-support"))]
  139pub use prettier::FORMAT_SUFFIX as TEST_PRETTIER_FORMAT_SUFFIX;
  140pub use worktree::{
  141    Entry, EntryKind, FS_WATCH_LATENCY, File, LocalWorktree, PathChange, ProjectEntryId,
  142    UpdatedEntriesSet, UpdatedGitRepositoriesSet, Worktree, WorktreeId, WorktreeSettings,
  143};
  144
  145const SERVER_LAUNCHING_BEFORE_SHUTDOWN_TIMEOUT: Duration = Duration::from_secs(5);
  146pub const SERVER_PROGRESS_THROTTLE_TIMEOUT: Duration = Duration::from_millis(100);
  147const WORKSPACE_DIAGNOSTICS_TOKEN_START: &str = "id:";
  148const SERVER_DOWNLOAD_TIMEOUT: Duration = Duration::from_secs(10);
  149
  150#[derive(Debug, Clone, PartialEq, Eq, PartialOrd, Ord, Hash, Serialize)]
  151pub enum ProgressToken {
  152    Number(i32),
  153    String(SharedString),
  154}
  155
  156impl std::fmt::Display for ProgressToken {
  157    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
  158        match self {
  159            Self::Number(number) => write!(f, "{number}"),
  160            Self::String(string) => write!(f, "{string}"),
  161        }
  162    }
  163}
  164
  165impl ProgressToken {
  166    fn from_lsp(value: lsp::NumberOrString) -> Self {
  167        match value {
  168            lsp::NumberOrString::Number(number) => Self::Number(number),
  169            lsp::NumberOrString::String(string) => Self::String(SharedString::new(string)),
  170        }
  171    }
  172
  173    fn to_lsp(&self) -> lsp::NumberOrString {
  174        match self {
  175            Self::Number(number) => lsp::NumberOrString::Number(*number),
  176            Self::String(string) => lsp::NumberOrString::String(string.to_string()),
  177        }
  178    }
  179
  180    fn from_proto(value: proto::ProgressToken) -> Option<Self> {
  181        Some(match value.value? {
  182            proto::progress_token::Value::Number(number) => Self::Number(number),
  183            proto::progress_token::Value::String(string) => Self::String(SharedString::new(string)),
  184        })
  185    }
  186
  187    fn to_proto(&self) -> proto::ProgressToken {
  188        proto::ProgressToken {
  189            value: Some(match self {
  190                Self::Number(number) => proto::progress_token::Value::Number(*number),
  191                Self::String(string) => proto::progress_token::Value::String(string.to_string()),
  192            }),
  193        }
  194    }
  195}
  196
  197#[derive(Debug, Clone, Copy, PartialEq, Eq)]
  198pub enum FormatTrigger {
  199    Save,
  200    Manual,
  201}
  202
  203pub enum LspFormatTarget {
  204    Buffers,
  205    Ranges(BTreeMap<BufferId, Vec<Range<Anchor>>>),
  206}
  207
  208#[derive(Clone, PartialEq, Eq, Hash)]
  209pub struct OpenLspBufferHandle(Entity<OpenLspBuffer>);
  210
  211struct OpenLspBuffer(Entity<Buffer>);
  212
  213impl FormatTrigger {
  214    fn from_proto(value: i32) -> FormatTrigger {
  215        match value {
  216            0 => FormatTrigger::Save,
  217            1 => FormatTrigger::Manual,
  218            _ => FormatTrigger::Save,
  219        }
  220    }
  221}
  222
  223#[derive(Clone)]
  224struct UnifiedLanguageServer {
  225    id: LanguageServerId,
  226    project_roots: HashSet<Arc<RelPath>>,
  227}
  228
  229#[derive(Clone, Debug, Hash, PartialEq, Eq)]
  230struct LanguageServerSeed {
  231    worktree_id: WorktreeId,
  232    name: LanguageServerName,
  233    toolchain: Option<Toolchain>,
  234    settings: Arc<LspSettings>,
  235}
  236
  237#[derive(Debug)]
  238pub struct DocumentDiagnosticsUpdate<'a, D> {
  239    pub diagnostics: D,
  240    pub result_id: Option<SharedString>,
  241    pub registration_id: Option<SharedString>,
  242    pub server_id: LanguageServerId,
  243    pub disk_based_sources: Cow<'a, [String]>,
  244}
  245
  246pub struct DocumentDiagnostics {
  247    diagnostics: Vec<DiagnosticEntry<Unclipped<PointUtf16>>>,
  248    document_abs_path: PathBuf,
  249    version: Option<i32>,
  250}
  251
  252#[derive(Default, Debug)]
  253struct DynamicRegistrations {
  254    did_change_watched_files: HashMap<String, Vec<FileSystemWatcher>>,
  255    diagnostics: HashMap<Option<String>, DiagnosticServerCapabilities>,
  256}
  257
  258pub struct LocalLspStore {
  259    weak: WeakEntity<LspStore>,
  260    pub worktree_store: Entity<WorktreeStore>,
  261    toolchain_store: Entity<LocalToolchainStore>,
  262    http_client: Arc<dyn HttpClient>,
  263    environment: Entity<ProjectEnvironment>,
  264    fs: Arc<dyn Fs>,
  265    languages: Arc<LanguageRegistry>,
  266    language_server_ids: HashMap<LanguageServerSeed, UnifiedLanguageServer>,
  267    yarn: Entity<YarnPathStore>,
  268    pub language_servers: HashMap<LanguageServerId, LanguageServerState>,
  269    buffers_being_formatted: HashSet<BufferId>,
  270    last_workspace_edits_by_language_server: HashMap<LanguageServerId, ProjectTransaction>,
  271    language_server_watched_paths: HashMap<LanguageServerId, LanguageServerWatchedPaths>,
  272    watched_manifest_filenames: HashSet<ManifestName>,
  273    language_server_paths_watched_for_rename:
  274        HashMap<LanguageServerId, RenamePathsWatchedForServer>,
  275    language_server_dynamic_registrations: HashMap<LanguageServerId, DynamicRegistrations>,
  276    supplementary_language_servers:
  277        HashMap<LanguageServerId, (LanguageServerName, Arc<LanguageServer>)>,
  278    prettier_store: Entity<PrettierStore>,
  279    next_diagnostic_group_id: usize,
  280    diagnostics: HashMap<
  281        WorktreeId,
  282        HashMap<
  283            Arc<RelPath>,
  284            Vec<(
  285                LanguageServerId,
  286                Vec<DiagnosticEntry<Unclipped<PointUtf16>>>,
  287            )>,
  288        >,
  289    >,
  290    buffer_snapshots: HashMap<BufferId, HashMap<LanguageServerId, Vec<LspBufferSnapshot>>>, // buffer_id -> server_id -> vec of snapshots
  291    _subscription: gpui::Subscription,
  292    lsp_tree: LanguageServerTree,
  293    registered_buffers: HashMap<BufferId, usize>,
  294    buffers_opened_in_servers: HashMap<BufferId, HashSet<LanguageServerId>>,
  295    buffer_pull_diagnostics_result_ids: HashMap<
  296        LanguageServerId,
  297        HashMap<Option<SharedString>, HashMap<PathBuf, Option<SharedString>>>,
  298    >,
  299    workspace_pull_diagnostics_result_ids: HashMap<
  300        LanguageServerId,
  301        HashMap<Option<SharedString>, HashMap<PathBuf, Option<SharedString>>>,
  302    >,
  303    restricted_worktrees_tasks: HashMap<WorktreeId, (Subscription, Receiver<()>)>,
  304}
  305
  306impl LocalLspStore {
  307    /// Returns the running language server for the given ID. Note if the language server is starting, it will not be returned.
  308    pub fn running_language_server_for_id(
  309        &self,
  310        id: LanguageServerId,
  311    ) -> Option<&Arc<LanguageServer>> {
  312        let language_server_state = self.language_servers.get(&id)?;
  313
  314        match language_server_state {
  315            LanguageServerState::Running { server, .. } => Some(server),
  316            LanguageServerState::Starting { .. } => None,
  317        }
  318    }
  319
  320    fn get_or_insert_language_server(
  321        &mut self,
  322        worktree_handle: &Entity<Worktree>,
  323        delegate: Arc<LocalLspAdapterDelegate>,
  324        disposition: &Arc<LaunchDisposition>,
  325        language_name: &LanguageName,
  326        cx: &mut App,
  327    ) -> LanguageServerId {
  328        let key = LanguageServerSeed {
  329            worktree_id: worktree_handle.read(cx).id(),
  330            name: disposition.server_name.clone(),
  331            settings: disposition.settings.clone(),
  332            toolchain: disposition.toolchain.clone(),
  333        };
  334        if let Some(state) = self.language_server_ids.get_mut(&key) {
  335            state.project_roots.insert(disposition.path.path.clone());
  336            state.id
  337        } else {
  338            let adapter = self
  339                .languages
  340                .lsp_adapters(language_name)
  341                .into_iter()
  342                .find(|adapter| adapter.name() == disposition.server_name)
  343                .expect("To find LSP adapter");
  344            let new_language_server_id = self.start_language_server(
  345                worktree_handle,
  346                delegate,
  347                adapter,
  348                disposition.settings.clone(),
  349                key.clone(),
  350                cx,
  351            );
  352            if let Some(state) = self.language_server_ids.get_mut(&key) {
  353                state.project_roots.insert(disposition.path.path.clone());
  354            } else {
  355                debug_assert!(
  356                    false,
  357                    "Expected `start_language_server` to ensure that `key` exists in a map"
  358                );
  359            }
  360            new_language_server_id
  361        }
  362    }
  363
  364    fn start_language_server(
  365        &mut self,
  366        worktree_handle: &Entity<Worktree>,
  367        delegate: Arc<LocalLspAdapterDelegate>,
  368        adapter: Arc<CachedLspAdapter>,
  369        settings: Arc<LspSettings>,
  370        key: LanguageServerSeed,
  371        cx: &mut App,
  372    ) -> LanguageServerId {
  373        let worktree = worktree_handle.read(cx);
  374
  375        let worktree_id = worktree.id();
  376        let worktree_abs_path = worktree.abs_path();
  377        let toolchain = key.toolchain.clone();
  378        let override_options = settings.initialization_options.clone();
  379
  380        let stderr_capture = Arc::new(Mutex::new(Some(String::new())));
  381
  382        let server_id = self.languages.next_language_server_id();
  383        log::trace!(
  384            "attempting to start language server {:?}, path: {worktree_abs_path:?}, id: {server_id}",
  385            adapter.name.0
  386        );
  387
  388        let untrusted_worktree_task =
  389            TrustedWorktrees::try_get_global(cx).and_then(|trusted_worktrees| {
  390                let can_trust = trusted_worktrees.update(cx, |trusted_worktrees, cx| {
  391                    trusted_worktrees.can_trust(&self.worktree_store, worktree_id, cx)
  392                });
  393                if can_trust {
  394                    self.restricted_worktrees_tasks.remove(&worktree_id);
  395                    None
  396                } else {
  397                    match self.restricted_worktrees_tasks.entry(worktree_id) {
  398                        hash_map::Entry::Occupied(o) => Some(o.get().1.clone()),
  399                        hash_map::Entry::Vacant(v) => {
  400                            let (tx, rx) = smol::channel::bounded::<()>(1);
  401                            let subscription = cx.subscribe(&trusted_worktrees, move |_, e, _| {
  402                                if let TrustedWorktreesEvent::Trusted(_, trusted_paths) = e {
  403                                    if trusted_paths.contains(&PathTrust::Worktree(worktree_id)) {
  404                                        tx.send_blocking(()).ok();
  405                                    }
  406                                }
  407                            });
  408                            v.insert((subscription, rx.clone()));
  409                            Some(rx)
  410                        }
  411                    }
  412                }
  413            });
  414        let update_binary_status = untrusted_worktree_task.is_none();
  415
  416        let binary = self.get_language_server_binary(
  417            worktree_abs_path.clone(),
  418            adapter.clone(),
  419            settings,
  420            toolchain.clone(),
  421            delegate.clone(),
  422            true,
  423            untrusted_worktree_task,
  424            cx,
  425        );
  426        let pending_workspace_folders = Arc::<Mutex<BTreeSet<Uri>>>::default();
  427
  428        let pending_server = cx.spawn({
  429            let adapter = adapter.clone();
  430            let server_name = adapter.name.clone();
  431            let stderr_capture = stderr_capture.clone();
  432            #[cfg(any(test, feature = "test-support"))]
  433            let lsp_store = self.weak.clone();
  434            let pending_workspace_folders = pending_workspace_folders.clone();
  435            async move |cx| {
  436                let binary = binary.await?;
  437                #[cfg(any(test, feature = "test-support"))]
  438                if let Some(server) = lsp_store
  439                    .update(&mut cx.clone(), |this, cx| {
  440                        this.languages.create_fake_language_server(
  441                            server_id,
  442                            &server_name,
  443                            binary.clone(),
  444                            &mut cx.to_async(),
  445                        )
  446                    })
  447                    .ok()
  448                    .flatten()
  449                {
  450                    return Ok(server);
  451                }
  452
  453                let code_action_kinds = adapter.code_action_kinds();
  454                lsp::LanguageServer::new(
  455                    stderr_capture,
  456                    server_id,
  457                    server_name,
  458                    binary,
  459                    &worktree_abs_path,
  460                    code_action_kinds,
  461                    Some(pending_workspace_folders),
  462                    cx,
  463                )
  464            }
  465        });
  466
  467        let startup = {
  468            let server_name = adapter.name.0.clone();
  469            let delegate = delegate as Arc<dyn LspAdapterDelegate>;
  470            let key = key.clone();
  471            let adapter = adapter.clone();
  472            let lsp_store = self.weak.clone();
  473            let pending_workspace_folders = pending_workspace_folders.clone();
  474
  475            let pull_diagnostics = ProjectSettings::get_global(cx)
  476                .diagnostics
  477                .lsp_pull_diagnostics
  478                .enabled;
  479            cx.spawn(async move |cx| {
  480                let result = async {
  481                    let language_server = pending_server.await?;
  482
  483                    let workspace_config = Self::workspace_configuration_for_adapter(
  484                        adapter.adapter.clone(),
  485                        &delegate,
  486                        toolchain,
  487                        None,
  488                        cx,
  489                    )
  490                    .await?;
  491
  492                    let mut initialization_options = Self::initialization_options_for_adapter(
  493                        adapter.adapter.clone(),
  494                        &delegate,
  495                    )
  496                    .await?;
  497
  498                    match (&mut initialization_options, override_options) {
  499                        (Some(initialization_options), Some(override_options)) => {
  500                            merge_json_value_into(override_options, initialization_options);
  501                        }
  502                        (None, override_options) => initialization_options = override_options,
  503                        _ => {}
  504                    }
  505
  506                    let initialization_params = cx.update(|cx| {
  507                        let mut params =
  508                            language_server.default_initialize_params(pull_diagnostics, cx);
  509                        params.initialization_options = initialization_options;
  510                        adapter.adapter.prepare_initialize_params(params, cx)
  511                    })??;
  512
  513                    Self::setup_lsp_messages(
  514                        lsp_store.clone(),
  515                        &language_server,
  516                        delegate.clone(),
  517                        adapter.clone(),
  518                    );
  519
  520                    let did_change_configuration_params = lsp::DidChangeConfigurationParams {
  521                        settings: workspace_config,
  522                    };
  523                    let language_server = cx
  524                        .update(|cx| {
  525                            language_server.initialize(
  526                                initialization_params,
  527                                Arc::new(did_change_configuration_params.clone()),
  528                                cx,
  529                            )
  530                        })?
  531                        .await
  532                        .inspect_err(|_| {
  533                            if let Some(lsp_store) = lsp_store.upgrade() {
  534                                lsp_store
  535                                    .update(cx, |lsp_store, cx| {
  536                                        lsp_store.cleanup_lsp_data(server_id);
  537                                        cx.emit(LspStoreEvent::LanguageServerRemoved(server_id))
  538                                    })
  539                                    .ok();
  540                            }
  541                        })?;
  542
  543                    language_server.notify::<lsp::notification::DidChangeConfiguration>(
  544                        did_change_configuration_params,
  545                    )?;
  546
  547                    anyhow::Ok(language_server)
  548                }
  549                .await;
  550
  551                match result {
  552                    Ok(server) => {
  553                        lsp_store
  554                            .update(cx, |lsp_store, cx| {
  555                                lsp_store.insert_newly_running_language_server(
  556                                    adapter,
  557                                    server.clone(),
  558                                    server_id,
  559                                    key,
  560                                    pending_workspace_folders,
  561                                    cx,
  562                                );
  563                            })
  564                            .ok();
  565                        stderr_capture.lock().take();
  566                        Some(server)
  567                    }
  568
  569                    Err(err) => {
  570                        let log = stderr_capture.lock().take().unwrap_or_default();
  571                        delegate.update_status(
  572                            adapter.name(),
  573                            BinaryStatus::Failed {
  574                                error: if log.is_empty() {
  575                                    format!("{err:#}")
  576                                } else {
  577                                    format!("{err:#}\n-- stderr --\n{log}")
  578                                },
  579                            },
  580                        );
  581                        log::error!(
  582                            "Failed to start language server {server_name:?}: {}",
  583                            redact_command(&format!("{err:?}"))
  584                        );
  585                        if !log.is_empty() {
  586                            log::error!("server stderr: {}", redact_command(&log));
  587                        }
  588                        None
  589                    }
  590                }
  591            })
  592        };
  593        let state = LanguageServerState::Starting {
  594            startup,
  595            pending_workspace_folders,
  596        };
  597
  598        if update_binary_status {
  599            self.languages
  600                .update_lsp_binary_status(adapter.name(), BinaryStatus::Starting);
  601        }
  602
  603        self.language_servers.insert(server_id, state);
  604        self.language_server_ids
  605            .entry(key)
  606            .or_insert(UnifiedLanguageServer {
  607                id: server_id,
  608                project_roots: Default::default(),
  609            });
  610        server_id
  611    }
  612
  613    fn get_language_server_binary(
  614        &self,
  615        worktree_abs_path: Arc<Path>,
  616        adapter: Arc<CachedLspAdapter>,
  617        settings: Arc<LspSettings>,
  618        toolchain: Option<Toolchain>,
  619        delegate: Arc<dyn LspAdapterDelegate>,
  620        allow_binary_download: bool,
  621        untrusted_worktree_task: Option<Receiver<()>>,
  622        cx: &mut App,
  623    ) -> Task<Result<LanguageServerBinary>> {
  624        if let Some(settings) = &settings.binary
  625            && let Some(path) = settings.path.as_ref().map(PathBuf::from)
  626        {
  627            let settings = settings.clone();
  628            let languages = self.languages.clone();
  629            return cx.background_spawn(async move {
  630                if let Some(untrusted_worktree_task) = untrusted_worktree_task {
  631                    log::info!(
  632                        "Waiting for worktree {worktree_abs_path:?} to be trusted, before starting language server {}",
  633                        adapter.name(),
  634                    );
  635                    untrusted_worktree_task.recv().await.ok();
  636                    log::info!(
  637                        "Worktree {worktree_abs_path:?} is trusted, starting language server {}",
  638                        adapter.name(),
  639                    );
  640                    languages
  641                        .update_lsp_binary_status(adapter.name(), BinaryStatus::Starting);
  642                }
  643                let mut env = delegate.shell_env().await;
  644                env.extend(settings.env.unwrap_or_default());
  645
  646                Ok(LanguageServerBinary {
  647                    path: delegate.resolve_executable_path(path),
  648                    env: Some(env),
  649                    arguments: settings
  650                        .arguments
  651                        .unwrap_or_default()
  652                        .iter()
  653                        .map(Into::into)
  654                        .collect(),
  655                })
  656            });
  657        }
  658        let lsp_binary_options = LanguageServerBinaryOptions {
  659            allow_path_lookup: !settings
  660                .binary
  661                .as_ref()
  662                .and_then(|b| b.ignore_system_version)
  663                .unwrap_or_default(),
  664            allow_binary_download,
  665            pre_release: settings
  666                .fetch
  667                .as_ref()
  668                .and_then(|f| f.pre_release)
  669                .unwrap_or(false),
  670        };
  671
  672        cx.spawn(async move |cx| {
  673            if let Some(untrusted_worktree_task) = untrusted_worktree_task {
  674                log::info!(
  675                    "Waiting for worktree {worktree_abs_path:?} to be trusted, before starting language server {}",
  676                    adapter.name(),
  677                );
  678                untrusted_worktree_task.recv().await.ok();
  679                log::info!(
  680                    "Worktree {worktree_abs_path:?} is trusted, starting language server {}",
  681                    adapter.name(),
  682                );
  683            }
  684
  685            let (existing_binary, maybe_download_binary) = adapter
  686                .clone()
  687                .get_language_server_command(delegate.clone(), toolchain, lsp_binary_options, cx)
  688                .await
  689                .await;
  690
  691            delegate.update_status(adapter.name.clone(), BinaryStatus::None);
  692
  693            let mut binary = match (existing_binary, maybe_download_binary) {
  694                (binary, None) => binary?,
  695                (Err(_), Some(downloader)) => downloader.await?,
  696                (Ok(existing_binary), Some(downloader)) => {
  697                    let mut download_timeout = cx
  698                        .background_executor()
  699                        .timer(SERVER_DOWNLOAD_TIMEOUT)
  700                        .fuse();
  701                    let mut downloader = downloader.fuse();
  702                    futures::select! {
  703                        _ = download_timeout => {
  704                            // Return existing binary and kick the existing work to the background.
  705                            cx.spawn(async move |_| downloader.await).detach();
  706                            Ok(existing_binary)
  707                        },
  708                        downloaded_or_existing_binary = downloader => {
  709                            // If download fails, this results in the existing binary.
  710                            downloaded_or_existing_binary
  711                        }
  712                    }?
  713                }
  714            };
  715            let mut shell_env = delegate.shell_env().await;
  716
  717            shell_env.extend(binary.env.unwrap_or_default());
  718
  719            if let Some(settings) = settings.binary.as_ref() {
  720                if let Some(arguments) = &settings.arguments {
  721                    binary.arguments = arguments.iter().map(Into::into).collect();
  722                }
  723                if let Some(env) = &settings.env {
  724                    shell_env.extend(env.iter().map(|(k, v)| (k.clone(), v.clone())));
  725                }
  726            }
  727
  728            binary.env = Some(shell_env);
  729            Ok(binary)
  730        })
  731    }
  732
  733    fn setup_lsp_messages(
  734        lsp_store: WeakEntity<LspStore>,
  735        language_server: &LanguageServer,
  736        delegate: Arc<dyn LspAdapterDelegate>,
  737        adapter: Arc<CachedLspAdapter>,
  738    ) {
  739        let name = language_server.name();
  740        let server_id = language_server.server_id();
  741        language_server
  742            .on_notification::<lsp::notification::PublishDiagnostics, _>({
  743                let adapter = adapter.clone();
  744                let this = lsp_store.clone();
  745                move |mut params, cx| {
  746                    let adapter = adapter.clone();
  747                    if let Some(this) = this.upgrade() {
  748                        this.update(cx, |this, cx| {
  749                            {
  750                                let buffer = params
  751                                    .uri
  752                                    .to_file_path()
  753                                    .map(|file_path| this.get_buffer(&file_path, cx))
  754                                    .ok()
  755                                    .flatten();
  756                                adapter.process_diagnostics(&mut params, server_id, buffer);
  757                            }
  758
  759                            this.merge_lsp_diagnostics(
  760                                DiagnosticSourceKind::Pushed,
  761                                vec![DocumentDiagnosticsUpdate {
  762                                    server_id,
  763                                    diagnostics: params,
  764                                    result_id: None,
  765                                    disk_based_sources: Cow::Borrowed(
  766                                        &adapter.disk_based_diagnostic_sources,
  767                                    ),
  768                                    registration_id: None,
  769                                }],
  770                                |_, diagnostic, cx| match diagnostic.source_kind {
  771                                    DiagnosticSourceKind::Other | DiagnosticSourceKind::Pushed => {
  772                                        adapter.retain_old_diagnostic(diagnostic, cx)
  773                                    }
  774                                    DiagnosticSourceKind::Pulled => true,
  775                                },
  776                                cx,
  777                            )
  778                            .log_err();
  779                        })
  780                        .ok();
  781                    }
  782                }
  783            })
  784            .detach();
  785        language_server
  786            .on_request::<lsp::request::WorkspaceConfiguration, _, _>({
  787                let adapter = adapter.adapter.clone();
  788                let delegate = delegate.clone();
  789                let this = lsp_store.clone();
  790                move |params, cx| {
  791                    let adapter = adapter.clone();
  792                    let delegate = delegate.clone();
  793                    let this = this.clone();
  794                    let mut cx = cx.clone();
  795                    async move {
  796                        let toolchain_for_id = this
  797                            .update(&mut cx, |this, _| {
  798                                this.as_local()?.language_server_ids.iter().find_map(
  799                                    |(seed, value)| {
  800                                        (value.id == server_id).then(|| seed.toolchain.clone())
  801                                    },
  802                                )
  803                            })?
  804                            .context("Expected the LSP store to be in a local mode")?;
  805
  806                        let mut scope_uri_to_workspace_config = BTreeMap::new();
  807                        for item in &params.items {
  808                            let scope_uri = item.scope_uri.clone();
  809                            let std::collections::btree_map::Entry::Vacant(new_scope_uri) =
  810                                scope_uri_to_workspace_config.entry(scope_uri.clone())
  811                            else {
  812                                // We've already queried workspace configuration of this URI.
  813                                continue;
  814                            };
  815                            let workspace_config = Self::workspace_configuration_for_adapter(
  816                                adapter.clone(),
  817                                &delegate,
  818                                toolchain_for_id.clone(),
  819                                scope_uri,
  820                                &mut cx,
  821                            )
  822                            .await?;
  823                            new_scope_uri.insert(workspace_config);
  824                        }
  825
  826                        Ok(params
  827                            .items
  828                            .into_iter()
  829                            .filter_map(|item| {
  830                                let workspace_config =
  831                                    scope_uri_to_workspace_config.get(&item.scope_uri)?;
  832                                if let Some(section) = &item.section {
  833                                    Some(
  834                                        workspace_config
  835                                            .get(section)
  836                                            .cloned()
  837                                            .unwrap_or(serde_json::Value::Null),
  838                                    )
  839                                } else {
  840                                    Some(workspace_config.clone())
  841                                }
  842                            })
  843                            .collect())
  844                    }
  845                }
  846            })
  847            .detach();
  848
  849        language_server
  850            .on_request::<lsp::request::WorkspaceFoldersRequest, _, _>({
  851                let this = lsp_store.clone();
  852                move |_, cx| {
  853                    let this = this.clone();
  854                    let cx = cx.clone();
  855                    async move {
  856                        let Some(server) =
  857                            this.read_with(&cx, |this, _| this.language_server_for_id(server_id))?
  858                        else {
  859                            return Ok(None);
  860                        };
  861                        let root = server.workspace_folders();
  862                        Ok(Some(
  863                            root.into_iter()
  864                                .map(|uri| WorkspaceFolder {
  865                                    uri,
  866                                    name: Default::default(),
  867                                })
  868                                .collect(),
  869                        ))
  870                    }
  871                }
  872            })
  873            .detach();
  874        // Even though we don't have handling for these requests, respond to them to
  875        // avoid stalling any language server like `gopls` which waits for a response
  876        // to these requests when initializing.
  877        language_server
  878            .on_request::<lsp::request::WorkDoneProgressCreate, _, _>({
  879                let this = lsp_store.clone();
  880                move |params, cx| {
  881                    let this = this.clone();
  882                    let mut cx = cx.clone();
  883                    async move {
  884                        this.update(&mut cx, |this, _| {
  885                            if let Some(status) = this.language_server_statuses.get_mut(&server_id)
  886                            {
  887                                status
  888                                    .progress_tokens
  889                                    .insert(ProgressToken::from_lsp(params.token));
  890                            }
  891                        })?;
  892
  893                        Ok(())
  894                    }
  895                }
  896            })
  897            .detach();
  898
  899        language_server
  900            .on_request::<lsp::request::RegisterCapability, _, _>({
  901                let lsp_store = lsp_store.clone();
  902                move |params, cx| {
  903                    let lsp_store = lsp_store.clone();
  904                    let mut cx = cx.clone();
  905                    async move {
  906                        lsp_store
  907                            .update(&mut cx, |lsp_store, cx| {
  908                                if lsp_store.as_local().is_some() {
  909                                    match lsp_store
  910                                        .register_server_capabilities(server_id, params, cx)
  911                                    {
  912                                        Ok(()) => {}
  913                                        Err(e) => {
  914                                            log::error!(
  915                                                "Failed to register server capabilities: {e:#}"
  916                                            );
  917                                        }
  918                                    };
  919                                }
  920                            })
  921                            .ok();
  922                        Ok(())
  923                    }
  924                }
  925            })
  926            .detach();
  927
  928        language_server
  929            .on_request::<lsp::request::UnregisterCapability, _, _>({
  930                let lsp_store = lsp_store.clone();
  931                move |params, cx| {
  932                    let lsp_store = lsp_store.clone();
  933                    let mut cx = cx.clone();
  934                    async move {
  935                        lsp_store
  936                            .update(&mut cx, |lsp_store, cx| {
  937                                if lsp_store.as_local().is_some() {
  938                                    match lsp_store
  939                                        .unregister_server_capabilities(server_id, params, cx)
  940                                    {
  941                                        Ok(()) => {}
  942                                        Err(e) => {
  943                                            log::error!(
  944                                                "Failed to unregister server capabilities: {e:#}"
  945                                            );
  946                                        }
  947                                    }
  948                                }
  949                            })
  950                            .ok();
  951                        Ok(())
  952                    }
  953                }
  954            })
  955            .detach();
  956
  957        language_server
  958            .on_request::<lsp::request::ApplyWorkspaceEdit, _, _>({
  959                let this = lsp_store.clone();
  960                move |params, cx| {
  961                    let mut cx = cx.clone();
  962                    let this = this.clone();
  963                    async move {
  964                        LocalLspStore::on_lsp_workspace_edit(
  965                            this.clone(),
  966                            params,
  967                            server_id,
  968                            &mut cx,
  969                        )
  970                        .await
  971                    }
  972                }
  973            })
  974            .detach();
  975
  976        language_server
  977            .on_request::<lsp::request::InlayHintRefreshRequest, _, _>({
  978                let lsp_store = lsp_store.clone();
  979                let request_id = Arc::new(AtomicUsize::new(0));
  980                move |(), cx| {
  981                    let lsp_store = lsp_store.clone();
  982                    let request_id = request_id.clone();
  983                    let mut cx = cx.clone();
  984                    async move {
  985                        lsp_store
  986                            .update(&mut cx, |lsp_store, cx| {
  987                                let request_id =
  988                                    Some(request_id.fetch_add(1, atomic::Ordering::AcqRel));
  989                                cx.emit(LspStoreEvent::RefreshInlayHints {
  990                                    server_id,
  991                                    request_id,
  992                                });
  993                                lsp_store
  994                                    .downstream_client
  995                                    .as_ref()
  996                                    .map(|(client, project_id)| {
  997                                        client.send(proto::RefreshInlayHints {
  998                                            project_id: *project_id,
  999                                            server_id: server_id.to_proto(),
 1000                                            request_id: request_id.map(|id| id as u64),
 1001                                        })
 1002                                    })
 1003                            })?
 1004                            .transpose()?;
 1005                        Ok(())
 1006                    }
 1007                }
 1008            })
 1009            .detach();
 1010
 1011        language_server
 1012            .on_request::<lsp::request::CodeLensRefresh, _, _>({
 1013                let this = lsp_store.clone();
 1014                move |(), cx| {
 1015                    let this = this.clone();
 1016                    let mut cx = cx.clone();
 1017                    async move {
 1018                        this.update(&mut cx, |this, cx| {
 1019                            cx.emit(LspStoreEvent::RefreshCodeLens);
 1020                            this.downstream_client.as_ref().map(|(client, project_id)| {
 1021                                client.send(proto::RefreshCodeLens {
 1022                                    project_id: *project_id,
 1023                                })
 1024                            })
 1025                        })?
 1026                        .transpose()?;
 1027                        Ok(())
 1028                    }
 1029                }
 1030            })
 1031            .detach();
 1032
 1033        language_server
 1034            .on_request::<lsp::request::WorkspaceDiagnosticRefresh, _, _>({
 1035                let this = lsp_store.clone();
 1036                move |(), cx| {
 1037                    let this = this.clone();
 1038                    let mut cx = cx.clone();
 1039                    async move {
 1040                        this.update(&mut cx, |lsp_store, cx| {
 1041                            lsp_store.pull_workspace_diagnostics(server_id);
 1042                            lsp_store.pull_document_diagnostics_for_server(server_id, cx);
 1043                            lsp_store
 1044                                .downstream_client
 1045                                .as_ref()
 1046                                .map(|(client, project_id)| {
 1047                                    client.send(proto::PullWorkspaceDiagnostics {
 1048                                        project_id: *project_id,
 1049                                        server_id: server_id.to_proto(),
 1050                                    })
 1051                                })
 1052                        })?
 1053                        .transpose()?;
 1054                        Ok(())
 1055                    }
 1056                }
 1057            })
 1058            .detach();
 1059
 1060        language_server
 1061            .on_request::<lsp::request::ShowMessageRequest, _, _>({
 1062                let this = lsp_store.clone();
 1063                let name = name.to_string();
 1064                let adapter = adapter.clone();
 1065                move |params, cx| {
 1066                    let this = this.clone();
 1067                    let name = name.to_string();
 1068                    let adapter = adapter.clone();
 1069                    let mut cx = cx.clone();
 1070                    async move {
 1071                        let actions = params.actions.unwrap_or_default();
 1072                        let message = params.message.clone();
 1073                        let (tx, rx) = smol::channel::bounded(1);
 1074                        let request = LanguageServerPromptRequest {
 1075                            level: match params.typ {
 1076                                lsp::MessageType::ERROR => PromptLevel::Critical,
 1077                                lsp::MessageType::WARNING => PromptLevel::Warning,
 1078                                _ => PromptLevel::Info,
 1079                            },
 1080                            message: params.message,
 1081                            actions,
 1082                            response_channel: tx,
 1083                            lsp_name: name.clone(),
 1084                        };
 1085
 1086                        let did_update = this
 1087                            .update(&mut cx, |_, cx| {
 1088                                cx.emit(LspStoreEvent::LanguageServerPrompt(request));
 1089                            })
 1090                            .is_ok();
 1091                        if did_update {
 1092                            let response = rx.recv().await.ok();
 1093                            if let Some(ref selected_action) = response {
 1094                                let context = language::PromptResponseContext {
 1095                                    message,
 1096                                    selected_action: selected_action.clone(),
 1097                                };
 1098                                adapter.process_prompt_response(&context, &mut cx)
 1099                            }
 1100
 1101                            Ok(response)
 1102                        } else {
 1103                            Ok(None)
 1104                        }
 1105                    }
 1106                }
 1107            })
 1108            .detach();
 1109        language_server
 1110            .on_notification::<lsp::notification::ShowMessage, _>({
 1111                let this = lsp_store.clone();
 1112                let name = name.to_string();
 1113                move |params, cx| {
 1114                    let this = this.clone();
 1115                    let name = name.to_string();
 1116                    let mut cx = cx.clone();
 1117
 1118                    let (tx, _) = smol::channel::bounded(1);
 1119                    let request = LanguageServerPromptRequest {
 1120                        level: match params.typ {
 1121                            lsp::MessageType::ERROR => PromptLevel::Critical,
 1122                            lsp::MessageType::WARNING => PromptLevel::Warning,
 1123                            _ => PromptLevel::Info,
 1124                        },
 1125                        message: params.message,
 1126                        actions: vec![],
 1127                        response_channel: tx,
 1128                        lsp_name: name,
 1129                    };
 1130
 1131                    let _ = this.update(&mut cx, |_, cx| {
 1132                        cx.emit(LspStoreEvent::LanguageServerPrompt(request));
 1133                    });
 1134                }
 1135            })
 1136            .detach();
 1137
 1138        let disk_based_diagnostics_progress_token =
 1139            adapter.disk_based_diagnostics_progress_token.clone();
 1140
 1141        language_server
 1142            .on_notification::<lsp::notification::Progress, _>({
 1143                let this = lsp_store.clone();
 1144                move |params, cx| {
 1145                    if let Some(this) = this.upgrade() {
 1146                        this.update(cx, |this, cx| {
 1147                            this.on_lsp_progress(
 1148                                params,
 1149                                server_id,
 1150                                disk_based_diagnostics_progress_token.clone(),
 1151                                cx,
 1152                            );
 1153                        })
 1154                        .ok();
 1155                    }
 1156                }
 1157            })
 1158            .detach();
 1159
 1160        language_server
 1161            .on_notification::<lsp::notification::LogMessage, _>({
 1162                let this = lsp_store.clone();
 1163                move |params, cx| {
 1164                    if let Some(this) = this.upgrade() {
 1165                        this.update(cx, |_, cx| {
 1166                            cx.emit(LspStoreEvent::LanguageServerLog(
 1167                                server_id,
 1168                                LanguageServerLogType::Log(params.typ),
 1169                                params.message,
 1170                            ));
 1171                        })
 1172                        .ok();
 1173                    }
 1174                }
 1175            })
 1176            .detach();
 1177
 1178        language_server
 1179            .on_notification::<lsp::notification::LogTrace, _>({
 1180                let this = lsp_store.clone();
 1181                move |params, cx| {
 1182                    let mut cx = cx.clone();
 1183                    if let Some(this) = this.upgrade() {
 1184                        this.update(&mut cx, |_, cx| {
 1185                            cx.emit(LspStoreEvent::LanguageServerLog(
 1186                                server_id,
 1187                                LanguageServerLogType::Trace {
 1188                                    verbose_info: params.verbose,
 1189                                },
 1190                                params.message,
 1191                            ));
 1192                        })
 1193                        .ok();
 1194                    }
 1195                }
 1196            })
 1197            .detach();
 1198
 1199        vue_language_server_ext::register_requests(lsp_store.clone(), language_server);
 1200        json_language_server_ext::register_requests(lsp_store.clone(), language_server);
 1201        rust_analyzer_ext::register_notifications(lsp_store.clone(), language_server);
 1202        clangd_ext::register_notifications(lsp_store, language_server, adapter);
 1203    }
 1204
 1205    fn shutdown_language_servers_on_quit(
 1206        &mut self,
 1207        _: &mut Context<LspStore>,
 1208    ) -> impl Future<Output = ()> + use<> {
 1209        let shutdown_futures = self
 1210            .language_servers
 1211            .drain()
 1212            .map(|(_, server_state)| Self::shutdown_server(server_state))
 1213            .collect::<Vec<_>>();
 1214
 1215        async move {
 1216            join_all(shutdown_futures).await;
 1217        }
 1218    }
 1219
 1220    async fn shutdown_server(server_state: LanguageServerState) -> anyhow::Result<()> {
 1221        match server_state {
 1222            LanguageServerState::Running { server, .. } => {
 1223                if let Some(shutdown) = server.shutdown() {
 1224                    shutdown.await;
 1225                }
 1226            }
 1227            LanguageServerState::Starting { startup, .. } => {
 1228                if let Some(server) = startup.await
 1229                    && let Some(shutdown) = server.shutdown()
 1230                {
 1231                    shutdown.await;
 1232                }
 1233            }
 1234        }
 1235        Ok(())
 1236    }
 1237
 1238    fn language_servers_for_worktree(
 1239        &self,
 1240        worktree_id: WorktreeId,
 1241    ) -> impl Iterator<Item = &Arc<LanguageServer>> {
 1242        self.language_server_ids
 1243            .iter()
 1244            .filter_map(move |(seed, state)| {
 1245                if seed.worktree_id != worktree_id {
 1246                    return None;
 1247                }
 1248
 1249                if let Some(LanguageServerState::Running { server, .. }) =
 1250                    self.language_servers.get(&state.id)
 1251                {
 1252                    Some(server)
 1253                } else {
 1254                    None
 1255                }
 1256            })
 1257    }
 1258
 1259    fn language_server_ids_for_project_path(
 1260        &self,
 1261        project_path: ProjectPath,
 1262        language: &Language,
 1263        cx: &mut App,
 1264    ) -> Vec<LanguageServerId> {
 1265        let Some(worktree) = self
 1266            .worktree_store
 1267            .read(cx)
 1268            .worktree_for_id(project_path.worktree_id, cx)
 1269        else {
 1270            return Vec::new();
 1271        };
 1272        let delegate: Arc<dyn ManifestDelegate> =
 1273            Arc::new(ManifestQueryDelegate::new(worktree.read(cx).snapshot()));
 1274
 1275        self.lsp_tree
 1276            .get(
 1277                project_path,
 1278                language.name(),
 1279                language.manifest(),
 1280                &delegate,
 1281                cx,
 1282            )
 1283            .collect::<Vec<_>>()
 1284    }
 1285
 1286    fn language_server_ids_for_buffer(
 1287        &self,
 1288        buffer: &Buffer,
 1289        cx: &mut App,
 1290    ) -> Vec<LanguageServerId> {
 1291        if let Some((file, language)) = File::from_dyn(buffer.file()).zip(buffer.language()) {
 1292            let worktree_id = file.worktree_id(cx);
 1293
 1294            let path: Arc<RelPath> = file
 1295                .path()
 1296                .parent()
 1297                .map(Arc::from)
 1298                .unwrap_or_else(|| file.path().clone());
 1299            let worktree_path = ProjectPath { worktree_id, path };
 1300            self.language_server_ids_for_project_path(worktree_path, language, cx)
 1301        } else {
 1302            Vec::new()
 1303        }
 1304    }
 1305
 1306    fn language_servers_for_buffer<'a>(
 1307        &'a self,
 1308        buffer: &'a Buffer,
 1309        cx: &'a mut App,
 1310    ) -> impl Iterator<Item = (&'a Arc<CachedLspAdapter>, &'a Arc<LanguageServer>)> {
 1311        self.language_server_ids_for_buffer(buffer, cx)
 1312            .into_iter()
 1313            .filter_map(|server_id| match self.language_servers.get(&server_id)? {
 1314                LanguageServerState::Running {
 1315                    adapter, server, ..
 1316                } => Some((adapter, server)),
 1317                _ => None,
 1318            })
 1319    }
 1320
 1321    async fn execute_code_action_kind_locally(
 1322        lsp_store: WeakEntity<LspStore>,
 1323        mut buffers: Vec<Entity<Buffer>>,
 1324        kind: CodeActionKind,
 1325        push_to_history: bool,
 1326        cx: &mut AsyncApp,
 1327    ) -> anyhow::Result<ProjectTransaction> {
 1328        // Do not allow multiple concurrent code actions requests for the
 1329        // same buffer.
 1330        lsp_store.update(cx, |this, cx| {
 1331            let this = this.as_local_mut().unwrap();
 1332            buffers.retain(|buffer| {
 1333                this.buffers_being_formatted
 1334                    .insert(buffer.read(cx).remote_id())
 1335            });
 1336        })?;
 1337        let _cleanup = defer({
 1338            let this = lsp_store.clone();
 1339            let mut cx = cx.clone();
 1340            let buffers = &buffers;
 1341            move || {
 1342                this.update(&mut cx, |this, cx| {
 1343                    let this = this.as_local_mut().unwrap();
 1344                    for buffer in buffers {
 1345                        this.buffers_being_formatted
 1346                            .remove(&buffer.read(cx).remote_id());
 1347                    }
 1348                })
 1349                .ok();
 1350            }
 1351        });
 1352        let mut project_transaction = ProjectTransaction::default();
 1353
 1354        for buffer in &buffers {
 1355            let adapters_and_servers = lsp_store.update(cx, |lsp_store, cx| {
 1356                buffer.update(cx, |buffer, cx| {
 1357                    lsp_store
 1358                        .as_local()
 1359                        .unwrap()
 1360                        .language_servers_for_buffer(buffer, cx)
 1361                        .map(|(adapter, lsp)| (adapter.clone(), lsp.clone()))
 1362                        .collect::<Vec<_>>()
 1363                })
 1364            })?;
 1365            for (_, language_server) in adapters_and_servers.iter() {
 1366                let actions = Self::get_server_code_actions_from_action_kinds(
 1367                    &lsp_store,
 1368                    language_server.server_id(),
 1369                    vec![kind.clone()],
 1370                    buffer,
 1371                    cx,
 1372                )
 1373                .await?;
 1374                Self::execute_code_actions_on_server(
 1375                    &lsp_store,
 1376                    language_server,
 1377                    actions,
 1378                    push_to_history,
 1379                    &mut project_transaction,
 1380                    cx,
 1381                )
 1382                .await?;
 1383            }
 1384        }
 1385        Ok(project_transaction)
 1386    }
 1387
 1388    async fn format_locally(
 1389        lsp_store: WeakEntity<LspStore>,
 1390        mut buffers: Vec<FormattableBuffer>,
 1391        push_to_history: bool,
 1392        trigger: FormatTrigger,
 1393        logger: zlog::Logger,
 1394        cx: &mut AsyncApp,
 1395    ) -> anyhow::Result<ProjectTransaction> {
 1396        // Do not allow multiple concurrent formatting requests for the
 1397        // same buffer.
 1398        lsp_store.update(cx, |this, cx| {
 1399            let this = this.as_local_mut().unwrap();
 1400            buffers.retain(|buffer| {
 1401                this.buffers_being_formatted
 1402                    .insert(buffer.handle.read(cx).remote_id())
 1403            });
 1404        })?;
 1405
 1406        let _cleanup = defer({
 1407            let this = lsp_store.clone();
 1408            let mut cx = cx.clone();
 1409            let buffers = &buffers;
 1410            move || {
 1411                this.update(&mut cx, |this, cx| {
 1412                    let this = this.as_local_mut().unwrap();
 1413                    for buffer in buffers {
 1414                        this.buffers_being_formatted
 1415                            .remove(&buffer.handle.read(cx).remote_id());
 1416                    }
 1417                })
 1418                .ok();
 1419            }
 1420        });
 1421
 1422        let mut project_transaction = ProjectTransaction::default();
 1423
 1424        for buffer in &buffers {
 1425            zlog::debug!(
 1426                logger =>
 1427                "formatting buffer '{:?}'",
 1428                buffer.abs_path.as_ref().unwrap_or(&PathBuf::from("unknown")).display()
 1429            );
 1430            // Create an empty transaction to hold all of the formatting edits.
 1431            let formatting_transaction_id = buffer.handle.update(cx, |buffer, cx| {
 1432                // ensure no transactions created while formatting are
 1433                // grouped with the previous transaction in the history
 1434                // based on the transaction group interval
 1435                buffer.finalize_last_transaction();
 1436                buffer
 1437                    .start_transaction()
 1438                    .context("transaction already open")?;
 1439                buffer.end_transaction(cx);
 1440                let transaction_id = buffer.push_empty_transaction(cx.background_executor().now());
 1441                buffer.finalize_last_transaction();
 1442                anyhow::Ok(transaction_id)
 1443            })??;
 1444
 1445            let result = Self::format_buffer_locally(
 1446                lsp_store.clone(),
 1447                buffer,
 1448                formatting_transaction_id,
 1449                trigger,
 1450                logger,
 1451                cx,
 1452            )
 1453            .await;
 1454
 1455            buffer.handle.update(cx, |buffer, cx| {
 1456                let Some(formatting_transaction) =
 1457                    buffer.get_transaction(formatting_transaction_id).cloned()
 1458                else {
 1459                    zlog::warn!(logger => "no formatting transaction");
 1460                    return;
 1461                };
 1462                if formatting_transaction.edit_ids.is_empty() {
 1463                    zlog::debug!(logger => "no changes made while formatting");
 1464                    buffer.forget_transaction(formatting_transaction_id);
 1465                    return;
 1466                }
 1467                if !push_to_history {
 1468                    zlog::trace!(logger => "forgetting format transaction");
 1469                    buffer.forget_transaction(formatting_transaction.id);
 1470                }
 1471                project_transaction
 1472                    .0
 1473                    .insert(cx.entity(), formatting_transaction);
 1474            })?;
 1475
 1476            result?;
 1477        }
 1478
 1479        Ok(project_transaction)
 1480    }
 1481
 1482    async fn format_buffer_locally(
 1483        lsp_store: WeakEntity<LspStore>,
 1484        buffer: &FormattableBuffer,
 1485        formatting_transaction_id: clock::Lamport,
 1486        trigger: FormatTrigger,
 1487        logger: zlog::Logger,
 1488        cx: &mut AsyncApp,
 1489    ) -> Result<()> {
 1490        let (adapters_and_servers, settings) = lsp_store.update(cx, |lsp_store, cx| {
 1491            buffer.handle.update(cx, |buffer, cx| {
 1492                let adapters_and_servers = lsp_store
 1493                    .as_local()
 1494                    .unwrap()
 1495                    .language_servers_for_buffer(buffer, cx)
 1496                    .map(|(adapter, lsp)| (adapter.clone(), lsp.clone()))
 1497                    .collect::<Vec<_>>();
 1498                let settings =
 1499                    language_settings(buffer.language().map(|l| l.name()), buffer.file(), cx)
 1500                        .into_owned();
 1501                (adapters_and_servers, settings)
 1502            })
 1503        })?;
 1504
 1505        /// Apply edits to the buffer that will become part of the formatting transaction.
 1506        /// Fails if the buffer has been edited since the start of that transaction.
 1507        fn extend_formatting_transaction(
 1508            buffer: &FormattableBuffer,
 1509            formatting_transaction_id: text::TransactionId,
 1510            cx: &mut AsyncApp,
 1511            operation: impl FnOnce(&mut Buffer, &mut Context<Buffer>),
 1512        ) -> anyhow::Result<()> {
 1513            buffer.handle.update(cx, |buffer, cx| {
 1514                let last_transaction_id = buffer.peek_undo_stack().map(|t| t.transaction_id());
 1515                if last_transaction_id != Some(formatting_transaction_id) {
 1516                    anyhow::bail!("Buffer edited while formatting. Aborting")
 1517                }
 1518                buffer.start_transaction();
 1519                operation(buffer, cx);
 1520                if let Some(transaction_id) = buffer.end_transaction(cx) {
 1521                    buffer.merge_transactions(transaction_id, formatting_transaction_id);
 1522                }
 1523                Ok(())
 1524            })?
 1525        }
 1526
 1527        // handle whitespace formatting
 1528        if settings.remove_trailing_whitespace_on_save {
 1529            zlog::trace!(logger => "removing trailing whitespace");
 1530            let diff = buffer
 1531                .handle
 1532                .read_with(cx, |buffer, cx| buffer.remove_trailing_whitespace(cx))?
 1533                .await;
 1534            extend_formatting_transaction(buffer, formatting_transaction_id, cx, |buffer, cx| {
 1535                buffer.apply_diff(diff, cx);
 1536            })?;
 1537        }
 1538
 1539        if settings.ensure_final_newline_on_save {
 1540            zlog::trace!(logger => "ensuring final newline");
 1541            extend_formatting_transaction(buffer, formatting_transaction_id, cx, |buffer, cx| {
 1542                buffer.ensure_final_newline(cx);
 1543            })?;
 1544        }
 1545
 1546        // Formatter for `code_actions_on_format` that runs before
 1547        // the rest of the formatters
 1548        let mut code_actions_on_format_formatters = None;
 1549        let should_run_code_actions_on_format = !matches!(
 1550            (trigger, &settings.format_on_save),
 1551            (FormatTrigger::Save, &FormatOnSave::Off)
 1552        );
 1553        if should_run_code_actions_on_format {
 1554            let have_code_actions_to_run_on_format = settings
 1555                .code_actions_on_format
 1556                .values()
 1557                .any(|enabled| *enabled);
 1558            if have_code_actions_to_run_on_format {
 1559                zlog::trace!(logger => "going to run code actions on format");
 1560                code_actions_on_format_formatters = Some(
 1561                    settings
 1562                        .code_actions_on_format
 1563                        .iter()
 1564                        .filter_map(|(action, enabled)| enabled.then_some(action))
 1565                        .cloned()
 1566                        .map(Formatter::CodeAction)
 1567                        .collect::<Vec<_>>(),
 1568                );
 1569            }
 1570        }
 1571
 1572        let formatters = match (trigger, &settings.format_on_save) {
 1573            (FormatTrigger::Save, FormatOnSave::Off) => &[],
 1574            (FormatTrigger::Manual, _) | (FormatTrigger::Save, FormatOnSave::On) => {
 1575                settings.formatter.as_ref()
 1576            }
 1577        };
 1578
 1579        let formatters = code_actions_on_format_formatters
 1580            .iter()
 1581            .flatten()
 1582            .chain(formatters);
 1583
 1584        for formatter in formatters {
 1585            let formatter = if formatter == &Formatter::Auto {
 1586                if settings.prettier.allowed {
 1587                    zlog::trace!(logger => "Formatter set to auto: defaulting to prettier");
 1588                    &Formatter::Prettier
 1589                } else {
 1590                    zlog::trace!(logger => "Formatter set to auto: defaulting to primary language server");
 1591                    &Formatter::LanguageServer(settings::LanguageServerFormatterSpecifier::Current)
 1592                }
 1593            } else {
 1594                formatter
 1595            };
 1596            match formatter {
 1597                Formatter::Auto => unreachable!("Auto resolved above"),
 1598                Formatter::Prettier => {
 1599                    let logger = zlog::scoped!(logger => "prettier");
 1600                    zlog::trace!(logger => "formatting");
 1601                    let _timer = zlog::time!(logger => "Formatting buffer via prettier");
 1602
 1603                    let prettier = lsp_store.read_with(cx, |lsp_store, _cx| {
 1604                        lsp_store.prettier_store().unwrap().downgrade()
 1605                    })?;
 1606                    let diff = prettier_store::format_with_prettier(&prettier, &buffer.handle, cx)
 1607                        .await
 1608                        .transpose()?;
 1609                    let Some(diff) = diff else {
 1610                        zlog::trace!(logger => "No changes");
 1611                        continue;
 1612                    };
 1613
 1614                    extend_formatting_transaction(
 1615                        buffer,
 1616                        formatting_transaction_id,
 1617                        cx,
 1618                        |buffer, cx| {
 1619                            buffer.apply_diff(diff, cx);
 1620                        },
 1621                    )?;
 1622                }
 1623                Formatter::External { command, arguments } => {
 1624                    let logger = zlog::scoped!(logger => "command");
 1625                    zlog::trace!(logger => "formatting");
 1626                    let _timer = zlog::time!(logger => "Formatting buffer via external command");
 1627
 1628                    let diff = Self::format_via_external_command(
 1629                        buffer,
 1630                        command.as_ref(),
 1631                        arguments.as_deref(),
 1632                        cx,
 1633                    )
 1634                    .await
 1635                    .with_context(|| {
 1636                        format!("Failed to format buffer via external command: {}", command)
 1637                    })?;
 1638                    let Some(diff) = diff else {
 1639                        zlog::trace!(logger => "No changes");
 1640                        continue;
 1641                    };
 1642
 1643                    extend_formatting_transaction(
 1644                        buffer,
 1645                        formatting_transaction_id,
 1646                        cx,
 1647                        |buffer, cx| {
 1648                            buffer.apply_diff(diff, cx);
 1649                        },
 1650                    )?;
 1651                }
 1652                Formatter::LanguageServer(specifier) => {
 1653                    let logger = zlog::scoped!(logger => "language-server");
 1654                    zlog::trace!(logger => "formatting");
 1655                    let _timer = zlog::time!(logger => "Formatting buffer using language server");
 1656
 1657                    let Some(buffer_path_abs) = buffer.abs_path.as_ref() else {
 1658                        zlog::warn!(logger => "Cannot format buffer that is not backed by a file on disk using language servers. Skipping");
 1659                        continue;
 1660                    };
 1661
 1662                    let language_server = match specifier {
 1663                        settings::LanguageServerFormatterSpecifier::Specific { name } => {
 1664                            adapters_and_servers.iter().find_map(|(adapter, server)| {
 1665                                if adapter.name.0.as_ref() == name {
 1666                                    Some(server.clone())
 1667                                } else {
 1668                                    None
 1669                                }
 1670                            })
 1671                        }
 1672                        settings::LanguageServerFormatterSpecifier::Current => {
 1673                            adapters_and_servers.first().map(|e| e.1.clone())
 1674                        }
 1675                    };
 1676
 1677                    let Some(language_server) = language_server else {
 1678                        log::debug!(
 1679                            "No language server found to format buffer '{:?}'. Skipping",
 1680                            buffer_path_abs.as_path().to_string_lossy()
 1681                        );
 1682                        continue;
 1683                    };
 1684
 1685                    zlog::trace!(
 1686                        logger =>
 1687                        "Formatting buffer '{:?}' using language server '{:?}'",
 1688                        buffer_path_abs.as_path().to_string_lossy(),
 1689                        language_server.name()
 1690                    );
 1691
 1692                    let edits = if let Some(ranges) = buffer.ranges.as_ref() {
 1693                        zlog::trace!(logger => "formatting ranges");
 1694                        Self::format_ranges_via_lsp(
 1695                            &lsp_store,
 1696                            &buffer.handle,
 1697                            ranges,
 1698                            buffer_path_abs,
 1699                            &language_server,
 1700                            &settings,
 1701                            cx,
 1702                        )
 1703                        .await
 1704                        .context("Failed to format ranges via language server")?
 1705                    } else {
 1706                        zlog::trace!(logger => "formatting full");
 1707                        Self::format_via_lsp(
 1708                            &lsp_store,
 1709                            &buffer.handle,
 1710                            buffer_path_abs,
 1711                            &language_server,
 1712                            &settings,
 1713                            cx,
 1714                        )
 1715                        .await
 1716                        .context("failed to format via language server")?
 1717                    };
 1718
 1719                    if edits.is_empty() {
 1720                        zlog::trace!(logger => "No changes");
 1721                        continue;
 1722                    }
 1723                    extend_formatting_transaction(
 1724                        buffer,
 1725                        formatting_transaction_id,
 1726                        cx,
 1727                        |buffer, cx| {
 1728                            buffer.edit(edits, None, cx);
 1729                        },
 1730                    )?;
 1731                }
 1732                Formatter::CodeAction(code_action_name) => {
 1733                    let logger = zlog::scoped!(logger => "code-actions");
 1734                    zlog::trace!(logger => "formatting");
 1735                    let _timer = zlog::time!(logger => "Formatting buffer using code actions");
 1736
 1737                    let Some(buffer_path_abs) = buffer.abs_path.as_ref() else {
 1738                        zlog::warn!(logger => "Cannot format buffer that is not backed by a file on disk using code actions. Skipping");
 1739                        continue;
 1740                    };
 1741
 1742                    let code_action_kind: CodeActionKind = code_action_name.clone().into();
 1743                    zlog::trace!(logger => "Attempting to resolve code actions {:?}", &code_action_kind);
 1744
 1745                    let mut actions_and_servers = Vec::new();
 1746
 1747                    for (index, (_, language_server)) in adapters_and_servers.iter().enumerate() {
 1748                        let actions_result = Self::get_server_code_actions_from_action_kinds(
 1749                            &lsp_store,
 1750                            language_server.server_id(),
 1751                            vec![code_action_kind.clone()],
 1752                            &buffer.handle,
 1753                            cx,
 1754                        )
 1755                        .await
 1756                        .with_context(|| {
 1757                            format!(
 1758                                "Failed to resolve code action {:?} with language server {}",
 1759                                code_action_kind,
 1760                                language_server.name()
 1761                            )
 1762                        });
 1763                        let Ok(actions) = actions_result else {
 1764                            // note: it may be better to set result to the error and break formatters here
 1765                            // but for now we try to execute the actions that we can resolve and skip the rest
 1766                            zlog::error!(
 1767                                logger =>
 1768                                "Failed to resolve code action {:?} with language server {}",
 1769                                code_action_kind,
 1770                                language_server.name()
 1771                            );
 1772                            continue;
 1773                        };
 1774                        for action in actions {
 1775                            actions_and_servers.push((action, index));
 1776                        }
 1777                    }
 1778
 1779                    if actions_and_servers.is_empty() {
 1780                        zlog::warn!(logger => "No code actions were resolved, continuing");
 1781                        continue;
 1782                    }
 1783
 1784                    'actions: for (mut action, server_index) in actions_and_servers {
 1785                        let server = &adapters_and_servers[server_index].1;
 1786
 1787                        let describe_code_action = |action: &CodeAction| {
 1788                            format!(
 1789                                "code action '{}' with title \"{}\" on server {}",
 1790                                action
 1791                                    .lsp_action
 1792                                    .action_kind()
 1793                                    .unwrap_or("unknown".into())
 1794                                    .as_str(),
 1795                                action.lsp_action.title(),
 1796                                server.name(),
 1797                            )
 1798                        };
 1799
 1800                        zlog::trace!(logger => "Executing {}", describe_code_action(&action));
 1801
 1802                        if let Err(err) = Self::try_resolve_code_action(server, &mut action).await {
 1803                            zlog::error!(
 1804                                logger =>
 1805                                "Failed to resolve {}. Error: {}",
 1806                                describe_code_action(&action),
 1807                                err
 1808                            );
 1809                            continue;
 1810                        }
 1811
 1812                        if let Some(edit) = action.lsp_action.edit().cloned() {
 1813                            // NOTE: code below duplicated from `Self::deserialize_workspace_edit`
 1814                            // but filters out and logs warnings for code actions that require unreasonably
 1815                            // difficult handling on our part, such as:
 1816                            // - applying edits that call commands
 1817                            //   which can result in arbitrary workspace edits being sent from the server that
 1818                            //   have no way of being tied back to the command that initiated them (i.e. we
 1819                            //   can't know which edits are part of the format request, or if the server is done sending
 1820                            //   actions in response to the command)
 1821                            // - actions that create/delete/modify/rename files other than the one we are formatting
 1822                            //   as we then would need to handle such changes correctly in the local history as well
 1823                            //   as the remote history through the ProjectTransaction
 1824                            // - actions with snippet edits, as these simply don't make sense in the context of a format request
 1825                            // Supporting these actions is not impossible, but not supported as of yet.
 1826                            if edit.changes.is_none() && edit.document_changes.is_none() {
 1827                                zlog::trace!(
 1828                                    logger =>
 1829                                    "No changes for code action. Skipping {}",
 1830                                    describe_code_action(&action),
 1831                                );
 1832                                continue;
 1833                            }
 1834
 1835                            let mut operations = Vec::new();
 1836                            if let Some(document_changes) = edit.document_changes {
 1837                                match document_changes {
 1838                                    lsp::DocumentChanges::Edits(edits) => operations.extend(
 1839                                        edits.into_iter().map(lsp::DocumentChangeOperation::Edit),
 1840                                    ),
 1841                                    lsp::DocumentChanges::Operations(ops) => operations = ops,
 1842                                }
 1843                            } else if let Some(changes) = edit.changes {
 1844                                operations.extend(changes.into_iter().map(|(uri, edits)| {
 1845                                    lsp::DocumentChangeOperation::Edit(lsp::TextDocumentEdit {
 1846                                        text_document:
 1847                                            lsp::OptionalVersionedTextDocumentIdentifier {
 1848                                                uri,
 1849                                                version: None,
 1850                                            },
 1851                                        edits: edits.into_iter().map(Edit::Plain).collect(),
 1852                                    })
 1853                                }));
 1854                            }
 1855
 1856                            let mut edits = Vec::with_capacity(operations.len());
 1857
 1858                            if operations.is_empty() {
 1859                                zlog::trace!(
 1860                                    logger =>
 1861                                    "No changes for code action. Skipping {}",
 1862                                    describe_code_action(&action),
 1863                                );
 1864                                continue;
 1865                            }
 1866                            for operation in operations {
 1867                                let op = match operation {
 1868                                    lsp::DocumentChangeOperation::Edit(op) => op,
 1869                                    lsp::DocumentChangeOperation::Op(_) => {
 1870                                        zlog::warn!(
 1871                                            logger =>
 1872                                            "Code actions which create, delete, or rename files are not supported on format. Skipping {}",
 1873                                            describe_code_action(&action),
 1874                                        );
 1875                                        continue 'actions;
 1876                                    }
 1877                                };
 1878                                let Ok(file_path) = op.text_document.uri.to_file_path() else {
 1879                                    zlog::warn!(
 1880                                        logger =>
 1881                                        "Failed to convert URI '{:?}' to file path. Skipping {}",
 1882                                        &op.text_document.uri,
 1883                                        describe_code_action(&action),
 1884                                    );
 1885                                    continue 'actions;
 1886                                };
 1887                                if &file_path != buffer_path_abs {
 1888                                    zlog::warn!(
 1889                                        logger =>
 1890                                        "File path '{:?}' does not match buffer path '{:?}'. Skipping {}",
 1891                                        file_path,
 1892                                        buffer_path_abs,
 1893                                        describe_code_action(&action),
 1894                                    );
 1895                                    continue 'actions;
 1896                                }
 1897
 1898                                let mut lsp_edits = Vec::new();
 1899                                for edit in op.edits {
 1900                                    match edit {
 1901                                        Edit::Plain(edit) => {
 1902                                            if !lsp_edits.contains(&edit) {
 1903                                                lsp_edits.push(edit);
 1904                                            }
 1905                                        }
 1906                                        Edit::Annotated(edit) => {
 1907                                            if !lsp_edits.contains(&edit.text_edit) {
 1908                                                lsp_edits.push(edit.text_edit);
 1909                                            }
 1910                                        }
 1911                                        Edit::Snippet(_) => {
 1912                                            zlog::warn!(
 1913                                                logger =>
 1914                                                "Code actions which produce snippet edits are not supported during formatting. Skipping {}",
 1915                                                describe_code_action(&action),
 1916                                            );
 1917                                            continue 'actions;
 1918                                        }
 1919                                    }
 1920                                }
 1921                                let edits_result = lsp_store
 1922                                    .update(cx, |lsp_store, cx| {
 1923                                        lsp_store.as_local_mut().unwrap().edits_from_lsp(
 1924                                            &buffer.handle,
 1925                                            lsp_edits,
 1926                                            server.server_id(),
 1927                                            op.text_document.version,
 1928                                            cx,
 1929                                        )
 1930                                    })?
 1931                                    .await;
 1932                                let Ok(resolved_edits) = edits_result else {
 1933                                    zlog::warn!(
 1934                                        logger =>
 1935                                        "Failed to resolve edits from LSP for buffer {:?} while handling {}",
 1936                                        buffer_path_abs.as_path(),
 1937                                        describe_code_action(&action),
 1938                                    );
 1939                                    continue 'actions;
 1940                                };
 1941                                edits.extend(resolved_edits);
 1942                            }
 1943
 1944                            if edits.is_empty() {
 1945                                zlog::warn!(logger => "No edits resolved from LSP");
 1946                                continue;
 1947                            }
 1948
 1949                            extend_formatting_transaction(
 1950                                buffer,
 1951                                formatting_transaction_id,
 1952                                cx,
 1953                                |buffer, cx| {
 1954                                    zlog::info!(
 1955                                        "Applying edits {edits:?}. Content: {:?}",
 1956                                        buffer.text()
 1957                                    );
 1958                                    buffer.edit(edits, None, cx);
 1959                                    zlog::info!("Applied edits. New Content: {:?}", buffer.text());
 1960                                },
 1961                            )?;
 1962                        }
 1963
 1964                        if let Some(command) = action.lsp_action.command() {
 1965                            zlog::warn!(
 1966                                logger =>
 1967                                "Executing code action command '{}'. This may cause formatting to abort unnecessarily as well as splitting formatting into two entries in the undo history",
 1968                                &command.command,
 1969                            );
 1970
 1971                            // bail early if command is invalid
 1972                            let server_capabilities = server.capabilities();
 1973                            let available_commands = server_capabilities
 1974                                .execute_command_provider
 1975                                .as_ref()
 1976                                .map(|options| options.commands.as_slice())
 1977                                .unwrap_or_default();
 1978                            if !available_commands.contains(&command.command) {
 1979                                zlog::warn!(
 1980                                    logger =>
 1981                                    "Cannot execute a command {} not listed in the language server capabilities of server {}",
 1982                                    command.command,
 1983                                    server.name(),
 1984                                );
 1985                                continue;
 1986                            }
 1987
 1988                            // noop so we just ensure buffer hasn't been edited since resolving code actions
 1989                            extend_formatting_transaction(
 1990                                buffer,
 1991                                formatting_transaction_id,
 1992                                cx,
 1993                                |_, _| {},
 1994                            )?;
 1995                            zlog::info!(logger => "Executing command {}", &command.command);
 1996
 1997                            lsp_store.update(cx, |this, _| {
 1998                                this.as_local_mut()
 1999                                    .unwrap()
 2000                                    .last_workspace_edits_by_language_server
 2001                                    .remove(&server.server_id());
 2002                            })?;
 2003
 2004                            let execute_command_result = server
 2005                                .request::<lsp::request::ExecuteCommand>(
 2006                                    lsp::ExecuteCommandParams {
 2007                                        command: command.command.clone(),
 2008                                        arguments: command.arguments.clone().unwrap_or_default(),
 2009                                        ..Default::default()
 2010                                    },
 2011                                )
 2012                                .await
 2013                                .into_response();
 2014
 2015                            if execute_command_result.is_err() {
 2016                                zlog::error!(
 2017                                    logger =>
 2018                                    "Failed to execute command '{}' as part of {}",
 2019                                    &command.command,
 2020                                    describe_code_action(&action),
 2021                                );
 2022                                continue 'actions;
 2023                            }
 2024
 2025                            let mut project_transaction_command =
 2026                                lsp_store.update(cx, |this, _| {
 2027                                    this.as_local_mut()
 2028                                        .unwrap()
 2029                                        .last_workspace_edits_by_language_server
 2030                                        .remove(&server.server_id())
 2031                                        .unwrap_or_default()
 2032                                })?;
 2033
 2034                            if let Some(transaction) =
 2035                                project_transaction_command.0.remove(&buffer.handle)
 2036                            {
 2037                                zlog::trace!(
 2038                                    logger =>
 2039                                    "Successfully captured {} edits that resulted from command {}",
 2040                                    transaction.edit_ids.len(),
 2041                                    &command.command,
 2042                                );
 2043                                let transaction_id_project_transaction = transaction.id;
 2044                                buffer.handle.update(cx, |buffer, _| {
 2045                                    // it may have been removed from history if push_to_history was
 2046                                    // false in deserialize_workspace_edit. If so push it so we
 2047                                    // can merge it with the format transaction
 2048                                    // and pop the combined transaction off the history stack
 2049                                    // later if push_to_history is false
 2050                                    if buffer.get_transaction(transaction.id).is_none() {
 2051                                        buffer.push_transaction(transaction, Instant::now());
 2052                                    }
 2053                                    buffer.merge_transactions(
 2054                                        transaction_id_project_transaction,
 2055                                        formatting_transaction_id,
 2056                                    );
 2057                                })?;
 2058                            }
 2059
 2060                            if !project_transaction_command.0.is_empty() {
 2061                                let mut extra_buffers = String::new();
 2062                                for buffer in project_transaction_command.0.keys() {
 2063                                    buffer
 2064                                        .read_with(cx, |b, cx| {
 2065                                            if let Some(path) = b.project_path(cx) {
 2066                                                if !extra_buffers.is_empty() {
 2067                                                    extra_buffers.push_str(", ");
 2068                                                }
 2069                                                extra_buffers.push_str(path.path.as_unix_str());
 2070                                            }
 2071                                        })
 2072                                        .ok();
 2073                                }
 2074                                zlog::warn!(
 2075                                    logger =>
 2076                                    "Unexpected edits to buffers other than the buffer actively being formatted due to command {}. Impacted buffers: [{}].",
 2077                                    &command.command,
 2078                                    extra_buffers,
 2079                                );
 2080                                // NOTE: if this case is hit, the proper thing to do is to for each buffer, merge the extra transaction
 2081                                // into the existing transaction in project_transaction if there is one, and if there isn't one in project_transaction,
 2082                                // add it so it's included, and merge it into the format transaction when its created later
 2083                            }
 2084                        }
 2085                    }
 2086                }
 2087            }
 2088        }
 2089
 2090        Ok(())
 2091    }
 2092
 2093    pub async fn format_ranges_via_lsp(
 2094        this: &WeakEntity<LspStore>,
 2095        buffer_handle: &Entity<Buffer>,
 2096        ranges: &[Range<Anchor>],
 2097        abs_path: &Path,
 2098        language_server: &Arc<LanguageServer>,
 2099        settings: &LanguageSettings,
 2100        cx: &mut AsyncApp,
 2101    ) -> Result<Vec<(Range<Anchor>, Arc<str>)>> {
 2102        let capabilities = &language_server.capabilities();
 2103        let range_formatting_provider = capabilities.document_range_formatting_provider.as_ref();
 2104        if range_formatting_provider == Some(&OneOf::Left(false)) {
 2105            anyhow::bail!(
 2106                "{} language server does not support range formatting",
 2107                language_server.name()
 2108            );
 2109        }
 2110
 2111        let uri = file_path_to_lsp_url(abs_path)?;
 2112        let text_document = lsp::TextDocumentIdentifier::new(uri);
 2113
 2114        let lsp_edits = {
 2115            let mut lsp_ranges = Vec::new();
 2116            this.update(cx, |_this, cx| {
 2117                // TODO(#22930): In the case of formatting multibuffer selections, this buffer may
 2118                // not have been sent to the language server. This seems like a fairly systemic
 2119                // issue, though, the resolution probably is not specific to formatting.
 2120                //
 2121                // TODO: Instead of using current snapshot, should use the latest snapshot sent to
 2122                // LSP.
 2123                let snapshot = buffer_handle.read(cx).snapshot();
 2124                for range in ranges {
 2125                    lsp_ranges.push(range_to_lsp(range.to_point_utf16(&snapshot))?);
 2126                }
 2127                anyhow::Ok(())
 2128            })??;
 2129
 2130            let mut edits = None;
 2131            for range in lsp_ranges {
 2132                if let Some(mut edit) = language_server
 2133                    .request::<lsp::request::RangeFormatting>(lsp::DocumentRangeFormattingParams {
 2134                        text_document: text_document.clone(),
 2135                        range,
 2136                        options: lsp_command::lsp_formatting_options(settings),
 2137                        work_done_progress_params: Default::default(),
 2138                    })
 2139                    .await
 2140                    .into_response()?
 2141                {
 2142                    edits.get_or_insert_with(Vec::new).append(&mut edit);
 2143                }
 2144            }
 2145            edits
 2146        };
 2147
 2148        if let Some(lsp_edits) = lsp_edits {
 2149            this.update(cx, |this, cx| {
 2150                this.as_local_mut().unwrap().edits_from_lsp(
 2151                    buffer_handle,
 2152                    lsp_edits,
 2153                    language_server.server_id(),
 2154                    None,
 2155                    cx,
 2156                )
 2157            })?
 2158            .await
 2159        } else {
 2160            Ok(Vec::with_capacity(0))
 2161        }
 2162    }
 2163
 2164    async fn format_via_lsp(
 2165        this: &WeakEntity<LspStore>,
 2166        buffer: &Entity<Buffer>,
 2167        abs_path: &Path,
 2168        language_server: &Arc<LanguageServer>,
 2169        settings: &LanguageSettings,
 2170        cx: &mut AsyncApp,
 2171    ) -> Result<Vec<(Range<Anchor>, Arc<str>)>> {
 2172        let logger = zlog::scoped!("lsp_format");
 2173        zlog::debug!(logger => "Formatting via LSP");
 2174
 2175        let uri = file_path_to_lsp_url(abs_path)?;
 2176        let text_document = lsp::TextDocumentIdentifier::new(uri);
 2177        let capabilities = &language_server.capabilities();
 2178
 2179        let formatting_provider = capabilities.document_formatting_provider.as_ref();
 2180        let range_formatting_provider = capabilities.document_range_formatting_provider.as_ref();
 2181
 2182        let lsp_edits = if matches!(formatting_provider, Some(p) if *p != OneOf::Left(false)) {
 2183            let _timer = zlog::time!(logger => "format-full");
 2184            language_server
 2185                .request::<lsp::request::Formatting>(lsp::DocumentFormattingParams {
 2186                    text_document,
 2187                    options: lsp_command::lsp_formatting_options(settings),
 2188                    work_done_progress_params: Default::default(),
 2189                })
 2190                .await
 2191                .into_response()?
 2192        } else if matches!(range_formatting_provider, Some(p) if *p != OneOf::Left(false)) {
 2193            let _timer = zlog::time!(logger => "format-range");
 2194            let buffer_start = lsp::Position::new(0, 0);
 2195            let buffer_end = buffer.read_with(cx, |b, _| point_to_lsp(b.max_point_utf16()))?;
 2196            language_server
 2197                .request::<lsp::request::RangeFormatting>(lsp::DocumentRangeFormattingParams {
 2198                    text_document: text_document.clone(),
 2199                    range: lsp::Range::new(buffer_start, buffer_end),
 2200                    options: lsp_command::lsp_formatting_options(settings),
 2201                    work_done_progress_params: Default::default(),
 2202                })
 2203                .await
 2204                .into_response()?
 2205        } else {
 2206            None
 2207        };
 2208
 2209        if let Some(lsp_edits) = lsp_edits {
 2210            this.update(cx, |this, cx| {
 2211                this.as_local_mut().unwrap().edits_from_lsp(
 2212                    buffer,
 2213                    lsp_edits,
 2214                    language_server.server_id(),
 2215                    None,
 2216                    cx,
 2217                )
 2218            })?
 2219            .await
 2220        } else {
 2221            Ok(Vec::with_capacity(0))
 2222        }
 2223    }
 2224
 2225    async fn format_via_external_command(
 2226        buffer: &FormattableBuffer,
 2227        command: &str,
 2228        arguments: Option<&[String]>,
 2229        cx: &mut AsyncApp,
 2230    ) -> Result<Option<Diff>> {
 2231        let working_dir_path = buffer.handle.update(cx, |buffer, cx| {
 2232            let file = File::from_dyn(buffer.file())?;
 2233            let worktree = file.worktree.read(cx);
 2234            let mut worktree_path = worktree.abs_path().to_path_buf();
 2235            if worktree.root_entry()?.is_file() {
 2236                worktree_path.pop();
 2237            }
 2238            Some(worktree_path)
 2239        })?;
 2240
 2241        let mut child = util::command::new_smol_command(command);
 2242
 2243        if let Some(buffer_env) = buffer.env.as_ref() {
 2244            child.envs(buffer_env);
 2245        }
 2246
 2247        if let Some(working_dir_path) = working_dir_path {
 2248            child.current_dir(working_dir_path);
 2249        }
 2250
 2251        if let Some(arguments) = arguments {
 2252            child.args(arguments.iter().map(|arg| {
 2253                if let Some(buffer_abs_path) = buffer.abs_path.as_ref() {
 2254                    arg.replace("{buffer_path}", &buffer_abs_path.to_string_lossy())
 2255                } else {
 2256                    arg.replace("{buffer_path}", "Untitled")
 2257                }
 2258            }));
 2259        }
 2260
 2261        let mut child = child
 2262            .stdin(smol::process::Stdio::piped())
 2263            .stdout(smol::process::Stdio::piped())
 2264            .stderr(smol::process::Stdio::piped())
 2265            .spawn()?;
 2266
 2267        let stdin = child.stdin.as_mut().context("failed to acquire stdin")?;
 2268        let text = buffer
 2269            .handle
 2270            .read_with(cx, |buffer, _| buffer.as_rope().clone())?;
 2271        for chunk in text.chunks() {
 2272            stdin.write_all(chunk.as_bytes()).await?;
 2273        }
 2274        stdin.flush().await?;
 2275
 2276        let output = child.output().await?;
 2277        anyhow::ensure!(
 2278            output.status.success(),
 2279            "command failed with exit code {:?}:\nstdout: {}\nstderr: {}",
 2280            output.status.code(),
 2281            String::from_utf8_lossy(&output.stdout),
 2282            String::from_utf8_lossy(&output.stderr),
 2283        );
 2284
 2285        let stdout = String::from_utf8(output.stdout)?;
 2286        Ok(Some(
 2287            buffer
 2288                .handle
 2289                .update(cx, |buffer, cx| buffer.diff(stdout, cx))?
 2290                .await,
 2291        ))
 2292    }
 2293
 2294    async fn try_resolve_code_action(
 2295        lang_server: &LanguageServer,
 2296        action: &mut CodeAction,
 2297    ) -> anyhow::Result<()> {
 2298        match &mut action.lsp_action {
 2299            LspAction::Action(lsp_action) => {
 2300                if !action.resolved
 2301                    && GetCodeActions::can_resolve_actions(&lang_server.capabilities())
 2302                    && lsp_action.data.is_some()
 2303                    && (lsp_action.command.is_none() || lsp_action.edit.is_none())
 2304                {
 2305                    **lsp_action = lang_server
 2306                        .request::<lsp::request::CodeActionResolveRequest>(*lsp_action.clone())
 2307                        .await
 2308                        .into_response()?;
 2309                }
 2310            }
 2311            LspAction::CodeLens(lens) => {
 2312                if !action.resolved && GetCodeLens::can_resolve_lens(&lang_server.capabilities()) {
 2313                    *lens = lang_server
 2314                        .request::<lsp::request::CodeLensResolve>(lens.clone())
 2315                        .await
 2316                        .into_response()?;
 2317                }
 2318            }
 2319            LspAction::Command(_) => {}
 2320        }
 2321
 2322        action.resolved = true;
 2323        anyhow::Ok(())
 2324    }
 2325
 2326    fn initialize_buffer(&mut self, buffer_handle: &Entity<Buffer>, cx: &mut Context<LspStore>) {
 2327        let buffer = buffer_handle.read(cx);
 2328
 2329        let file = buffer.file().cloned();
 2330
 2331        let Some(file) = File::from_dyn(file.as_ref()) else {
 2332            return;
 2333        };
 2334        if !file.is_local() {
 2335            return;
 2336        }
 2337        let path = ProjectPath::from_file(file, cx);
 2338        let worktree_id = file.worktree_id(cx);
 2339        let language = buffer.language().cloned();
 2340
 2341        if let Some(diagnostics) = self.diagnostics.get(&worktree_id) {
 2342            for (server_id, diagnostics) in
 2343                diagnostics.get(file.path()).cloned().unwrap_or_default()
 2344            {
 2345                self.update_buffer_diagnostics(
 2346                    buffer_handle,
 2347                    server_id,
 2348                    None,
 2349                    None,
 2350                    None,
 2351                    Vec::new(),
 2352                    diagnostics,
 2353                    cx,
 2354                )
 2355                .log_err();
 2356            }
 2357        }
 2358        let Some(language) = language else {
 2359            return;
 2360        };
 2361        let Some(snapshot) = self
 2362            .worktree_store
 2363            .read(cx)
 2364            .worktree_for_id(worktree_id, cx)
 2365            .map(|worktree| worktree.read(cx).snapshot())
 2366        else {
 2367            return;
 2368        };
 2369        let delegate: Arc<dyn ManifestDelegate> = Arc::new(ManifestQueryDelegate::new(snapshot));
 2370
 2371        for server_id in
 2372            self.lsp_tree
 2373                .get(path, language.name(), language.manifest(), &delegate, cx)
 2374        {
 2375            let server = self
 2376                .language_servers
 2377                .get(&server_id)
 2378                .and_then(|server_state| {
 2379                    if let LanguageServerState::Running { server, .. } = server_state {
 2380                        Some(server.clone())
 2381                    } else {
 2382                        None
 2383                    }
 2384                });
 2385            let server = match server {
 2386                Some(server) => server,
 2387                None => continue,
 2388            };
 2389
 2390            buffer_handle.update(cx, |buffer, cx| {
 2391                buffer.set_completion_triggers(
 2392                    server.server_id(),
 2393                    server
 2394                        .capabilities()
 2395                        .completion_provider
 2396                        .as_ref()
 2397                        .and_then(|provider| {
 2398                            provider
 2399                                .trigger_characters
 2400                                .as_ref()
 2401                                .map(|characters| characters.iter().cloned().collect())
 2402                        })
 2403                        .unwrap_or_default(),
 2404                    cx,
 2405                );
 2406            });
 2407        }
 2408    }
 2409
 2410    pub(crate) fn reset_buffer(&mut self, buffer: &Entity<Buffer>, old_file: &File, cx: &mut App) {
 2411        buffer.update(cx, |buffer, cx| {
 2412            let Some(language) = buffer.language() else {
 2413                return;
 2414            };
 2415            let path = ProjectPath {
 2416                worktree_id: old_file.worktree_id(cx),
 2417                path: old_file.path.clone(),
 2418            };
 2419            for server_id in self.language_server_ids_for_project_path(path, language, cx) {
 2420                buffer.update_diagnostics(server_id, DiagnosticSet::new([], buffer), cx);
 2421                buffer.set_completion_triggers(server_id, Default::default(), cx);
 2422            }
 2423        });
 2424    }
 2425
 2426    fn update_buffer_diagnostics(
 2427        &mut self,
 2428        buffer: &Entity<Buffer>,
 2429        server_id: LanguageServerId,
 2430        registration_id: Option<Option<SharedString>>,
 2431        result_id: Option<SharedString>,
 2432        version: Option<i32>,
 2433        new_diagnostics: Vec<DiagnosticEntry<Unclipped<PointUtf16>>>,
 2434        reused_diagnostics: Vec<DiagnosticEntry<Unclipped<PointUtf16>>>,
 2435        cx: &mut Context<LspStore>,
 2436    ) -> Result<()> {
 2437        fn compare_diagnostics(a: &Diagnostic, b: &Diagnostic) -> Ordering {
 2438            Ordering::Equal
 2439                .then_with(|| b.is_primary.cmp(&a.is_primary))
 2440                .then_with(|| a.is_disk_based.cmp(&b.is_disk_based))
 2441                .then_with(|| a.severity.cmp(&b.severity))
 2442                .then_with(|| a.message.cmp(&b.message))
 2443        }
 2444
 2445        let mut diagnostics = Vec::with_capacity(new_diagnostics.len() + reused_diagnostics.len());
 2446        diagnostics.extend(new_diagnostics.into_iter().map(|d| (true, d)));
 2447        diagnostics.extend(reused_diagnostics.into_iter().map(|d| (false, d)));
 2448
 2449        diagnostics.sort_unstable_by(|(_, a), (_, b)| {
 2450            Ordering::Equal
 2451                .then_with(|| a.range.start.cmp(&b.range.start))
 2452                .then_with(|| b.range.end.cmp(&a.range.end))
 2453                .then_with(|| compare_diagnostics(&a.diagnostic, &b.diagnostic))
 2454        });
 2455
 2456        let snapshot = self.buffer_snapshot_for_lsp_version(buffer, server_id, version, cx)?;
 2457
 2458        let edits_since_save = std::cell::LazyCell::new(|| {
 2459            let saved_version = buffer.read(cx).saved_version();
 2460            Patch::new(snapshot.edits_since::<PointUtf16>(saved_version).collect())
 2461        });
 2462
 2463        let mut sanitized_diagnostics = Vec::with_capacity(diagnostics.len());
 2464
 2465        for (new_diagnostic, entry) in diagnostics {
 2466            let start;
 2467            let end;
 2468            if new_diagnostic && entry.diagnostic.is_disk_based {
 2469                // Some diagnostics are based on files on disk instead of buffers'
 2470                // current contents. Adjust these diagnostics' ranges to reflect
 2471                // any unsaved edits.
 2472                // Do not alter the reused ones though, as their coordinates were stored as anchors
 2473                // and were properly adjusted on reuse.
 2474                start = Unclipped((*edits_since_save).old_to_new(entry.range.start.0));
 2475                end = Unclipped((*edits_since_save).old_to_new(entry.range.end.0));
 2476            } else {
 2477                start = entry.range.start;
 2478                end = entry.range.end;
 2479            }
 2480
 2481            let mut range = snapshot.clip_point_utf16(start, Bias::Left)
 2482                ..snapshot.clip_point_utf16(end, Bias::Right);
 2483
 2484            // Expand empty ranges by one codepoint
 2485            if range.start == range.end {
 2486                // This will be go to the next boundary when being clipped
 2487                range.end.column += 1;
 2488                range.end = snapshot.clip_point_utf16(Unclipped(range.end), Bias::Right);
 2489                if range.start == range.end && range.end.column > 0 {
 2490                    range.start.column -= 1;
 2491                    range.start = snapshot.clip_point_utf16(Unclipped(range.start), Bias::Left);
 2492                }
 2493            }
 2494
 2495            sanitized_diagnostics.push(DiagnosticEntry {
 2496                range,
 2497                diagnostic: entry.diagnostic,
 2498            });
 2499        }
 2500        drop(edits_since_save);
 2501
 2502        let set = DiagnosticSet::new(sanitized_diagnostics, &snapshot);
 2503        buffer.update(cx, |buffer, cx| {
 2504            if let Some(registration_id) = registration_id {
 2505                if let Some(abs_path) = File::from_dyn(buffer.file()).map(|f| f.abs_path(cx)) {
 2506                    self.buffer_pull_diagnostics_result_ids
 2507                        .entry(server_id)
 2508                        .or_default()
 2509                        .entry(registration_id)
 2510                        .or_default()
 2511                        .insert(abs_path, result_id);
 2512                }
 2513            }
 2514
 2515            buffer.update_diagnostics(server_id, set, cx)
 2516        });
 2517
 2518        Ok(())
 2519    }
 2520
 2521    fn register_language_server_for_invisible_worktree(
 2522        &mut self,
 2523        worktree: &Entity<Worktree>,
 2524        language_server_id: LanguageServerId,
 2525        cx: &mut App,
 2526    ) {
 2527        let worktree = worktree.read(cx);
 2528        let worktree_id = worktree.id();
 2529        debug_assert!(!worktree.is_visible());
 2530        let Some(mut origin_seed) = self
 2531            .language_server_ids
 2532            .iter()
 2533            .find_map(|(seed, state)| (state.id == language_server_id).then(|| seed.clone()))
 2534        else {
 2535            return;
 2536        };
 2537        origin_seed.worktree_id = worktree_id;
 2538        self.language_server_ids
 2539            .entry(origin_seed)
 2540            .or_insert_with(|| UnifiedLanguageServer {
 2541                id: language_server_id,
 2542                project_roots: Default::default(),
 2543            });
 2544    }
 2545
 2546    fn register_buffer_with_language_servers(
 2547        &mut self,
 2548        buffer_handle: &Entity<Buffer>,
 2549        only_register_servers: HashSet<LanguageServerSelector>,
 2550        cx: &mut Context<LspStore>,
 2551    ) {
 2552        let buffer = buffer_handle.read(cx);
 2553        let buffer_id = buffer.remote_id();
 2554
 2555        let Some(file) = File::from_dyn(buffer.file()) else {
 2556            return;
 2557        };
 2558        if !file.is_local() {
 2559            return;
 2560        }
 2561
 2562        let abs_path = file.abs_path(cx);
 2563        let Some(uri) = file_path_to_lsp_url(&abs_path).log_err() else {
 2564            return;
 2565        };
 2566        let initial_snapshot = buffer.text_snapshot();
 2567        let worktree_id = file.worktree_id(cx);
 2568
 2569        let Some(language) = buffer.language().cloned() else {
 2570            return;
 2571        };
 2572        let path: Arc<RelPath> = file
 2573            .path()
 2574            .parent()
 2575            .map(Arc::from)
 2576            .unwrap_or_else(|| file.path().clone());
 2577        let Some(worktree) = self
 2578            .worktree_store
 2579            .read(cx)
 2580            .worktree_for_id(worktree_id, cx)
 2581        else {
 2582            return;
 2583        };
 2584        let language_name = language.name();
 2585        let (reused, delegate, servers) = self
 2586            .reuse_existing_language_server(&self.lsp_tree, &worktree, &language_name, cx)
 2587            .map(|(delegate, apply)| (true, delegate, apply(&mut self.lsp_tree)))
 2588            .unwrap_or_else(|| {
 2589                let lsp_delegate = LocalLspAdapterDelegate::from_local_lsp(self, &worktree, cx);
 2590                let delegate: Arc<dyn ManifestDelegate> =
 2591                    Arc::new(ManifestQueryDelegate::new(worktree.read(cx).snapshot()));
 2592
 2593                let servers = self
 2594                    .lsp_tree
 2595                    .walk(
 2596                        ProjectPath { worktree_id, path },
 2597                        language.name(),
 2598                        language.manifest(),
 2599                        &delegate,
 2600                        cx,
 2601                    )
 2602                    .collect::<Vec<_>>();
 2603                (false, lsp_delegate, servers)
 2604            });
 2605        let servers_and_adapters = servers
 2606            .into_iter()
 2607            .filter_map(|server_node| {
 2608                if reused && server_node.server_id().is_none() {
 2609                    return None;
 2610                }
 2611                if !only_register_servers.is_empty() {
 2612                    if let Some(server_id) = server_node.server_id()
 2613                        && !only_register_servers.contains(&LanguageServerSelector::Id(server_id))
 2614                    {
 2615                        return None;
 2616                    }
 2617                    if let Some(name) = server_node.name()
 2618                        && !only_register_servers.contains(&LanguageServerSelector::Name(name))
 2619                    {
 2620                        return None;
 2621                    }
 2622                }
 2623
 2624                let server_id = server_node.server_id_or_init(|disposition| {
 2625                    let path = &disposition.path;
 2626
 2627                    {
 2628                        let uri = Uri::from_file_path(worktree.read(cx).absolutize(&path.path));
 2629
 2630                        let server_id = self.get_or_insert_language_server(
 2631                            &worktree,
 2632                            delegate.clone(),
 2633                            disposition,
 2634                            &language_name,
 2635                            cx,
 2636                        );
 2637
 2638                        if let Some(state) = self.language_servers.get(&server_id)
 2639                            && let Ok(uri) = uri
 2640                        {
 2641                            state.add_workspace_folder(uri);
 2642                        };
 2643                        server_id
 2644                    }
 2645                })?;
 2646                let server_state = self.language_servers.get(&server_id)?;
 2647                if let LanguageServerState::Running {
 2648                    server, adapter, ..
 2649                } = server_state
 2650                {
 2651                    Some((server.clone(), adapter.clone()))
 2652                } else {
 2653                    None
 2654                }
 2655            })
 2656            .collect::<Vec<_>>();
 2657        for (server, adapter) in servers_and_adapters {
 2658            buffer_handle.update(cx, |buffer, cx| {
 2659                buffer.set_completion_triggers(
 2660                    server.server_id(),
 2661                    server
 2662                        .capabilities()
 2663                        .completion_provider
 2664                        .as_ref()
 2665                        .and_then(|provider| {
 2666                            provider
 2667                                .trigger_characters
 2668                                .as_ref()
 2669                                .map(|characters| characters.iter().cloned().collect())
 2670                        })
 2671                        .unwrap_or_default(),
 2672                    cx,
 2673                );
 2674            });
 2675
 2676            let snapshot = LspBufferSnapshot {
 2677                version: 0,
 2678                snapshot: initial_snapshot.clone(),
 2679            };
 2680
 2681            let mut registered = false;
 2682            self.buffer_snapshots
 2683                .entry(buffer_id)
 2684                .or_default()
 2685                .entry(server.server_id())
 2686                .or_insert_with(|| {
 2687                    registered = true;
 2688                    server.register_buffer(
 2689                        uri.clone(),
 2690                        adapter.language_id(&language.name()),
 2691                        0,
 2692                        initial_snapshot.text(),
 2693                    );
 2694
 2695                    vec![snapshot]
 2696                });
 2697
 2698            self.buffers_opened_in_servers
 2699                .entry(buffer_id)
 2700                .or_default()
 2701                .insert(server.server_id());
 2702            if registered {
 2703                cx.emit(LspStoreEvent::LanguageServerUpdate {
 2704                    language_server_id: server.server_id(),
 2705                    name: None,
 2706                    message: proto::update_language_server::Variant::RegisteredForBuffer(
 2707                        proto::RegisteredForBuffer {
 2708                            buffer_abs_path: abs_path.to_string_lossy().into_owned(),
 2709                            buffer_id: buffer_id.to_proto(),
 2710                        },
 2711                    ),
 2712                });
 2713            }
 2714        }
 2715    }
 2716
 2717    fn reuse_existing_language_server<'lang_name>(
 2718        &self,
 2719        server_tree: &LanguageServerTree,
 2720        worktree: &Entity<Worktree>,
 2721        language_name: &'lang_name LanguageName,
 2722        cx: &mut App,
 2723    ) -> Option<(
 2724        Arc<LocalLspAdapterDelegate>,
 2725        impl FnOnce(&mut LanguageServerTree) -> Vec<LanguageServerTreeNode> + use<'lang_name>,
 2726    )> {
 2727        if worktree.read(cx).is_visible() {
 2728            return None;
 2729        }
 2730
 2731        let worktree_store = self.worktree_store.read(cx);
 2732        let servers = server_tree
 2733            .instances
 2734            .iter()
 2735            .filter(|(worktree_id, _)| {
 2736                worktree_store
 2737                    .worktree_for_id(**worktree_id, cx)
 2738                    .is_some_and(|worktree| worktree.read(cx).is_visible())
 2739            })
 2740            .flat_map(|(worktree_id, servers)| {
 2741                servers
 2742                    .roots
 2743                    .iter()
 2744                    .flat_map(|(_, language_servers)| language_servers)
 2745                    .map(move |(_, (server_node, server_languages))| {
 2746                        (worktree_id, server_node, server_languages)
 2747                    })
 2748                    .filter(|(_, _, server_languages)| server_languages.contains(language_name))
 2749                    .map(|(worktree_id, server_node, _)| {
 2750                        (
 2751                            *worktree_id,
 2752                            LanguageServerTreeNode::from(Arc::downgrade(server_node)),
 2753                        )
 2754                    })
 2755            })
 2756            .fold(HashMap::default(), |mut acc, (worktree_id, server_node)| {
 2757                acc.entry(worktree_id)
 2758                    .or_insert_with(Vec::new)
 2759                    .push(server_node);
 2760                acc
 2761            })
 2762            .into_values()
 2763            .max_by_key(|servers| servers.len())?;
 2764
 2765        let worktree_id = worktree.read(cx).id();
 2766        let apply = move |tree: &mut LanguageServerTree| {
 2767            for server_node in &servers {
 2768                tree.register_reused(worktree_id, language_name.clone(), server_node.clone());
 2769            }
 2770            servers
 2771        };
 2772
 2773        let delegate = LocalLspAdapterDelegate::from_local_lsp(self, worktree, cx);
 2774        Some((delegate, apply))
 2775    }
 2776
 2777    pub(crate) fn unregister_old_buffer_from_language_servers(
 2778        &mut self,
 2779        buffer: &Entity<Buffer>,
 2780        old_file: &File,
 2781        cx: &mut App,
 2782    ) {
 2783        let old_path = match old_file.as_local() {
 2784            Some(local) => local.abs_path(cx),
 2785            None => return,
 2786        };
 2787
 2788        let Ok(file_url) = lsp::Uri::from_file_path(old_path.as_path()) else {
 2789            debug_panic!("{old_path:?} is not parseable as an URI");
 2790            return;
 2791        };
 2792        self.unregister_buffer_from_language_servers(buffer, &file_url, cx);
 2793    }
 2794
 2795    pub(crate) fn unregister_buffer_from_language_servers(
 2796        &mut self,
 2797        buffer: &Entity<Buffer>,
 2798        file_url: &lsp::Uri,
 2799        cx: &mut App,
 2800    ) {
 2801        buffer.update(cx, |buffer, cx| {
 2802            let mut snapshots = self.buffer_snapshots.remove(&buffer.remote_id());
 2803
 2804            for (_, language_server) in self.language_servers_for_buffer(buffer, cx) {
 2805                if snapshots
 2806                    .as_mut()
 2807                    .is_some_and(|map| map.remove(&language_server.server_id()).is_some())
 2808                {
 2809                    language_server.unregister_buffer(file_url.clone());
 2810                }
 2811            }
 2812        });
 2813    }
 2814
 2815    fn buffer_snapshot_for_lsp_version(
 2816        &mut self,
 2817        buffer: &Entity<Buffer>,
 2818        server_id: LanguageServerId,
 2819        version: Option<i32>,
 2820        cx: &App,
 2821    ) -> Result<TextBufferSnapshot> {
 2822        const OLD_VERSIONS_TO_RETAIN: i32 = 10;
 2823
 2824        if let Some(version) = version {
 2825            let buffer_id = buffer.read(cx).remote_id();
 2826            let snapshots = if let Some(snapshots) = self
 2827                .buffer_snapshots
 2828                .get_mut(&buffer_id)
 2829                .and_then(|m| m.get_mut(&server_id))
 2830            {
 2831                snapshots
 2832            } else if version == 0 {
 2833                // Some language servers report version 0 even if the buffer hasn't been opened yet.
 2834                // We detect this case and treat it as if the version was `None`.
 2835                return Ok(buffer.read(cx).text_snapshot());
 2836            } else {
 2837                anyhow::bail!("no snapshots found for buffer {buffer_id} and server {server_id}");
 2838            };
 2839
 2840            let found_snapshot = snapshots
 2841                    .binary_search_by_key(&version, |e| e.version)
 2842                    .map(|ix| snapshots[ix].snapshot.clone())
 2843                    .map_err(|_| {
 2844                        anyhow!("snapshot not found for buffer {buffer_id} server {server_id} at version {version}")
 2845                    })?;
 2846
 2847            snapshots.retain(|snapshot| snapshot.version + OLD_VERSIONS_TO_RETAIN >= version);
 2848            Ok(found_snapshot)
 2849        } else {
 2850            Ok((buffer.read(cx)).text_snapshot())
 2851        }
 2852    }
 2853
 2854    async fn get_server_code_actions_from_action_kinds(
 2855        lsp_store: &WeakEntity<LspStore>,
 2856        language_server_id: LanguageServerId,
 2857        code_action_kinds: Vec<lsp::CodeActionKind>,
 2858        buffer: &Entity<Buffer>,
 2859        cx: &mut AsyncApp,
 2860    ) -> Result<Vec<CodeAction>> {
 2861        let actions = lsp_store
 2862            .update(cx, move |this, cx| {
 2863                let request = GetCodeActions {
 2864                    range: text::Anchor::min_max_range_for_buffer(buffer.read(cx).remote_id()),
 2865                    kinds: Some(code_action_kinds),
 2866                };
 2867                let server = LanguageServerToQuery::Other(language_server_id);
 2868                this.request_lsp(buffer.clone(), server, request, cx)
 2869            })?
 2870            .await?;
 2871        Ok(actions)
 2872    }
 2873
 2874    pub async fn execute_code_actions_on_server(
 2875        lsp_store: &WeakEntity<LspStore>,
 2876        language_server: &Arc<LanguageServer>,
 2877
 2878        actions: Vec<CodeAction>,
 2879        push_to_history: bool,
 2880        project_transaction: &mut ProjectTransaction,
 2881        cx: &mut AsyncApp,
 2882    ) -> anyhow::Result<()> {
 2883        for mut action in actions {
 2884            Self::try_resolve_code_action(language_server, &mut action)
 2885                .await
 2886                .context("resolving a formatting code action")?;
 2887
 2888            if let Some(edit) = action.lsp_action.edit() {
 2889                if edit.changes.is_none() && edit.document_changes.is_none() {
 2890                    continue;
 2891                }
 2892
 2893                let new = Self::deserialize_workspace_edit(
 2894                    lsp_store.upgrade().context("project dropped")?,
 2895                    edit.clone(),
 2896                    push_to_history,
 2897                    language_server.clone(),
 2898                    cx,
 2899                )
 2900                .await?;
 2901                project_transaction.0.extend(new.0);
 2902            }
 2903
 2904            if let Some(command) = action.lsp_action.command() {
 2905                let server_capabilities = language_server.capabilities();
 2906                let available_commands = server_capabilities
 2907                    .execute_command_provider
 2908                    .as_ref()
 2909                    .map(|options| options.commands.as_slice())
 2910                    .unwrap_or_default();
 2911                if available_commands.contains(&command.command) {
 2912                    lsp_store.update(cx, |lsp_store, _| {
 2913                        if let LspStoreMode::Local(mode) = &mut lsp_store.mode {
 2914                            mode.last_workspace_edits_by_language_server
 2915                                .remove(&language_server.server_id());
 2916                        }
 2917                    })?;
 2918
 2919                    language_server
 2920                        .request::<lsp::request::ExecuteCommand>(lsp::ExecuteCommandParams {
 2921                            command: command.command.clone(),
 2922                            arguments: command.arguments.clone().unwrap_or_default(),
 2923                            ..Default::default()
 2924                        })
 2925                        .await
 2926                        .into_response()
 2927                        .context("execute command")?;
 2928
 2929                    lsp_store.update(cx, |this, _| {
 2930                        if let LspStoreMode::Local(mode) = &mut this.mode {
 2931                            project_transaction.0.extend(
 2932                                mode.last_workspace_edits_by_language_server
 2933                                    .remove(&language_server.server_id())
 2934                                    .unwrap_or_default()
 2935                                    .0,
 2936                            )
 2937                        }
 2938                    })?;
 2939                } else {
 2940                    log::warn!(
 2941                        "Cannot execute a command {} not listed in the language server capabilities",
 2942                        command.command
 2943                    )
 2944                }
 2945            }
 2946        }
 2947        Ok(())
 2948    }
 2949
 2950    pub async fn deserialize_text_edits(
 2951        this: Entity<LspStore>,
 2952        buffer_to_edit: Entity<Buffer>,
 2953        edits: Vec<lsp::TextEdit>,
 2954        push_to_history: bool,
 2955        _: Arc<CachedLspAdapter>,
 2956        language_server: Arc<LanguageServer>,
 2957        cx: &mut AsyncApp,
 2958    ) -> Result<Option<Transaction>> {
 2959        let edits = this
 2960            .update(cx, |this, cx| {
 2961                this.as_local_mut().unwrap().edits_from_lsp(
 2962                    &buffer_to_edit,
 2963                    edits,
 2964                    language_server.server_id(),
 2965                    None,
 2966                    cx,
 2967                )
 2968            })?
 2969            .await?;
 2970
 2971        let transaction = buffer_to_edit.update(cx, |buffer, cx| {
 2972            buffer.finalize_last_transaction();
 2973            buffer.start_transaction();
 2974            for (range, text) in edits {
 2975                buffer.edit([(range, text)], None, cx);
 2976            }
 2977
 2978            if buffer.end_transaction(cx).is_some() {
 2979                let transaction = buffer.finalize_last_transaction().unwrap().clone();
 2980                if !push_to_history {
 2981                    buffer.forget_transaction(transaction.id);
 2982                }
 2983                Some(transaction)
 2984            } else {
 2985                None
 2986            }
 2987        })?;
 2988
 2989        Ok(transaction)
 2990    }
 2991
 2992    #[allow(clippy::type_complexity)]
 2993    pub(crate) fn edits_from_lsp(
 2994        &mut self,
 2995        buffer: &Entity<Buffer>,
 2996        lsp_edits: impl 'static + Send + IntoIterator<Item = lsp::TextEdit>,
 2997        server_id: LanguageServerId,
 2998        version: Option<i32>,
 2999        cx: &mut Context<LspStore>,
 3000    ) -> Task<Result<Vec<(Range<Anchor>, Arc<str>)>>> {
 3001        let snapshot = self.buffer_snapshot_for_lsp_version(buffer, server_id, version, cx);
 3002        cx.background_spawn(async move {
 3003            let snapshot = snapshot?;
 3004            let mut lsp_edits = lsp_edits
 3005                .into_iter()
 3006                .map(|edit| (range_from_lsp(edit.range), edit.new_text))
 3007                .collect::<Vec<_>>();
 3008
 3009            lsp_edits.sort_by_key(|(range, _)| (range.start, range.end));
 3010
 3011            let mut lsp_edits = lsp_edits.into_iter().peekable();
 3012            let mut edits = Vec::new();
 3013            while let Some((range, mut new_text)) = lsp_edits.next() {
 3014                // Clip invalid ranges provided by the language server.
 3015                let mut range = snapshot.clip_point_utf16(range.start, Bias::Left)
 3016                    ..snapshot.clip_point_utf16(range.end, Bias::Left);
 3017
 3018                // Combine any LSP edits that are adjacent.
 3019                //
 3020                // Also, combine LSP edits that are separated from each other by only
 3021                // a newline. This is important because for some code actions,
 3022                // Rust-analyzer rewrites the entire buffer via a series of edits that
 3023                // are separated by unchanged newline characters.
 3024                //
 3025                // In order for the diffing logic below to work properly, any edits that
 3026                // cancel each other out must be combined into one.
 3027                while let Some((next_range, next_text)) = lsp_edits.peek() {
 3028                    if next_range.start.0 > range.end {
 3029                        if next_range.start.0.row > range.end.row + 1
 3030                            || next_range.start.0.column > 0
 3031                            || snapshot.clip_point_utf16(
 3032                                Unclipped(PointUtf16::new(range.end.row, u32::MAX)),
 3033                                Bias::Left,
 3034                            ) > range.end
 3035                        {
 3036                            break;
 3037                        }
 3038                        new_text.push('\n');
 3039                    }
 3040                    range.end = snapshot.clip_point_utf16(next_range.end, Bias::Left);
 3041                    new_text.push_str(next_text);
 3042                    lsp_edits.next();
 3043                }
 3044
 3045                // For multiline edits, perform a diff of the old and new text so that
 3046                // we can identify the changes more precisely, preserving the locations
 3047                // of any anchors positioned in the unchanged regions.
 3048                if range.end.row > range.start.row {
 3049                    let offset = range.start.to_offset(&snapshot);
 3050                    let old_text = snapshot.text_for_range(range).collect::<String>();
 3051                    let range_edits = language::text_diff(old_text.as_str(), &new_text);
 3052                    edits.extend(range_edits.into_iter().map(|(range, replacement)| {
 3053                        (
 3054                            snapshot.anchor_after(offset + range.start)
 3055                                ..snapshot.anchor_before(offset + range.end),
 3056                            replacement,
 3057                        )
 3058                    }));
 3059                } else if range.end == range.start {
 3060                    let anchor = snapshot.anchor_after(range.start);
 3061                    edits.push((anchor..anchor, new_text.into()));
 3062                } else {
 3063                    let edit_start = snapshot.anchor_after(range.start);
 3064                    let edit_end = snapshot.anchor_before(range.end);
 3065                    edits.push((edit_start..edit_end, new_text.into()));
 3066                }
 3067            }
 3068
 3069            Ok(edits)
 3070        })
 3071    }
 3072
 3073    pub(crate) async fn deserialize_workspace_edit(
 3074        this: Entity<LspStore>,
 3075        edit: lsp::WorkspaceEdit,
 3076        push_to_history: bool,
 3077        language_server: Arc<LanguageServer>,
 3078        cx: &mut AsyncApp,
 3079    ) -> Result<ProjectTransaction> {
 3080        let fs = this.read_with(cx, |this, _| this.as_local().unwrap().fs.clone())?;
 3081
 3082        let mut operations = Vec::new();
 3083        if let Some(document_changes) = edit.document_changes {
 3084            match document_changes {
 3085                lsp::DocumentChanges::Edits(edits) => {
 3086                    operations.extend(edits.into_iter().map(lsp::DocumentChangeOperation::Edit))
 3087                }
 3088                lsp::DocumentChanges::Operations(ops) => operations = ops,
 3089            }
 3090        } else if let Some(changes) = edit.changes {
 3091            operations.extend(changes.into_iter().map(|(uri, edits)| {
 3092                lsp::DocumentChangeOperation::Edit(lsp::TextDocumentEdit {
 3093                    text_document: lsp::OptionalVersionedTextDocumentIdentifier {
 3094                        uri,
 3095                        version: None,
 3096                    },
 3097                    edits: edits.into_iter().map(Edit::Plain).collect(),
 3098                })
 3099            }));
 3100        }
 3101
 3102        let mut project_transaction = ProjectTransaction::default();
 3103        for operation in operations {
 3104            match operation {
 3105                lsp::DocumentChangeOperation::Op(lsp::ResourceOp::Create(op)) => {
 3106                    let abs_path = op
 3107                        .uri
 3108                        .to_file_path()
 3109                        .map_err(|()| anyhow!("can't convert URI to path"))?;
 3110
 3111                    if let Some(parent_path) = abs_path.parent() {
 3112                        fs.create_dir(parent_path).await?;
 3113                    }
 3114                    if abs_path.ends_with("/") {
 3115                        fs.create_dir(&abs_path).await?;
 3116                    } else {
 3117                        fs.create_file(
 3118                            &abs_path,
 3119                            op.options
 3120                                .map(|options| fs::CreateOptions {
 3121                                    overwrite: options.overwrite.unwrap_or(false),
 3122                                    ignore_if_exists: options.ignore_if_exists.unwrap_or(false),
 3123                                })
 3124                                .unwrap_or_default(),
 3125                        )
 3126                        .await?;
 3127                    }
 3128                }
 3129
 3130                lsp::DocumentChangeOperation::Op(lsp::ResourceOp::Rename(op)) => {
 3131                    let source_abs_path = op
 3132                        .old_uri
 3133                        .to_file_path()
 3134                        .map_err(|()| anyhow!("can't convert URI to path"))?;
 3135                    let target_abs_path = op
 3136                        .new_uri
 3137                        .to_file_path()
 3138                        .map_err(|()| anyhow!("can't convert URI to path"))?;
 3139
 3140                    let options = fs::RenameOptions {
 3141                        overwrite: op
 3142                            .options
 3143                            .as_ref()
 3144                            .and_then(|options| options.overwrite)
 3145                            .unwrap_or(false),
 3146                        ignore_if_exists: op
 3147                            .options
 3148                            .as_ref()
 3149                            .and_then(|options| options.ignore_if_exists)
 3150                            .unwrap_or(false),
 3151                        create_parents: true,
 3152                    };
 3153
 3154                    fs.rename(&source_abs_path, &target_abs_path, options)
 3155                        .await?;
 3156                }
 3157
 3158                lsp::DocumentChangeOperation::Op(lsp::ResourceOp::Delete(op)) => {
 3159                    let abs_path = op
 3160                        .uri
 3161                        .to_file_path()
 3162                        .map_err(|()| anyhow!("can't convert URI to path"))?;
 3163                    let options = op
 3164                        .options
 3165                        .map(|options| fs::RemoveOptions {
 3166                            recursive: options.recursive.unwrap_or(false),
 3167                            ignore_if_not_exists: options.ignore_if_not_exists.unwrap_or(false),
 3168                        })
 3169                        .unwrap_or_default();
 3170                    if abs_path.ends_with("/") {
 3171                        fs.remove_dir(&abs_path, options).await?;
 3172                    } else {
 3173                        fs.remove_file(&abs_path, options).await?;
 3174                    }
 3175                }
 3176
 3177                lsp::DocumentChangeOperation::Edit(op) => {
 3178                    let buffer_to_edit = this
 3179                        .update(cx, |this, cx| {
 3180                            this.open_local_buffer_via_lsp(
 3181                                op.text_document.uri.clone(),
 3182                                language_server.server_id(),
 3183                                cx,
 3184                            )
 3185                        })?
 3186                        .await?;
 3187
 3188                    let edits = this
 3189                        .update(cx, |this, cx| {
 3190                            let path = buffer_to_edit.read(cx).project_path(cx);
 3191                            let active_entry = this.active_entry;
 3192                            let is_active_entry = path.is_some_and(|project_path| {
 3193                                this.worktree_store
 3194                                    .read(cx)
 3195                                    .entry_for_path(&project_path, cx)
 3196                                    .is_some_and(|entry| Some(entry.id) == active_entry)
 3197                            });
 3198                            let local = this.as_local_mut().unwrap();
 3199
 3200                            let (mut edits, mut snippet_edits) = (vec![], vec![]);
 3201                            for edit in op.edits {
 3202                                match edit {
 3203                                    Edit::Plain(edit) => {
 3204                                        if !edits.contains(&edit) {
 3205                                            edits.push(edit)
 3206                                        }
 3207                                    }
 3208                                    Edit::Annotated(edit) => {
 3209                                        if !edits.contains(&edit.text_edit) {
 3210                                            edits.push(edit.text_edit)
 3211                                        }
 3212                                    }
 3213                                    Edit::Snippet(edit) => {
 3214                                        let Ok(snippet) = Snippet::parse(&edit.snippet.value)
 3215                                        else {
 3216                                            continue;
 3217                                        };
 3218
 3219                                        if is_active_entry {
 3220                                            snippet_edits.push((edit.range, snippet));
 3221                                        } else {
 3222                                            // Since this buffer is not focused, apply a normal edit.
 3223                                            let new_edit = TextEdit {
 3224                                                range: edit.range,
 3225                                                new_text: snippet.text,
 3226                                            };
 3227                                            if !edits.contains(&new_edit) {
 3228                                                edits.push(new_edit);
 3229                                            }
 3230                                        }
 3231                                    }
 3232                                }
 3233                            }
 3234                            if !snippet_edits.is_empty() {
 3235                                let buffer_id = buffer_to_edit.read(cx).remote_id();
 3236                                let version = if let Some(buffer_version) = op.text_document.version
 3237                                {
 3238                                    local
 3239                                        .buffer_snapshot_for_lsp_version(
 3240                                            &buffer_to_edit,
 3241                                            language_server.server_id(),
 3242                                            Some(buffer_version),
 3243                                            cx,
 3244                                        )
 3245                                        .ok()
 3246                                        .map(|snapshot| snapshot.version)
 3247                                } else {
 3248                                    Some(buffer_to_edit.read(cx).saved_version().clone())
 3249                                };
 3250
 3251                                let most_recent_edit =
 3252                                    version.and_then(|version| version.most_recent());
 3253                                // Check if the edit that triggered that edit has been made by this participant.
 3254
 3255                                if let Some(most_recent_edit) = most_recent_edit {
 3256                                    cx.emit(LspStoreEvent::SnippetEdit {
 3257                                        buffer_id,
 3258                                        edits: snippet_edits,
 3259                                        most_recent_edit,
 3260                                    });
 3261                                }
 3262                            }
 3263
 3264                            local.edits_from_lsp(
 3265                                &buffer_to_edit,
 3266                                edits,
 3267                                language_server.server_id(),
 3268                                op.text_document.version,
 3269                                cx,
 3270                            )
 3271                        })?
 3272                        .await?;
 3273
 3274                    let transaction = buffer_to_edit.update(cx, |buffer, cx| {
 3275                        buffer.finalize_last_transaction();
 3276                        buffer.start_transaction();
 3277                        for (range, text) in edits {
 3278                            buffer.edit([(range, text)], None, cx);
 3279                        }
 3280
 3281                        buffer.end_transaction(cx).and_then(|transaction_id| {
 3282                            if push_to_history {
 3283                                buffer.finalize_last_transaction();
 3284                                buffer.get_transaction(transaction_id).cloned()
 3285                            } else {
 3286                                buffer.forget_transaction(transaction_id)
 3287                            }
 3288                        })
 3289                    })?;
 3290                    if let Some(transaction) = transaction {
 3291                        project_transaction.0.insert(buffer_to_edit, transaction);
 3292                    }
 3293                }
 3294            }
 3295        }
 3296
 3297        Ok(project_transaction)
 3298    }
 3299
 3300    async fn on_lsp_workspace_edit(
 3301        this: WeakEntity<LspStore>,
 3302        params: lsp::ApplyWorkspaceEditParams,
 3303        server_id: LanguageServerId,
 3304        cx: &mut AsyncApp,
 3305    ) -> Result<lsp::ApplyWorkspaceEditResponse> {
 3306        let this = this.upgrade().context("project project closed")?;
 3307        let language_server = this
 3308            .read_with(cx, |this, _| this.language_server_for_id(server_id))?
 3309            .context("language server not found")?;
 3310        let transaction = Self::deserialize_workspace_edit(
 3311            this.clone(),
 3312            params.edit,
 3313            true,
 3314            language_server.clone(),
 3315            cx,
 3316        )
 3317        .await
 3318        .log_err();
 3319        this.update(cx, |this, cx| {
 3320            if let Some(transaction) = transaction {
 3321                cx.emit(LspStoreEvent::WorkspaceEditApplied(transaction.clone()));
 3322
 3323                this.as_local_mut()
 3324                    .unwrap()
 3325                    .last_workspace_edits_by_language_server
 3326                    .insert(server_id, transaction);
 3327            }
 3328        })?;
 3329        Ok(lsp::ApplyWorkspaceEditResponse {
 3330            applied: true,
 3331            failed_change: None,
 3332            failure_reason: None,
 3333        })
 3334    }
 3335
 3336    fn remove_worktree(
 3337        &mut self,
 3338        id_to_remove: WorktreeId,
 3339        cx: &mut Context<LspStore>,
 3340    ) -> Vec<LanguageServerId> {
 3341        self.restricted_worktrees_tasks.remove(&id_to_remove);
 3342        self.diagnostics.remove(&id_to_remove);
 3343        self.prettier_store.update(cx, |prettier_store, cx| {
 3344            prettier_store.remove_worktree(id_to_remove, cx);
 3345        });
 3346
 3347        let mut servers_to_remove = BTreeSet::default();
 3348        let mut servers_to_preserve = HashSet::default();
 3349        for (seed, state) in &self.language_server_ids {
 3350            if seed.worktree_id == id_to_remove {
 3351                servers_to_remove.insert(state.id);
 3352            } else {
 3353                servers_to_preserve.insert(state.id);
 3354            }
 3355        }
 3356        servers_to_remove.retain(|server_id| !servers_to_preserve.contains(server_id));
 3357        self.language_server_ids
 3358            .retain(|_, state| !servers_to_remove.contains(&state.id));
 3359        for server_id_to_remove in &servers_to_remove {
 3360            self.language_server_watched_paths
 3361                .remove(server_id_to_remove);
 3362            self.language_server_paths_watched_for_rename
 3363                .remove(server_id_to_remove);
 3364            self.last_workspace_edits_by_language_server
 3365                .remove(server_id_to_remove);
 3366            self.language_servers.remove(server_id_to_remove);
 3367            self.buffer_pull_diagnostics_result_ids
 3368                .remove(server_id_to_remove);
 3369            self.workspace_pull_diagnostics_result_ids
 3370                .remove(server_id_to_remove);
 3371            for buffer_servers in self.buffers_opened_in_servers.values_mut() {
 3372                buffer_servers.remove(server_id_to_remove);
 3373            }
 3374            cx.emit(LspStoreEvent::LanguageServerRemoved(*server_id_to_remove));
 3375        }
 3376        servers_to_remove.into_iter().collect()
 3377    }
 3378
 3379    fn rebuild_watched_paths_inner<'a>(
 3380        &'a self,
 3381        language_server_id: LanguageServerId,
 3382        watchers: impl Iterator<Item = &'a FileSystemWatcher>,
 3383        cx: &mut Context<LspStore>,
 3384    ) -> LanguageServerWatchedPathsBuilder {
 3385        let worktrees = self
 3386            .worktree_store
 3387            .read(cx)
 3388            .worktrees()
 3389            .filter_map(|worktree| {
 3390                self.language_servers_for_worktree(worktree.read(cx).id())
 3391                    .find(|server| server.server_id() == language_server_id)
 3392                    .map(|_| worktree)
 3393            })
 3394            .collect::<Vec<_>>();
 3395
 3396        let mut worktree_globs = HashMap::default();
 3397        let mut abs_globs = HashMap::default();
 3398        log::trace!(
 3399            "Processing new watcher paths for language server with id {}",
 3400            language_server_id
 3401        );
 3402
 3403        for watcher in watchers {
 3404            if let Some((worktree, literal_prefix, pattern)) =
 3405                Self::worktree_and_path_for_file_watcher(&worktrees, watcher, cx)
 3406            {
 3407                worktree.update(cx, |worktree, _| {
 3408                    if let Some((tree, glob)) =
 3409                        worktree.as_local_mut().zip(Glob::new(&pattern).log_err())
 3410                    {
 3411                        tree.add_path_prefix_to_scan(literal_prefix);
 3412                        worktree_globs
 3413                            .entry(tree.id())
 3414                            .or_insert_with(GlobSetBuilder::new)
 3415                            .add(glob);
 3416                    }
 3417                });
 3418            } else {
 3419                let (path, pattern) = match &watcher.glob_pattern {
 3420                    lsp::GlobPattern::String(s) => {
 3421                        let watcher_path = SanitizedPath::new(s);
 3422                        let path = glob_literal_prefix(watcher_path.as_path());
 3423                        let pattern = watcher_path
 3424                            .as_path()
 3425                            .strip_prefix(&path)
 3426                            .map(|p| p.to_string_lossy().into_owned())
 3427                            .unwrap_or_else(|e| {
 3428                                debug_panic!(
 3429                                    "Failed to strip prefix for string pattern: {}, with prefix: {}, with error: {}",
 3430                                    s,
 3431                                    path.display(),
 3432                                    e
 3433                                );
 3434                                watcher_path.as_path().to_string_lossy().into_owned()
 3435                            });
 3436                        (path, pattern)
 3437                    }
 3438                    lsp::GlobPattern::Relative(rp) => {
 3439                        let Ok(mut base_uri) = match &rp.base_uri {
 3440                            lsp::OneOf::Left(workspace_folder) => &workspace_folder.uri,
 3441                            lsp::OneOf::Right(base_uri) => base_uri,
 3442                        }
 3443                        .to_file_path() else {
 3444                            continue;
 3445                        };
 3446
 3447                        let path = glob_literal_prefix(Path::new(&rp.pattern));
 3448                        let pattern = Path::new(&rp.pattern)
 3449                            .strip_prefix(&path)
 3450                            .map(|p| p.to_string_lossy().into_owned())
 3451                            .unwrap_or_else(|e| {
 3452                                debug_panic!(
 3453                                    "Failed to strip prefix for relative pattern: {}, with prefix: {}, with error: {}",
 3454                                    rp.pattern,
 3455                                    path.display(),
 3456                                    e
 3457                                );
 3458                                rp.pattern.clone()
 3459                            });
 3460                        base_uri.push(path);
 3461                        (base_uri, pattern)
 3462                    }
 3463                };
 3464
 3465                if let Some(glob) = Glob::new(&pattern).log_err() {
 3466                    if !path
 3467                        .components()
 3468                        .any(|c| matches!(c, path::Component::Normal(_)))
 3469                    {
 3470                        // For an unrooted glob like `**/Cargo.toml`, watch it within each worktree,
 3471                        // rather than adding a new watcher for `/`.
 3472                        for worktree in &worktrees {
 3473                            worktree_globs
 3474                                .entry(worktree.read(cx).id())
 3475                                .or_insert_with(GlobSetBuilder::new)
 3476                                .add(glob.clone());
 3477                        }
 3478                    } else {
 3479                        abs_globs
 3480                            .entry(path.into())
 3481                            .or_insert_with(GlobSetBuilder::new)
 3482                            .add(glob);
 3483                    }
 3484                }
 3485            }
 3486        }
 3487
 3488        let mut watch_builder = LanguageServerWatchedPathsBuilder::default();
 3489        for (worktree_id, builder) in worktree_globs {
 3490            if let Ok(globset) = builder.build() {
 3491                watch_builder.watch_worktree(worktree_id, globset);
 3492            }
 3493        }
 3494        for (abs_path, builder) in abs_globs {
 3495            if let Ok(globset) = builder.build() {
 3496                watch_builder.watch_abs_path(abs_path, globset);
 3497            }
 3498        }
 3499        watch_builder
 3500    }
 3501
 3502    fn worktree_and_path_for_file_watcher(
 3503        worktrees: &[Entity<Worktree>],
 3504        watcher: &FileSystemWatcher,
 3505        cx: &App,
 3506    ) -> Option<(Entity<Worktree>, Arc<RelPath>, String)> {
 3507        worktrees.iter().find_map(|worktree| {
 3508            let tree = worktree.read(cx);
 3509            let worktree_root_path = tree.abs_path();
 3510            let path_style = tree.path_style();
 3511            match &watcher.glob_pattern {
 3512                lsp::GlobPattern::String(s) => {
 3513                    let watcher_path = SanitizedPath::new(s);
 3514                    let relative = watcher_path
 3515                        .as_path()
 3516                        .strip_prefix(&worktree_root_path)
 3517                        .ok()?;
 3518                    let literal_prefix = glob_literal_prefix(relative);
 3519                    Some((
 3520                        worktree.clone(),
 3521                        RelPath::new(&literal_prefix, path_style).ok()?.into_arc(),
 3522                        relative.to_string_lossy().into_owned(),
 3523                    ))
 3524                }
 3525                lsp::GlobPattern::Relative(rp) => {
 3526                    let base_uri = match &rp.base_uri {
 3527                        lsp::OneOf::Left(workspace_folder) => &workspace_folder.uri,
 3528                        lsp::OneOf::Right(base_uri) => base_uri,
 3529                    }
 3530                    .to_file_path()
 3531                    .ok()?;
 3532                    let relative = base_uri.strip_prefix(&worktree_root_path).ok()?;
 3533                    let mut literal_prefix = relative.to_owned();
 3534                    literal_prefix.push(glob_literal_prefix(Path::new(&rp.pattern)));
 3535                    Some((
 3536                        worktree.clone(),
 3537                        RelPath::new(&literal_prefix, path_style).ok()?.into_arc(),
 3538                        rp.pattern.clone(),
 3539                    ))
 3540                }
 3541            }
 3542        })
 3543    }
 3544
 3545    fn rebuild_watched_paths(
 3546        &mut self,
 3547        language_server_id: LanguageServerId,
 3548        cx: &mut Context<LspStore>,
 3549    ) {
 3550        let Some(registrations) = self
 3551            .language_server_dynamic_registrations
 3552            .get(&language_server_id)
 3553        else {
 3554            return;
 3555        };
 3556
 3557        let watch_builder = self.rebuild_watched_paths_inner(
 3558            language_server_id,
 3559            registrations.did_change_watched_files.values().flatten(),
 3560            cx,
 3561        );
 3562        let watcher = watch_builder.build(self.fs.clone(), language_server_id, cx);
 3563        self.language_server_watched_paths
 3564            .insert(language_server_id, watcher);
 3565
 3566        cx.notify();
 3567    }
 3568
 3569    fn on_lsp_did_change_watched_files(
 3570        &mut self,
 3571        language_server_id: LanguageServerId,
 3572        registration_id: &str,
 3573        params: DidChangeWatchedFilesRegistrationOptions,
 3574        cx: &mut Context<LspStore>,
 3575    ) {
 3576        let registrations = self
 3577            .language_server_dynamic_registrations
 3578            .entry(language_server_id)
 3579            .or_default();
 3580
 3581        registrations
 3582            .did_change_watched_files
 3583            .insert(registration_id.to_string(), params.watchers);
 3584
 3585        self.rebuild_watched_paths(language_server_id, cx);
 3586    }
 3587
 3588    fn on_lsp_unregister_did_change_watched_files(
 3589        &mut self,
 3590        language_server_id: LanguageServerId,
 3591        registration_id: &str,
 3592        cx: &mut Context<LspStore>,
 3593    ) {
 3594        let registrations = self
 3595            .language_server_dynamic_registrations
 3596            .entry(language_server_id)
 3597            .or_default();
 3598
 3599        if registrations
 3600            .did_change_watched_files
 3601            .remove(registration_id)
 3602            .is_some()
 3603        {
 3604            log::info!(
 3605                "language server {}: unregistered workspace/DidChangeWatchedFiles capability with id {}",
 3606                language_server_id,
 3607                registration_id
 3608            );
 3609        } else {
 3610            log::warn!(
 3611                "language server {}: failed to unregister workspace/DidChangeWatchedFiles capability with id {}. not registered.",
 3612                language_server_id,
 3613                registration_id
 3614            );
 3615        }
 3616
 3617        self.rebuild_watched_paths(language_server_id, cx);
 3618    }
 3619
 3620    async fn initialization_options_for_adapter(
 3621        adapter: Arc<dyn LspAdapter>,
 3622        delegate: &Arc<dyn LspAdapterDelegate>,
 3623    ) -> Result<Option<serde_json::Value>> {
 3624        let Some(mut initialization_config) =
 3625            adapter.clone().initialization_options(delegate).await?
 3626        else {
 3627            return Ok(None);
 3628        };
 3629
 3630        for other_adapter in delegate.registered_lsp_adapters() {
 3631            if other_adapter.name() == adapter.name() {
 3632                continue;
 3633            }
 3634            if let Ok(Some(target_config)) = other_adapter
 3635                .clone()
 3636                .additional_initialization_options(adapter.name(), delegate)
 3637                .await
 3638            {
 3639                merge_json_value_into(target_config.clone(), &mut initialization_config);
 3640            }
 3641        }
 3642
 3643        Ok(Some(initialization_config))
 3644    }
 3645
 3646    async fn workspace_configuration_for_adapter(
 3647        adapter: Arc<dyn LspAdapter>,
 3648        delegate: &Arc<dyn LspAdapterDelegate>,
 3649        toolchain: Option<Toolchain>,
 3650        requested_uri: Option<Uri>,
 3651        cx: &mut AsyncApp,
 3652    ) -> Result<serde_json::Value> {
 3653        let mut workspace_config = adapter
 3654            .clone()
 3655            .workspace_configuration(delegate, toolchain, requested_uri, cx)
 3656            .await?;
 3657
 3658        for other_adapter in delegate.registered_lsp_adapters() {
 3659            if other_adapter.name() == adapter.name() {
 3660                continue;
 3661            }
 3662            if let Ok(Some(target_config)) = other_adapter
 3663                .clone()
 3664                .additional_workspace_configuration(adapter.name(), delegate, cx)
 3665                .await
 3666            {
 3667                merge_json_value_into(target_config.clone(), &mut workspace_config);
 3668            }
 3669        }
 3670
 3671        Ok(workspace_config)
 3672    }
 3673
 3674    fn language_server_for_id(&self, id: LanguageServerId) -> Option<Arc<LanguageServer>> {
 3675        if let Some(LanguageServerState::Running { server, .. }) = self.language_servers.get(&id) {
 3676            Some(server.clone())
 3677        } else if let Some((_, server)) = self.supplementary_language_servers.get(&id) {
 3678            Some(Arc::clone(server))
 3679        } else {
 3680            None
 3681        }
 3682    }
 3683}
 3684
 3685fn notify_server_capabilities_updated(server: &LanguageServer, cx: &mut Context<LspStore>) {
 3686    if let Some(capabilities) = serde_json::to_string(&server.capabilities()).ok() {
 3687        cx.emit(LspStoreEvent::LanguageServerUpdate {
 3688            language_server_id: server.server_id(),
 3689            name: Some(server.name()),
 3690            message: proto::update_language_server::Variant::MetadataUpdated(
 3691                proto::ServerMetadataUpdated {
 3692                    capabilities: Some(capabilities),
 3693                    binary: Some(proto::LanguageServerBinaryInfo {
 3694                        path: server.binary().path.to_string_lossy().into_owned(),
 3695                        arguments: server
 3696                            .binary()
 3697                            .arguments
 3698                            .iter()
 3699                            .map(|arg| arg.to_string_lossy().into_owned())
 3700                            .collect(),
 3701                    }),
 3702                    configuration: serde_json::to_string(server.configuration()).ok(),
 3703                    workspace_folders: server
 3704                        .workspace_folders()
 3705                        .iter()
 3706                        .map(|uri| uri.to_string())
 3707                        .collect(),
 3708                },
 3709            ),
 3710        });
 3711    }
 3712}
 3713
 3714#[derive(Debug)]
 3715pub struct FormattableBuffer {
 3716    handle: Entity<Buffer>,
 3717    abs_path: Option<PathBuf>,
 3718    env: Option<HashMap<String, String>>,
 3719    ranges: Option<Vec<Range<Anchor>>>,
 3720}
 3721
 3722pub struct RemoteLspStore {
 3723    upstream_client: Option<AnyProtoClient>,
 3724    upstream_project_id: u64,
 3725}
 3726
 3727pub(crate) enum LspStoreMode {
 3728    Local(LocalLspStore),   // ssh host and collab host
 3729    Remote(RemoteLspStore), // collab guest
 3730}
 3731
 3732impl LspStoreMode {
 3733    fn is_local(&self) -> bool {
 3734        matches!(self, LspStoreMode::Local(_))
 3735    }
 3736}
 3737
 3738pub struct LspStore {
 3739    mode: LspStoreMode,
 3740    last_formatting_failure: Option<String>,
 3741    downstream_client: Option<(AnyProtoClient, u64)>,
 3742    nonce: u128,
 3743    buffer_store: Entity<BufferStore>,
 3744    worktree_store: Entity<WorktreeStore>,
 3745    pub languages: Arc<LanguageRegistry>,
 3746    pub language_server_statuses: BTreeMap<LanguageServerId, LanguageServerStatus>,
 3747    active_entry: Option<ProjectEntryId>,
 3748    _maintain_workspace_config: (Task<Result<()>>, watch::Sender<()>),
 3749    _maintain_buffer_languages: Task<()>,
 3750    diagnostic_summaries:
 3751        HashMap<WorktreeId, HashMap<Arc<RelPath>, HashMap<LanguageServerId, DiagnosticSummary>>>,
 3752    pub lsp_server_capabilities: HashMap<LanguageServerId, lsp::ServerCapabilities>,
 3753    lsp_data: HashMap<BufferId, BufferLspData>,
 3754    next_hint_id: Arc<AtomicUsize>,
 3755}
 3756
 3757#[derive(Debug)]
 3758pub struct BufferLspData {
 3759    buffer_version: Global,
 3760    document_colors: Option<DocumentColorData>,
 3761    code_lens: Option<CodeLensData>,
 3762    inlay_hints: BufferInlayHints,
 3763    lsp_requests: HashMap<LspKey, HashMap<LspRequestId, Task<()>>>,
 3764    chunk_lsp_requests: HashMap<LspKey, HashMap<RowChunk, LspRequestId>>,
 3765}
 3766
 3767#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
 3768struct LspKey {
 3769    request_type: TypeId,
 3770    server_queried: Option<LanguageServerId>,
 3771}
 3772
 3773impl BufferLspData {
 3774    fn new(buffer: &Entity<Buffer>, cx: &mut App) -> Self {
 3775        Self {
 3776            buffer_version: buffer.read(cx).version(),
 3777            document_colors: None,
 3778            code_lens: None,
 3779            inlay_hints: BufferInlayHints::new(buffer, cx),
 3780            lsp_requests: HashMap::default(),
 3781            chunk_lsp_requests: HashMap::default(),
 3782        }
 3783    }
 3784
 3785    fn remove_server_data(&mut self, for_server: LanguageServerId) {
 3786        if let Some(document_colors) = &mut self.document_colors {
 3787            document_colors.colors.remove(&for_server);
 3788            document_colors.cache_version += 1;
 3789        }
 3790
 3791        if let Some(code_lens) = &mut self.code_lens {
 3792            code_lens.lens.remove(&for_server);
 3793        }
 3794
 3795        self.inlay_hints.remove_server_data(for_server);
 3796    }
 3797
 3798    #[cfg(any(test, feature = "test-support"))]
 3799    pub fn inlay_hints(&self) -> &BufferInlayHints {
 3800        &self.inlay_hints
 3801    }
 3802}
 3803
 3804#[derive(Debug, Default, Clone)]
 3805pub struct DocumentColors {
 3806    pub colors: HashSet<DocumentColor>,
 3807    pub cache_version: Option<usize>,
 3808}
 3809
 3810type DocumentColorTask = Shared<Task<std::result::Result<DocumentColors, Arc<anyhow::Error>>>>;
 3811type CodeLensTask = Shared<Task<std::result::Result<Option<Vec<CodeAction>>, Arc<anyhow::Error>>>>;
 3812
 3813#[derive(Debug, Default)]
 3814struct DocumentColorData {
 3815    colors: HashMap<LanguageServerId, HashSet<DocumentColor>>,
 3816    cache_version: usize,
 3817    colors_update: Option<(Global, DocumentColorTask)>,
 3818}
 3819
 3820#[derive(Debug, Default)]
 3821struct CodeLensData {
 3822    lens: HashMap<LanguageServerId, Vec<CodeAction>>,
 3823    update: Option<(Global, CodeLensTask)>,
 3824}
 3825
 3826#[derive(Debug)]
 3827pub enum LspStoreEvent {
 3828    LanguageServerAdded(LanguageServerId, LanguageServerName, Option<WorktreeId>),
 3829    LanguageServerRemoved(LanguageServerId),
 3830    LanguageServerUpdate {
 3831        language_server_id: LanguageServerId,
 3832        name: Option<LanguageServerName>,
 3833        message: proto::update_language_server::Variant,
 3834    },
 3835    LanguageServerLog(LanguageServerId, LanguageServerLogType, String),
 3836    LanguageServerPrompt(LanguageServerPromptRequest),
 3837    LanguageDetected {
 3838        buffer: Entity<Buffer>,
 3839        new_language: Option<Arc<Language>>,
 3840    },
 3841    Notification(String),
 3842    RefreshInlayHints {
 3843        server_id: LanguageServerId,
 3844        request_id: Option<usize>,
 3845    },
 3846    RefreshCodeLens,
 3847    DiagnosticsUpdated {
 3848        server_id: LanguageServerId,
 3849        paths: Vec<ProjectPath>,
 3850    },
 3851    DiskBasedDiagnosticsStarted {
 3852        language_server_id: LanguageServerId,
 3853    },
 3854    DiskBasedDiagnosticsFinished {
 3855        language_server_id: LanguageServerId,
 3856    },
 3857    SnippetEdit {
 3858        buffer_id: BufferId,
 3859        edits: Vec<(lsp::Range, Snippet)>,
 3860        most_recent_edit: clock::Lamport,
 3861    },
 3862    WorkspaceEditApplied(ProjectTransaction),
 3863}
 3864
 3865#[derive(Clone, Debug, Serialize)]
 3866pub struct LanguageServerStatus {
 3867    pub name: LanguageServerName,
 3868    pub server_version: Option<SharedString>,
 3869    pub pending_work: BTreeMap<ProgressToken, LanguageServerProgress>,
 3870    pub has_pending_diagnostic_updates: bool,
 3871    pub progress_tokens: HashSet<ProgressToken>,
 3872    pub worktree: Option<WorktreeId>,
 3873    pub binary: Option<LanguageServerBinary>,
 3874    pub configuration: Option<Value>,
 3875    pub workspace_folders: BTreeSet<Uri>,
 3876}
 3877
 3878#[derive(Clone, Debug)]
 3879struct CoreSymbol {
 3880    pub language_server_name: LanguageServerName,
 3881    pub source_worktree_id: WorktreeId,
 3882    pub source_language_server_id: LanguageServerId,
 3883    pub path: SymbolLocation,
 3884    pub name: String,
 3885    pub kind: lsp::SymbolKind,
 3886    pub range: Range<Unclipped<PointUtf16>>,
 3887}
 3888
 3889#[derive(Clone, Debug, PartialEq, Eq)]
 3890pub enum SymbolLocation {
 3891    InProject(ProjectPath),
 3892    OutsideProject {
 3893        abs_path: Arc<Path>,
 3894        signature: [u8; 32],
 3895    },
 3896}
 3897
 3898impl SymbolLocation {
 3899    fn file_name(&self) -> Option<&str> {
 3900        match self {
 3901            Self::InProject(path) => path.path.file_name(),
 3902            Self::OutsideProject { abs_path, .. } => abs_path.file_name()?.to_str(),
 3903        }
 3904    }
 3905}
 3906
 3907impl LspStore {
 3908    pub fn init(client: &AnyProtoClient) {
 3909        client.add_entity_request_handler(Self::handle_lsp_query);
 3910        client.add_entity_message_handler(Self::handle_lsp_query_response);
 3911        client.add_entity_request_handler(Self::handle_restart_language_servers);
 3912        client.add_entity_request_handler(Self::handle_stop_language_servers);
 3913        client.add_entity_request_handler(Self::handle_cancel_language_server_work);
 3914        client.add_entity_message_handler(Self::handle_start_language_server);
 3915        client.add_entity_message_handler(Self::handle_update_language_server);
 3916        client.add_entity_message_handler(Self::handle_language_server_log);
 3917        client.add_entity_message_handler(Self::handle_update_diagnostic_summary);
 3918        client.add_entity_request_handler(Self::handle_format_buffers);
 3919        client.add_entity_request_handler(Self::handle_apply_code_action_kind);
 3920        client.add_entity_request_handler(Self::handle_resolve_completion_documentation);
 3921        client.add_entity_request_handler(Self::handle_apply_code_action);
 3922        client.add_entity_request_handler(Self::handle_get_project_symbols);
 3923        client.add_entity_request_handler(Self::handle_resolve_inlay_hint);
 3924        client.add_entity_request_handler(Self::handle_get_color_presentation);
 3925        client.add_entity_request_handler(Self::handle_open_buffer_for_symbol);
 3926        client.add_entity_request_handler(Self::handle_refresh_inlay_hints);
 3927        client.add_entity_request_handler(Self::handle_refresh_code_lens);
 3928        client.add_entity_request_handler(Self::handle_on_type_formatting);
 3929        client.add_entity_request_handler(Self::handle_apply_additional_edits_for_completion);
 3930        client.add_entity_request_handler(Self::handle_register_buffer_with_language_servers);
 3931        client.add_entity_request_handler(Self::handle_rename_project_entry);
 3932        client.add_entity_request_handler(Self::handle_pull_workspace_diagnostics);
 3933        client.add_entity_request_handler(Self::handle_lsp_get_completions);
 3934        client.add_entity_request_handler(Self::handle_lsp_command::<GetDocumentHighlights>);
 3935        client.add_entity_request_handler(Self::handle_lsp_command::<GetDocumentSymbols>);
 3936        client.add_entity_request_handler(Self::handle_lsp_command::<PrepareRename>);
 3937        client.add_entity_request_handler(Self::handle_lsp_command::<PerformRename>);
 3938        client.add_entity_request_handler(Self::handle_lsp_command::<LinkedEditingRange>);
 3939
 3940        client.add_entity_request_handler(Self::handle_lsp_ext_cancel_flycheck);
 3941        client.add_entity_request_handler(Self::handle_lsp_ext_run_flycheck);
 3942        client.add_entity_request_handler(Self::handle_lsp_ext_clear_flycheck);
 3943        client.add_entity_request_handler(Self::handle_lsp_command::<lsp_ext_command::ExpandMacro>);
 3944        client.add_entity_request_handler(Self::handle_lsp_command::<lsp_ext_command::OpenDocs>);
 3945        client.add_entity_request_handler(
 3946            Self::handle_lsp_command::<lsp_ext_command::GoToParentModule>,
 3947        );
 3948        client.add_entity_request_handler(
 3949            Self::handle_lsp_command::<lsp_ext_command::GetLspRunnables>,
 3950        );
 3951        client.add_entity_request_handler(
 3952            Self::handle_lsp_command::<lsp_ext_command::SwitchSourceHeader>,
 3953        );
 3954    }
 3955
 3956    pub fn as_remote(&self) -> Option<&RemoteLspStore> {
 3957        match &self.mode {
 3958            LspStoreMode::Remote(remote_lsp_store) => Some(remote_lsp_store),
 3959            _ => None,
 3960        }
 3961    }
 3962
 3963    pub fn as_local(&self) -> Option<&LocalLspStore> {
 3964        match &self.mode {
 3965            LspStoreMode::Local(local_lsp_store) => Some(local_lsp_store),
 3966            _ => None,
 3967        }
 3968    }
 3969
 3970    pub fn as_local_mut(&mut self) -> Option<&mut LocalLspStore> {
 3971        match &mut self.mode {
 3972            LspStoreMode::Local(local_lsp_store) => Some(local_lsp_store),
 3973            _ => None,
 3974        }
 3975    }
 3976
 3977    pub fn upstream_client(&self) -> Option<(AnyProtoClient, u64)> {
 3978        match &self.mode {
 3979            LspStoreMode::Remote(RemoteLspStore {
 3980                upstream_client: Some(upstream_client),
 3981                upstream_project_id,
 3982                ..
 3983            }) => Some((upstream_client.clone(), *upstream_project_id)),
 3984
 3985            LspStoreMode::Remote(RemoteLspStore {
 3986                upstream_client: None,
 3987                ..
 3988            }) => None,
 3989            LspStoreMode::Local(_) => None,
 3990        }
 3991    }
 3992
 3993    pub fn new_local(
 3994        buffer_store: Entity<BufferStore>,
 3995        worktree_store: Entity<WorktreeStore>,
 3996        prettier_store: Entity<PrettierStore>,
 3997        toolchain_store: Entity<LocalToolchainStore>,
 3998        environment: Entity<ProjectEnvironment>,
 3999        manifest_tree: Entity<ManifestTree>,
 4000        languages: Arc<LanguageRegistry>,
 4001        http_client: Arc<dyn HttpClient>,
 4002        fs: Arc<dyn Fs>,
 4003        cx: &mut Context<Self>,
 4004    ) -> Self {
 4005        let yarn = YarnPathStore::new(fs.clone(), cx);
 4006        cx.subscribe(&buffer_store, Self::on_buffer_store_event)
 4007            .detach();
 4008        cx.subscribe(&worktree_store, Self::on_worktree_store_event)
 4009            .detach();
 4010        cx.subscribe(&prettier_store, Self::on_prettier_store_event)
 4011            .detach();
 4012        cx.subscribe(&toolchain_store, Self::on_toolchain_store_event)
 4013            .detach();
 4014        cx.observe_global::<SettingsStore>(Self::on_settings_changed)
 4015            .detach();
 4016        subscribe_to_binary_statuses(&languages, cx).detach();
 4017
 4018        let _maintain_workspace_config = {
 4019            let (sender, receiver) = watch::channel();
 4020            (Self::maintain_workspace_config(receiver, cx), sender)
 4021        };
 4022
 4023        Self {
 4024            mode: LspStoreMode::Local(LocalLspStore {
 4025                weak: cx.weak_entity(),
 4026                worktree_store: worktree_store.clone(),
 4027
 4028                supplementary_language_servers: Default::default(),
 4029                languages: languages.clone(),
 4030                language_server_ids: Default::default(),
 4031                language_servers: Default::default(),
 4032                last_workspace_edits_by_language_server: Default::default(),
 4033                language_server_watched_paths: Default::default(),
 4034                language_server_paths_watched_for_rename: Default::default(),
 4035                language_server_dynamic_registrations: Default::default(),
 4036                buffers_being_formatted: Default::default(),
 4037                buffer_snapshots: Default::default(),
 4038                prettier_store,
 4039                environment,
 4040                http_client,
 4041                fs,
 4042                yarn,
 4043                next_diagnostic_group_id: Default::default(),
 4044                diagnostics: Default::default(),
 4045                _subscription: cx.on_app_quit(|this, cx| {
 4046                    this.as_local_mut()
 4047                        .unwrap()
 4048                        .shutdown_language_servers_on_quit(cx)
 4049                }),
 4050                lsp_tree: LanguageServerTree::new(
 4051                    manifest_tree,
 4052                    languages.clone(),
 4053                    toolchain_store.clone(),
 4054                ),
 4055                toolchain_store,
 4056                registered_buffers: HashMap::default(),
 4057                buffers_opened_in_servers: HashMap::default(),
 4058                buffer_pull_diagnostics_result_ids: HashMap::default(),
 4059                workspace_pull_diagnostics_result_ids: HashMap::default(),
 4060                restricted_worktrees_tasks: HashMap::default(),
 4061                watched_manifest_filenames: ManifestProvidersStore::global(cx)
 4062                    .manifest_file_names(),
 4063            }),
 4064            last_formatting_failure: None,
 4065            downstream_client: None,
 4066            buffer_store,
 4067            worktree_store,
 4068            languages: languages.clone(),
 4069            language_server_statuses: Default::default(),
 4070            nonce: StdRng::from_os_rng().random(),
 4071            diagnostic_summaries: HashMap::default(),
 4072            lsp_server_capabilities: HashMap::default(),
 4073            lsp_data: HashMap::default(),
 4074            next_hint_id: Arc::default(),
 4075            active_entry: None,
 4076            _maintain_workspace_config,
 4077            _maintain_buffer_languages: Self::maintain_buffer_languages(languages, cx),
 4078        }
 4079    }
 4080
 4081    fn send_lsp_proto_request<R: LspCommand>(
 4082        &self,
 4083        buffer: Entity<Buffer>,
 4084        client: AnyProtoClient,
 4085        upstream_project_id: u64,
 4086        request: R,
 4087        cx: &mut Context<LspStore>,
 4088    ) -> Task<anyhow::Result<<R as LspCommand>::Response>> {
 4089        if !self.is_capable_for_proto_request(&buffer, &request, cx) {
 4090            return Task::ready(Ok(R::Response::default()));
 4091        }
 4092        let message = request.to_proto(upstream_project_id, buffer.read(cx));
 4093        cx.spawn(async move |this, cx| {
 4094            let response = client.request(message).await?;
 4095            let this = this.upgrade().context("project dropped")?;
 4096            request
 4097                .response_from_proto(response, this, buffer, cx.clone())
 4098                .await
 4099        })
 4100    }
 4101
 4102    pub(super) fn new_remote(
 4103        buffer_store: Entity<BufferStore>,
 4104        worktree_store: Entity<WorktreeStore>,
 4105        languages: Arc<LanguageRegistry>,
 4106        upstream_client: AnyProtoClient,
 4107        project_id: u64,
 4108        cx: &mut Context<Self>,
 4109    ) -> Self {
 4110        cx.subscribe(&buffer_store, Self::on_buffer_store_event)
 4111            .detach();
 4112        cx.subscribe(&worktree_store, Self::on_worktree_store_event)
 4113            .detach();
 4114        subscribe_to_binary_statuses(&languages, cx).detach();
 4115        let _maintain_workspace_config = {
 4116            let (sender, receiver) = watch::channel();
 4117            (Self::maintain_workspace_config(receiver, cx), sender)
 4118        };
 4119        Self {
 4120            mode: LspStoreMode::Remote(RemoteLspStore {
 4121                upstream_client: Some(upstream_client),
 4122                upstream_project_id: project_id,
 4123            }),
 4124            downstream_client: None,
 4125            last_formatting_failure: None,
 4126            buffer_store,
 4127            worktree_store,
 4128            languages: languages.clone(),
 4129            language_server_statuses: Default::default(),
 4130            nonce: StdRng::from_os_rng().random(),
 4131            diagnostic_summaries: HashMap::default(),
 4132            lsp_server_capabilities: HashMap::default(),
 4133            next_hint_id: Arc::default(),
 4134            lsp_data: HashMap::default(),
 4135            active_entry: None,
 4136
 4137            _maintain_workspace_config,
 4138            _maintain_buffer_languages: Self::maintain_buffer_languages(languages.clone(), cx),
 4139        }
 4140    }
 4141
 4142    fn on_buffer_store_event(
 4143        &mut self,
 4144        _: Entity<BufferStore>,
 4145        event: &BufferStoreEvent,
 4146        cx: &mut Context<Self>,
 4147    ) {
 4148        match event {
 4149            BufferStoreEvent::BufferAdded(buffer) => {
 4150                self.on_buffer_added(buffer, cx).log_err();
 4151            }
 4152            BufferStoreEvent::BufferChangedFilePath { buffer, old_file } => {
 4153                let buffer_id = buffer.read(cx).remote_id();
 4154                if let Some(local) = self.as_local_mut()
 4155                    && let Some(old_file) = File::from_dyn(old_file.as_ref())
 4156                {
 4157                    local.reset_buffer(buffer, old_file, cx);
 4158
 4159                    if local.registered_buffers.contains_key(&buffer_id) {
 4160                        local.unregister_old_buffer_from_language_servers(buffer, old_file, cx);
 4161                    }
 4162                }
 4163
 4164                self.detect_language_for_buffer(buffer, cx);
 4165                if let Some(local) = self.as_local_mut() {
 4166                    local.initialize_buffer(buffer, cx);
 4167                    if local.registered_buffers.contains_key(&buffer_id) {
 4168                        local.register_buffer_with_language_servers(buffer, HashSet::default(), cx);
 4169                    }
 4170                }
 4171            }
 4172            _ => {}
 4173        }
 4174    }
 4175
 4176    fn on_worktree_store_event(
 4177        &mut self,
 4178        _: Entity<WorktreeStore>,
 4179        event: &WorktreeStoreEvent,
 4180        cx: &mut Context<Self>,
 4181    ) {
 4182        match event {
 4183            WorktreeStoreEvent::WorktreeAdded(worktree) => {
 4184                if !worktree.read(cx).is_local() {
 4185                    return;
 4186                }
 4187                cx.subscribe(worktree, |this, worktree, event, cx| match event {
 4188                    worktree::Event::UpdatedEntries(changes) => {
 4189                        this.update_local_worktree_language_servers(&worktree, changes, cx);
 4190                    }
 4191                    worktree::Event::UpdatedGitRepositories(_)
 4192                    | worktree::Event::DeletedEntry(_) => {}
 4193                })
 4194                .detach()
 4195            }
 4196            WorktreeStoreEvent::WorktreeRemoved(_, id) => self.remove_worktree(*id, cx),
 4197            WorktreeStoreEvent::WorktreeUpdateSent(worktree) => {
 4198                worktree.update(cx, |worktree, _cx| self.send_diagnostic_summaries(worktree));
 4199            }
 4200            WorktreeStoreEvent::WorktreeReleased(..)
 4201            | WorktreeStoreEvent::WorktreeOrderChanged
 4202            | WorktreeStoreEvent::WorktreeUpdatedEntries(..)
 4203            | WorktreeStoreEvent::WorktreeUpdatedGitRepositories(..)
 4204            | WorktreeStoreEvent::WorktreeDeletedEntry(..) => {}
 4205        }
 4206    }
 4207
 4208    fn on_prettier_store_event(
 4209        &mut self,
 4210        _: Entity<PrettierStore>,
 4211        event: &PrettierStoreEvent,
 4212        cx: &mut Context<Self>,
 4213    ) {
 4214        match event {
 4215            PrettierStoreEvent::LanguageServerRemoved(prettier_server_id) => {
 4216                self.unregister_supplementary_language_server(*prettier_server_id, cx);
 4217            }
 4218            PrettierStoreEvent::LanguageServerAdded {
 4219                new_server_id,
 4220                name,
 4221                prettier_server,
 4222            } => {
 4223                self.register_supplementary_language_server(
 4224                    *new_server_id,
 4225                    name.clone(),
 4226                    prettier_server.clone(),
 4227                    cx,
 4228                );
 4229            }
 4230        }
 4231    }
 4232
 4233    fn on_toolchain_store_event(
 4234        &mut self,
 4235        _: Entity<LocalToolchainStore>,
 4236        event: &ToolchainStoreEvent,
 4237        _: &mut Context<Self>,
 4238    ) {
 4239        if let ToolchainStoreEvent::ToolchainActivated = event {
 4240            self.request_workspace_config_refresh()
 4241        }
 4242    }
 4243
 4244    fn request_workspace_config_refresh(&mut self) {
 4245        *self._maintain_workspace_config.1.borrow_mut() = ();
 4246    }
 4247
 4248    pub fn prettier_store(&self) -> Option<Entity<PrettierStore>> {
 4249        self.as_local().map(|local| local.prettier_store.clone())
 4250    }
 4251
 4252    fn on_buffer_event(
 4253        &mut self,
 4254        buffer: Entity<Buffer>,
 4255        event: &language::BufferEvent,
 4256        cx: &mut Context<Self>,
 4257    ) {
 4258        match event {
 4259            language::BufferEvent::Edited => {
 4260                self.on_buffer_edited(buffer, cx);
 4261            }
 4262
 4263            language::BufferEvent::Saved => {
 4264                self.on_buffer_saved(buffer, cx);
 4265            }
 4266
 4267            _ => {}
 4268        }
 4269    }
 4270
 4271    fn on_buffer_added(&mut self, buffer: &Entity<Buffer>, cx: &mut Context<Self>) -> Result<()> {
 4272        buffer
 4273            .read(cx)
 4274            .set_language_registry(self.languages.clone());
 4275
 4276        cx.subscribe(buffer, |this, buffer, event, cx| {
 4277            this.on_buffer_event(buffer, event, cx);
 4278        })
 4279        .detach();
 4280
 4281        self.detect_language_for_buffer(buffer, cx);
 4282        if let Some(local) = self.as_local_mut() {
 4283            local.initialize_buffer(buffer, cx);
 4284        }
 4285
 4286        Ok(())
 4287    }
 4288
 4289    pub(crate) fn register_buffer_with_language_servers(
 4290        &mut self,
 4291        buffer: &Entity<Buffer>,
 4292        only_register_servers: HashSet<LanguageServerSelector>,
 4293        ignore_refcounts: bool,
 4294        cx: &mut Context<Self>,
 4295    ) -> OpenLspBufferHandle {
 4296        let buffer_id = buffer.read(cx).remote_id();
 4297        let handle = OpenLspBufferHandle(cx.new(|_| OpenLspBuffer(buffer.clone())));
 4298        if let Some(local) = self.as_local_mut() {
 4299            let refcount = local.registered_buffers.entry(buffer_id).or_insert(0);
 4300            if !ignore_refcounts {
 4301                *refcount += 1;
 4302            }
 4303
 4304            // We run early exits on non-existing buffers AFTER we mark the buffer as registered in order to handle buffer saving.
 4305            // 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
 4306            // 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
 4307            // servers in practice (we don't support non-file URI schemes in our LSP impl).
 4308            let Some(file) = File::from_dyn(buffer.read(cx).file()) else {
 4309                return handle;
 4310            };
 4311            if !file.is_local() {
 4312                return handle;
 4313            }
 4314
 4315            if ignore_refcounts || *refcount == 1 {
 4316                local.register_buffer_with_language_servers(buffer, only_register_servers, cx);
 4317            }
 4318            if !ignore_refcounts {
 4319                cx.observe_release(&handle.0, move |lsp_store, buffer, cx| {
 4320                    let refcount = {
 4321                        let local = lsp_store.as_local_mut().unwrap();
 4322                        let Some(refcount) = local.registered_buffers.get_mut(&buffer_id) else {
 4323                            debug_panic!("bad refcounting");
 4324                            return;
 4325                        };
 4326
 4327                        *refcount -= 1;
 4328                        *refcount
 4329                    };
 4330                    if refcount == 0 {
 4331                        lsp_store.lsp_data.remove(&buffer_id);
 4332                        let local = lsp_store.as_local_mut().unwrap();
 4333                        local.registered_buffers.remove(&buffer_id);
 4334
 4335                        local.buffers_opened_in_servers.remove(&buffer_id);
 4336                        if let Some(file) = File::from_dyn(buffer.0.read(cx).file()).cloned() {
 4337                            local.unregister_old_buffer_from_language_servers(&buffer.0, &file, cx);
 4338
 4339                            let buffer_abs_path = file.abs_path(cx);
 4340                            for (_, buffer_pull_diagnostics_result_ids) in
 4341                                &mut local.buffer_pull_diagnostics_result_ids
 4342                            {
 4343                                buffer_pull_diagnostics_result_ids.retain(
 4344                                    |_, buffer_result_ids| {
 4345                                        buffer_result_ids.remove(&buffer_abs_path);
 4346                                        !buffer_result_ids.is_empty()
 4347                                    },
 4348                                );
 4349                            }
 4350
 4351                            let diagnostic_updates = local
 4352                                .language_servers
 4353                                .keys()
 4354                                .cloned()
 4355                                .map(|server_id| DocumentDiagnosticsUpdate {
 4356                                    diagnostics: DocumentDiagnostics {
 4357                                        document_abs_path: buffer_abs_path.clone(),
 4358                                        version: None,
 4359                                        diagnostics: Vec::new(),
 4360                                    },
 4361                                    result_id: None,
 4362                                    registration_id: None,
 4363                                    server_id: server_id,
 4364                                    disk_based_sources: Cow::Borrowed(&[]),
 4365                                })
 4366                                .collect::<Vec<_>>();
 4367
 4368                            lsp_store
 4369                                .merge_diagnostic_entries(
 4370                                    diagnostic_updates,
 4371                                    |_, diagnostic, _| {
 4372                                        diagnostic.source_kind != DiagnosticSourceKind::Pulled
 4373                                    },
 4374                                    cx,
 4375                                )
 4376                                .context("Clearing diagnostics for the closed buffer")
 4377                                .log_err();
 4378                        }
 4379                    }
 4380                })
 4381                .detach();
 4382            }
 4383        } else if let Some((upstream_client, upstream_project_id)) = self.upstream_client() {
 4384            let buffer_id = buffer.read(cx).remote_id().to_proto();
 4385            cx.background_spawn(async move {
 4386                upstream_client
 4387                    .request(proto::RegisterBufferWithLanguageServers {
 4388                        project_id: upstream_project_id,
 4389                        buffer_id,
 4390                        only_servers: only_register_servers
 4391                            .into_iter()
 4392                            .map(|selector| {
 4393                                let selector = match selector {
 4394                                    LanguageServerSelector::Id(language_server_id) => {
 4395                                        proto::language_server_selector::Selector::ServerId(
 4396                                            language_server_id.to_proto(),
 4397                                        )
 4398                                    }
 4399                                    LanguageServerSelector::Name(language_server_name) => {
 4400                                        proto::language_server_selector::Selector::Name(
 4401                                            language_server_name.to_string(),
 4402                                        )
 4403                                    }
 4404                                };
 4405                                proto::LanguageServerSelector {
 4406                                    selector: Some(selector),
 4407                                }
 4408                            })
 4409                            .collect(),
 4410                    })
 4411                    .await
 4412            })
 4413            .detach();
 4414        } else {
 4415            // Our remote connection got closed
 4416        }
 4417        handle
 4418    }
 4419
 4420    fn maintain_buffer_languages(
 4421        languages: Arc<LanguageRegistry>,
 4422        cx: &mut Context<Self>,
 4423    ) -> Task<()> {
 4424        let mut subscription = languages.subscribe();
 4425        let mut prev_reload_count = languages.reload_count();
 4426        cx.spawn(async move |this, cx| {
 4427            while let Some(()) = subscription.next().await {
 4428                if let Some(this) = this.upgrade() {
 4429                    // If the language registry has been reloaded, then remove and
 4430                    // re-assign the languages on all open buffers.
 4431                    let reload_count = languages.reload_count();
 4432                    if reload_count > prev_reload_count {
 4433                        prev_reload_count = reload_count;
 4434                        this.update(cx, |this, cx| {
 4435                            this.buffer_store.clone().update(cx, |buffer_store, cx| {
 4436                                for buffer in buffer_store.buffers() {
 4437                                    if let Some(f) = File::from_dyn(buffer.read(cx).file()).cloned()
 4438                                    {
 4439                                        buffer.update(cx, |buffer, cx| {
 4440                                            buffer.set_language_async(None, cx)
 4441                                        });
 4442                                        if let Some(local) = this.as_local_mut() {
 4443                                            local.reset_buffer(&buffer, &f, cx);
 4444
 4445                                            if local
 4446                                                .registered_buffers
 4447                                                .contains_key(&buffer.read(cx).remote_id())
 4448                                                && let Some(file_url) =
 4449                                                    file_path_to_lsp_url(&f.abs_path(cx)).log_err()
 4450                                            {
 4451                                                local.unregister_buffer_from_language_servers(
 4452                                                    &buffer, &file_url, cx,
 4453                                                );
 4454                                            }
 4455                                        }
 4456                                    }
 4457                                }
 4458                            });
 4459                        })
 4460                        .ok();
 4461                    }
 4462
 4463                    this.update(cx, |this, cx| {
 4464                        let mut plain_text_buffers = Vec::new();
 4465                        let mut buffers_with_unknown_injections = Vec::new();
 4466                        for handle in this.buffer_store.read(cx).buffers() {
 4467                            let buffer = handle.read(cx);
 4468                            if buffer.language().is_none()
 4469                                || buffer.language() == Some(&*language::PLAIN_TEXT)
 4470                            {
 4471                                plain_text_buffers.push(handle);
 4472                            } else if buffer.contains_unknown_injections() {
 4473                                buffers_with_unknown_injections.push(handle);
 4474                            }
 4475                        }
 4476
 4477                        // Deprioritize the invisible worktrees so main worktrees' language servers can be started first,
 4478                        // and reused later in the invisible worktrees.
 4479                        plain_text_buffers.sort_by_key(|buffer| {
 4480                            Reverse(
 4481                                File::from_dyn(buffer.read(cx).file())
 4482                                    .map(|file| file.worktree.read(cx).is_visible()),
 4483                            )
 4484                        });
 4485
 4486                        for buffer in plain_text_buffers {
 4487                            this.detect_language_for_buffer(&buffer, cx);
 4488                            if let Some(local) = this.as_local_mut() {
 4489                                local.initialize_buffer(&buffer, cx);
 4490                                if local
 4491                                    .registered_buffers
 4492                                    .contains_key(&buffer.read(cx).remote_id())
 4493                                {
 4494                                    local.register_buffer_with_language_servers(
 4495                                        &buffer,
 4496                                        HashSet::default(),
 4497                                        cx,
 4498                                    );
 4499                                }
 4500                            }
 4501                        }
 4502
 4503                        for buffer in buffers_with_unknown_injections {
 4504                            buffer.update(cx, |buffer, cx| buffer.reparse(cx, false));
 4505                        }
 4506                    })
 4507                    .ok();
 4508                }
 4509            }
 4510        })
 4511    }
 4512
 4513    fn detect_language_for_buffer(
 4514        &mut self,
 4515        buffer_handle: &Entity<Buffer>,
 4516        cx: &mut Context<Self>,
 4517    ) -> Option<language::AvailableLanguage> {
 4518        // If the buffer has a language, set it and start the language server if we haven't already.
 4519        let buffer = buffer_handle.read(cx);
 4520        let file = buffer.file()?;
 4521
 4522        let content = buffer.as_rope();
 4523        let available_language = self.languages.language_for_file(file, Some(content), cx);
 4524        if let Some(available_language) = &available_language {
 4525            if let Some(Ok(Ok(new_language))) = self
 4526                .languages
 4527                .load_language(available_language)
 4528                .now_or_never()
 4529            {
 4530                self.set_language_for_buffer(buffer_handle, new_language, cx);
 4531            }
 4532        } else {
 4533            cx.emit(LspStoreEvent::LanguageDetected {
 4534                buffer: buffer_handle.clone(),
 4535                new_language: None,
 4536            });
 4537        }
 4538
 4539        available_language
 4540    }
 4541
 4542    pub(crate) fn set_language_for_buffer(
 4543        &mut self,
 4544        buffer_entity: &Entity<Buffer>,
 4545        new_language: Arc<Language>,
 4546        cx: &mut Context<Self>,
 4547    ) {
 4548        let buffer = buffer_entity.read(cx);
 4549        let buffer_file = buffer.file().cloned();
 4550        let buffer_id = buffer.remote_id();
 4551        if let Some(local_store) = self.as_local_mut()
 4552            && local_store.registered_buffers.contains_key(&buffer_id)
 4553            && let Some(abs_path) =
 4554                File::from_dyn(buffer_file.as_ref()).map(|file| file.abs_path(cx))
 4555            && let Some(file_url) = file_path_to_lsp_url(&abs_path).log_err()
 4556        {
 4557            local_store.unregister_buffer_from_language_servers(buffer_entity, &file_url, cx);
 4558        }
 4559        buffer_entity.update(cx, |buffer, cx| {
 4560            if buffer
 4561                .language()
 4562                .is_none_or(|old_language| !Arc::ptr_eq(old_language, &new_language))
 4563            {
 4564                buffer.set_language_async(Some(new_language.clone()), cx);
 4565            }
 4566        });
 4567
 4568        let settings =
 4569            language_settings(Some(new_language.name()), buffer_file.as_ref(), cx).into_owned();
 4570        let buffer_file = File::from_dyn(buffer_file.as_ref());
 4571
 4572        let worktree_id = if let Some(file) = buffer_file {
 4573            let worktree = file.worktree.clone();
 4574
 4575            if let Some(local) = self.as_local_mut()
 4576                && local.registered_buffers.contains_key(&buffer_id)
 4577            {
 4578                local.register_buffer_with_language_servers(buffer_entity, HashSet::default(), cx);
 4579            }
 4580            Some(worktree.read(cx).id())
 4581        } else {
 4582            None
 4583        };
 4584
 4585        if settings.prettier.allowed
 4586            && let Some(prettier_plugins) = prettier_store::prettier_plugins_for_language(&settings)
 4587        {
 4588            let prettier_store = self.as_local().map(|s| s.prettier_store.clone());
 4589            if let Some(prettier_store) = prettier_store {
 4590                prettier_store.update(cx, |prettier_store, cx| {
 4591                    prettier_store.install_default_prettier(
 4592                        worktree_id,
 4593                        prettier_plugins.iter().map(|s| Arc::from(s.as_str())),
 4594                        cx,
 4595                    )
 4596                })
 4597            }
 4598        }
 4599
 4600        cx.emit(LspStoreEvent::LanguageDetected {
 4601            buffer: buffer_entity.clone(),
 4602            new_language: Some(new_language),
 4603        })
 4604    }
 4605
 4606    pub fn buffer_store(&self) -> Entity<BufferStore> {
 4607        self.buffer_store.clone()
 4608    }
 4609
 4610    pub fn set_active_entry(&mut self, active_entry: Option<ProjectEntryId>) {
 4611        self.active_entry = active_entry;
 4612    }
 4613
 4614    pub(crate) fn send_diagnostic_summaries(&self, worktree: &mut Worktree) {
 4615        if let Some((client, downstream_project_id)) = self.downstream_client.clone()
 4616            && let Some(diangostic_summaries) = self.diagnostic_summaries.get(&worktree.id())
 4617        {
 4618            let mut summaries = diangostic_summaries.iter().flat_map(|(path, summaries)| {
 4619                summaries
 4620                    .iter()
 4621                    .map(|(server_id, summary)| summary.to_proto(*server_id, path.as_ref()))
 4622            });
 4623            if let Some(summary) = summaries.next() {
 4624                client
 4625                    .send(proto::UpdateDiagnosticSummary {
 4626                        project_id: downstream_project_id,
 4627                        worktree_id: worktree.id().to_proto(),
 4628                        summary: Some(summary),
 4629                        more_summaries: summaries.collect(),
 4630                    })
 4631                    .log_err();
 4632            }
 4633        }
 4634    }
 4635
 4636    fn is_capable_for_proto_request<R>(
 4637        &self,
 4638        buffer: &Entity<Buffer>,
 4639        request: &R,
 4640        cx: &App,
 4641    ) -> bool
 4642    where
 4643        R: LspCommand,
 4644    {
 4645        self.check_if_capable_for_proto_request(
 4646            buffer,
 4647            |capabilities| {
 4648                request.check_capabilities(AdapterServerCapabilities {
 4649                    server_capabilities: capabilities.clone(),
 4650                    code_action_kinds: None,
 4651                })
 4652            },
 4653            cx,
 4654        )
 4655    }
 4656
 4657    fn check_if_capable_for_proto_request<F>(
 4658        &self,
 4659        buffer: &Entity<Buffer>,
 4660        check: F,
 4661        cx: &App,
 4662    ) -> bool
 4663    where
 4664        F: FnMut(&lsp::ServerCapabilities) -> bool,
 4665    {
 4666        let Some(language) = buffer.read(cx).language().cloned() else {
 4667            return false;
 4668        };
 4669        let registered_language_servers = self
 4670            .languages
 4671            .lsp_adapters(&language.name())
 4672            .into_iter()
 4673            .map(|lsp_adapter| lsp_adapter.name())
 4674            .collect::<HashSet<_>>();
 4675        self.language_server_statuses
 4676            .iter()
 4677            .filter_map(|(server_id, server_status)| {
 4678                // Include servers that are either registered for this language OR
 4679                // available to be loaded (for SSH remote mode where adapters like
 4680                // ty/pylsp/pyright are registered via register_available_lsp_adapter
 4681                // but only loaded on the server side)
 4682                let is_relevant = registered_language_servers.contains(&server_status.name)
 4683                    || self.languages.is_lsp_adapter_available(&server_status.name);
 4684                is_relevant.then_some(server_id)
 4685            })
 4686            .filter_map(|server_id| self.lsp_server_capabilities.get(server_id))
 4687            .any(check)
 4688    }
 4689
 4690    fn all_capable_for_proto_request<F>(
 4691        &self,
 4692        buffer: &Entity<Buffer>,
 4693        mut check: F,
 4694        cx: &App,
 4695    ) -> Vec<lsp::LanguageServerId>
 4696    where
 4697        F: FnMut(&lsp::LanguageServerName, &lsp::ServerCapabilities) -> bool,
 4698    {
 4699        let Some(language) = buffer.read(cx).language().cloned() else {
 4700            return Vec::default();
 4701        };
 4702        let registered_language_servers = self
 4703            .languages
 4704            .lsp_adapters(&language.name())
 4705            .into_iter()
 4706            .map(|lsp_adapter| lsp_adapter.name())
 4707            .collect::<HashSet<_>>();
 4708        self.language_server_statuses
 4709            .iter()
 4710            .filter_map(|(server_id, server_status)| {
 4711                // Include servers that are either registered for this language OR
 4712                // available to be loaded (for SSH remote mode where adapters like
 4713                // ty/pylsp/pyright are registered via register_available_lsp_adapter
 4714                // but only loaded on the server side)
 4715                let is_relevant = registered_language_servers.contains(&server_status.name)
 4716                    || self.languages.is_lsp_adapter_available(&server_status.name);
 4717                is_relevant.then_some((server_id, &server_status.name))
 4718            })
 4719            .filter_map(|(server_id, server_name)| {
 4720                self.lsp_server_capabilities
 4721                    .get(server_id)
 4722                    .map(|c| (server_id, server_name, c))
 4723            })
 4724            .filter(|(_, server_name, capabilities)| check(server_name, capabilities))
 4725            .map(|(server_id, _, _)| *server_id)
 4726            .collect()
 4727    }
 4728
 4729    pub fn request_lsp<R>(
 4730        &mut self,
 4731        buffer: Entity<Buffer>,
 4732        server: LanguageServerToQuery,
 4733        request: R,
 4734        cx: &mut Context<Self>,
 4735    ) -> Task<Result<R::Response>>
 4736    where
 4737        R: LspCommand,
 4738        <R::LspRequest as lsp::request::Request>::Result: Send,
 4739        <R::LspRequest as lsp::request::Request>::Params: Send,
 4740    {
 4741        if let Some((upstream_client, upstream_project_id)) = self.upstream_client() {
 4742            return self.send_lsp_proto_request(
 4743                buffer,
 4744                upstream_client,
 4745                upstream_project_id,
 4746                request,
 4747                cx,
 4748            );
 4749        }
 4750
 4751        let Some(language_server) = buffer.update(cx, |buffer, cx| match server {
 4752            LanguageServerToQuery::FirstCapable => self.as_local().and_then(|local| {
 4753                local
 4754                    .language_servers_for_buffer(buffer, cx)
 4755                    .find(|(_, server)| {
 4756                        request.check_capabilities(server.adapter_server_capabilities())
 4757                    })
 4758                    .map(|(_, server)| server.clone())
 4759            }),
 4760            LanguageServerToQuery::Other(id) => self
 4761                .language_server_for_local_buffer(buffer, id, cx)
 4762                .and_then(|(_, server)| {
 4763                    request
 4764                        .check_capabilities(server.adapter_server_capabilities())
 4765                        .then(|| Arc::clone(server))
 4766                }),
 4767        }) else {
 4768            return Task::ready(Ok(Default::default()));
 4769        };
 4770
 4771        let file = File::from_dyn(buffer.read(cx).file()).and_then(File::as_local);
 4772
 4773        let Some(file) = file else {
 4774            return Task::ready(Ok(Default::default()));
 4775        };
 4776
 4777        let lsp_params = match request.to_lsp_params_or_response(
 4778            &file.abs_path(cx),
 4779            buffer.read(cx),
 4780            &language_server,
 4781            cx,
 4782        ) {
 4783            Ok(LspParamsOrResponse::Params(lsp_params)) => lsp_params,
 4784            Ok(LspParamsOrResponse::Response(response)) => return Task::ready(Ok(response)),
 4785            Err(err) => {
 4786                let message = format!(
 4787                    "{} via {} failed: {}",
 4788                    request.display_name(),
 4789                    language_server.name(),
 4790                    err
 4791                );
 4792                // rust-analyzer likes to error with this when its still loading up
 4793                if !message.ends_with("content modified") {
 4794                    log::warn!("{message}");
 4795                }
 4796                return Task::ready(Err(anyhow!(message)));
 4797            }
 4798        };
 4799
 4800        let status = request.status();
 4801        if !request.check_capabilities(language_server.adapter_server_capabilities()) {
 4802            return Task::ready(Ok(Default::default()));
 4803        }
 4804        cx.spawn(async move |this, cx| {
 4805            let lsp_request = language_server.request::<R::LspRequest>(lsp_params);
 4806
 4807            let id = lsp_request.id();
 4808            let _cleanup = if status.is_some() {
 4809                cx.update(|cx| {
 4810                    this.update(cx, |this, cx| {
 4811                        this.on_lsp_work_start(
 4812                            language_server.server_id(),
 4813                            ProgressToken::Number(id),
 4814                            LanguageServerProgress {
 4815                                is_disk_based_diagnostics_progress: false,
 4816                                is_cancellable: false,
 4817                                title: None,
 4818                                message: status.clone(),
 4819                                percentage: None,
 4820                                last_update_at: cx.background_executor().now(),
 4821                            },
 4822                            cx,
 4823                        );
 4824                    })
 4825                })
 4826                .log_err();
 4827
 4828                Some(defer(|| {
 4829                    cx.update(|cx| {
 4830                        this.update(cx, |this, cx| {
 4831                            this.on_lsp_work_end(
 4832                                language_server.server_id(),
 4833                                ProgressToken::Number(id),
 4834                                cx,
 4835                            );
 4836                        })
 4837                    })
 4838                    .log_err();
 4839                }))
 4840            } else {
 4841                None
 4842            };
 4843
 4844            let result = lsp_request.await.into_response();
 4845
 4846            let response = result.map_err(|err| {
 4847                let message = format!(
 4848                    "{} via {} failed: {}",
 4849                    request.display_name(),
 4850                    language_server.name(),
 4851                    err
 4852                );
 4853                // rust-analyzer likes to error with this when its still loading up
 4854                if !message.ends_with("content modified") {
 4855                    log::warn!("{message}");
 4856                }
 4857                anyhow::anyhow!(message)
 4858            })?;
 4859
 4860            request
 4861                .response_from_lsp(
 4862                    response,
 4863                    this.upgrade().context("no app context")?,
 4864                    buffer,
 4865                    language_server.server_id(),
 4866                    cx.clone(),
 4867                )
 4868                .await
 4869        })
 4870    }
 4871
 4872    fn on_settings_changed(&mut self, cx: &mut Context<Self>) {
 4873        let mut language_formatters_to_check = Vec::new();
 4874        for buffer in self.buffer_store.read(cx).buffers() {
 4875            let buffer = buffer.read(cx);
 4876            let buffer_file = File::from_dyn(buffer.file());
 4877            let buffer_language = buffer.language();
 4878            let settings = language_settings(buffer_language.map(|l| l.name()), buffer.file(), cx);
 4879            if buffer_language.is_some() {
 4880                language_formatters_to_check.push((
 4881                    buffer_file.map(|f| f.worktree_id(cx)),
 4882                    settings.into_owned(),
 4883                ));
 4884            }
 4885        }
 4886
 4887        self.request_workspace_config_refresh();
 4888
 4889        if let Some(prettier_store) = self.as_local().map(|s| s.prettier_store.clone()) {
 4890            prettier_store.update(cx, |prettier_store, cx| {
 4891                prettier_store.on_settings_changed(language_formatters_to_check, cx)
 4892            })
 4893        }
 4894
 4895        cx.notify();
 4896    }
 4897
 4898    fn refresh_server_tree(&mut self, cx: &mut Context<Self>) {
 4899        let buffer_store = self.buffer_store.clone();
 4900        let Some(local) = self.as_local_mut() else {
 4901            return;
 4902        };
 4903        let mut adapters = BTreeMap::default();
 4904        let get_adapter = {
 4905            let languages = local.languages.clone();
 4906            let environment = local.environment.clone();
 4907            let weak = local.weak.clone();
 4908            let worktree_store = local.worktree_store.clone();
 4909            let http_client = local.http_client.clone();
 4910            let fs = local.fs.clone();
 4911            move |worktree_id, cx: &mut App| {
 4912                let worktree = worktree_store.read(cx).worktree_for_id(worktree_id, cx)?;
 4913                Some(LocalLspAdapterDelegate::new(
 4914                    languages.clone(),
 4915                    &environment,
 4916                    weak.clone(),
 4917                    &worktree,
 4918                    http_client.clone(),
 4919                    fs.clone(),
 4920                    cx,
 4921                ))
 4922            }
 4923        };
 4924
 4925        let mut messages_to_report = Vec::new();
 4926        let (new_tree, to_stop) = {
 4927            let mut rebase = local.lsp_tree.rebase();
 4928            let buffers = buffer_store
 4929                .read(cx)
 4930                .buffers()
 4931                .filter_map(|buffer| {
 4932                    let raw_buffer = buffer.read(cx);
 4933                    if !local
 4934                        .registered_buffers
 4935                        .contains_key(&raw_buffer.remote_id())
 4936                    {
 4937                        return None;
 4938                    }
 4939                    let file = File::from_dyn(raw_buffer.file()).cloned()?;
 4940                    let language = raw_buffer.language().cloned()?;
 4941                    Some((file, language, raw_buffer.remote_id()))
 4942                })
 4943                .sorted_by_key(|(file, _, _)| Reverse(file.worktree.read(cx).is_visible()));
 4944            for (file, language, buffer_id) in buffers {
 4945                let worktree_id = file.worktree_id(cx);
 4946                let Some(worktree) = local
 4947                    .worktree_store
 4948                    .read(cx)
 4949                    .worktree_for_id(worktree_id, cx)
 4950                else {
 4951                    continue;
 4952                };
 4953
 4954                if let Some((_, apply)) = local.reuse_existing_language_server(
 4955                    rebase.server_tree(),
 4956                    &worktree,
 4957                    &language.name(),
 4958                    cx,
 4959                ) {
 4960                    (apply)(rebase.server_tree());
 4961                } else if let Some(lsp_delegate) = adapters
 4962                    .entry(worktree_id)
 4963                    .or_insert_with(|| get_adapter(worktree_id, cx))
 4964                    .clone()
 4965                {
 4966                    let delegate =
 4967                        Arc::new(ManifestQueryDelegate::new(worktree.read(cx).snapshot()));
 4968                    let path = file
 4969                        .path()
 4970                        .parent()
 4971                        .map(Arc::from)
 4972                        .unwrap_or_else(|| file.path().clone());
 4973                    let worktree_path = ProjectPath { worktree_id, path };
 4974                    let abs_path = file.abs_path(cx);
 4975                    let nodes = rebase
 4976                        .walk(
 4977                            worktree_path,
 4978                            language.name(),
 4979                            language.manifest(),
 4980                            delegate.clone(),
 4981                            cx,
 4982                        )
 4983                        .collect::<Vec<_>>();
 4984                    for node in nodes {
 4985                        let server_id = node.server_id_or_init(|disposition| {
 4986                            let path = &disposition.path;
 4987                            let uri = Uri::from_file_path(worktree.read(cx).absolutize(&path.path));
 4988                            let key = LanguageServerSeed {
 4989                                worktree_id,
 4990                                name: disposition.server_name.clone(),
 4991                                settings: disposition.settings.clone(),
 4992                                toolchain: local.toolchain_store.read(cx).active_toolchain(
 4993                                    path.worktree_id,
 4994                                    &path.path,
 4995                                    language.name(),
 4996                                ),
 4997                            };
 4998                            local.language_server_ids.remove(&key);
 4999
 5000                            let server_id = local.get_or_insert_language_server(
 5001                                &worktree,
 5002                                lsp_delegate.clone(),
 5003                                disposition,
 5004                                &language.name(),
 5005                                cx,
 5006                            );
 5007                            if let Some(state) = local.language_servers.get(&server_id)
 5008                                && let Ok(uri) = uri
 5009                            {
 5010                                state.add_workspace_folder(uri);
 5011                            };
 5012                            server_id
 5013                        });
 5014
 5015                        if let Some(language_server_id) = server_id {
 5016                            messages_to_report.push(LspStoreEvent::LanguageServerUpdate {
 5017                                language_server_id,
 5018                                name: node.name(),
 5019                                message:
 5020                                    proto::update_language_server::Variant::RegisteredForBuffer(
 5021                                        proto::RegisteredForBuffer {
 5022                                            buffer_abs_path: abs_path
 5023                                                .to_string_lossy()
 5024                                                .into_owned(),
 5025                                            buffer_id: buffer_id.to_proto(),
 5026                                        },
 5027                                    ),
 5028                            });
 5029                        }
 5030                    }
 5031                } else {
 5032                    continue;
 5033                }
 5034            }
 5035            rebase.finish()
 5036        };
 5037        for message in messages_to_report {
 5038            cx.emit(message);
 5039        }
 5040        local.lsp_tree = new_tree;
 5041        for (id, _) in to_stop {
 5042            self.stop_local_language_server(id, cx).detach();
 5043        }
 5044    }
 5045
 5046    pub fn apply_code_action(
 5047        &self,
 5048        buffer_handle: Entity<Buffer>,
 5049        mut action: CodeAction,
 5050        push_to_history: bool,
 5051        cx: &mut Context<Self>,
 5052    ) -> Task<Result<ProjectTransaction>> {
 5053        if let Some((upstream_client, project_id)) = self.upstream_client() {
 5054            let request = proto::ApplyCodeAction {
 5055                project_id,
 5056                buffer_id: buffer_handle.read(cx).remote_id().into(),
 5057                action: Some(Self::serialize_code_action(&action)),
 5058            };
 5059            let buffer_store = self.buffer_store();
 5060            cx.spawn(async move |_, cx| {
 5061                let response = upstream_client
 5062                    .request(request)
 5063                    .await?
 5064                    .transaction
 5065                    .context("missing transaction")?;
 5066
 5067                buffer_store
 5068                    .update(cx, |buffer_store, cx| {
 5069                        buffer_store.deserialize_project_transaction(response, push_to_history, cx)
 5070                    })?
 5071                    .await
 5072            })
 5073        } else if self.mode.is_local() {
 5074            let Some((_, lang_server)) = buffer_handle.update(cx, |buffer, cx| {
 5075                self.language_server_for_local_buffer(buffer, action.server_id, cx)
 5076                    .map(|(adapter, server)| (adapter.clone(), server.clone()))
 5077            }) else {
 5078                return Task::ready(Ok(ProjectTransaction::default()));
 5079            };
 5080            cx.spawn(async move |this,  cx| {
 5081                LocalLspStore::try_resolve_code_action(&lang_server, &mut action)
 5082                    .await
 5083                    .context("resolving a code action")?;
 5084                if let Some(edit) = action.lsp_action.edit()
 5085                    && (edit.changes.is_some() || edit.document_changes.is_some()) {
 5086                        return LocalLspStore::deserialize_workspace_edit(
 5087                            this.upgrade().context("no app present")?,
 5088                            edit.clone(),
 5089                            push_to_history,
 5090
 5091                            lang_server.clone(),
 5092                            cx,
 5093                        )
 5094                        .await;
 5095                    }
 5096
 5097                if let Some(command) = action.lsp_action.command() {
 5098                    let server_capabilities = lang_server.capabilities();
 5099                    let available_commands = server_capabilities
 5100                        .execute_command_provider
 5101                        .as_ref()
 5102                        .map(|options| options.commands.as_slice())
 5103                        .unwrap_or_default();
 5104                    if available_commands.contains(&command.command) {
 5105                        this.update(cx, |this, _| {
 5106                            this.as_local_mut()
 5107                                .unwrap()
 5108                                .last_workspace_edits_by_language_server
 5109                                .remove(&lang_server.server_id());
 5110                        })?;
 5111
 5112                        let _result = lang_server
 5113                            .request::<lsp::request::ExecuteCommand>(lsp::ExecuteCommandParams {
 5114                                command: command.command.clone(),
 5115                                arguments: command.arguments.clone().unwrap_or_default(),
 5116                                ..lsp::ExecuteCommandParams::default()
 5117                            })
 5118                            .await.into_response()
 5119                            .context("execute command")?;
 5120
 5121                        return this.update(cx, |this, _| {
 5122                            this.as_local_mut()
 5123                                .unwrap()
 5124                                .last_workspace_edits_by_language_server
 5125                                .remove(&lang_server.server_id())
 5126                                .unwrap_or_default()
 5127                        });
 5128                    } else {
 5129                        log::warn!("Cannot execute a command {} not listed in the language server capabilities", command.command);
 5130                    }
 5131                }
 5132
 5133                Ok(ProjectTransaction::default())
 5134            })
 5135        } else {
 5136            Task::ready(Err(anyhow!("no upstream client and not local")))
 5137        }
 5138    }
 5139
 5140    pub fn apply_code_action_kind(
 5141        &mut self,
 5142        buffers: HashSet<Entity<Buffer>>,
 5143        kind: CodeActionKind,
 5144        push_to_history: bool,
 5145        cx: &mut Context<Self>,
 5146    ) -> Task<anyhow::Result<ProjectTransaction>> {
 5147        if self.as_local().is_some() {
 5148            cx.spawn(async move |lsp_store, cx| {
 5149                let buffers = buffers.into_iter().collect::<Vec<_>>();
 5150                let result = LocalLspStore::execute_code_action_kind_locally(
 5151                    lsp_store.clone(),
 5152                    buffers,
 5153                    kind,
 5154                    push_to_history,
 5155                    cx,
 5156                )
 5157                .await;
 5158                lsp_store.update(cx, |lsp_store, _| {
 5159                    lsp_store.update_last_formatting_failure(&result);
 5160                })?;
 5161                result
 5162            })
 5163        } else if let Some((client, project_id)) = self.upstream_client() {
 5164            let buffer_store = self.buffer_store();
 5165            cx.spawn(async move |lsp_store, cx| {
 5166                let result = client
 5167                    .request(proto::ApplyCodeActionKind {
 5168                        project_id,
 5169                        kind: kind.as_str().to_owned(),
 5170                        buffer_ids: buffers
 5171                            .iter()
 5172                            .map(|buffer| {
 5173                                buffer.read_with(cx, |buffer, _| buffer.remote_id().into())
 5174                            })
 5175                            .collect::<Result<_>>()?,
 5176                    })
 5177                    .await
 5178                    .and_then(|result| result.transaction.context("missing transaction"));
 5179                lsp_store.update(cx, |lsp_store, _| {
 5180                    lsp_store.update_last_formatting_failure(&result);
 5181                })?;
 5182
 5183                let transaction_response = result?;
 5184                buffer_store
 5185                    .update(cx, |buffer_store, cx| {
 5186                        buffer_store.deserialize_project_transaction(
 5187                            transaction_response,
 5188                            push_to_history,
 5189                            cx,
 5190                        )
 5191                    })?
 5192                    .await
 5193            })
 5194        } else {
 5195            Task::ready(Ok(ProjectTransaction::default()))
 5196        }
 5197    }
 5198
 5199    pub fn resolved_hint(
 5200        &mut self,
 5201        buffer_id: BufferId,
 5202        id: InlayId,
 5203        cx: &mut Context<Self>,
 5204    ) -> Option<ResolvedHint> {
 5205        let buffer = self.buffer_store.read(cx).get(buffer_id)?;
 5206
 5207        let lsp_data = self.lsp_data.get_mut(&buffer_id)?;
 5208        let buffer_lsp_hints = &mut lsp_data.inlay_hints;
 5209        let hint = buffer_lsp_hints.hint_for_id(id)?.clone();
 5210        let (server_id, resolve_data) = match &hint.resolve_state {
 5211            ResolveState::Resolved => return Some(ResolvedHint::Resolved(hint)),
 5212            ResolveState::Resolving => {
 5213                return Some(ResolvedHint::Resolving(
 5214                    buffer_lsp_hints.hint_resolves.get(&id)?.clone(),
 5215                ));
 5216            }
 5217            ResolveState::CanResolve(server_id, resolve_data) => (*server_id, resolve_data.clone()),
 5218        };
 5219
 5220        let resolve_task = self.resolve_inlay_hint(hint, buffer, server_id, cx);
 5221        let buffer_lsp_hints = &mut self.lsp_data.get_mut(&buffer_id)?.inlay_hints;
 5222        let previous_task = buffer_lsp_hints.hint_resolves.insert(
 5223            id,
 5224            cx.spawn(async move |lsp_store, cx| {
 5225                let resolved_hint = resolve_task.await;
 5226                lsp_store
 5227                    .update(cx, |lsp_store, _| {
 5228                        if let Some(old_inlay_hint) = lsp_store
 5229                            .lsp_data
 5230                            .get_mut(&buffer_id)
 5231                            .and_then(|buffer_lsp_data| buffer_lsp_data.inlay_hints.hint_for_id(id))
 5232                        {
 5233                            match resolved_hint {
 5234                                Ok(resolved_hint) => {
 5235                                    *old_inlay_hint = resolved_hint;
 5236                                }
 5237                                Err(e) => {
 5238                                    old_inlay_hint.resolve_state =
 5239                                        ResolveState::CanResolve(server_id, resolve_data);
 5240                                    log::error!("Inlay hint resolve failed: {e:#}");
 5241                                }
 5242                            }
 5243                        }
 5244                    })
 5245                    .ok();
 5246            })
 5247            .shared(),
 5248        );
 5249        debug_assert!(
 5250            previous_task.is_none(),
 5251            "Did not change hint's resolve state after spawning its resolve"
 5252        );
 5253        buffer_lsp_hints.hint_for_id(id)?.resolve_state = ResolveState::Resolving;
 5254        None
 5255    }
 5256
 5257    fn resolve_inlay_hint(
 5258        &self,
 5259        mut hint: InlayHint,
 5260        buffer: Entity<Buffer>,
 5261        server_id: LanguageServerId,
 5262        cx: &mut Context<Self>,
 5263    ) -> Task<anyhow::Result<InlayHint>> {
 5264        if let Some((upstream_client, project_id)) = self.upstream_client() {
 5265            if !self.check_if_capable_for_proto_request(&buffer, InlayHints::can_resolve_inlays, cx)
 5266            {
 5267                hint.resolve_state = ResolveState::Resolved;
 5268                return Task::ready(Ok(hint));
 5269            }
 5270            let request = proto::ResolveInlayHint {
 5271                project_id,
 5272                buffer_id: buffer.read(cx).remote_id().into(),
 5273                language_server_id: server_id.0 as u64,
 5274                hint: Some(InlayHints::project_to_proto_hint(hint.clone())),
 5275            };
 5276            cx.background_spawn(async move {
 5277                let response = upstream_client
 5278                    .request(request)
 5279                    .await
 5280                    .context("inlay hints proto request")?;
 5281                match response.hint {
 5282                    Some(resolved_hint) => InlayHints::proto_to_project_hint(resolved_hint)
 5283                        .context("inlay hints proto resolve response conversion"),
 5284                    None => Ok(hint),
 5285                }
 5286            })
 5287        } else {
 5288            let Some(lang_server) = buffer.update(cx, |buffer, cx| {
 5289                self.language_server_for_local_buffer(buffer, server_id, cx)
 5290                    .map(|(_, server)| server.clone())
 5291            }) else {
 5292                return Task::ready(Ok(hint));
 5293            };
 5294            if !InlayHints::can_resolve_inlays(&lang_server.capabilities()) {
 5295                return Task::ready(Ok(hint));
 5296            }
 5297            let buffer_snapshot = buffer.read(cx).snapshot();
 5298            cx.spawn(async move |_, cx| {
 5299                let resolve_task = lang_server.request::<lsp::request::InlayHintResolveRequest>(
 5300                    InlayHints::project_to_lsp_hint(hint, &buffer_snapshot),
 5301                );
 5302                let resolved_hint = resolve_task
 5303                    .await
 5304                    .into_response()
 5305                    .context("inlay hint resolve LSP request")?;
 5306                let resolved_hint = InlayHints::lsp_to_project_hint(
 5307                    resolved_hint,
 5308                    &buffer,
 5309                    server_id,
 5310                    ResolveState::Resolved,
 5311                    false,
 5312                    cx,
 5313                )
 5314                .await?;
 5315                Ok(resolved_hint)
 5316            })
 5317        }
 5318    }
 5319
 5320    pub fn resolve_color_presentation(
 5321        &mut self,
 5322        mut color: DocumentColor,
 5323        buffer: Entity<Buffer>,
 5324        server_id: LanguageServerId,
 5325        cx: &mut Context<Self>,
 5326    ) -> Task<Result<DocumentColor>> {
 5327        if color.resolved {
 5328            return Task::ready(Ok(color));
 5329        }
 5330
 5331        if let Some((upstream_client, project_id)) = self.upstream_client() {
 5332            let start = color.lsp_range.start;
 5333            let end = color.lsp_range.end;
 5334            let request = proto::GetColorPresentation {
 5335                project_id,
 5336                server_id: server_id.to_proto(),
 5337                buffer_id: buffer.read(cx).remote_id().into(),
 5338                color: Some(proto::ColorInformation {
 5339                    red: color.color.red,
 5340                    green: color.color.green,
 5341                    blue: color.color.blue,
 5342                    alpha: color.color.alpha,
 5343                    lsp_range_start: Some(proto::PointUtf16 {
 5344                        row: start.line,
 5345                        column: start.character,
 5346                    }),
 5347                    lsp_range_end: Some(proto::PointUtf16 {
 5348                        row: end.line,
 5349                        column: end.character,
 5350                    }),
 5351                }),
 5352            };
 5353            cx.background_spawn(async move {
 5354                let response = upstream_client
 5355                    .request(request)
 5356                    .await
 5357                    .context("color presentation proto request")?;
 5358                color.resolved = true;
 5359                color.color_presentations = response
 5360                    .presentations
 5361                    .into_iter()
 5362                    .map(|presentation| ColorPresentation {
 5363                        label: SharedString::from(presentation.label),
 5364                        text_edit: presentation.text_edit.and_then(deserialize_lsp_edit),
 5365                        additional_text_edits: presentation
 5366                            .additional_text_edits
 5367                            .into_iter()
 5368                            .filter_map(deserialize_lsp_edit)
 5369                            .collect(),
 5370                    })
 5371                    .collect();
 5372                Ok(color)
 5373            })
 5374        } else {
 5375            let path = match buffer
 5376                .update(cx, |buffer, cx| {
 5377                    Some(File::from_dyn(buffer.file())?.abs_path(cx))
 5378                })
 5379                .context("buffer with the missing path")
 5380            {
 5381                Ok(path) => path,
 5382                Err(e) => return Task::ready(Err(e)),
 5383            };
 5384            let Some(lang_server) = buffer.update(cx, |buffer, cx| {
 5385                self.language_server_for_local_buffer(buffer, server_id, cx)
 5386                    .map(|(_, server)| server.clone())
 5387            }) else {
 5388                return Task::ready(Ok(color));
 5389            };
 5390            cx.background_spawn(async move {
 5391                let resolve_task = lang_server.request::<lsp::request::ColorPresentationRequest>(
 5392                    lsp::ColorPresentationParams {
 5393                        text_document: make_text_document_identifier(&path)?,
 5394                        color: color.color,
 5395                        range: color.lsp_range,
 5396                        work_done_progress_params: Default::default(),
 5397                        partial_result_params: Default::default(),
 5398                    },
 5399                );
 5400                color.color_presentations = resolve_task
 5401                    .await
 5402                    .into_response()
 5403                    .context("color presentation resolve LSP request")?
 5404                    .into_iter()
 5405                    .map(|presentation| ColorPresentation {
 5406                        label: SharedString::from(presentation.label),
 5407                        text_edit: presentation.text_edit,
 5408                        additional_text_edits: presentation
 5409                            .additional_text_edits
 5410                            .unwrap_or_default(),
 5411                    })
 5412                    .collect();
 5413                color.resolved = true;
 5414                Ok(color)
 5415            })
 5416        }
 5417    }
 5418
 5419    pub(crate) fn linked_edits(
 5420        &mut self,
 5421        buffer: &Entity<Buffer>,
 5422        position: Anchor,
 5423        cx: &mut Context<Self>,
 5424    ) -> Task<Result<Vec<Range<Anchor>>>> {
 5425        let snapshot = buffer.read(cx).snapshot();
 5426        let scope = snapshot.language_scope_at(position);
 5427        let Some(server_id) = self
 5428            .as_local()
 5429            .and_then(|local| {
 5430                buffer.update(cx, |buffer, cx| {
 5431                    local
 5432                        .language_servers_for_buffer(buffer, cx)
 5433                        .filter(|(_, server)| {
 5434                            LinkedEditingRange::check_server_capabilities(server.capabilities())
 5435                        })
 5436                        .filter(|(adapter, _)| {
 5437                            scope
 5438                                .as_ref()
 5439                                .map(|scope| scope.language_allowed(&adapter.name))
 5440                                .unwrap_or(true)
 5441                        })
 5442                        .map(|(_, server)| LanguageServerToQuery::Other(server.server_id()))
 5443                        .next()
 5444                })
 5445            })
 5446            .or_else(|| {
 5447                self.upstream_client()
 5448                    .is_some()
 5449                    .then_some(LanguageServerToQuery::FirstCapable)
 5450            })
 5451            .filter(|_| {
 5452                maybe!({
 5453                    let language = buffer.read(cx).language_at(position)?;
 5454                    Some(
 5455                        language_settings(Some(language.name()), buffer.read(cx).file(), cx)
 5456                            .linked_edits,
 5457                    )
 5458                }) == Some(true)
 5459            })
 5460        else {
 5461            return Task::ready(Ok(Vec::new()));
 5462        };
 5463
 5464        self.request_lsp(
 5465            buffer.clone(),
 5466            server_id,
 5467            LinkedEditingRange { position },
 5468            cx,
 5469        )
 5470    }
 5471
 5472    fn apply_on_type_formatting(
 5473        &mut self,
 5474        buffer: Entity<Buffer>,
 5475        position: Anchor,
 5476        trigger: String,
 5477        cx: &mut Context<Self>,
 5478    ) -> Task<Result<Option<Transaction>>> {
 5479        if let Some((client, project_id)) = self.upstream_client() {
 5480            if !self.check_if_capable_for_proto_request(
 5481                &buffer,
 5482                |capabilities| {
 5483                    OnTypeFormatting::supports_on_type_formatting(&trigger, capabilities)
 5484                },
 5485                cx,
 5486            ) {
 5487                return Task::ready(Ok(None));
 5488            }
 5489            let request = proto::OnTypeFormatting {
 5490                project_id,
 5491                buffer_id: buffer.read(cx).remote_id().into(),
 5492                position: Some(serialize_anchor(&position)),
 5493                trigger,
 5494                version: serialize_version(&buffer.read(cx).version()),
 5495            };
 5496            cx.background_spawn(async move {
 5497                client
 5498                    .request(request)
 5499                    .await?
 5500                    .transaction
 5501                    .map(language::proto::deserialize_transaction)
 5502                    .transpose()
 5503            })
 5504        } else if let Some(local) = self.as_local_mut() {
 5505            let buffer_id = buffer.read(cx).remote_id();
 5506            local.buffers_being_formatted.insert(buffer_id);
 5507            cx.spawn(async move |this, cx| {
 5508                let _cleanup = defer({
 5509                    let this = this.clone();
 5510                    let mut cx = cx.clone();
 5511                    move || {
 5512                        this.update(&mut cx, |this, _| {
 5513                            if let Some(local) = this.as_local_mut() {
 5514                                local.buffers_being_formatted.remove(&buffer_id);
 5515                            }
 5516                        })
 5517                        .ok();
 5518                    }
 5519                });
 5520
 5521                buffer
 5522                    .update(cx, |buffer, _| {
 5523                        buffer.wait_for_edits(Some(position.timestamp))
 5524                    })?
 5525                    .await?;
 5526                this.update(cx, |this, cx| {
 5527                    let position = position.to_point_utf16(buffer.read(cx));
 5528                    this.on_type_format(buffer, position, trigger, false, cx)
 5529                })?
 5530                .await
 5531            })
 5532        } else {
 5533            Task::ready(Err(anyhow!("No upstream client or local language server")))
 5534        }
 5535    }
 5536
 5537    pub fn on_type_format<T: ToPointUtf16>(
 5538        &mut self,
 5539        buffer: Entity<Buffer>,
 5540        position: T,
 5541        trigger: String,
 5542        push_to_history: bool,
 5543        cx: &mut Context<Self>,
 5544    ) -> Task<Result<Option<Transaction>>> {
 5545        let position = position.to_point_utf16(buffer.read(cx));
 5546        self.on_type_format_impl(buffer, position, trigger, push_to_history, cx)
 5547    }
 5548
 5549    fn on_type_format_impl(
 5550        &mut self,
 5551        buffer: Entity<Buffer>,
 5552        position: PointUtf16,
 5553        trigger: String,
 5554        push_to_history: bool,
 5555        cx: &mut Context<Self>,
 5556    ) -> Task<Result<Option<Transaction>>> {
 5557        let options = buffer.update(cx, |buffer, cx| {
 5558            lsp_command::lsp_formatting_options(
 5559                language_settings(
 5560                    buffer.language_at(position).map(|l| l.name()),
 5561                    buffer.file(),
 5562                    cx,
 5563                )
 5564                .as_ref(),
 5565            )
 5566        });
 5567
 5568        cx.spawn(async move |this, cx| {
 5569            if let Some(waiter) =
 5570                buffer.update(cx, |buffer, _| buffer.wait_for_autoindent_applied())?
 5571            {
 5572                waiter.await?;
 5573            }
 5574            cx.update(|cx| {
 5575                this.update(cx, |this, cx| {
 5576                    this.request_lsp(
 5577                        buffer.clone(),
 5578                        LanguageServerToQuery::FirstCapable,
 5579                        OnTypeFormatting {
 5580                            position,
 5581                            trigger,
 5582                            options,
 5583                            push_to_history,
 5584                        },
 5585                        cx,
 5586                    )
 5587                })
 5588            })??
 5589            .await
 5590        })
 5591    }
 5592
 5593    pub fn definitions(
 5594        &mut self,
 5595        buffer: &Entity<Buffer>,
 5596        position: PointUtf16,
 5597        cx: &mut Context<Self>,
 5598    ) -> Task<Result<Option<Vec<LocationLink>>>> {
 5599        if let Some((upstream_client, project_id)) = self.upstream_client() {
 5600            let request = GetDefinitions { position };
 5601            if !self.is_capable_for_proto_request(buffer, &request, cx) {
 5602                return Task::ready(Ok(None));
 5603            }
 5604            let request_task = upstream_client.request_lsp(
 5605                project_id,
 5606                None,
 5607                LSP_REQUEST_TIMEOUT,
 5608                cx.background_executor().clone(),
 5609                request.to_proto(project_id, buffer.read(cx)),
 5610            );
 5611            let buffer = buffer.clone();
 5612            cx.spawn(async move |weak_lsp_store, cx| {
 5613                let Some(lsp_store) = weak_lsp_store.upgrade() else {
 5614                    return Ok(None);
 5615                };
 5616                let Some(responses) = request_task.await? else {
 5617                    return Ok(None);
 5618                };
 5619                let actions = join_all(responses.payload.into_iter().map(|response| {
 5620                    GetDefinitions { position }.response_from_proto(
 5621                        response.response,
 5622                        lsp_store.clone(),
 5623                        buffer.clone(),
 5624                        cx.clone(),
 5625                    )
 5626                }))
 5627                .await;
 5628
 5629                Ok(Some(
 5630                    actions
 5631                        .into_iter()
 5632                        .collect::<Result<Vec<Vec<_>>>>()?
 5633                        .into_iter()
 5634                        .flatten()
 5635                        .dedup()
 5636                        .collect(),
 5637                ))
 5638            })
 5639        } else {
 5640            let definitions_task = self.request_multiple_lsp_locally(
 5641                buffer,
 5642                Some(position),
 5643                GetDefinitions { position },
 5644                cx,
 5645            );
 5646            cx.background_spawn(async move {
 5647                Ok(Some(
 5648                    definitions_task
 5649                        .await
 5650                        .into_iter()
 5651                        .flat_map(|(_, definitions)| definitions)
 5652                        .dedup()
 5653                        .collect(),
 5654                ))
 5655            })
 5656        }
 5657    }
 5658
 5659    pub fn declarations(
 5660        &mut self,
 5661        buffer: &Entity<Buffer>,
 5662        position: PointUtf16,
 5663        cx: &mut Context<Self>,
 5664    ) -> Task<Result<Option<Vec<LocationLink>>>> {
 5665        if let Some((upstream_client, project_id)) = self.upstream_client() {
 5666            let request = GetDeclarations { position };
 5667            if !self.is_capable_for_proto_request(buffer, &request, cx) {
 5668                return Task::ready(Ok(None));
 5669            }
 5670            let request_task = upstream_client.request_lsp(
 5671                project_id,
 5672                None,
 5673                LSP_REQUEST_TIMEOUT,
 5674                cx.background_executor().clone(),
 5675                request.to_proto(project_id, buffer.read(cx)),
 5676            );
 5677            let buffer = buffer.clone();
 5678            cx.spawn(async move |weak_lsp_store, cx| {
 5679                let Some(lsp_store) = weak_lsp_store.upgrade() else {
 5680                    return Ok(None);
 5681                };
 5682                let Some(responses) = request_task.await? else {
 5683                    return Ok(None);
 5684                };
 5685                let actions = join_all(responses.payload.into_iter().map(|response| {
 5686                    GetDeclarations { position }.response_from_proto(
 5687                        response.response,
 5688                        lsp_store.clone(),
 5689                        buffer.clone(),
 5690                        cx.clone(),
 5691                    )
 5692                }))
 5693                .await;
 5694
 5695                Ok(Some(
 5696                    actions
 5697                        .into_iter()
 5698                        .collect::<Result<Vec<Vec<_>>>>()?
 5699                        .into_iter()
 5700                        .flatten()
 5701                        .dedup()
 5702                        .collect(),
 5703                ))
 5704            })
 5705        } else {
 5706            let declarations_task = self.request_multiple_lsp_locally(
 5707                buffer,
 5708                Some(position),
 5709                GetDeclarations { position },
 5710                cx,
 5711            );
 5712            cx.background_spawn(async move {
 5713                Ok(Some(
 5714                    declarations_task
 5715                        .await
 5716                        .into_iter()
 5717                        .flat_map(|(_, declarations)| declarations)
 5718                        .dedup()
 5719                        .collect(),
 5720                ))
 5721            })
 5722        }
 5723    }
 5724
 5725    pub fn type_definitions(
 5726        &mut self,
 5727        buffer: &Entity<Buffer>,
 5728        position: PointUtf16,
 5729        cx: &mut Context<Self>,
 5730    ) -> Task<Result<Option<Vec<LocationLink>>>> {
 5731        if let Some((upstream_client, project_id)) = self.upstream_client() {
 5732            let request = GetTypeDefinitions { position };
 5733            if !self.is_capable_for_proto_request(buffer, &request, cx) {
 5734                return Task::ready(Ok(None));
 5735            }
 5736            let request_task = upstream_client.request_lsp(
 5737                project_id,
 5738                None,
 5739                LSP_REQUEST_TIMEOUT,
 5740                cx.background_executor().clone(),
 5741                request.to_proto(project_id, buffer.read(cx)),
 5742            );
 5743            let buffer = buffer.clone();
 5744            cx.spawn(async move |weak_lsp_store, cx| {
 5745                let Some(lsp_store) = weak_lsp_store.upgrade() else {
 5746                    return Ok(None);
 5747                };
 5748                let Some(responses) = request_task.await? else {
 5749                    return Ok(None);
 5750                };
 5751                let actions = join_all(responses.payload.into_iter().map(|response| {
 5752                    GetTypeDefinitions { position }.response_from_proto(
 5753                        response.response,
 5754                        lsp_store.clone(),
 5755                        buffer.clone(),
 5756                        cx.clone(),
 5757                    )
 5758                }))
 5759                .await;
 5760
 5761                Ok(Some(
 5762                    actions
 5763                        .into_iter()
 5764                        .collect::<Result<Vec<Vec<_>>>>()?
 5765                        .into_iter()
 5766                        .flatten()
 5767                        .dedup()
 5768                        .collect(),
 5769                ))
 5770            })
 5771        } else {
 5772            let type_definitions_task = self.request_multiple_lsp_locally(
 5773                buffer,
 5774                Some(position),
 5775                GetTypeDefinitions { position },
 5776                cx,
 5777            );
 5778            cx.background_spawn(async move {
 5779                Ok(Some(
 5780                    type_definitions_task
 5781                        .await
 5782                        .into_iter()
 5783                        .flat_map(|(_, type_definitions)| type_definitions)
 5784                        .dedup()
 5785                        .collect(),
 5786                ))
 5787            })
 5788        }
 5789    }
 5790
 5791    pub fn implementations(
 5792        &mut self,
 5793        buffer: &Entity<Buffer>,
 5794        position: PointUtf16,
 5795        cx: &mut Context<Self>,
 5796    ) -> Task<Result<Option<Vec<LocationLink>>>> {
 5797        if let Some((upstream_client, project_id)) = self.upstream_client() {
 5798            let request = GetImplementations { position };
 5799            if !self.is_capable_for_proto_request(buffer, &request, cx) {
 5800                return Task::ready(Ok(None));
 5801            }
 5802            let request_task = upstream_client.request_lsp(
 5803                project_id,
 5804                None,
 5805                LSP_REQUEST_TIMEOUT,
 5806                cx.background_executor().clone(),
 5807                request.to_proto(project_id, buffer.read(cx)),
 5808            );
 5809            let buffer = buffer.clone();
 5810            cx.spawn(async move |weak_lsp_store, cx| {
 5811                let Some(lsp_store) = weak_lsp_store.upgrade() else {
 5812                    return Ok(None);
 5813                };
 5814                let Some(responses) = request_task.await? else {
 5815                    return Ok(None);
 5816                };
 5817                let actions = join_all(responses.payload.into_iter().map(|response| {
 5818                    GetImplementations { position }.response_from_proto(
 5819                        response.response,
 5820                        lsp_store.clone(),
 5821                        buffer.clone(),
 5822                        cx.clone(),
 5823                    )
 5824                }))
 5825                .await;
 5826
 5827                Ok(Some(
 5828                    actions
 5829                        .into_iter()
 5830                        .collect::<Result<Vec<Vec<_>>>>()?
 5831                        .into_iter()
 5832                        .flatten()
 5833                        .dedup()
 5834                        .collect(),
 5835                ))
 5836            })
 5837        } else {
 5838            let implementations_task = self.request_multiple_lsp_locally(
 5839                buffer,
 5840                Some(position),
 5841                GetImplementations { position },
 5842                cx,
 5843            );
 5844            cx.background_spawn(async move {
 5845                Ok(Some(
 5846                    implementations_task
 5847                        .await
 5848                        .into_iter()
 5849                        .flat_map(|(_, implementations)| implementations)
 5850                        .dedup()
 5851                        .collect(),
 5852                ))
 5853            })
 5854        }
 5855    }
 5856
 5857    pub fn references(
 5858        &mut self,
 5859        buffer: &Entity<Buffer>,
 5860        position: PointUtf16,
 5861        cx: &mut Context<Self>,
 5862    ) -> Task<Result<Option<Vec<Location>>>> {
 5863        if let Some((upstream_client, project_id)) = self.upstream_client() {
 5864            let request = GetReferences { position };
 5865            if !self.is_capable_for_proto_request(buffer, &request, cx) {
 5866                return Task::ready(Ok(None));
 5867            }
 5868
 5869            let request_task = upstream_client.request_lsp(
 5870                project_id,
 5871                None,
 5872                LSP_REQUEST_TIMEOUT,
 5873                cx.background_executor().clone(),
 5874                request.to_proto(project_id, buffer.read(cx)),
 5875            );
 5876            let buffer = buffer.clone();
 5877            cx.spawn(async move |weak_lsp_store, cx| {
 5878                let Some(lsp_store) = weak_lsp_store.upgrade() else {
 5879                    return Ok(None);
 5880                };
 5881                let Some(responses) = request_task.await? else {
 5882                    return Ok(None);
 5883                };
 5884
 5885                let locations = join_all(responses.payload.into_iter().map(|lsp_response| {
 5886                    GetReferences { position }.response_from_proto(
 5887                        lsp_response.response,
 5888                        lsp_store.clone(),
 5889                        buffer.clone(),
 5890                        cx.clone(),
 5891                    )
 5892                }))
 5893                .await
 5894                .into_iter()
 5895                .collect::<Result<Vec<Vec<_>>>>()?
 5896                .into_iter()
 5897                .flatten()
 5898                .dedup()
 5899                .collect();
 5900                Ok(Some(locations))
 5901            })
 5902        } else {
 5903            let references_task = self.request_multiple_lsp_locally(
 5904                buffer,
 5905                Some(position),
 5906                GetReferences { position },
 5907                cx,
 5908            );
 5909            cx.background_spawn(async move {
 5910                Ok(Some(
 5911                    references_task
 5912                        .await
 5913                        .into_iter()
 5914                        .flat_map(|(_, references)| references)
 5915                        .dedup()
 5916                        .collect(),
 5917                ))
 5918            })
 5919        }
 5920    }
 5921
 5922    pub fn code_actions(
 5923        &mut self,
 5924        buffer: &Entity<Buffer>,
 5925        range: Range<Anchor>,
 5926        kinds: Option<Vec<CodeActionKind>>,
 5927        cx: &mut Context<Self>,
 5928    ) -> Task<Result<Option<Vec<CodeAction>>>> {
 5929        if let Some((upstream_client, project_id)) = self.upstream_client() {
 5930            let request = GetCodeActions {
 5931                range: range.clone(),
 5932                kinds: kinds.clone(),
 5933            };
 5934            if !self.is_capable_for_proto_request(buffer, &request, cx) {
 5935                return Task::ready(Ok(None));
 5936            }
 5937            let request_task = upstream_client.request_lsp(
 5938                project_id,
 5939                None,
 5940                LSP_REQUEST_TIMEOUT,
 5941                cx.background_executor().clone(),
 5942                request.to_proto(project_id, buffer.read(cx)),
 5943            );
 5944            let buffer = buffer.clone();
 5945            cx.spawn(async move |weak_lsp_store, cx| {
 5946                let Some(lsp_store) = weak_lsp_store.upgrade() else {
 5947                    return Ok(None);
 5948                };
 5949                let Some(responses) = request_task.await? else {
 5950                    return Ok(None);
 5951                };
 5952                let actions = join_all(responses.payload.into_iter().map(|response| {
 5953                    GetCodeActions {
 5954                        range: range.clone(),
 5955                        kinds: kinds.clone(),
 5956                    }
 5957                    .response_from_proto(
 5958                        response.response,
 5959                        lsp_store.clone(),
 5960                        buffer.clone(),
 5961                        cx.clone(),
 5962                    )
 5963                }))
 5964                .await;
 5965
 5966                Ok(Some(
 5967                    actions
 5968                        .into_iter()
 5969                        .collect::<Result<Vec<Vec<_>>>>()?
 5970                        .into_iter()
 5971                        .flatten()
 5972                        .collect(),
 5973                ))
 5974            })
 5975        } else {
 5976            let all_actions_task = self.request_multiple_lsp_locally(
 5977                buffer,
 5978                Some(range.start),
 5979                GetCodeActions { range, kinds },
 5980                cx,
 5981            );
 5982            cx.background_spawn(async move {
 5983                Ok(Some(
 5984                    all_actions_task
 5985                        .await
 5986                        .into_iter()
 5987                        .flat_map(|(_, actions)| actions)
 5988                        .collect(),
 5989                ))
 5990            })
 5991        }
 5992    }
 5993
 5994    pub fn code_lens_actions(
 5995        &mut self,
 5996        buffer: &Entity<Buffer>,
 5997        cx: &mut Context<Self>,
 5998    ) -> CodeLensTask {
 5999        let version_queried_for = buffer.read(cx).version();
 6000        let buffer_id = buffer.read(cx).remote_id();
 6001        let existing_servers = self.as_local().map(|local| {
 6002            local
 6003                .buffers_opened_in_servers
 6004                .get(&buffer_id)
 6005                .cloned()
 6006                .unwrap_or_default()
 6007        });
 6008
 6009        if let Some(lsp_data) = self.current_lsp_data(buffer_id) {
 6010            if let Some(cached_lens) = &lsp_data.code_lens {
 6011                if !version_queried_for.changed_since(&lsp_data.buffer_version) {
 6012                    let has_different_servers = existing_servers.is_some_and(|existing_servers| {
 6013                        existing_servers != cached_lens.lens.keys().copied().collect()
 6014                    });
 6015                    if !has_different_servers {
 6016                        return Task::ready(Ok(Some(
 6017                            cached_lens.lens.values().flatten().cloned().collect(),
 6018                        )))
 6019                        .shared();
 6020                    }
 6021                } else if let Some((updating_for, running_update)) = cached_lens.update.as_ref() {
 6022                    if !version_queried_for.changed_since(updating_for) {
 6023                        return running_update.clone();
 6024                    }
 6025                }
 6026            }
 6027        }
 6028
 6029        let lens_lsp_data = self
 6030            .latest_lsp_data(buffer, cx)
 6031            .code_lens
 6032            .get_or_insert_default();
 6033        let buffer = buffer.clone();
 6034        let query_version_queried_for = version_queried_for.clone();
 6035        let new_task = cx
 6036            .spawn(async move |lsp_store, cx| {
 6037                cx.background_executor()
 6038                    .timer(Duration::from_millis(30))
 6039                    .await;
 6040                let fetched_lens = lsp_store
 6041                    .update(cx, |lsp_store, cx| lsp_store.fetch_code_lens(&buffer, cx))
 6042                    .map_err(Arc::new)?
 6043                    .await
 6044                    .context("fetching code lens")
 6045                    .map_err(Arc::new);
 6046                let fetched_lens = match fetched_lens {
 6047                    Ok(fetched_lens) => fetched_lens,
 6048                    Err(e) => {
 6049                        lsp_store
 6050                            .update(cx, |lsp_store, _| {
 6051                                if let Some(lens_lsp_data) = lsp_store
 6052                                    .lsp_data
 6053                                    .get_mut(&buffer_id)
 6054                                    .and_then(|lsp_data| lsp_data.code_lens.as_mut())
 6055                                {
 6056                                    lens_lsp_data.update = None;
 6057                                }
 6058                            })
 6059                            .ok();
 6060                        return Err(e);
 6061                    }
 6062                };
 6063
 6064                lsp_store
 6065                    .update(cx, |lsp_store, _| {
 6066                        let lsp_data = lsp_store.current_lsp_data(buffer_id)?;
 6067                        let code_lens = lsp_data.code_lens.as_mut()?;
 6068                        if let Some(fetched_lens) = fetched_lens {
 6069                            if lsp_data.buffer_version == query_version_queried_for {
 6070                                code_lens.lens.extend(fetched_lens);
 6071                            } else if !lsp_data
 6072                                .buffer_version
 6073                                .changed_since(&query_version_queried_for)
 6074                            {
 6075                                lsp_data.buffer_version = query_version_queried_for;
 6076                                code_lens.lens = fetched_lens;
 6077                            }
 6078                        }
 6079                        code_lens.update = None;
 6080                        Some(code_lens.lens.values().flatten().cloned().collect())
 6081                    })
 6082                    .map_err(Arc::new)
 6083            })
 6084            .shared();
 6085        lens_lsp_data.update = Some((version_queried_for, new_task.clone()));
 6086        new_task
 6087    }
 6088
 6089    fn fetch_code_lens(
 6090        &mut self,
 6091        buffer: &Entity<Buffer>,
 6092        cx: &mut Context<Self>,
 6093    ) -> Task<Result<Option<HashMap<LanguageServerId, Vec<CodeAction>>>>> {
 6094        if let Some((upstream_client, project_id)) = self.upstream_client() {
 6095            let request = GetCodeLens;
 6096            if !self.is_capable_for_proto_request(buffer, &request, cx) {
 6097                return Task::ready(Ok(None));
 6098            }
 6099            let request_task = upstream_client.request_lsp(
 6100                project_id,
 6101                None,
 6102                LSP_REQUEST_TIMEOUT,
 6103                cx.background_executor().clone(),
 6104                request.to_proto(project_id, buffer.read(cx)),
 6105            );
 6106            let buffer = buffer.clone();
 6107            cx.spawn(async move |weak_lsp_store, cx| {
 6108                let Some(lsp_store) = weak_lsp_store.upgrade() else {
 6109                    return Ok(None);
 6110                };
 6111                let Some(responses) = request_task.await? else {
 6112                    return Ok(None);
 6113                };
 6114
 6115                let code_lens_actions = join_all(responses.payload.into_iter().map(|response| {
 6116                    let lsp_store = lsp_store.clone();
 6117                    let buffer = buffer.clone();
 6118                    let cx = cx.clone();
 6119                    async move {
 6120                        (
 6121                            LanguageServerId::from_proto(response.server_id),
 6122                            GetCodeLens
 6123                                .response_from_proto(response.response, lsp_store, buffer, cx)
 6124                                .await,
 6125                        )
 6126                    }
 6127                }))
 6128                .await;
 6129
 6130                let mut has_errors = false;
 6131                let code_lens_actions = code_lens_actions
 6132                    .into_iter()
 6133                    .filter_map(|(server_id, code_lens)| match code_lens {
 6134                        Ok(code_lens) => Some((server_id, code_lens)),
 6135                        Err(e) => {
 6136                            has_errors = true;
 6137                            log::error!("{e:#}");
 6138                            None
 6139                        }
 6140                    })
 6141                    .collect::<HashMap<_, _>>();
 6142                anyhow::ensure!(
 6143                    !has_errors || !code_lens_actions.is_empty(),
 6144                    "Failed to fetch code lens"
 6145                );
 6146                Ok(Some(code_lens_actions))
 6147            })
 6148        } else {
 6149            let code_lens_actions_task =
 6150                self.request_multiple_lsp_locally(buffer, None::<usize>, GetCodeLens, cx);
 6151            cx.background_spawn(async move {
 6152                Ok(Some(code_lens_actions_task.await.into_iter().collect()))
 6153            })
 6154        }
 6155    }
 6156
 6157    #[inline(never)]
 6158    pub fn completions(
 6159        &self,
 6160        buffer: &Entity<Buffer>,
 6161        position: PointUtf16,
 6162        context: CompletionContext,
 6163        cx: &mut Context<Self>,
 6164    ) -> Task<Result<Vec<CompletionResponse>>> {
 6165        let language_registry = self.languages.clone();
 6166
 6167        if let Some((upstream_client, project_id)) = self.upstream_client() {
 6168            let snapshot = buffer.read(cx).snapshot();
 6169            let offset = position.to_offset(&snapshot);
 6170            let scope = snapshot.language_scope_at(offset);
 6171            let capable_lsps = self.all_capable_for_proto_request(
 6172                buffer,
 6173                |server_name, capabilities| {
 6174                    capabilities.completion_provider.is_some()
 6175                        && scope
 6176                            .as_ref()
 6177                            .map(|scope| scope.language_allowed(server_name))
 6178                            .unwrap_or(true)
 6179                },
 6180                cx,
 6181            );
 6182            if capable_lsps.is_empty() {
 6183                return Task::ready(Ok(Vec::new()));
 6184            }
 6185
 6186            let language = buffer.read(cx).language().cloned();
 6187
 6188            // In the future, we should provide project guests with the names of LSP adapters,
 6189            // so that they can use the correct LSP adapter when computing labels. For now,
 6190            // guests just use the first LSP adapter associated with the buffer's language.
 6191            let lsp_adapter = language.as_ref().and_then(|language| {
 6192                language_registry
 6193                    .lsp_adapters(&language.name())
 6194                    .first()
 6195                    .cloned()
 6196            });
 6197
 6198            let buffer = buffer.clone();
 6199
 6200            cx.spawn(async move |this, cx| {
 6201                let requests = join_all(
 6202                    capable_lsps
 6203                        .into_iter()
 6204                        .map(|id| {
 6205                            let request = GetCompletions {
 6206                                position,
 6207                                context: context.clone(),
 6208                                server_id: Some(id),
 6209                            };
 6210                            let buffer = buffer.clone();
 6211                            let language = language.clone();
 6212                            let lsp_adapter = lsp_adapter.clone();
 6213                            let upstream_client = upstream_client.clone();
 6214                            let response = this
 6215                                .update(cx, |this, cx| {
 6216                                    this.send_lsp_proto_request(
 6217                                        buffer,
 6218                                        upstream_client,
 6219                                        project_id,
 6220                                        request,
 6221                                        cx,
 6222                                    )
 6223                                })
 6224                                .log_err();
 6225                            async move {
 6226                                let response = response?.await.log_err()?;
 6227
 6228                                let completions = populate_labels_for_completions(
 6229                                    response.completions,
 6230                                    language,
 6231                                    lsp_adapter,
 6232                                )
 6233                                .await;
 6234
 6235                                Some(CompletionResponse {
 6236                                    completions,
 6237                                    display_options: CompletionDisplayOptions::default(),
 6238                                    is_incomplete: response.is_incomplete,
 6239                                })
 6240                            }
 6241                        })
 6242                        .collect::<Vec<_>>(),
 6243                );
 6244                Ok(requests.await.into_iter().flatten().collect::<Vec<_>>())
 6245            })
 6246        } else if let Some(local) = self.as_local() {
 6247            let snapshot = buffer.read(cx).snapshot();
 6248            let offset = position.to_offset(&snapshot);
 6249            let scope = snapshot.language_scope_at(offset);
 6250            let language = snapshot.language().cloned();
 6251            let completion_settings = language_settings(
 6252                language.as_ref().map(|language| language.name()),
 6253                buffer.read(cx).file(),
 6254                cx,
 6255            )
 6256            .completions
 6257            .clone();
 6258            if !completion_settings.lsp {
 6259                return Task::ready(Ok(Vec::new()));
 6260            }
 6261
 6262            let server_ids: Vec<_> = buffer.update(cx, |buffer, cx| {
 6263                local
 6264                    .language_servers_for_buffer(buffer, cx)
 6265                    .filter(|(_, server)| server.capabilities().completion_provider.is_some())
 6266                    .filter(|(adapter, _)| {
 6267                        scope
 6268                            .as_ref()
 6269                            .map(|scope| scope.language_allowed(&adapter.name))
 6270                            .unwrap_or(true)
 6271                    })
 6272                    .map(|(_, server)| server.server_id())
 6273                    .collect()
 6274            });
 6275
 6276            let buffer = buffer.clone();
 6277            let lsp_timeout = completion_settings.lsp_fetch_timeout_ms;
 6278            let lsp_timeout = if lsp_timeout > 0 {
 6279                Some(Duration::from_millis(lsp_timeout))
 6280            } else {
 6281                None
 6282            };
 6283            cx.spawn(async move |this,  cx| {
 6284                let mut tasks = Vec::with_capacity(server_ids.len());
 6285                this.update(cx, |lsp_store, cx| {
 6286                    for server_id in server_ids {
 6287                        let lsp_adapter = lsp_store.language_server_adapter_for_id(server_id);
 6288                        let lsp_timeout = lsp_timeout
 6289                            .map(|lsp_timeout| cx.background_executor().timer(lsp_timeout));
 6290                        let mut timeout = cx.background_spawn(async move {
 6291                            match lsp_timeout {
 6292                                Some(lsp_timeout) => {
 6293                                    lsp_timeout.await;
 6294                                    true
 6295                                },
 6296                                None => false,
 6297                            }
 6298                        }).fuse();
 6299                        let mut lsp_request = lsp_store.request_lsp(
 6300                            buffer.clone(),
 6301                            LanguageServerToQuery::Other(server_id),
 6302                            GetCompletions {
 6303                                position,
 6304                                context: context.clone(),
 6305                                server_id: Some(server_id),
 6306                            },
 6307                            cx,
 6308                        ).fuse();
 6309                        let new_task = cx.background_spawn(async move {
 6310                            select_biased! {
 6311                                response = lsp_request => anyhow::Ok(Some(response?)),
 6312                                timeout_happened = timeout => {
 6313                                    if timeout_happened {
 6314                                        log::warn!("Fetching completions from server {server_id} timed out, timeout ms: {}", completion_settings.lsp_fetch_timeout_ms);
 6315                                        Ok(None)
 6316                                    } else {
 6317                                        let completions = lsp_request.await?;
 6318                                        Ok(Some(completions))
 6319                                    }
 6320                                },
 6321                            }
 6322                        });
 6323                        tasks.push((lsp_adapter, new_task));
 6324                    }
 6325                })?;
 6326
 6327                let futures = tasks.into_iter().map(async |(lsp_adapter, task)| {
 6328                    let completion_response = task.await.ok()??;
 6329                    let completions = populate_labels_for_completions(
 6330                            completion_response.completions,
 6331                            language.clone(),
 6332                            lsp_adapter,
 6333                        )
 6334                        .await;
 6335                    Some(CompletionResponse {
 6336                        completions,
 6337                        display_options: CompletionDisplayOptions::default(),
 6338                        is_incomplete: completion_response.is_incomplete,
 6339                    })
 6340                });
 6341
 6342                let responses: Vec<Option<CompletionResponse>> = join_all(futures).await;
 6343
 6344                Ok(responses.into_iter().flatten().collect())
 6345            })
 6346        } else {
 6347            Task::ready(Err(anyhow!("No upstream client or local language server")))
 6348        }
 6349    }
 6350
 6351    pub fn resolve_completions(
 6352        &self,
 6353        buffer: Entity<Buffer>,
 6354        completion_indices: Vec<usize>,
 6355        completions: Rc<RefCell<Box<[Completion]>>>,
 6356        cx: &mut Context<Self>,
 6357    ) -> Task<Result<bool>> {
 6358        let client = self.upstream_client();
 6359        let buffer_id = buffer.read(cx).remote_id();
 6360        let buffer_snapshot = buffer.read(cx).snapshot();
 6361
 6362        if !self.check_if_capable_for_proto_request(
 6363            &buffer,
 6364            GetCompletions::can_resolve_completions,
 6365            cx,
 6366        ) {
 6367            return Task::ready(Ok(false));
 6368        }
 6369        cx.spawn(async move |lsp_store, cx| {
 6370            let mut did_resolve = false;
 6371            if let Some((client, project_id)) = client {
 6372                for completion_index in completion_indices {
 6373                    let server_id = {
 6374                        let completion = &completions.borrow()[completion_index];
 6375                        completion.source.server_id()
 6376                    };
 6377                    if let Some(server_id) = server_id {
 6378                        if Self::resolve_completion_remote(
 6379                            project_id,
 6380                            server_id,
 6381                            buffer_id,
 6382                            completions.clone(),
 6383                            completion_index,
 6384                            client.clone(),
 6385                        )
 6386                        .await
 6387                        .log_err()
 6388                        .is_some()
 6389                        {
 6390                            did_resolve = true;
 6391                        }
 6392                    } else {
 6393                        resolve_word_completion(
 6394                            &buffer_snapshot,
 6395                            &mut completions.borrow_mut()[completion_index],
 6396                        );
 6397                    }
 6398                }
 6399            } else {
 6400                for completion_index in completion_indices {
 6401                    let server_id = {
 6402                        let completion = &completions.borrow()[completion_index];
 6403                        completion.source.server_id()
 6404                    };
 6405                    if let Some(server_id) = server_id {
 6406                        let server_and_adapter = lsp_store
 6407                            .read_with(cx, |lsp_store, _| {
 6408                                let server = lsp_store.language_server_for_id(server_id)?;
 6409                                let adapter =
 6410                                    lsp_store.language_server_adapter_for_id(server.server_id())?;
 6411                                Some((server, adapter))
 6412                            })
 6413                            .ok()
 6414                            .flatten();
 6415                        let Some((server, adapter)) = server_and_adapter else {
 6416                            continue;
 6417                        };
 6418
 6419                        let resolved = Self::resolve_completion_local(
 6420                            server,
 6421                            completions.clone(),
 6422                            completion_index,
 6423                        )
 6424                        .await
 6425                        .log_err()
 6426                        .is_some();
 6427                        if resolved {
 6428                            Self::regenerate_completion_labels(
 6429                                adapter,
 6430                                &buffer_snapshot,
 6431                                completions.clone(),
 6432                                completion_index,
 6433                            )
 6434                            .await
 6435                            .log_err();
 6436                            did_resolve = true;
 6437                        }
 6438                    } else {
 6439                        resolve_word_completion(
 6440                            &buffer_snapshot,
 6441                            &mut completions.borrow_mut()[completion_index],
 6442                        );
 6443                    }
 6444                }
 6445            }
 6446
 6447            Ok(did_resolve)
 6448        })
 6449    }
 6450
 6451    async fn resolve_completion_local(
 6452        server: Arc<lsp::LanguageServer>,
 6453        completions: Rc<RefCell<Box<[Completion]>>>,
 6454        completion_index: usize,
 6455    ) -> Result<()> {
 6456        let server_id = server.server_id();
 6457        if !GetCompletions::can_resolve_completions(&server.capabilities()) {
 6458            return Ok(());
 6459        }
 6460
 6461        let request = {
 6462            let completion = &completions.borrow()[completion_index];
 6463            match &completion.source {
 6464                CompletionSource::Lsp {
 6465                    lsp_completion,
 6466                    resolved,
 6467                    server_id: completion_server_id,
 6468                    ..
 6469                } => {
 6470                    if *resolved {
 6471                        return Ok(());
 6472                    }
 6473                    anyhow::ensure!(
 6474                        server_id == *completion_server_id,
 6475                        "server_id mismatch, querying completion resolve for {server_id} but completion server id is {completion_server_id}"
 6476                    );
 6477                    server.request::<lsp::request::ResolveCompletionItem>(*lsp_completion.clone())
 6478                }
 6479                CompletionSource::BufferWord { .. }
 6480                | CompletionSource::Dap { .. }
 6481                | CompletionSource::Custom => {
 6482                    return Ok(());
 6483                }
 6484            }
 6485        };
 6486        let resolved_completion = request
 6487            .await
 6488            .into_response()
 6489            .context("resolve completion")?;
 6490
 6491        // We must not use any data such as sortText, filterText, insertText and textEdit to edit `Completion` since they are not suppose change during resolve.
 6492        // Refer: https://microsoft.github.io/language-server-protocol/specifications/lsp/3.17/specification/#textDocument_completion
 6493
 6494        let mut completions = completions.borrow_mut();
 6495        let completion = &mut completions[completion_index];
 6496        if let CompletionSource::Lsp {
 6497            lsp_completion,
 6498            resolved,
 6499            server_id: completion_server_id,
 6500            ..
 6501        } = &mut completion.source
 6502        {
 6503            if *resolved {
 6504                return Ok(());
 6505            }
 6506            anyhow::ensure!(
 6507                server_id == *completion_server_id,
 6508                "server_id mismatch, applying completion resolve for {server_id} but completion server id is {completion_server_id}"
 6509            );
 6510            **lsp_completion = resolved_completion;
 6511            *resolved = true;
 6512        }
 6513        Ok(())
 6514    }
 6515
 6516    async fn regenerate_completion_labels(
 6517        adapter: Arc<CachedLspAdapter>,
 6518        snapshot: &BufferSnapshot,
 6519        completions: Rc<RefCell<Box<[Completion]>>>,
 6520        completion_index: usize,
 6521    ) -> Result<()> {
 6522        let completion_item = completions.borrow()[completion_index]
 6523            .source
 6524            .lsp_completion(true)
 6525            .map(Cow::into_owned);
 6526        if let Some(lsp_documentation) = completion_item
 6527            .as_ref()
 6528            .and_then(|completion_item| completion_item.documentation.clone())
 6529        {
 6530            let mut completions = completions.borrow_mut();
 6531            let completion = &mut completions[completion_index];
 6532            completion.documentation = Some(lsp_documentation.into());
 6533        } else {
 6534            let mut completions = completions.borrow_mut();
 6535            let completion = &mut completions[completion_index];
 6536            completion.documentation = Some(CompletionDocumentation::Undocumented);
 6537        }
 6538
 6539        let mut new_label = match completion_item {
 6540            Some(completion_item) => {
 6541                // Some language servers always return `detail` lazily via resolve, regardless of
 6542                // the resolvable properties Zed advertises. Regenerate labels here to handle this.
 6543                // See: https://github.com/yioneko/vtsls/issues/213
 6544                let language = snapshot.language();
 6545                match language {
 6546                    Some(language) => {
 6547                        adapter
 6548                            .labels_for_completions(
 6549                                std::slice::from_ref(&completion_item),
 6550                                language,
 6551                            )
 6552                            .await?
 6553                    }
 6554                    None => Vec::new(),
 6555                }
 6556                .pop()
 6557                .flatten()
 6558                .unwrap_or_else(|| {
 6559                    CodeLabel::fallback_for_completion(
 6560                        &completion_item,
 6561                        language.map(|language| language.as_ref()),
 6562                    )
 6563                })
 6564            }
 6565            None => CodeLabel::plain(
 6566                completions.borrow()[completion_index].new_text.clone(),
 6567                None,
 6568            ),
 6569        };
 6570        ensure_uniform_list_compatible_label(&mut new_label);
 6571
 6572        let mut completions = completions.borrow_mut();
 6573        let completion = &mut completions[completion_index];
 6574        if completion.label.filter_text() == new_label.filter_text() {
 6575            completion.label = new_label;
 6576        } else {
 6577            log::error!(
 6578                "Resolved completion changed display label from {} to {}. \
 6579                 Refusing to apply this because it changes the fuzzy match text from {} to {}",
 6580                completion.label.text(),
 6581                new_label.text(),
 6582                completion.label.filter_text(),
 6583                new_label.filter_text()
 6584            );
 6585        }
 6586
 6587        Ok(())
 6588    }
 6589
 6590    async fn resolve_completion_remote(
 6591        project_id: u64,
 6592        server_id: LanguageServerId,
 6593        buffer_id: BufferId,
 6594        completions: Rc<RefCell<Box<[Completion]>>>,
 6595        completion_index: usize,
 6596        client: AnyProtoClient,
 6597    ) -> Result<()> {
 6598        let lsp_completion = {
 6599            let completion = &completions.borrow()[completion_index];
 6600            match &completion.source {
 6601                CompletionSource::Lsp {
 6602                    lsp_completion,
 6603                    resolved,
 6604                    server_id: completion_server_id,
 6605                    ..
 6606                } => {
 6607                    anyhow::ensure!(
 6608                        server_id == *completion_server_id,
 6609                        "remote server_id mismatch, querying completion resolve for {server_id} but completion server id is {completion_server_id}"
 6610                    );
 6611                    if *resolved {
 6612                        return Ok(());
 6613                    }
 6614                    serde_json::to_string(lsp_completion).unwrap().into_bytes()
 6615                }
 6616                CompletionSource::Custom
 6617                | CompletionSource::Dap { .. }
 6618                | CompletionSource::BufferWord { .. } => {
 6619                    return Ok(());
 6620                }
 6621            }
 6622        };
 6623        let request = proto::ResolveCompletionDocumentation {
 6624            project_id,
 6625            language_server_id: server_id.0 as u64,
 6626            lsp_completion,
 6627            buffer_id: buffer_id.into(),
 6628        };
 6629
 6630        let response = client
 6631            .request(request)
 6632            .await
 6633            .context("completion documentation resolve proto request")?;
 6634        let resolved_lsp_completion = serde_json::from_slice(&response.lsp_completion)?;
 6635
 6636        let documentation = if response.documentation.is_empty() {
 6637            CompletionDocumentation::Undocumented
 6638        } else if response.documentation_is_markdown {
 6639            CompletionDocumentation::MultiLineMarkdown(response.documentation.into())
 6640        } else if response.documentation.lines().count() <= 1 {
 6641            CompletionDocumentation::SingleLine(response.documentation.into())
 6642        } else {
 6643            CompletionDocumentation::MultiLinePlainText(response.documentation.into())
 6644        };
 6645
 6646        let mut completions = completions.borrow_mut();
 6647        let completion = &mut completions[completion_index];
 6648        completion.documentation = Some(documentation);
 6649        if let CompletionSource::Lsp {
 6650            insert_range,
 6651            lsp_completion,
 6652            resolved,
 6653            server_id: completion_server_id,
 6654            lsp_defaults: _,
 6655        } = &mut completion.source
 6656        {
 6657            let completion_insert_range = response
 6658                .old_insert_start
 6659                .and_then(deserialize_anchor)
 6660                .zip(response.old_insert_end.and_then(deserialize_anchor));
 6661            *insert_range = completion_insert_range.map(|(start, end)| start..end);
 6662
 6663            if *resolved {
 6664                return Ok(());
 6665            }
 6666            anyhow::ensure!(
 6667                server_id == *completion_server_id,
 6668                "remote server_id mismatch, applying completion resolve for {server_id} but completion server id is {completion_server_id}"
 6669            );
 6670            **lsp_completion = resolved_lsp_completion;
 6671            *resolved = true;
 6672        }
 6673
 6674        let replace_range = response
 6675            .old_replace_start
 6676            .and_then(deserialize_anchor)
 6677            .zip(response.old_replace_end.and_then(deserialize_anchor));
 6678        if let Some((old_replace_start, old_replace_end)) = replace_range
 6679            && !response.new_text.is_empty()
 6680        {
 6681            completion.new_text = response.new_text;
 6682            completion.replace_range = old_replace_start..old_replace_end;
 6683        }
 6684
 6685        Ok(())
 6686    }
 6687
 6688    pub fn apply_additional_edits_for_completion(
 6689        &self,
 6690        buffer_handle: Entity<Buffer>,
 6691        completions: Rc<RefCell<Box<[Completion]>>>,
 6692        completion_index: usize,
 6693        push_to_history: bool,
 6694        cx: &mut Context<Self>,
 6695    ) -> Task<Result<Option<Transaction>>> {
 6696        if let Some((client, project_id)) = self.upstream_client() {
 6697            let buffer = buffer_handle.read(cx);
 6698            let buffer_id = buffer.remote_id();
 6699            cx.spawn(async move |_, cx| {
 6700                let request = {
 6701                    let completion = completions.borrow()[completion_index].clone();
 6702                    proto::ApplyCompletionAdditionalEdits {
 6703                        project_id,
 6704                        buffer_id: buffer_id.into(),
 6705                        completion: Some(Self::serialize_completion(&CoreCompletion {
 6706                            replace_range: completion.replace_range,
 6707                            new_text: completion.new_text,
 6708                            source: completion.source,
 6709                        })),
 6710                    }
 6711                };
 6712
 6713                if let Some(transaction) = client.request(request).await?.transaction {
 6714                    let transaction = language::proto::deserialize_transaction(transaction)?;
 6715                    buffer_handle
 6716                        .update(cx, |buffer, _| {
 6717                            buffer.wait_for_edits(transaction.edit_ids.iter().copied())
 6718                        })?
 6719                        .await?;
 6720                    if push_to_history {
 6721                        buffer_handle.update(cx, |buffer, _| {
 6722                            buffer.push_transaction(transaction.clone(), Instant::now());
 6723                            buffer.finalize_last_transaction();
 6724                        })?;
 6725                    }
 6726                    Ok(Some(transaction))
 6727                } else {
 6728                    Ok(None)
 6729                }
 6730            })
 6731        } else {
 6732            let Some(server) = buffer_handle.update(cx, |buffer, cx| {
 6733                let completion = &completions.borrow()[completion_index];
 6734                let server_id = completion.source.server_id()?;
 6735                Some(
 6736                    self.language_server_for_local_buffer(buffer, server_id, cx)?
 6737                        .1
 6738                        .clone(),
 6739                )
 6740            }) else {
 6741                return Task::ready(Ok(None));
 6742            };
 6743
 6744            cx.spawn(async move |this, cx| {
 6745                Self::resolve_completion_local(
 6746                    server.clone(),
 6747                    completions.clone(),
 6748                    completion_index,
 6749                )
 6750                .await
 6751                .context("resolving completion")?;
 6752                let completion = completions.borrow()[completion_index].clone();
 6753                let additional_text_edits = completion
 6754                    .source
 6755                    .lsp_completion(true)
 6756                    .as_ref()
 6757                    .and_then(|lsp_completion| lsp_completion.additional_text_edits.clone());
 6758                if let Some(edits) = additional_text_edits {
 6759                    let edits = this
 6760                        .update(cx, |this, cx| {
 6761                            this.as_local_mut().unwrap().edits_from_lsp(
 6762                                &buffer_handle,
 6763                                edits,
 6764                                server.server_id(),
 6765                                None,
 6766                                cx,
 6767                            )
 6768                        })?
 6769                        .await?;
 6770
 6771                    buffer_handle.update(cx, |buffer, cx| {
 6772                        buffer.finalize_last_transaction();
 6773                        buffer.start_transaction();
 6774
 6775                        for (range, text) in edits {
 6776                            let primary = &completion.replace_range;
 6777
 6778                            // Special case: if both ranges start at the very beginning of the file (line 0, column 0),
 6779                            // and the primary completion is just an insertion (empty range), then this is likely
 6780                            // an auto-import scenario and should not be considered overlapping
 6781                            // https://github.com/zed-industries/zed/issues/26136
 6782                            let is_file_start_auto_import = {
 6783                                let snapshot = buffer.snapshot();
 6784                                let primary_start_point = primary.start.to_point(&snapshot);
 6785                                let range_start_point = range.start.to_point(&snapshot);
 6786
 6787                                let result = primary_start_point.row == 0
 6788                                    && primary_start_point.column == 0
 6789                                    && range_start_point.row == 0
 6790                                    && range_start_point.column == 0;
 6791
 6792                                result
 6793                            };
 6794
 6795                            let has_overlap = if is_file_start_auto_import {
 6796                                false
 6797                            } else {
 6798                                let start_within = primary.start.cmp(&range.start, buffer).is_le()
 6799                                    && primary.end.cmp(&range.start, buffer).is_ge();
 6800                                let end_within = range.start.cmp(&primary.end, buffer).is_le()
 6801                                    && range.end.cmp(&primary.end, buffer).is_ge();
 6802                                let result = start_within || end_within;
 6803                                result
 6804                            };
 6805
 6806                            //Skip additional edits which overlap with the primary completion edit
 6807                            //https://github.com/zed-industries/zed/pull/1871
 6808                            if !has_overlap {
 6809                                buffer.edit([(range, text)], None, cx);
 6810                            }
 6811                        }
 6812
 6813                        let transaction = if buffer.end_transaction(cx).is_some() {
 6814                            let transaction = buffer.finalize_last_transaction().unwrap().clone();
 6815                            if !push_to_history {
 6816                                buffer.forget_transaction(transaction.id);
 6817                            }
 6818                            Some(transaction)
 6819                        } else {
 6820                            None
 6821                        };
 6822                        Ok(transaction)
 6823                    })?
 6824                } else {
 6825                    Ok(None)
 6826                }
 6827            })
 6828        }
 6829    }
 6830
 6831    pub fn pull_diagnostics(
 6832        &mut self,
 6833        buffer: Entity<Buffer>,
 6834        cx: &mut Context<Self>,
 6835    ) -> Task<Result<Option<Vec<LspPullDiagnostics>>>> {
 6836        let buffer_id = buffer.read(cx).remote_id();
 6837
 6838        if let Some((client, upstream_project_id)) = self.upstream_client() {
 6839            let mut suitable_capabilities = None;
 6840            // Are we capable for proto request?
 6841            let any_server_has_diagnostics_provider = self.check_if_capable_for_proto_request(
 6842                &buffer,
 6843                |capabilities| {
 6844                    if let Some(caps) = &capabilities.diagnostic_provider {
 6845                        suitable_capabilities = Some(caps.clone());
 6846                        true
 6847                    } else {
 6848                        false
 6849                    }
 6850                },
 6851                cx,
 6852            );
 6853            // We don't really care which caps are passed into the request, as they're ignored by RPC anyways.
 6854            let Some(dynamic_caps) = suitable_capabilities else {
 6855                return Task::ready(Ok(None));
 6856            };
 6857            assert!(any_server_has_diagnostics_provider);
 6858
 6859            let identifier = buffer_diagnostic_identifier(&dynamic_caps);
 6860            let request = GetDocumentDiagnostics {
 6861                previous_result_id: None,
 6862                identifier,
 6863                registration_id: None,
 6864            };
 6865            let request_task = client.request_lsp(
 6866                upstream_project_id,
 6867                None,
 6868                LSP_REQUEST_TIMEOUT,
 6869                cx.background_executor().clone(),
 6870                request.to_proto(upstream_project_id, buffer.read(cx)),
 6871            );
 6872            cx.background_spawn(async move {
 6873                // Proto requests cause the diagnostics to be pulled from language server(s) on the local side
 6874                // and then, buffer state updated with the diagnostics received, which will be later propagated to the client.
 6875                // Do not attempt to further process the dummy responses here.
 6876                let _response = request_task.await?;
 6877                Ok(None)
 6878            })
 6879        } else {
 6880            let servers = buffer.update(cx, |buffer, cx| {
 6881                self.running_language_servers_for_local_buffer(buffer, cx)
 6882                    .map(|(_, server)| server.clone())
 6883                    .collect::<Vec<_>>()
 6884            });
 6885
 6886            let pull_diagnostics = servers
 6887                .into_iter()
 6888                .flat_map(|server| {
 6889                    let result = maybe!({
 6890                        let local = self.as_local()?;
 6891                        let server_id = server.server_id();
 6892                        let providers_with_identifiers = local
 6893                            .language_server_dynamic_registrations
 6894                            .get(&server_id)
 6895                            .into_iter()
 6896                            .flat_map(|registrations| registrations.diagnostics.clone())
 6897                            .collect::<Vec<_>>();
 6898                        Some(
 6899                            providers_with_identifiers
 6900                                .into_iter()
 6901                                .map(|(registration_id, dynamic_caps)| {
 6902                                    let identifier = buffer_diagnostic_identifier(&dynamic_caps);
 6903                                    let registration_id = registration_id.map(SharedString::from);
 6904                                    let result_id = self.result_id_for_buffer_pull(
 6905                                        server_id,
 6906                                        buffer_id,
 6907                                        &registration_id,
 6908                                        cx,
 6909                                    );
 6910                                    self.request_lsp(
 6911                                        buffer.clone(),
 6912                                        LanguageServerToQuery::Other(server_id),
 6913                                        GetDocumentDiagnostics {
 6914                                            previous_result_id: result_id,
 6915                                            registration_id,
 6916                                            identifier,
 6917                                        },
 6918                                        cx,
 6919                                    )
 6920                                })
 6921                                .collect::<Vec<_>>(),
 6922                        )
 6923                    });
 6924
 6925                    result.unwrap_or_default()
 6926                })
 6927                .collect::<Vec<_>>();
 6928
 6929            cx.background_spawn(async move {
 6930                let mut responses = Vec::new();
 6931                for diagnostics in join_all(pull_diagnostics).await {
 6932                    responses.extend(diagnostics?);
 6933                }
 6934                Ok(Some(responses))
 6935            })
 6936        }
 6937    }
 6938
 6939    pub fn applicable_inlay_chunks(
 6940        &mut self,
 6941        buffer: &Entity<Buffer>,
 6942        ranges: &[Range<text::Anchor>],
 6943        cx: &mut Context<Self>,
 6944    ) -> Vec<Range<BufferRow>> {
 6945        let buffer_snapshot = buffer.read(cx).snapshot();
 6946        let ranges = ranges
 6947            .iter()
 6948            .map(|range| range.to_point(&buffer_snapshot))
 6949            .collect::<Vec<_>>();
 6950
 6951        self.latest_lsp_data(buffer, cx)
 6952            .inlay_hints
 6953            .applicable_chunks(ranges.as_slice())
 6954            .map(|chunk| chunk.row_range())
 6955            .collect()
 6956    }
 6957
 6958    pub fn invalidate_inlay_hints<'a>(
 6959        &'a mut self,
 6960        for_buffers: impl IntoIterator<Item = &'a BufferId> + 'a,
 6961    ) {
 6962        for buffer_id in for_buffers {
 6963            if let Some(lsp_data) = self.lsp_data.get_mut(buffer_id) {
 6964                lsp_data.inlay_hints.clear();
 6965            }
 6966        }
 6967    }
 6968
 6969    pub fn inlay_hints(
 6970        &mut self,
 6971        invalidate: InvalidationStrategy,
 6972        buffer: Entity<Buffer>,
 6973        ranges: Vec<Range<text::Anchor>>,
 6974        known_chunks: Option<(clock::Global, HashSet<Range<BufferRow>>)>,
 6975        cx: &mut Context<Self>,
 6976    ) -> HashMap<Range<BufferRow>, Task<Result<CacheInlayHints>>> {
 6977        let next_hint_id = self.next_hint_id.clone();
 6978        let lsp_data = self.latest_lsp_data(&buffer, cx);
 6979        let query_version = lsp_data.buffer_version.clone();
 6980        let mut lsp_refresh_requested = false;
 6981        let for_server = if let InvalidationStrategy::RefreshRequested {
 6982            server_id,
 6983            request_id,
 6984        } = invalidate
 6985        {
 6986            let invalidated = lsp_data
 6987                .inlay_hints
 6988                .invalidate_for_server_refresh(server_id, request_id);
 6989            lsp_refresh_requested = invalidated;
 6990            Some(server_id)
 6991        } else {
 6992            None
 6993        };
 6994        let existing_inlay_hints = &mut lsp_data.inlay_hints;
 6995        let known_chunks = known_chunks
 6996            .filter(|(known_version, _)| !lsp_data.buffer_version.changed_since(known_version))
 6997            .map(|(_, known_chunks)| known_chunks)
 6998            .unwrap_or_default();
 6999
 7000        let buffer_snapshot = buffer.read(cx).snapshot();
 7001        let ranges = ranges
 7002            .iter()
 7003            .map(|range| range.to_point(&buffer_snapshot))
 7004            .collect::<Vec<_>>();
 7005
 7006        let mut hint_fetch_tasks = Vec::new();
 7007        let mut cached_inlay_hints = None;
 7008        let mut ranges_to_query = None;
 7009        let applicable_chunks = existing_inlay_hints
 7010            .applicable_chunks(ranges.as_slice())
 7011            .filter(|chunk| !known_chunks.contains(&chunk.row_range()))
 7012            .collect::<Vec<_>>();
 7013        if applicable_chunks.is_empty() {
 7014            return HashMap::default();
 7015        }
 7016
 7017        for row_chunk in applicable_chunks {
 7018            match (
 7019                existing_inlay_hints
 7020                    .cached_hints(&row_chunk)
 7021                    .filter(|_| !lsp_refresh_requested)
 7022                    .cloned(),
 7023                existing_inlay_hints
 7024                    .fetched_hints(&row_chunk)
 7025                    .as_ref()
 7026                    .filter(|_| !lsp_refresh_requested)
 7027                    .cloned(),
 7028            ) {
 7029                (None, None) => {
 7030                    let chunk_range = row_chunk.anchor_range();
 7031                    ranges_to_query
 7032                        .get_or_insert_with(Vec::new)
 7033                        .push((row_chunk, chunk_range));
 7034                }
 7035                (None, Some(fetched_hints)) => hint_fetch_tasks.push((row_chunk, fetched_hints)),
 7036                (Some(cached_hints), None) => {
 7037                    for (server_id, cached_hints) in cached_hints {
 7038                        if for_server.is_none_or(|for_server| for_server == server_id) {
 7039                            cached_inlay_hints
 7040                                .get_or_insert_with(HashMap::default)
 7041                                .entry(row_chunk.row_range())
 7042                                .or_insert_with(HashMap::default)
 7043                                .entry(server_id)
 7044                                .or_insert_with(Vec::new)
 7045                                .extend(cached_hints);
 7046                        }
 7047                    }
 7048                }
 7049                (Some(cached_hints), Some(fetched_hints)) => {
 7050                    hint_fetch_tasks.push((row_chunk, fetched_hints));
 7051                    for (server_id, cached_hints) in cached_hints {
 7052                        if for_server.is_none_or(|for_server| for_server == server_id) {
 7053                            cached_inlay_hints
 7054                                .get_or_insert_with(HashMap::default)
 7055                                .entry(row_chunk.row_range())
 7056                                .or_insert_with(HashMap::default)
 7057                                .entry(server_id)
 7058                                .or_insert_with(Vec::new)
 7059                                .extend(cached_hints);
 7060                        }
 7061                    }
 7062                }
 7063            }
 7064        }
 7065
 7066        if hint_fetch_tasks.is_empty()
 7067            && ranges_to_query
 7068                .as_ref()
 7069                .is_none_or(|ranges| ranges.is_empty())
 7070            && let Some(cached_inlay_hints) = cached_inlay_hints
 7071        {
 7072            cached_inlay_hints
 7073                .into_iter()
 7074                .map(|(row_chunk, hints)| (row_chunk, Task::ready(Ok(hints))))
 7075                .collect()
 7076        } else {
 7077            for (chunk, range_to_query) in ranges_to_query.into_iter().flatten() {
 7078                let next_hint_id = next_hint_id.clone();
 7079                let buffer = buffer.clone();
 7080                let query_version = query_version.clone();
 7081                let new_inlay_hints = cx
 7082                    .spawn(async move |lsp_store, cx| {
 7083                        let new_fetch_task = lsp_store.update(cx, |lsp_store, cx| {
 7084                            lsp_store.fetch_inlay_hints(for_server, &buffer, range_to_query, cx)
 7085                        })?;
 7086                        new_fetch_task
 7087                            .await
 7088                            .and_then(|new_hints_by_server| {
 7089                                lsp_store.update(cx, |lsp_store, cx| {
 7090                                    let lsp_data = lsp_store.latest_lsp_data(&buffer, cx);
 7091                                    let update_cache = lsp_data.buffer_version == query_version;
 7092                                    if new_hints_by_server.is_empty() {
 7093                                        if update_cache {
 7094                                            lsp_data.inlay_hints.invalidate_for_chunk(chunk);
 7095                                        }
 7096                                        HashMap::default()
 7097                                    } else {
 7098                                        new_hints_by_server
 7099                                            .into_iter()
 7100                                            .map(|(server_id, new_hints)| {
 7101                                                let new_hints = new_hints
 7102                                                    .into_iter()
 7103                                                    .map(|new_hint| {
 7104                                                        (
 7105                                                            InlayId::Hint(next_hint_id.fetch_add(
 7106                                                                1,
 7107                                                                atomic::Ordering::AcqRel,
 7108                                                            )),
 7109                                                            new_hint,
 7110                                                        )
 7111                                                    })
 7112                                                    .collect::<Vec<_>>();
 7113                                                if update_cache {
 7114                                                    lsp_data.inlay_hints.insert_new_hints(
 7115                                                        chunk,
 7116                                                        server_id,
 7117                                                        new_hints.clone(),
 7118                                                    );
 7119                                                }
 7120                                                (server_id, new_hints)
 7121                                            })
 7122                                            .collect()
 7123                                    }
 7124                                })
 7125                            })
 7126                            .map_err(Arc::new)
 7127                    })
 7128                    .shared();
 7129
 7130                let fetch_task = lsp_data.inlay_hints.fetched_hints(&chunk);
 7131                *fetch_task = Some(new_inlay_hints.clone());
 7132                hint_fetch_tasks.push((chunk, new_inlay_hints));
 7133            }
 7134
 7135            cached_inlay_hints
 7136                .unwrap_or_default()
 7137                .into_iter()
 7138                .map(|(row_chunk, hints)| (row_chunk, Task::ready(Ok(hints))))
 7139                .chain(hint_fetch_tasks.into_iter().map(|(chunk, hints_fetch)| {
 7140                    (
 7141                        chunk.row_range(),
 7142                        cx.spawn(async move |_, _| {
 7143                            hints_fetch.await.map_err(|e| {
 7144                                if e.error_code() != ErrorCode::Internal {
 7145                                    anyhow!(e.error_code())
 7146                                } else {
 7147                                    anyhow!("{e:#}")
 7148                                }
 7149                            })
 7150                        }),
 7151                    )
 7152                }))
 7153                .collect()
 7154        }
 7155    }
 7156
 7157    fn fetch_inlay_hints(
 7158        &mut self,
 7159        for_server: Option<LanguageServerId>,
 7160        buffer: &Entity<Buffer>,
 7161        range: Range<Anchor>,
 7162        cx: &mut Context<Self>,
 7163    ) -> Task<Result<HashMap<LanguageServerId, Vec<InlayHint>>>> {
 7164        let request = InlayHints {
 7165            range: range.clone(),
 7166        };
 7167        if let Some((upstream_client, project_id)) = self.upstream_client() {
 7168            if !self.is_capable_for_proto_request(buffer, &request, cx) {
 7169                return Task::ready(Ok(HashMap::default()));
 7170            }
 7171            let request_task = upstream_client.request_lsp(
 7172                project_id,
 7173                for_server.map(|id| id.to_proto()),
 7174                LSP_REQUEST_TIMEOUT,
 7175                cx.background_executor().clone(),
 7176                request.to_proto(project_id, buffer.read(cx)),
 7177            );
 7178            let buffer = buffer.clone();
 7179            cx.spawn(async move |weak_lsp_store, cx| {
 7180                let Some(lsp_store) = weak_lsp_store.upgrade() else {
 7181                    return Ok(HashMap::default());
 7182                };
 7183                let Some(responses) = request_task.await? else {
 7184                    return Ok(HashMap::default());
 7185                };
 7186
 7187                let inlay_hints = join_all(responses.payload.into_iter().map(|response| {
 7188                    let lsp_store = lsp_store.clone();
 7189                    let buffer = buffer.clone();
 7190                    let cx = cx.clone();
 7191                    let request = request.clone();
 7192                    async move {
 7193                        (
 7194                            LanguageServerId::from_proto(response.server_id),
 7195                            request
 7196                                .response_from_proto(response.response, lsp_store, buffer, cx)
 7197                                .await,
 7198                        )
 7199                    }
 7200                }))
 7201                .await;
 7202
 7203                let buffer_snapshot = buffer.read_with(cx, |buffer, _| buffer.snapshot())?;
 7204                let mut has_errors = false;
 7205                let inlay_hints = inlay_hints
 7206                    .into_iter()
 7207                    .filter_map(|(server_id, inlay_hints)| match inlay_hints {
 7208                        Ok(inlay_hints) => Some((server_id, inlay_hints)),
 7209                        Err(e) => {
 7210                            has_errors = true;
 7211                            log::error!("{e:#}");
 7212                            None
 7213                        }
 7214                    })
 7215                    .map(|(server_id, mut new_hints)| {
 7216                        new_hints.retain(|hint| {
 7217                            hint.position.is_valid(&buffer_snapshot)
 7218                                && range.start.is_valid(&buffer_snapshot)
 7219                                && range.end.is_valid(&buffer_snapshot)
 7220                                && hint.position.cmp(&range.start, &buffer_snapshot).is_ge()
 7221                                && hint.position.cmp(&range.end, &buffer_snapshot).is_lt()
 7222                        });
 7223                        (server_id, new_hints)
 7224                    })
 7225                    .collect::<HashMap<_, _>>();
 7226                anyhow::ensure!(
 7227                    !has_errors || !inlay_hints.is_empty(),
 7228                    "Failed to fetch inlay hints"
 7229                );
 7230                Ok(inlay_hints)
 7231            })
 7232        } else {
 7233            let inlay_hints_task = match for_server {
 7234                Some(server_id) => {
 7235                    let server_task = self.request_lsp(
 7236                        buffer.clone(),
 7237                        LanguageServerToQuery::Other(server_id),
 7238                        request,
 7239                        cx,
 7240                    );
 7241                    cx.background_spawn(async move {
 7242                        let mut responses = Vec::new();
 7243                        match server_task.await {
 7244                            Ok(response) => responses.push((server_id, response)),
 7245                            // rust-analyzer likes to error with this when its still loading up
 7246                            Err(e) if format!("{e:#}").ends_with("content modified") => (),
 7247                            Err(e) => log::error!(
 7248                                "Error handling response for inlay hints request: {e:#}"
 7249                            ),
 7250                        }
 7251                        responses
 7252                    })
 7253                }
 7254                None => self.request_multiple_lsp_locally(buffer, None::<usize>, request, cx),
 7255            };
 7256            let buffer_snapshot = buffer.read_with(cx, |buffer, _| buffer.snapshot());
 7257            cx.background_spawn(async move {
 7258                Ok(inlay_hints_task
 7259                    .await
 7260                    .into_iter()
 7261                    .map(|(server_id, mut new_hints)| {
 7262                        new_hints.retain(|hint| {
 7263                            hint.position.is_valid(&buffer_snapshot)
 7264                                && range.start.is_valid(&buffer_snapshot)
 7265                                && range.end.is_valid(&buffer_snapshot)
 7266                                && hint.position.cmp(&range.start, &buffer_snapshot).is_ge()
 7267                                && hint.position.cmp(&range.end, &buffer_snapshot).is_lt()
 7268                        });
 7269                        (server_id, new_hints)
 7270                    })
 7271                    .collect())
 7272            })
 7273        }
 7274    }
 7275
 7276    fn diagnostic_registration_exists(
 7277        &self,
 7278        server_id: LanguageServerId,
 7279        registration_id: &Option<SharedString>,
 7280    ) -> bool {
 7281        let Some(local) = self.as_local() else {
 7282            return false;
 7283        };
 7284        let Some(registrations) = local.language_server_dynamic_registrations.get(&server_id)
 7285        else {
 7286            return false;
 7287        };
 7288        let registration_key = registration_id.as_ref().map(|s| s.to_string());
 7289        registrations.diagnostics.contains_key(&registration_key)
 7290    }
 7291
 7292    pub fn pull_diagnostics_for_buffer(
 7293        &mut self,
 7294        buffer: Entity<Buffer>,
 7295        cx: &mut Context<Self>,
 7296    ) -> Task<anyhow::Result<()>> {
 7297        let diagnostics = self.pull_diagnostics(buffer, cx);
 7298        cx.spawn(async move |lsp_store, cx| {
 7299            let Some(diagnostics) = diagnostics.await.context("pulling diagnostics")? else {
 7300                return Ok(());
 7301            };
 7302            lsp_store.update(cx, |lsp_store, cx| {
 7303                if lsp_store.as_local().is_none() {
 7304                    return;
 7305                }
 7306
 7307                let mut unchanged_buffers = HashMap::default();
 7308                let server_diagnostics_updates = diagnostics
 7309                    .into_iter()
 7310                    .filter_map(|diagnostics_set| match diagnostics_set {
 7311                        LspPullDiagnostics::Response {
 7312                            server_id,
 7313                            uri,
 7314                            diagnostics,
 7315                            registration_id,
 7316                        } => Some((server_id, uri, diagnostics, registration_id)),
 7317                        LspPullDiagnostics::Default => None,
 7318                    })
 7319                    .filter(|(server_id, _, _, registration_id)| {
 7320                        lsp_store.diagnostic_registration_exists(*server_id, registration_id)
 7321                    })
 7322                    .fold(
 7323                        HashMap::default(),
 7324                        |mut acc, (server_id, uri, diagnostics, new_registration_id)| {
 7325                            let (result_id, diagnostics) = match diagnostics {
 7326                                PulledDiagnostics::Unchanged { result_id } => {
 7327                                    unchanged_buffers
 7328                                        .entry(new_registration_id.clone())
 7329                                        .or_insert_with(HashSet::default)
 7330                                        .insert(uri.clone());
 7331                                    (Some(result_id), Vec::new())
 7332                                }
 7333                                PulledDiagnostics::Changed {
 7334                                    result_id,
 7335                                    diagnostics,
 7336                                } => (result_id, diagnostics),
 7337                            };
 7338                            let disk_based_sources = Cow::Owned(
 7339                                lsp_store
 7340                                    .language_server_adapter_for_id(server_id)
 7341                                    .as_ref()
 7342                                    .map(|adapter| adapter.disk_based_diagnostic_sources.as_slice())
 7343                                    .unwrap_or(&[])
 7344                                    .to_vec(),
 7345                            );
 7346                            acc.entry(server_id)
 7347                                .or_insert_with(HashMap::default)
 7348                                .entry(new_registration_id.clone())
 7349                                .or_insert_with(Vec::new)
 7350                                .push(DocumentDiagnosticsUpdate {
 7351                                    server_id,
 7352                                    diagnostics: lsp::PublishDiagnosticsParams {
 7353                                        uri,
 7354                                        diagnostics,
 7355                                        version: None,
 7356                                    },
 7357                                    result_id,
 7358                                    disk_based_sources,
 7359                                    registration_id: new_registration_id,
 7360                                });
 7361                            acc
 7362                        },
 7363                    );
 7364
 7365                for diagnostic_updates in server_diagnostics_updates.into_values() {
 7366                    for (registration_id, diagnostic_updates) in diagnostic_updates {
 7367                        lsp_store
 7368                            .merge_lsp_diagnostics(
 7369                                DiagnosticSourceKind::Pulled,
 7370                                diagnostic_updates,
 7371                                |document_uri, old_diagnostic, _| match old_diagnostic.source_kind {
 7372                                    DiagnosticSourceKind::Pulled => {
 7373                                        old_diagnostic.registration_id != registration_id
 7374                                            || unchanged_buffers
 7375                                                .get(&old_diagnostic.registration_id)
 7376                                                .is_some_and(|unchanged_buffers| {
 7377                                                    unchanged_buffers.contains(&document_uri)
 7378                                                })
 7379                                    }
 7380                                    DiagnosticSourceKind::Other | DiagnosticSourceKind::Pushed => {
 7381                                        true
 7382                                    }
 7383                                },
 7384                                cx,
 7385                            )
 7386                            .log_err();
 7387                    }
 7388                }
 7389            })
 7390        })
 7391    }
 7392
 7393    pub fn document_colors(
 7394        &mut self,
 7395        known_cache_version: Option<usize>,
 7396        buffer: Entity<Buffer>,
 7397        cx: &mut Context<Self>,
 7398    ) -> Option<DocumentColorTask> {
 7399        let version_queried_for = buffer.read(cx).version();
 7400        let buffer_id = buffer.read(cx).remote_id();
 7401
 7402        let current_language_servers = self.as_local().map(|local| {
 7403            local
 7404                .buffers_opened_in_servers
 7405                .get(&buffer_id)
 7406                .cloned()
 7407                .unwrap_or_default()
 7408        });
 7409
 7410        if let Some(lsp_data) = self.current_lsp_data(buffer_id) {
 7411            if let Some(cached_colors) = &lsp_data.document_colors {
 7412                if !version_queried_for.changed_since(&lsp_data.buffer_version) {
 7413                    let has_different_servers =
 7414                        current_language_servers.is_some_and(|current_language_servers| {
 7415                            current_language_servers
 7416                                != cached_colors.colors.keys().copied().collect()
 7417                        });
 7418                    if !has_different_servers {
 7419                        let cache_version = cached_colors.cache_version;
 7420                        if Some(cache_version) == known_cache_version {
 7421                            return None;
 7422                        } else {
 7423                            return Some(
 7424                                Task::ready(Ok(DocumentColors {
 7425                                    colors: cached_colors
 7426                                        .colors
 7427                                        .values()
 7428                                        .flatten()
 7429                                        .cloned()
 7430                                        .collect(),
 7431                                    cache_version: Some(cache_version),
 7432                                }))
 7433                                .shared(),
 7434                            );
 7435                        }
 7436                    }
 7437                }
 7438            }
 7439        }
 7440
 7441        let color_lsp_data = self
 7442            .latest_lsp_data(&buffer, cx)
 7443            .document_colors
 7444            .get_or_insert_default();
 7445        if let Some((updating_for, running_update)) = &color_lsp_data.colors_update
 7446            && !version_queried_for.changed_since(updating_for)
 7447        {
 7448            return Some(running_update.clone());
 7449        }
 7450        let buffer_version_queried_for = version_queried_for.clone();
 7451        let new_task = cx
 7452            .spawn(async move |lsp_store, cx| {
 7453                cx.background_executor()
 7454                    .timer(Duration::from_millis(30))
 7455                    .await;
 7456                let fetched_colors = lsp_store
 7457                    .update(cx, |lsp_store, cx| {
 7458                        lsp_store.fetch_document_colors_for_buffer(&buffer, cx)
 7459                    })?
 7460                    .await
 7461                    .context("fetching document colors")
 7462                    .map_err(Arc::new);
 7463                let fetched_colors = match fetched_colors {
 7464                    Ok(fetched_colors) => {
 7465                        if Some(true)
 7466                            == buffer
 7467                                .update(cx, |buffer, _| {
 7468                                    buffer.version() != buffer_version_queried_for
 7469                                })
 7470                                .ok()
 7471                        {
 7472                            return Ok(DocumentColors::default());
 7473                        }
 7474                        fetched_colors
 7475                    }
 7476                    Err(e) => {
 7477                        lsp_store
 7478                            .update(cx, |lsp_store, _| {
 7479                                if let Some(lsp_data) = lsp_store.lsp_data.get_mut(&buffer_id) {
 7480                                    if let Some(document_colors) = &mut lsp_data.document_colors {
 7481                                        document_colors.colors_update = None;
 7482                                    }
 7483                                }
 7484                            })
 7485                            .ok();
 7486                        return Err(e);
 7487                    }
 7488                };
 7489
 7490                lsp_store
 7491                    .update(cx, |lsp_store, cx| {
 7492                        let lsp_data = lsp_store.latest_lsp_data(&buffer, cx);
 7493                        let lsp_colors = lsp_data.document_colors.get_or_insert_default();
 7494
 7495                        if let Some(fetched_colors) = fetched_colors {
 7496                            if lsp_data.buffer_version == buffer_version_queried_for {
 7497                                lsp_colors.colors.extend(fetched_colors);
 7498                                lsp_colors.cache_version += 1;
 7499                            } else if !lsp_data
 7500                                .buffer_version
 7501                                .changed_since(&buffer_version_queried_for)
 7502                            {
 7503                                lsp_data.buffer_version = buffer_version_queried_for;
 7504                                lsp_colors.colors = fetched_colors;
 7505                                lsp_colors.cache_version += 1;
 7506                            }
 7507                        }
 7508                        lsp_colors.colors_update = None;
 7509                        let colors = lsp_colors
 7510                            .colors
 7511                            .values()
 7512                            .flatten()
 7513                            .cloned()
 7514                            .collect::<HashSet<_>>();
 7515                        DocumentColors {
 7516                            colors,
 7517                            cache_version: Some(lsp_colors.cache_version),
 7518                        }
 7519                    })
 7520                    .map_err(Arc::new)
 7521            })
 7522            .shared();
 7523        color_lsp_data.colors_update = Some((version_queried_for, new_task.clone()));
 7524        Some(new_task)
 7525    }
 7526
 7527    fn fetch_document_colors_for_buffer(
 7528        &mut self,
 7529        buffer: &Entity<Buffer>,
 7530        cx: &mut Context<Self>,
 7531    ) -> Task<anyhow::Result<Option<HashMap<LanguageServerId, HashSet<DocumentColor>>>>> {
 7532        if let Some((client, project_id)) = self.upstream_client() {
 7533            let request = GetDocumentColor {};
 7534            if !self.is_capable_for_proto_request(buffer, &request, cx) {
 7535                return Task::ready(Ok(None));
 7536            }
 7537
 7538            let request_task = client.request_lsp(
 7539                project_id,
 7540                None,
 7541                LSP_REQUEST_TIMEOUT,
 7542                cx.background_executor().clone(),
 7543                request.to_proto(project_id, buffer.read(cx)),
 7544            );
 7545            let buffer = buffer.clone();
 7546            cx.spawn(async move |lsp_store, cx| {
 7547                let Some(lsp_store) = lsp_store.upgrade() else {
 7548                    return Ok(None);
 7549                };
 7550                let colors = join_all(
 7551                    request_task
 7552                        .await
 7553                        .log_err()
 7554                        .flatten()
 7555                        .map(|response| response.payload)
 7556                        .unwrap_or_default()
 7557                        .into_iter()
 7558                        .map(|color_response| {
 7559                            let response = request.response_from_proto(
 7560                                color_response.response,
 7561                                lsp_store.clone(),
 7562                                buffer.clone(),
 7563                                cx.clone(),
 7564                            );
 7565                            async move {
 7566                                (
 7567                                    LanguageServerId::from_proto(color_response.server_id),
 7568                                    response.await.log_err().unwrap_or_default(),
 7569                                )
 7570                            }
 7571                        }),
 7572                )
 7573                .await
 7574                .into_iter()
 7575                .fold(HashMap::default(), |mut acc, (server_id, colors)| {
 7576                    acc.entry(server_id)
 7577                        .or_insert_with(HashSet::default)
 7578                        .extend(colors);
 7579                    acc
 7580                });
 7581                Ok(Some(colors))
 7582            })
 7583        } else {
 7584            let document_colors_task =
 7585                self.request_multiple_lsp_locally(buffer, None::<usize>, GetDocumentColor, cx);
 7586            cx.background_spawn(async move {
 7587                Ok(Some(
 7588                    document_colors_task
 7589                        .await
 7590                        .into_iter()
 7591                        .fold(HashMap::default(), |mut acc, (server_id, colors)| {
 7592                            acc.entry(server_id)
 7593                                .or_insert_with(HashSet::default)
 7594                                .extend(colors);
 7595                            acc
 7596                        })
 7597                        .into_iter()
 7598                        .collect(),
 7599                ))
 7600            })
 7601        }
 7602    }
 7603
 7604    pub fn signature_help<T: ToPointUtf16>(
 7605        &mut self,
 7606        buffer: &Entity<Buffer>,
 7607        position: T,
 7608        cx: &mut Context<Self>,
 7609    ) -> Task<Option<Vec<SignatureHelp>>> {
 7610        let position = position.to_point_utf16(buffer.read(cx));
 7611
 7612        if let Some((client, upstream_project_id)) = self.upstream_client() {
 7613            let request = GetSignatureHelp { position };
 7614            if !self.is_capable_for_proto_request(buffer, &request, cx) {
 7615                return Task::ready(None);
 7616            }
 7617            let request_task = client.request_lsp(
 7618                upstream_project_id,
 7619                None,
 7620                LSP_REQUEST_TIMEOUT,
 7621                cx.background_executor().clone(),
 7622                request.to_proto(upstream_project_id, buffer.read(cx)),
 7623            );
 7624            let buffer = buffer.clone();
 7625            cx.spawn(async move |weak_lsp_store, cx| {
 7626                let lsp_store = weak_lsp_store.upgrade()?;
 7627                let signatures = join_all(
 7628                    request_task
 7629                        .await
 7630                        .log_err()
 7631                        .flatten()
 7632                        .map(|response| response.payload)
 7633                        .unwrap_or_default()
 7634                        .into_iter()
 7635                        .map(|response| {
 7636                            let response = GetSignatureHelp { position }.response_from_proto(
 7637                                response.response,
 7638                                lsp_store.clone(),
 7639                                buffer.clone(),
 7640                                cx.clone(),
 7641                            );
 7642                            async move { response.await.log_err().flatten() }
 7643                        }),
 7644                )
 7645                .await
 7646                .into_iter()
 7647                .flatten()
 7648                .collect();
 7649                Some(signatures)
 7650            })
 7651        } else {
 7652            let all_actions_task = self.request_multiple_lsp_locally(
 7653                buffer,
 7654                Some(position),
 7655                GetSignatureHelp { position },
 7656                cx,
 7657            );
 7658            cx.background_spawn(async move {
 7659                Some(
 7660                    all_actions_task
 7661                        .await
 7662                        .into_iter()
 7663                        .flat_map(|(_, actions)| actions)
 7664                        .collect::<Vec<_>>(),
 7665                )
 7666            })
 7667        }
 7668    }
 7669
 7670    pub fn hover(
 7671        &mut self,
 7672        buffer: &Entity<Buffer>,
 7673        position: PointUtf16,
 7674        cx: &mut Context<Self>,
 7675    ) -> Task<Option<Vec<Hover>>> {
 7676        if let Some((client, upstream_project_id)) = self.upstream_client() {
 7677            let request = GetHover { position };
 7678            if !self.is_capable_for_proto_request(buffer, &request, cx) {
 7679                return Task::ready(None);
 7680            }
 7681            let request_task = client.request_lsp(
 7682                upstream_project_id,
 7683                None,
 7684                LSP_REQUEST_TIMEOUT,
 7685                cx.background_executor().clone(),
 7686                request.to_proto(upstream_project_id, buffer.read(cx)),
 7687            );
 7688            let buffer = buffer.clone();
 7689            cx.spawn(async move |weak_lsp_store, cx| {
 7690                let lsp_store = weak_lsp_store.upgrade()?;
 7691                let hovers = join_all(
 7692                    request_task
 7693                        .await
 7694                        .log_err()
 7695                        .flatten()
 7696                        .map(|response| response.payload)
 7697                        .unwrap_or_default()
 7698                        .into_iter()
 7699                        .map(|response| {
 7700                            let response = GetHover { position }.response_from_proto(
 7701                                response.response,
 7702                                lsp_store.clone(),
 7703                                buffer.clone(),
 7704                                cx.clone(),
 7705                            );
 7706                            async move {
 7707                                response
 7708                                    .await
 7709                                    .log_err()
 7710                                    .flatten()
 7711                                    .and_then(remove_empty_hover_blocks)
 7712                            }
 7713                        }),
 7714                )
 7715                .await
 7716                .into_iter()
 7717                .flatten()
 7718                .collect();
 7719                Some(hovers)
 7720            })
 7721        } else {
 7722            let all_actions_task = self.request_multiple_lsp_locally(
 7723                buffer,
 7724                Some(position),
 7725                GetHover { position },
 7726                cx,
 7727            );
 7728            cx.background_spawn(async move {
 7729                Some(
 7730                    all_actions_task
 7731                        .await
 7732                        .into_iter()
 7733                        .filter_map(|(_, hover)| remove_empty_hover_blocks(hover?))
 7734                        .collect::<Vec<Hover>>(),
 7735                )
 7736            })
 7737        }
 7738    }
 7739
 7740    pub fn symbols(&self, query: &str, cx: &mut Context<Self>) -> Task<Result<Vec<Symbol>>> {
 7741        let language_registry = self.languages.clone();
 7742
 7743        if let Some((upstream_client, project_id)) = self.upstream_client().as_ref() {
 7744            let request = upstream_client.request(proto::GetProjectSymbols {
 7745                project_id: *project_id,
 7746                query: query.to_string(),
 7747            });
 7748            cx.foreground_executor().spawn(async move {
 7749                let response = request.await?;
 7750                let mut symbols = Vec::new();
 7751                let core_symbols = response
 7752                    .symbols
 7753                    .into_iter()
 7754                    .filter_map(|symbol| Self::deserialize_symbol(symbol).log_err())
 7755                    .collect::<Vec<_>>();
 7756                populate_labels_for_symbols(core_symbols, &language_registry, None, &mut symbols)
 7757                    .await;
 7758                Ok(symbols)
 7759            })
 7760        } else if let Some(local) = self.as_local() {
 7761            struct WorkspaceSymbolsResult {
 7762                server_id: LanguageServerId,
 7763                lsp_adapter: Arc<CachedLspAdapter>,
 7764                worktree: WeakEntity<Worktree>,
 7765                lsp_symbols: Vec<(String, SymbolKind, lsp::Location)>,
 7766            }
 7767
 7768            let mut requests = Vec::new();
 7769            let mut requested_servers = BTreeSet::new();
 7770            for (seed, state) in local.language_server_ids.iter() {
 7771                let Some(worktree_handle) = self
 7772                    .worktree_store
 7773                    .read(cx)
 7774                    .worktree_for_id(seed.worktree_id, cx)
 7775                else {
 7776                    continue;
 7777                };
 7778                let worktree = worktree_handle.read(cx);
 7779                if !worktree.is_visible() {
 7780                    continue;
 7781                }
 7782
 7783                if !requested_servers.insert(state.id) {
 7784                    continue;
 7785                }
 7786
 7787                let (lsp_adapter, server) = match local.language_servers.get(&state.id) {
 7788                    Some(LanguageServerState::Running {
 7789                        adapter, server, ..
 7790                    }) => (adapter.clone(), server),
 7791
 7792                    _ => continue,
 7793                };
 7794                let supports_workspace_symbol_request =
 7795                    match server.capabilities().workspace_symbol_provider {
 7796                        Some(OneOf::Left(supported)) => supported,
 7797                        Some(OneOf::Right(_)) => true,
 7798                        None => false,
 7799                    };
 7800                if !supports_workspace_symbol_request {
 7801                    continue;
 7802                }
 7803                let worktree_handle = worktree_handle.clone();
 7804                let server_id = server.server_id();
 7805                requests.push(
 7806                        server
 7807                            .request::<lsp::request::WorkspaceSymbolRequest>(
 7808                                lsp::WorkspaceSymbolParams {
 7809                                    query: query.to_string(),
 7810                                    ..Default::default()
 7811                                },
 7812                            )
 7813                            .map(move |response| {
 7814                                let lsp_symbols = response.into_response()
 7815                                    .context("workspace symbols request")
 7816                                    .log_err()
 7817                                    .flatten()
 7818                                    .map(|symbol_response| match symbol_response {
 7819                                        lsp::WorkspaceSymbolResponse::Flat(flat_responses) => {
 7820                                            flat_responses.into_iter().map(|lsp_symbol| {
 7821                                            (lsp_symbol.name, lsp_symbol.kind, lsp_symbol.location)
 7822                                            }).collect::<Vec<_>>()
 7823                                        }
 7824                                        lsp::WorkspaceSymbolResponse::Nested(nested_responses) => {
 7825                                            nested_responses.into_iter().filter_map(|lsp_symbol| {
 7826                                                let location = match lsp_symbol.location {
 7827                                                    OneOf::Left(location) => location,
 7828                                                    OneOf::Right(_) => {
 7829                                                        log::error!("Unexpected: client capabilities forbid symbol resolutions in workspace.symbol.resolveSupport");
 7830                                                        return None
 7831                                                    }
 7832                                                };
 7833                                                Some((lsp_symbol.name, lsp_symbol.kind, location))
 7834                                            }).collect::<Vec<_>>()
 7835                                        }
 7836                                    }).unwrap_or_default();
 7837
 7838                                WorkspaceSymbolsResult {
 7839                                    server_id,
 7840                                    lsp_adapter,
 7841                                    worktree: worktree_handle.downgrade(),
 7842                                    lsp_symbols,
 7843                                }
 7844                            }),
 7845                    );
 7846            }
 7847
 7848            cx.spawn(async move |this, cx| {
 7849                let responses = futures::future::join_all(requests).await;
 7850                let this = match this.upgrade() {
 7851                    Some(this) => this,
 7852                    None => return Ok(Vec::new()),
 7853                };
 7854
 7855                let mut symbols = Vec::new();
 7856                for result in responses {
 7857                    let core_symbols = this.update(cx, |this, cx| {
 7858                        result
 7859                            .lsp_symbols
 7860                            .into_iter()
 7861                            .filter_map(|(symbol_name, symbol_kind, symbol_location)| {
 7862                                let abs_path = symbol_location.uri.to_file_path().ok()?;
 7863                                let source_worktree = result.worktree.upgrade()?;
 7864                                let source_worktree_id = source_worktree.read(cx).id();
 7865
 7866                                let path = if let Some((tree, rel_path)) =
 7867                                    this.worktree_store.read(cx).find_worktree(&abs_path, cx)
 7868                                {
 7869                                    let worktree_id = tree.read(cx).id();
 7870                                    SymbolLocation::InProject(ProjectPath {
 7871                                        worktree_id,
 7872                                        path: rel_path,
 7873                                    })
 7874                                } else {
 7875                                    SymbolLocation::OutsideProject {
 7876                                        signature: this.symbol_signature(&abs_path),
 7877                                        abs_path: abs_path.into(),
 7878                                    }
 7879                                };
 7880
 7881                                Some(CoreSymbol {
 7882                                    source_language_server_id: result.server_id,
 7883                                    language_server_name: result.lsp_adapter.name.clone(),
 7884                                    source_worktree_id,
 7885                                    path,
 7886                                    kind: symbol_kind,
 7887                                    name: symbol_name,
 7888                                    range: range_from_lsp(symbol_location.range),
 7889                                })
 7890                            })
 7891                            .collect()
 7892                    })?;
 7893
 7894                    populate_labels_for_symbols(
 7895                        core_symbols,
 7896                        &language_registry,
 7897                        Some(result.lsp_adapter),
 7898                        &mut symbols,
 7899                    )
 7900                    .await;
 7901                }
 7902
 7903                Ok(symbols)
 7904            })
 7905        } else {
 7906            Task::ready(Err(anyhow!("No upstream client or local language server")))
 7907        }
 7908    }
 7909
 7910    pub fn diagnostic_summary(&self, include_ignored: bool, cx: &App) -> DiagnosticSummary {
 7911        let mut summary = DiagnosticSummary::default();
 7912        for (_, _, path_summary) in self.diagnostic_summaries(include_ignored, cx) {
 7913            summary.error_count += path_summary.error_count;
 7914            summary.warning_count += path_summary.warning_count;
 7915        }
 7916        summary
 7917    }
 7918
 7919    /// Returns the diagnostic summary for a specific project path.
 7920    pub fn diagnostic_summary_for_path(
 7921        &self,
 7922        project_path: &ProjectPath,
 7923        _: &App,
 7924    ) -> DiagnosticSummary {
 7925        if let Some(summaries) = self
 7926            .diagnostic_summaries
 7927            .get(&project_path.worktree_id)
 7928            .and_then(|map| map.get(&project_path.path))
 7929        {
 7930            let (error_count, warning_count) = summaries.iter().fold(
 7931                (0, 0),
 7932                |(error_count, warning_count), (_language_server_id, summary)| {
 7933                    (
 7934                        error_count + summary.error_count,
 7935                        warning_count + summary.warning_count,
 7936                    )
 7937                },
 7938            );
 7939
 7940            DiagnosticSummary {
 7941                error_count,
 7942                warning_count,
 7943            }
 7944        } else {
 7945            DiagnosticSummary::default()
 7946        }
 7947    }
 7948
 7949    pub fn diagnostic_summaries<'a>(
 7950        &'a self,
 7951        include_ignored: bool,
 7952        cx: &'a App,
 7953    ) -> impl Iterator<Item = (ProjectPath, LanguageServerId, DiagnosticSummary)> + 'a {
 7954        self.worktree_store
 7955            .read(cx)
 7956            .visible_worktrees(cx)
 7957            .filter_map(|worktree| {
 7958                let worktree = worktree.read(cx);
 7959                Some((worktree, self.diagnostic_summaries.get(&worktree.id())?))
 7960            })
 7961            .flat_map(move |(worktree, summaries)| {
 7962                let worktree_id = worktree.id();
 7963                summaries
 7964                    .iter()
 7965                    .filter(move |(path, _)| {
 7966                        include_ignored
 7967                            || worktree
 7968                                .entry_for_path(path.as_ref())
 7969                                .is_some_and(|entry| !entry.is_ignored)
 7970                    })
 7971                    .flat_map(move |(path, summaries)| {
 7972                        summaries.iter().map(move |(server_id, summary)| {
 7973                            (
 7974                                ProjectPath {
 7975                                    worktree_id,
 7976                                    path: path.clone(),
 7977                                },
 7978                                *server_id,
 7979                                *summary,
 7980                            )
 7981                        })
 7982                    })
 7983            })
 7984    }
 7985
 7986    pub fn on_buffer_edited(
 7987        &mut self,
 7988        buffer: Entity<Buffer>,
 7989        cx: &mut Context<Self>,
 7990    ) -> Option<()> {
 7991        let language_servers: Vec<_> = buffer.update(cx, |buffer, cx| {
 7992            Some(
 7993                self.as_local()?
 7994                    .language_servers_for_buffer(buffer, cx)
 7995                    .map(|i| i.1.clone())
 7996                    .collect(),
 7997            )
 7998        })?;
 7999
 8000        let buffer = buffer.read(cx);
 8001        let file = File::from_dyn(buffer.file())?;
 8002        let abs_path = file.as_local()?.abs_path(cx);
 8003        let uri = lsp::Uri::from_file_path(&abs_path)
 8004            .ok()
 8005            .with_context(|| format!("Failed to convert path to URI: {}", abs_path.display()))
 8006            .log_err()?;
 8007        let next_snapshot = buffer.text_snapshot();
 8008        for language_server in language_servers {
 8009            let language_server = language_server.clone();
 8010
 8011            let buffer_snapshots = self
 8012                .as_local_mut()?
 8013                .buffer_snapshots
 8014                .get_mut(&buffer.remote_id())
 8015                .and_then(|m| m.get_mut(&language_server.server_id()))?;
 8016            let previous_snapshot = buffer_snapshots.last()?;
 8017
 8018            let build_incremental_change = || {
 8019                buffer
 8020                    .edits_since::<Dimensions<PointUtf16, usize>>(
 8021                        previous_snapshot.snapshot.version(),
 8022                    )
 8023                    .map(|edit| {
 8024                        let edit_start = edit.new.start.0;
 8025                        let edit_end = edit_start + (edit.old.end.0 - edit.old.start.0);
 8026                        let new_text = next_snapshot
 8027                            .text_for_range(edit.new.start.1..edit.new.end.1)
 8028                            .collect();
 8029                        lsp::TextDocumentContentChangeEvent {
 8030                            range: Some(lsp::Range::new(
 8031                                point_to_lsp(edit_start),
 8032                                point_to_lsp(edit_end),
 8033                            )),
 8034                            range_length: None,
 8035                            text: new_text,
 8036                        }
 8037                    })
 8038                    .collect()
 8039            };
 8040
 8041            let document_sync_kind = language_server
 8042                .capabilities()
 8043                .text_document_sync
 8044                .as_ref()
 8045                .and_then(|sync| match sync {
 8046                    lsp::TextDocumentSyncCapability::Kind(kind) => Some(*kind),
 8047                    lsp::TextDocumentSyncCapability::Options(options) => options.change,
 8048                });
 8049
 8050            let content_changes: Vec<_> = match document_sync_kind {
 8051                Some(lsp::TextDocumentSyncKind::FULL) => {
 8052                    vec![lsp::TextDocumentContentChangeEvent {
 8053                        range: None,
 8054                        range_length: None,
 8055                        text: next_snapshot.text(),
 8056                    }]
 8057                }
 8058                Some(lsp::TextDocumentSyncKind::INCREMENTAL) => build_incremental_change(),
 8059                _ => {
 8060                    #[cfg(any(test, feature = "test-support"))]
 8061                    {
 8062                        build_incremental_change()
 8063                    }
 8064
 8065                    #[cfg(not(any(test, feature = "test-support")))]
 8066                    {
 8067                        continue;
 8068                    }
 8069                }
 8070            };
 8071
 8072            let next_version = previous_snapshot.version + 1;
 8073            buffer_snapshots.push(LspBufferSnapshot {
 8074                version: next_version,
 8075                snapshot: next_snapshot.clone(),
 8076            });
 8077
 8078            language_server
 8079                .notify::<lsp::notification::DidChangeTextDocument>(
 8080                    lsp::DidChangeTextDocumentParams {
 8081                        text_document: lsp::VersionedTextDocumentIdentifier::new(
 8082                            uri.clone(),
 8083                            next_version,
 8084                        ),
 8085                        content_changes,
 8086                    },
 8087                )
 8088                .ok();
 8089            self.pull_workspace_diagnostics(language_server.server_id());
 8090        }
 8091
 8092        None
 8093    }
 8094
 8095    pub fn on_buffer_saved(
 8096        &mut self,
 8097        buffer: Entity<Buffer>,
 8098        cx: &mut Context<Self>,
 8099    ) -> Option<()> {
 8100        let file = File::from_dyn(buffer.read(cx).file())?;
 8101        let worktree_id = file.worktree_id(cx);
 8102        let abs_path = file.as_local()?.abs_path(cx);
 8103        let text_document = lsp::TextDocumentIdentifier {
 8104            uri: file_path_to_lsp_url(&abs_path).log_err()?,
 8105        };
 8106        let local = self.as_local()?;
 8107
 8108        for server in local.language_servers_for_worktree(worktree_id) {
 8109            if let Some(include_text) = include_text(server.as_ref()) {
 8110                let text = if include_text {
 8111                    Some(buffer.read(cx).text())
 8112                } else {
 8113                    None
 8114                };
 8115                server
 8116                    .notify::<lsp::notification::DidSaveTextDocument>(
 8117                        lsp::DidSaveTextDocumentParams {
 8118                            text_document: text_document.clone(),
 8119                            text,
 8120                        },
 8121                    )
 8122                    .ok();
 8123            }
 8124        }
 8125
 8126        let language_servers = buffer.update(cx, |buffer, cx| {
 8127            local.language_server_ids_for_buffer(buffer, cx)
 8128        });
 8129        for language_server_id in language_servers {
 8130            self.simulate_disk_based_diagnostics_events_if_needed(language_server_id, cx);
 8131        }
 8132
 8133        None
 8134    }
 8135
 8136    async fn refresh_workspace_configurations(lsp_store: &WeakEntity<Self>, cx: &mut AsyncApp) {
 8137        maybe!(async move {
 8138            let mut refreshed_servers = HashSet::default();
 8139            let servers = lsp_store
 8140                .update(cx, |lsp_store, cx| {
 8141                    let local = lsp_store.as_local()?;
 8142
 8143                    let servers = local
 8144                        .language_server_ids
 8145                        .iter()
 8146                        .filter_map(|(seed, state)| {
 8147                            let worktree = lsp_store
 8148                                .worktree_store
 8149                                .read(cx)
 8150                                .worktree_for_id(seed.worktree_id, cx);
 8151                            let delegate: Arc<dyn LspAdapterDelegate> =
 8152                                worktree.map(|worktree| {
 8153                                    LocalLspAdapterDelegate::new(
 8154                                        local.languages.clone(),
 8155                                        &local.environment,
 8156                                        cx.weak_entity(),
 8157                                        &worktree,
 8158                                        local.http_client.clone(),
 8159                                        local.fs.clone(),
 8160                                        cx,
 8161                                    )
 8162                                })?;
 8163                            let server_id = state.id;
 8164
 8165                            let states = local.language_servers.get(&server_id)?;
 8166
 8167                            match states {
 8168                                LanguageServerState::Starting { .. } => None,
 8169                                LanguageServerState::Running {
 8170                                    adapter, server, ..
 8171                                } => {
 8172                                    let adapter = adapter.clone();
 8173                                    let server = server.clone();
 8174                                    refreshed_servers.insert(server.name());
 8175                                    let toolchain = seed.toolchain.clone();
 8176                                    Some(cx.spawn(async move |_, cx| {
 8177                                        let settings =
 8178                                            LocalLspStore::workspace_configuration_for_adapter(
 8179                                                adapter.adapter.clone(),
 8180                                                &delegate,
 8181                                                toolchain,
 8182                                                None,
 8183                                                cx,
 8184                                            )
 8185                                            .await
 8186                                            .ok()?;
 8187                                        server
 8188                                            .notify::<lsp::notification::DidChangeConfiguration>(
 8189                                                lsp::DidChangeConfigurationParams { settings },
 8190                                            )
 8191                                            .ok()?;
 8192                                        Some(())
 8193                                    }))
 8194                                }
 8195                            }
 8196                        })
 8197                        .collect::<Vec<_>>();
 8198
 8199                    Some(servers)
 8200                })
 8201                .ok()
 8202                .flatten()?;
 8203
 8204            log::debug!("Refreshing workspace configurations for servers {refreshed_servers:?}");
 8205            // TODO this asynchronous job runs concurrently with extension (de)registration and may take enough time for a certain extension
 8206            // to stop and unregister its language server wrapper.
 8207            // This is racy : an extension might have already removed all `local.language_servers` state, but here we `.clone()` and hold onto it anyway.
 8208            // This now causes errors in the logs, we should find a way to remove such servers from the processing everywhere.
 8209            let _: Vec<Option<()>> = join_all(servers).await;
 8210
 8211            Some(())
 8212        })
 8213        .await;
 8214    }
 8215
 8216    fn maintain_workspace_config(
 8217        external_refresh_requests: watch::Receiver<()>,
 8218        cx: &mut Context<Self>,
 8219    ) -> Task<Result<()>> {
 8220        let (mut settings_changed_tx, mut settings_changed_rx) = watch::channel();
 8221        let _ = postage::stream::Stream::try_recv(&mut settings_changed_rx);
 8222
 8223        let settings_observation = cx.observe_global::<SettingsStore>(move |_, _| {
 8224            *settings_changed_tx.borrow_mut() = ();
 8225        });
 8226
 8227        let mut joint_future =
 8228            futures::stream::select(settings_changed_rx, external_refresh_requests);
 8229        // Multiple things can happen when a workspace environment (selected toolchain + settings) change:
 8230        // - 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).
 8231        // - 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.
 8232        // - In the same vein, we might also decide to start a new language server if the workspace configuration *diverges* from the other.
 8233        // - 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,
 8234        // but it is still different to what we had before, we're gonna send out a workspace configuration update.
 8235        cx.spawn(async move |this, cx| {
 8236            while let Some(()) = joint_future.next().await {
 8237                this.update(cx, |this, cx| {
 8238                    this.refresh_server_tree(cx);
 8239                })
 8240                .ok();
 8241
 8242                Self::refresh_workspace_configurations(&this, cx).await;
 8243            }
 8244
 8245            drop(settings_observation);
 8246            anyhow::Ok(())
 8247        })
 8248    }
 8249
 8250    pub fn running_language_servers_for_local_buffer<'a>(
 8251        &'a self,
 8252        buffer: &Buffer,
 8253        cx: &mut App,
 8254    ) -> impl Iterator<Item = (&'a Arc<CachedLspAdapter>, &'a Arc<LanguageServer>)> {
 8255        let local = self.as_local();
 8256        let language_server_ids = local
 8257            .map(|local| local.language_server_ids_for_buffer(buffer, cx))
 8258            .unwrap_or_default();
 8259
 8260        language_server_ids
 8261            .into_iter()
 8262            .filter_map(
 8263                move |server_id| match local?.language_servers.get(&server_id)? {
 8264                    LanguageServerState::Running {
 8265                        adapter, server, ..
 8266                    } => Some((adapter, server)),
 8267                    _ => None,
 8268                },
 8269            )
 8270    }
 8271
 8272    pub fn language_servers_for_local_buffer(
 8273        &self,
 8274        buffer: &Buffer,
 8275        cx: &mut App,
 8276    ) -> Vec<LanguageServerId> {
 8277        let local = self.as_local();
 8278        local
 8279            .map(|local| local.language_server_ids_for_buffer(buffer, cx))
 8280            .unwrap_or_default()
 8281    }
 8282
 8283    pub fn language_server_for_local_buffer<'a>(
 8284        &'a self,
 8285        buffer: &'a Buffer,
 8286        server_id: LanguageServerId,
 8287        cx: &'a mut App,
 8288    ) -> Option<(&'a Arc<CachedLspAdapter>, &'a Arc<LanguageServer>)> {
 8289        self.as_local()?
 8290            .language_servers_for_buffer(buffer, cx)
 8291            .find(|(_, s)| s.server_id() == server_id)
 8292    }
 8293
 8294    fn remove_worktree(&mut self, id_to_remove: WorktreeId, cx: &mut Context<Self>) {
 8295        self.diagnostic_summaries.remove(&id_to_remove);
 8296        if let Some(local) = self.as_local_mut() {
 8297            let to_remove = local.remove_worktree(id_to_remove, cx);
 8298            for server in to_remove {
 8299                self.language_server_statuses.remove(&server);
 8300            }
 8301        }
 8302    }
 8303
 8304    pub fn shared(
 8305        &mut self,
 8306        project_id: u64,
 8307        downstream_client: AnyProtoClient,
 8308        _: &mut Context<Self>,
 8309    ) {
 8310        self.downstream_client = Some((downstream_client.clone(), project_id));
 8311
 8312        for (server_id, status) in &self.language_server_statuses {
 8313            if let Some(server) = self.language_server_for_id(*server_id) {
 8314                downstream_client
 8315                    .send(proto::StartLanguageServer {
 8316                        project_id,
 8317                        server: Some(proto::LanguageServer {
 8318                            id: server_id.to_proto(),
 8319                            name: status.name.to_string(),
 8320                            worktree_id: status.worktree.map(|id| id.to_proto()),
 8321                        }),
 8322                        capabilities: serde_json::to_string(&server.capabilities())
 8323                            .expect("serializing server LSP capabilities"),
 8324                    })
 8325                    .log_err();
 8326            }
 8327        }
 8328    }
 8329
 8330    pub fn disconnected_from_host(&mut self) {
 8331        self.downstream_client.take();
 8332    }
 8333
 8334    pub fn disconnected_from_ssh_remote(&mut self) {
 8335        if let LspStoreMode::Remote(RemoteLspStore {
 8336            upstream_client, ..
 8337        }) = &mut self.mode
 8338        {
 8339            upstream_client.take();
 8340        }
 8341    }
 8342
 8343    pub(crate) fn set_language_server_statuses_from_proto(
 8344        &mut self,
 8345        project: WeakEntity<Project>,
 8346        language_servers: Vec<proto::LanguageServer>,
 8347        server_capabilities: Vec<String>,
 8348        cx: &mut Context<Self>,
 8349    ) {
 8350        let lsp_logs = cx
 8351            .try_global::<GlobalLogStore>()
 8352            .map(|lsp_store| lsp_store.0.clone());
 8353
 8354        self.language_server_statuses = language_servers
 8355            .into_iter()
 8356            .zip(server_capabilities)
 8357            .map(|(server, server_capabilities)| {
 8358                let server_id = LanguageServerId(server.id as usize);
 8359                if let Ok(server_capabilities) = serde_json::from_str(&server_capabilities) {
 8360                    self.lsp_server_capabilities
 8361                        .insert(server_id, server_capabilities);
 8362                }
 8363
 8364                let name = LanguageServerName::from_proto(server.name);
 8365                let worktree = server.worktree_id.map(WorktreeId::from_proto);
 8366
 8367                if let Some(lsp_logs) = &lsp_logs {
 8368                    lsp_logs.update(cx, |lsp_logs, cx| {
 8369                        lsp_logs.add_language_server(
 8370                            // Only remote clients get their language servers set from proto
 8371                            LanguageServerKind::Remote {
 8372                                project: project.clone(),
 8373                            },
 8374                            server_id,
 8375                            Some(name.clone()),
 8376                            worktree,
 8377                            None,
 8378                            cx,
 8379                        );
 8380                    });
 8381                }
 8382
 8383                (
 8384                    server_id,
 8385                    LanguageServerStatus {
 8386                        name,
 8387                        server_version: None,
 8388                        pending_work: Default::default(),
 8389                        has_pending_diagnostic_updates: false,
 8390                        progress_tokens: Default::default(),
 8391                        worktree,
 8392                        binary: None,
 8393                        configuration: None,
 8394                        workspace_folders: BTreeSet::new(),
 8395                    },
 8396                )
 8397            })
 8398            .collect();
 8399    }
 8400
 8401    #[cfg(test)]
 8402    pub fn update_diagnostic_entries(
 8403        &mut self,
 8404        server_id: LanguageServerId,
 8405        abs_path: PathBuf,
 8406        result_id: Option<SharedString>,
 8407        version: Option<i32>,
 8408        diagnostics: Vec<DiagnosticEntry<Unclipped<PointUtf16>>>,
 8409        cx: &mut Context<Self>,
 8410    ) -> anyhow::Result<()> {
 8411        self.merge_diagnostic_entries(
 8412            vec![DocumentDiagnosticsUpdate {
 8413                diagnostics: DocumentDiagnostics {
 8414                    diagnostics,
 8415                    document_abs_path: abs_path,
 8416                    version,
 8417                },
 8418                result_id,
 8419                server_id,
 8420                disk_based_sources: Cow::Borrowed(&[]),
 8421                registration_id: None,
 8422            }],
 8423            |_, _, _| false,
 8424            cx,
 8425        )?;
 8426        Ok(())
 8427    }
 8428
 8429    pub fn merge_diagnostic_entries<'a>(
 8430        &mut self,
 8431        diagnostic_updates: Vec<DocumentDiagnosticsUpdate<'a, DocumentDiagnostics>>,
 8432        merge: impl Fn(&lsp::Uri, &Diagnostic, &App) -> bool + Clone,
 8433        cx: &mut Context<Self>,
 8434    ) -> anyhow::Result<()> {
 8435        let mut diagnostics_summary = None::<proto::UpdateDiagnosticSummary>;
 8436        let mut updated_diagnostics_paths = HashMap::default();
 8437        for mut update in diagnostic_updates {
 8438            let abs_path = &update.diagnostics.document_abs_path;
 8439            let server_id = update.server_id;
 8440            let Some((worktree, relative_path)) =
 8441                self.worktree_store.read(cx).find_worktree(abs_path, cx)
 8442            else {
 8443                log::warn!("skipping diagnostics update, no worktree found for path {abs_path:?}");
 8444                return Ok(());
 8445            };
 8446
 8447            let worktree_id = worktree.read(cx).id();
 8448            let project_path = ProjectPath {
 8449                worktree_id,
 8450                path: relative_path,
 8451            };
 8452
 8453            let document_uri = lsp::Uri::from_file_path(abs_path)
 8454                .map_err(|()| anyhow!("Failed to convert buffer path {abs_path:?} to lsp Uri"))?;
 8455            if let Some(buffer_handle) = self.buffer_store.read(cx).get_by_path(&project_path) {
 8456                let snapshot = buffer_handle.read(cx).snapshot();
 8457                let buffer = buffer_handle.read(cx);
 8458                let reused_diagnostics = buffer
 8459                    .buffer_diagnostics(Some(server_id))
 8460                    .iter()
 8461                    .filter(|v| merge(&document_uri, &v.diagnostic, cx))
 8462                    .map(|v| {
 8463                        let start = Unclipped(v.range.start.to_point_utf16(&snapshot));
 8464                        let end = Unclipped(v.range.end.to_point_utf16(&snapshot));
 8465                        DiagnosticEntry {
 8466                            range: start..end,
 8467                            diagnostic: v.diagnostic.clone(),
 8468                        }
 8469                    })
 8470                    .collect::<Vec<_>>();
 8471
 8472                self.as_local_mut()
 8473                    .context("cannot merge diagnostics on a remote LspStore")?
 8474                    .update_buffer_diagnostics(
 8475                        &buffer_handle,
 8476                        server_id,
 8477                        Some(update.registration_id),
 8478                        update.result_id,
 8479                        update.diagnostics.version,
 8480                        update.diagnostics.diagnostics.clone(),
 8481                        reused_diagnostics.clone(),
 8482                        cx,
 8483                    )?;
 8484
 8485                update.diagnostics.diagnostics.extend(reused_diagnostics);
 8486            } else if let Some(local) = self.as_local() {
 8487                let reused_diagnostics = local
 8488                    .diagnostics
 8489                    .get(&worktree_id)
 8490                    .and_then(|diagnostics_for_tree| diagnostics_for_tree.get(&project_path.path))
 8491                    .and_then(|diagnostics_by_server_id| {
 8492                        diagnostics_by_server_id
 8493                            .binary_search_by_key(&server_id, |e| e.0)
 8494                            .ok()
 8495                            .map(|ix| &diagnostics_by_server_id[ix].1)
 8496                    })
 8497                    .into_iter()
 8498                    .flatten()
 8499                    .filter(|v| merge(&document_uri, &v.diagnostic, cx));
 8500
 8501                update
 8502                    .diagnostics
 8503                    .diagnostics
 8504                    .extend(reused_diagnostics.cloned());
 8505            }
 8506
 8507            let updated = worktree.update(cx, |worktree, cx| {
 8508                self.update_worktree_diagnostics(
 8509                    worktree.id(),
 8510                    server_id,
 8511                    project_path.path.clone(),
 8512                    update.diagnostics.diagnostics,
 8513                    cx,
 8514                )
 8515            })?;
 8516            match updated {
 8517                ControlFlow::Continue(new_summary) => {
 8518                    if let Some((project_id, new_summary)) = new_summary {
 8519                        match &mut diagnostics_summary {
 8520                            Some(diagnostics_summary) => {
 8521                                diagnostics_summary
 8522                                    .more_summaries
 8523                                    .push(proto::DiagnosticSummary {
 8524                                        path: project_path.path.as_ref().to_proto(),
 8525                                        language_server_id: server_id.0 as u64,
 8526                                        error_count: new_summary.error_count,
 8527                                        warning_count: new_summary.warning_count,
 8528                                    })
 8529                            }
 8530                            None => {
 8531                                diagnostics_summary = Some(proto::UpdateDiagnosticSummary {
 8532                                    project_id,
 8533                                    worktree_id: worktree_id.to_proto(),
 8534                                    summary: Some(proto::DiagnosticSummary {
 8535                                        path: project_path.path.as_ref().to_proto(),
 8536                                        language_server_id: server_id.0 as u64,
 8537                                        error_count: new_summary.error_count,
 8538                                        warning_count: new_summary.warning_count,
 8539                                    }),
 8540                                    more_summaries: Vec::new(),
 8541                                })
 8542                            }
 8543                        }
 8544                    }
 8545                    updated_diagnostics_paths
 8546                        .entry(server_id)
 8547                        .or_insert_with(Vec::new)
 8548                        .push(project_path);
 8549                }
 8550                ControlFlow::Break(()) => {}
 8551            }
 8552        }
 8553
 8554        if let Some((diagnostics_summary, (downstream_client, _))) =
 8555            diagnostics_summary.zip(self.downstream_client.as_ref())
 8556        {
 8557            downstream_client.send(diagnostics_summary).log_err();
 8558        }
 8559        for (server_id, paths) in updated_diagnostics_paths {
 8560            cx.emit(LspStoreEvent::DiagnosticsUpdated { server_id, paths });
 8561        }
 8562        Ok(())
 8563    }
 8564
 8565    fn update_worktree_diagnostics(
 8566        &mut self,
 8567        worktree_id: WorktreeId,
 8568        server_id: LanguageServerId,
 8569        path_in_worktree: Arc<RelPath>,
 8570        diagnostics: Vec<DiagnosticEntry<Unclipped<PointUtf16>>>,
 8571        _: &mut Context<Worktree>,
 8572    ) -> Result<ControlFlow<(), Option<(u64, proto::DiagnosticSummary)>>> {
 8573        let local = match &mut self.mode {
 8574            LspStoreMode::Local(local_lsp_store) => local_lsp_store,
 8575            _ => anyhow::bail!("update_worktree_diagnostics called on remote"),
 8576        };
 8577
 8578        let summaries_for_tree = self.diagnostic_summaries.entry(worktree_id).or_default();
 8579        let diagnostics_for_tree = local.diagnostics.entry(worktree_id).or_default();
 8580        let summaries_by_server_id = summaries_for_tree
 8581            .entry(path_in_worktree.clone())
 8582            .or_default();
 8583
 8584        let old_summary = summaries_by_server_id
 8585            .remove(&server_id)
 8586            .unwrap_or_default();
 8587
 8588        let new_summary = DiagnosticSummary::new(&diagnostics);
 8589        if diagnostics.is_empty() {
 8590            if let Some(diagnostics_by_server_id) = diagnostics_for_tree.get_mut(&path_in_worktree)
 8591            {
 8592                if let Ok(ix) = diagnostics_by_server_id.binary_search_by_key(&server_id, |e| e.0) {
 8593                    diagnostics_by_server_id.remove(ix);
 8594                }
 8595                if diagnostics_by_server_id.is_empty() {
 8596                    diagnostics_for_tree.remove(&path_in_worktree);
 8597                }
 8598            }
 8599        } else {
 8600            summaries_by_server_id.insert(server_id, new_summary);
 8601            let diagnostics_by_server_id = diagnostics_for_tree
 8602                .entry(path_in_worktree.clone())
 8603                .or_default();
 8604            match diagnostics_by_server_id.binary_search_by_key(&server_id, |e| e.0) {
 8605                Ok(ix) => {
 8606                    diagnostics_by_server_id[ix] = (server_id, diagnostics);
 8607                }
 8608                Err(ix) => {
 8609                    diagnostics_by_server_id.insert(ix, (server_id, diagnostics));
 8610                }
 8611            }
 8612        }
 8613
 8614        if !old_summary.is_empty() || !new_summary.is_empty() {
 8615            if let Some((_, project_id)) = &self.downstream_client {
 8616                Ok(ControlFlow::Continue(Some((
 8617                    *project_id,
 8618                    proto::DiagnosticSummary {
 8619                        path: path_in_worktree.to_proto(),
 8620                        language_server_id: server_id.0 as u64,
 8621                        error_count: new_summary.error_count as u32,
 8622                        warning_count: new_summary.warning_count as u32,
 8623                    },
 8624                ))))
 8625            } else {
 8626                Ok(ControlFlow::Continue(None))
 8627            }
 8628        } else {
 8629            Ok(ControlFlow::Break(()))
 8630        }
 8631    }
 8632
 8633    pub fn open_buffer_for_symbol(
 8634        &mut self,
 8635        symbol: &Symbol,
 8636        cx: &mut Context<Self>,
 8637    ) -> Task<Result<Entity<Buffer>>> {
 8638        if let Some((client, project_id)) = self.upstream_client() {
 8639            let request = client.request(proto::OpenBufferForSymbol {
 8640                project_id,
 8641                symbol: Some(Self::serialize_symbol(symbol)),
 8642            });
 8643            cx.spawn(async move |this, cx| {
 8644                let response = request.await?;
 8645                let buffer_id = BufferId::new(response.buffer_id)?;
 8646                this.update(cx, |this, cx| this.wait_for_remote_buffer(buffer_id, cx))?
 8647                    .await
 8648            })
 8649        } else if let Some(local) = self.as_local() {
 8650            let is_valid = local.language_server_ids.iter().any(|(seed, state)| {
 8651                seed.worktree_id == symbol.source_worktree_id
 8652                    && state.id == symbol.source_language_server_id
 8653                    && symbol.language_server_name == seed.name
 8654            });
 8655            if !is_valid {
 8656                return Task::ready(Err(anyhow!(
 8657                    "language server for worktree and language not found"
 8658                )));
 8659            };
 8660
 8661            let symbol_abs_path = match &symbol.path {
 8662                SymbolLocation::InProject(project_path) => self
 8663                    .worktree_store
 8664                    .read(cx)
 8665                    .absolutize(&project_path, cx)
 8666                    .context("no such worktree"),
 8667                SymbolLocation::OutsideProject {
 8668                    abs_path,
 8669                    signature: _,
 8670                } => Ok(abs_path.to_path_buf()),
 8671            };
 8672            let symbol_abs_path = match symbol_abs_path {
 8673                Ok(abs_path) => abs_path,
 8674                Err(err) => return Task::ready(Err(err)),
 8675            };
 8676            let symbol_uri = if let Ok(uri) = lsp::Uri::from_file_path(symbol_abs_path) {
 8677                uri
 8678            } else {
 8679                return Task::ready(Err(anyhow!("invalid symbol path")));
 8680            };
 8681
 8682            self.open_local_buffer_via_lsp(symbol_uri, symbol.source_language_server_id, cx)
 8683        } else {
 8684            Task::ready(Err(anyhow!("no upstream client or local store")))
 8685        }
 8686    }
 8687
 8688    pub(crate) fn open_local_buffer_via_lsp(
 8689        &mut self,
 8690        abs_path: lsp::Uri,
 8691        language_server_id: LanguageServerId,
 8692        cx: &mut Context<Self>,
 8693    ) -> Task<Result<Entity<Buffer>>> {
 8694        cx.spawn(async move |lsp_store, cx| {
 8695            // Escape percent-encoded string.
 8696            let current_scheme = abs_path.scheme().to_owned();
 8697            // Uri is immutable, so we can't modify the scheme
 8698
 8699            let abs_path = abs_path
 8700                .to_file_path()
 8701                .map_err(|()| anyhow!("can't convert URI to path"))?;
 8702            let p = abs_path.clone();
 8703            let yarn_worktree = lsp_store
 8704                .update(cx, move |lsp_store, cx| match lsp_store.as_local() {
 8705                    Some(local_lsp_store) => local_lsp_store.yarn.update(cx, |_, cx| {
 8706                        cx.spawn(async move |this, cx| {
 8707                            let t = this
 8708                                .update(cx, |this, cx| this.process_path(&p, &current_scheme, cx))
 8709                                .ok()?;
 8710                            t.await
 8711                        })
 8712                    }),
 8713                    None => Task::ready(None),
 8714                })?
 8715                .await;
 8716            let (worktree_root_target, known_relative_path) =
 8717                if let Some((zip_root, relative_path)) = yarn_worktree {
 8718                    (zip_root, Some(relative_path))
 8719                } else {
 8720                    (Arc::<Path>::from(abs_path.as_path()), None)
 8721                };
 8722            let worktree = lsp_store.update(cx, |lsp_store, cx| {
 8723                lsp_store.worktree_store.update(cx, |worktree_store, cx| {
 8724                    worktree_store.find_worktree(&worktree_root_target, cx)
 8725                })
 8726            })?;
 8727            let (worktree, relative_path, source_ws) = if let Some(result) = worktree {
 8728                let relative_path = known_relative_path.unwrap_or_else(|| result.1.clone());
 8729                (result.0, relative_path, None)
 8730            } else {
 8731                let worktree = lsp_store
 8732                    .update(cx, |lsp_store, cx| {
 8733                        lsp_store.worktree_store.update(cx, |worktree_store, cx| {
 8734                            worktree_store.create_worktree(&worktree_root_target, false, cx)
 8735                        })
 8736                    })?
 8737                    .await?;
 8738                let worktree_root = worktree.read_with(cx, |worktree, _| worktree.abs_path())?;
 8739                let source_ws = if worktree.read_with(cx, |worktree, _| worktree.is_local())? {
 8740                    lsp_store
 8741                        .update(cx, |lsp_store, cx| {
 8742                            if let Some(local) = lsp_store.as_local_mut() {
 8743                                local.register_language_server_for_invisible_worktree(
 8744                                    &worktree,
 8745                                    language_server_id,
 8746                                    cx,
 8747                                )
 8748                            }
 8749                            match lsp_store.language_server_statuses.get(&language_server_id) {
 8750                                Some(status) => status.worktree,
 8751                                None => None,
 8752                            }
 8753                        })
 8754                        .ok()
 8755                        .flatten()
 8756                        .zip(Some(worktree_root.clone()))
 8757                } else {
 8758                    None
 8759                };
 8760                let relative_path = if let Some(known_path) = known_relative_path {
 8761                    known_path
 8762                } else {
 8763                    RelPath::new(abs_path.strip_prefix(worktree_root)?, PathStyle::local())?
 8764                        .into_arc()
 8765                };
 8766                (worktree, relative_path, source_ws)
 8767            };
 8768            let project_path = ProjectPath {
 8769                worktree_id: worktree.read_with(cx, |worktree, _| worktree.id())?,
 8770                path: relative_path,
 8771            };
 8772            let buffer = lsp_store
 8773                .update(cx, |lsp_store, cx| {
 8774                    lsp_store.buffer_store().update(cx, |buffer_store, cx| {
 8775                        buffer_store.open_buffer(project_path, cx)
 8776                    })
 8777                })?
 8778                .await?;
 8779            // we want to adhere to the read-only settings of the worktree we came from in case we opened an invisible one
 8780            if let Some((source_ws, worktree_root)) = source_ws {
 8781                buffer.update(cx, |buffer, cx| {
 8782                    let settings = WorktreeSettings::get(
 8783                        Some(
 8784                            (&ProjectPath {
 8785                                worktree_id: source_ws,
 8786                                path: Arc::from(RelPath::empty()),
 8787                            })
 8788                                .into(),
 8789                        ),
 8790                        cx,
 8791                    );
 8792                    let is_read_only = settings.is_std_path_read_only(&worktree_root);
 8793                    if is_read_only {
 8794                        buffer.set_capability(Capability::ReadOnly, cx);
 8795                    }
 8796                })?;
 8797            }
 8798            Ok(buffer)
 8799        })
 8800    }
 8801
 8802    fn request_multiple_lsp_locally<P, R>(
 8803        &mut self,
 8804        buffer: &Entity<Buffer>,
 8805        position: Option<P>,
 8806        request: R,
 8807        cx: &mut Context<Self>,
 8808    ) -> Task<Vec<(LanguageServerId, R::Response)>>
 8809    where
 8810        P: ToOffset,
 8811        R: LspCommand + Clone,
 8812        <R::LspRequest as lsp::request::Request>::Result: Send,
 8813        <R::LspRequest as lsp::request::Request>::Params: Send,
 8814    {
 8815        let Some(local) = self.as_local() else {
 8816            return Task::ready(Vec::new());
 8817        };
 8818
 8819        let snapshot = buffer.read(cx).snapshot();
 8820        let scope = position.and_then(|position| snapshot.language_scope_at(position));
 8821
 8822        let server_ids = buffer.update(cx, |buffer, cx| {
 8823            local
 8824                .language_servers_for_buffer(buffer, cx)
 8825                .filter(|(adapter, _)| {
 8826                    scope
 8827                        .as_ref()
 8828                        .map(|scope| scope.language_allowed(&adapter.name))
 8829                        .unwrap_or(true)
 8830                })
 8831                .map(|(_, server)| server.server_id())
 8832                .filter(|server_id| {
 8833                    self.as_local().is_none_or(|local| {
 8834                        local
 8835                            .buffers_opened_in_servers
 8836                            .get(&snapshot.remote_id())
 8837                            .is_some_and(|servers| servers.contains(server_id))
 8838                    })
 8839                })
 8840                .collect::<Vec<_>>()
 8841        });
 8842
 8843        let mut response_results = server_ids
 8844            .into_iter()
 8845            .map(|server_id| {
 8846                let task = self.request_lsp(
 8847                    buffer.clone(),
 8848                    LanguageServerToQuery::Other(server_id),
 8849                    request.clone(),
 8850                    cx,
 8851                );
 8852                async move { (server_id, task.await) }
 8853            })
 8854            .collect::<FuturesUnordered<_>>();
 8855
 8856        cx.background_spawn(async move {
 8857            let mut responses = Vec::with_capacity(response_results.len());
 8858            while let Some((server_id, response_result)) = response_results.next().await {
 8859                match response_result {
 8860                    Ok(response) => responses.push((server_id, response)),
 8861                    // rust-analyzer likes to error with this when its still loading up
 8862                    Err(e) if format!("{e:#}").ends_with("content modified") => (),
 8863                    Err(e) => log::error!("Error handling response for request {request:?}: {e:#}"),
 8864                }
 8865            }
 8866            responses
 8867        })
 8868    }
 8869
 8870    async fn handle_lsp_get_completions(
 8871        this: Entity<Self>,
 8872        envelope: TypedEnvelope<proto::GetCompletions>,
 8873        mut cx: AsyncApp,
 8874    ) -> Result<proto::GetCompletionsResponse> {
 8875        let sender_id = envelope.original_sender_id().unwrap_or_default();
 8876
 8877        let buffer_id = GetCompletions::buffer_id_from_proto(&envelope.payload)?;
 8878        let buffer_handle = this.update(&mut cx, |this, cx| {
 8879            this.buffer_store.read(cx).get_existing(buffer_id)
 8880        })??;
 8881        let request = GetCompletions::from_proto(
 8882            envelope.payload,
 8883            this.clone(),
 8884            buffer_handle.clone(),
 8885            cx.clone(),
 8886        )
 8887        .await?;
 8888
 8889        let server_to_query = match request.server_id {
 8890            Some(server_id) => LanguageServerToQuery::Other(server_id),
 8891            None => LanguageServerToQuery::FirstCapable,
 8892        };
 8893
 8894        let response = this
 8895            .update(&mut cx, |this, cx| {
 8896                this.request_lsp(buffer_handle.clone(), server_to_query, request, cx)
 8897            })?
 8898            .await?;
 8899        this.update(&mut cx, |this, cx| {
 8900            Ok(GetCompletions::response_to_proto(
 8901                response,
 8902                this,
 8903                sender_id,
 8904                &buffer_handle.read(cx).version(),
 8905                cx,
 8906            ))
 8907        })?
 8908    }
 8909
 8910    async fn handle_lsp_command<T: LspCommand>(
 8911        this: Entity<Self>,
 8912        envelope: TypedEnvelope<T::ProtoRequest>,
 8913        mut cx: AsyncApp,
 8914    ) -> Result<<T::ProtoRequest as proto::RequestMessage>::Response>
 8915    where
 8916        <T::LspRequest as lsp::request::Request>::Params: Send,
 8917        <T::LspRequest as lsp::request::Request>::Result: Send,
 8918    {
 8919        let sender_id = envelope.original_sender_id().unwrap_or_default();
 8920        let buffer_id = T::buffer_id_from_proto(&envelope.payload)?;
 8921        let buffer_handle = this.update(&mut cx, |this, cx| {
 8922            this.buffer_store.read(cx).get_existing(buffer_id)
 8923        })??;
 8924        let request = T::from_proto(
 8925            envelope.payload,
 8926            this.clone(),
 8927            buffer_handle.clone(),
 8928            cx.clone(),
 8929        )
 8930        .await?;
 8931        let response = this
 8932            .update(&mut cx, |this, cx| {
 8933                this.request_lsp(
 8934                    buffer_handle.clone(),
 8935                    LanguageServerToQuery::FirstCapable,
 8936                    request,
 8937                    cx,
 8938                )
 8939            })?
 8940            .await?;
 8941        this.update(&mut cx, |this, cx| {
 8942            Ok(T::response_to_proto(
 8943                response,
 8944                this,
 8945                sender_id,
 8946                &buffer_handle.read(cx).version(),
 8947                cx,
 8948            ))
 8949        })?
 8950    }
 8951
 8952    async fn handle_lsp_query(
 8953        lsp_store: Entity<Self>,
 8954        envelope: TypedEnvelope<proto::LspQuery>,
 8955        mut cx: AsyncApp,
 8956    ) -> Result<proto::Ack> {
 8957        use proto::lsp_query::Request;
 8958        let sender_id = envelope.original_sender_id().unwrap_or_default();
 8959        let lsp_query = envelope.payload;
 8960        let lsp_request_id = LspRequestId(lsp_query.lsp_request_id);
 8961        let server_id = lsp_query.server_id.map(LanguageServerId::from_proto);
 8962        match lsp_query.request.context("invalid LSP query request")? {
 8963            Request::GetReferences(get_references) => {
 8964                let position = get_references.position.clone().and_then(deserialize_anchor);
 8965                Self::query_lsp_locally::<GetReferences>(
 8966                    lsp_store,
 8967                    server_id,
 8968                    sender_id,
 8969                    lsp_request_id,
 8970                    get_references,
 8971                    position,
 8972                    &mut cx,
 8973                )
 8974                .await?;
 8975            }
 8976            Request::GetDocumentColor(get_document_color) => {
 8977                Self::query_lsp_locally::<GetDocumentColor>(
 8978                    lsp_store,
 8979                    server_id,
 8980                    sender_id,
 8981                    lsp_request_id,
 8982                    get_document_color,
 8983                    None,
 8984                    &mut cx,
 8985                )
 8986                .await?;
 8987            }
 8988            Request::GetHover(get_hover) => {
 8989                let position = get_hover.position.clone().and_then(deserialize_anchor);
 8990                Self::query_lsp_locally::<GetHover>(
 8991                    lsp_store,
 8992                    server_id,
 8993                    sender_id,
 8994                    lsp_request_id,
 8995                    get_hover,
 8996                    position,
 8997                    &mut cx,
 8998                )
 8999                .await?;
 9000            }
 9001            Request::GetCodeActions(get_code_actions) => {
 9002                Self::query_lsp_locally::<GetCodeActions>(
 9003                    lsp_store,
 9004                    server_id,
 9005                    sender_id,
 9006                    lsp_request_id,
 9007                    get_code_actions,
 9008                    None,
 9009                    &mut cx,
 9010                )
 9011                .await?;
 9012            }
 9013            Request::GetSignatureHelp(get_signature_help) => {
 9014                let position = get_signature_help
 9015                    .position
 9016                    .clone()
 9017                    .and_then(deserialize_anchor);
 9018                Self::query_lsp_locally::<GetSignatureHelp>(
 9019                    lsp_store,
 9020                    server_id,
 9021                    sender_id,
 9022                    lsp_request_id,
 9023                    get_signature_help,
 9024                    position,
 9025                    &mut cx,
 9026                )
 9027                .await?;
 9028            }
 9029            Request::GetCodeLens(get_code_lens) => {
 9030                Self::query_lsp_locally::<GetCodeLens>(
 9031                    lsp_store,
 9032                    server_id,
 9033                    sender_id,
 9034                    lsp_request_id,
 9035                    get_code_lens,
 9036                    None,
 9037                    &mut cx,
 9038                )
 9039                .await?;
 9040            }
 9041            Request::GetDefinition(get_definition) => {
 9042                let position = get_definition.position.clone().and_then(deserialize_anchor);
 9043                Self::query_lsp_locally::<GetDefinitions>(
 9044                    lsp_store,
 9045                    server_id,
 9046                    sender_id,
 9047                    lsp_request_id,
 9048                    get_definition,
 9049                    position,
 9050                    &mut cx,
 9051                )
 9052                .await?;
 9053            }
 9054            Request::GetDeclaration(get_declaration) => {
 9055                let position = get_declaration
 9056                    .position
 9057                    .clone()
 9058                    .and_then(deserialize_anchor);
 9059                Self::query_lsp_locally::<GetDeclarations>(
 9060                    lsp_store,
 9061                    server_id,
 9062                    sender_id,
 9063                    lsp_request_id,
 9064                    get_declaration,
 9065                    position,
 9066                    &mut cx,
 9067                )
 9068                .await?;
 9069            }
 9070            Request::GetTypeDefinition(get_type_definition) => {
 9071                let position = get_type_definition
 9072                    .position
 9073                    .clone()
 9074                    .and_then(deserialize_anchor);
 9075                Self::query_lsp_locally::<GetTypeDefinitions>(
 9076                    lsp_store,
 9077                    server_id,
 9078                    sender_id,
 9079                    lsp_request_id,
 9080                    get_type_definition,
 9081                    position,
 9082                    &mut cx,
 9083                )
 9084                .await?;
 9085            }
 9086            Request::GetImplementation(get_implementation) => {
 9087                let position = get_implementation
 9088                    .position
 9089                    .clone()
 9090                    .and_then(deserialize_anchor);
 9091                Self::query_lsp_locally::<GetImplementations>(
 9092                    lsp_store,
 9093                    server_id,
 9094                    sender_id,
 9095                    lsp_request_id,
 9096                    get_implementation,
 9097                    position,
 9098                    &mut cx,
 9099                )
 9100                .await?;
 9101            }
 9102            Request::GetDocumentDiagnostics(get_document_diagnostics) => {
 9103                let buffer_id = BufferId::new(get_document_diagnostics.buffer_id())?;
 9104                let version = deserialize_version(get_document_diagnostics.buffer_version());
 9105                let buffer = lsp_store.update(&mut cx, |this, cx| {
 9106                    this.buffer_store.read(cx).get_existing(buffer_id)
 9107                })??;
 9108                buffer
 9109                    .update(&mut cx, |buffer, _| {
 9110                        buffer.wait_for_version(version.clone())
 9111                    })?
 9112                    .await?;
 9113                lsp_store.update(&mut cx, |lsp_store, cx| {
 9114                    let lsp_data = lsp_store.latest_lsp_data(&buffer, cx);
 9115                    let key = LspKey {
 9116                        request_type: TypeId::of::<GetDocumentDiagnostics>(),
 9117                        server_queried: server_id,
 9118                    };
 9119                    if <GetDocumentDiagnostics as LspCommand>::ProtoRequest::stop_previous_requests(
 9120                    ) {
 9121                        if let Some(lsp_requests) = lsp_data.lsp_requests.get_mut(&key) {
 9122                            lsp_requests.clear();
 9123                        };
 9124                    }
 9125
 9126                    let existing_queries = lsp_data.lsp_requests.entry(key).or_default();
 9127                    existing_queries.insert(
 9128                        lsp_request_id,
 9129                        cx.spawn(async move |lsp_store, cx| {
 9130                            let diagnostics_pull = lsp_store
 9131                                .update(cx, |lsp_store, cx| {
 9132                                    lsp_store.pull_diagnostics_for_buffer(buffer, cx)
 9133                                })
 9134                                .ok();
 9135                            if let Some(diagnostics_pull) = diagnostics_pull {
 9136                                match diagnostics_pull.await {
 9137                                    Ok(()) => {}
 9138                                    Err(e) => log::error!("Failed to pull diagnostics: {e:#}"),
 9139                                };
 9140                            }
 9141                        }),
 9142                    );
 9143                })?;
 9144            }
 9145            Request::InlayHints(inlay_hints) => {
 9146                let query_start = inlay_hints
 9147                    .start
 9148                    .clone()
 9149                    .and_then(deserialize_anchor)
 9150                    .context("invalid inlay hints range start")?;
 9151                let query_end = inlay_hints
 9152                    .end
 9153                    .clone()
 9154                    .and_then(deserialize_anchor)
 9155                    .context("invalid inlay hints range end")?;
 9156                Self::deduplicate_range_based_lsp_requests::<InlayHints>(
 9157                    &lsp_store,
 9158                    server_id,
 9159                    lsp_request_id,
 9160                    &inlay_hints,
 9161                    query_start..query_end,
 9162                    &mut cx,
 9163                )
 9164                .await
 9165                .context("preparing inlay hints request")?;
 9166                Self::query_lsp_locally::<InlayHints>(
 9167                    lsp_store,
 9168                    server_id,
 9169                    sender_id,
 9170                    lsp_request_id,
 9171                    inlay_hints,
 9172                    None,
 9173                    &mut cx,
 9174                )
 9175                .await
 9176                .context("querying for inlay hints")?
 9177            }
 9178        }
 9179        Ok(proto::Ack {})
 9180    }
 9181
 9182    async fn handle_lsp_query_response(
 9183        lsp_store: Entity<Self>,
 9184        envelope: TypedEnvelope<proto::LspQueryResponse>,
 9185        cx: AsyncApp,
 9186    ) -> Result<()> {
 9187        lsp_store.read_with(&cx, |lsp_store, _| {
 9188            if let Some((upstream_client, _)) = lsp_store.upstream_client() {
 9189                upstream_client.handle_lsp_response(envelope.clone());
 9190            }
 9191        })?;
 9192        Ok(())
 9193    }
 9194
 9195    async fn handle_apply_code_action(
 9196        this: Entity<Self>,
 9197        envelope: TypedEnvelope<proto::ApplyCodeAction>,
 9198        mut cx: AsyncApp,
 9199    ) -> Result<proto::ApplyCodeActionResponse> {
 9200        let sender_id = envelope.original_sender_id().unwrap_or_default();
 9201        let action =
 9202            Self::deserialize_code_action(envelope.payload.action.context("invalid action")?)?;
 9203        let apply_code_action = this.update(&mut cx, |this, cx| {
 9204            let buffer_id = BufferId::new(envelope.payload.buffer_id)?;
 9205            let buffer = this.buffer_store.read(cx).get_existing(buffer_id)?;
 9206            anyhow::Ok(this.apply_code_action(buffer, action, false, cx))
 9207        })??;
 9208
 9209        let project_transaction = apply_code_action.await?;
 9210        let project_transaction = this.update(&mut cx, |this, cx| {
 9211            this.buffer_store.update(cx, |buffer_store, cx| {
 9212                buffer_store.serialize_project_transaction_for_peer(
 9213                    project_transaction,
 9214                    sender_id,
 9215                    cx,
 9216                )
 9217            })
 9218        })?;
 9219        Ok(proto::ApplyCodeActionResponse {
 9220            transaction: Some(project_transaction),
 9221        })
 9222    }
 9223
 9224    async fn handle_register_buffer_with_language_servers(
 9225        this: Entity<Self>,
 9226        envelope: TypedEnvelope<proto::RegisterBufferWithLanguageServers>,
 9227        mut cx: AsyncApp,
 9228    ) -> Result<proto::Ack> {
 9229        let buffer_id = BufferId::new(envelope.payload.buffer_id)?;
 9230        let peer_id = envelope.original_sender_id.unwrap_or(envelope.sender_id);
 9231        this.update(&mut cx, |this, cx| {
 9232            if let Some((upstream_client, upstream_project_id)) = this.upstream_client() {
 9233                return upstream_client.send(proto::RegisterBufferWithLanguageServers {
 9234                    project_id: upstream_project_id,
 9235                    buffer_id: buffer_id.to_proto(),
 9236                    only_servers: envelope.payload.only_servers,
 9237                });
 9238            }
 9239
 9240            let Some(buffer) = this.buffer_store().read(cx).get(buffer_id) else {
 9241                anyhow::bail!("buffer is not open");
 9242            };
 9243
 9244            let handle = this.register_buffer_with_language_servers(
 9245                &buffer,
 9246                envelope
 9247                    .payload
 9248                    .only_servers
 9249                    .into_iter()
 9250                    .filter_map(|selector| {
 9251                        Some(match selector.selector? {
 9252                            proto::language_server_selector::Selector::ServerId(server_id) => {
 9253                                LanguageServerSelector::Id(LanguageServerId::from_proto(server_id))
 9254                            }
 9255                            proto::language_server_selector::Selector::Name(name) => {
 9256                                LanguageServerSelector::Name(LanguageServerName(
 9257                                    SharedString::from(name),
 9258                                ))
 9259                            }
 9260                        })
 9261                    })
 9262                    .collect(),
 9263                false,
 9264                cx,
 9265            );
 9266            this.buffer_store().update(cx, |buffer_store, _| {
 9267                buffer_store.register_shared_lsp_handle(peer_id, buffer_id, handle);
 9268            });
 9269
 9270            Ok(())
 9271        })??;
 9272        Ok(proto::Ack {})
 9273    }
 9274
 9275    async fn handle_rename_project_entry(
 9276        this: Entity<Self>,
 9277        envelope: TypedEnvelope<proto::RenameProjectEntry>,
 9278        mut cx: AsyncApp,
 9279    ) -> Result<proto::ProjectEntryResponse> {
 9280        let entry_id = ProjectEntryId::from_proto(envelope.payload.entry_id);
 9281        let new_worktree_id = WorktreeId::from_proto(envelope.payload.new_worktree_id);
 9282        let new_path =
 9283            RelPath::from_proto(&envelope.payload.new_path).context("invalid relative path")?;
 9284
 9285        let (worktree_store, old_worktree, new_worktree, old_entry) = this
 9286            .update(&mut cx, |this, cx| {
 9287                let (worktree, entry) = this
 9288                    .worktree_store
 9289                    .read(cx)
 9290                    .worktree_and_entry_for_id(entry_id, cx)?;
 9291                let new_worktree = this
 9292                    .worktree_store
 9293                    .read(cx)
 9294                    .worktree_for_id(new_worktree_id, cx)?;
 9295                Some((
 9296                    this.worktree_store.clone(),
 9297                    worktree,
 9298                    new_worktree,
 9299                    entry.clone(),
 9300                ))
 9301            })?
 9302            .context("worktree not found")?;
 9303        let (old_abs_path, old_worktree_id) = old_worktree.read_with(&cx, |worktree, _| {
 9304            (worktree.absolutize(&old_entry.path), worktree.id())
 9305        })?;
 9306        let new_abs_path =
 9307            new_worktree.read_with(&cx, |worktree, _| worktree.absolutize(&new_path))?;
 9308
 9309        let _transaction = Self::will_rename_entry(
 9310            this.downgrade(),
 9311            old_worktree_id,
 9312            &old_abs_path,
 9313            &new_abs_path,
 9314            old_entry.is_dir(),
 9315            cx.clone(),
 9316        )
 9317        .await;
 9318        let response = WorktreeStore::handle_rename_project_entry(
 9319            worktree_store,
 9320            envelope.payload,
 9321            cx.clone(),
 9322        )
 9323        .await;
 9324        this.read_with(&cx, |this, _| {
 9325            this.did_rename_entry(
 9326                old_worktree_id,
 9327                &old_abs_path,
 9328                &new_abs_path,
 9329                old_entry.is_dir(),
 9330            );
 9331        })
 9332        .ok();
 9333        response
 9334    }
 9335
 9336    async fn handle_update_diagnostic_summary(
 9337        this: Entity<Self>,
 9338        envelope: TypedEnvelope<proto::UpdateDiagnosticSummary>,
 9339        mut cx: AsyncApp,
 9340    ) -> Result<()> {
 9341        this.update(&mut cx, |lsp_store, cx| {
 9342            let worktree_id = WorktreeId::from_proto(envelope.payload.worktree_id);
 9343            let mut updated_diagnostics_paths = HashMap::default();
 9344            let mut diagnostics_summary = None::<proto::UpdateDiagnosticSummary>;
 9345            for message_summary in envelope
 9346                .payload
 9347                .summary
 9348                .into_iter()
 9349                .chain(envelope.payload.more_summaries)
 9350            {
 9351                let project_path = ProjectPath {
 9352                    worktree_id,
 9353                    path: RelPath::from_proto(&message_summary.path).context("invalid path")?,
 9354                };
 9355                let path = project_path.path.clone();
 9356                let server_id = LanguageServerId(message_summary.language_server_id as usize);
 9357                let summary = DiagnosticSummary {
 9358                    error_count: message_summary.error_count as usize,
 9359                    warning_count: message_summary.warning_count as usize,
 9360                };
 9361
 9362                if summary.is_empty() {
 9363                    if let Some(worktree_summaries) =
 9364                        lsp_store.diagnostic_summaries.get_mut(&worktree_id)
 9365                        && let Some(summaries) = worktree_summaries.get_mut(&path)
 9366                    {
 9367                        summaries.remove(&server_id);
 9368                        if summaries.is_empty() {
 9369                            worktree_summaries.remove(&path);
 9370                        }
 9371                    }
 9372                } else {
 9373                    lsp_store
 9374                        .diagnostic_summaries
 9375                        .entry(worktree_id)
 9376                        .or_default()
 9377                        .entry(path)
 9378                        .or_default()
 9379                        .insert(server_id, summary);
 9380                }
 9381
 9382                if let Some((_, project_id)) = &lsp_store.downstream_client {
 9383                    match &mut diagnostics_summary {
 9384                        Some(diagnostics_summary) => {
 9385                            diagnostics_summary
 9386                                .more_summaries
 9387                                .push(proto::DiagnosticSummary {
 9388                                    path: project_path.path.as_ref().to_proto(),
 9389                                    language_server_id: server_id.0 as u64,
 9390                                    error_count: summary.error_count as u32,
 9391                                    warning_count: summary.warning_count as u32,
 9392                                })
 9393                        }
 9394                        None => {
 9395                            diagnostics_summary = Some(proto::UpdateDiagnosticSummary {
 9396                                project_id: *project_id,
 9397                                worktree_id: worktree_id.to_proto(),
 9398                                summary: Some(proto::DiagnosticSummary {
 9399                                    path: project_path.path.as_ref().to_proto(),
 9400                                    language_server_id: server_id.0 as u64,
 9401                                    error_count: summary.error_count as u32,
 9402                                    warning_count: summary.warning_count as u32,
 9403                                }),
 9404                                more_summaries: Vec::new(),
 9405                            })
 9406                        }
 9407                    }
 9408                }
 9409                updated_diagnostics_paths
 9410                    .entry(server_id)
 9411                    .or_insert_with(Vec::new)
 9412                    .push(project_path);
 9413            }
 9414
 9415            if let Some((diagnostics_summary, (downstream_client, _))) =
 9416                diagnostics_summary.zip(lsp_store.downstream_client.as_ref())
 9417            {
 9418                downstream_client.send(diagnostics_summary).log_err();
 9419            }
 9420            for (server_id, paths) in updated_diagnostics_paths {
 9421                cx.emit(LspStoreEvent::DiagnosticsUpdated { server_id, paths });
 9422            }
 9423            Ok(())
 9424        })?
 9425    }
 9426
 9427    async fn handle_start_language_server(
 9428        lsp_store: Entity<Self>,
 9429        envelope: TypedEnvelope<proto::StartLanguageServer>,
 9430        mut cx: AsyncApp,
 9431    ) -> Result<()> {
 9432        let server = envelope.payload.server.context("invalid server")?;
 9433        let server_capabilities =
 9434            serde_json::from_str::<lsp::ServerCapabilities>(&envelope.payload.capabilities)
 9435                .with_context(|| {
 9436                    format!(
 9437                        "incorrect server capabilities {}",
 9438                        envelope.payload.capabilities
 9439                    )
 9440                })?;
 9441        lsp_store.update(&mut cx, |lsp_store, cx| {
 9442            let server_id = LanguageServerId(server.id as usize);
 9443            let server_name = LanguageServerName::from_proto(server.name.clone());
 9444            lsp_store
 9445                .lsp_server_capabilities
 9446                .insert(server_id, server_capabilities);
 9447            lsp_store.language_server_statuses.insert(
 9448                server_id,
 9449                LanguageServerStatus {
 9450                    name: server_name.clone(),
 9451                    server_version: None,
 9452                    pending_work: Default::default(),
 9453                    has_pending_diagnostic_updates: false,
 9454                    progress_tokens: Default::default(),
 9455                    worktree: server.worktree_id.map(WorktreeId::from_proto),
 9456                    binary: None,
 9457                    configuration: None,
 9458                    workspace_folders: BTreeSet::new(),
 9459                },
 9460            );
 9461            cx.emit(LspStoreEvent::LanguageServerAdded(
 9462                server_id,
 9463                server_name,
 9464                server.worktree_id.map(WorktreeId::from_proto),
 9465            ));
 9466            cx.notify();
 9467        })?;
 9468        Ok(())
 9469    }
 9470
 9471    async fn handle_update_language_server(
 9472        lsp_store: Entity<Self>,
 9473        envelope: TypedEnvelope<proto::UpdateLanguageServer>,
 9474        mut cx: AsyncApp,
 9475    ) -> Result<()> {
 9476        lsp_store.update(&mut cx, |lsp_store, cx| {
 9477            let language_server_id = LanguageServerId(envelope.payload.language_server_id as usize);
 9478
 9479            match envelope.payload.variant.context("invalid variant")? {
 9480                proto::update_language_server::Variant::WorkStart(payload) => {
 9481                    lsp_store.on_lsp_work_start(
 9482                        language_server_id,
 9483                        ProgressToken::from_proto(payload.token.context("missing progress token")?)
 9484                            .context("invalid progress token value")?,
 9485                        LanguageServerProgress {
 9486                            title: payload.title,
 9487                            is_disk_based_diagnostics_progress: false,
 9488                            is_cancellable: payload.is_cancellable.unwrap_or(false),
 9489                            message: payload.message,
 9490                            percentage: payload.percentage.map(|p| p as usize),
 9491                            last_update_at: cx.background_executor().now(),
 9492                        },
 9493                        cx,
 9494                    );
 9495                }
 9496                proto::update_language_server::Variant::WorkProgress(payload) => {
 9497                    lsp_store.on_lsp_work_progress(
 9498                        language_server_id,
 9499                        ProgressToken::from_proto(payload.token.context("missing progress token")?)
 9500                            .context("invalid progress token value")?,
 9501                        LanguageServerProgress {
 9502                            title: None,
 9503                            is_disk_based_diagnostics_progress: false,
 9504                            is_cancellable: payload.is_cancellable.unwrap_or(false),
 9505                            message: payload.message,
 9506                            percentage: payload.percentage.map(|p| p as usize),
 9507                            last_update_at: cx.background_executor().now(),
 9508                        },
 9509                        cx,
 9510                    );
 9511                }
 9512
 9513                proto::update_language_server::Variant::WorkEnd(payload) => {
 9514                    lsp_store.on_lsp_work_end(
 9515                        language_server_id,
 9516                        ProgressToken::from_proto(payload.token.context("missing progress token")?)
 9517                            .context("invalid progress token value")?,
 9518                        cx,
 9519                    );
 9520                }
 9521
 9522                proto::update_language_server::Variant::DiskBasedDiagnosticsUpdating(_) => {
 9523                    lsp_store.disk_based_diagnostics_started(language_server_id, cx);
 9524                }
 9525
 9526                proto::update_language_server::Variant::DiskBasedDiagnosticsUpdated(_) => {
 9527                    lsp_store.disk_based_diagnostics_finished(language_server_id, cx)
 9528                }
 9529
 9530                non_lsp @ proto::update_language_server::Variant::StatusUpdate(_)
 9531                | non_lsp @ proto::update_language_server::Variant::RegisteredForBuffer(_)
 9532                | non_lsp @ proto::update_language_server::Variant::MetadataUpdated(_) => {
 9533                    cx.emit(LspStoreEvent::LanguageServerUpdate {
 9534                        language_server_id,
 9535                        name: envelope
 9536                            .payload
 9537                            .server_name
 9538                            .map(SharedString::new)
 9539                            .map(LanguageServerName),
 9540                        message: non_lsp,
 9541                    });
 9542                }
 9543            }
 9544
 9545            Ok(())
 9546        })?
 9547    }
 9548
 9549    async fn handle_language_server_log(
 9550        this: Entity<Self>,
 9551        envelope: TypedEnvelope<proto::LanguageServerLog>,
 9552        mut cx: AsyncApp,
 9553    ) -> Result<()> {
 9554        let language_server_id = LanguageServerId(envelope.payload.language_server_id as usize);
 9555        let log_type = envelope
 9556            .payload
 9557            .log_type
 9558            .map(LanguageServerLogType::from_proto)
 9559            .context("invalid language server log type")?;
 9560
 9561        let message = envelope.payload.message;
 9562
 9563        this.update(&mut cx, |_, cx| {
 9564            cx.emit(LspStoreEvent::LanguageServerLog(
 9565                language_server_id,
 9566                log_type,
 9567                message,
 9568            ));
 9569        })
 9570    }
 9571
 9572    async fn handle_lsp_ext_cancel_flycheck(
 9573        lsp_store: Entity<Self>,
 9574        envelope: TypedEnvelope<proto::LspExtCancelFlycheck>,
 9575        cx: AsyncApp,
 9576    ) -> Result<proto::Ack> {
 9577        let server_id = LanguageServerId(envelope.payload.language_server_id as usize);
 9578        let task = lsp_store.read_with(&cx, |lsp_store, _| {
 9579            if let Some(server) = lsp_store.language_server_for_id(server_id) {
 9580                Some(server.notify::<lsp_store::lsp_ext_command::LspExtCancelFlycheck>(()))
 9581            } else {
 9582                None
 9583            }
 9584        })?;
 9585        if let Some(task) = task {
 9586            task.context("handling lsp ext cancel flycheck")?;
 9587        }
 9588
 9589        Ok(proto::Ack {})
 9590    }
 9591
 9592    async fn handle_lsp_ext_run_flycheck(
 9593        lsp_store: Entity<Self>,
 9594        envelope: TypedEnvelope<proto::LspExtRunFlycheck>,
 9595        mut cx: AsyncApp,
 9596    ) -> Result<proto::Ack> {
 9597        let server_id = LanguageServerId(envelope.payload.language_server_id as usize);
 9598        lsp_store.update(&mut cx, |lsp_store, cx| {
 9599            if let Some(server) = lsp_store.language_server_for_id(server_id) {
 9600                let text_document = if envelope.payload.current_file_only {
 9601                    let buffer_id = envelope
 9602                        .payload
 9603                        .buffer_id
 9604                        .map(|id| BufferId::new(id))
 9605                        .transpose()?;
 9606                    buffer_id
 9607                        .and_then(|buffer_id| {
 9608                            lsp_store
 9609                                .buffer_store()
 9610                                .read(cx)
 9611                                .get(buffer_id)
 9612                                .and_then(|buffer| {
 9613                                    Some(buffer.read(cx).file()?.as_local()?.abs_path(cx))
 9614                                })
 9615                                .map(|path| make_text_document_identifier(&path))
 9616                        })
 9617                        .transpose()?
 9618                } else {
 9619                    None
 9620                };
 9621                server.notify::<lsp_store::lsp_ext_command::LspExtRunFlycheck>(
 9622                    lsp_store::lsp_ext_command::RunFlycheckParams { text_document },
 9623                )?;
 9624            }
 9625            anyhow::Ok(())
 9626        })??;
 9627
 9628        Ok(proto::Ack {})
 9629    }
 9630
 9631    async fn handle_lsp_ext_clear_flycheck(
 9632        lsp_store: Entity<Self>,
 9633        envelope: TypedEnvelope<proto::LspExtClearFlycheck>,
 9634        cx: AsyncApp,
 9635    ) -> Result<proto::Ack> {
 9636        let server_id = LanguageServerId(envelope.payload.language_server_id as usize);
 9637        lsp_store
 9638            .read_with(&cx, |lsp_store, _| {
 9639                if let Some(server) = lsp_store.language_server_for_id(server_id) {
 9640                    Some(server.notify::<lsp_store::lsp_ext_command::LspExtClearFlycheck>(()))
 9641                } else {
 9642                    None
 9643                }
 9644            })
 9645            .context("handling lsp ext clear flycheck")?;
 9646
 9647        Ok(proto::Ack {})
 9648    }
 9649
 9650    pub fn disk_based_diagnostics_started(
 9651        &mut self,
 9652        language_server_id: LanguageServerId,
 9653        cx: &mut Context<Self>,
 9654    ) {
 9655        if let Some(language_server_status) =
 9656            self.language_server_statuses.get_mut(&language_server_id)
 9657        {
 9658            language_server_status.has_pending_diagnostic_updates = true;
 9659        }
 9660
 9661        cx.emit(LspStoreEvent::DiskBasedDiagnosticsStarted { language_server_id });
 9662        cx.emit(LspStoreEvent::LanguageServerUpdate {
 9663            language_server_id,
 9664            name: self
 9665                .language_server_adapter_for_id(language_server_id)
 9666                .map(|adapter| adapter.name()),
 9667            message: proto::update_language_server::Variant::DiskBasedDiagnosticsUpdating(
 9668                Default::default(),
 9669            ),
 9670        })
 9671    }
 9672
 9673    pub fn disk_based_diagnostics_finished(
 9674        &mut self,
 9675        language_server_id: LanguageServerId,
 9676        cx: &mut Context<Self>,
 9677    ) {
 9678        if let Some(language_server_status) =
 9679            self.language_server_statuses.get_mut(&language_server_id)
 9680        {
 9681            language_server_status.has_pending_diagnostic_updates = false;
 9682        }
 9683
 9684        cx.emit(LspStoreEvent::DiskBasedDiagnosticsFinished { language_server_id });
 9685        cx.emit(LspStoreEvent::LanguageServerUpdate {
 9686            language_server_id,
 9687            name: self
 9688                .language_server_adapter_for_id(language_server_id)
 9689                .map(|adapter| adapter.name()),
 9690            message: proto::update_language_server::Variant::DiskBasedDiagnosticsUpdated(
 9691                Default::default(),
 9692            ),
 9693        })
 9694    }
 9695
 9696    // After saving a buffer using a language server that doesn't provide a disk-based progress token,
 9697    // kick off a timer that will reset every time the buffer is saved. If the timer eventually fires,
 9698    // simulate disk-based diagnostics being finished so that other pieces of UI (e.g., project
 9699    // diagnostics view, diagnostic status bar) can update. We don't emit an event right away because
 9700    // the language server might take some time to publish diagnostics.
 9701    fn simulate_disk_based_diagnostics_events_if_needed(
 9702        &mut self,
 9703        language_server_id: LanguageServerId,
 9704        cx: &mut Context<Self>,
 9705    ) {
 9706        const DISK_BASED_DIAGNOSTICS_DEBOUNCE: Duration = Duration::from_secs(1);
 9707
 9708        let Some(LanguageServerState::Running {
 9709            simulate_disk_based_diagnostics_completion,
 9710            adapter,
 9711            ..
 9712        }) = self
 9713            .as_local_mut()
 9714            .and_then(|local_store| local_store.language_servers.get_mut(&language_server_id))
 9715        else {
 9716            return;
 9717        };
 9718
 9719        if adapter.disk_based_diagnostics_progress_token.is_some() {
 9720            return;
 9721        }
 9722
 9723        let prev_task =
 9724            simulate_disk_based_diagnostics_completion.replace(cx.spawn(async move |this, cx| {
 9725                cx.background_executor()
 9726                    .timer(DISK_BASED_DIAGNOSTICS_DEBOUNCE)
 9727                    .await;
 9728
 9729                this.update(cx, |this, cx| {
 9730                    this.disk_based_diagnostics_finished(language_server_id, cx);
 9731
 9732                    if let Some(LanguageServerState::Running {
 9733                        simulate_disk_based_diagnostics_completion,
 9734                        ..
 9735                    }) = this.as_local_mut().and_then(|local_store| {
 9736                        local_store.language_servers.get_mut(&language_server_id)
 9737                    }) {
 9738                        *simulate_disk_based_diagnostics_completion = None;
 9739                    }
 9740                })
 9741                .ok();
 9742            }));
 9743
 9744        if prev_task.is_none() {
 9745            self.disk_based_diagnostics_started(language_server_id, cx);
 9746        }
 9747    }
 9748
 9749    pub fn language_server_statuses(
 9750        &self,
 9751    ) -> impl DoubleEndedIterator<Item = (LanguageServerId, &LanguageServerStatus)> {
 9752        self.language_server_statuses
 9753            .iter()
 9754            .map(|(key, value)| (*key, value))
 9755    }
 9756
 9757    pub(super) fn did_rename_entry(
 9758        &self,
 9759        worktree_id: WorktreeId,
 9760        old_path: &Path,
 9761        new_path: &Path,
 9762        is_dir: bool,
 9763    ) {
 9764        maybe!({
 9765            let local_store = self.as_local()?;
 9766
 9767            let old_uri = lsp::Uri::from_file_path(old_path)
 9768                .ok()
 9769                .map(|uri| uri.to_string())?;
 9770            let new_uri = lsp::Uri::from_file_path(new_path)
 9771                .ok()
 9772                .map(|uri| uri.to_string())?;
 9773
 9774            for language_server in local_store.language_servers_for_worktree(worktree_id) {
 9775                let Some(filter) = local_store
 9776                    .language_server_paths_watched_for_rename
 9777                    .get(&language_server.server_id())
 9778                else {
 9779                    continue;
 9780                };
 9781
 9782                if filter.should_send_did_rename(&old_uri, is_dir) {
 9783                    language_server
 9784                        .notify::<DidRenameFiles>(RenameFilesParams {
 9785                            files: vec![FileRename {
 9786                                old_uri: old_uri.clone(),
 9787                                new_uri: new_uri.clone(),
 9788                            }],
 9789                        })
 9790                        .ok();
 9791                }
 9792            }
 9793            Some(())
 9794        });
 9795    }
 9796
 9797    pub(super) fn will_rename_entry(
 9798        this: WeakEntity<Self>,
 9799        worktree_id: WorktreeId,
 9800        old_path: &Path,
 9801        new_path: &Path,
 9802        is_dir: bool,
 9803        cx: AsyncApp,
 9804    ) -> Task<ProjectTransaction> {
 9805        let old_uri = lsp::Uri::from_file_path(old_path)
 9806            .ok()
 9807            .map(|uri| uri.to_string());
 9808        let new_uri = lsp::Uri::from_file_path(new_path)
 9809            .ok()
 9810            .map(|uri| uri.to_string());
 9811        cx.spawn(async move |cx| {
 9812            let mut tasks = vec![];
 9813            this.update(cx, |this, cx| {
 9814                let local_store = this.as_local()?;
 9815                let old_uri = old_uri?;
 9816                let new_uri = new_uri?;
 9817                for language_server in local_store.language_servers_for_worktree(worktree_id) {
 9818                    let Some(filter) = local_store
 9819                        .language_server_paths_watched_for_rename
 9820                        .get(&language_server.server_id())
 9821                    else {
 9822                        continue;
 9823                    };
 9824
 9825                    if filter.should_send_will_rename(&old_uri, is_dir) {
 9826                        let apply_edit = cx.spawn({
 9827                            let old_uri = old_uri.clone();
 9828                            let new_uri = new_uri.clone();
 9829                            let language_server = language_server.clone();
 9830                            async move |this, cx| {
 9831                                let edit = language_server
 9832                                    .request::<WillRenameFiles>(RenameFilesParams {
 9833                                        files: vec![FileRename { old_uri, new_uri }],
 9834                                    })
 9835                                    .await
 9836                                    .into_response()
 9837                                    .context("will rename files")
 9838                                    .log_err()
 9839                                    .flatten()?;
 9840
 9841                                let transaction = LocalLspStore::deserialize_workspace_edit(
 9842                                    this.upgrade()?,
 9843                                    edit,
 9844                                    false,
 9845                                    language_server.clone(),
 9846                                    cx,
 9847                                )
 9848                                .await
 9849                                .ok()?;
 9850                                Some(transaction)
 9851                            }
 9852                        });
 9853                        tasks.push(apply_edit);
 9854                    }
 9855                }
 9856                Some(())
 9857            })
 9858            .ok()
 9859            .flatten();
 9860            let mut merged_transaction = ProjectTransaction::default();
 9861            for task in tasks {
 9862                // Await on tasks sequentially so that the order of application of edits is deterministic
 9863                // (at least with regards to the order of registration of language servers)
 9864                if let Some(transaction) = task.await {
 9865                    for (buffer, buffer_transaction) in transaction.0 {
 9866                        merged_transaction.0.insert(buffer, buffer_transaction);
 9867                    }
 9868                }
 9869            }
 9870            merged_transaction
 9871        })
 9872    }
 9873
 9874    fn lsp_notify_abs_paths_changed(
 9875        &mut self,
 9876        server_id: LanguageServerId,
 9877        changes: Vec<PathEvent>,
 9878    ) {
 9879        maybe!({
 9880            let server = self.language_server_for_id(server_id)?;
 9881            let changes = changes
 9882                .into_iter()
 9883                .filter_map(|event| {
 9884                    let typ = match event.kind? {
 9885                        PathEventKind::Created => lsp::FileChangeType::CREATED,
 9886                        PathEventKind::Removed => lsp::FileChangeType::DELETED,
 9887                        PathEventKind::Changed => lsp::FileChangeType::CHANGED,
 9888                    };
 9889                    Some(lsp::FileEvent {
 9890                        uri: file_path_to_lsp_url(&event.path).log_err()?,
 9891                        typ,
 9892                    })
 9893                })
 9894                .collect::<Vec<_>>();
 9895            if !changes.is_empty() {
 9896                server
 9897                    .notify::<lsp::notification::DidChangeWatchedFiles>(
 9898                        lsp::DidChangeWatchedFilesParams { changes },
 9899                    )
 9900                    .ok();
 9901            }
 9902            Some(())
 9903        });
 9904    }
 9905
 9906    pub fn language_server_for_id(&self, id: LanguageServerId) -> Option<Arc<LanguageServer>> {
 9907        self.as_local()?.language_server_for_id(id)
 9908    }
 9909
 9910    fn on_lsp_progress(
 9911        &mut self,
 9912        progress_params: lsp::ProgressParams,
 9913        language_server_id: LanguageServerId,
 9914        disk_based_diagnostics_progress_token: Option<String>,
 9915        cx: &mut Context<Self>,
 9916    ) {
 9917        match progress_params.value {
 9918            lsp::ProgressParamsValue::WorkDone(progress) => {
 9919                self.handle_work_done_progress(
 9920                    progress,
 9921                    language_server_id,
 9922                    disk_based_diagnostics_progress_token,
 9923                    ProgressToken::from_lsp(progress_params.token),
 9924                    cx,
 9925                );
 9926            }
 9927            lsp::ProgressParamsValue::WorkspaceDiagnostic(report) => {
 9928                let registration_id = match progress_params.token {
 9929                    lsp::NumberOrString::Number(_) => None,
 9930                    lsp::NumberOrString::String(token) => token
 9931                        .split_once(WORKSPACE_DIAGNOSTICS_TOKEN_START)
 9932                        .map(|(_, id)| id.to_owned()),
 9933                };
 9934                if let Some(LanguageServerState::Running {
 9935                    workspace_diagnostics_refresh_tasks,
 9936                    ..
 9937                }) = self
 9938                    .as_local_mut()
 9939                    .and_then(|local| local.language_servers.get_mut(&language_server_id))
 9940                    && let Some(workspace_diagnostics) =
 9941                        workspace_diagnostics_refresh_tasks.get_mut(&registration_id)
 9942                {
 9943                    workspace_diagnostics.progress_tx.try_send(()).ok();
 9944                    self.apply_workspace_diagnostic_report(
 9945                        language_server_id,
 9946                        report,
 9947                        registration_id.map(SharedString::from),
 9948                        cx,
 9949                    )
 9950                }
 9951            }
 9952        }
 9953    }
 9954
 9955    fn handle_work_done_progress(
 9956        &mut self,
 9957        progress: lsp::WorkDoneProgress,
 9958        language_server_id: LanguageServerId,
 9959        disk_based_diagnostics_progress_token: Option<String>,
 9960        token: ProgressToken,
 9961        cx: &mut Context<Self>,
 9962    ) {
 9963        let language_server_status =
 9964            if let Some(status) = self.language_server_statuses.get_mut(&language_server_id) {
 9965                status
 9966            } else {
 9967                return;
 9968            };
 9969
 9970        if !language_server_status.progress_tokens.contains(&token) {
 9971            return;
 9972        }
 9973
 9974        let is_disk_based_diagnostics_progress =
 9975            if let (Some(disk_based_token), ProgressToken::String(token)) =
 9976                (&disk_based_diagnostics_progress_token, &token)
 9977            {
 9978                token.starts_with(disk_based_token)
 9979            } else {
 9980                false
 9981            };
 9982
 9983        match progress {
 9984            lsp::WorkDoneProgress::Begin(report) => {
 9985                if is_disk_based_diagnostics_progress {
 9986                    self.disk_based_diagnostics_started(language_server_id, cx);
 9987                }
 9988                self.on_lsp_work_start(
 9989                    language_server_id,
 9990                    token.clone(),
 9991                    LanguageServerProgress {
 9992                        title: Some(report.title),
 9993                        is_disk_based_diagnostics_progress,
 9994                        is_cancellable: report.cancellable.unwrap_or(false),
 9995                        message: report.message.clone(),
 9996                        percentage: report.percentage.map(|p| p as usize),
 9997                        last_update_at: cx.background_executor().now(),
 9998                    },
 9999                    cx,
10000                );
10001            }
10002            lsp::WorkDoneProgress::Report(report) => self.on_lsp_work_progress(
10003                language_server_id,
10004                token,
10005                LanguageServerProgress {
10006                    title: None,
10007                    is_disk_based_diagnostics_progress,
10008                    is_cancellable: report.cancellable.unwrap_or(false),
10009                    message: report.message,
10010                    percentage: report.percentage.map(|p| p as usize),
10011                    last_update_at: cx.background_executor().now(),
10012                },
10013                cx,
10014            ),
10015            lsp::WorkDoneProgress::End(_) => {
10016                language_server_status.progress_tokens.remove(&token);
10017                self.on_lsp_work_end(language_server_id, token.clone(), cx);
10018                if is_disk_based_diagnostics_progress {
10019                    self.disk_based_diagnostics_finished(language_server_id, cx);
10020                }
10021            }
10022        }
10023    }
10024
10025    fn on_lsp_work_start(
10026        &mut self,
10027        language_server_id: LanguageServerId,
10028        token: ProgressToken,
10029        progress: LanguageServerProgress,
10030        cx: &mut Context<Self>,
10031    ) {
10032        if let Some(status) = self.language_server_statuses.get_mut(&language_server_id) {
10033            status.pending_work.insert(token.clone(), progress.clone());
10034            cx.notify();
10035        }
10036        cx.emit(LspStoreEvent::LanguageServerUpdate {
10037            language_server_id,
10038            name: self
10039                .language_server_adapter_for_id(language_server_id)
10040                .map(|adapter| adapter.name()),
10041            message: proto::update_language_server::Variant::WorkStart(proto::LspWorkStart {
10042                token: Some(token.to_proto()),
10043                title: progress.title,
10044                message: progress.message,
10045                percentage: progress.percentage.map(|p| p as u32),
10046                is_cancellable: Some(progress.is_cancellable),
10047            }),
10048        })
10049    }
10050
10051    fn on_lsp_work_progress(
10052        &mut self,
10053        language_server_id: LanguageServerId,
10054        token: ProgressToken,
10055        progress: LanguageServerProgress,
10056        cx: &mut Context<Self>,
10057    ) {
10058        let mut did_update = false;
10059        if let Some(status) = self.language_server_statuses.get_mut(&language_server_id) {
10060            match status.pending_work.entry(token.clone()) {
10061                btree_map::Entry::Vacant(entry) => {
10062                    entry.insert(progress.clone());
10063                    did_update = true;
10064                }
10065                btree_map::Entry::Occupied(mut entry) => {
10066                    let entry = entry.get_mut();
10067                    if (progress.last_update_at - entry.last_update_at)
10068                        >= SERVER_PROGRESS_THROTTLE_TIMEOUT
10069                    {
10070                        entry.last_update_at = progress.last_update_at;
10071                        if progress.message.is_some() {
10072                            entry.message = progress.message.clone();
10073                        }
10074                        if progress.percentage.is_some() {
10075                            entry.percentage = progress.percentage;
10076                        }
10077                        if progress.is_cancellable != entry.is_cancellable {
10078                            entry.is_cancellable = progress.is_cancellable;
10079                        }
10080                        did_update = true;
10081                    }
10082                }
10083            }
10084        }
10085
10086        if did_update {
10087            cx.emit(LspStoreEvent::LanguageServerUpdate {
10088                language_server_id,
10089                name: self
10090                    .language_server_adapter_for_id(language_server_id)
10091                    .map(|adapter| adapter.name()),
10092                message: proto::update_language_server::Variant::WorkProgress(
10093                    proto::LspWorkProgress {
10094                        token: Some(token.to_proto()),
10095                        message: progress.message,
10096                        percentage: progress.percentage.map(|p| p as u32),
10097                        is_cancellable: Some(progress.is_cancellable),
10098                    },
10099                ),
10100            })
10101        }
10102    }
10103
10104    fn on_lsp_work_end(
10105        &mut self,
10106        language_server_id: LanguageServerId,
10107        token: ProgressToken,
10108        cx: &mut Context<Self>,
10109    ) {
10110        if let Some(status) = self.language_server_statuses.get_mut(&language_server_id) {
10111            if let Some(work) = status.pending_work.remove(&token)
10112                && !work.is_disk_based_diagnostics_progress
10113            {
10114                cx.emit(LspStoreEvent::RefreshInlayHints {
10115                    server_id: language_server_id,
10116                    request_id: None,
10117                });
10118            }
10119            cx.notify();
10120        }
10121
10122        cx.emit(LspStoreEvent::LanguageServerUpdate {
10123            language_server_id,
10124            name: self
10125                .language_server_adapter_for_id(language_server_id)
10126                .map(|adapter| adapter.name()),
10127            message: proto::update_language_server::Variant::WorkEnd(proto::LspWorkEnd {
10128                token: Some(token.to_proto()),
10129            }),
10130        })
10131    }
10132
10133    pub async fn handle_resolve_completion_documentation(
10134        this: Entity<Self>,
10135        envelope: TypedEnvelope<proto::ResolveCompletionDocumentation>,
10136        mut cx: AsyncApp,
10137    ) -> Result<proto::ResolveCompletionDocumentationResponse> {
10138        let lsp_completion = serde_json::from_slice(&envelope.payload.lsp_completion)?;
10139
10140        let completion = this
10141            .read_with(&cx, |this, cx| {
10142                let id = LanguageServerId(envelope.payload.language_server_id as usize);
10143                let server = this
10144                    .language_server_for_id(id)
10145                    .with_context(|| format!("No language server {id}"))?;
10146
10147                anyhow::Ok(cx.background_spawn(async move {
10148                    let can_resolve = server
10149                        .capabilities()
10150                        .completion_provider
10151                        .as_ref()
10152                        .and_then(|options| options.resolve_provider)
10153                        .unwrap_or(false);
10154                    if can_resolve {
10155                        server
10156                            .request::<lsp::request::ResolveCompletionItem>(lsp_completion)
10157                            .await
10158                            .into_response()
10159                            .context("resolve completion item")
10160                    } else {
10161                        anyhow::Ok(lsp_completion)
10162                    }
10163                }))
10164            })??
10165            .await?;
10166
10167        let mut documentation_is_markdown = false;
10168        let lsp_completion = serde_json::to_string(&completion)?.into_bytes();
10169        let documentation = match completion.documentation {
10170            Some(lsp::Documentation::String(text)) => text,
10171
10172            Some(lsp::Documentation::MarkupContent(lsp::MarkupContent { kind, value })) => {
10173                documentation_is_markdown = kind == lsp::MarkupKind::Markdown;
10174                value
10175            }
10176
10177            _ => String::new(),
10178        };
10179
10180        // If we have a new buffer_id, that means we're talking to a new client
10181        // and want to check for new text_edits in the completion too.
10182        let mut old_replace_start = None;
10183        let mut old_replace_end = None;
10184        let mut old_insert_start = None;
10185        let mut old_insert_end = None;
10186        let mut new_text = String::default();
10187        if let Ok(buffer_id) = BufferId::new(envelope.payload.buffer_id) {
10188            let buffer_snapshot = this.update(&mut cx, |this, cx| {
10189                let buffer = this.buffer_store.read(cx).get_existing(buffer_id)?;
10190                anyhow::Ok(buffer.read(cx).snapshot())
10191            })??;
10192
10193            if let Some(text_edit) = completion.text_edit.as_ref() {
10194                let edit = parse_completion_text_edit(text_edit, &buffer_snapshot);
10195
10196                if let Some(mut edit) = edit {
10197                    LineEnding::normalize(&mut edit.new_text);
10198
10199                    new_text = edit.new_text;
10200                    old_replace_start = Some(serialize_anchor(&edit.replace_range.start));
10201                    old_replace_end = Some(serialize_anchor(&edit.replace_range.end));
10202                    if let Some(insert_range) = edit.insert_range {
10203                        old_insert_start = Some(serialize_anchor(&insert_range.start));
10204                        old_insert_end = Some(serialize_anchor(&insert_range.end));
10205                    }
10206                }
10207            }
10208        }
10209
10210        Ok(proto::ResolveCompletionDocumentationResponse {
10211            documentation,
10212            documentation_is_markdown,
10213            old_replace_start,
10214            old_replace_end,
10215            new_text,
10216            lsp_completion,
10217            old_insert_start,
10218            old_insert_end,
10219        })
10220    }
10221
10222    async fn handle_on_type_formatting(
10223        this: Entity<Self>,
10224        envelope: TypedEnvelope<proto::OnTypeFormatting>,
10225        mut cx: AsyncApp,
10226    ) -> Result<proto::OnTypeFormattingResponse> {
10227        let on_type_formatting = this.update(&mut cx, |this, cx| {
10228            let buffer_id = BufferId::new(envelope.payload.buffer_id)?;
10229            let buffer = this.buffer_store.read(cx).get_existing(buffer_id)?;
10230            let position = envelope
10231                .payload
10232                .position
10233                .and_then(deserialize_anchor)
10234                .context("invalid position")?;
10235            anyhow::Ok(this.apply_on_type_formatting(
10236                buffer,
10237                position,
10238                envelope.payload.trigger.clone(),
10239                cx,
10240            ))
10241        })??;
10242
10243        let transaction = on_type_formatting
10244            .await?
10245            .as_ref()
10246            .map(language::proto::serialize_transaction);
10247        Ok(proto::OnTypeFormattingResponse { transaction })
10248    }
10249
10250    async fn handle_refresh_inlay_hints(
10251        lsp_store: Entity<Self>,
10252        envelope: TypedEnvelope<proto::RefreshInlayHints>,
10253        mut cx: AsyncApp,
10254    ) -> Result<proto::Ack> {
10255        lsp_store.update(&mut cx, |_, cx| {
10256            cx.emit(LspStoreEvent::RefreshInlayHints {
10257                server_id: LanguageServerId::from_proto(envelope.payload.server_id),
10258                request_id: envelope.payload.request_id.map(|id| id as usize),
10259            });
10260        })?;
10261        Ok(proto::Ack {})
10262    }
10263
10264    async fn handle_pull_workspace_diagnostics(
10265        lsp_store: Entity<Self>,
10266        envelope: TypedEnvelope<proto::PullWorkspaceDiagnostics>,
10267        mut cx: AsyncApp,
10268    ) -> Result<proto::Ack> {
10269        let server_id = LanguageServerId::from_proto(envelope.payload.server_id);
10270        lsp_store.update(&mut cx, |lsp_store, _| {
10271            lsp_store.pull_workspace_diagnostics(server_id);
10272        })?;
10273        Ok(proto::Ack {})
10274    }
10275
10276    async fn handle_get_color_presentation(
10277        lsp_store: Entity<Self>,
10278        envelope: TypedEnvelope<proto::GetColorPresentation>,
10279        mut cx: AsyncApp,
10280    ) -> Result<proto::GetColorPresentationResponse> {
10281        let buffer_id = BufferId::new(envelope.payload.buffer_id)?;
10282        let buffer = lsp_store.update(&mut cx, |lsp_store, cx| {
10283            lsp_store.buffer_store.read(cx).get_existing(buffer_id)
10284        })??;
10285
10286        let color = envelope
10287            .payload
10288            .color
10289            .context("invalid color resolve request")?;
10290        let start = color
10291            .lsp_range_start
10292            .context("invalid color resolve request")?;
10293        let end = color
10294            .lsp_range_end
10295            .context("invalid color resolve request")?;
10296
10297        let color = DocumentColor {
10298            lsp_range: lsp::Range {
10299                start: point_to_lsp(PointUtf16::new(start.row, start.column)),
10300                end: point_to_lsp(PointUtf16::new(end.row, end.column)),
10301            },
10302            color: lsp::Color {
10303                red: color.red,
10304                green: color.green,
10305                blue: color.blue,
10306                alpha: color.alpha,
10307            },
10308            resolved: false,
10309            color_presentations: Vec::new(),
10310        };
10311        let resolved_color = lsp_store
10312            .update(&mut cx, |lsp_store, cx| {
10313                lsp_store.resolve_color_presentation(
10314                    color,
10315                    buffer.clone(),
10316                    LanguageServerId(envelope.payload.server_id as usize),
10317                    cx,
10318                )
10319            })?
10320            .await
10321            .context("resolving color presentation")?;
10322
10323        Ok(proto::GetColorPresentationResponse {
10324            presentations: resolved_color
10325                .color_presentations
10326                .into_iter()
10327                .map(|presentation| proto::ColorPresentation {
10328                    label: presentation.label.to_string(),
10329                    text_edit: presentation.text_edit.map(serialize_lsp_edit),
10330                    additional_text_edits: presentation
10331                        .additional_text_edits
10332                        .into_iter()
10333                        .map(serialize_lsp_edit)
10334                        .collect(),
10335                })
10336                .collect(),
10337        })
10338    }
10339
10340    async fn handle_resolve_inlay_hint(
10341        lsp_store: Entity<Self>,
10342        envelope: TypedEnvelope<proto::ResolveInlayHint>,
10343        mut cx: AsyncApp,
10344    ) -> Result<proto::ResolveInlayHintResponse> {
10345        let proto_hint = envelope
10346            .payload
10347            .hint
10348            .expect("incorrect protobuf resolve inlay hint message: missing the inlay hint");
10349        let hint = InlayHints::proto_to_project_hint(proto_hint)
10350            .context("resolved proto inlay hint conversion")?;
10351        let buffer = lsp_store.update(&mut cx, |lsp_store, cx| {
10352            let buffer_id = BufferId::new(envelope.payload.buffer_id)?;
10353            lsp_store.buffer_store.read(cx).get_existing(buffer_id)
10354        })??;
10355        let response_hint = lsp_store
10356            .update(&mut cx, |lsp_store, cx| {
10357                lsp_store.resolve_inlay_hint(
10358                    hint,
10359                    buffer,
10360                    LanguageServerId(envelope.payload.language_server_id as usize),
10361                    cx,
10362                )
10363            })?
10364            .await
10365            .context("inlay hints fetch")?;
10366        Ok(proto::ResolveInlayHintResponse {
10367            hint: Some(InlayHints::project_to_proto_hint(response_hint)),
10368        })
10369    }
10370
10371    async fn handle_refresh_code_lens(
10372        this: Entity<Self>,
10373        _: TypedEnvelope<proto::RefreshCodeLens>,
10374        mut cx: AsyncApp,
10375    ) -> Result<proto::Ack> {
10376        this.update(&mut cx, |_, cx| {
10377            cx.emit(LspStoreEvent::RefreshCodeLens);
10378        })?;
10379        Ok(proto::Ack {})
10380    }
10381
10382    async fn handle_open_buffer_for_symbol(
10383        this: Entity<Self>,
10384        envelope: TypedEnvelope<proto::OpenBufferForSymbol>,
10385        mut cx: AsyncApp,
10386    ) -> Result<proto::OpenBufferForSymbolResponse> {
10387        let peer_id = envelope.original_sender_id().unwrap_or_default();
10388        let symbol = envelope.payload.symbol.context("invalid symbol")?;
10389        let symbol = Self::deserialize_symbol(symbol)?;
10390        this.read_with(&cx, |this, _| {
10391            if let SymbolLocation::OutsideProject {
10392                abs_path,
10393                signature,
10394            } = &symbol.path
10395            {
10396                let new_signature = this.symbol_signature(&abs_path);
10397                anyhow::ensure!(&new_signature == signature, "invalid symbol signature");
10398            }
10399            Ok(())
10400        })??;
10401        let buffer = this
10402            .update(&mut cx, |this, cx| {
10403                this.open_buffer_for_symbol(
10404                    &Symbol {
10405                        language_server_name: symbol.language_server_name,
10406                        source_worktree_id: symbol.source_worktree_id,
10407                        source_language_server_id: symbol.source_language_server_id,
10408                        path: symbol.path,
10409                        name: symbol.name,
10410                        kind: symbol.kind,
10411                        range: symbol.range,
10412                        label: CodeLabel::default(),
10413                    },
10414                    cx,
10415                )
10416            })?
10417            .await?;
10418
10419        this.update(&mut cx, |this, cx| {
10420            let is_private = buffer
10421                .read(cx)
10422                .file()
10423                .map(|f| f.is_private())
10424                .unwrap_or_default();
10425            if is_private {
10426                Err(anyhow!(rpc::ErrorCode::UnsharedItem))
10427            } else {
10428                this.buffer_store
10429                    .update(cx, |buffer_store, cx| {
10430                        buffer_store.create_buffer_for_peer(&buffer, peer_id, cx)
10431                    })
10432                    .detach_and_log_err(cx);
10433                let buffer_id = buffer.read(cx).remote_id().to_proto();
10434                Ok(proto::OpenBufferForSymbolResponse { buffer_id })
10435            }
10436        })?
10437    }
10438
10439    fn symbol_signature(&self, abs_path: &Path) -> [u8; 32] {
10440        let mut hasher = Sha256::new();
10441        hasher.update(abs_path.to_string_lossy().as_bytes());
10442        hasher.update(self.nonce.to_be_bytes());
10443        hasher.finalize().as_slice().try_into().unwrap()
10444    }
10445
10446    pub async fn handle_get_project_symbols(
10447        this: Entity<Self>,
10448        envelope: TypedEnvelope<proto::GetProjectSymbols>,
10449        mut cx: AsyncApp,
10450    ) -> Result<proto::GetProjectSymbolsResponse> {
10451        let symbols = this
10452            .update(&mut cx, |this, cx| {
10453                this.symbols(&envelope.payload.query, cx)
10454            })?
10455            .await?;
10456
10457        Ok(proto::GetProjectSymbolsResponse {
10458            symbols: symbols.iter().map(Self::serialize_symbol).collect(),
10459        })
10460    }
10461
10462    pub async fn handle_restart_language_servers(
10463        this: Entity<Self>,
10464        envelope: TypedEnvelope<proto::RestartLanguageServers>,
10465        mut cx: AsyncApp,
10466    ) -> Result<proto::Ack> {
10467        this.update(&mut cx, |lsp_store, cx| {
10468            let buffers =
10469                lsp_store.buffer_ids_to_buffers(envelope.payload.buffer_ids.into_iter(), cx);
10470            lsp_store.restart_language_servers_for_buffers(
10471                buffers,
10472                envelope
10473                    .payload
10474                    .only_servers
10475                    .into_iter()
10476                    .filter_map(|selector| {
10477                        Some(match selector.selector? {
10478                            proto::language_server_selector::Selector::ServerId(server_id) => {
10479                                LanguageServerSelector::Id(LanguageServerId::from_proto(server_id))
10480                            }
10481                            proto::language_server_selector::Selector::Name(name) => {
10482                                LanguageServerSelector::Name(LanguageServerName(
10483                                    SharedString::from(name),
10484                                ))
10485                            }
10486                        })
10487                    })
10488                    .collect(),
10489                cx,
10490            );
10491        })?;
10492
10493        Ok(proto::Ack {})
10494    }
10495
10496    pub async fn handle_stop_language_servers(
10497        lsp_store: Entity<Self>,
10498        envelope: TypedEnvelope<proto::StopLanguageServers>,
10499        mut cx: AsyncApp,
10500    ) -> Result<proto::Ack> {
10501        lsp_store.update(&mut cx, |lsp_store, cx| {
10502            if envelope.payload.all
10503                && envelope.payload.also_servers.is_empty()
10504                && envelope.payload.buffer_ids.is_empty()
10505            {
10506                lsp_store.stop_all_language_servers(cx);
10507            } else {
10508                let buffers =
10509                    lsp_store.buffer_ids_to_buffers(envelope.payload.buffer_ids.into_iter(), cx);
10510                lsp_store
10511                    .stop_language_servers_for_buffers(
10512                        buffers,
10513                        envelope
10514                            .payload
10515                            .also_servers
10516                            .into_iter()
10517                            .filter_map(|selector| {
10518                                Some(match selector.selector? {
10519                                    proto::language_server_selector::Selector::ServerId(
10520                                        server_id,
10521                                    ) => LanguageServerSelector::Id(LanguageServerId::from_proto(
10522                                        server_id,
10523                                    )),
10524                                    proto::language_server_selector::Selector::Name(name) => {
10525                                        LanguageServerSelector::Name(LanguageServerName(
10526                                            SharedString::from(name),
10527                                        ))
10528                                    }
10529                                })
10530                            })
10531                            .collect(),
10532                        cx,
10533                    )
10534                    .detach_and_log_err(cx);
10535            }
10536        })?;
10537
10538        Ok(proto::Ack {})
10539    }
10540
10541    pub async fn handle_cancel_language_server_work(
10542        lsp_store: Entity<Self>,
10543        envelope: TypedEnvelope<proto::CancelLanguageServerWork>,
10544        mut cx: AsyncApp,
10545    ) -> Result<proto::Ack> {
10546        lsp_store.update(&mut cx, |lsp_store, cx| {
10547            if let Some(work) = envelope.payload.work {
10548                match work {
10549                    proto::cancel_language_server_work::Work::Buffers(buffers) => {
10550                        let buffers =
10551                            lsp_store.buffer_ids_to_buffers(buffers.buffer_ids.into_iter(), cx);
10552                        lsp_store.cancel_language_server_work_for_buffers(buffers, cx);
10553                    }
10554                    proto::cancel_language_server_work::Work::LanguageServerWork(work) => {
10555                        let server_id = LanguageServerId::from_proto(work.language_server_id);
10556                        let token = work
10557                            .token
10558                            .map(|token| {
10559                                ProgressToken::from_proto(token)
10560                                    .context("invalid work progress token")
10561                            })
10562                            .transpose()?;
10563                        lsp_store.cancel_language_server_work(server_id, token, cx);
10564                    }
10565                }
10566            }
10567            anyhow::Ok(())
10568        })??;
10569
10570        Ok(proto::Ack {})
10571    }
10572
10573    fn buffer_ids_to_buffers(
10574        &mut self,
10575        buffer_ids: impl Iterator<Item = u64>,
10576        cx: &mut Context<Self>,
10577    ) -> Vec<Entity<Buffer>> {
10578        buffer_ids
10579            .into_iter()
10580            .flat_map(|buffer_id| {
10581                self.buffer_store
10582                    .read(cx)
10583                    .get(BufferId::new(buffer_id).log_err()?)
10584            })
10585            .collect::<Vec<_>>()
10586    }
10587
10588    async fn handle_apply_additional_edits_for_completion(
10589        this: Entity<Self>,
10590        envelope: TypedEnvelope<proto::ApplyCompletionAdditionalEdits>,
10591        mut cx: AsyncApp,
10592    ) -> Result<proto::ApplyCompletionAdditionalEditsResponse> {
10593        let (buffer, completion) = this.update(&mut cx, |this, cx| {
10594            let buffer_id = BufferId::new(envelope.payload.buffer_id)?;
10595            let buffer = this.buffer_store.read(cx).get_existing(buffer_id)?;
10596            let completion = Self::deserialize_completion(
10597                envelope.payload.completion.context("invalid completion")?,
10598            )?;
10599            anyhow::Ok((buffer, completion))
10600        })??;
10601
10602        let apply_additional_edits = this.update(&mut cx, |this, cx| {
10603            this.apply_additional_edits_for_completion(
10604                buffer,
10605                Rc::new(RefCell::new(Box::new([Completion {
10606                    replace_range: completion.replace_range,
10607                    new_text: completion.new_text,
10608                    source: completion.source,
10609                    documentation: None,
10610                    label: CodeLabel::default(),
10611                    match_start: None,
10612                    snippet_deduplication_key: None,
10613                    insert_text_mode: None,
10614                    icon_path: None,
10615                    confirm: None,
10616                }]))),
10617                0,
10618                false,
10619                cx,
10620            )
10621        })?;
10622
10623        Ok(proto::ApplyCompletionAdditionalEditsResponse {
10624            transaction: apply_additional_edits
10625                .await?
10626                .as_ref()
10627                .map(language::proto::serialize_transaction),
10628        })
10629    }
10630
10631    pub fn last_formatting_failure(&self) -> Option<&str> {
10632        self.last_formatting_failure.as_deref()
10633    }
10634
10635    pub fn reset_last_formatting_failure(&mut self) {
10636        self.last_formatting_failure = None;
10637    }
10638
10639    pub fn environment_for_buffer(
10640        &self,
10641        buffer: &Entity<Buffer>,
10642        cx: &mut Context<Self>,
10643    ) -> Shared<Task<Option<HashMap<String, String>>>> {
10644        if let Some(environment) = &self.as_local().map(|local| local.environment.clone()) {
10645            environment.update(cx, |env, cx| {
10646                env.buffer_environment(buffer, &self.worktree_store, cx)
10647            })
10648        } else {
10649            Task::ready(None).shared()
10650        }
10651    }
10652
10653    pub fn format(
10654        &mut self,
10655        buffers: HashSet<Entity<Buffer>>,
10656        target: LspFormatTarget,
10657        push_to_history: bool,
10658        trigger: FormatTrigger,
10659        cx: &mut Context<Self>,
10660    ) -> Task<anyhow::Result<ProjectTransaction>> {
10661        let logger = zlog::scoped!("format");
10662        if self.as_local().is_some() {
10663            zlog::trace!(logger => "Formatting locally");
10664            let logger = zlog::scoped!(logger => "local");
10665            let buffers = buffers
10666                .into_iter()
10667                .map(|buffer_handle| {
10668                    let buffer = buffer_handle.read(cx);
10669                    let buffer_abs_path = File::from_dyn(buffer.file())
10670                        .and_then(|file| file.as_local().map(|f| f.abs_path(cx)));
10671
10672                    (buffer_handle, buffer_abs_path, buffer.remote_id())
10673                })
10674                .collect::<Vec<_>>();
10675
10676            cx.spawn(async move |lsp_store, cx| {
10677                let mut formattable_buffers = Vec::with_capacity(buffers.len());
10678
10679                for (handle, abs_path, id) in buffers {
10680                    let env = lsp_store
10681                        .update(cx, |lsp_store, cx| {
10682                            lsp_store.environment_for_buffer(&handle, cx)
10683                        })?
10684                        .await;
10685
10686                    let ranges = match &target {
10687                        LspFormatTarget::Buffers => None,
10688                        LspFormatTarget::Ranges(ranges) => {
10689                            Some(ranges.get(&id).context("No format ranges provided for buffer")?.clone())
10690                        }
10691                    };
10692
10693                    formattable_buffers.push(FormattableBuffer {
10694                        handle,
10695                        abs_path,
10696                        env,
10697                        ranges,
10698                    });
10699                }
10700                zlog::trace!(logger => "Formatting {:?} buffers", formattable_buffers.len());
10701
10702                let format_timer = zlog::time!(logger => "Formatting buffers");
10703                let result = LocalLspStore::format_locally(
10704                    lsp_store.clone(),
10705                    formattable_buffers,
10706                    push_to_history,
10707                    trigger,
10708                    logger,
10709                    cx,
10710                )
10711                .await;
10712                format_timer.end();
10713
10714                zlog::trace!(logger => "Formatting completed with result {:?}", result.as_ref().map(|_| "<project-transaction>"));
10715
10716                lsp_store.update(cx, |lsp_store, _| {
10717                    lsp_store.update_last_formatting_failure(&result);
10718                })?;
10719
10720                result
10721            })
10722        } else if let Some((client, project_id)) = self.upstream_client() {
10723            zlog::trace!(logger => "Formatting remotely");
10724            let logger = zlog::scoped!(logger => "remote");
10725            // Don't support formatting ranges via remote
10726            match target {
10727                LspFormatTarget::Buffers => {}
10728                LspFormatTarget::Ranges(_) => {
10729                    zlog::trace!(logger => "Ignoring unsupported remote range formatting request");
10730                    return Task::ready(Ok(ProjectTransaction::default()));
10731                }
10732            }
10733
10734            let buffer_store = self.buffer_store();
10735            cx.spawn(async move |lsp_store, cx| {
10736                zlog::trace!(logger => "Sending remote format request");
10737                let request_timer = zlog::time!(logger => "remote format request");
10738                let result = client
10739                    .request(proto::FormatBuffers {
10740                        project_id,
10741                        trigger: trigger as i32,
10742                        buffer_ids: buffers
10743                            .iter()
10744                            .map(|buffer| buffer.read_with(cx, |buffer, _| buffer.remote_id().into()))
10745                            .collect::<Result<_>>()?,
10746                    })
10747                    .await
10748                    .and_then(|result| result.transaction.context("missing transaction"));
10749                request_timer.end();
10750
10751                zlog::trace!(logger => "Remote format request resolved to {:?}", result.as_ref().map(|_| "<project_transaction>"));
10752
10753                lsp_store.update(cx, |lsp_store, _| {
10754                    lsp_store.update_last_formatting_failure(&result);
10755                })?;
10756
10757                let transaction_response = result?;
10758                let _timer = zlog::time!(logger => "deserializing project transaction");
10759                buffer_store
10760                    .update(cx, |buffer_store, cx| {
10761                        buffer_store.deserialize_project_transaction(
10762                            transaction_response,
10763                            push_to_history,
10764                            cx,
10765                        )
10766                    })?
10767                    .await
10768            })
10769        } else {
10770            zlog::trace!(logger => "Not formatting");
10771            Task::ready(Ok(ProjectTransaction::default()))
10772        }
10773    }
10774
10775    async fn handle_format_buffers(
10776        this: Entity<Self>,
10777        envelope: TypedEnvelope<proto::FormatBuffers>,
10778        mut cx: AsyncApp,
10779    ) -> Result<proto::FormatBuffersResponse> {
10780        let sender_id = envelope.original_sender_id().unwrap_or_default();
10781        let format = this.update(&mut cx, |this, cx| {
10782            let mut buffers = HashSet::default();
10783            for buffer_id in &envelope.payload.buffer_ids {
10784                let buffer_id = BufferId::new(*buffer_id)?;
10785                buffers.insert(this.buffer_store.read(cx).get_existing(buffer_id)?);
10786            }
10787            let trigger = FormatTrigger::from_proto(envelope.payload.trigger);
10788            anyhow::Ok(this.format(buffers, LspFormatTarget::Buffers, false, trigger, cx))
10789        })??;
10790
10791        let project_transaction = format.await?;
10792        let project_transaction = this.update(&mut cx, |this, cx| {
10793            this.buffer_store.update(cx, |buffer_store, cx| {
10794                buffer_store.serialize_project_transaction_for_peer(
10795                    project_transaction,
10796                    sender_id,
10797                    cx,
10798                )
10799            })
10800        })?;
10801        Ok(proto::FormatBuffersResponse {
10802            transaction: Some(project_transaction),
10803        })
10804    }
10805
10806    async fn handle_apply_code_action_kind(
10807        this: Entity<Self>,
10808        envelope: TypedEnvelope<proto::ApplyCodeActionKind>,
10809        mut cx: AsyncApp,
10810    ) -> Result<proto::ApplyCodeActionKindResponse> {
10811        let sender_id = envelope.original_sender_id().unwrap_or_default();
10812        let format = this.update(&mut cx, |this, cx| {
10813            let mut buffers = HashSet::default();
10814            for buffer_id in &envelope.payload.buffer_ids {
10815                let buffer_id = BufferId::new(*buffer_id)?;
10816                buffers.insert(this.buffer_store.read(cx).get_existing(buffer_id)?);
10817            }
10818            let kind = match envelope.payload.kind.as_str() {
10819                "" => CodeActionKind::EMPTY,
10820                "quickfix" => CodeActionKind::QUICKFIX,
10821                "refactor" => CodeActionKind::REFACTOR,
10822                "refactor.extract" => CodeActionKind::REFACTOR_EXTRACT,
10823                "refactor.inline" => CodeActionKind::REFACTOR_INLINE,
10824                "refactor.rewrite" => CodeActionKind::REFACTOR_REWRITE,
10825                "source" => CodeActionKind::SOURCE,
10826                "source.organizeImports" => CodeActionKind::SOURCE_ORGANIZE_IMPORTS,
10827                "source.fixAll" => CodeActionKind::SOURCE_FIX_ALL,
10828                _ => anyhow::bail!(
10829                    "Invalid code action kind {}",
10830                    envelope.payload.kind.as_str()
10831                ),
10832            };
10833            anyhow::Ok(this.apply_code_action_kind(buffers, kind, false, cx))
10834        })??;
10835
10836        let project_transaction = format.await?;
10837        let project_transaction = this.update(&mut cx, |this, cx| {
10838            this.buffer_store.update(cx, |buffer_store, cx| {
10839                buffer_store.serialize_project_transaction_for_peer(
10840                    project_transaction,
10841                    sender_id,
10842                    cx,
10843                )
10844            })
10845        })?;
10846        Ok(proto::ApplyCodeActionKindResponse {
10847            transaction: Some(project_transaction),
10848        })
10849    }
10850
10851    async fn shutdown_language_server(
10852        server_state: Option<LanguageServerState>,
10853        name: LanguageServerName,
10854        cx: &mut AsyncApp,
10855    ) {
10856        let server = match server_state {
10857            Some(LanguageServerState::Starting { startup, .. }) => {
10858                let mut timer = cx
10859                    .background_executor()
10860                    .timer(SERVER_LAUNCHING_BEFORE_SHUTDOWN_TIMEOUT)
10861                    .fuse();
10862
10863                select! {
10864                    server = startup.fuse() => server,
10865                    () = timer => {
10866                        log::info!("timeout waiting for language server {name} to finish launching before stopping");
10867                        None
10868                    },
10869                }
10870            }
10871
10872            Some(LanguageServerState::Running { server, .. }) => Some(server),
10873
10874            None => None,
10875        };
10876
10877        if let Some(server) = server
10878            && let Some(shutdown) = server.shutdown()
10879        {
10880            shutdown.await;
10881        }
10882    }
10883
10884    // Returns a list of all of the worktrees which no longer have a language server and the root path
10885    // for the stopped server
10886    fn stop_local_language_server(
10887        &mut self,
10888        server_id: LanguageServerId,
10889        cx: &mut Context<Self>,
10890    ) -> Task<()> {
10891        let local = match &mut self.mode {
10892            LspStoreMode::Local(local) => local,
10893            _ => {
10894                return Task::ready(());
10895            }
10896        };
10897
10898        // Remove this server ID from all entries in the given worktree.
10899        local
10900            .language_server_ids
10901            .retain(|_, state| state.id != server_id);
10902        self.buffer_store.update(cx, |buffer_store, cx| {
10903            for buffer in buffer_store.buffers() {
10904                buffer.update(cx, |buffer, cx| {
10905                    buffer.update_diagnostics(server_id, DiagnosticSet::new([], buffer), cx);
10906                    buffer.set_completion_triggers(server_id, Default::default(), cx);
10907                });
10908            }
10909        });
10910
10911        for (worktree_id, summaries) in self.diagnostic_summaries.iter_mut() {
10912            summaries.retain(|path, summaries_by_server_id| {
10913                if summaries_by_server_id.remove(&server_id).is_some() {
10914                    if let Some((client, project_id)) = self.downstream_client.clone() {
10915                        client
10916                            .send(proto::UpdateDiagnosticSummary {
10917                                project_id,
10918                                worktree_id: worktree_id.to_proto(),
10919                                summary: Some(proto::DiagnosticSummary {
10920                                    path: path.as_ref().to_proto(),
10921                                    language_server_id: server_id.0 as u64,
10922                                    error_count: 0,
10923                                    warning_count: 0,
10924                                }),
10925                                more_summaries: Vec::new(),
10926                            })
10927                            .log_err();
10928                    }
10929                    !summaries_by_server_id.is_empty()
10930                } else {
10931                    true
10932                }
10933            });
10934        }
10935
10936        let local = self.as_local_mut().unwrap();
10937        for diagnostics in local.diagnostics.values_mut() {
10938            diagnostics.retain(|_, diagnostics_by_server_id| {
10939                if let Ok(ix) = diagnostics_by_server_id.binary_search_by_key(&server_id, |e| e.0) {
10940                    diagnostics_by_server_id.remove(ix);
10941                    !diagnostics_by_server_id.is_empty()
10942                } else {
10943                    true
10944                }
10945            });
10946        }
10947        local.language_server_watched_paths.remove(&server_id);
10948
10949        let server_state = local.language_servers.remove(&server_id);
10950        self.cleanup_lsp_data(server_id);
10951        let name = self
10952            .language_server_statuses
10953            .remove(&server_id)
10954            .map(|status| status.name)
10955            .or_else(|| {
10956                if let Some(LanguageServerState::Running { adapter, .. }) = server_state.as_ref() {
10957                    Some(adapter.name())
10958                } else {
10959                    None
10960                }
10961            });
10962
10963        if let Some(name) = name {
10964            log::info!("stopping language server {name}");
10965            self.languages
10966                .update_lsp_binary_status(name.clone(), BinaryStatus::Stopping);
10967            cx.notify();
10968
10969            return cx.spawn(async move |lsp_store, cx| {
10970                Self::shutdown_language_server(server_state, name.clone(), cx).await;
10971                lsp_store
10972                    .update(cx, |lsp_store, cx| {
10973                        lsp_store
10974                            .languages
10975                            .update_lsp_binary_status(name, BinaryStatus::Stopped);
10976                        cx.emit(LspStoreEvent::LanguageServerRemoved(server_id));
10977                        cx.notify();
10978                    })
10979                    .ok();
10980            });
10981        }
10982
10983        if server_state.is_some() {
10984            cx.emit(LspStoreEvent::LanguageServerRemoved(server_id));
10985        }
10986        Task::ready(())
10987    }
10988
10989    pub fn stop_all_language_servers(&mut self, cx: &mut Context<Self>) {
10990        if let Some((client, project_id)) = self.upstream_client() {
10991            let request = client.request(proto::StopLanguageServers {
10992                project_id,
10993                buffer_ids: Vec::new(),
10994                also_servers: Vec::new(),
10995                all: true,
10996            });
10997            cx.background_spawn(request).detach_and_log_err(cx);
10998        } else {
10999            let Some(local) = self.as_local_mut() else {
11000                return;
11001            };
11002            let language_servers_to_stop = local
11003                .language_server_ids
11004                .values()
11005                .map(|state| state.id)
11006                .collect();
11007            local.lsp_tree.remove_nodes(&language_servers_to_stop);
11008            let tasks = language_servers_to_stop
11009                .into_iter()
11010                .map(|server| self.stop_local_language_server(server, cx))
11011                .collect::<Vec<_>>();
11012            cx.background_spawn(async move {
11013                futures::future::join_all(tasks).await;
11014            })
11015            .detach();
11016        }
11017    }
11018
11019    pub fn restart_language_servers_for_buffers(
11020        &mut self,
11021        buffers: Vec<Entity<Buffer>>,
11022        only_restart_servers: HashSet<LanguageServerSelector>,
11023        cx: &mut Context<Self>,
11024    ) {
11025        if let Some((client, project_id)) = self.upstream_client() {
11026            let request = client.request(proto::RestartLanguageServers {
11027                project_id,
11028                buffer_ids: buffers
11029                    .into_iter()
11030                    .map(|b| b.read(cx).remote_id().to_proto())
11031                    .collect(),
11032                only_servers: only_restart_servers
11033                    .into_iter()
11034                    .map(|selector| {
11035                        let selector = match selector {
11036                            LanguageServerSelector::Id(language_server_id) => {
11037                                proto::language_server_selector::Selector::ServerId(
11038                                    language_server_id.to_proto(),
11039                                )
11040                            }
11041                            LanguageServerSelector::Name(language_server_name) => {
11042                                proto::language_server_selector::Selector::Name(
11043                                    language_server_name.to_string(),
11044                                )
11045                            }
11046                        };
11047                        proto::LanguageServerSelector {
11048                            selector: Some(selector),
11049                        }
11050                    })
11051                    .collect(),
11052                all: false,
11053            });
11054            cx.background_spawn(request).detach_and_log_err(cx);
11055        } else {
11056            let stop_task = if only_restart_servers.is_empty() {
11057                self.stop_local_language_servers_for_buffers(&buffers, HashSet::default(), cx)
11058            } else {
11059                self.stop_local_language_servers_for_buffers(&[], only_restart_servers.clone(), cx)
11060            };
11061            cx.spawn(async move |lsp_store, cx| {
11062                stop_task.await;
11063                lsp_store
11064                    .update(cx, |lsp_store, cx| {
11065                        for buffer in buffers {
11066                            lsp_store.register_buffer_with_language_servers(
11067                                &buffer,
11068                                only_restart_servers.clone(),
11069                                true,
11070                                cx,
11071                            );
11072                        }
11073                    })
11074                    .ok()
11075            })
11076            .detach();
11077        }
11078    }
11079
11080    pub fn stop_language_servers_for_buffers(
11081        &mut self,
11082        buffers: Vec<Entity<Buffer>>,
11083        also_stop_servers: HashSet<LanguageServerSelector>,
11084        cx: &mut Context<Self>,
11085    ) -> Task<Result<()>> {
11086        if let Some((client, project_id)) = self.upstream_client() {
11087            let request = client.request(proto::StopLanguageServers {
11088                project_id,
11089                buffer_ids: buffers
11090                    .into_iter()
11091                    .map(|b| b.read(cx).remote_id().to_proto())
11092                    .collect(),
11093                also_servers: also_stop_servers
11094                    .into_iter()
11095                    .map(|selector| {
11096                        let selector = match selector {
11097                            LanguageServerSelector::Id(language_server_id) => {
11098                                proto::language_server_selector::Selector::ServerId(
11099                                    language_server_id.to_proto(),
11100                                )
11101                            }
11102                            LanguageServerSelector::Name(language_server_name) => {
11103                                proto::language_server_selector::Selector::Name(
11104                                    language_server_name.to_string(),
11105                                )
11106                            }
11107                        };
11108                        proto::LanguageServerSelector {
11109                            selector: Some(selector),
11110                        }
11111                    })
11112                    .collect(),
11113                all: false,
11114            });
11115            cx.background_spawn(async move {
11116                let _ = request.await?;
11117                Ok(())
11118            })
11119        } else {
11120            let task =
11121                self.stop_local_language_servers_for_buffers(&buffers, also_stop_servers, cx);
11122            cx.background_spawn(async move {
11123                task.await;
11124                Ok(())
11125            })
11126        }
11127    }
11128
11129    fn stop_local_language_servers_for_buffers(
11130        &mut self,
11131        buffers: &[Entity<Buffer>],
11132        also_stop_servers: HashSet<LanguageServerSelector>,
11133        cx: &mut Context<Self>,
11134    ) -> Task<()> {
11135        let Some(local) = self.as_local_mut() else {
11136            return Task::ready(());
11137        };
11138        let mut language_server_names_to_stop = BTreeSet::default();
11139        let mut language_servers_to_stop = also_stop_servers
11140            .into_iter()
11141            .flat_map(|selector| match selector {
11142                LanguageServerSelector::Id(id) => Some(id),
11143                LanguageServerSelector::Name(name) => {
11144                    language_server_names_to_stop.insert(name);
11145                    None
11146                }
11147            })
11148            .collect::<BTreeSet<_>>();
11149
11150        let mut covered_worktrees = HashSet::default();
11151        for buffer in buffers {
11152            buffer.update(cx, |buffer, cx| {
11153                language_servers_to_stop.extend(local.language_server_ids_for_buffer(buffer, cx));
11154                if let Some(worktree_id) = buffer.file().map(|f| f.worktree_id(cx))
11155                    && covered_worktrees.insert(worktree_id)
11156                {
11157                    language_server_names_to_stop.retain(|name| {
11158                        let old_ids_count = language_servers_to_stop.len();
11159                        let all_language_servers_with_this_name = local
11160                            .language_server_ids
11161                            .iter()
11162                            .filter_map(|(seed, state)| seed.name.eq(name).then(|| state.id));
11163                        language_servers_to_stop.extend(all_language_servers_with_this_name);
11164                        old_ids_count == language_servers_to_stop.len()
11165                    });
11166                }
11167            });
11168        }
11169        for name in language_server_names_to_stop {
11170            language_servers_to_stop.extend(
11171                local
11172                    .language_server_ids
11173                    .iter()
11174                    .filter_map(|(seed, v)| seed.name.eq(&name).then(|| v.id)),
11175            );
11176        }
11177
11178        local.lsp_tree.remove_nodes(&language_servers_to_stop);
11179        let tasks = language_servers_to_stop
11180            .into_iter()
11181            .map(|server| self.stop_local_language_server(server, cx))
11182            .collect::<Vec<_>>();
11183
11184        cx.background_spawn(futures::future::join_all(tasks).map(|_| ()))
11185    }
11186
11187    fn get_buffer<'a>(&self, abs_path: &Path, cx: &'a App) -> Option<&'a Buffer> {
11188        let (worktree, relative_path) =
11189            self.worktree_store.read(cx).find_worktree(&abs_path, cx)?;
11190
11191        let project_path = ProjectPath {
11192            worktree_id: worktree.read(cx).id(),
11193            path: relative_path,
11194        };
11195
11196        Some(
11197            self.buffer_store()
11198                .read(cx)
11199                .get_by_path(&project_path)?
11200                .read(cx),
11201        )
11202    }
11203
11204    #[cfg(any(test, feature = "test-support"))]
11205    pub fn update_diagnostics(
11206        &mut self,
11207        server_id: LanguageServerId,
11208        diagnostics: lsp::PublishDiagnosticsParams,
11209        result_id: Option<SharedString>,
11210        source_kind: DiagnosticSourceKind,
11211        disk_based_sources: &[String],
11212        cx: &mut Context<Self>,
11213    ) -> Result<()> {
11214        self.merge_lsp_diagnostics(
11215            source_kind,
11216            vec![DocumentDiagnosticsUpdate {
11217                diagnostics,
11218                result_id,
11219                server_id,
11220                disk_based_sources: Cow::Borrowed(disk_based_sources),
11221                registration_id: None,
11222            }],
11223            |_, _, _| false,
11224            cx,
11225        )
11226    }
11227
11228    pub fn merge_lsp_diagnostics(
11229        &mut self,
11230        source_kind: DiagnosticSourceKind,
11231        lsp_diagnostics: Vec<DocumentDiagnosticsUpdate<lsp::PublishDiagnosticsParams>>,
11232        merge: impl Fn(&lsp::Uri, &Diagnostic, &App) -> bool + Clone,
11233        cx: &mut Context<Self>,
11234    ) -> Result<()> {
11235        anyhow::ensure!(self.mode.is_local(), "called update_diagnostics on remote");
11236        let updates = lsp_diagnostics
11237            .into_iter()
11238            .filter_map(|update| {
11239                let abs_path = update.diagnostics.uri.to_file_path().ok()?;
11240                Some(DocumentDiagnosticsUpdate {
11241                    diagnostics: self.lsp_to_document_diagnostics(
11242                        abs_path,
11243                        source_kind,
11244                        update.server_id,
11245                        update.diagnostics,
11246                        &update.disk_based_sources,
11247                        update.registration_id.clone(),
11248                    ),
11249                    result_id: update.result_id,
11250                    server_id: update.server_id,
11251                    disk_based_sources: update.disk_based_sources,
11252                    registration_id: update.registration_id,
11253                })
11254            })
11255            .collect();
11256        self.merge_diagnostic_entries(updates, merge, cx)?;
11257        Ok(())
11258    }
11259
11260    fn lsp_to_document_diagnostics(
11261        &mut self,
11262        document_abs_path: PathBuf,
11263        source_kind: DiagnosticSourceKind,
11264        server_id: LanguageServerId,
11265        mut lsp_diagnostics: lsp::PublishDiagnosticsParams,
11266        disk_based_sources: &[String],
11267        registration_id: Option<SharedString>,
11268    ) -> DocumentDiagnostics {
11269        let mut diagnostics = Vec::default();
11270        let mut primary_diagnostic_group_ids = HashMap::default();
11271        let mut sources_by_group_id = HashMap::default();
11272        let mut supporting_diagnostics = HashMap::default();
11273
11274        let adapter = self.language_server_adapter_for_id(server_id);
11275
11276        // Ensure that primary diagnostics are always the most severe
11277        lsp_diagnostics
11278            .diagnostics
11279            .sort_by_key(|item| item.severity);
11280
11281        for diagnostic in &lsp_diagnostics.diagnostics {
11282            let source = diagnostic.source.as_ref();
11283            let range = range_from_lsp(diagnostic.range);
11284            let is_supporting = diagnostic
11285                .related_information
11286                .as_ref()
11287                .is_some_and(|infos| {
11288                    infos.iter().any(|info| {
11289                        primary_diagnostic_group_ids.contains_key(&(
11290                            source,
11291                            diagnostic.code.clone(),
11292                            range_from_lsp(info.location.range),
11293                        ))
11294                    })
11295                });
11296
11297            let is_unnecessary = diagnostic
11298                .tags
11299                .as_ref()
11300                .is_some_and(|tags| tags.contains(&DiagnosticTag::UNNECESSARY));
11301
11302            let underline = self
11303                .language_server_adapter_for_id(server_id)
11304                .is_none_or(|adapter| adapter.underline_diagnostic(diagnostic));
11305
11306            if is_supporting {
11307                supporting_diagnostics.insert(
11308                    (source, diagnostic.code.clone(), range),
11309                    (diagnostic.severity, is_unnecessary),
11310                );
11311            } else {
11312                let group_id = post_inc(&mut self.as_local_mut().unwrap().next_diagnostic_group_id);
11313                let is_disk_based =
11314                    source.is_some_and(|source| disk_based_sources.contains(source));
11315
11316                sources_by_group_id.insert(group_id, source);
11317                primary_diagnostic_group_ids
11318                    .insert((source, diagnostic.code.clone(), range.clone()), group_id);
11319
11320                diagnostics.push(DiagnosticEntry {
11321                    range,
11322                    diagnostic: Diagnostic {
11323                        source: diagnostic.source.clone(),
11324                        source_kind,
11325                        code: diagnostic.code.clone(),
11326                        code_description: diagnostic
11327                            .code_description
11328                            .as_ref()
11329                            .and_then(|d| d.href.clone()),
11330                        severity: diagnostic.severity.unwrap_or(DiagnosticSeverity::ERROR),
11331                        markdown: adapter.as_ref().and_then(|adapter| {
11332                            adapter.diagnostic_message_to_markdown(&diagnostic.message)
11333                        }),
11334                        message: diagnostic.message.trim().to_string(),
11335                        group_id,
11336                        is_primary: true,
11337                        is_disk_based,
11338                        is_unnecessary,
11339                        underline,
11340                        data: diagnostic.data.clone(),
11341                        registration_id: registration_id.clone(),
11342                    },
11343                });
11344                if let Some(infos) = &diagnostic.related_information {
11345                    for info in infos {
11346                        if info.location.uri == lsp_diagnostics.uri && !info.message.is_empty() {
11347                            let range = range_from_lsp(info.location.range);
11348                            diagnostics.push(DiagnosticEntry {
11349                                range,
11350                                diagnostic: Diagnostic {
11351                                    source: diagnostic.source.clone(),
11352                                    source_kind,
11353                                    code: diagnostic.code.clone(),
11354                                    code_description: diagnostic
11355                                        .code_description
11356                                        .as_ref()
11357                                        .and_then(|d| d.href.clone()),
11358                                    severity: DiagnosticSeverity::INFORMATION,
11359                                    markdown: adapter.as_ref().and_then(|adapter| {
11360                                        adapter.diagnostic_message_to_markdown(&info.message)
11361                                    }),
11362                                    message: info.message.trim().to_string(),
11363                                    group_id,
11364                                    is_primary: false,
11365                                    is_disk_based,
11366                                    is_unnecessary: false,
11367                                    underline,
11368                                    data: diagnostic.data.clone(),
11369                                    registration_id: registration_id.clone(),
11370                                },
11371                            });
11372                        }
11373                    }
11374                }
11375            }
11376        }
11377
11378        for entry in &mut diagnostics {
11379            let diagnostic = &mut entry.diagnostic;
11380            if !diagnostic.is_primary {
11381                let source = *sources_by_group_id.get(&diagnostic.group_id).unwrap();
11382                if let Some(&(severity, is_unnecessary)) = supporting_diagnostics.get(&(
11383                    source,
11384                    diagnostic.code.clone(),
11385                    entry.range.clone(),
11386                )) {
11387                    if let Some(severity) = severity {
11388                        diagnostic.severity = severity;
11389                    }
11390                    diagnostic.is_unnecessary = is_unnecessary;
11391                }
11392            }
11393        }
11394
11395        DocumentDiagnostics {
11396            diagnostics,
11397            document_abs_path,
11398            version: lsp_diagnostics.version,
11399        }
11400    }
11401
11402    fn insert_newly_running_language_server(
11403        &mut self,
11404        adapter: Arc<CachedLspAdapter>,
11405        language_server: Arc<LanguageServer>,
11406        server_id: LanguageServerId,
11407        key: LanguageServerSeed,
11408        workspace_folders: Arc<Mutex<BTreeSet<Uri>>>,
11409        cx: &mut Context<Self>,
11410    ) {
11411        let Some(local) = self.as_local_mut() else {
11412            return;
11413        };
11414        // If the language server for this key doesn't match the server id, don't store the
11415        // server. Which will cause it to be dropped, killing the process
11416        if local
11417            .language_server_ids
11418            .get(&key)
11419            .map(|state| state.id != server_id)
11420            .unwrap_or(false)
11421        {
11422            return;
11423        }
11424
11425        // Update language_servers collection with Running variant of LanguageServerState
11426        // indicating that the server is up and running and ready
11427        let workspace_folders = workspace_folders.lock().clone();
11428        language_server.set_workspace_folders(workspace_folders);
11429
11430        let workspace_diagnostics_refresh_tasks = language_server
11431            .capabilities()
11432            .diagnostic_provider
11433            .and_then(|provider| {
11434                local
11435                    .language_server_dynamic_registrations
11436                    .entry(server_id)
11437                    .or_default()
11438                    .diagnostics
11439                    .entry(None)
11440                    .or_insert(provider.clone());
11441                let workspace_refresher =
11442                    lsp_workspace_diagnostics_refresh(None, provider, language_server.clone(), cx)?;
11443
11444                Some((None, workspace_refresher))
11445            })
11446            .into_iter()
11447            .collect();
11448        local.language_servers.insert(
11449            server_id,
11450            LanguageServerState::Running {
11451                workspace_diagnostics_refresh_tasks,
11452                adapter: adapter.clone(),
11453                server: language_server.clone(),
11454                simulate_disk_based_diagnostics_completion: None,
11455            },
11456        );
11457        local
11458            .languages
11459            .update_lsp_binary_status(adapter.name(), BinaryStatus::None);
11460        if let Some(file_ops_caps) = language_server
11461            .capabilities()
11462            .workspace
11463            .as_ref()
11464            .and_then(|ws| ws.file_operations.as_ref())
11465        {
11466            let did_rename_caps = file_ops_caps.did_rename.as_ref();
11467            let will_rename_caps = file_ops_caps.will_rename.as_ref();
11468            if did_rename_caps.or(will_rename_caps).is_some() {
11469                let watcher = RenamePathsWatchedForServer::default()
11470                    .with_did_rename_patterns(did_rename_caps)
11471                    .with_will_rename_patterns(will_rename_caps);
11472                local
11473                    .language_server_paths_watched_for_rename
11474                    .insert(server_id, watcher);
11475            }
11476        }
11477
11478        self.language_server_statuses.insert(
11479            server_id,
11480            LanguageServerStatus {
11481                name: language_server.name(),
11482                server_version: language_server.version(),
11483                pending_work: Default::default(),
11484                has_pending_diagnostic_updates: false,
11485                progress_tokens: Default::default(),
11486                worktree: Some(key.worktree_id),
11487                binary: Some(language_server.binary().clone()),
11488                configuration: Some(language_server.configuration().clone()),
11489                workspace_folders: language_server.workspace_folders(),
11490            },
11491        );
11492
11493        cx.emit(LspStoreEvent::LanguageServerAdded(
11494            server_id,
11495            language_server.name(),
11496            Some(key.worktree_id),
11497        ));
11498
11499        let server_capabilities = language_server.capabilities();
11500        if let Some((downstream_client, project_id)) = self.downstream_client.as_ref() {
11501            downstream_client
11502                .send(proto::StartLanguageServer {
11503                    project_id: *project_id,
11504                    server: Some(proto::LanguageServer {
11505                        id: server_id.to_proto(),
11506                        name: language_server.name().to_string(),
11507                        worktree_id: Some(key.worktree_id.to_proto()),
11508                    }),
11509                    capabilities: serde_json::to_string(&server_capabilities)
11510                        .expect("serializing server LSP capabilities"),
11511                })
11512                .log_err();
11513        }
11514        self.lsp_server_capabilities
11515            .insert(server_id, server_capabilities);
11516
11517        // Tell the language server about every open buffer in the worktree that matches the language.
11518        // Also check for buffers in worktrees that reused this server
11519        let mut worktrees_using_server = vec![key.worktree_id];
11520        if let Some(local) = self.as_local() {
11521            // Find all worktrees that have this server in their language server tree
11522            for (worktree_id, servers) in &local.lsp_tree.instances {
11523                if *worktree_id != key.worktree_id {
11524                    for server_map in servers.roots.values() {
11525                        if server_map
11526                            .values()
11527                            .any(|(node, _)| node.id() == Some(server_id))
11528                        {
11529                            worktrees_using_server.push(*worktree_id);
11530                        }
11531                    }
11532                }
11533            }
11534        }
11535
11536        let mut buffer_paths_registered = Vec::new();
11537        self.buffer_store.clone().update(cx, |buffer_store, cx| {
11538            let mut lsp_adapters = HashMap::default();
11539            for buffer_handle in buffer_store.buffers() {
11540                let buffer = buffer_handle.read(cx);
11541                let file = match File::from_dyn(buffer.file()) {
11542                    Some(file) => file,
11543                    None => continue,
11544                };
11545                let language = match buffer.language() {
11546                    Some(language) => language,
11547                    None => continue,
11548                };
11549
11550                if !worktrees_using_server.contains(&file.worktree.read(cx).id())
11551                    || !lsp_adapters
11552                        .entry(language.name())
11553                        .or_insert_with(|| self.languages.lsp_adapters(&language.name()))
11554                        .iter()
11555                        .any(|a| a.name == key.name)
11556                {
11557                    continue;
11558                }
11559                // didOpen
11560                let file = match file.as_local() {
11561                    Some(file) => file,
11562                    None => continue,
11563                };
11564
11565                let local = self.as_local_mut().unwrap();
11566
11567                let buffer_id = buffer.remote_id();
11568                if local.registered_buffers.contains_key(&buffer_id) {
11569                    let versions = local
11570                        .buffer_snapshots
11571                        .entry(buffer_id)
11572                        .or_default()
11573                        .entry(server_id)
11574                        .and_modify(|_| {
11575                            assert!(
11576                            false,
11577                            "There should not be an existing snapshot for a newly inserted buffer"
11578                        )
11579                        })
11580                        .or_insert_with(|| {
11581                            vec![LspBufferSnapshot {
11582                                version: 0,
11583                                snapshot: buffer.text_snapshot(),
11584                            }]
11585                        });
11586
11587                    let snapshot = versions.last().unwrap();
11588                    let version = snapshot.version;
11589                    let initial_snapshot = &snapshot.snapshot;
11590                    let uri = lsp::Uri::from_file_path(file.abs_path(cx)).unwrap();
11591                    language_server.register_buffer(
11592                        uri,
11593                        adapter.language_id(&language.name()),
11594                        version,
11595                        initial_snapshot.text(),
11596                    );
11597                    buffer_paths_registered.push((buffer_id, file.abs_path(cx)));
11598                    local
11599                        .buffers_opened_in_servers
11600                        .entry(buffer_id)
11601                        .or_default()
11602                        .insert(server_id);
11603                }
11604                buffer_handle.update(cx, |buffer, cx| {
11605                    buffer.set_completion_triggers(
11606                        server_id,
11607                        language_server
11608                            .capabilities()
11609                            .completion_provider
11610                            .as_ref()
11611                            .and_then(|provider| {
11612                                provider
11613                                    .trigger_characters
11614                                    .as_ref()
11615                                    .map(|characters| characters.iter().cloned().collect())
11616                            })
11617                            .unwrap_or_default(),
11618                        cx,
11619                    )
11620                });
11621            }
11622        });
11623
11624        for (buffer_id, abs_path) in buffer_paths_registered {
11625            cx.emit(LspStoreEvent::LanguageServerUpdate {
11626                language_server_id: server_id,
11627                name: Some(adapter.name()),
11628                message: proto::update_language_server::Variant::RegisteredForBuffer(
11629                    proto::RegisteredForBuffer {
11630                        buffer_abs_path: abs_path.to_string_lossy().into_owned(),
11631                        buffer_id: buffer_id.to_proto(),
11632                    },
11633                ),
11634            });
11635        }
11636
11637        cx.notify();
11638    }
11639
11640    pub fn language_servers_running_disk_based_diagnostics(
11641        &self,
11642    ) -> impl Iterator<Item = LanguageServerId> + '_ {
11643        self.language_server_statuses
11644            .iter()
11645            .filter_map(|(id, status)| {
11646                if status.has_pending_diagnostic_updates {
11647                    Some(*id)
11648                } else {
11649                    None
11650                }
11651            })
11652    }
11653
11654    pub(crate) fn cancel_language_server_work_for_buffers(
11655        &mut self,
11656        buffers: impl IntoIterator<Item = Entity<Buffer>>,
11657        cx: &mut Context<Self>,
11658    ) {
11659        if let Some((client, project_id)) = self.upstream_client() {
11660            let request = client.request(proto::CancelLanguageServerWork {
11661                project_id,
11662                work: Some(proto::cancel_language_server_work::Work::Buffers(
11663                    proto::cancel_language_server_work::Buffers {
11664                        buffer_ids: buffers
11665                            .into_iter()
11666                            .map(|b| b.read(cx).remote_id().to_proto())
11667                            .collect(),
11668                    },
11669                )),
11670            });
11671            cx.background_spawn(request).detach_and_log_err(cx);
11672        } else if let Some(local) = self.as_local() {
11673            let servers = buffers
11674                .into_iter()
11675                .flat_map(|buffer| {
11676                    buffer.update(cx, |buffer, cx| {
11677                        local.language_server_ids_for_buffer(buffer, cx).into_iter()
11678                    })
11679                })
11680                .collect::<HashSet<_>>();
11681            for server_id in servers {
11682                self.cancel_language_server_work(server_id, None, cx);
11683            }
11684        }
11685    }
11686
11687    pub(crate) fn cancel_language_server_work(
11688        &mut self,
11689        server_id: LanguageServerId,
11690        token_to_cancel: Option<ProgressToken>,
11691        cx: &mut Context<Self>,
11692    ) {
11693        if let Some(local) = self.as_local() {
11694            let status = self.language_server_statuses.get(&server_id);
11695            let server = local.language_servers.get(&server_id);
11696            if let Some((LanguageServerState::Running { server, .. }, status)) = server.zip(status)
11697            {
11698                for (token, progress) in &status.pending_work {
11699                    if let Some(token_to_cancel) = token_to_cancel.as_ref()
11700                        && token != token_to_cancel
11701                    {
11702                        continue;
11703                    }
11704                    if progress.is_cancellable {
11705                        server
11706                            .notify::<lsp::notification::WorkDoneProgressCancel>(
11707                                WorkDoneProgressCancelParams {
11708                                    token: token.to_lsp(),
11709                                },
11710                            )
11711                            .ok();
11712                    }
11713                }
11714            }
11715        } else if let Some((client, project_id)) = self.upstream_client() {
11716            let request = client.request(proto::CancelLanguageServerWork {
11717                project_id,
11718                work: Some(
11719                    proto::cancel_language_server_work::Work::LanguageServerWork(
11720                        proto::cancel_language_server_work::LanguageServerWork {
11721                            language_server_id: server_id.to_proto(),
11722                            token: token_to_cancel.map(|token| token.to_proto()),
11723                        },
11724                    ),
11725                ),
11726            });
11727            cx.background_spawn(request).detach_and_log_err(cx);
11728        }
11729    }
11730
11731    fn register_supplementary_language_server(
11732        &mut self,
11733        id: LanguageServerId,
11734        name: LanguageServerName,
11735        server: Arc<LanguageServer>,
11736        cx: &mut Context<Self>,
11737    ) {
11738        if let Some(local) = self.as_local_mut() {
11739            local
11740                .supplementary_language_servers
11741                .insert(id, (name.clone(), server));
11742            cx.emit(LspStoreEvent::LanguageServerAdded(id, name, None));
11743        }
11744    }
11745
11746    fn unregister_supplementary_language_server(
11747        &mut self,
11748        id: LanguageServerId,
11749        cx: &mut Context<Self>,
11750    ) {
11751        if let Some(local) = self.as_local_mut() {
11752            local.supplementary_language_servers.remove(&id);
11753            cx.emit(LspStoreEvent::LanguageServerRemoved(id));
11754        }
11755    }
11756
11757    pub(crate) fn supplementary_language_servers(
11758        &self,
11759    ) -> impl '_ + Iterator<Item = (LanguageServerId, LanguageServerName)> {
11760        self.as_local().into_iter().flat_map(|local| {
11761            local
11762                .supplementary_language_servers
11763                .iter()
11764                .map(|(id, (name, _))| (*id, name.clone()))
11765        })
11766    }
11767
11768    pub fn language_server_adapter_for_id(
11769        &self,
11770        id: LanguageServerId,
11771    ) -> Option<Arc<CachedLspAdapter>> {
11772        self.as_local()
11773            .and_then(|local| local.language_servers.get(&id))
11774            .and_then(|language_server_state| match language_server_state {
11775                LanguageServerState::Running { adapter, .. } => Some(adapter.clone()),
11776                _ => None,
11777            })
11778    }
11779
11780    pub(super) fn update_local_worktree_language_servers(
11781        &mut self,
11782        worktree_handle: &Entity<Worktree>,
11783        changes: &[(Arc<RelPath>, ProjectEntryId, PathChange)],
11784        cx: &mut Context<Self>,
11785    ) {
11786        if changes.is_empty() {
11787            return;
11788        }
11789
11790        let Some(local) = self.as_local() else { return };
11791
11792        local.prettier_store.update(cx, |prettier_store, cx| {
11793            prettier_store.update_prettier_settings(worktree_handle, changes, cx)
11794        });
11795
11796        let worktree_id = worktree_handle.read(cx).id();
11797        let mut language_server_ids = local
11798            .language_server_ids
11799            .iter()
11800            .filter_map(|(seed, v)| seed.worktree_id.eq(&worktree_id).then(|| v.id))
11801            .collect::<Vec<_>>();
11802        language_server_ids.sort();
11803        language_server_ids.dedup();
11804
11805        // let abs_path = worktree_handle.read(cx).abs_path();
11806        for server_id in &language_server_ids {
11807            if let Some(LanguageServerState::Running { server, .. }) =
11808                local.language_servers.get(server_id)
11809                && let Some(watched_paths) = local
11810                    .language_server_watched_paths
11811                    .get(server_id)
11812                    .and_then(|paths| paths.worktree_paths.get(&worktree_id))
11813            {
11814                let params = lsp::DidChangeWatchedFilesParams {
11815                    changes: changes
11816                        .iter()
11817                        .filter_map(|(path, _, change)| {
11818                            if !watched_paths.is_match(path.as_std_path()) {
11819                                return None;
11820                            }
11821                            let typ = match change {
11822                                PathChange::Loaded => return None,
11823                                PathChange::Added => lsp::FileChangeType::CREATED,
11824                                PathChange::Removed => lsp::FileChangeType::DELETED,
11825                                PathChange::Updated => lsp::FileChangeType::CHANGED,
11826                                PathChange::AddedOrUpdated => lsp::FileChangeType::CHANGED,
11827                            };
11828                            let uri = lsp::Uri::from_file_path(
11829                                worktree_handle.read(cx).absolutize(&path),
11830                            )
11831                            .ok()?;
11832                            Some(lsp::FileEvent { uri, typ })
11833                        })
11834                        .collect(),
11835                };
11836                if !params.changes.is_empty() {
11837                    server
11838                        .notify::<lsp::notification::DidChangeWatchedFiles>(params)
11839                        .ok();
11840                }
11841            }
11842        }
11843        for (path, _, _) in changes {
11844            if let Some(file_name) = path.file_name()
11845                && local.watched_manifest_filenames.contains(file_name)
11846            {
11847                self.request_workspace_config_refresh();
11848                break;
11849            }
11850        }
11851    }
11852
11853    pub fn wait_for_remote_buffer(
11854        &mut self,
11855        id: BufferId,
11856        cx: &mut Context<Self>,
11857    ) -> Task<Result<Entity<Buffer>>> {
11858        self.buffer_store.update(cx, |buffer_store, cx| {
11859            buffer_store.wait_for_remote_buffer(id, cx)
11860        })
11861    }
11862
11863    fn serialize_symbol(symbol: &Symbol) -> proto::Symbol {
11864        let mut result = proto::Symbol {
11865            language_server_name: symbol.language_server_name.0.to_string(),
11866            source_worktree_id: symbol.source_worktree_id.to_proto(),
11867            language_server_id: symbol.source_language_server_id.to_proto(),
11868            name: symbol.name.clone(),
11869            kind: unsafe { mem::transmute::<lsp::SymbolKind, i32>(symbol.kind) },
11870            start: Some(proto::PointUtf16 {
11871                row: symbol.range.start.0.row,
11872                column: symbol.range.start.0.column,
11873            }),
11874            end: Some(proto::PointUtf16 {
11875                row: symbol.range.end.0.row,
11876                column: symbol.range.end.0.column,
11877            }),
11878            worktree_id: Default::default(),
11879            path: Default::default(),
11880            signature: Default::default(),
11881        };
11882        match &symbol.path {
11883            SymbolLocation::InProject(path) => {
11884                result.worktree_id = path.worktree_id.to_proto();
11885                result.path = path.path.to_proto();
11886            }
11887            SymbolLocation::OutsideProject {
11888                abs_path,
11889                signature,
11890            } => {
11891                result.path = abs_path.to_string_lossy().into_owned();
11892                result.signature = signature.to_vec();
11893            }
11894        }
11895        result
11896    }
11897
11898    fn deserialize_symbol(serialized_symbol: proto::Symbol) -> Result<CoreSymbol> {
11899        let source_worktree_id = WorktreeId::from_proto(serialized_symbol.source_worktree_id);
11900        let worktree_id = WorktreeId::from_proto(serialized_symbol.worktree_id);
11901        let kind = unsafe { mem::transmute::<i32, lsp::SymbolKind>(serialized_symbol.kind) };
11902
11903        let path = if serialized_symbol.signature.is_empty() {
11904            SymbolLocation::InProject(ProjectPath {
11905                worktree_id,
11906                path: RelPath::from_proto(&serialized_symbol.path)
11907                    .context("invalid symbol path")?,
11908            })
11909        } else {
11910            SymbolLocation::OutsideProject {
11911                abs_path: Path::new(&serialized_symbol.path).into(),
11912                signature: serialized_symbol
11913                    .signature
11914                    .try_into()
11915                    .map_err(|_| anyhow!("invalid signature"))?,
11916            }
11917        };
11918
11919        let start = serialized_symbol.start.context("invalid start")?;
11920        let end = serialized_symbol.end.context("invalid end")?;
11921        Ok(CoreSymbol {
11922            language_server_name: LanguageServerName(serialized_symbol.language_server_name.into()),
11923            source_worktree_id,
11924            source_language_server_id: LanguageServerId::from_proto(
11925                serialized_symbol.language_server_id,
11926            ),
11927            path,
11928            name: serialized_symbol.name,
11929            range: Unclipped(PointUtf16::new(start.row, start.column))
11930                ..Unclipped(PointUtf16::new(end.row, end.column)),
11931            kind,
11932        })
11933    }
11934
11935    pub(crate) fn serialize_completion(completion: &CoreCompletion) -> proto::Completion {
11936        let mut serialized_completion = proto::Completion {
11937            old_replace_start: Some(serialize_anchor(&completion.replace_range.start)),
11938            old_replace_end: Some(serialize_anchor(&completion.replace_range.end)),
11939            new_text: completion.new_text.clone(),
11940            ..proto::Completion::default()
11941        };
11942        match &completion.source {
11943            CompletionSource::Lsp {
11944                insert_range,
11945                server_id,
11946                lsp_completion,
11947                lsp_defaults,
11948                resolved,
11949            } => {
11950                let (old_insert_start, old_insert_end) = insert_range
11951                    .as_ref()
11952                    .map(|range| (serialize_anchor(&range.start), serialize_anchor(&range.end)))
11953                    .unzip();
11954
11955                serialized_completion.old_insert_start = old_insert_start;
11956                serialized_completion.old_insert_end = old_insert_end;
11957                serialized_completion.source = proto::completion::Source::Lsp as i32;
11958                serialized_completion.server_id = server_id.0 as u64;
11959                serialized_completion.lsp_completion = serde_json::to_vec(lsp_completion).unwrap();
11960                serialized_completion.lsp_defaults = lsp_defaults
11961                    .as_deref()
11962                    .map(|lsp_defaults| serde_json::to_vec(lsp_defaults).unwrap());
11963                serialized_completion.resolved = *resolved;
11964            }
11965            CompletionSource::BufferWord {
11966                word_range,
11967                resolved,
11968            } => {
11969                serialized_completion.source = proto::completion::Source::BufferWord as i32;
11970                serialized_completion.buffer_word_start = Some(serialize_anchor(&word_range.start));
11971                serialized_completion.buffer_word_end = Some(serialize_anchor(&word_range.end));
11972                serialized_completion.resolved = *resolved;
11973            }
11974            CompletionSource::Custom => {
11975                serialized_completion.source = proto::completion::Source::Custom as i32;
11976                serialized_completion.resolved = true;
11977            }
11978            CompletionSource::Dap { sort_text } => {
11979                serialized_completion.source = proto::completion::Source::Dap as i32;
11980                serialized_completion.sort_text = Some(sort_text.clone());
11981            }
11982        }
11983
11984        serialized_completion
11985    }
11986
11987    pub(crate) fn deserialize_completion(completion: proto::Completion) -> Result<CoreCompletion> {
11988        let old_replace_start = completion
11989            .old_replace_start
11990            .and_then(deserialize_anchor)
11991            .context("invalid old start")?;
11992        let old_replace_end = completion
11993            .old_replace_end
11994            .and_then(deserialize_anchor)
11995            .context("invalid old end")?;
11996        let insert_range = {
11997            match completion.old_insert_start.zip(completion.old_insert_end) {
11998                Some((start, end)) => {
11999                    let start = deserialize_anchor(start).context("invalid insert old start")?;
12000                    let end = deserialize_anchor(end).context("invalid insert old end")?;
12001                    Some(start..end)
12002                }
12003                None => None,
12004            }
12005        };
12006        Ok(CoreCompletion {
12007            replace_range: old_replace_start..old_replace_end,
12008            new_text: completion.new_text,
12009            source: match proto::completion::Source::from_i32(completion.source) {
12010                Some(proto::completion::Source::Custom) => CompletionSource::Custom,
12011                Some(proto::completion::Source::Lsp) => CompletionSource::Lsp {
12012                    insert_range,
12013                    server_id: LanguageServerId::from_proto(completion.server_id),
12014                    lsp_completion: serde_json::from_slice(&completion.lsp_completion)?,
12015                    lsp_defaults: completion
12016                        .lsp_defaults
12017                        .as_deref()
12018                        .map(serde_json::from_slice)
12019                        .transpose()?,
12020                    resolved: completion.resolved,
12021                },
12022                Some(proto::completion::Source::BufferWord) => {
12023                    let word_range = completion
12024                        .buffer_word_start
12025                        .and_then(deserialize_anchor)
12026                        .context("invalid buffer word start")?
12027                        ..completion
12028                            .buffer_word_end
12029                            .and_then(deserialize_anchor)
12030                            .context("invalid buffer word end")?;
12031                    CompletionSource::BufferWord {
12032                        word_range,
12033                        resolved: completion.resolved,
12034                    }
12035                }
12036                Some(proto::completion::Source::Dap) => CompletionSource::Dap {
12037                    sort_text: completion
12038                        .sort_text
12039                        .context("expected sort text to exist")?,
12040                },
12041                _ => anyhow::bail!("Unexpected completion source {}", completion.source),
12042            },
12043        })
12044    }
12045
12046    pub(crate) fn serialize_code_action(action: &CodeAction) -> proto::CodeAction {
12047        let (kind, lsp_action) = match &action.lsp_action {
12048            LspAction::Action(code_action) => (
12049                proto::code_action::Kind::Action as i32,
12050                serde_json::to_vec(code_action).unwrap(),
12051            ),
12052            LspAction::Command(command) => (
12053                proto::code_action::Kind::Command as i32,
12054                serde_json::to_vec(command).unwrap(),
12055            ),
12056            LspAction::CodeLens(code_lens) => (
12057                proto::code_action::Kind::CodeLens as i32,
12058                serde_json::to_vec(code_lens).unwrap(),
12059            ),
12060        };
12061
12062        proto::CodeAction {
12063            server_id: action.server_id.0 as u64,
12064            start: Some(serialize_anchor(&action.range.start)),
12065            end: Some(serialize_anchor(&action.range.end)),
12066            lsp_action,
12067            kind,
12068            resolved: action.resolved,
12069        }
12070    }
12071
12072    pub(crate) fn deserialize_code_action(action: proto::CodeAction) -> Result<CodeAction> {
12073        let start = action
12074            .start
12075            .and_then(deserialize_anchor)
12076            .context("invalid start")?;
12077        let end = action
12078            .end
12079            .and_then(deserialize_anchor)
12080            .context("invalid end")?;
12081        let lsp_action = match proto::code_action::Kind::from_i32(action.kind) {
12082            Some(proto::code_action::Kind::Action) => {
12083                LspAction::Action(serde_json::from_slice(&action.lsp_action)?)
12084            }
12085            Some(proto::code_action::Kind::Command) => {
12086                LspAction::Command(serde_json::from_slice(&action.lsp_action)?)
12087            }
12088            Some(proto::code_action::Kind::CodeLens) => {
12089                LspAction::CodeLens(serde_json::from_slice(&action.lsp_action)?)
12090            }
12091            None => anyhow::bail!("Unknown action kind {}", action.kind),
12092        };
12093        Ok(CodeAction {
12094            server_id: LanguageServerId(action.server_id as usize),
12095            range: start..end,
12096            resolved: action.resolved,
12097            lsp_action,
12098        })
12099    }
12100
12101    fn update_last_formatting_failure<T>(&mut self, formatting_result: &anyhow::Result<T>) {
12102        match &formatting_result {
12103            Ok(_) => self.last_formatting_failure = None,
12104            Err(error) => {
12105                let error_string = format!("{error:#}");
12106                log::error!("Formatting failed: {error_string}");
12107                self.last_formatting_failure
12108                    .replace(error_string.lines().join(" "));
12109            }
12110        }
12111    }
12112
12113    fn cleanup_lsp_data(&mut self, for_server: LanguageServerId) {
12114        self.lsp_server_capabilities.remove(&for_server);
12115        for lsp_data in self.lsp_data.values_mut() {
12116            lsp_data.remove_server_data(for_server);
12117        }
12118        if let Some(local) = self.as_local_mut() {
12119            local.buffer_pull_diagnostics_result_ids.remove(&for_server);
12120            local
12121                .workspace_pull_diagnostics_result_ids
12122                .remove(&for_server);
12123            for buffer_servers in local.buffers_opened_in_servers.values_mut() {
12124                buffer_servers.remove(&for_server);
12125            }
12126        }
12127    }
12128
12129    pub fn result_id_for_buffer_pull(
12130        &self,
12131        server_id: LanguageServerId,
12132        buffer_id: BufferId,
12133        registration_id: &Option<SharedString>,
12134        cx: &App,
12135    ) -> Option<SharedString> {
12136        let abs_path = self
12137            .buffer_store
12138            .read(cx)
12139            .get(buffer_id)
12140            .and_then(|b| File::from_dyn(b.read(cx).file()))
12141            .map(|f| f.abs_path(cx))?;
12142        self.as_local()?
12143            .buffer_pull_diagnostics_result_ids
12144            .get(&server_id)?
12145            .get(registration_id)?
12146            .get(&abs_path)?
12147            .clone()
12148    }
12149
12150    /// Gets all result_ids for a workspace diagnostics pull request.
12151    /// 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.
12152    /// The latter is supposed to be of lower priority as we keep on pulling diagnostics for open buffers eagerly.
12153    pub fn result_ids_for_workspace_refresh(
12154        &self,
12155        server_id: LanguageServerId,
12156        registration_id: &Option<SharedString>,
12157    ) -> HashMap<PathBuf, SharedString> {
12158        let Some(local) = self.as_local() else {
12159            return HashMap::default();
12160        };
12161        local
12162            .workspace_pull_diagnostics_result_ids
12163            .get(&server_id)
12164            .into_iter()
12165            .filter_map(|diagnostics| diagnostics.get(registration_id))
12166            .flatten()
12167            .filter_map(|(abs_path, result_id)| {
12168                let result_id = local
12169                    .buffer_pull_diagnostics_result_ids
12170                    .get(&server_id)
12171                    .and_then(|buffer_ids_result_ids| {
12172                        buffer_ids_result_ids.get(registration_id)?.get(abs_path)
12173                    })
12174                    .cloned()
12175                    .flatten()
12176                    .or_else(|| result_id.clone())?;
12177                Some((abs_path.clone(), result_id))
12178            })
12179            .collect()
12180    }
12181
12182    pub fn pull_workspace_diagnostics(&mut self, server_id: LanguageServerId) {
12183        if let Some(LanguageServerState::Running {
12184            workspace_diagnostics_refresh_tasks,
12185            ..
12186        }) = self
12187            .as_local_mut()
12188            .and_then(|local| local.language_servers.get_mut(&server_id))
12189        {
12190            for diagnostics in workspace_diagnostics_refresh_tasks.values_mut() {
12191                diagnostics.refresh_tx.try_send(()).ok();
12192            }
12193        }
12194    }
12195
12196    /// Refreshes `textDocument/diagnostic` for all open buffers associated with the given server.
12197    /// This is called in response to `workspace/diagnostic/refresh` to comply with the LSP spec,
12198    /// which requires refreshing both workspace and document diagnostics.
12199    pub fn pull_document_diagnostics_for_server(
12200        &mut self,
12201        server_id: LanguageServerId,
12202        cx: &mut Context<Self>,
12203    ) {
12204        let buffers_to_pull: Vec<_> = self
12205            .as_local()
12206            .into_iter()
12207            .flat_map(|local| {
12208                self.buffer_store.read(cx).buffers().filter(|buffer| {
12209                    let buffer_id = buffer.read(cx).remote_id();
12210                    local
12211                        .buffers_opened_in_servers
12212                        .get(&buffer_id)
12213                        .is_some_and(|servers| servers.contains(&server_id))
12214                })
12215            })
12216            .collect();
12217
12218        for buffer in buffers_to_pull {
12219            self.pull_diagnostics_for_buffer(buffer, cx)
12220                .detach_and_log_err(cx);
12221        }
12222    }
12223
12224    fn apply_workspace_diagnostic_report(
12225        &mut self,
12226        server_id: LanguageServerId,
12227        report: lsp::WorkspaceDiagnosticReportResult,
12228        registration_id: Option<SharedString>,
12229        cx: &mut Context<Self>,
12230    ) {
12231        let mut workspace_diagnostics =
12232            GetDocumentDiagnostics::deserialize_workspace_diagnostics_report(
12233                report,
12234                server_id,
12235                registration_id,
12236            );
12237        workspace_diagnostics.retain(|d| match &d.diagnostics {
12238            LspPullDiagnostics::Response {
12239                server_id,
12240                registration_id,
12241                ..
12242            } => self.diagnostic_registration_exists(*server_id, registration_id),
12243            LspPullDiagnostics::Default => false,
12244        });
12245        let mut unchanged_buffers = HashMap::default();
12246        let workspace_diagnostics_updates = workspace_diagnostics
12247            .into_iter()
12248            .filter_map(
12249                |workspace_diagnostics| match workspace_diagnostics.diagnostics {
12250                    LspPullDiagnostics::Response {
12251                        server_id,
12252                        uri,
12253                        diagnostics,
12254                        registration_id,
12255                    } => Some((
12256                        server_id,
12257                        uri,
12258                        diagnostics,
12259                        workspace_diagnostics.version,
12260                        registration_id,
12261                    )),
12262                    LspPullDiagnostics::Default => None,
12263                },
12264            )
12265            .fold(
12266                HashMap::default(),
12267                |mut acc, (server_id, uri, diagnostics, version, new_registration_id)| {
12268                    let (result_id, diagnostics) = match diagnostics {
12269                        PulledDiagnostics::Unchanged { result_id } => {
12270                            unchanged_buffers
12271                                .entry(new_registration_id.clone())
12272                                .or_insert_with(HashSet::default)
12273                                .insert(uri.clone());
12274                            (Some(result_id), Vec::new())
12275                        }
12276                        PulledDiagnostics::Changed {
12277                            result_id,
12278                            diagnostics,
12279                        } => (result_id, diagnostics),
12280                    };
12281                    let disk_based_sources = Cow::Owned(
12282                        self.language_server_adapter_for_id(server_id)
12283                            .as_ref()
12284                            .map(|adapter| adapter.disk_based_diagnostic_sources.as_slice())
12285                            .unwrap_or(&[])
12286                            .to_vec(),
12287                    );
12288
12289                    let Some(abs_path) = uri.to_file_path().ok() else {
12290                        return acc;
12291                    };
12292                    let Some((worktree, relative_path)) =
12293                        self.worktree_store.read(cx).find_worktree(abs_path.clone(), cx)
12294                    else {
12295                        log::warn!("skipping workspace diagnostics update, no worktree found for path {abs_path:?}");
12296                        return acc;
12297                    };
12298                    let worktree_id = worktree.read(cx).id();
12299                    let project_path = ProjectPath {
12300                        worktree_id,
12301                        path: relative_path,
12302                    };
12303                    if let Some(local_lsp_store) = self.as_local_mut() {
12304                        local_lsp_store.workspace_pull_diagnostics_result_ids.entry(server_id)
12305                            .or_default().entry(new_registration_id.clone()).or_default().insert(abs_path, result_id.clone());
12306                    }
12307                    // The LSP spec recommends that "diagnostics from a document pull should win over diagnostics from a workspace pull."
12308                    // Since we actively pull diagnostics for documents with open buffers, we ignore contents of workspace pulls for these documents.
12309                    if self.buffer_store.read(cx).get_by_path(&project_path).is_none() {
12310                        acc.entry(server_id)
12311                            .or_insert_with(HashMap::default)
12312                            .entry(new_registration_id.clone())
12313                            .or_insert_with(Vec::new)
12314                            .push(DocumentDiagnosticsUpdate {
12315                                server_id,
12316                                diagnostics: lsp::PublishDiagnosticsParams {
12317                                    uri,
12318                                    diagnostics,
12319                                    version,
12320                                },
12321                                result_id,
12322                                disk_based_sources,
12323                                registration_id: new_registration_id,
12324                            });
12325                    }
12326                    acc
12327                },
12328            );
12329
12330        for diagnostic_updates in workspace_diagnostics_updates.into_values() {
12331            for (registration_id, diagnostic_updates) in diagnostic_updates {
12332                self.merge_lsp_diagnostics(
12333                    DiagnosticSourceKind::Pulled,
12334                    diagnostic_updates,
12335                    |document_uri, old_diagnostic, _| match old_diagnostic.source_kind {
12336                        DiagnosticSourceKind::Pulled => {
12337                            old_diagnostic.registration_id != registration_id
12338                                || unchanged_buffers
12339                                    .get(&old_diagnostic.registration_id)
12340                                    .is_some_and(|unchanged_buffers| {
12341                                        unchanged_buffers.contains(&document_uri)
12342                                    })
12343                        }
12344                        DiagnosticSourceKind::Other | DiagnosticSourceKind::Pushed => true,
12345                    },
12346                    cx,
12347                )
12348                .log_err();
12349            }
12350        }
12351    }
12352
12353    fn register_server_capabilities(
12354        &mut self,
12355        server_id: LanguageServerId,
12356        params: lsp::RegistrationParams,
12357        cx: &mut Context<Self>,
12358    ) -> anyhow::Result<()> {
12359        let server = self
12360            .language_server_for_id(server_id)
12361            .with_context(|| format!("no server {server_id} found"))?;
12362        for reg in params.registrations {
12363            match reg.method.as_str() {
12364                "workspace/didChangeWatchedFiles" => {
12365                    if let Some(options) = reg.register_options {
12366                        let notify = if let Some(local_lsp_store) = self.as_local_mut() {
12367                            let caps = serde_json::from_value(options)?;
12368                            local_lsp_store
12369                                .on_lsp_did_change_watched_files(server_id, &reg.id, caps, cx);
12370                            true
12371                        } else {
12372                            false
12373                        };
12374                        if notify {
12375                            notify_server_capabilities_updated(&server, cx);
12376                        }
12377                    }
12378                }
12379                "workspace/didChangeConfiguration" => {
12380                    // Ignore payload since we notify clients of setting changes unconditionally, relying on them pulling the latest settings.
12381                }
12382                "workspace/didChangeWorkspaceFolders" => {
12383                    // In this case register options is an empty object, we can ignore it
12384                    let caps = lsp::WorkspaceFoldersServerCapabilities {
12385                        supported: Some(true),
12386                        change_notifications: Some(OneOf::Right(reg.id)),
12387                    };
12388                    server.update_capabilities(|capabilities| {
12389                        capabilities
12390                            .workspace
12391                            .get_or_insert_default()
12392                            .workspace_folders = Some(caps);
12393                    });
12394                    notify_server_capabilities_updated(&server, cx);
12395                }
12396                "workspace/symbol" => {
12397                    let options = parse_register_capabilities(reg)?;
12398                    server.update_capabilities(|capabilities| {
12399                        capabilities.workspace_symbol_provider = Some(options);
12400                    });
12401                    notify_server_capabilities_updated(&server, cx);
12402                }
12403                "workspace/fileOperations" => {
12404                    if let Some(options) = reg.register_options {
12405                        let caps = serde_json::from_value(options)?;
12406                        server.update_capabilities(|capabilities| {
12407                            capabilities
12408                                .workspace
12409                                .get_or_insert_default()
12410                                .file_operations = Some(caps);
12411                        });
12412                        notify_server_capabilities_updated(&server, cx);
12413                    }
12414                }
12415                "workspace/executeCommand" => {
12416                    if let Some(options) = reg.register_options {
12417                        let options = serde_json::from_value(options)?;
12418                        server.update_capabilities(|capabilities| {
12419                            capabilities.execute_command_provider = Some(options);
12420                        });
12421                        notify_server_capabilities_updated(&server, cx);
12422                    }
12423                }
12424                "textDocument/rangeFormatting" => {
12425                    let options = parse_register_capabilities(reg)?;
12426                    server.update_capabilities(|capabilities| {
12427                        capabilities.document_range_formatting_provider = Some(options);
12428                    });
12429                    notify_server_capabilities_updated(&server, cx);
12430                }
12431                "textDocument/onTypeFormatting" => {
12432                    if let Some(options) = reg
12433                        .register_options
12434                        .map(serde_json::from_value)
12435                        .transpose()?
12436                    {
12437                        server.update_capabilities(|capabilities| {
12438                            capabilities.document_on_type_formatting_provider = Some(options);
12439                        });
12440                        notify_server_capabilities_updated(&server, cx);
12441                    }
12442                }
12443                "textDocument/formatting" => {
12444                    let options = parse_register_capabilities(reg)?;
12445                    server.update_capabilities(|capabilities| {
12446                        capabilities.document_formatting_provider = Some(options);
12447                    });
12448                    notify_server_capabilities_updated(&server, cx);
12449                }
12450                "textDocument/rename" => {
12451                    let options = parse_register_capabilities(reg)?;
12452                    server.update_capabilities(|capabilities| {
12453                        capabilities.rename_provider = Some(options);
12454                    });
12455                    notify_server_capabilities_updated(&server, cx);
12456                }
12457                "textDocument/inlayHint" => {
12458                    let options = parse_register_capabilities(reg)?;
12459                    server.update_capabilities(|capabilities| {
12460                        capabilities.inlay_hint_provider = Some(options);
12461                    });
12462                    notify_server_capabilities_updated(&server, cx);
12463                }
12464                "textDocument/documentSymbol" => {
12465                    let options = parse_register_capabilities(reg)?;
12466                    server.update_capabilities(|capabilities| {
12467                        capabilities.document_symbol_provider = Some(options);
12468                    });
12469                    notify_server_capabilities_updated(&server, cx);
12470                }
12471                "textDocument/codeAction" => {
12472                    let options = parse_register_capabilities(reg)?;
12473                    let provider = match options {
12474                        OneOf::Left(value) => lsp::CodeActionProviderCapability::Simple(value),
12475                        OneOf::Right(caps) => caps,
12476                    };
12477                    server.update_capabilities(|capabilities| {
12478                        capabilities.code_action_provider = Some(provider);
12479                    });
12480                    notify_server_capabilities_updated(&server, cx);
12481                }
12482                "textDocument/definition" => {
12483                    let options = parse_register_capabilities(reg)?;
12484                    server.update_capabilities(|capabilities| {
12485                        capabilities.definition_provider = Some(options);
12486                    });
12487                    notify_server_capabilities_updated(&server, cx);
12488                }
12489                "textDocument/completion" => {
12490                    if let Some(caps) = reg
12491                        .register_options
12492                        .map(serde_json::from_value::<CompletionOptions>)
12493                        .transpose()?
12494                    {
12495                        server.update_capabilities(|capabilities| {
12496                            capabilities.completion_provider = Some(caps.clone());
12497                        });
12498
12499                        if let Some(local) = self.as_local() {
12500                            let mut buffers_with_language_server = Vec::new();
12501                            for handle in self.buffer_store.read(cx).buffers() {
12502                                let buffer_id = handle.read(cx).remote_id();
12503                                if local
12504                                    .buffers_opened_in_servers
12505                                    .get(&buffer_id)
12506                                    .filter(|s| s.contains(&server_id))
12507                                    .is_some()
12508                                {
12509                                    buffers_with_language_server.push(handle);
12510                                }
12511                            }
12512                            let triggers = caps
12513                                .trigger_characters
12514                                .unwrap_or_default()
12515                                .into_iter()
12516                                .collect::<BTreeSet<_>>();
12517                            for handle in buffers_with_language_server {
12518                                let triggers = triggers.clone();
12519                                let _ = handle.update(cx, move |buffer, cx| {
12520                                    buffer.set_completion_triggers(server_id, triggers, cx);
12521                                });
12522                            }
12523                        }
12524                        notify_server_capabilities_updated(&server, cx);
12525                    }
12526                }
12527                "textDocument/hover" => {
12528                    let options = parse_register_capabilities(reg)?;
12529                    let provider = match options {
12530                        OneOf::Left(value) => lsp::HoverProviderCapability::Simple(value),
12531                        OneOf::Right(caps) => caps,
12532                    };
12533                    server.update_capabilities(|capabilities| {
12534                        capabilities.hover_provider = Some(provider);
12535                    });
12536                    notify_server_capabilities_updated(&server, cx);
12537                }
12538                "textDocument/signatureHelp" => {
12539                    if let Some(caps) = reg
12540                        .register_options
12541                        .map(serde_json::from_value)
12542                        .transpose()?
12543                    {
12544                        server.update_capabilities(|capabilities| {
12545                            capabilities.signature_help_provider = Some(caps);
12546                        });
12547                        notify_server_capabilities_updated(&server, cx);
12548                    }
12549                }
12550                "textDocument/didChange" => {
12551                    if let Some(sync_kind) = reg
12552                        .register_options
12553                        .and_then(|opts| opts.get("syncKind").cloned())
12554                        .map(serde_json::from_value::<lsp::TextDocumentSyncKind>)
12555                        .transpose()?
12556                    {
12557                        server.update_capabilities(|capabilities| {
12558                            let mut sync_options =
12559                                Self::take_text_document_sync_options(capabilities);
12560                            sync_options.change = Some(sync_kind);
12561                            capabilities.text_document_sync =
12562                                Some(lsp::TextDocumentSyncCapability::Options(sync_options));
12563                        });
12564                        notify_server_capabilities_updated(&server, cx);
12565                    }
12566                }
12567                "textDocument/didSave" => {
12568                    if let Some(include_text) = reg
12569                        .register_options
12570                        .map(|opts| {
12571                            let transpose = opts
12572                                .get("includeText")
12573                                .cloned()
12574                                .map(serde_json::from_value::<Option<bool>>)
12575                                .transpose();
12576                            match transpose {
12577                                Ok(value) => Ok(value.flatten()),
12578                                Err(e) => Err(e),
12579                            }
12580                        })
12581                        .transpose()?
12582                    {
12583                        server.update_capabilities(|capabilities| {
12584                            let mut sync_options =
12585                                Self::take_text_document_sync_options(capabilities);
12586                            sync_options.save =
12587                                Some(TextDocumentSyncSaveOptions::SaveOptions(lsp::SaveOptions {
12588                                    include_text,
12589                                }));
12590                            capabilities.text_document_sync =
12591                                Some(lsp::TextDocumentSyncCapability::Options(sync_options));
12592                        });
12593                        notify_server_capabilities_updated(&server, cx);
12594                    }
12595                }
12596                "textDocument/codeLens" => {
12597                    if let Some(caps) = reg
12598                        .register_options
12599                        .map(serde_json::from_value)
12600                        .transpose()?
12601                    {
12602                        server.update_capabilities(|capabilities| {
12603                            capabilities.code_lens_provider = Some(caps);
12604                        });
12605                        notify_server_capabilities_updated(&server, cx);
12606                    }
12607                }
12608                "textDocument/diagnostic" => {
12609                    if let Some(caps) = reg
12610                        .register_options
12611                        .map(serde_json::from_value::<DiagnosticServerCapabilities>)
12612                        .transpose()?
12613                    {
12614                        let local = self
12615                            .as_local_mut()
12616                            .context("Expected LSP Store to be local")?;
12617                        let state = local
12618                            .language_servers
12619                            .get_mut(&server_id)
12620                            .context("Could not obtain Language Servers state")?;
12621                        local
12622                            .language_server_dynamic_registrations
12623                            .entry(server_id)
12624                            .or_default()
12625                            .diagnostics
12626                            .insert(Some(reg.id.clone()), caps.clone());
12627
12628                        let supports_workspace_diagnostics =
12629                            |capabilities: &DiagnosticServerCapabilities| match capabilities {
12630                                DiagnosticServerCapabilities::Options(diagnostic_options) => {
12631                                    diagnostic_options.workspace_diagnostics
12632                                }
12633                                DiagnosticServerCapabilities::RegistrationOptions(
12634                                    diagnostic_registration_options,
12635                                ) => {
12636                                    diagnostic_registration_options
12637                                        .diagnostic_options
12638                                        .workspace_diagnostics
12639                                }
12640                            };
12641
12642                        if supports_workspace_diagnostics(&caps) {
12643                            if let LanguageServerState::Running {
12644                                workspace_diagnostics_refresh_tasks,
12645                                ..
12646                            } = state
12647                                && let Some(task) = lsp_workspace_diagnostics_refresh(
12648                                    Some(reg.id.clone()),
12649                                    caps.clone(),
12650                                    server.clone(),
12651                                    cx,
12652                                )
12653                            {
12654                                workspace_diagnostics_refresh_tasks.insert(Some(reg.id), task);
12655                            }
12656                        }
12657
12658                        server.update_capabilities(|capabilities| {
12659                            capabilities.diagnostic_provider = Some(caps);
12660                        });
12661
12662                        notify_server_capabilities_updated(&server, cx);
12663
12664                        self.pull_document_diagnostics_for_server(server_id, cx);
12665                    }
12666                }
12667                "textDocument/documentColor" => {
12668                    let options = parse_register_capabilities(reg)?;
12669                    let provider = match options {
12670                        OneOf::Left(value) => lsp::ColorProviderCapability::Simple(value),
12671                        OneOf::Right(caps) => caps,
12672                    };
12673                    server.update_capabilities(|capabilities| {
12674                        capabilities.color_provider = Some(provider);
12675                    });
12676                    notify_server_capabilities_updated(&server, cx);
12677                }
12678                _ => log::warn!("unhandled capability registration: {reg:?}"),
12679            }
12680        }
12681
12682        Ok(())
12683    }
12684
12685    fn unregister_server_capabilities(
12686        &mut self,
12687        server_id: LanguageServerId,
12688        params: lsp::UnregistrationParams,
12689        cx: &mut Context<Self>,
12690    ) -> anyhow::Result<()> {
12691        let server = self
12692            .language_server_for_id(server_id)
12693            .with_context(|| format!("no server {server_id} found"))?;
12694        for unreg in params.unregisterations.iter() {
12695            match unreg.method.as_str() {
12696                "workspace/didChangeWatchedFiles" => {
12697                    let notify = if let Some(local_lsp_store) = self.as_local_mut() {
12698                        local_lsp_store
12699                            .on_lsp_unregister_did_change_watched_files(server_id, &unreg.id, cx);
12700                        true
12701                    } else {
12702                        false
12703                    };
12704                    if notify {
12705                        notify_server_capabilities_updated(&server, cx);
12706                    }
12707                }
12708                "workspace/didChangeConfiguration" => {
12709                    // Ignore payload since we notify clients of setting changes unconditionally, relying on them pulling the latest settings.
12710                }
12711                "workspace/didChangeWorkspaceFolders" => {
12712                    server.update_capabilities(|capabilities| {
12713                        capabilities
12714                            .workspace
12715                            .get_or_insert_with(|| lsp::WorkspaceServerCapabilities {
12716                                workspace_folders: None,
12717                                file_operations: None,
12718                            })
12719                            .workspace_folders = None;
12720                    });
12721                    notify_server_capabilities_updated(&server, cx);
12722                }
12723                "workspace/symbol" => {
12724                    server.update_capabilities(|capabilities| {
12725                        capabilities.workspace_symbol_provider = None
12726                    });
12727                    notify_server_capabilities_updated(&server, cx);
12728                }
12729                "workspace/fileOperations" => {
12730                    server.update_capabilities(|capabilities| {
12731                        capabilities
12732                            .workspace
12733                            .get_or_insert_with(|| lsp::WorkspaceServerCapabilities {
12734                                workspace_folders: None,
12735                                file_operations: None,
12736                            })
12737                            .file_operations = None;
12738                    });
12739                    notify_server_capabilities_updated(&server, cx);
12740                }
12741                "workspace/executeCommand" => {
12742                    server.update_capabilities(|capabilities| {
12743                        capabilities.execute_command_provider = None;
12744                    });
12745                    notify_server_capabilities_updated(&server, cx);
12746                }
12747                "textDocument/rangeFormatting" => {
12748                    server.update_capabilities(|capabilities| {
12749                        capabilities.document_range_formatting_provider = None
12750                    });
12751                    notify_server_capabilities_updated(&server, cx);
12752                }
12753                "textDocument/onTypeFormatting" => {
12754                    server.update_capabilities(|capabilities| {
12755                        capabilities.document_on_type_formatting_provider = None;
12756                    });
12757                    notify_server_capabilities_updated(&server, cx);
12758                }
12759                "textDocument/formatting" => {
12760                    server.update_capabilities(|capabilities| {
12761                        capabilities.document_formatting_provider = None;
12762                    });
12763                    notify_server_capabilities_updated(&server, cx);
12764                }
12765                "textDocument/rename" => {
12766                    server.update_capabilities(|capabilities| capabilities.rename_provider = None);
12767                    notify_server_capabilities_updated(&server, cx);
12768                }
12769                "textDocument/codeAction" => {
12770                    server.update_capabilities(|capabilities| {
12771                        capabilities.code_action_provider = None;
12772                    });
12773                    notify_server_capabilities_updated(&server, cx);
12774                }
12775                "textDocument/definition" => {
12776                    server.update_capabilities(|capabilities| {
12777                        capabilities.definition_provider = None;
12778                    });
12779                    notify_server_capabilities_updated(&server, cx);
12780                }
12781                "textDocument/completion" => {
12782                    server.update_capabilities(|capabilities| {
12783                        capabilities.completion_provider = None;
12784                    });
12785                    notify_server_capabilities_updated(&server, cx);
12786                }
12787                "textDocument/hover" => {
12788                    server.update_capabilities(|capabilities| {
12789                        capabilities.hover_provider = None;
12790                    });
12791                    notify_server_capabilities_updated(&server, cx);
12792                }
12793                "textDocument/signatureHelp" => {
12794                    server.update_capabilities(|capabilities| {
12795                        capabilities.signature_help_provider = None;
12796                    });
12797                    notify_server_capabilities_updated(&server, cx);
12798                }
12799                "textDocument/didChange" => {
12800                    server.update_capabilities(|capabilities| {
12801                        let mut sync_options = Self::take_text_document_sync_options(capabilities);
12802                        sync_options.change = None;
12803                        capabilities.text_document_sync =
12804                            Some(lsp::TextDocumentSyncCapability::Options(sync_options));
12805                    });
12806                    notify_server_capabilities_updated(&server, cx);
12807                }
12808                "textDocument/didSave" => {
12809                    server.update_capabilities(|capabilities| {
12810                        let mut sync_options = Self::take_text_document_sync_options(capabilities);
12811                        sync_options.save = None;
12812                        capabilities.text_document_sync =
12813                            Some(lsp::TextDocumentSyncCapability::Options(sync_options));
12814                    });
12815                    notify_server_capabilities_updated(&server, cx);
12816                }
12817                "textDocument/codeLens" => {
12818                    server.update_capabilities(|capabilities| {
12819                        capabilities.code_lens_provider = None;
12820                    });
12821                    notify_server_capabilities_updated(&server, cx);
12822                }
12823                "textDocument/diagnostic" => {
12824                    let local = self
12825                        .as_local_mut()
12826                        .context("Expected LSP Store to be local")?;
12827
12828                    let state = local
12829                        .language_servers
12830                        .get_mut(&server_id)
12831                        .context("Could not obtain Language Servers state")?;
12832                    let registrations = local
12833                        .language_server_dynamic_registrations
12834                        .get_mut(&server_id)
12835                        .with_context(|| {
12836                            format!("Expected dynamic registration to exist for server {server_id}")
12837                        })?;
12838                    registrations.diagnostics
12839                        .remove(&Some(unreg.id.clone()))
12840                        .with_context(|| format!(
12841                            "Attempted to unregister non-existent diagnostic registration with ID {}",
12842                            unreg.id)
12843                        )?;
12844                    let removed_last_diagnostic_provider = registrations.diagnostics.is_empty();
12845
12846                    if let LanguageServerState::Running {
12847                        workspace_diagnostics_refresh_tasks,
12848                        ..
12849                    } = state
12850                    {
12851                        workspace_diagnostics_refresh_tasks.remove(&Some(unreg.id.clone()));
12852                    }
12853
12854                    self.clear_unregistered_diagnostics(
12855                        server_id,
12856                        SharedString::from(unreg.id.clone()),
12857                        cx,
12858                    )?;
12859
12860                    if removed_last_diagnostic_provider {
12861                        server.update_capabilities(|capabilities| {
12862                            debug_assert!(capabilities.diagnostic_provider.is_some());
12863                            capabilities.diagnostic_provider = None;
12864                        });
12865                    }
12866
12867                    notify_server_capabilities_updated(&server, cx);
12868                }
12869                "textDocument/documentColor" => {
12870                    server.update_capabilities(|capabilities| {
12871                        capabilities.color_provider = None;
12872                    });
12873                    notify_server_capabilities_updated(&server, cx);
12874                }
12875                _ => log::warn!("unhandled capability unregistration: {unreg:?}"),
12876            }
12877        }
12878
12879        Ok(())
12880    }
12881
12882    fn clear_unregistered_diagnostics(
12883        &mut self,
12884        server_id: LanguageServerId,
12885        cleared_registration_id: SharedString,
12886        cx: &mut Context<Self>,
12887    ) -> anyhow::Result<()> {
12888        let mut affected_abs_paths: HashSet<PathBuf> = HashSet::default();
12889
12890        self.buffer_store.update(cx, |buffer_store, cx| {
12891            for buffer_handle in buffer_store.buffers() {
12892                let buffer = buffer_handle.read(cx);
12893                let abs_path = File::from_dyn(buffer.file()).map(|f| f.abs_path(cx));
12894                let Some(abs_path) = abs_path else {
12895                    continue;
12896                };
12897                affected_abs_paths.insert(abs_path);
12898            }
12899        });
12900
12901        let local = self.as_local().context("Expected LSP Store to be local")?;
12902        for (worktree_id, diagnostics_for_tree) in local.diagnostics.iter() {
12903            let Some(worktree) = self
12904                .worktree_store
12905                .read(cx)
12906                .worktree_for_id(*worktree_id, cx)
12907            else {
12908                continue;
12909            };
12910
12911            for (rel_path, diagnostics_by_server_id) in diagnostics_for_tree.iter() {
12912                if let Ok(ix) = diagnostics_by_server_id.binary_search_by_key(&server_id, |e| e.0) {
12913                    let has_matching_registration =
12914                        diagnostics_by_server_id[ix].1.iter().any(|entry| {
12915                            entry.diagnostic.registration_id.as_ref()
12916                                == Some(&cleared_registration_id)
12917                        });
12918                    if has_matching_registration {
12919                        let abs_path = worktree.read(cx).absolutize(rel_path);
12920                        affected_abs_paths.insert(abs_path);
12921                    }
12922                }
12923            }
12924        }
12925
12926        if affected_abs_paths.is_empty() {
12927            return Ok(());
12928        }
12929
12930        // Send a fake diagnostic update which clears the state for the registration ID
12931        let clears: Vec<DocumentDiagnosticsUpdate<'static, DocumentDiagnostics>> =
12932            affected_abs_paths
12933                .into_iter()
12934                .map(|abs_path| DocumentDiagnosticsUpdate {
12935                    diagnostics: DocumentDiagnostics {
12936                        diagnostics: Vec::new(),
12937                        document_abs_path: abs_path,
12938                        version: None,
12939                    },
12940                    result_id: None,
12941                    registration_id: Some(cleared_registration_id.clone()),
12942                    server_id,
12943                    disk_based_sources: Cow::Borrowed(&[]),
12944                })
12945                .collect();
12946
12947        let merge_registration_id = cleared_registration_id.clone();
12948        self.merge_diagnostic_entries(
12949            clears,
12950            move |_, diagnostic, _| {
12951                if diagnostic.source_kind == DiagnosticSourceKind::Pulled {
12952                    diagnostic.registration_id != Some(merge_registration_id.clone())
12953                } else {
12954                    true
12955                }
12956            },
12957            cx,
12958        )?;
12959
12960        Ok(())
12961    }
12962
12963    async fn deduplicate_range_based_lsp_requests<T>(
12964        lsp_store: &Entity<Self>,
12965        server_id: Option<LanguageServerId>,
12966        lsp_request_id: LspRequestId,
12967        proto_request: &T::ProtoRequest,
12968        range: Range<Anchor>,
12969        cx: &mut AsyncApp,
12970    ) -> Result<()>
12971    where
12972        T: LspCommand,
12973        T::ProtoRequest: proto::LspRequestMessage,
12974    {
12975        let buffer_id = BufferId::new(proto_request.buffer_id())?;
12976        let version = deserialize_version(proto_request.buffer_version());
12977        let buffer = lsp_store.update(cx, |this, cx| {
12978            this.buffer_store.read(cx).get_existing(buffer_id)
12979        })??;
12980        buffer
12981            .update(cx, |buffer, _| buffer.wait_for_version(version))?
12982            .await?;
12983        lsp_store.update(cx, |lsp_store, cx| {
12984            let buffer_snapshot = buffer.read(cx).snapshot();
12985            let lsp_data = lsp_store.latest_lsp_data(&buffer, cx);
12986            let chunks_queried_for = lsp_data
12987                .inlay_hints
12988                .applicable_chunks(&[range.to_point(&buffer_snapshot)])
12989                .collect::<Vec<_>>();
12990            match chunks_queried_for.as_slice() {
12991                &[chunk] => {
12992                    let key = LspKey {
12993                        request_type: TypeId::of::<T>(),
12994                        server_queried: server_id,
12995                    };
12996                    let previous_request = lsp_data
12997                        .chunk_lsp_requests
12998                        .entry(key)
12999                        .or_default()
13000                        .insert(chunk, lsp_request_id);
13001                    if let Some((previous_request, running_requests)) =
13002                        previous_request.zip(lsp_data.lsp_requests.get_mut(&key))
13003                    {
13004                        running_requests.remove(&previous_request);
13005                    }
13006                }
13007                _ambiguous_chunks => {
13008                    // Have not found a unique chunk for the query range — be lenient and let the query to be spawned,
13009                    // there, a buffer version-based check will be performed and outdated requests discarded.
13010                }
13011            }
13012            anyhow::Ok(())
13013        })??;
13014
13015        Ok(())
13016    }
13017
13018    async fn query_lsp_locally<T>(
13019        lsp_store: Entity<Self>,
13020        for_server_id: Option<LanguageServerId>,
13021        sender_id: proto::PeerId,
13022        lsp_request_id: LspRequestId,
13023        proto_request: T::ProtoRequest,
13024        position: Option<Anchor>,
13025        cx: &mut AsyncApp,
13026    ) -> Result<()>
13027    where
13028        T: LspCommand + Clone,
13029        T::ProtoRequest: proto::LspRequestMessage,
13030        <T::ProtoRequest as proto::RequestMessage>::Response:
13031            Into<<T::ProtoRequest as proto::LspRequestMessage>::Response>,
13032    {
13033        let buffer_id = BufferId::new(proto_request.buffer_id())?;
13034        let version = deserialize_version(proto_request.buffer_version());
13035        let buffer = lsp_store.update(cx, |this, cx| {
13036            this.buffer_store.read(cx).get_existing(buffer_id)
13037        })??;
13038        buffer
13039            .update(cx, |buffer, _| buffer.wait_for_version(version.clone()))?
13040            .await?;
13041        let buffer_version = buffer.read_with(cx, |buffer, _| buffer.version())?;
13042        let request =
13043            T::from_proto(proto_request, lsp_store.clone(), buffer.clone(), cx.clone()).await?;
13044        let key = LspKey {
13045            request_type: TypeId::of::<T>(),
13046            server_queried: for_server_id,
13047        };
13048        lsp_store.update(cx, |lsp_store, cx| {
13049            let request_task = match for_server_id {
13050                Some(server_id) => {
13051                    let server_task = lsp_store.request_lsp(
13052                        buffer.clone(),
13053                        LanguageServerToQuery::Other(server_id),
13054                        request.clone(),
13055                        cx,
13056                    );
13057                    cx.background_spawn(async move {
13058                        let mut responses = Vec::new();
13059                        match server_task.await {
13060                            Ok(response) => responses.push((server_id, response)),
13061                            // rust-analyzer likes to error with this when its still loading up
13062                            Err(e) if format!("{e:#}").ends_with("content modified") => (),
13063                            Err(e) => log::error!(
13064                                "Error handling response for request {request:?}: {e:#}"
13065                            ),
13066                        }
13067                        responses
13068                    })
13069                }
13070                None => lsp_store.request_multiple_lsp_locally(&buffer, position, request, cx),
13071            };
13072            let lsp_data = lsp_store.latest_lsp_data(&buffer, cx);
13073            if T::ProtoRequest::stop_previous_requests() {
13074                if let Some(lsp_requests) = lsp_data.lsp_requests.get_mut(&key) {
13075                    lsp_requests.clear();
13076                }
13077            }
13078            lsp_data.lsp_requests.entry(key).or_default().insert(
13079                lsp_request_id,
13080                cx.spawn(async move |lsp_store, cx| {
13081                    let response = request_task.await;
13082                    lsp_store
13083                        .update(cx, |lsp_store, cx| {
13084                            if let Some((client, project_id)) = lsp_store.downstream_client.clone()
13085                            {
13086                                let response = response
13087                                    .into_iter()
13088                                    .map(|(server_id, response)| {
13089                                        (
13090                                            server_id.to_proto(),
13091                                            T::response_to_proto(
13092                                                response,
13093                                                lsp_store,
13094                                                sender_id,
13095                                                &buffer_version,
13096                                                cx,
13097                                            )
13098                                            .into(),
13099                                        )
13100                                    })
13101                                    .collect::<HashMap<_, _>>();
13102                                match client.send_lsp_response::<T::ProtoRequest>(
13103                                    project_id,
13104                                    lsp_request_id,
13105                                    response,
13106                                ) {
13107                                    Ok(()) => {}
13108                                    Err(e) => {
13109                                        log::error!("Failed to send LSP response: {e:#}",)
13110                                    }
13111                                }
13112                            }
13113                        })
13114                        .ok();
13115                }),
13116            );
13117        })?;
13118        Ok(())
13119    }
13120
13121    fn take_text_document_sync_options(
13122        capabilities: &mut lsp::ServerCapabilities,
13123    ) -> lsp::TextDocumentSyncOptions {
13124        match capabilities.text_document_sync.take() {
13125            Some(lsp::TextDocumentSyncCapability::Options(sync_options)) => sync_options,
13126            Some(lsp::TextDocumentSyncCapability::Kind(sync_kind)) => {
13127                let mut sync_options = lsp::TextDocumentSyncOptions::default();
13128                sync_options.change = Some(sync_kind);
13129                sync_options
13130            }
13131            None => lsp::TextDocumentSyncOptions::default(),
13132        }
13133    }
13134
13135    #[cfg(any(test, feature = "test-support"))]
13136    pub fn forget_code_lens_task(&mut self, buffer_id: BufferId) -> Option<CodeLensTask> {
13137        Some(
13138            self.lsp_data
13139                .get_mut(&buffer_id)?
13140                .code_lens
13141                .take()?
13142                .update
13143                .take()?
13144                .1,
13145        )
13146    }
13147
13148    pub fn downstream_client(&self) -> Option<(AnyProtoClient, u64)> {
13149        self.downstream_client.clone()
13150    }
13151
13152    pub fn worktree_store(&self) -> Entity<WorktreeStore> {
13153        self.worktree_store.clone()
13154    }
13155
13156    /// Gets what's stored in the LSP data for the given buffer.
13157    pub fn current_lsp_data(&mut self, buffer_id: BufferId) -> Option<&mut BufferLspData> {
13158        self.lsp_data.get_mut(&buffer_id)
13159    }
13160
13161    /// Gets the most recent LSP data for the given buffer: if the data is absent or out of date,
13162    /// new [`BufferLspData`] will be created to replace the previous state.
13163    pub fn latest_lsp_data(&mut self, buffer: &Entity<Buffer>, cx: &mut App) -> &mut BufferLspData {
13164        let (buffer_id, buffer_version) =
13165            buffer.read_with(cx, |buffer, _| (buffer.remote_id(), buffer.version()));
13166        let lsp_data = self
13167            .lsp_data
13168            .entry(buffer_id)
13169            .or_insert_with(|| BufferLspData::new(buffer, cx));
13170        if buffer_version.changed_since(&lsp_data.buffer_version) {
13171            *lsp_data = BufferLspData::new(buffer, cx);
13172        }
13173        lsp_data
13174    }
13175}
13176
13177// Registration with registerOptions as null, should fallback to true.
13178// https://github.com/microsoft/vscode-languageserver-node/blob/d90a87f9557a0df9142cfb33e251cfa6fe27d970/client/src/common/client.ts#L2133
13179fn parse_register_capabilities<T: serde::de::DeserializeOwned>(
13180    reg: lsp::Registration,
13181) -> Result<OneOf<bool, T>> {
13182    Ok(match reg.register_options {
13183        Some(options) => OneOf::Right(serde_json::from_value::<T>(options)?),
13184        None => OneOf::Left(true),
13185    })
13186}
13187
13188fn subscribe_to_binary_statuses(
13189    languages: &Arc<LanguageRegistry>,
13190    cx: &mut Context<'_, LspStore>,
13191) -> Task<()> {
13192    let mut server_statuses = languages.language_server_binary_statuses();
13193    cx.spawn(async move |lsp_store, cx| {
13194        while let Some((server_name, binary_status)) = server_statuses.next().await {
13195            if lsp_store
13196                .update(cx, |_, cx| {
13197                    let mut message = None;
13198                    let binary_status = match binary_status {
13199                        BinaryStatus::None => proto::ServerBinaryStatus::None,
13200                        BinaryStatus::CheckingForUpdate => {
13201                            proto::ServerBinaryStatus::CheckingForUpdate
13202                        }
13203                        BinaryStatus::Downloading => proto::ServerBinaryStatus::Downloading,
13204                        BinaryStatus::Starting => proto::ServerBinaryStatus::Starting,
13205                        BinaryStatus::Stopping => proto::ServerBinaryStatus::Stopping,
13206                        BinaryStatus::Stopped => proto::ServerBinaryStatus::Stopped,
13207                        BinaryStatus::Failed { error } => {
13208                            message = Some(error);
13209                            proto::ServerBinaryStatus::Failed
13210                        }
13211                    };
13212                    cx.emit(LspStoreEvent::LanguageServerUpdate {
13213                        // Binary updates are about the binary that might not have any language server id at that point.
13214                        // Reuse `LanguageServerUpdate` for them and provide a fake id that won't be used on the receiver side.
13215                        language_server_id: LanguageServerId(0),
13216                        name: Some(server_name),
13217                        message: proto::update_language_server::Variant::StatusUpdate(
13218                            proto::StatusUpdate {
13219                                message,
13220                                status: Some(proto::status_update::Status::Binary(
13221                                    binary_status as i32,
13222                                )),
13223                            },
13224                        ),
13225                    });
13226                })
13227                .is_err()
13228            {
13229                break;
13230            }
13231        }
13232    })
13233}
13234
13235fn lsp_workspace_diagnostics_refresh(
13236    registration_id: Option<String>,
13237    options: DiagnosticServerCapabilities,
13238    server: Arc<LanguageServer>,
13239    cx: &mut Context<'_, LspStore>,
13240) -> Option<WorkspaceRefreshTask> {
13241    let identifier = workspace_diagnostic_identifier(&options)?;
13242    let registration_id_shared = registration_id.as_ref().map(SharedString::from);
13243
13244    let (progress_tx, mut progress_rx) = mpsc::channel(1);
13245    let (mut refresh_tx, mut refresh_rx) = mpsc::channel(1);
13246    refresh_tx.try_send(()).ok();
13247
13248    let workspace_query_language_server = cx.spawn(async move |lsp_store, cx| {
13249        let mut attempts = 0;
13250        let max_attempts = 50;
13251        let mut requests = 0;
13252
13253        loop {
13254            let Some(()) = refresh_rx.recv().await else {
13255                return;
13256            };
13257
13258            'request: loop {
13259                requests += 1;
13260                if attempts > max_attempts {
13261                    log::error!(
13262                        "Failed to pull workspace diagnostics {max_attempts} times, aborting"
13263                    );
13264                    return;
13265                }
13266                let backoff_millis = (50 * (1 << attempts)).clamp(30, 1000);
13267                cx.background_executor()
13268                    .timer(Duration::from_millis(backoff_millis))
13269                    .await;
13270                attempts += 1;
13271
13272                let Ok(previous_result_ids) = lsp_store.update(cx, |lsp_store, _| {
13273                    lsp_store
13274                        .result_ids_for_workspace_refresh(server.server_id(), &registration_id_shared)
13275                        .into_iter()
13276                        .filter_map(|(abs_path, result_id)| {
13277                            let uri = file_path_to_lsp_url(&abs_path).ok()?;
13278                            Some(lsp::PreviousResultId {
13279                                uri,
13280                                value: result_id.to_string(),
13281                            })
13282                        })
13283                        .collect()
13284                }) else {
13285                    return;
13286                };
13287
13288                let token = if let Some(registration_id) = &registration_id {
13289                    format!(
13290                        "workspace/diagnostic/{}/{requests}/{WORKSPACE_DIAGNOSTICS_TOKEN_START}{registration_id}",
13291                        server.server_id(),
13292                    )
13293                } else {
13294                    format!("workspace/diagnostic/{}/{requests}", server.server_id())
13295                };
13296
13297                progress_rx.try_recv().ok();
13298                let timer =
13299                    LanguageServer::default_request_timer(cx.background_executor().clone()).fuse();
13300                let progress = pin!(progress_rx.recv().fuse());
13301                let response_result = server
13302                    .request_with_timer::<lsp::WorkspaceDiagnosticRequest, _>(
13303                        lsp::WorkspaceDiagnosticParams {
13304                            previous_result_ids,
13305                            identifier: identifier.clone(),
13306                            work_done_progress_params: Default::default(),
13307                            partial_result_params: lsp::PartialResultParams {
13308                                partial_result_token: Some(lsp::ProgressToken::String(token)),
13309                            },
13310                        },
13311                        select(timer, progress).then(|either| match either {
13312                            Either::Left((message, ..)) => ready(message).left_future(),
13313                            Either::Right(..) => pending::<String>().right_future(),
13314                        }),
13315                    )
13316                    .await;
13317
13318                // https://microsoft.github.io/language-server-protocol/specifications/lsp/3.17/specification/#diagnostic_refresh
13319                // >  If a server closes a workspace diagnostic pull request the client should re-trigger the request.
13320                match response_result {
13321                    ConnectionResult::Timeout => {
13322                        log::error!("Timeout during workspace diagnostics pull");
13323                        continue 'request;
13324                    }
13325                    ConnectionResult::ConnectionReset => {
13326                        log::error!("Server closed a workspace diagnostics pull request");
13327                        continue 'request;
13328                    }
13329                    ConnectionResult::Result(Err(e)) => {
13330                        log::error!("Error during workspace diagnostics pull: {e:#}");
13331                        break 'request;
13332                    }
13333                    ConnectionResult::Result(Ok(pulled_diagnostics)) => {
13334                        attempts = 0;
13335                        if lsp_store
13336                            .update(cx, |lsp_store, cx| {
13337                                lsp_store.apply_workspace_diagnostic_report(
13338                                    server.server_id(),
13339                                    pulled_diagnostics,
13340                                    registration_id_shared.clone(),
13341                                    cx,
13342                                )
13343                            })
13344                            .is_err()
13345                        {
13346                            return;
13347                        }
13348                        break 'request;
13349                    }
13350                }
13351            }
13352        }
13353    });
13354
13355    Some(WorkspaceRefreshTask {
13356        refresh_tx,
13357        progress_tx,
13358        task: workspace_query_language_server,
13359    })
13360}
13361
13362fn buffer_diagnostic_identifier(options: &DiagnosticServerCapabilities) -> Option<String> {
13363    match &options {
13364        lsp::DiagnosticServerCapabilities::Options(diagnostic_options) => {
13365            diagnostic_options.identifier.clone()
13366        }
13367        lsp::DiagnosticServerCapabilities::RegistrationOptions(registration_options) => {
13368            let diagnostic_options = &registration_options.diagnostic_options;
13369            diagnostic_options.identifier.clone()
13370        }
13371    }
13372}
13373
13374fn workspace_diagnostic_identifier(
13375    options: &DiagnosticServerCapabilities,
13376) -> Option<Option<String>> {
13377    match &options {
13378        lsp::DiagnosticServerCapabilities::Options(diagnostic_options) => {
13379            if !diagnostic_options.workspace_diagnostics {
13380                return None;
13381            }
13382            Some(diagnostic_options.identifier.clone())
13383        }
13384        lsp::DiagnosticServerCapabilities::RegistrationOptions(registration_options) => {
13385            let diagnostic_options = &registration_options.diagnostic_options;
13386            if !diagnostic_options.workspace_diagnostics {
13387                return None;
13388            }
13389            Some(diagnostic_options.identifier.clone())
13390        }
13391    }
13392}
13393
13394fn resolve_word_completion(snapshot: &BufferSnapshot, completion: &mut Completion) {
13395    let CompletionSource::BufferWord {
13396        word_range,
13397        resolved,
13398    } = &mut completion.source
13399    else {
13400        return;
13401    };
13402    if *resolved {
13403        return;
13404    }
13405
13406    if completion.new_text
13407        != snapshot
13408            .text_for_range(word_range.clone())
13409            .collect::<String>()
13410    {
13411        return;
13412    }
13413
13414    let mut offset = 0;
13415    for chunk in snapshot.chunks(word_range.clone(), true) {
13416        let end_offset = offset + chunk.text.len();
13417        if let Some(highlight_id) = chunk.syntax_highlight_id {
13418            completion
13419                .label
13420                .runs
13421                .push((offset..end_offset, highlight_id));
13422        }
13423        offset = end_offset;
13424    }
13425    *resolved = true;
13426}
13427
13428impl EventEmitter<LspStoreEvent> for LspStore {}
13429
13430fn remove_empty_hover_blocks(mut hover: Hover) -> Option<Hover> {
13431    hover
13432        .contents
13433        .retain(|hover_block| !hover_block.text.trim().is_empty());
13434    if hover.contents.is_empty() {
13435        None
13436    } else {
13437        Some(hover)
13438    }
13439}
13440
13441async fn populate_labels_for_completions(
13442    new_completions: Vec<CoreCompletion>,
13443    language: Option<Arc<Language>>,
13444    lsp_adapter: Option<Arc<CachedLspAdapter>>,
13445) -> Vec<Completion> {
13446    let lsp_completions = new_completions
13447        .iter()
13448        .filter_map(|new_completion| {
13449            new_completion
13450                .source
13451                .lsp_completion(true)
13452                .map(|lsp_completion| lsp_completion.into_owned())
13453        })
13454        .collect::<Vec<_>>();
13455
13456    let mut labels = if let Some((language, lsp_adapter)) = language.as_ref().zip(lsp_adapter) {
13457        lsp_adapter
13458            .labels_for_completions(&lsp_completions, language)
13459            .await
13460            .log_err()
13461            .unwrap_or_default()
13462    } else {
13463        Vec::new()
13464    }
13465    .into_iter()
13466    .fuse();
13467
13468    let mut completions = Vec::new();
13469    for completion in new_completions {
13470        match completion.source.lsp_completion(true) {
13471            Some(lsp_completion) => {
13472                let documentation = lsp_completion.documentation.clone().map(|docs| docs.into());
13473
13474                let mut label = labels.next().flatten().unwrap_or_else(|| {
13475                    CodeLabel::fallback_for_completion(&lsp_completion, language.as_deref())
13476                });
13477                ensure_uniform_list_compatible_label(&mut label);
13478                completions.push(Completion {
13479                    label,
13480                    documentation,
13481                    replace_range: completion.replace_range,
13482                    new_text: completion.new_text,
13483                    insert_text_mode: lsp_completion.insert_text_mode,
13484                    source: completion.source,
13485                    icon_path: None,
13486                    confirm: None,
13487                    match_start: None,
13488                    snippet_deduplication_key: None,
13489                });
13490            }
13491            None => {
13492                let mut label = CodeLabel::plain(completion.new_text.clone(), None);
13493                ensure_uniform_list_compatible_label(&mut label);
13494                completions.push(Completion {
13495                    label,
13496                    documentation: None,
13497                    replace_range: completion.replace_range,
13498                    new_text: completion.new_text,
13499                    source: completion.source,
13500                    insert_text_mode: None,
13501                    icon_path: None,
13502                    confirm: None,
13503                    match_start: None,
13504                    snippet_deduplication_key: None,
13505                });
13506            }
13507        }
13508    }
13509    completions
13510}
13511
13512#[derive(Debug)]
13513pub enum LanguageServerToQuery {
13514    /// Query language servers in order of users preference, up until one capable of handling the request is found.
13515    FirstCapable,
13516    /// Query a specific language server.
13517    Other(LanguageServerId),
13518}
13519
13520#[derive(Default)]
13521struct RenamePathsWatchedForServer {
13522    did_rename: Vec<RenameActionPredicate>,
13523    will_rename: Vec<RenameActionPredicate>,
13524}
13525
13526impl RenamePathsWatchedForServer {
13527    fn with_did_rename_patterns(
13528        mut self,
13529        did_rename: Option<&FileOperationRegistrationOptions>,
13530    ) -> Self {
13531        if let Some(did_rename) = did_rename {
13532            self.did_rename = did_rename
13533                .filters
13534                .iter()
13535                .filter_map(|filter| filter.try_into().log_err())
13536                .collect();
13537        }
13538        self
13539    }
13540    fn with_will_rename_patterns(
13541        mut self,
13542        will_rename: Option<&FileOperationRegistrationOptions>,
13543    ) -> Self {
13544        if let Some(will_rename) = will_rename {
13545            self.will_rename = will_rename
13546                .filters
13547                .iter()
13548                .filter_map(|filter| filter.try_into().log_err())
13549                .collect();
13550        }
13551        self
13552    }
13553
13554    fn should_send_did_rename(&self, path: &str, is_dir: bool) -> bool {
13555        self.did_rename.iter().any(|pred| pred.eval(path, is_dir))
13556    }
13557    fn should_send_will_rename(&self, path: &str, is_dir: bool) -> bool {
13558        self.will_rename.iter().any(|pred| pred.eval(path, is_dir))
13559    }
13560}
13561
13562impl TryFrom<&FileOperationFilter> for RenameActionPredicate {
13563    type Error = globset::Error;
13564    fn try_from(ops: &FileOperationFilter) -> Result<Self, globset::Error> {
13565        Ok(Self {
13566            kind: ops.pattern.matches.clone(),
13567            glob: GlobBuilder::new(&ops.pattern.glob)
13568                .case_insensitive(
13569                    ops.pattern
13570                        .options
13571                        .as_ref()
13572                        .is_some_and(|ops| ops.ignore_case.unwrap_or(false)),
13573                )
13574                .build()?
13575                .compile_matcher(),
13576        })
13577    }
13578}
13579struct RenameActionPredicate {
13580    glob: GlobMatcher,
13581    kind: Option<FileOperationPatternKind>,
13582}
13583
13584impl RenameActionPredicate {
13585    // Returns true if language server should be notified
13586    fn eval(&self, path: &str, is_dir: bool) -> bool {
13587        self.kind.as_ref().is_none_or(|kind| {
13588            let expected_kind = if is_dir {
13589                FileOperationPatternKind::Folder
13590            } else {
13591                FileOperationPatternKind::File
13592            };
13593            kind == &expected_kind
13594        }) && self.glob.is_match(path)
13595    }
13596}
13597
13598#[derive(Default)]
13599struct LanguageServerWatchedPaths {
13600    worktree_paths: HashMap<WorktreeId, GlobSet>,
13601    abs_paths: HashMap<Arc<Path>, (GlobSet, Task<()>)>,
13602}
13603
13604#[derive(Default)]
13605struct LanguageServerWatchedPathsBuilder {
13606    worktree_paths: HashMap<WorktreeId, GlobSet>,
13607    abs_paths: HashMap<Arc<Path>, GlobSet>,
13608}
13609
13610impl LanguageServerWatchedPathsBuilder {
13611    fn watch_worktree(&mut self, worktree_id: WorktreeId, glob_set: GlobSet) {
13612        self.worktree_paths.insert(worktree_id, glob_set);
13613    }
13614    fn watch_abs_path(&mut self, path: Arc<Path>, glob_set: GlobSet) {
13615        self.abs_paths.insert(path, glob_set);
13616    }
13617    fn build(
13618        self,
13619        fs: Arc<dyn Fs>,
13620        language_server_id: LanguageServerId,
13621        cx: &mut Context<LspStore>,
13622    ) -> LanguageServerWatchedPaths {
13623        let lsp_store = cx.weak_entity();
13624
13625        const LSP_ABS_PATH_OBSERVE: Duration = Duration::from_millis(100);
13626        let abs_paths = self
13627            .abs_paths
13628            .into_iter()
13629            .map(|(abs_path, globset)| {
13630                let task = cx.spawn({
13631                    let abs_path = abs_path.clone();
13632                    let fs = fs.clone();
13633
13634                    let lsp_store = lsp_store.clone();
13635                    async move |_, cx| {
13636                        maybe!(async move {
13637                            let mut push_updates = fs.watch(&abs_path, LSP_ABS_PATH_OBSERVE).await;
13638                            while let Some(update) = push_updates.0.next().await {
13639                                let action = lsp_store
13640                                    .update(cx, |this, _| {
13641                                        let Some(local) = this.as_local() else {
13642                                            return ControlFlow::Break(());
13643                                        };
13644                                        let Some(watcher) = local
13645                                            .language_server_watched_paths
13646                                            .get(&language_server_id)
13647                                        else {
13648                                            return ControlFlow::Break(());
13649                                        };
13650                                        let (globs, _) = watcher.abs_paths.get(&abs_path).expect(
13651                                            "Watched abs path is not registered with a watcher",
13652                                        );
13653                                        let matching_entries = update
13654                                            .into_iter()
13655                                            .filter(|event| globs.is_match(&event.path))
13656                                            .collect::<Vec<_>>();
13657                                        this.lsp_notify_abs_paths_changed(
13658                                            language_server_id,
13659                                            matching_entries,
13660                                        );
13661                                        ControlFlow::Continue(())
13662                                    })
13663                                    .ok()?;
13664
13665                                if action.is_break() {
13666                                    break;
13667                                }
13668                            }
13669                            Some(())
13670                        })
13671                        .await;
13672                    }
13673                });
13674                (abs_path, (globset, task))
13675            })
13676            .collect();
13677        LanguageServerWatchedPaths {
13678            worktree_paths: self.worktree_paths,
13679            abs_paths,
13680        }
13681    }
13682}
13683
13684struct LspBufferSnapshot {
13685    version: i32,
13686    snapshot: TextBufferSnapshot,
13687}
13688
13689/// A prompt requested by LSP server.
13690#[derive(Clone, Debug)]
13691pub struct LanguageServerPromptRequest {
13692    pub level: PromptLevel,
13693    pub message: String,
13694    pub actions: Vec<MessageActionItem>,
13695    pub lsp_name: String,
13696    pub(crate) response_channel: Sender<MessageActionItem>,
13697}
13698
13699impl LanguageServerPromptRequest {
13700    pub async fn respond(self, index: usize) -> Option<()> {
13701        if let Some(response) = self.actions.into_iter().nth(index) {
13702            self.response_channel.send(response).await.ok()
13703        } else {
13704            None
13705        }
13706    }
13707}
13708impl PartialEq for LanguageServerPromptRequest {
13709    fn eq(&self, other: &Self) -> bool {
13710        self.message == other.message && self.actions == other.actions
13711    }
13712}
13713
13714#[derive(Clone, Debug, PartialEq)]
13715pub enum LanguageServerLogType {
13716    Log(MessageType),
13717    Trace { verbose_info: Option<String> },
13718    Rpc { received: bool },
13719}
13720
13721impl LanguageServerLogType {
13722    pub fn to_proto(&self) -> proto::language_server_log::LogType {
13723        match self {
13724            Self::Log(log_type) => {
13725                use proto::log_message::LogLevel;
13726                let level = match *log_type {
13727                    MessageType::ERROR => LogLevel::Error,
13728                    MessageType::WARNING => LogLevel::Warning,
13729                    MessageType::INFO => LogLevel::Info,
13730                    MessageType::LOG => LogLevel::Log,
13731                    other => {
13732                        log::warn!("Unknown lsp log message type: {other:?}");
13733                        LogLevel::Log
13734                    }
13735                };
13736                proto::language_server_log::LogType::Log(proto::LogMessage {
13737                    level: level as i32,
13738                })
13739            }
13740            Self::Trace { verbose_info } => {
13741                proto::language_server_log::LogType::Trace(proto::TraceMessage {
13742                    verbose_info: verbose_info.to_owned(),
13743                })
13744            }
13745            Self::Rpc { received } => {
13746                let kind = if *received {
13747                    proto::rpc_message::Kind::Received
13748                } else {
13749                    proto::rpc_message::Kind::Sent
13750                };
13751                let kind = kind as i32;
13752                proto::language_server_log::LogType::Rpc(proto::RpcMessage { kind })
13753            }
13754        }
13755    }
13756
13757    pub fn from_proto(log_type: proto::language_server_log::LogType) -> Self {
13758        use proto::log_message::LogLevel;
13759        use proto::rpc_message;
13760        match log_type {
13761            proto::language_server_log::LogType::Log(message_type) => Self::Log(
13762                match LogLevel::from_i32(message_type.level).unwrap_or(LogLevel::Log) {
13763                    LogLevel::Error => MessageType::ERROR,
13764                    LogLevel::Warning => MessageType::WARNING,
13765                    LogLevel::Info => MessageType::INFO,
13766                    LogLevel::Log => MessageType::LOG,
13767                },
13768            ),
13769            proto::language_server_log::LogType::Trace(trace_message) => Self::Trace {
13770                verbose_info: trace_message.verbose_info,
13771            },
13772            proto::language_server_log::LogType::Rpc(message) => Self::Rpc {
13773                received: match rpc_message::Kind::from_i32(message.kind)
13774                    .unwrap_or(rpc_message::Kind::Received)
13775                {
13776                    rpc_message::Kind::Received => true,
13777                    rpc_message::Kind::Sent => false,
13778                },
13779            },
13780        }
13781    }
13782}
13783
13784pub struct WorkspaceRefreshTask {
13785    refresh_tx: mpsc::Sender<()>,
13786    progress_tx: mpsc::Sender<()>,
13787    #[allow(dead_code)]
13788    task: Task<()>,
13789}
13790
13791pub enum LanguageServerState {
13792    Starting {
13793        startup: Task<Option<Arc<LanguageServer>>>,
13794        /// List of language servers that will be added to the workspace once it's initialization completes.
13795        pending_workspace_folders: Arc<Mutex<BTreeSet<Uri>>>,
13796    },
13797
13798    Running {
13799        adapter: Arc<CachedLspAdapter>,
13800        server: Arc<LanguageServer>,
13801        simulate_disk_based_diagnostics_completion: Option<Task<()>>,
13802        workspace_diagnostics_refresh_tasks: HashMap<Option<String>, WorkspaceRefreshTask>,
13803    },
13804}
13805
13806impl LanguageServerState {
13807    fn add_workspace_folder(&self, uri: Uri) {
13808        match self {
13809            LanguageServerState::Starting {
13810                pending_workspace_folders,
13811                ..
13812            } => {
13813                pending_workspace_folders.lock().insert(uri);
13814            }
13815            LanguageServerState::Running { server, .. } => {
13816                server.add_workspace_folder(uri);
13817            }
13818        }
13819    }
13820    fn _remove_workspace_folder(&self, uri: Uri) {
13821        match self {
13822            LanguageServerState::Starting {
13823                pending_workspace_folders,
13824                ..
13825            } => {
13826                pending_workspace_folders.lock().remove(&uri);
13827            }
13828            LanguageServerState::Running { server, .. } => server.remove_workspace_folder(uri),
13829        }
13830    }
13831}
13832
13833impl std::fmt::Debug for LanguageServerState {
13834    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
13835        match self {
13836            LanguageServerState::Starting { .. } => {
13837                f.debug_struct("LanguageServerState::Starting").finish()
13838            }
13839            LanguageServerState::Running { .. } => {
13840                f.debug_struct("LanguageServerState::Running").finish()
13841            }
13842        }
13843    }
13844}
13845
13846#[derive(Clone, Debug, Serialize)]
13847pub struct LanguageServerProgress {
13848    pub is_disk_based_diagnostics_progress: bool,
13849    pub is_cancellable: bool,
13850    pub title: Option<String>,
13851    pub message: Option<String>,
13852    pub percentage: Option<usize>,
13853    #[serde(skip_serializing)]
13854    pub last_update_at: Instant,
13855}
13856
13857#[derive(Copy, Clone, Debug, Default, PartialEq, Serialize)]
13858pub struct DiagnosticSummary {
13859    pub error_count: usize,
13860    pub warning_count: usize,
13861}
13862
13863impl DiagnosticSummary {
13864    pub fn new<'a, T: 'a>(diagnostics: impl IntoIterator<Item = &'a DiagnosticEntry<T>>) -> Self {
13865        let mut this = Self {
13866            error_count: 0,
13867            warning_count: 0,
13868        };
13869
13870        for entry in diagnostics {
13871            if entry.diagnostic.is_primary {
13872                match entry.diagnostic.severity {
13873                    DiagnosticSeverity::ERROR => this.error_count += 1,
13874                    DiagnosticSeverity::WARNING => this.warning_count += 1,
13875                    _ => {}
13876                }
13877            }
13878        }
13879
13880        this
13881    }
13882
13883    pub fn is_empty(&self) -> bool {
13884        self.error_count == 0 && self.warning_count == 0
13885    }
13886
13887    pub fn to_proto(
13888        self,
13889        language_server_id: LanguageServerId,
13890        path: &RelPath,
13891    ) -> proto::DiagnosticSummary {
13892        proto::DiagnosticSummary {
13893            path: path.to_proto(),
13894            language_server_id: language_server_id.0 as u64,
13895            error_count: self.error_count as u32,
13896            warning_count: self.warning_count as u32,
13897        }
13898    }
13899}
13900
13901#[derive(Clone, Debug)]
13902pub enum CompletionDocumentation {
13903    /// There is no documentation for this completion.
13904    Undocumented,
13905    /// A single line of documentation.
13906    SingleLine(SharedString),
13907    /// Multiple lines of plain text documentation.
13908    MultiLinePlainText(SharedString),
13909    /// Markdown documentation.
13910    MultiLineMarkdown(SharedString),
13911    /// Both single line and multiple lines of plain text documentation.
13912    SingleLineAndMultiLinePlainText {
13913        single_line: SharedString,
13914        plain_text: Option<SharedString>,
13915    },
13916}
13917
13918impl CompletionDocumentation {
13919    #[cfg(any(test, feature = "test-support"))]
13920    pub fn text(&self) -> SharedString {
13921        match self {
13922            CompletionDocumentation::Undocumented => "".into(),
13923            CompletionDocumentation::SingleLine(s) => s.clone(),
13924            CompletionDocumentation::MultiLinePlainText(s) => s.clone(),
13925            CompletionDocumentation::MultiLineMarkdown(s) => s.clone(),
13926            CompletionDocumentation::SingleLineAndMultiLinePlainText { single_line, .. } => {
13927                single_line.clone()
13928            }
13929        }
13930    }
13931}
13932
13933impl From<lsp::Documentation> for CompletionDocumentation {
13934    fn from(docs: lsp::Documentation) -> Self {
13935        match docs {
13936            lsp::Documentation::String(text) => {
13937                if text.lines().count() <= 1 {
13938                    CompletionDocumentation::SingleLine(text.trim().to_string().into())
13939                } else {
13940                    CompletionDocumentation::MultiLinePlainText(text.into())
13941                }
13942            }
13943
13944            lsp::Documentation::MarkupContent(lsp::MarkupContent { kind, value }) => match kind {
13945                lsp::MarkupKind::PlainText => {
13946                    if value.lines().count() <= 1 {
13947                        CompletionDocumentation::SingleLine(value.into())
13948                    } else {
13949                        CompletionDocumentation::MultiLinePlainText(value.into())
13950                    }
13951                }
13952
13953                lsp::MarkupKind::Markdown => {
13954                    CompletionDocumentation::MultiLineMarkdown(value.into())
13955                }
13956            },
13957        }
13958    }
13959}
13960
13961pub enum ResolvedHint {
13962    Resolved(InlayHint),
13963    Resolving(Shared<Task<()>>),
13964}
13965
13966fn glob_literal_prefix(glob: &Path) -> PathBuf {
13967    glob.components()
13968        .take_while(|component| match component {
13969            path::Component::Normal(part) => !part.to_string_lossy().contains(['*', '?', '{', '}']),
13970            _ => true,
13971        })
13972        .collect()
13973}
13974
13975pub struct SshLspAdapter {
13976    name: LanguageServerName,
13977    binary: LanguageServerBinary,
13978    initialization_options: Option<String>,
13979    code_action_kinds: Option<Vec<CodeActionKind>>,
13980}
13981
13982impl SshLspAdapter {
13983    pub fn new(
13984        name: LanguageServerName,
13985        binary: LanguageServerBinary,
13986        initialization_options: Option<String>,
13987        code_action_kinds: Option<String>,
13988    ) -> Self {
13989        Self {
13990            name,
13991            binary,
13992            initialization_options,
13993            code_action_kinds: code_action_kinds
13994                .as_ref()
13995                .and_then(|c| serde_json::from_str(c).ok()),
13996        }
13997    }
13998}
13999
14000impl LspInstaller for SshLspAdapter {
14001    type BinaryVersion = ();
14002    async fn check_if_user_installed(
14003        &self,
14004        _: &dyn LspAdapterDelegate,
14005        _: Option<Toolchain>,
14006        _: &AsyncApp,
14007    ) -> Option<LanguageServerBinary> {
14008        Some(self.binary.clone())
14009    }
14010
14011    async fn cached_server_binary(
14012        &self,
14013        _: PathBuf,
14014        _: &dyn LspAdapterDelegate,
14015    ) -> Option<LanguageServerBinary> {
14016        None
14017    }
14018
14019    async fn fetch_latest_server_version(
14020        &self,
14021        _: &dyn LspAdapterDelegate,
14022        _: bool,
14023        _: &mut AsyncApp,
14024    ) -> Result<()> {
14025        anyhow::bail!("SshLspAdapter does not support fetch_latest_server_version")
14026    }
14027
14028    async fn fetch_server_binary(
14029        &self,
14030        _: (),
14031        _: PathBuf,
14032        _: &dyn LspAdapterDelegate,
14033    ) -> Result<LanguageServerBinary> {
14034        anyhow::bail!("SshLspAdapter does not support fetch_server_binary")
14035    }
14036}
14037
14038#[async_trait(?Send)]
14039impl LspAdapter for SshLspAdapter {
14040    fn name(&self) -> LanguageServerName {
14041        self.name.clone()
14042    }
14043
14044    async fn initialization_options(
14045        self: Arc<Self>,
14046        _: &Arc<dyn LspAdapterDelegate>,
14047    ) -> Result<Option<serde_json::Value>> {
14048        let Some(options) = &self.initialization_options else {
14049            return Ok(None);
14050        };
14051        let result = serde_json::from_str(options)?;
14052        Ok(result)
14053    }
14054
14055    fn code_action_kinds(&self) -> Option<Vec<CodeActionKind>> {
14056        self.code_action_kinds.clone()
14057    }
14058}
14059
14060pub fn language_server_settings<'a>(
14061    delegate: &'a dyn LspAdapterDelegate,
14062    language: &LanguageServerName,
14063    cx: &'a App,
14064) -> Option<&'a LspSettings> {
14065    language_server_settings_for(
14066        SettingsLocation {
14067            worktree_id: delegate.worktree_id(),
14068            path: RelPath::empty(),
14069        },
14070        language,
14071        cx,
14072    )
14073}
14074
14075pub fn language_server_settings_for<'a>(
14076    location: SettingsLocation<'a>,
14077    language: &LanguageServerName,
14078    cx: &'a App,
14079) -> Option<&'a LspSettings> {
14080    ProjectSettings::get(Some(location), cx).lsp.get(language)
14081}
14082
14083pub struct LocalLspAdapterDelegate {
14084    lsp_store: WeakEntity<LspStore>,
14085    worktree: worktree::Snapshot,
14086    fs: Arc<dyn Fs>,
14087    http_client: Arc<dyn HttpClient>,
14088    language_registry: Arc<LanguageRegistry>,
14089    load_shell_env_task: Shared<Task<Option<HashMap<String, String>>>>,
14090}
14091
14092impl LocalLspAdapterDelegate {
14093    pub fn new(
14094        language_registry: Arc<LanguageRegistry>,
14095        environment: &Entity<ProjectEnvironment>,
14096        lsp_store: WeakEntity<LspStore>,
14097        worktree: &Entity<Worktree>,
14098        http_client: Arc<dyn HttpClient>,
14099        fs: Arc<dyn Fs>,
14100        cx: &mut App,
14101    ) -> Arc<Self> {
14102        let load_shell_env_task =
14103            environment.update(cx, |env, cx| env.worktree_environment(worktree.clone(), cx));
14104
14105        Arc::new(Self {
14106            lsp_store,
14107            worktree: worktree.read(cx).snapshot(),
14108            fs,
14109            http_client,
14110            language_registry,
14111            load_shell_env_task,
14112        })
14113    }
14114
14115    pub fn from_local_lsp(
14116        local: &LocalLspStore,
14117        worktree: &Entity<Worktree>,
14118        cx: &mut App,
14119    ) -> Arc<Self> {
14120        Self::new(
14121            local.languages.clone(),
14122            &local.environment,
14123            local.weak.clone(),
14124            worktree,
14125            local.http_client.clone(),
14126            local.fs.clone(),
14127            cx,
14128        )
14129    }
14130}
14131
14132#[async_trait]
14133impl LspAdapterDelegate for LocalLspAdapterDelegate {
14134    fn show_notification(&self, message: &str, cx: &mut App) {
14135        self.lsp_store
14136            .update(cx, |_, cx| {
14137                cx.emit(LspStoreEvent::Notification(message.to_owned()))
14138            })
14139            .ok();
14140    }
14141
14142    fn http_client(&self) -> Arc<dyn HttpClient> {
14143        self.http_client.clone()
14144    }
14145
14146    fn worktree_id(&self) -> WorktreeId {
14147        self.worktree.id()
14148    }
14149
14150    fn worktree_root_path(&self) -> &Path {
14151        self.worktree.abs_path().as_ref()
14152    }
14153
14154    fn resolve_executable_path(&self, path: PathBuf) -> PathBuf {
14155        self.worktree.resolve_executable_path(path)
14156    }
14157
14158    async fn shell_env(&self) -> HashMap<String, String> {
14159        let task = self.load_shell_env_task.clone();
14160        task.await.unwrap_or_default()
14161    }
14162
14163    async fn npm_package_installed_version(
14164        &self,
14165        package_name: &str,
14166    ) -> Result<Option<(PathBuf, Version)>> {
14167        let local_package_directory = self.worktree_root_path();
14168        let node_modules_directory = local_package_directory.join("node_modules");
14169
14170        if let Some(version) =
14171            read_package_installed_version(node_modules_directory.clone(), package_name).await?
14172        {
14173            return Ok(Some((node_modules_directory, version)));
14174        }
14175        let Some(npm) = self.which("npm".as_ref()).await else {
14176            log::warn!(
14177                "Failed to find npm executable for {:?}",
14178                local_package_directory
14179            );
14180            return Ok(None);
14181        };
14182
14183        let env = self.shell_env().await;
14184        let output = util::command::new_smol_command(&npm)
14185            .args(["root", "-g"])
14186            .envs(env)
14187            .current_dir(local_package_directory)
14188            .output()
14189            .await?;
14190        let global_node_modules =
14191            PathBuf::from(String::from_utf8_lossy(&output.stdout).to_string());
14192
14193        if let Some(version) =
14194            read_package_installed_version(global_node_modules.clone(), package_name).await?
14195        {
14196            return Ok(Some((global_node_modules, version)));
14197        }
14198        return Ok(None);
14199    }
14200
14201    async fn which(&self, command: &OsStr) -> Option<PathBuf> {
14202        let mut worktree_abs_path = self.worktree_root_path().to_path_buf();
14203        if self.fs.is_file(&worktree_abs_path).await {
14204            worktree_abs_path.pop();
14205        }
14206
14207        let env = self.shell_env().await;
14208
14209        let shell_path = env.get("PATH").cloned();
14210
14211        which::which_in(command, shell_path.as_ref(), worktree_abs_path).ok()
14212    }
14213
14214    async fn try_exec(&self, command: LanguageServerBinary) -> Result<()> {
14215        let mut working_dir = self.worktree_root_path().to_path_buf();
14216        if self.fs.is_file(&working_dir).await {
14217            working_dir.pop();
14218        }
14219        let output = util::command::new_smol_command(&command.path)
14220            .args(command.arguments)
14221            .envs(command.env.clone().unwrap_or_default())
14222            .current_dir(working_dir)
14223            .output()
14224            .await?;
14225
14226        anyhow::ensure!(
14227            output.status.success(),
14228            "{}, stdout: {:?}, stderr: {:?}",
14229            output.status,
14230            String::from_utf8_lossy(&output.stdout),
14231            String::from_utf8_lossy(&output.stderr)
14232        );
14233        Ok(())
14234    }
14235
14236    fn update_status(&self, server_name: LanguageServerName, status: language::BinaryStatus) {
14237        self.language_registry
14238            .update_lsp_binary_status(server_name, status);
14239    }
14240
14241    fn registered_lsp_adapters(&self) -> Vec<Arc<dyn LspAdapter>> {
14242        self.language_registry
14243            .all_lsp_adapters()
14244            .into_iter()
14245            .map(|adapter| adapter.adapter.clone() as Arc<dyn LspAdapter>)
14246            .collect()
14247    }
14248
14249    async fn language_server_download_dir(&self, name: &LanguageServerName) -> Option<Arc<Path>> {
14250        let dir = self.language_registry.language_server_download_dir(name)?;
14251
14252        if !dir.exists() {
14253            smol::fs::create_dir_all(&dir)
14254                .await
14255                .context("failed to create container directory")
14256                .log_err()?;
14257        }
14258
14259        Some(dir)
14260    }
14261
14262    async fn read_text_file(&self, path: &RelPath) -> Result<String> {
14263        let entry = self
14264            .worktree
14265            .entry_for_path(path)
14266            .with_context(|| format!("no worktree entry for path {path:?}"))?;
14267        let abs_path = self.worktree.absolutize(&entry.path);
14268        self.fs.load(&abs_path).await
14269    }
14270}
14271
14272async fn populate_labels_for_symbols(
14273    symbols: Vec<CoreSymbol>,
14274    language_registry: &Arc<LanguageRegistry>,
14275    lsp_adapter: Option<Arc<CachedLspAdapter>>,
14276    output: &mut Vec<Symbol>,
14277) {
14278    #[allow(clippy::mutable_key_type)]
14279    let mut symbols_by_language = HashMap::<Option<Arc<Language>>, Vec<CoreSymbol>>::default();
14280
14281    let mut unknown_paths = BTreeSet::<Arc<str>>::new();
14282    for symbol in symbols {
14283        let Some(file_name) = symbol.path.file_name() else {
14284            continue;
14285        };
14286        let language = language_registry
14287            .load_language_for_file_path(Path::new(file_name))
14288            .await
14289            .ok()
14290            .or_else(|| {
14291                unknown_paths.insert(file_name.into());
14292                None
14293            });
14294        symbols_by_language
14295            .entry(language)
14296            .or_default()
14297            .push(symbol);
14298    }
14299
14300    for unknown_path in unknown_paths {
14301        log::info!("no language found for symbol in file {unknown_path:?}");
14302    }
14303
14304    let mut label_params = Vec::new();
14305    for (language, mut symbols) in symbols_by_language {
14306        label_params.clear();
14307        label_params.extend(
14308            symbols
14309                .iter_mut()
14310                .map(|symbol| (mem::take(&mut symbol.name), symbol.kind)),
14311        );
14312
14313        let mut labels = Vec::new();
14314        if let Some(language) = language {
14315            let lsp_adapter = lsp_adapter.clone().or_else(|| {
14316                language_registry
14317                    .lsp_adapters(&language.name())
14318                    .first()
14319                    .cloned()
14320            });
14321            if let Some(lsp_adapter) = lsp_adapter {
14322                labels = lsp_adapter
14323                    .labels_for_symbols(&label_params, &language)
14324                    .await
14325                    .log_err()
14326                    .unwrap_or_default();
14327            }
14328        }
14329
14330        for ((symbol, (name, _)), label) in symbols
14331            .into_iter()
14332            .zip(label_params.drain(..))
14333            .zip(labels.into_iter().chain(iter::repeat(None)))
14334        {
14335            output.push(Symbol {
14336                language_server_name: symbol.language_server_name,
14337                source_worktree_id: symbol.source_worktree_id,
14338                source_language_server_id: symbol.source_language_server_id,
14339                path: symbol.path,
14340                label: label.unwrap_or_else(|| CodeLabel::plain(name.clone(), None)),
14341                name,
14342                kind: symbol.kind,
14343                range: symbol.range,
14344            });
14345        }
14346    }
14347}
14348
14349fn include_text(server: &lsp::LanguageServer) -> Option<bool> {
14350    match server.capabilities().text_document_sync.as_ref()? {
14351        lsp::TextDocumentSyncCapability::Options(opts) => match opts.save.as_ref()? {
14352            // Server wants didSave but didn't specify includeText.
14353            lsp::TextDocumentSyncSaveOptions::Supported(true) => Some(false),
14354            // Server doesn't want didSave at all.
14355            lsp::TextDocumentSyncSaveOptions::Supported(false) => None,
14356            // Server provided SaveOptions.
14357            lsp::TextDocumentSyncSaveOptions::SaveOptions(save_options) => {
14358                Some(save_options.include_text.unwrap_or(false))
14359            }
14360        },
14361        // We do not have any save info. Kind affects didChange only.
14362        lsp::TextDocumentSyncCapability::Kind(_) => None,
14363    }
14364}
14365
14366/// Completion items are displayed in a `UniformList`.
14367/// Usually, those items are single-line strings, but in LSP responses,
14368/// completion items `label`, `detail` and `label_details.description` may contain newlines or long spaces.
14369/// Many language plugins construct these items by joining these parts together, and we may use `CodeLabel::fallback_for_completion` that uses `label` at least.
14370/// 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,
14371/// breaking the completions menu presentation.
14372///
14373/// 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.
14374fn ensure_uniform_list_compatible_label(label: &mut CodeLabel) {
14375    let mut new_text = String::with_capacity(label.text.len());
14376    let mut offset_map = vec![0; label.text.len() + 1];
14377    let mut last_char_was_space = false;
14378    let mut new_idx = 0;
14379    let chars = label.text.char_indices().fuse();
14380    let mut newlines_removed = false;
14381
14382    for (idx, c) in chars {
14383        offset_map[idx] = new_idx;
14384
14385        match c {
14386            '\n' if last_char_was_space => {
14387                newlines_removed = true;
14388            }
14389            '\t' | ' ' if last_char_was_space => {}
14390            '\n' if !last_char_was_space => {
14391                new_text.push(' ');
14392                new_idx += 1;
14393                last_char_was_space = true;
14394                newlines_removed = true;
14395            }
14396            ' ' | '\t' => {
14397                new_text.push(' ');
14398                new_idx += 1;
14399                last_char_was_space = true;
14400            }
14401            _ => {
14402                new_text.push(c);
14403                new_idx += c.len_utf8();
14404                last_char_was_space = false;
14405            }
14406        }
14407    }
14408    offset_map[label.text.len()] = new_idx;
14409
14410    // Only modify the label if newlines were removed.
14411    if !newlines_removed {
14412        return;
14413    }
14414
14415    let last_index = new_idx;
14416    let mut run_ranges_errors = Vec::new();
14417    label.runs.retain_mut(|(range, _)| {
14418        match offset_map.get(range.start) {
14419            Some(&start) => range.start = start,
14420            None => {
14421                run_ranges_errors.push(range.clone());
14422                return false;
14423            }
14424        }
14425
14426        match offset_map.get(range.end) {
14427            Some(&end) => range.end = end,
14428            None => {
14429                run_ranges_errors.push(range.clone());
14430                range.end = last_index;
14431            }
14432        }
14433        true
14434    });
14435    if !run_ranges_errors.is_empty() {
14436        log::error!(
14437            "Completion label has errors in its run ranges: {run_ranges_errors:?}, label text: {}",
14438            label.text
14439        );
14440    }
14441
14442    let mut wrong_filter_range = None;
14443    if label.filter_range == (0..label.text.len()) {
14444        label.filter_range = 0..new_text.len();
14445    } else {
14446        let mut original_filter_range = Some(label.filter_range.clone());
14447        match offset_map.get(label.filter_range.start) {
14448            Some(&start) => label.filter_range.start = start,
14449            None => {
14450                wrong_filter_range = original_filter_range.take();
14451                label.filter_range.start = last_index;
14452            }
14453        }
14454
14455        match offset_map.get(label.filter_range.end) {
14456            Some(&end) => label.filter_range.end = end,
14457            None => {
14458                wrong_filter_range = original_filter_range.take();
14459                label.filter_range.end = last_index;
14460            }
14461        }
14462    }
14463    if let Some(wrong_filter_range) = wrong_filter_range {
14464        log::error!(
14465            "Completion label has an invalid filter range: {wrong_filter_range:?}, label text: {}",
14466            label.text
14467        );
14468    }
14469
14470    label.text = new_text;
14471}
14472
14473#[cfg(test)]
14474mod tests {
14475    use language::HighlightId;
14476
14477    use super::*;
14478
14479    #[test]
14480    fn test_glob_literal_prefix() {
14481        assert_eq!(glob_literal_prefix(Path::new("**/*.js")), Path::new(""));
14482        assert_eq!(
14483            glob_literal_prefix(Path::new("node_modules/**/*.js")),
14484            Path::new("node_modules")
14485        );
14486        assert_eq!(
14487            glob_literal_prefix(Path::new("foo/{bar,baz}.js")),
14488            Path::new("foo")
14489        );
14490        assert_eq!(
14491            glob_literal_prefix(Path::new("foo/bar/baz.js")),
14492            Path::new("foo/bar/baz.js")
14493        );
14494
14495        #[cfg(target_os = "windows")]
14496        {
14497            assert_eq!(glob_literal_prefix(Path::new("**\\*.js")), Path::new(""));
14498            assert_eq!(
14499                glob_literal_prefix(Path::new("node_modules\\**/*.js")),
14500                Path::new("node_modules")
14501            );
14502            assert_eq!(
14503                glob_literal_prefix(Path::new("foo/{bar,baz}.js")),
14504                Path::new("foo")
14505            );
14506            assert_eq!(
14507                glob_literal_prefix(Path::new("foo\\bar\\baz.js")),
14508                Path::new("foo/bar/baz.js")
14509            );
14510        }
14511    }
14512
14513    #[test]
14514    fn test_multi_len_chars_normalization() {
14515        let mut label = CodeLabel::new(
14516            "myElˇ (parameter) myElˇ: {\n    foo: string;\n}".to_string(),
14517            0..6,
14518            vec![(0..6, HighlightId(1))],
14519        );
14520        ensure_uniform_list_compatible_label(&mut label);
14521        assert_eq!(
14522            label,
14523            CodeLabel::new(
14524                "myElˇ (parameter) myElˇ: { foo: string; }".to_string(),
14525                0..6,
14526                vec![(0..6, HighlightId(1))],
14527            )
14528        );
14529    }
14530
14531    #[test]
14532    fn test_trailing_newline_in_completion_documentation() {
14533        let doc = lsp::Documentation::String(
14534            "Inappropriate argument value (of correct type).\n".to_string(),
14535        );
14536        let completion_doc: CompletionDocumentation = doc.into();
14537        assert!(
14538            matches!(completion_doc, CompletionDocumentation::SingleLine(s) if s == "Inappropriate argument value (of correct type).")
14539        );
14540
14541        let doc = lsp::Documentation::String("  some value  \n".to_string());
14542        let completion_doc: CompletionDocumentation = doc.into();
14543        assert!(matches!(
14544            completion_doc,
14545            CompletionDocumentation::SingleLine(s) if s == "some value"
14546        ));
14547    }
14548}